Commit Graph

870 Commits

Author SHA1 Message Date
Fangrui Song 3534d26cc1 [ELF] Slightly speed up -z keep-text-section-prefix 2021-12-15 10:20:11 -08:00
Fangrui Song 3deb82cd07 [ELF] Adjust getOutputSectionName prefix order
Sorting the prefixes by decreasing frequency can improve performance.
.gcc_except_table is relatively frequent, so move it ahead.
.ctors and .dtors mostly disappear and should be the last.
2021-12-15 00:18:58 -08:00
Fangrui Song 5816f1855c [ELF] Slightly speed up getOutputSectionName. NFC 2021-12-14 23:43:00 -08:00
Fangrui Song e652f3f04a [ELF] Simplify some ctx->outSec with sec. NFC 2021-11-28 19:08:27 -08:00
Fangrui Song 89c0f4553e [ELF] Simplify/remove LinkerScript::switchTo. NFC 2021-11-28 19:05:15 -08:00
Fangrui Song 1164c4b375 [ELF] Simplify/remove LinkerScript::output and advance. NFC 2021-11-28 16:58:06 -08:00
Fangrui Song e80a0b353c [ELF] Remove unneeded getOutputSectionVA. NFC
I attempted to remove it 1 or 2 year ago but kept it just to have a good
diagnostic in case the output section is nullptr (should be impossible).
It is long enough that we haven't seen such a case.
2021-11-28 16:17:10 -08:00
Fangrui Song 7ea662e2dd [ELF] Replace one make_unique from r316378 with a stack object. NFC 2021-11-28 15:32:29 -08:00
Fangrui Song 7051aeef7a [ELF] Rename BaseCommand to SectionCommand. NFC
BaseCommand was picked when PHDRS/INSERT/etc were not implemented. Rename it to
SectionCommand to match `sectionCommands` and make it clear that the commands
are used in SECTIONS (except a special case for SymbolAssignment).

Also, improve naming of some BaseCommand variables (base -> cmd).
2021-11-25 20:24:23 -08:00
Fangrui Song 6188fd4957 [ELF] Rename OutputSection::sectionCommands to commands. NFC
This partially reverts r315409: the description applies to LinkerScript, but not
to OutputSection.

The name "sectionCommands" is used in both LinkerScript::sectionCommands and
OutputSection::sectionCommands, which may lead to confusion.
"commands" in OutputSection has no ambiguity because there are no other types
of commands.
2021-11-25 16:47:07 -08:00
Igor Kudrin 8cdf1c1edb [ELF] Support the "read-only" memory region attribute
The attribute 'r' allows (or disallows for the negative case) read-only
sections, i.e. ones without the SHF_WRITE flag, to be assigned to the
memory region. Before the patch, lld could put a section in the wrong
region or fail with "error: no memory region specified for section".

Differential Revision: https://reviews.llvm.org/D113771
2021-11-24 12:17:09 +07:00
Igor Kudrin a05b694b1e [ELF][NFC] Do not pass region name to expandMemoryRegion()
The name can be easily got on-site.

Differential Revision: https://reviews.llvm.org/D114228
2021-11-22 14:19:07 +07:00
Fangrui Song 648157b05a [ELF] Move getOutputSectionName from Writer.cpp to LinkerScript.cpp. NFC
and internalize it.
2021-11-20 22:18:09 -08:00
Andrew Ng 47eb3f155f [ELF] Ensure output section is not discarded in addStartEndSymbols()
Fixes https://bugs.llvm.org/show_bug.cgi?id=52534.

Differential Revision: https://reviews.llvm.org/D114179
2021-11-19 11:45:58 +00:00
Konstantin Schwarz 8c18719bae [ELF] Expand LMA region if output section alignment introduces padding
When aligning the start address of an output section introduces a gap between the current dot pointer
and the new aligned address, we were already properly expanding the memory region, if available.

D74286 introduced a new behavior to also align the LMA address if an LMA region is specified.
However, this did not expand the corresponding LMA region.
Now, we also expand the LMA region if it is set.

This fixes PR52510.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D114166
2021-11-19 11:27:21 +01:00
Igor Kudrin 66691de94c [ELF] Do not try to assign a memory region to a non-allocatable section
Non-allocatable sections are not part of the memory image of the
program, so there is no need to find memory regions for them either
matching properties or handling explicit assignments. The early test
and return help to simplify LinkerScript::findMemoryRegion() a bit.

Differential Revision: https://reviews.llvm.org/D113768
2021-11-15 15:59:39 +07:00
Igor Kudrin d2dd36bbbe [ELF] Better resemble GNU ld when placing orphan sections into memory regions
An orphan section should be placed in the same memory region as its
anchor section if the latter specifies the memory region explicitly.
If there is no explicit assignment for the anchor section in the linker
script, its memory region is selected by matching attributes, and the
same should be done for the orphan section.

Before the patch, some scripts that were handled smoothly in GNU ld
caused an "error: no memory region specified for section" in lld.

Differential Revision: https://reviews.llvm.org/D112925
2021-11-11 15:07:38 +07:00
Fangrui Song bf6e259b21 [ELF] Update comments/diagnostics for some long options to use the canonical two-dash form
Rewrite some comments as appropriate.
2021-10-25 12:52:06 -07:00
Fangrui Song 9bd29a73d1 [ELF] Make dot in .tbss correct
GNU ld doesn't support multiple SHF_TLS SHT_NOBITS output sections (it restores
the address after an SHF_TLS SHT_NOBITS section, so consecutive SHF_TLS
SHT_NOBITS sections will have conflicting address ranges).

That said, `threadBssOffset` implements limited support for consecutive SHF_TLS
SHT_NOBITS sections. (SHF_TLS SHT_PROGBITS following a SHF_TLS SHT_NOBITS can still be
incorrect.)

`.` in an output section description of an SHF_TLS SHT_NOBITS section is
incorrect. (https://lists.llvm.org/pipermail/llvm-dev/2021-July/151974.html)

This patch saves the end address of the previous tbss section in
`ctx->tbssAddr`, changes `dot` in the beginning of `assignOffset` so
that `.` evaluation will be correct.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D107208
2021-08-04 08:58:50 -07:00
Fangrui Song 03051f7ac8 [ELF] Preserve section order within an INSERT AFTER command
For
```
SECTIONS {
  text.0 : {}
  text.1 : {}
  text.2 : {}
} INSERT AFTER .data;
```

the current order is `.data text.2 text.1 text.0`. It makes more sense to
preserve the specified order and thus improve compatibility with GNU ld.

For
```
SECTIONS { text.0 : {} } INSERT AFTER .data;
SECTIONS { text.3 : {} } INSERT AFTER .data;
```

GNU ld somehow collects sections with `INSERT AFTER .data` together (IMO
inconsistent) but I think it makes more sense to execute the commands in order
and get `.data text.3 text.0` instead.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D105158
2021-06-30 11:35:50 -07:00
Fangrui Song 899fdf548e [ELF] Add OVERWRITE_SECTIONS command
This implements https://sourceware.org/bugzilla/show_bug.cgi?id=26404

An `OVERWRITE_SECTIONS` command is a `SECTIONS` variant which contains several
output section descriptions. The output sections do not have specify an order.
Similar to `INSERT [BEFORE|AFTER]`, `LinkerScript::hasSectionsCommand` is not
set, so the built-in rules (see `docs/ELF/linker_script.rst`) still apply.
`OVERWRITE_SECTIONS` can be more convenient than `INSERT` because it does not
need an anchor section.

The initial syntax is intentionally narrow to facilitate backward compatible
extensions in the future. Symbol assignments cannot be used.

This feature is versatile. To list a few usage:

* Use `section : { KEEP(...) }` to retain input sections under GC
* Define encapsulation symbols (start/end) for an output section
* Use `section : ALIGN(...) : { ... }` to overalign an output section (similar to ld64 `-sectalign`)

When an output section is specified by both `OVERWRITE_SECTIONS` and
`INSERT`, `INSERT` is processed after overwrite sections. To make this work,
this patch changes `InsertCommand` to use name based matching instead of pointer
based matching. (This may cause a difference when `INSERT` moves one output
section more than once. Such duplicate commands should not be used in practice
(seems that in GNU ld the output sections may just disappear).)

A linker script can be used without -T/--script. The traditional `SECTIONS`
commands are concatenated, so a wrong rule can be more noticeable from the
section order. This feature if misused can be less noticeable, just like
`INSERT`.

Differential Revision: https://reviews.llvm.org/D103303
2021-06-13 12:41:11 -07:00
Nico Weber 1e89f08f59 fix typo to cycle bots 2021-04-14 14:52:53 -04:00
Georgii Rymar 3f5dc57fd1 [LLD][ELF] - Don't keep empty output sections which have explicit program headers.
This reverts a side effect introduced in the code cleanup patch D43571:
LLD started to emit empty output sections that are explicitly assigned to a segment.

This patch fixes the issue by removing the !sec.phdrs.empty() special case from
isDiscardable. As compensation, we add an early phdrs propagation step (see the inline comment).
This is similar to one that we do in adjustSectionsAfterSorting.

Differential revision: https://reviews.llvm.org/D92301
2020-12-02 11:19:21 +03:00
Fangrui Song 048b16f7fb [ELF] Check --orphan-handling=place (default value) early
The function took 1% (161MiB clang) to 1.7% (an 4.9GiB executable) time.
2020-11-29 12:36:27 -08:00
Fangrui Song 73d01a80ce [ELF] Sort by input order within an input section description
According to
https://sourceware.org/binutils/docs/ld/Input-Section-Basics.html#Input-Section-Basics
for `*(.a .b)`, the order should match the input order:

* for `ld 1.o 2.o`, sections from 1.o precede sections from 2.o
* within a file, `.a` and `.b` appear in the section header table order

This patch implements the behavior. The interaction with `SORT*` and --sort-section is:

Matched sections are ordered by radix sort with the keys being `(SORT*, --sort-section, input order)`,
where `SORT*` (if present) is most significant.

> Note, multiple `SORT*` within an input section description has undocumented and
> confusing behaviors in GNU ld:
> https://sourceware.org/pipermail/binutils/2020-November/114083.html
> Therefore multiple `SORT*` is not the focus for this patch but
> this patch still strives to have an explainable behavior.

As an example, we partition `SORT(a.*) b.* c.* SORT(d.*)`, into
`SORT(a.*) | b.* c.* | SORT(d.*)` and perform sorting within groups. Sections
matched by patterns between two `SORT*` are sorted by input order.  If
--sort-alignment is given, they are sorted by --sort-alignment, breaking tie by
input order.

This patch also allows a section to be matched by multiple patterns, previously
duplicated sections could occupy more space in the output and had erroneous zero bytes.

The patch is in preparation for support for
`*(SORT_BY_INIT_PRIORITY(.init_array.* .ctors.*)) *(.init_array .ctors)`,
which will allow LLD to mix .ctors*/.init_array* like GNU ld (gold's --ctors-in-init-array)
PR44698 and PR48096

Reviewed By: grimar, psmith

Differential Revision: https://reviews.llvm.org/D91127
2020-11-12 08:53:11 -08:00
James Henderson 439341b9bf [lld][ELF] Add additional time trace categories
I noticed when running a large link with the --time-trace option that
there were several areas which were missing any specific time trace
categories (aside from the generic link/ExecuteLinker categories). This
patch adds new categories to fill most of the "gaps", or to provide more
detail than was previously provided.

Reviewed by: MaskRay, grimar, russell.gallop

Differential Revision: https://reviews.llvm.org/D90686
2020-11-10 10:28:46 +00:00
Fangrui Song ae73091f30 [ELF] -r: don't crash when a non-SHF_LINK_ORDER orphan is added before a SHF_LINK_ORDER orphan
Fixes https://github.com/ClangBuiltLinux/linux/issues/1186

If a non-SHF_LINK_ORDER orphan is added first, `firstIsec->flags & SHF_LINK_ORDER`
will be zero and we currently assert when calling `getLinkOrderDep`.

Reviewed By: grimar

Differential Revision: https://reviews.llvm.org/D90200
2020-10-28 08:56:42 -07:00
Andrew Ng 77152a6b7a [LLD][ELF] Optimize linker script filename glob pattern matching NFC
Optimize the filename glob pattern matching in
LinkerScript::computeInputSections() and LinkerScript::shouldKeep().

Add InputFile::getNameForScript() which gets and if required caches the
Inputfile's name used for linker script matching. This avoids the
overhead of name creation that was in getFilename() in LinkerScript.cpp.

Add InputSectionDescription::matchesFile() and
SectionPattern::excludesFile() which perform the glob pattern matching
for an InputFile and make use of a cache of the previous result. As both
computeInputSections() and shouldKeep() process sections in order and
the sections of the same InputFile are contiguous, these single entry
caches can significantly speed up performance for more complex glob
patterns.

These changes have been seen to reduce link time with --gc-sections by
up to ~40% with linker scripts that contain KEEP filename glob patterns
such as "*crtbegin*.o".

Differential Revision: https://reviews.llvm.org/D87469
2020-09-16 10:26:11 +01:00
Fangrui Song 9670029b6b [ELF] Keep st_type for symbol assignment
PR46970: for `alias = aliasee`, the alias can be used in relocation processing
and on ARM st_type does affect Thumb interworking. It is thus desirable for the
alias to get the same st_type.

Note that the st_size field should not be inherited because some tools use
st_size=0 as a heuristic to detect aliases. Retaining st_size can thwart such
heuristics and cause aliases to be preferred over the original symbols.

Differential Revision: https://reviews.llvm.org/D86263
2020-08-20 16:05:27 -07:00
Fangrui Song ec29538af2 [ELF] Assign file offsets of non-SHF_ALLOC after SHF_ALLOC and set sh_addr=0 to non-SHF_ALLOC
* 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
2020-08-18 09:03:01 -07:00
Fangrui Song a6db64ef4a [ELF] Allow sections after a non-SHF_ALLOC section to be covered by PT_LOAD
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
2020-08-06 08:27:15 -07:00
Muhammad Omair Javaid d9e191cb17 Revert "[ELF] Allow sections after a non-SHF_ALLOC section to be covered by PT_LOAD"
This reverts commit 030ddc0a0b.

This breaks http://lab.llvm.org:8011/builders/lldb-arm-ubuntu
and http://lab.llvm.org:8011/builders/lldb-aarch64-ubuntu

Differential Revision: https://reviews.llvm.org/D85100
2020-08-06 16:30:05 +05:00
Fangrui Song 030ddc0a0b [ELF] Allow sections after a non-SHF_ALLOC section to be covered by PT_LOAD
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
2020-08-05 09:30:23 -07:00
Fangrui Song 8ffb2097cc [ELF] Refine LMA offset propagation rule in D76995
If neither AT(lma) nor AT>lma_region is specified,
D76995 keeps `lmaOffset` (LMA - VMA) if the previous section is in the
default LMA region.

This patch additionally checks that the two sections are in the same
memory region.

Add a test case derived from https://bugs.llvm.org/show_bug.cgi?id=45313

  .mdata : AT(0xfb01000) { *(.data); } > TCM
  // It is odd to make .bss inherit lmaOffset, because the two sections
  // are in different memory regions.
  .bss : { *(.bss) } > DDR

With this patch, section VMA/LMA match GNU ld. Note, GNU ld supports
out-of-order (w.r.t sh_offset) sections and places .text and .bss in the
same PT_LOAD. We don't have that behavior.

Reviewed By: grimar

Differential Revision: https://reviews.llvm.org/D81986
2020-06-19 09:11:33 -07:00
Fangrui Song 07837b8f49 [ELF] Use namespace qualifiers (lld:: or elf::) instead of `namespace lld { namespace elf {`
Similar to D74882. This reverts much code from commit
bd8cfe65f5 (D68323) and fixes some
problems before D68323.

Sorry for the churn but D68323 was a mistake. Namespace qualifiers avoid
bugs where the definition does not match the declaration from the
header. See
https://llvm.org/docs/CodingStandards.html#use-namespace-qualifiers-to-implement-previously-declared-functions (D74515)

Differential Revision: https://reviews.llvm.org/D79982
2020-05-15 08:49:53 -07:00
Peter Smith 0ae7990b60 [ELF][ARM] Support /DISCARD/ of subset of .ARM.exidx sections
Both the .ARM.exidx and .eh_frame sections have a custom SyntheticSection
that acts as a container for the InputSections. The InputSections are added
to the SyntheticSection prior to /DISCARD/ which limits the affect a
/DISCARD/ can have to the whole SyntheticSection. In the majority of cases
this is sufficient as it is not common to discard subsets of the
InputSections. The Linux kernel has one of these scripts which has something
like:
/DISCARD/ : { *(.ARM.exidx.exit.text) *(.ARM.extab.exit.text) ... }
The .ARM.exidx.exit.text are not discarded because the InputSection has been
transferred to the Synthetic Section. The *(.ARM.extab.exit.text) sections
have not so they are discarded. When we come to write out the .ARM.exidx
sections the dangling references from .ARM.exidx.exit.text to
.ARM.extab.exit.text currently cause relocation out of range errors, but
could as easily cause a fatal error message if we check for dangling
references at relocation time.

This patch attempts to respect the /DISCARD/ command by running it on the
.ARM.exidx InputSections stored in the SyntheticSection.

The .eh_frame is in theory affected by this problem, but I don't think that
there is a dangling reference problem that can happen with these sections.

Fixes remaining part of pr44824

Differential Revision: https://reviews.llvm.org/D79687
2020-05-11 14:27:13 +01:00
Reid Kleckner 932f0276ea [Support] Move LLD's parallel algorithm wrappers to support
Essentially takes the lld/Common/Threads.h wrappers and moves them to
the llvm/Support/Paralle.h algorithm header.

The changes are:
- Remove policy parameter, since all clients use `par`.
- Rename the methods to `parallelSort` etc to match LLVM style, since
  they are no longer C++17 pstl compatible.
- Move algorithms from llvm::parallel:: to llvm::, since they have
  "parallel" in the name and are no longer overloads of the regular
  algorithms.
- Add range overloads
- Use the sequential algorithm directly when 1 thread is requested
  (skips task grouping)
- Fix the index type of parallelForEachN to size_t. Nobody in LLVM was
  using any other parameter, and it made overload resolution hard for
  for_each_n(par, 0, foo.size(), ...) because 0 is int, not size_t.

Remove Threads.h and update LLD for that.

This is a prerequisite for parallel public symbol processing in the PDB
library, which is in LLVM.

Reviewed By: MaskRay, aganea

Differential Revision: https://reviews.llvm.org/D79390
2020-05-05 15:21:05 -07:00
Fangrui Song bb4a36ea28 [ELF] Propagate LMA offset to sections with neither AT() nor AT>
Fixes https://bugs.llvm.org/show_bug.cgi?id=45313
Also fixes linkerscript/{at4.s,overlay.test} LMA address issues exposed by
011b785505.
Related: D74297

This patch improves emulation of GNU ld's heuristics on the difference
between the LMA and the VMA:
https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html#Output-Section-LMA

New test linkerscript/lma-offset.s (based on at4.s) demonstrates some behaviors.

Reviewed By: psmith

Differential Revision: https://reviews.llvm.org/D76995
2020-04-01 08:19:06 -07:00
James Henderson 3ff3c6986b [lld][ELF] Fix error message
The error previously talked about a "section header" but was actually
referring to a program header.

Reviewed by: grimar, MaskRay

Differential Revision: https://reviews.llvm.org/D76846
2020-03-26 15:30:24 +00:00
Fangrui Song fbf41b5267 [ELF] Simplify sh_addr computation and warn if sh_addr is not a multiple of sh_addralign
See `docs/ELF/linker_script.rst` for the new computation for sh_addr and sh_addralign.
`ALIGN(section_align)` now means: "increase alignment to section_align"
(like yet another input section requirement).

The "start of section .foo changes from 0x11 to 0x20" warning no longer
makes sense. Change it to warn if sh_addr%sh_addralign!=0.

To decrease the alignment from the default max_input_align,
use `.output ALIGN(8) : {}` instead of `.output : ALIGN(8) {}`
See linkerscript/section-address-align.test as an example.

When both an output section address and ALIGN are set (can be seen as an
"undefined behavior" https://sourceware.org/ml/binutils/2020-03/msg00115.html),
lld may align more than GNU ld, but it makes a linker script working
with GNU ld hard to break with lld.

This patch can be considered as restoring part of the behavior before D74736.

Differential Revision: https://reviews.llvm.org/D75724
2020-03-11 09:35:42 -07:00
David Bozier 6e2804ce6b [LLD] Add support for --unique option
Summary:
Places orphan sections into a unique output section. This prevents the merging of orphan sections of the same name.
Matches behaviour of GNU ld --unique. --unique=pattern is not implemented.

Motivated user case shown in the test has 2 local symbols as they would appear if C++ source has been compiled with -ffunction-sections. The merging of these sections in the case of a partial link (-r) may limit the effectiveness of -gc-sections of a subsequent link.

Reviewers: espindola, jhenderson, bd1976llvm, edd, andrewng, JonChesterfield, MaskRay, grimar, ruiu, psmith

Reviewed By: MaskRay, grimar

Subscribers: emaste, arichardson, MaskRay, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D75536
2020-03-10 12:20:21 +00:00
Fangrui Song 92b5b980d2 [ELF] Postpone evaluation of ORIGIN/LENGTH in a MEMORY command
```
createFiles(args)
 readDefsym
 readerLinkerScript(*mb)
  ...
   readMemory
    readMemoryAssignment("ORIGIN", "org", "o") // eagerly evaluated
target = getTarget();
link(args)
 writeResult<ELFT>()
  ...
   finalizeSections()
    script->processSymbolAssignments()
     addSymbol(cmd) // with this patch, evaluated here
```

readMemoryAssignment eagerly evaluates ORIGIN/LENGTH and returns an uint64_t.
This patch postpones the evaluation to make

* --defsym and symbol assignments
* `CONSTANT(COMMONPAGESIZE)` (requires a non-null `lld:🧝:target`)

work. If the expression somehow requires interaction with memory
regions, the circular dependency may cause the expression to evaluate to
a strange value. See the new test added to memory-err.s

Reviewed By: grimar

Differential Revision: https://reviews.llvm.org/D75763
2020-03-09 08:31:41 -07:00
Fangrui Song 37c7f0d945 [ELF] --orphan-handling=: don't warn/error for input SHT_REL[A] retained by --emit-relocs
They are purposefully skipped by input section descriptions (rL295324).
Similarly, --orphan-handling= should not warn/error for them.
This behavior matches GNU ld.

Reviewed By: grimar

Differential Revision: https://reviews.llvm.org/D75151
2020-02-26 10:32:54 -08:00
Fangrui Song 423194098b [ELF] --orphan-handling=: don't warn/error for unused synthesized sections
This makes --orphan-handling= less noisy.
This change also improves our compatibility with GNU ld.

GNU ld special cases .symtab, .strtab and .shstrtab . We need output section
descriptions for .symtab, .strtab and .shstrtab to suppress:

  <internal>:(.symtab) is being placed in '.symtab'
  <internal>:(.shstrtab) is being placed in '.shstrtab'
  <internal>:(.strtab) is being placed in '.strtab'

With --strip-all, .symtab and .strtab can be omitted (note, --strip-all is not compatible with --emit-relocs).

Reviewed By: nickdesaulniers

Differential Revision: https://reviews.llvm.org/D75149
2020-02-26 08:56:12 -08:00
Fangrui Song 93331a17e8 [ELF] Support archive:file syntax in input section descriptions
Fixes https://bugs.llvm.org/show_bug.cgi?id=44450

https://sourceware.org/binutils/docs/ld/Input-Section-Basics.html#Input-Section-Basics
The following two rules are not implemented.

* `archive:` matches every file in the archive.
* `:file` matches a file not in an archive.

Reviewed By: grimar, ruiu

Differential Revision: https://reviews.llvm.org/D75100
2020-02-25 07:57:43 -08:00
Fangrui Song de0dda54d3 [ELF] Warn changed output section address
When the output section address (addrExpr) is specified, GNU ld warns if
sh_addr is different. This patch implements the warning.

Note, LinkerScript::assignAddresses can be called more than once. We
need to record the changed section addresses, and only report the
warnings after the addresses are finalized.

Reviewed By: grimar

Differential Revision: https://reviews.llvm.org/D74741
2020-02-21 08:13:29 -08:00
Fangrui Song 6ed8e20143 [ELF] Ignore the maximum of input section alignments for two cases
Follow-up for D74286.

Notations:

* alignExpr: the computed ALIGN value
* max_input_align: the maximum of input section alignments

This patch changes the following two cases to match GNU ld:

* When ALIGN is present, GNU ld sets output sh_addr to alignExpr, while lld use max(alignExpr, max_input_align)
* When addrExpr is specified but alignExpr is not, GNU ld sets output sh_addr to addrExpr, while lld uses `advance(0, max_input_align)`

Note, sh_addralign is still set to max(alignExpr, max_input_align).

lma-align.test is enhanced a bit to check we don't overalign sh_addr.

fixSectionAlignments() sets addrExpr but not alignExpr for the `!hasSectionsCommand` case.
This patch sets alignExpr as well so that max_input_align will be respected.

Reviewed By: grimar

Differential Revision: https://reviews.llvm.org/D74736
2020-02-21 08:12:00 -08:00
Fangrui Song 7c426fb1a6 [ELF] Support INSERT [AFTER|BEFORE] for orphan sections
D43468+D44380 added INSERT [AFTER|BEFORE] for non-orphan sections. This patch
makes INSERT work for orphan sections as well.

`SECTIONS {...} INSERT [AFTER|BEFORE] .foo` does not set `hasSectionCommands`, so the result
will be similar to a regular link without a linker script. The differences when `hasSectionCommands` is set include:

* image base is different
* -z noseparate-code/-z noseparate-loadable-segments are unavailable
* some special symbols such as `_end _etext _edata` are not defined

The behavior is similar to GNU ld:
INSERT is not considered an external linker script.

This feature makes the section layout more flexible. It can be used to:

* Place .nv_fatbin before other readonly SHT_PROGBITS sections to mitigate relocation overflows.
* Disturb the layout to expose address sensitive application bugs.

Reviewed By: grimar

Differential Revision: https://reviews.llvm.org/D74375
2020-02-12 08:21:52 -08:00
Fangrui Song b498d99338 [ELF] Start a new PT_LOAD if LMA region is different
GNU ld has a counterintuitive lang_propagate_lma_regions rule.

```
// .foo's LMA region is propagated to .bar because their VMA region is the same,
// and .bar does not have an explicit output section address (addr_tree).
.foo : { *(.foo) } >RAM AT> FLASH
.bar : { *(.bar) } >RAM

// An explicit output section address disables propagation.
.foo : { *(.foo) } >RAM AT> FLASH
.bar . : { *(.bar) } >RAM
```

In both cases, lld thinks .foo's LMA region is propagated and
places .bar in the same PT_LOAD, so lld diverges from GNU ld w.r.t. the
second case (lma-align.test).

This patch changes Writer<ELFT>::createPhdrs to disable propagation
(start a new PT_LOAD). A user of the first case can make linker scripts
portable by explicitly specifying `AT>`. By contrast, there was no
workaround for the old behavior.

This change uncovers another LMA related bug in assignOffsets() where
`ctx->lmaOffset = 0;` was omitted. It caused a spurious "load address
range overlaps" error for at2.test

The new PT_LOAD rule is complex. For convenience, I listed the origins of some subexpressions:

* rL323449: `sec->memRegion == load->firstSec->memRegion`; linkerscript/at3.test
* D43284: `load->lastSec == Out::programHeaders` (don't start a new PT_LOAD after program headers); linkerscript/at4.test
* D58892: `sec != relroEnd` (start a new PT_LOAD after PT_GNU_RELRO)

Reviewed By: psmith

Differential Revision: https://reviews.llvm.org/D74297
2020-02-12 08:20:14 -08:00
Fangrui Song e21b9ca751 [ELF] Respect output section alignment for AT> (non-null lmaRegion)
When lmaRegion is non-null, respect `sec->alignment`
This rule is analogous to `switchTo(sec)` which advances sh_addr (VMA).

This fixes the p_paddr misalignment issue as reported by
https://android-review.googlesource.com/c/trusty/external/trusted-firmware-a/+/1230058

Note, `sec->alignment` is the maximum of ALIGN and input section alignments. We may overalign LMA than GNU ld.

linkerscript/align-lma.s has a FIXME that demonstrates another bug:
`.bss ... >RAM` should be placed in a different PT_LOAD (GNU ld
behavior) because its lmaRegion (nullptr) is different from the previous
section's lmaRegion (ROM).

Reviewed By: psmith

Differential Revision: https://reviews.llvm.org/D74286
2020-02-12 08:19:42 -08:00