我正在使用binutils-2.21.53.0.1-6.fc16.x86_64
。
我有一个小的目标文件,hello.o
只有足够的“东西”,所有部分都有内容:
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
如果我使用-pie
而没有链接器脚本,则结果如预期所示:
$ 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
但是,如果我包含任何类型的链接描述文件,则输出大小会爆炸:
$ 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
如您所见,此文件变得非常庞大。
请注意,这似乎是因为.text
部分坚持从文件中的偏移量0x200000开始:
$ 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
无论我的链接器脚本的内容如何,都会发生这种情况。有什么想法正在发生什么?
答案 0 :(得分:6)
我在学习链接器脚本时遇到了同样的问题。 SIZEOF_HEADERS是解决它的灵丹妙药。这是我构建我正在链接的对象的简单源文件:
.section .text
.global _start
_start:
mov $1, %eax
mov $8, %ebx
int $0x80
使用以下链接描述文件,我得到一个2+ MB的可执行文件:
SECTIONS
{
. = 0x400000;
.text : { *(.text) }
}
如果我添加+ SIZEOF_HEADERS,如下所示,我得到一个568字节的可执行文件:
SECTIONS
{
. = 0x400000 + SIZEOF_HEADERS;
.text : { *(.text) }
}
根据LD documentation,此函数返回输出文件标题的大小。手动设置偏移量以包括标头大小也会产生568字节的可执行文件:
SECTIONS
{
. = 0x400078;
.text : { *(.text) }
}
如果我进一步向下移动.text,可执行文件就会开始扩展。以下产生一个65984字节的可执行文件:
SECTIONS
{
. = 0x410000;
.text : { *(.text) }
}
所以基本上,据我所知,它似乎是:
答案 1 :(得分:5)
默认情况下ld
页面对齐输入节。由于您的内核强制执行超级页面(页面为2MB = 0x200000字节),因此.text
部分将在偏移量0x200000处对齐。这似乎是ld
中的一个错误,因为它应该使用偏移量0x0000000(请参阅下面的编辑以获得可能的解释)
为了防止这种创建更大文件的对齐,您可以使用--nmagic
标志来阻止它对.text部分进行页面对齐,尽管它有副作用(它还禁用链接到共享库) 。但请注意将其他部分(.data
,.rodata
,...)与2M页面对齐,因为它们不能与.text位于同一页面中,因为所有这些部分都需要不同的访问位
答案 2 :(得分:4)
使用ld(或gcc)尝试以下命令行选项:
-z max-page-size=0x1000