了解__libc_init_array [英] understanding the __libc_init_array

查看:1036
本文介绍了了解__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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆