Ошибка сегментации с использованием раздела .init_array - PullRequest
0 голосов
/ 10 июля 2019

Я учусь ELF и столкнулся со странной ошибкой сегмента

code:

#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 Я вижу

[root@20f890034489 ch5]# ./hello 
init2
init1
Segmentation fault

это исходит от .init_arr .Если я сделаю, чтобы этот массив содержал одну функцию ptr, все работает как положено, но с 2 ptrs там происходит сбой.

Любое предложение?Просто найдите это странное

VK

1 Ответ

2 голосов
/ 10 июля 2019

init_array должен быть выровнен по размеру указателя;если вы измените это значение на

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

, оно будет работать.

Если нет (по крайней мере, на x86-64), gcc выровняет ваш массив по границе 16 байтов, создаваяРазрыв в 8 байтов в секции .init_array между 3 указателями функций, которые уже существуют (frame_dummy + ваши init1 и init2), и двумя новыми функциями, которые будут отображаться для динамического компоновщика в виде указателя NULL.

...