在调用__libc_init_array之前,哪些操作不安全?

时间:2017-01-02 12:31:25

标签: libc

我希望在main开始之前运行一些代码,然后运行静态变量的构造函数。我可以使用代码like this (ideone)

extern "C" {
    static void do_my_pre_init(void) {
        // something
    }
    __attribute__ ((section (".preinit_array"))) void(*p_init)(void) = &do_my_pre_init;
}

由于_init.init_array尚未执行,是否有任何语言功能在此功能中执行时无效?

或者只是用户代码应该挂钩到这个机制?

__libc_init_array

的一些背景知识

typical __libc_init_array的来源类似于:

static void __libc_init_array() {
    size_t count, i;

    count = __preinit_array_end - __preinit_array_start;
    for (i = 0; i < count; i++)
        __preinit_array_start[i]();

    _init();

    count = __init_array_end - __init_array_start;
    for (i = 0; i < count; i++)
        __init_array_start[i]();
}

__...符号来自包含

的链接描述文件
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;

. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;

1 个答案:

答案 0 :(得分:1)

  

由于_init和.init_array尚未执行,是否有任何语言功能在此功能中执行时无效?

这个问题不可能回答一般,因为语言本身没有.preinit_array_init.init_array的概念。所有这些概念都是特定系统的实现详细信息。

实际上,您并不能确保任何工作。像malloc这样简单的事情可能无效(例如,因为malloc子系统本身可能正在使用.preinit_array来初始化自己)。

实际上,在基于GLIBC的平台上使用动态链接,大多数都可以工作(因为libc.so.6在主可执行文件的第一条指令运行之前很久就会初始化。)

对于全静态可执行文件,所有投注均已关闭。

对于非GLIBC平台,您需要查看该平台的具体内容(并且您不太可能找到任何保证)。

更新

  

我可以进行函数调用吗,

函数调用不需要使用全静态链接进行设置,并且需要动态加载器在动态链接情况下进行初始化。

表示,动态加载器在完全初始化之前不会在应用程序中开始执行代码,因此函数调用应该是安全的。

  

指定结构

C中,充其量只是一些说明。最糟糕的是,这是对memcpymemset的调用。这应该是安全的。

  

使用数组初始值设定项。

这只是结构分配的一个特例,所以应该是安全的。