我正在学习链接,遇到一个问题。
如果我有一个源文件main.c:
int main()
{
return 0;
}
我用静态链接编译它:
gcc -static -o a.out main.c
然后我发现可执行文件中有像.got这样与动态链接相关的节,其大小大于0:
readelf -S a.out
输出:
There are 33 section headers, starting at offset 0xa4e04:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .note.ABI-tag NOTE 080480f4 0000f4 000020 00 A 0 0 4
[ 2] .note.gnu.build-i NOTE 08048114 000114 000024 00 A 0 0 4
[ 3] .rel.plt REL 08048138 000138 000088 08 A 0 5 4
[ 4] .init PROGBITS 080481c0 0001c0 00002e 00 AX 0 0 4
[ 5] .plt PROGBITS 080481f0 0001f0 000110 00 AX 0 0 16
[ 6] .text PROGBITS 08048300 000300 07ab7c 00 AX 0 0 16
[ 7] __libc_thread_fre PROGBITS 080c2e80 07ae80 000076 00 AX 0 0 16
[ 8] __libc_freeres_fn PROGBITS 080c2f00 07af00 000b2f 00 AX 0 0 16
[ 9] .fini PROGBITS 080c3a30 07ba30 00001a 00 AX 0 0 4
[10] .rodata PROGBITS 080c3a60 07ba60 019394 00 A 0 0 32
[11] __libc_thread_sub PROGBITS 080dcdf4 094df4 000004 00 A 0 0 4
[12] __libc_subfreeres PROGBITS 080dcdf8 094df8 00002c 00 A 0 0 4
[13] __libc_atexit PROGBITS 080dce24 094e24 000004 00 A 0 0 4
[14] .eh_frame PROGBITS 080dce28 094e28 00e308 00 A 0 0 4
[15] .gcc_except_table PROGBITS 080eb130 0a3130 000179 00 A 0 0 1
[16] .tdata PROGBITS 080ecf90 0a3f90 000010 00 WAT 0 0 4
[17] .tbss NOBITS 080ecfa0 0a3fa0 000018 00 WAT 0 0 4
[18] .init_array INIT_ARRAY 080ecfa0 0a3fa0 000004 00 WA 0 0 4
[19] .fini_array FINI_ARRAY 080ecfa4 0a3fa4 000004 00 WA 0 0 4
[20] .ctors PROGBITS 080ecfa8 0a3fa8 000008 00 WA 0 0 4
[21] .dtors PROGBITS 080ecfb0 0a3fb0 000008 00 WA 0 0 4
[22] .jcr PROGBITS 080ecfb8 0a3fb8 000004 00 WA 0 0 4
[23] .data.rel.ro PROGBITS 080ecfbc 0a3fbc 000030 00 WA 0 0 4
[24] .got PROGBITS 080ecfec 0a3fec 000008 04 WA 0 0 4
[25] .got.plt PROGBITS 080ecff4 0a3ff4 000050 04 WA 0 0 4
[26] .data PROGBITS 080ed060 0a4060 000c20 00 WA 0 0 32
[27] .bss NOBITS 080edc80 0a4c80 0016d4 00 WA 0 0 32
[28] __libc_freeres_pt NOBITS 080ef354 0a4c80 000018 00 WA 0 0 4
[29] .comment PROGBITS 00000000 0a4c80 00002a 01 MS 0 0 1
[30] .shstrtab STRTAB 00000000 0a4caa 00015a 00 0 0 1
[31] .symtab SYMTAB 00000000 0a532c 0086e0 10 32 957 4
[32] .strtab STRTAB 00000000 0ada0c 007aed 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
为什么?
根据 Linux 静态链接已死? 及其答案,
-static
标志实际上并没有创建静态链接的可执行文件,因为 C 库本身使用动态链接。 因此,与动态链接相关的部分会在可执行文件中发出。