I have a statically linked binary and I'm trying to size it down. I don't understand why it emits dynamic sections and I don't think it really should.
I think -fpic -fPIC should get rid of all relocations, but there's some left. start.s contains call main but that's within the same segment so there shouldn't be a relocation there either.
My Makefile:
hello: start.s hello.c Makefile
gcc -o hello -nostartfiles -nostdlib -Wl,--no-dynamic-linker -fpic -fPIC -fno-asynchronous-unwind-tables -s start.s hello.c
strip -R .comment hello
Result of objdump -x
hello: file format elf64-x86-64
hello
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000001000
Program Header:
LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**12
filesz 0x0000000000000261 memsz 0x0000000000000261 flags r--
LOAD off 0x0000000000001000 vaddr 0x0000000000001000 paddr 0x0000000000001000 align 2**12
filesz 0x00000000000000bb memsz 0x00000000000000bb flags r-x
LOAD off 0x0000000000002000 vaddr 0x0000000000002000 paddr 0x0000000000002000 align 2**12
filesz 0x0000000000000010 memsz 0x0000000000000010 flags r--
LOAD off 0x0000000000002f30 vaddr 0x0000000000003f30 paddr 0x0000000000003f30 align 2**12
filesz 0x00000000000000d0 memsz 0x00000000000000d0 flags rw-
DYNAMIC off 0x0000000000002f30 vaddr 0x0000000000003f30 paddr 0x0000000000003f30 align 2**3
filesz 0x00000000000000d0 memsz 0x00000000000000d0 flags rw-
NOTE off 0x0000000000000200 vaddr 0x0000000000000200 paddr 0x0000000000000200 align 2**2
filesz 0x0000000000000024 memsz 0x0000000000000024 flags r--
STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
RELRO off 0x0000000000002f30 vaddr 0x0000000000003f30 paddr 0x0000000000003f30 align 2**0
filesz 0x00000000000000d0 memsz 0x00000000000000d0 flags r--
Dynamic Section:
GNU_HASH 0x0000000000000228
STRTAB 0x0000000000000260
SYMTAB 0x0000000000000248
STRSZ 0x0000000000000001
SYMENT 0x0000000000000018
DEBUG 0x0000000000000000
FLAGS_1 0x0000000008000000
Sections:
Idx Name Size VMA LMA File off Algn
0 .note.gnu.build-id 00000024 0000000000000200 0000000000000200 00000200 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .gnu.hash 0000001c 0000000000000228 0000000000000228 00000228 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .dynsym 00000018 0000000000000248 0000000000000248 00000248 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .dynstr 00000001 0000000000000260 0000000000000260 00000260 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .text 000000bb 0000000000001000 0000000000001000 00001000 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
5 .rodata 0000000f 0000000000002000 0000000000002000 00002000 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .eh_frame 00000000 0000000000002010 0000000000002010 00002010 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .dynamic 000000d0 0000000000003f30 0000000000003f30 00002f30 2**3
CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
no symbols
After banging at this for hours I got a working answer. This
ldscript works.And the build command is
This will explode if there are any initialized pointers in global variables. Why? Because we are relocatable and we don't have any relocations, so there is literally no way to express that.
is poison.
is fine.
If you need initialized global pointers to work; forfeit ASLR instead by changing that
. = 0;to. = 0x10000;line and remove-fpic -fpiefrom the build instructions.