I'm using binutils-2.21.53.0.1-6.fc16.x86_64
.
I have a small object file, hello.o
with just enough "stuff" to have contents in all sections:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040
000000000000005d 0000000000000000 AX 0 0 4
[ 2] .rela.text RELA 0000000000000000 00000808
0000000000000060 0000000000000018 15 1 8
[ 3] .data PROGBITS 0000000000000000 000000a0
0000000000000000 0000000000000000 WA 0 0 4
[ 4] .bss NOBITS 0000000000000000 000000a0
0000000000000053 0000000000000000 WA 0 0 32
[ 5] .rodata PROGBITS 0000000000000000 000000a0
000000000000000f 0000000000000000 A 0 0 1
[ 6] .data.rel.local PROGBITS 0000000000000000 000000b0
0000000000000008 0000000000000000 WA 0 0 8
[ 7] .rela.data.rel.lo RELA 0000000000000000 00000868
0000000000000018 0000000000000018 15 6 8
[ 8] .data.rel PROGBITS 0000000000000000 000000b8
0000000000000008 0000000000000000 WA 0 0 8
[ 9] .rela.data.rel RELA 0000000000000000 00000880
0000000000000018 0000000000000018 15 8 8
[10] .comment PROGBITS 0000000000000000 000000c0
000000000000002d 0000000000000001 MS 0 0 1
[11] .note.GNU-stack PROGBITS 0000000000000000 000000ed
0000000000000000 0000000000000000 0 0 1
[12] .eh_frame PROGBITS 0000000000000000 000000f0
0000000000000058 0000000000000000 A 0 0 8
[13] .rela.eh_frame RELA 0000000000000000 00000898
0000000000000030 0000000000000018 15 12 8
[14] .shstrtab STRTAB 0000000000000000 00000148
0000000000000085 0000000000000000 0 0 1
[15] .symtab SYMTAB 0000000000000000 00000610
00000000000001b0 0000000000000018 16 11 8
[16] .strtab STRTAB 0000000000000000 000007c0
0000000000000045 0000000000000000 0 0 1
If I use -pie
and no linker script, the results are as expected:
$ ld -pie -Map hello_pie.map -o hello_pie.elf hello.o
$ ll hello_pie.elf
-rwxrwx---. 1 jreinhart jreinhart 3453 Mar 13 23:44 hello_pie.elf
However, if I include any sort of linker script, the output size explodes:
$ cat 1.ld
SECTIONS
{
}
$ ld -T 1.ld -pie -Map hello_pie.map -o hello_pie.elf hello.o
$ ll hello_pie.elf
-rwxrwx---. 1 jreinhart jreinhart 2100070 Mar 13 23:45 hello_pie.elf
As you can see, this file became huge.
Note that this appears to happen because the .text
section insists on starting at offset 0x200000 in the file:
$ readelf -l -S hello_pie.elf
There are 19 section headers, starting at offset 0x200400:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00200000 <--- Why?
000000000000005d 0000000000000000 AX 0 0 4
[ 2] .rodata PROGBITS 000000000000005d 0020005d
000000000000000f 0000000000000000 A 0 0 1
[ 3] .eh_frame PROGBITS 0000000000000070 00200070
0000000000000058 0000000000000000 A 0 0 8
[ 4] .interp PROGBITS 00000000000000c8 002000c8
000000000000000f 0000000000000000 A 0 0 1
[ 5] .dynsym DYNSYM 00000000000000d8 002000d8
0000000000000078 0000000000000018 A 6 2 8
[ 6] .dynstr STRTAB 0000000000000150 00200150
0000000000000014 0000000000000000 A 0 0 1
[ 7] .hash HASH 0000000000000168 00200168
0000000000000028 0000000000000004 A 5 0 8
[ 8] .rela.dyn RELA 0000000000000190 00200190
0000000000000078 0000000000000018 A 5 0 8
[ 9] .data.rel.local PROGBITS 0000000000000208 00200208
0000000000000008 0000000000000000 WA 0 0 8
[10] .data.rel PROGBITS 0000000000000210 00200210
0000000000000008 0000000000000000 WA 0 0 8
[11] .dynamic DYNAMIC 0000000000000218 00200218
00000000000000f0 0000000000000010 WA 6 0 8
[12] .got PROGBITS 0000000000000308 00200308
0000000000000018 0000000000000008 WA 0 0 8
[13] .got.plt PROGBITS 0000000000000320 00200320
0000000000000018 0000000000000008 WA 0 0 8
[14] .bss NOBITS 0000000000000340 00200338
0000000000000053 0000000000000000 WA 0 0 32
[15] .comment PROGBITS 0000000000000000 00200338
000000000000002c 0000000000000001 MS 0 0 1
[16] .shstrtab STRTAB 0000000000000000 00200364
000000000000009a 0000000000000000 0 0 1
[17] .symtab SYMTAB 0000000000000000 002008c0
0000000000000258 0000000000000018 18 19 8
[18] .strtab STRTAB 0000000000000000 00200b18
000000000000004e 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
Elf file type is DYN (Shared object file)
Entry point 0x0
There are 5 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000200040 0x0000000000000000
0x0000000000000118 0x0000000000000118 R E 8
INTERP 0x00000000002000c8 0x00000000000000c8 0x00000000000000c8
0x000000000000000f 0x000000000000000f R 1
[Requesting program interpreter: /lib/ld64.so.1]
LOAD --> 0x0000000000200000 0x0000000000000000 0x0000000000000000
0x0000000000000338 0x0000000000000393 RWE 200000
DYNAMIC 0x0000000000200218 0x0000000000000218 0x0000000000000218
0x00000000000000f0 0x00000000000000f0 RW 8
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 8
This has been happening regardless of the contents of my linker script. Any ideas what's going on?
I ran into this same problem today when learning about linker scripts. SIZEOF_HEADERS was the magic bullet to solve it. Here is my simple source file to build the object I'm linking:
.section .text
.global _start
_start:
mov $1, %eax
mov $8, %ebx
int $0x80
With the following linker script, I get a 2+ MB executable:
SECTIONS
{
. = 0x400000;
.text : { *(.text) }
}
If I add +SIZEOF_HEADERS, as shown below, I get a 568-byte executable:
SECTIONS
{
. = 0x400000 + SIZEOF_HEADERS;
.text : { *(.text) }
}
Per the LD documentation, this function returns the size of the output file's headers. Manually setting the offset to include the header size also yields a 568-byte executable:
SECTIONS
{
. = 0x400078;
.text : { *(.text) }
}
If I move .text even further down, the executable starts to expand. The following yields a 65984-byte executable:
SECTIONS
{
. = 0x410000;
.text : { *(.text) }
}
So basically, from what I can tell, it appears that:
Try the following command line option with ld (or gcc):
-z max-page-size=0x1000
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With