Какая польза от локальных символов в таблице символов объектного файла?

avatar
dnjsdnwja
1 июля 2021 в 15:58
231
1
0

Из вопроса (Скрытие имен символов в библиотеке) я подумал, что статические функции удаляются из таблицы символов объектного файла при компиляции с оптимизацией (возможно, потому, что компиляторы предполагают, что это релизная сборка). Ниже приведен слегка измененный исходный код (Скрытие имен символов в библиотеке) и таблица символов скомпилированного объектного файла.

// compile with gcc -c -O2 -o file.o file.c

extern int a();
extern int b();

static int f_b1(){
return a();
}

static int f_b3(){
return b();
}
test.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 test.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 l    d  .bss   0000000000000000 .bss
0000000000000000 l    d  .note.GNU-stack        0000000000000000 .note.GNU-stack
0000000000000000 l    d  .comment       0000000000000000 .comment

Однако кажется, что такое исчезновение было вызвано тем, что обе f_b1 и f_b3 не использовались. Очевидно, что если они вызываются нестатической функцией, как показано ниже, их символы снова появляются в таблице символов (т.е. objdump -t file.o).

extern int a();
extern int b();

static int __attribute__ ((noinline)) f_b1(){
return a();
}

static int __attribute__ ((noinline)) f_b2(){
return b();
}

void f_b3(){
    f_b1();
    f_b2();
}
SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 test.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 l    d  .bss   0000000000000000 .bss
0000000000000000 l     F .text  0000000000000007 f_b1
0000000000000010 l     F .text  0000000000000007 f_b2
0000000000000000 l    d  .note.GNU-stack        0000000000000000 .note.GNU-stack
0000000000000000 l    d  .eh_frame      0000000000000000 .eh_frame
0000000000000000 l    d  .comment       0000000000000000 .comment
0000000000000000         *UND*  0000000000000000 _GLOBAL_OFFSET_TABLE_
0000000000000000         *UND*  0000000000000000 a
0000000000000000         *UND*  0000000000000000 b
0000000000000020 g     F .text  0000000000000013 f_b3

Таким образом, кажется, что по умолчанию компилятор выдает символы статических функций в таблицу символов даже при оптимизации. Тогда какая польза от таких местных символов? Они действительно нужны на этапе связывания (не понимаю, зачем они нужны, ведь вызов и прыжок выполняются относительно eip, не так ли?)?

Источник
Steve Summit
1 июля 2021 в 16:04
1

Статические символы могут быть очень полезны при отладке.

dnjsdnwja
1 июля 2021 в 16:11
0

Да, я знаю об этом. Однако мне интересно, единственная ли это причина, по которой компилятор это выдает.

Ответы (1)

avatar
Employed Russian
12 июля 2021 в 14:46
1

Действительно ли они необходимы на этапе связывания

№. Они нужны только для отладки.

Вы можете подтвердить это, используя objcopy --strip-unneeded test.o test1.o -- символы будут удалены, но вы все равно сможете связать test1.o с окончательным двоичным файлом так же, как вы могли бы с помощью test.o.