了解__libc_init_array [英] understanding the __libc_init_array
问题描述
我从 http:// newlib查看了__libc_init_array的源代码。 sourcearchive.com/documentation/1.18.0/init_8c-source.html 。
但我不太明白这个函数的作用。
我知道这些符号
/ *这些魔法符号是由链接器提供。 * /
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(我正在使用codesourcery g ++ lite)文档中关键的init_array只是为了什么都得不到。
在哪里可以找到这些符号的规格?
这些符号与在 main()
之前/之后调用的C / C ++构造函数和析构函数启动和拆卸代码有关。名为 .init
, .ctors
, .preinit_array
的部分,和 .init_array
用于初始化C / C ++对象,以及 .fini
, .fini_array
和 .dtors
用于拆卸。开始和结束符号定义与此类操作相关的代码段的开始和结束,并可能从运行时支持代码的其他部分引用。
.preinit_array
和 .init_array
部分包含指向将在初始化时调用的函数的指针数组。 .fini_array
是一个将在销毁时调用的函数数组。假设开始和结束标签用于遍历这些列表。
使用这些符号的代码的一个很好的例子可以在这里找到 libc源代码 initfini.c
。您可以看到在启动时调用了 __ libc_init_array()
,它首先调用 .preinit_array
部分中的所有函数指针,通过参考开始和结束标签。然后它调用 .init
部分中的 _init()
函数。最后,它调用 .init_array
部分中的所有函数指针。在 main()
完成后,对 __ libc_fini_array()
的拆卸调用将导致 .fini_array
,最后调用 _fini()
。请注意,在计算要在拆解时调用的函数的计数时,此代码中似乎存在剪切和粘贴错误。据推测他们正在处理一个实时微控制器操作系统,从未遇到过这一节。
I viewed the source code of __libc_init_array from http://newlib.sourcearchive.com/documentation/1.18.0/init_8c-source.html .
But I don't quite understand what this function does.
I know that these symbols
/* 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));
is defined in the linker script.
Part of the linker script may look like:
.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
...
and then I searched with the key "init_array" in the docs of ELF-v1.1, gcc 4.7.2, ld, and codesourcery(I'm using codesourcery g++ lite) only to get nothing.
Where can I find the specification of these symbols?
These symbols are related to the C / C++ constructor and destructor startup and tear down code that is called before / after main()
. Sections named .init
, .ctors
, .preinit_array
, and .init_array
are to do with initialization of C/C++ objects, and sections .fini
, .fini_array
, and .dtors
are for tear down. The start and end symbols define the beginning and end of code sections related to such operations and might be referenced from other parts of the runtime support code.
The .preinit_array
and .init_array
sections contain arrays of pointers to functions that will be called on initialization. The .fini_array
is an array of functions that will be called on destruction. Presumably the start and end labels are used to walk these lists.
A good example of code that uses these symbols is to be found here libc source for initfini.c
. You can see that on startup, __libc_init_array()
is called and this first calls all the function pointers in section .preinit_array
by referring to the start and end labels. Then it calls the _init()
function in the .init
section. Lastly it calls all the function pointers in section .init_array
. After main()
is complete the teardown call to __libc_fini_array()
causes all the functions in .fini_array
to be called, before finally calling _fini()
. Note that there seems to be a cut-and-paste bug in this code when it calculates the count of functions to call at teardown. Presumably they were dealing with a real time micro controller OS and never encountered this section.
这篇关于了解__libc_init_array的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!