* GNU ld places non-SHF_ALLOC sections after SHF_ALLOC sections. This has the
advantage that the file offsets of a non-SHF_ALLOC cannot be contained in
a PT_LOAD. This patch matches the behavior.
* For non-SHF_ALLOC non-orphan sections, GNU ld may assign non-zero sh_addr and
treat them similar to SHT_NOBITS (not advance location counter). This
is an alternative approach to what we have done in D85100.
By placing non-SHF_ALLOC sections at the end, we can drop special
cases in createSection and findOrphanPos added by D85100.
Different from GNU ld, we set sh_addr to 0 for non-SHF_ALLOC sections. 0
arguably is better because non-SHF_ALLOC sections don't appear in the memory
image.
ELF spec says:
> sh_addr - If the section will appear in the memory image of a process, this
> member gives the address at which the section's first byte should
> reside. Otherwise, the member contains 0.
D85100 appeared to take a detour. If we take a combined view on D85100 and this
patch, the overall complexity slightly increases (one more 3-line loop) and
compatibility with GNU ld improves.
The behavior we don't want to match is the special treatment of .symtab
.shstrtab .strtab: they can be matched in LLD but not in GNU ld.
Reviewed By: jhenderson, psmith
Differential Revision: https://reviews.llvm.org/D85867
GNU ld allows sections after a non-SHF_ALLOC section to be covered by PT_LOAD
(PR37607) and assigns addresses to non-SHF_ALLOC output sections (similar to
SHF_ALLOC NOBITS sections. The location counter is not advanced).
This patch tries to fix PR37607 (remove a special case in
`Writer<ELFT>::createPhdrs`). To make the created PT_LOAD meaningful, we cannot
reset dot to 0 for a middle non-SHF_ALLOC output section. This results in
removal of two special cases in LinkerScript::assignOffsets. Non-SHF_ALLOC
non-orphan sections can have non-zero addresses like in GNU ld.
The zero address rule for non-SHF_ALLOC sections is weakened to apply to orphan
only. This results in a special case in createSection and findOrphanPos, respectively.
Reviewed By: jhenderson
Differential Revision: https://reviews.llvm.org/D85100
GNU ld allows sections after a non-SHF_ALLOC section to be covered by PT_LOAD
(PR37607) and assigns addresses to non-SHF_ALLOC output sections (similar to
SHF_ALLOC NOBITS sections. The location counter is not advanced).
This patch tries to fix PR37607 (remove a special case in
`Writer<ELFT>::createPhdrs`). To make the created PT_LOAD meaningful, we cannot
reset dot to 0 for a middle non-SHF_ALLOC output section. This results in
removal of two special cases in LinkerScript::assignOffsets. Non-SHF_ALLOC
non-orphan sections can have non-zero addresses like in GNU ld.
The zero address rule for non-SHF_ALLOC sections is weakened to apply to orphan
only. This results in a special case in createSection and findOrphanPos, respectively.
Reviewed By: jhenderson
Differential Revision: https://reviews.llvm.org/D85100
We used to place orphans by just using compareSectionsNonScript.
Then we noticed that since linker scripts can use another order, we
should first try match the section to a given PT_LOAD. But there is
nothing special about PT_LOAD. The same issue can show up for
PT_GNU_RELRO for example.
In general, we have to search for the most similar section and put the
orphan next to it. Most similar being defined as how long they follow
the same code path in compareSecitonsNonScript.
That is what this patch does. We now compute a rank for each output
section, with a bit for each branch in what was
compareSectionsNonScript.
With this findOrphanPos is now fully general and orphan placement can
be optimized by placing every section with the same rank at once.
The included testcase is a variation of many-sections.s that uses
allocatable sections to avoid the fast path in the existing
code. Without threads it goes form 46 seconds to 0.9 seconds.
llvm-svn: 302903
We were already pretty close, the one exception was when a name was
reused in another SECTIONS directive:
SECTIONS {
.text : { *(.text) }
.data : { *(.data) }
}
SECTIONS {
.data : { *(other) }
}
In this case we would create a single .data and magically output
"other" while looking at the first OutputSectionCommand.
We now create two .data sections. This matches what gold does. If we
really want to create a single one, we should change the parser so that
the above is parsed as if the user had written
SECTIONS {
.text : { *(.text) }
.data : { *(.data) *(other)}
}
That is, there should be only one OutputSectionCommand for .data and
it would have two InputSectionDescriptions.
By itself this patch makes the code a bit more complicated, but is an
important step in allowing assignAddresses to operate just on the
linker script.
llvm-svn: 301484
Linux kernel linkerscript contains additional semicolon (last line):
.apicdrivers : AT(ADDR(.apicdrivers) - LOAD_OFFSET) {
__apicdrivers = .;
*(.apicdrivers);
I checked that both gold and bfd are able to parse something like:
.text : { ;;*(.text);;S = 0;; } }
Patch do the same.
Differential revision: https://reviews.llvm.org/D29276
llvm-svn: 293612
These were 3 last synthetics that were added in addPredefinedSections() instead
of createSyntheticSections(). Now it is possible to move addition to correct common place.
Also patch fixes testcase which discards .shstrtab, by restricting doing that.
Differential revision: https://reviews.llvm.org/D28561
llvm-svn: 291908
After Mark's patch I was wondering what was the rationale for the ELF
spec requiring us to merge only sections with matching flags and
types. I tried emailing
https://groups.google.com/forum/#!forum/generic-abi, but looks like my
emails are not being posted (the list is probably moderated). I
emailed Cary Coutant instead.
Cary pointed out that the section was a late addition and didn't got
the scrutiny it deserved. Given that and the problems found by
implementing the letter of the standard, I propose changing lld to
merge all sections with the same name and issue errors if the types or
some critical flags are different.
This should allow an unmodified firefox linked with lld to run.
This also merges some code with the linkerscript path.
llvm-svn: 291107
Summary:
This patch adds a ".comment" section to an output. The comment
section contains the linker's version string. You can now
find out whether a binary is created by LLD or not using objdump
command like this.
$ objdump -s -j .comment foo
foo: file format elf64-x86-64
Contents of section .comment:
0000 00474343 3a202855 62756e74 7520342e .GCC: (Ubuntu 4.
0010 382e342d 32756275 6e747531 7e31342e 8.4-2ubuntu1~14.
...
00c0 766d2f74 72756e6b 20323835 38343629 vm/trunk 285846)
00d0 004c696e 6b65723a 204c4c44 20342e30 .Linker: LLD 4.0
00e0 2e302028 7472756e 6b203238 36343036 .0 (trunk 286406
00f0 2900 ).
Compilers emits .comment section as well, so the output contains
both compiler and linker information.
Alternative considered:
I first tried to add a SHT_NOTE section because GNU gold does that.
A NOTE section starts with a header which contains content type.
It turned out that ld.gold sets type NT_GNU_GOLD_VERSION to their
NOTE section. So the NOTE type is only for GNU gold (surprise!)
Next, I tried to create ".linker-version" section. However, it seems
that reusing the existing ".comment" section is better because 1)
other tools already know about .comment section and is able to strip
it and 2) the result contans not only linker info but also compiler
info.
Differential Revision: https://reviews.llvm.org/D26487
llvm-svn: 286496
This matches gold and bfd, and is pretty much required by some linker
scripts. They end with commands like
foo 0 : { *(bar) }
if we put any SHF_ALLOC sections after they can have an address that
is too low.
llvm-svn: 281778