'Why are there global offset tables and procedure linkage tables in statically linked executables?
I've done a bunch of reading on dynamic linker relocations and position independent code including procedure linkage tables and global offset tables. I don't understand why a statically linked executable needs a PLT and GOT. I compiled a hello world program on my ubuntu x86_64 machine and when I dump the section headers with readelf -S it shows PLT and GOT sections.
I also created a shared library with a simple increment function that I compiled with gcc -shared without -fpic and I also see PLT and GOT sections. I didn't expect this either.
Solution 1:[1]
I don't understand why a statically linked executable needs a PLT and GOT.
It doesn't.
I compiled a hello world program on my ubuntu x86_64 machine and when I dump the section headers with readelf -S it shows PLT and GOT sections.
This is an accident of implementation. The sections come from crt1.o, and there isn't a separate crt1s.o for fully-static linking, so you end up with .plt and .got entries from there.
You can strip these sections, and the binary will still work:
objcopy -R.got -R.plt a.out a.out2
Note: do not strip .rela.plt, as that section is still needed to implement IFUNCs.
Solution 2:[2]
I found that gcc generates a .got and .got.lpt when generating position independent code and taking the address of a function defined in another source file.
My test files were:
part1.c:
extern void afunc();
int _start()
{
return 0x55 & (__SIZE_TYPE__) afunc;
}
part2.c:
void afunc() {}
My test was (substitute your own gcc version):
for o in s 4 3 2 1 0
do
aarch64-linux-gnu-gcc-10 -fPIC part1.c part2.c -o static.elf -static -nostdlib -O$o &&
aarch64-linux-gnu-objdump -x static.elf | grep 'GLOBAL_OFFSET'
done
I get the following output for all optimization levels:
0000000000410fd8 l O .got 0000000000000000 _GLOBAL_OFFSET_TABLE_
Replacing -fPIC with -fno-PIC and the segment goes away.
You can tell if your compiler defaults to -fPIC by running this:
aarch64-linux-gnu-gcc-10 -mcmodel=large -x c - < /dev/null
From which, I get the error, if it does:
cc1: sorry, unimplemented: code model ‘large’ with ‘-fPIC’
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Employed Russian |
| Solution 2 | Simon Willcocks |
