2013-03-07 10 views
4

我從http://newlib.sourcearchive.com/documentation/1.18.0/init_8c-source.html查看了__libc_init_array的源代碼。
但我不太明白這個功能的作用。瞭解__libc_init_array

我知道這些符號

/* These magic symbols are provided by the linker. */ 
extern void (*__preinit_array_start []) (void) __attribute__((weak)); 
extern void (*__preinit_array_end []) (void) __attribute__((weak)); 
extern void (*__init_array_start []) (void) __attribute__((weak)); 
extern void (*__init_array_end []) (void) __attribute__((weak)); 
extern void (*__fini_array_start []) (void) __attribute__((weak)); 
extern void (*__fini_array_end []) (void) __attribute__((weak)); 

在鏈接描述文件中定義。鏈接腳本的
部分可能看起來像:

.preinit_array  : 
    { 
    PROVIDE_HIDDEN (__preinit_array_start = .); 
    KEEP (*(.preinit_array*)) 
    PROVIDE_HIDDEN (__preinit_array_end = .); 
    } >FLASH 
    .init_array : 
    { 
    PROVIDE_HIDDEN (__init_array_start = .); 
    KEEP (*(SORT(.init_array.*))) 
    KEEP (*(.init_array*)) 
    PROVIDE_HIDDEN (__init_array_end = .); 
    } >FLASH 
    ... 

,然後我搜索與ELF-V1.1,GCC 4.7.2,LD和CodeSourcery的的文檔的關鍵 「init_array」(我'使用codesourcery g ++ lite)只能得不到任何東西。

我在哪裏可以找到這些符號的規格?

回答

3

這些特殊符號最終會被生成庫的PT_DYNAMIC部分引用。 PT_DYNAMIC定義了動態鏈接成功所需的各種資源(庫依賴項,導出的符號,符號哈希表,init/fini數組等)。

因此,這些列表中的任何函數最終都會鏈接到PT_DYNAMIC部分,並在動態鏈接過程中的適當時間進行調用。您可能需要諮詢ldd的來源以瞭解更多信息。

+0

感謝您的回覆。我只是谷歌編輯它。 .init_array部分是由System V ABI指定的特殊部分,我想它是由gcc自動生成的。 – Pony279 2013-03-07 08:46:43

9

這些符號與在main()之前/之後調用的C/C++構造函數和析構函數啓動和拆卸代碼有關。名爲.init,.ctors,.preinit_array.init_array的部分用於初始化C/C++對象,並且部分.fini,.fini_array.dtors用於拆卸。開始和結束符號定義與這些操作相關的代碼段的開始和結束,並且可以從運行時支持代碼的其他部分引用。

.preinit_array.init_array部分包含指向將在初始化時調用的函數的指針數組。 .fini_array是將在銷燬時調用的一組函數。推測起始和結束標籤被用於走這些列表。

使用這些符號的代碼的一個很好的例子是libc sourceinitfini.c。您可以看到在啓動時調用了__libc_init_array(),並且通過引用開始和結束標籤,首先調用了部分.preinit_array中的所有函數指針。然後它調用.init部分中的_init()函數。最後它調用.init_array中的所有函數指針。在main()完成之後,拆除撥打__libc_fini_array()會導致調用.fini_array中的所有功能,最後纔會調用_fini()。請注意,在計算要在拆解時調用的函數的計數時,此代碼中似乎存在剪切和粘貼錯誤。據推測他們正在處理一個實時的微控制器操作系統,從未遇到過這一節。

0

這些對象的規格是elf頭文件格式的規格。至少他們爲什麼在那裏。

他們是不是使任何形式的工作形式的手段或形式,除非你打算重寫glic lib和它談的一切。簡而言之,精靈標題需要一個_start函數。它不會啓動沒有一個的二進制文件。

很大一部分libc庫是用匯編語言編寫的,而不是C語言,它不考慮這個問題。 pre數組函數是添加此標頭的一種方式。

查覈在的glibc蠅頭-efl.git的例子GNU-CSU文件夾。它還將數組設置爲斜槓格式的字符串。將這兩個元素設置爲static,argv中的數組和init_array。它稍後會檢查以確保它們匹配。它也需要更多的代碼,而不是你應該添加到這種功能來打破這個過程,或者做任何事情,而不是它的意思。和你的冰箱一起玩吧。