使用.init_array节的分段错误

时间:2019-07-10 19:02:40

标签: c elf

我正在学习 ELF 并遇到了奇怪的段错误

代码:

.roi

使用#include <stdio.h> #include <stdint.h> __attribute__((constructor(102))) static void init1() { printf("%s\n", __FUNCTION__); } __attribute__((constructor(101))) static void init2() { printf("%s\n", __FUNCTION__); } void another_init1() { printf("%s\n", __FUNCTION__); } void another_init2() { printf("%s\n", __FUNCTION__); } typedef void (*init)(); __attribute__((section(".init_array"))) init init_arr[2] = {another_init1, another_init2}; static void my_function_1() {} int main() { printf("hello world\n"); return 0; } 编译并运行gcc -o hello hello.c,我看到

./hello

这来自 .init_arr 。如果我使该数组包含单个函数ptr,那么一切都会按预期运行,但是其中有2个ptrs,则会出现段错误。

有什么建议吗?只是发现这个奇怪的

VK

1 个答案:

答案 0 :(得分:2)

init_array应该与指针的大小对齐;如果您将其更改为:

__attribute__((section(".init_array"), aligned(sizeof (void*)))) init init_arr[2] = {another_init1, another_init2};

它将起作用。

如果不这样做(至少在x86-64上),gcc将使数组对齐16个字节的边界,从而在.init_array部分中已经存在的3个函数指针之间创建8个字节的间隙({ {1}} +您的frame_dummyinit1)和2个新函数,它们在动态链接器中将作为init2指针出现。