專利名稱:字節(jié)序轉(zhuǎn)換工具的制作方法
技術(shù)領域:
本發(fā)明涉及字節(jié)序轉(zhuǎn)換。
背景技術(shù):
字節(jié)序是數(shù)據(jù)存儲和檢索的屬性。大字節(jié)序(endian)數(shù)據(jù)或變量可以以與小字 節(jié)序數(shù)據(jù)或變量相反的字節(jié)順序被存儲在存儲器中。小字節(jié)序數(shù)據(jù)可以以最低有效字節(jié)在 最低的存儲器字節(jié)地址中的方式被存儲,而大字節(jié)序數(shù)據(jù)可以以最高有效字節(jié)在最低的存 儲器字節(jié)地址中的方式被存儲。具有相同值的大和小字節(jié)序變量在CPU寄存器中可以是相 同的,但是在存儲器中可能具有不同順序。在沒有識別一些數(shù)據(jù)以如何的不同順序被存儲在存儲器中的情況下,使用一種字 節(jié)序約定編寫的源代碼不可以在使用另一種字節(jié)序約定的平臺上被執(zhí)行。下面的C代碼提 供一個例子
{
int i = 0x12345678; char c = *((char*)&i);
}
如果該代碼被編譯并且在大字節(jié)序架構(gòu)上運行,則“C”將是0x12,但是如果該代碼被 編譯并且在小字節(jié)序架構(gòu)上運行,則“C”將是0x78。因此,為了在另一種字節(jié)序約定的計算 機系統(tǒng)平臺上執(zhí)行以一種字節(jié)序約定編寫的代碼,可能需要字節(jié)序轉(zhuǎn)換。當例如源代碼包 括union (聯(lián)合)或者將第一指針(其指向由多個字節(jié)構(gòu)成的數(shù)據(jù))轉(zhuǎn)換(cast)為第二指針 (其指向由單個字節(jié)構(gòu)成的數(shù)據(jù))時,這會是困難的。指針會產(chǎn)生困難,因為一些雙字節(jié)序編 譯器不追蹤通過指針(例如void指針)的字節(jié)順序,并且不產(chǎn)生對通過這樣的指針的潛在字 節(jié)順序改變的診斷。因此,指針等會導致無法預料的字節(jié)順序不相容性。
發(fā)明內(nèi)容
根據(jù)本發(fā)明的第一方面,提供一種方法。所述方法包括接收分別定義全局變量的 第一和第二實例的第一和第二源代碼部分,其中每個實例具有第一字節(jié)序格式并且這兩個 實例在編譯時間都不能被完全地初始化;生成對字節(jié)交換指令的第一和第二引用,其被配 置成分別將所述第一和第二實例轉(zhuǎn)換成第二字節(jié)序格式;使用處理器來生成影子變量,所 述影子變量被配置成在編譯時間之后并且基于所述第一實例已經(jīng)被字節(jié)交換來抑制所述 第二實例的字節(jié)交換;以及將所述影子變量存儲在耦合到所述處理器的存儲器中。根據(jù)本發(fā)明的第二方面,提供一種包括介質(zhì)的物品。所述介質(zhì)存儲用于使基于處 理器的系統(tǒng)能夠執(zhí)行以下操作的指令接收分別定義全局變量的第一和第二實例的第一和 第二代碼部分,其中所述全局變量的每個實例具有第一字節(jié)序格式并且這兩個實例在編譯 時間都不能被正確地初始化;以及生成第一變量,所述第一變量被配置成在編譯時間之后 并且基于所述第一實例已經(jīng)被字節(jié)序轉(zhuǎn)換來抑制所述第二實例的字節(jié)序轉(zhuǎn)換。
根據(jù)本發(fā)明的第三方面,提供一種裝置。所述裝置包括耦合到存儲器的處理器, 其執(zhí)行以下操作(1)使用所述存儲器接收分別定義全局變量的第一和第二實例的第一和 第二源代碼部分,其中所述全局變量的每個實例具有第一字節(jié)序格式并且這兩個實例在編 譯時間都不能被完全地初始化;以及(2)生成第一變量,所述第一變量被配置成在編譯時 間之后并且基于所述第一實例已經(jīng)被字節(jié)交換來抑制所述第二實例的字節(jié)交換。
根據(jù)所附權(quán)利要求、以下對一個或多個示例實施例的詳細描述、以及對應的圖,本 發(fā)明的實施例的特征和優(yōu)點將變得顯而易見,其中
圖1是用于本發(fā)明實施例中的方法的框圖,其包括偽代碼; 圖2是用于本發(fā)明實施例中的方法的框圖,其包括偽代碼; 圖3是本發(fā)明實施例中的方法的框圖;以及 圖4是供本發(fā)明實施例使用的系統(tǒng)框圖。
具體實施例方式在以下描述中,闡述了許多具體細節(jié)。然而,應該理解,可以在沒有這些具體細節(jié) 的情況下實踐本發(fā)明實施例。公知的電路、結(jié)構(gòu)和技術(shù)沒有被詳細示出以避免模糊對本描 述的理解。對“一個實施例”、“實施例”、“示例實施例”、“各種實施例”等等的提及表示,如 此描述的(一個或多個)實施例可以包括特定的特征、結(jié)構(gòu)或特性,但不是每個實施例必定 包括所述特定的特征、結(jié)構(gòu)或特性。此外,一些實施例可以具有針對其他實施例所描述的一 些、所有特征,或者不具有針對其他實施例所描述的特征。而且,如在此所用的“第一”、“第 二”、“第三”等等描述了共同的對象,并且表示相同對象的不同實例正在被提及。此類形容 詞不打算暗示如此描述的對象必須或者在時間上、在空間上、按照等級或者以任何其他方 式處于給定的序列。而且,為了清楚,在此討論的許多示例實施例提出編譯器(例如C/C++ 編譯器)以及其對源代碼的應用,但是本發(fā)明實施例不必受限于此。例如,盡管實施例包括 解析代碼,例如在編譯器中所包括的解析工具,但是其他實施例可以包括在其他形式的代 碼中所包括的解析代碼。在本發(fā)明的一個實施例中,代碼(例如編譯器、工具)可以生成信息,因此包括第一 字節(jié)序格式(例如大字節(jié)序)的指針值的代碼部分能夠被適當?shù)爻跏蓟⑶以诰哂械诙?節(jié)序格式(例如小字節(jié)序)的平臺上被執(zhí)行。圖1包括源代碼110以及可執(zhí)行代碼150的直觀表示。代碼110可能易受“復制 問題”的影響。具體而言,代碼Iio包括代碼部分111、112。每個部分包括全局變量“g”的 實例。全程變量“g”可以被常規(guī)的編譯器初始化兩次一次在代碼部分111的(int* _ attribute, ((bigendian)) g=&il)中,并且再一次在代碼部分 Il2 的(int* _attribute_ ((bigendian)) g=&i2)中。初始化包括例如通過向程序中的變量/數(shù)據(jù)結(jié)構(gòu)分配初始 值來定義變量的過程。代碼部分111、112包括指針((int* ,attribute,((bigendian)) g=&il)和(int*_attribute_((bigendian)) g=&i2)),這兩個指針具有大字節(jié)序?qū)傩缘?分別指向不同的地址。每個地址具有大字節(jié)序?qū)傩?。這些地址涉及兩個不同的對象((int _attribute_((bigendian)) il = 1;)禾口(int _attribute_((bigendian)) i2 = 2;))。編譯器(例如雙字節(jié)序編譯器)可能嘗試將源代碼110從大字節(jié)序格式或約定轉(zhuǎn)換成適合于具 有小字節(jié)序格式的平臺的代碼(例如可執(zhí)行代碼)。為了這樣做,編譯器可以對兩個部分111 和112中的大字節(jié)序全局變量“g”執(zhí)行例如字節(jié)交換操作。這可能導致“復制問題”,因為 “g”在第一字節(jié)序轉(zhuǎn)換期間從大字節(jié)序被轉(zhuǎn)換到小字節(jié)序,然后“g”在第二轉(zhuǎn)換中從小字節(jié) 序被轉(zhuǎn)換回到大字節(jié)序。因此,由于“g”被轉(zhuǎn)換了兩次,所以可能發(fā)生復制問題,從而顛倒 了所需的從大字節(jié)序到小字節(jié)序的轉(zhuǎn)換。關(guān)于代碼110可能如何導致復制問題的更具體的描述如下。兩個源文件111、112 定義了全局大字節(jié)序變量“g”。常規(guī)的編譯器可能基于不同的鏈接時間常量來初始化全局 大字節(jié)序變量“g”,即使直到在鏈接時間或在鏈接時間之后(即在編譯時間之后)才知道鏈 接時間常量的地址(例如il或i2)也是如此。編譯器可能不知道“g”的哪個特定值被鏈接 編輯器或系統(tǒng)載入器取得。因此,對于每個部分111、112,編譯器生成用于“g”的交換操作, 即使“g”是直到在編譯時間之后才能完全地初始化(即正確地初始化)的指針變量也是如 此。稍后,鏈接編輯器可能僅取“g”的一個實例,從而導致應用于“g”的單個實例的兩個交 換操作。本發(fā)明的一個實施例如下解決了復制問題
{
If (g_shadow == FALSE)
{
Byteswap(g); g_shadow = TRUE; } else /* g已經(jīng)被交換了一次,所以什么都不做*/
}
一般而言,以上偽代碼說明,本發(fā)明實施例可以使用“影子變量”以確保全局變量“g”被 轉(zhuǎn)換(例如被字節(jié)交換)一次,并且確保后續(xù)對轉(zhuǎn)換“g”的嘗試被抑制。在“g”的初始轉(zhuǎn)換 時,變量“g_shadoW”被從“FALSE”改變成“TRUE”。此后,轉(zhuǎn)換函數(shù)(例如字節(jié)交換函數(shù))被 抑制,因為它以“g_shad0W”被設置為“FALSE”為條件。因此,在本發(fā)明的一個實施例中,對于利用非固有的(native)字節(jié)順序的鏈接時 間常量初始化的每個全局變量,編譯器可以在應用程序(application)內(nèi)生成變量(例如不 可見的“影子變量”)。可以在特殊的影子段(section)內(nèi)部分配影子變量,因此影子變量不 干擾應用程序變量。例如,對影子變量的引用可以與對原始變量的引用放在一起。一開始, 一些或所有影子變量可以利用“FALSE”值來初始化,這意味著對應的實際應用程序變量尚 未被交換。稍后,在數(shù)據(jù)初始化過程期間,在第一次字節(jié)交換操作被應用于對應的原始變量 時,“TRUE”值可以被放入每個影子變量中。一旦影子變量等于“TRUE”,則用于原始變量的 所有相繼交換操作可以被抑制。因此,在本發(fā)明的一個實施例中,影子變量產(chǎn)生全局變量狀 態(tài)的“影子”以指示該全局變量是已經(jīng)被字節(jié)交換還是尚未被字節(jié)交換,并且有助于確保全 局變量僅被字節(jié)交換一次。 返回到圖1,代碼150是使用本發(fā)明實施例從源代碼110產(chǎn)生的經(jīng)編譯代碼的直 觀表示。對于全局變量“g”,代碼(例如編譯器)可以在代碼部分151和152這二者中生成 影子變量“g_shadoW”,因為這兩個部分相關(guān)于源代碼的包括“g”的部分(即代碼部分111、112)。“g_shadoW”變量是從“.initdatajhadow”段分配的?!癵_shadoW”變量的初始值是 “FALSE”。使用代碼(例如鏈接器),對“g”的符號引用可以經(jīng)由示意箭頭154、155、157、159 被從“g”的弱實例(參見示意塊170)轉(zhuǎn)換(例如重定位)到“g”的強實例(參見示意塊160)。 “弱”指定可以允許程序例如在程序執(zhí)行期間改變變量的位置。相比之下,“強”指定不會允 許程序在程序執(zhí)行期間改變變量的位置。變量的強定義可以改變由弱變量定義的位置,但 反過來并非如此。出于與以上關(guān)于“g”所討論的相同原因,對“gjhadow”的符號弱引用(塊175)還 可以經(jīng)由示意箭頭156、158被重定位到“8_吐3(1(^”的單個強實例(示意塊165)。該重定 位可以基于由編譯器提供的、與在塊150中提供重定位方向的箭頭一致的重定位信息。包 括對“g”和“g_shadoW”的重定位引用的代碼版本沒有在圖1中示出,但是將關(guān)于圖2被提 出。稍后,在后編譯數(shù)據(jù)初始化過程中,第一字節(jié)交換操作可以被應用于“g”(其經(jīng)由與箭 頭155 —致的重定位信息被重定位),并且可以將“TRUE”置于“g_Shad0W”處(其經(jīng)由與箭頭 156 一致的重定位信息被重定位)。然后,當該過程遇到對于“g”的第二字節(jié)交換操作(其經(jīng) 由與箭頭159 —致的重定位信息被重定位)時,“g_Shad0W”已經(jīng)具有“TRUE”值(其經(jīng)由與 箭頭158—致的重定位信息被重定位),并且交換操作因而沒有被執(zhí)行。因此,在實施例中, “g”僅被交換一次并且保持正確值。圖2包括本發(fā)明的實施例。方法200包括源代碼部分205,其類似于圖1的部分 110。在塊210中,應用程序被編譯。當雙字節(jié)序功能被啟用時,編譯器可以生成初始化數(shù) 據(jù)。由編譯器提供的初始化數(shù)據(jù)或信息可以包括影子變量、交換g引用、以及與影子變量 和交換g引用相關(guān)的重定位信息。編譯器可以將該初始化數(shù)據(jù)放入名為“.initdata”和 “.initdata_shadow"的特殊的可執(zhí)行與鏈接格式(ELF)段中,如在塊215中所示。塊215 類似于圖1的部分151。取決于編譯器選項,該.initdata段可以被放入可載入段或注釋段 中。在塊220中,諸如圖1的部分152之類的其他目標文件以與塊215類似的方式被 處理以生成更多的.initdata段。然后,在塊225中,鏈接器可以以由圖1中的箭頭所指示 的方式組合.initdata段并重定位g交換和影子變量(基于由編譯器提供的重定位信息)。. initdata段可以來自各種目標文件,并且可以以鏈接的二進制來放置.initdata段。在塊230中,使用后鏈接工具對代碼進行后處理,所述后鏈接工具在本發(fā)明的一 個實施例中可以被包括在編譯器中。在其他實施例中,所述后鏈接工具與編譯器是分開的。 后鏈接工具可以讀取可執(zhí)行映像的.initdata段,并且對具有在鏈接期間未被正確計算的 值的數(shù)據(jù)執(zhí)行初始化(例如,諸如“g”變量之類的全局變量地址)。因為可能留下未解析的 引用,所以該工具可以檢查位置是否不具有與之相關(guān)聯(lián)的重定位,例如針對圖1所討論的 那些重定位。在那種情況下,在運行時期間僅僅可以檢測到正確值,并且這里不可以執(zhí)行交 換,而是作為代替在塊245中(參見下文)執(zhí)行交換。否則,地址所指向的數(shù)據(jù)可以基于由編 譯器提供的初始化信息而如在塊235中所示的那樣被字節(jié)交換。注意,在塊235中,一些字 節(jié)交換現(xiàn)在已經(jīng)發(fā)生(例如long swapped (&il)),并且來自塊215的一些條目(例如g條 目)已經(jīng)被去除。由于先前發(fā)生的重定位,所以存在單個section」initdata段。 在塊240和245中,可以發(fā)生動態(tài)運行時初始化。如果從塊230中的連編(build) 中留下未執(zhí)行的字節(jié)交換(例如這可能對于動態(tài)鏈接的應用程序發(fā)生),則它們可以在塊245中被執(zhí)行,在塊245中在應用程序進入用戶代碼之前它們或者通過例如與可執(zhí)行程序 靜態(tài)鏈接的運行時初始化例程(例如由編譯器提供)或者通過經(jīng)修改的操作系統(tǒng)(OS)載入 器進行。在運行時初始化的情況下,可能需要數(shù)據(jù)被定位到讀_寫(R/W)段以被OS載入。 由于由編譯器提供的初始化信息,所以這些字節(jié)交換會是可能的。 在塊250中,可以發(fā)生驗證。例如,當應用程序啟動時,可以執(zhí)行檢查以確保沒有 剩余的未解析的.initdata記錄留下。這樣做可以避免由于在經(jīng)初始化的數(shù)據(jù)內(nèi)部丟失字 節(jié)序校正而引起的程序故障。編譯器可以生成運行時檢查,其確保初始化已經(jīng)被適當?shù)赝?成。對于這種運行時檢查的例子,編譯器可以為每個編譯單元創(chuàng)建大字節(jié)序“保護”變量。 該“保護變量”可以利用已知的鏈接時間常量值和例程來初始化,所述例程檢查該值是否已 經(jīng)被交換。如果沒有發(fā)生這樣的交換,則應用程序可以終止于錯誤狀態(tài)。否則,該應用程序 可以在塊255中繼續(xù)進行。因此,本發(fā)明的各種實施例涉及針對在編譯時間不能被完全地解析的數(shù)據(jù)初始化 的解決方案。例如,一個全局變量(例如來自圖1的“g”)可以保持另一全局變量的地址。在 這種情況下,直到鏈接階段才可能知道要被分配給該全局變量的確切值。在編譯時間不能 被完全地解析的數(shù)據(jù)初始化的另一例子涉及動態(tài)鏈接的應用程序,其中僅在運行時的動態(tài) 鏈接階段之后才知道最終值。如果假定實際的初始化值具有反向字節(jié)順序,則它應該在動 態(tài)鏈接之后并且在程序執(zhí)行之前的某一階段被交換。在編譯時間不能被完全地解析的數(shù)據(jù) 初始化的又一個例子涉及常用的允許變量的弱定義的應用程序二進制接口(ABI)。這樣的 弱定義允許聲明變量多于一次并且令鏈接器或載入器決定對象的哪個實例實際上被取得。本發(fā)明的各種實施例是基于工具的,并且可以使用標準ELF文件格式。這可以允 許用戶把未經(jīng)修改的基于ELF的工具(像鏈接器和操作系統(tǒng)(OS)載入器)用于本發(fā)明的實 施例。因此,在本發(fā)明的一個實施例中,期望移植(port)大字節(jié)序代碼以在小字節(jié)序平 臺上運行(或反之亦然)的程序員不需要重寫他或她的完全在固有的單個字節(jié)序模式下運 行的應用程序。作為替代,可以以特定的字節(jié)序格式來指定源代碼的部分,例如需要大字節(jié) 序格式以便與網(wǎng)絡分組交互的組件。本發(fā)明的實施例于是可以提供將允許在稍后的時間對 代碼部分進行適當初始化的數(shù)據(jù)。這些代碼部分可以包括第一字節(jié)序格式(例如大字節(jié)序) 的指針值,所述指針值必須稍后在具有第二字節(jié)序格式(例如小字節(jié)序)的平臺上執(zhí)行。本 發(fā)明的各種實施例提供了對靜態(tài)初始化對象(包括指針對象)的字節(jié)序的自動調(diào)整。一些實 施例解決了由多個分配的對象所引起的地址模糊性。而且,一些實施例提供了對在例如應 用程序啟動期間丟失字節(jié)序校正的運行時檢測。一些實施例使用特殊編譯器生成信息來描 述非編譯時間常數(shù)的大字節(jié)序指針值。各種實施例使用后處理工具來在鏈接過程已經(jīng)完成 之后校正字節(jié)序。附加的實施例使用特殊應用程序啟動代碼,其能夠在動態(tài)鏈接的應用程 序的情況下校正字節(jié)序。圖3是本發(fā)明實施例中的方法的框圖,該方法可以解決例如由解析代碼(例如雙 字節(jié)序編譯器)所引起的困難。一種這樣的困難涉及不追蹤通過void指針的字節(jié)順序的編 譯器。void指針可以包括指向具有未知類型的值的指針。另一困難可以包括以下情形通 過將指針向或從指針進行轉(zhuǎn)換而丟失了字節(jié)順序改變?!稗D(zhuǎn)換”可以包括從一種類型到另一 類型的程序員規(guī)定的數(shù)據(jù)轉(zhuǎn)換,例如從整數(shù)到浮點的轉(zhuǎn)換。由于這些示例困難,所以一些編譯器不能產(chǎn)生診斷(例如診斷報告、提示、消息、信息),所述診斷識別通過void指針而發(fā)生的潛在字節(jié)順序改變。這些困難會導致運行時問題。為了解決這些問題,本發(fā)明的各種實 施例幫助識別代碼的有問題區(qū)域,其中例如特定字節(jié)順序通過void指針而被拋棄。更具體 地說,本發(fā)明的實施例可以向用戶警告通過void指針的潛在有問題的轉(zhuǎn)換,從而有效地將 特定void與字節(jié)順序區(qū)域相關(guān)聯(lián),所以用戶可以通過代碼修改來解決所述轉(zhuǎn)換。在圖3的塊305中,程序員可以使用代碼(例如工具、編譯器)來將代碼的區(qū)域(例 如數(shù)據(jù)結(jié)構(gòu))標記為小或大字節(jié)序。如在此所解釋的那樣,一些區(qū)域由于它們與網(wǎng)絡分組等 等一起使用而可以被指定為例如大字節(jié)序。編譯器還可以識別出存在void指針。在塊310 中,可以識別字節(jié)序格式。在塊315中,如果void指針位于已經(jīng)被標記為大字節(jié)序的代碼 段中,則編譯器可以在內(nèi)部創(chuàng)建“大字節(jié)序void”。在塊320中,如果void指針位于指定為 小字節(jié)序的代碼部分,則編譯器可以創(chuàng)建“小字節(jié)序void”。盡管標準void類型可以匹配 任何語言類型,但是特定于字節(jié)順序的void (例如“大字節(jié)序void”或“小字節(jié)序void”) 可能僅匹配例如具有相同字節(jié)順序的數(shù)據(jù)(例如非聚合數(shù)據(jù))和在相同缺省字節(jié)順序的上 下文中聲明的(即定義的)數(shù)據(jù)(例如聚合數(shù)據(jù))。因此,在塊325中,確定不匹配的存在。在 塊330中,如果不存在不匹配,則可以允許匹配。然而,在塊335中,當存在不匹配時,編譯 器可以發(fā)布報告該不匹配的診斷(除非診斷被禁用)。例如,如果標準void指針從大字節(jié)序 值指向小字節(jié)序值,則通常不會引起問題,這是因為void指針是指向具有未知類型(并且 因此也具有未確定的長度和未確定的解引用特性)的值的指針。然而,與“大字節(jié)序void” 的如此嘗試的匹配可以在診斷中被記錄(塊340),并且引起程序員的注意,其中他或她可以 在塊345中解決該問題。對void類型名稱(例如大字節(jié)序void)的使用具有隱式地或顯式地(參見塊305) 分配給代碼區(qū)域的缺省字節(jié)順序的字節(jié)順序?qū)傩?。typedef可以被用來基于相應缺省字節(jié) 順序的typedef來創(chuàng)建大和小字節(jié)序void的void名稱類型。本發(fā)明的一些實施例涉及不同類型的void指針。具體而言,為了支持源轉(zhuǎn)換成為 字節(jié)順序中性的,可以創(chuàng)建void類型的族,對于其而言,數(shù)據(jù)的大小由附于void名稱的數(shù) 據(jù)的比特大小來捕獲,例如“void32”或“void64”。按照類似于關(guān)于方法300所解釋的方 式,這些類型匹配相同比特大小的類型。源代碼可以被修改以使用這些名稱,并且然后編譯 器將實施大小約束。因此,在本發(fā)明的一些實施例中,當編譯器執(zhí)行指針轉(zhuǎn)換時,它可以在出現(xiàn)幾種情 形中的任一種時確定并發(fā)布診斷。例如,當顯式地或隱式地從不同的字節(jié)排序類型轉(zhuǎn)換為 void指針(例如經(jīng)由void指針從大字節(jié)序值轉(zhuǎn)換到小字節(jié)序值)時,可以產(chǎn)生診斷?!帮@式”
轉(zhuǎn)換可以發(fā)生,其中例如程序員顯式地編寫轉(zhuǎn)換表達式,例如
{
int beint;
void *p = (void*)&beint; //從大字節(jié)序整數(shù)指針轉(zhuǎn)換到
void指針
}
“隱式”轉(zhuǎn)換是類似的,但是可能如下不包括轉(zhuǎn)換表達式
{void *p = &beint; Il從大字節(jié)序整數(shù)指針轉(zhuǎn)換到void指
針
}對于顯式轉(zhuǎn)換,編譯器可以產(chǎn)生更少的診斷,因為轉(zhuǎn)換向編譯器指示程序員的動作很 可能是有意的。然而,通過void指針轉(zhuǎn)換,字節(jié)順序可能丟失,因此,在本發(fā)明的一個實施 例中,可以產(chǎn)生診斷而不管該轉(zhuǎn)換的顯式性質(zhì)。因此可以在幾種情形中產(chǎn)生診斷(例如報告)。例如,在以下情形中可以發(fā)布報告 當(i)顯式地或隱式地從void指針轉(zhuǎn)換到不同的字節(jié)排序類型時;當(ii)顯式地或隱式 地從不同的字節(jié)排序類型轉(zhuǎn)換到void指針時;當(iii)隱式地從void指針轉(zhuǎn)換到具有不 同字節(jié)順序的另一 void指針時;以及當(iv)顯式地或隱式地從或向void大小指針進行轉(zhuǎn) 換時,其中基本類型具有不同大小(例如經(jīng)由void指針從32位值轉(zhuǎn)換到64位值)。實施例可以在許多不同的系統(tǒng)類型中被實施。現(xiàn)在參考圖4,示出了根據(jù)本發(fā)明實 施例的系統(tǒng)的框圖。多處理器系統(tǒng)500是點到點互連系統(tǒng),并且包括經(jīng)由點到點互連550 而耦合的第一處理器570和第二處理器580。處理器570和580中的每一個可以是多核處 理器,其包括第一和第二處理器核(即處理器核574a和574b以及處理器核584a和584b), 不過在處理器中可能存在更多的核。術(shù)語“處理器”可以是指處理來自寄存器和/或存儲 器的電子數(shù)據(jù)以將該電子數(shù)據(jù)變換成可以存儲在寄存器和/或存儲器中的其他電子數(shù)據(jù) 的任何設備或設備的一部分。第一處理器570進一步包括存儲控制器集線器(MCH)572和點到點(P_P)接口 576 和578。類似地,第二處理器580包括MCH 582和P-P接口 586和588。MCH 572和582將 處理器耦合到相應的存儲器,即存儲器532和存儲器534,其可以是本地地附于相應處理器 的主存儲器(例如動態(tài)隨機存取存儲器(DRAM))的部分。第一處理器570和第二處理器580 可以分別經(jīng)由P-P互連552和554被耦合到芯片組590。芯片組590包括P-P接口 594和 598。此外,芯片組590包括接口 592以通過P-P互連539將芯片組590與高性能圖形 引擎538耦合。繼而,芯片組590可以經(jīng)由接口 596被耦合到第一總線516。各種輸入/輸 出(1/0)設備514連同總線橋518 —起可以被耦合到第一總線516,所述總線橋518將第一 總線516耦合到第二總線520。各種設備可以被耦合到第二總線520,所述各種設備包括例 如鍵盤/鼠標522、通信設備526、以及數(shù)據(jù)存儲單元528 (例如盤驅(qū)動器或其他大容量存儲 設備),在一個實施例中數(shù)據(jù)存儲單元528可以包括代碼530。此外,音頻1/0 524可以被耦 合到第二總線520。實施例可以以代碼來實施并且可以被存儲在存儲介質(zhì)上,所述存儲介質(zhì)在其上存 儲有指令,所述指令能夠被用來對系統(tǒng)進行編程以執(zhí)行所述指令。所述存儲介質(zhì)可以包 括但不限于任何類型的盤(包括軟盤、光盤、固態(tài)驅(qū)動器(SSD)、光盤只讀存儲器(⑶-ROM)、 可重寫光盤(⑶_RW)、以及磁光盤),半導體器件(例如只讀存儲器(ROM)),隨機存取存儲器 (RAM)(例如動態(tài)隨機存取存儲器(DRAM)、靜態(tài)隨機存取存儲器(SRAM)、可擦除可編程只讀 存儲器(EPR0M)、閃速存儲器、電可擦除可編程只讀存儲器(EEPR0M)),磁或光卡,或適合于 存儲電子指令的任何其他類型的介質(zhì)。在此已參考諸如指令、函數(shù)、過程、數(shù)據(jù)結(jié)構(gòu)、應用程序、配置設置、代碼等之類的數(shù)據(jù)描述了本發(fā)明的實施例。當數(shù)據(jù)被機器訪問時,該機器可以通過執(zhí)行任務、定義抽象 數(shù)據(jù)類型、建立低級硬件上下文、和/或執(zhí)行其他操作來進行響應,如在此更詳細描述的那 樣。數(shù)據(jù)可以被存儲在易失性和/或非易失性的數(shù)據(jù)存儲裝置中。為了本公開的目的,術(shù) 語“代碼”或“程序”涵蓋了大范圍的組件和構(gòu)造,其包括應用程序、驅(qū)動器、過程、例程、方 法、模塊、以及子程序。因此,術(shù)語“代碼”或“程序”可以被用來指代在被處理系統(tǒng)執(zhí)行時 執(zhí)行(一個或多個)期望操作的指令的任何集合。另外,可替換的實施例可以包括使用少于 所有所公開操作的過程、使用附加操作的過程、以不同序列使用相同操作的過程、以及其中 在此所公開的各個操作被組合、細分或以其他方式改變的過程。在此常常關(guān)于字節(jié)交換指 令討論了字節(jié)序轉(zhuǎn)換,但是各種實施例不一定限于采用任何特定類型的指令來執(zhí)行或促進 字節(jié)序轉(zhuǎn)換。
盡管已經(jīng)相對于有限數(shù)目的實施例描述了本發(fā)明,但是本領域技術(shù)人員將由其認 識到許多修改和變化。所附權(quán)利要求打算覆蓋落入本發(fā)明的真實精神和范圍內(nèi)的所有這樣 的修改和變化。
權(quán)利要求
1.一種方法,包括接收分別定義全局變量的第一和第二實例的第一和第二源代碼部分,其中每個實例具 有第一字節(jié)序格式并且這兩個實例在編譯時間都不能被完全地初始化;生成對字節(jié)交換指令的第一和第二引用,其被配置成分別將所述第一和第二實例轉(zhuǎn)換 成第二字節(jié)序格式;使用處理器來生成影子變量,所述影子變量被配置成在編譯時間之后并且基于所述第 一實例已經(jīng)被字節(jié)交換來抑制所述第二實例的字節(jié)交換;以及 將所述影子變量存儲在耦合到所述處理器的存儲器中。
2.如權(quán)利要求1所述的方法,其中,基于所述全局變量是具有所述第一字節(jié)序格式的 指針,這兩個實例在編譯時間都不能被完全地初始化。
3.如權(quán)利要求2所述的方法,其中,所述影子變量被配置成指示所述第一實例是否被 字節(jié)交換。
4.如權(quán)利要求2所述的方法,其中,所述影子變量被配置成基于所述影子變量已經(jīng)從 弱定義的變量被轉(zhuǎn)換成強定義的變量來抑制所述第二實例的字節(jié)交換。
5.如權(quán)利要求2所述的方法,包括生成具有第一和第二字節(jié)序格式這二者的經(jīng)編譯 代碼。
6.如權(quán)利要求2所述的方法,包括生成保護變量,所述保護變量被配置成確定,在運 行時和在所述保護變量的初始化之后,所述保護變量已經(jīng)被字節(jié)轉(zhuǎn)換,其中所述保護變量 將利用已知的鏈接時間常量來被初始化。
7.如權(quán)利要求2所述的方法,其中,所述第一和第二實例被配置成在編譯時間之后分 別基于每一個都具有所述第一字節(jié)序格式的第一和第二鏈接時間常量來被初始化。
8.如權(quán)利要求1所述的方法,包括接收包括void指針的第三源代碼部分; 追蹤通過所述void指針的字節(jié)順序;以及 確定基于所述void指針所發(fā)生的字節(jié)順序不匹配。
9.如權(quán)利要求1所述的方法,包括接收包括void指針的第三源代碼部分; 追蹤通過所述void指針的數(shù)據(jù)大?。灰约?確定基于所述void指針所發(fā)生的數(shù)據(jù)大小不匹配。
10.一種包括介質(zhì)的物品,存儲用于使基于處理器的系統(tǒng)能夠執(zhí)行以下操作的指令 接收分別定義全局變量的第一和第二實例的第一和第二代碼部分,其中所述全局變量的每個實例具有第一字節(jié)序格式并且這兩個實例在編譯時間都不能被正確地初始化;以及 生成第一變量,所述第一變量被配置成在編譯時間之后并且基于所述第一實例已經(jīng)被 字節(jié)序轉(zhuǎn)換來抑制所述第二實例的字節(jié)序轉(zhuǎn)換。
11.如權(quán)利要求10所述的物品,其中,所述全局變量是指針。
12.如權(quán)利要求11所述的物品,進一步存儲用于使所述系統(tǒng)能夠基于從編譯器生成 的信息來重定位所述第一變量的指令,其中所述第一變量被配置成基于所述重定位來抑制 所述第二實例的字節(jié)序轉(zhuǎn)換。
13.如權(quán)利要求11所述的物品,其中,所述第一實例基于第二全局變量的地址。
14.如權(quán)利要求11所述的物品,其中,所述第一和第二代碼部分被配置成被動態(tài)地鏈接。
15.如權(quán)利要求10所述的物品,進一步存儲用于使所述系統(tǒng)能夠執(zhí)行以下操作的指令接收包括void指針的第三代碼部分; 追蹤通過所述void指針的字節(jié)順序;以及 確定基于所述void指針所發(fā)生的字節(jié)順序不匹配。
16.一種裝置,包括耦合到存儲器的處理器,其執(zhí)行以下操作(1)使用所述存儲器接收分別定義全局變 量的第一和第二實例的第一和第二源代碼部分,其中所述全局變量的每個實例具有第一字 節(jié)序格式并且這兩個實例在編譯時間都不能被完全地初始化;以及(2)生成第一變量,所 述第一變量被配置成在編譯時間之后并且基于所述第一實例已經(jīng)被字節(jié)交換來抑制所述 第二實例的字節(jié)交換。
17.如權(quán)利要求15所述的裝置,其中,所述全局變量是指針。
18.如權(quán)利要求17所述的裝置,其中,所述第一變量被配置成基于所述第一變量已經(jīng) 從弱定義的變量被轉(zhuǎn)換成強定義的變量來抑制所述第二實例的字節(jié)交換。
19.如權(quán)利要求17所述的裝置,其中,所述第一和第二代碼部分被配置成被動態(tài)地鏈接。
20.如權(quán)利要求15所述的裝置,其中,所述處理器執(zhí)行以下操作 接收包括void指針的第三源代碼部分;追蹤通過所述void指針的字節(jié)順序;以及 確定基于所述void指針所發(fā)生的字節(jié)順序不匹配。
全文摘要
本發(fā)明公開了字節(jié)序轉(zhuǎn)換工具。在本發(fā)明的一個實施例中,代碼(例如編譯器、工具)可以生成信息,因此包括第一字節(jié)序格式(例如大字節(jié)序)的指針值的第一代碼部分能夠被適當?shù)爻跏蓟?,并且在具有第二字?jié)序格式(例如小字節(jié)序)的平臺上被執(zhí)行。而且,本發(fā)明的各種實施例可以識別代碼(例如源代碼)的有問題區(qū)域,其中特定字節(jié)順序通過void指針而被拋棄。
文檔編號G06F9/30GK102103481SQ20101059805
公開日2011年6月22日 申請日期2010年12月21日 優(yōu)先權(quán)日2009年12月21日
發(fā)明者V. 布雷夫諾夫 E., 威爾金森 H., J. 多梅卡 M., P. 賴斯 M., 拉赫納 P. 申請人:英特爾公司