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