[PATCH] D67325: [ELF] Place the ELF header at imageBase
Fangrui Song via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 7 22:53:03 PDT 2019
MaskRay created this revision.
MaskRay added reviewers: grimar, peter.smith, ruiu.
Herald added subscribers: llvm-commits, jrtc27, fedor.sergeev, kbarton, arichardson, nemanjai, emaste, jyknight.
Herald added a reviewer: espindola.
Herald added a project: LLVM.
If there is no readonly section, we place:
- The ELF header at imageBase+maxPageSize
- Program headers at imageBase+maxPageSize+sizeof(Ehdr)
- The first section .text at imageBase+maxPageSize+sizeof(Ehdr)+sizeof(program headers)
This is due to an interaction between Writer<ELFT>::fixSectionAlignments
and LinkerScript::allocateHeaders:
- fixSectionAlignments says .text should be placed at `imageBase+maxPageSize+sizeof(Ehdr)+sizeof(program headers)` (formula: `alignTo(dot, maxPageSize) + dot % config->maxPageSize`)
- allocateHeaders computes the minimum address among SHF_ALLOC sections, i.e. addr(.text)
- allocateHeaders places ELF header at `addr(.text)-sizeof(Ehdr)-sizeof(program headers) = imageBase+maxPageSize`
This causes the first two PT_LOAD to overlap, which will not have
runtime problems, but not ideal.
// PHDR at 0x401034, should be 0x400034
PHDR 0x000034 0x00401034 0x00401034 0x000a0 0x000a0 R 0x4
// R PT_LOAD contains just Ehdr and program headers.
// It overlaps with the RX PT_LOAD.
LOAD 0x000000 0x00401000 0x00401000 0x000d4 0x000d4 R 0x1000
LOAD 0x0000d4 0x004010d4 0x004010d4 0x00001 0x00001 R E 0x1000
To fix the placement of the ELF header and program headers, set their
addresses in LinkerScript::assignAddresses, and make allocateHeaders a
NOP. Also drop the `getInitialDot` special case for -T<section>.
Before and after this change, with -T<section>, ld.lld consistently
creates a PT_PHDR while ld.bfd doesn't:
ld.bfd -o a -Ttext=0x3000 a.o => no PT_PHDR
ld.bfd -o a -Ttext=0x3000 a.o dummy.so (--enable-separate-code [1]) => place .note.gnu.property at 0x4000e8.
After dropping the special rule, if -Ttext is smaller than the default image base, the ELF header will be mapped at a higher address, which may look strange:
PHDR 0x000034 0x00400034 0x00400034 0x000a0 0x000a0 R 0x4
LOAD 0x000000 0x00400000 0x00400000 0x000d4 0x000d4 R 0x1000
LOAD 0x001000 0x00003000 0x00003000 0x00001 0x00001 R E 0x1000
This is probably OK because our behavior (the existence of PT_PHDR) has
already diverged from ld.bfd, and ld.bfd's own program headers can
change with or without -z separate-code.
It is advised to use a linker script with the PHDRS command to have a
consistent behavior across linkers. If PT_PHDR is needed, an explicit
--image-base can be a simpler alternative.
[1]: --enable-separate-code is the default on Linux x86-64 since binutils 2.31.
Repository:
rLLD LLVM Linker
https://reviews.llvm.org/D67325
Files:
ELF/LinkerScript.cpp
test/ELF/basic-aarch64.s
test/ELF/basic-i386.s
test/ELF/basic-ppc.s
test/ELF/basic-sparcv9.s
test/ELF/ttext-tdata-tbss.s
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D67325.219256.patch
Type: text/x-patch
Size: 8091 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190908/543d72ba/attachment.bin>
More information about the llvm-commits
mailing list