-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[lld] Unsorted loadable program headers with -Ttext=
argument
#138584
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
CC @MaskRay I guess? |
@llvm/issue-subscribers-bug Author: Pavel Skripkin (pskrgag)
ELF spec say that program headers must be sorted by `p_vaddr`
> Loadable segment entries in the program header table appear in ascending order, However it does not work if Consider following example: int main(void)
{
while (1);
} ~/Documents/compiler_ws/lld
paskripkin > ~/Documents/git/llvm-project/build/bin/ld.lld -e main -Ttext=0x800000 test.o -o a.out
~/Documents/compiler_ws/lld
paskripkin > llvm-readelf -l a.out
Elf file type is EXEC (Executable file)
Entry point 0x800000
There are 5 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000200040 0x0000000000200040 0x000118 0x000118 R 0x8
LOAD 0x000000 0x0000000000200000 0x0000000000200000 0x000158 0x000158 R 0x1000
LOAD 0x001000 0x0000000000800000 0x0000000000800000 0x00000d 0x00000d R E 0x1000
LOAD 0x001010 0x0000000000801010 0x0000000000801010 0x00003c 0x00003c R 0x1000
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x0
Section to Segment mapping:
Segment Sections...
00
01
02 .text
03 .eh_frame
04
None .comment .symtab .shstrtab .strtab Note that first loadable segment has a Sort of analysisThe first loadable segment is the one that contains ELF header and program headers. It's added in // Add the headers. We will remove them if they don't fit.
// In the other partitions the headers are ordinary sections, so they don't
// need to be added here.
if (isMain) {
load = addHdr(PT_LOAD, flags);
load->add(ctx.out.elfHeader.get());
load->add(ctx.out.programHeaders.get());
} In normal case it gets merged into some of other segments because of the following code bool sameLMARegion =
load && !sec->lmaExpr && sec->lmaRegion == load->firstSec->lmaRegion;
if (load && sec != relroEnd &&
sec->memRegion == load->firstSec->memRegion &&
(sameLMARegion || load->lastSec == ctx.out.programHeaders.get()) &&
(ctx.script->hasSectionsCommand || sec->type == SHT_NOBITS ||
load->lastSec->type != SHT_NOBITS)) {
load->p_flags |= newFlags;
} else {
load = addHdr(PT_LOAD, newFlags);
flags = newFlags;
}
However if NoteThis is not a synthetic example. It was observed in real life with very strict elf loader. |
It looks like all
Am I missing something? If you are talking about |
@rui314 Sorry, I've added extra 0 while writing this bug report. It should be I will update it in moment |
ELF spec say that program headers must be sorted by
p_vaddr
However it does not work if
-Ttext
argument is used.Consider following example:
Note that first loadable segment has a
p_vaddr
less than the second one. (still reproduces on current master c50cba6).Sort of analysis
The first loadable segment is the one that contains ELF header and program headers. It's added in
Writer<ELFT>::createPhdrs
.In normal case it gets merged into some of other segments because of the following code
However if
-Ttext
is specified, predicate above may fail and new segment will be inserted. Then duringLinkerScript::assignAddresses
, firstPT_LOAD
segment gets assigned toctx.target->getImageBase()
, which may be far from the base oftext
(IIUC lld starts calculatingp_vaddr
s from the base passed in-T
).Note
This is not a synthetic example. It was observed in real life with very strict elf loader.
The text was updated successfully, but these errors were encountered: