pts*_*pts 3 c linux gcc initialization
如果我定义的话,在带有 GCC 的 Linux 上
__attribute__((constructor)) static void myfunc(void) {}
Run Code Online (Sandbox Code Playgroud)
,那么 的地址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");
}
Run Code Online (Sandbox Code Playgroud)
文件转储到foo.c
,使用: 进行编译gcc -o foo foo.c
,然后运行会产生以下输出:
Foo 3 2 1
Hello World
Run Code Online (Sandbox Code Playgroud)
使用 编译的文件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
Run Code Online (Sandbox Code Playgroud)
我倾向于避免它,因为该部分中的代码运行先于所有其他初始化例程。如果您尝试执行一些“这应该首先运行”初始化,那么这确实不是一个好主意 - 您只是在与应该通过其他机制解决的竞争条件作斗争。