工具介面標準(TIS)可執行連結格式(ELF)規範-卷III-作業系統特性-程式載入和動態連結(五)
阿新 • • 發佈:2019-02-01
本文是對Tool Interface Standard (TIS) Executable and Linking Format (ELF) Specification Version 1.2的翻譯
工具介面標準(TIS)可執行連結格式(ELF)規範版本 1.2
翻譯以中英對照方式,英語水平有限,如有翻譯不當的地方,請諒解。
Hash Table
雜湊表
A hash table of Elf32_Word objects supports symbol table access. Labels appear below to help explain the hash table organization, but they are not part of the specification.
一個Elf32_Word物件的雜湊表支援符號表訪問。下面出現的標籤幫助解釋了雜湊表的組織,但是它們不是標準的一部分。
Figure2-8. Symbol Hash Table
圖2-8.符號雜湊表
nbucket |
nchain |
bucket[0] . . . bucket[nbucket-1] |
chain[0] . . . chain[nchain-1] |
The bucket array contains nbucket entries, and the chain array contains nchain entries; indexes start at 0. Both bucket and chain hold symbol table indexes. Chain table entries parallel the symbol table. The number of symbol table entries should equal nchain; so symbol table indexes also select chain table entries. A hashing function (shown below) accepts a symbol name and returns a value that may be used to computea bucket index. Consequently, if the hashing function returns the value x for some name, bucket[x%nbucket] gives an index, y, into both the symbol table and the chain table. If the symbol table entry is not the one desired, chain[y] gives the next symbol table entry with the same hash value. One can follow the chain links until either the selected symbol table entry holds the desired name or the chain entry contains the value STN_UNDEF.
bucket陣列包含nbucket個條目,chain陣列包含nchain個條目;索引從0開始。bucket和chain包含符號表索引。chain表條目並行化符號表。符號表條目的個數應該等於nchain;所以符號表索引也可以選擇chain表條目。一個雜湊函式(下面描述)接受一個符號名並返回一個用於計算bucket索引的值。因此,假如這個雜湊函式對某個名字返回值x,bucket[x%nbucket]給出一個索引y,同時可以用於符號表和chain表。假如符號表條目不是一個需要的符號,chain[y]給出下一個符號表條目。跟隨chain鏈直到選擇的符號表包含期望的名字或chain條目包含名字的值為STN_UNDEF。
Figure 2-9. Hashing Function
圖2-9.雜湊函式
unsigned long elf_hash(const unsigned char *name)
{
unsigned long h = 0, g;
while (*name)
{
h = (h << 4) + *name++;
if (g = h & 0xf0000000)
h ^= g >> 24;
h &= ~g;
}
return h;
}
Initialization and Termination Functions
初始化和結束函式
After the dynamic linker has built the process image and performed the relocations, each shared object gets the opportunity to execute some initialization code. All shared object initializations happen before the executable file gains control.
在動態連結器已經建立程序映像並執行重定位後,每個共享物件獲得執行一些初始化程式碼的機會。所有的共享物件初始化發生在可執行檔案獲取控制前。
Before the initialization code for any object A is called, the initialization code for any other objects that object A depends on are called. For these purposes, an object A depends on another object B, if B appears in A’s list of needed objects (recorded in the DT_NEEDED entries of the dynamic structure). The order of initialization for circular dependencies is undefined.
在任意物件A的初始化程式碼呼叫前,物件A依賴的其他物件的初始化程式碼會被呼叫。為了這些目的,一個物件A依賴於另外的物件B,假如B出現在A的需求物件列表(動態結構中記錄在DT_NEEDED條目中)。初始化環狀依賴的順序未定義。
The initialization of objects occurs by recursing through the needed entries of each object. The initialization code for an object is invoked after the needed entries for that object have been processed. The order of processing among the entries of a particular list of needed objects is unspecified.
物件初始化發生在遞迴遍歷每個物件的依賴入口時。一個物件的初始化程式碼在該物件的依賴入口處理之後被呼叫。詳細的依賴物件列表入口的處理順序未指定。
NOTE. Each processor supplement may optionally further restrict the algorithm used to determine the order of initialization. Any such restriction, however, may not conflict with the rules described by this specification.
注意:每個處理器補充說明可能在將來可選擇性的限制用於決定初始化順序的演算法。然而,任何一個這樣的限制都不會和本規範中描述的規則衝突。
The following example illustrates two of the possible correct orderings which can be generated for the example NEEDED lists. In this example the a.out is dependent on b, d, and e. b is dependent on d and f, while d is dependent on e and g. From this information, a dependency graph can be drawn. The above algorithm on initialization will then allow the following specified initialization orderings among others.
以下例子闡明瞭2個可能的生成例子的依賴列表的正確順序。在此例子中,a.out依賴於b、d和e。b依賴於d和f,同時,d依賴於e和g。從這些資訊,一個依賴圖能夠被畫出來。上面的初始化演算法允許以下的特定初始化順序。
Figure 2-10. Initialization Ordering Example
Similarly, shared objects may have termination functions, which are executed with the at exit(BA_OS) mechanism after the base process begins its termination sequence. The order in which the dynamic linker calls termination functions is the exact reverse order of their corresponding initialization functions. If a shared object has a termination function, but no initialization function, the termination function will execute in the order it would have as if the shared object's initialization function was present. The dynamic linker ensures that it will not execute any initialization or termination functions more than once.
相似的,共享物件可能有終止函式,終止函式隨著退出機制在基礎處理開始它的終止序列後被執行。動態連結器呼叫終止函式的順序是相應初始化函式確切的反向順序。假如一個共享物件有終止函式,如果一個共享物件有終止函式,卻沒有初始化函式,在假設共享物件初始化函式是出現了的情況下,終止函式仍然會以它應該有的順序執行。動態連結器確保不會執行任何的初始化或終止函式超過一次。
Shared objects designate their initialization and termination functions through the DT_INIT and DT_FINI entries in the dynamic structure, described in "Dynamic Section'' above. Typically, the code for these functions resides in the .init and .fini sections, mentioned in "Sections" of Chapter 1.
共享物件通過動態結構中的DT_INIT和DT_FINI入口指派它們的初始化或終止函式,在上面的“動態分節”部分由描述。典型的,這些函式的程式碼位於.init和.fini分節,在章節1的“分節”有提到過。
NOTE. Although the atexit(BA_OS) termination processing normally will be done, it is not guaranteed to have executed upon process death. In particular, the process will not execute the termination processing if it calls _exit[see exit (BA_OS)] or if the process dies because it received a signal that it neither caught nor ignored.
注意:雖然退出時的終止處理一般會被執行。但不保證在程序死亡時被執行。特別的,在通過呼叫_exit或程序由於接收到一個它不會捕獲或忽略的資訊而死亡的情況下,程序不會執行終止處理。
The dynamic linker is not responsible for calling the executable file's .init section or registering the executable file's .fini section with atexit(BA_OS). Termination functions specified by users via the atexit(BA_OS) mechanism must be executed before any termination functions of shared objects.
動態連結器不會負責呼叫可執行檔案的.init分節或註冊可執行檔案的.fini分節。終止函式由使用者經由退出機制指定,必須在任意共享物件終止函式前執行。