如果我定义了

__attribute__((constructor)) static void myfunc(void) {}

,则myfunc的地址将附加到__init_array_start部分的.ctors中。但我如何才能将函数指针附加到__preinit_array_start
在静态链接的二进制文件中__preinit_array_start是否相关?

最佳答案

由于没有__attribute__((preconstructor)),您只需使用一些节属性(如。

#include <stdio.h>

int v;
int w;
int x;

__attribute__((constructor)) static void
foo(void)
{
    printf("Foo %d %d %d\n", v, w, x);
}

static void
bar(void)
{
    v = 3;
}

static void
bar1(void)
{
    w = 2;
}

static void
bar2(void)
{
    x = 1;
}

__attribute__((section(".preinit_array"))) static void (*y[])(void) = { &bar, &bar1, &bar2 };

int
main(int argc, char **argv)
{
    printf("Hello World\n");
}

文件转储到foo.c,使用:gcc -o foo foo.c编译,然后运行将生成以下输出:
Foo 3 2 1
Hello World

使用gcc -static -o foo foo.c编译然后运行的文件会产生相同的输出,因此它看起来确实可以处理静态链接的二进制文件。
不过,它不能处理.so文件;链接器抱怨:
/usr/bin/ld: /tmp/ccI0lMgd.o: .preinit_array section is not allowed in DSO
/usr/bin/ld: failed to set dynamic section sizes: Nonrepresentable section on output

我倾向于避免它,因为在该部分中运行的代码先于所有其他初始化例程。如果你试图执行一些“这应该先运行”初始化,那么这真的不是一个好主意-你只是在与一个应该由其他机制解决的竞赛条件作斗争。

07-24 09:44
查看更多