Из вопроса (Скрытие имен символов в библиотеке) я подумал, что статические функции удалены из таблица символов объектного файла при компиляции с оптимизацией (возможно, потому, что компиляторы предполагают, что это сборка выпуска). Ниже приведен слегка измененный исходный код из (Скрытие имен символов в библиотеке) и таблица символов скомпилированного объектного файла.
// 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, не так ли?)?