Commit Graph

690 Commits

Author SHA1 Message Date
Fangrui Song
fae96104d4 [ELF] Support operator ^ and ^=
GNU ld added ^ support in July 2023 and it looks like ^= is in plan as
well.

For now, we don't support `a^=0` (^= without a preceding space).
2023-07-15 14:10:40 -07:00
Roger Pau Monne
7cab385a8f [lld/elf] support quote usage in section names
Section names used in ELF linker scripts can be quoted, but such
quotes must not be propagated to the binary ELF section names.  As
such strip the quotes from the section names when processing them, and
also strip them from linker script functions that take section names
as parameters.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D124266
2023-07-05 14:56:16 -07:00
Fangrui Song
daba24ee7b [ELF] << >>: make RHS less than 64
The left/right shift linker script operators may trigger UB.
E.g. in linkerscript/end-overflow-check.test, the initial REGION1__PADDED_SR_SHIFT is
uint64_t(-3), cause the following expression to trigger an out-of-range shift in
a ubsan build of lld.

    REGION1__PADDED_SR_SIZE = MAX(1 << REGION1__PADDED_SR_SHIFT, 32);

Protect such UBs by making RHS less than 64.
2023-06-15 10:34:33 -07:00
Andreu Carminati
e4118a7ac0 [ELF] Fix early overflow check in finalizeAddressDependentContent
LLD terminates with errors when it detects overflows in the
finalizeAddressDependentContent calculation. Although, sometimes, those errors
are not really errors, but an intermediate result of an ongoing address
calculation.  If we continue the fixed-point algorithm we can converge to the
correct result.

This patch

* Removes the verification inside the fixed point algorithm.
* Calls checkMemoryRegions at the end.

Reviewed By: peter.smith, MaskRay

Differential Revision: https://reviews.llvm.org/D152170
2023-06-14 15:26:31 -07:00
Andreu Carminati
58789ed62a [ELF] Refine warning condition for memory region assignment for non-allocatable section
The warning "ignoring memory region assignment for non-allocatable section"  should be generated under the following conditions:

* sections without SHF_ALLOC attribute and,
* presence of input sections or data commands (ByteCommand)

The goal of the change is to reduce spurious warnings that are generated for some output sections that have no input section.

Reviewed By: MaskRay, peter.smith

Differential Revision: https://reviews.llvm.org/D151802
2023-06-14 15:23:14 -07:00
Fangrui Song
361a8226f9 [ELF][test] Add -NEXT and -NOT after D150644 (–-print-memory-usage) 2023-05-25 13:05:43 -07:00
Petr Hosek
811cbfc262 [lld][ELF] Implement –print-memory-usage
This option was introduced in GNU ld in
https://sourceware.org/legacy-ml/binutils/2015-06/msg00086.html and is
often used in embedded development. This change implements this option
in LLD matching the GNU ld output verbatim.

Differential Revision: https://reviews.llvm.org/D150644
2023-05-25 07:14:18 +00:00
Leonard Chan
b9249a69cc [lld][ELF] Do not emit warning for NOLOAD output sections
Much of NOLOAD's intended use is to explicitly change the type of an
output section, so we shouldn't flag these as warnings.

Differential Revision: https://reviews.llvm.org/D151144
2023-05-23 20:41:20 +00:00
Peter Smith
ca39168a7c [LLD][ELF] change CHECK to CHECK-NEXT in overlay-phdr.test NFCI
A code-review comment to change a couple of CHECK to CHECK-NEXT that I
forgot to apply prior to committing.

Differential Revision: https://reviews.llvm.org/D150445
2023-05-15 19:08:16 +01:00
Peter Smith
e16af8a281 [LLD][ELF] Add missing program header parsing to OVERLAY
In D72756 the change to add INPUT_SECTION_FLAGS inadvertantly
removed the line to parse the program header assignment information for
OutputSections within an OVERLAY.

This change adds back the missing line and adds a test for it.

Differential Revision: https://reviews.llvm.org/D150445
2023-05-15 10:04:33 +01:00
Justin Cady
447aa48b4a [ELF] Add REVERSE input section description keyword
The `REVERSE` keyword is described here:

https://sourceware.org/bugzilla/show_bug.cgi?id=27565

It complements `SORT` by allowing the order of input sections to be reversed.

This is particularly useful for order-dependent sections such as .init_array,
where `REVERSE` can be used to either detect static initialization order fiasco
issues or as a mechanism to maintain .ctors element order while transitioning to
the modern .init_array. Such a transition is described here:

https://discourse.llvm.org/t/is-it-possible-to-manually-specify-init-array-order/68649

Differential Revision: https://reviews.llvm.org/D145381
2023-03-07 12:44:02 -05:00
Fangrui Song
ffa1118330 [ELF] Mention section name for STT_SECTION in reportRangeError()
D73518 mentioned non-STT_SECTION symbol names. This patch extends the code to
handle STT_SECTION symbols, where we report the section name.
This change helps at least the following cases with very little code.

* Whether a out-of-range relocation is due to code or data.
* For a relocation in .debug_info, which referenced `.debug_*` section (due to DWARF32 limitation) causes the problem.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D145199
2023-03-03 12:35:05 -08:00
Peter Collingbourne
82c2fcffc2 ELF: Respect MEMORY command when specified without a SECTIONS command.
We were previously ignoring the MEMORY command unless SECTIONS was also
specified. Fix it.

Differential Revision: https://reviews.llvm.org/D145132
2023-03-01 22:40:32 -08:00
Ben Shi
366d34b39e [AVR][MC] Add ELF flag 'EF_AVR_LINKRELAX_PREPARED' to OBJ files
This is in accordance with avr-gcc, even '-mno-relax' is specified
to avr-gcc, this flag will also be added to the output relocatables.

With this flag set, the GNU ld will perform long call -> short call
optimization for AVR, otherwise not.

Fixes https://github.com/llvm/llvm-project/issues/54508

Reviewed By: MaskRay, jacquesguan, aykevl

Differential Revision: https://reviews.llvm.org/D144617
2023-02-24 11:16:42 +08:00
Fangrui Song
d60ef9338d [ELF] Support quoted output section names
Similar to e7a7ad134f and
2bf06d9345 for other linker script syntax.

Close https://github.com/llvm/llvm-project/issues/60496
2023-02-03 11:03:00 -08:00
Fangrui Song
926a77b76c [ELF][test] Clean up PT_OPENBSD tests 2022-11-19 18:51:35 +00:00
Daniel Thornburgh
75cdab6dc2 [llvm-objdump] Add --no-print-imm-hex to tests depending on it.
This prepares for an upcoming change to make --print-imm-hex the default
behavior of llvm-objdump. These tests were updated in a semi-automatic
fashion.

See D136972 for details.
2022-10-29 15:40:26 -07:00
Fangrui Song
1837333dac [ELF] --check-sections: allow address 0xffffffff for ELFCLASS32
Fix https://github.com/llvm/llvm-project/issues/58101
2022-10-01 15:37:07 -07:00
Fangrui Song
3b4d800911 [ELF] Parallelize writes of different OutputSections
We currently process one OutputSection at a time and for each OutputSection
write contained input sections in parallel. This strategy does not leverage
multi-threading well. Instead, parallelize writes of different OutputSections.

The default TaskSize for parallelFor often leads to inferior sharding. We
prepare the task in the caller instead.

* Move llvm::parallel::detail::TaskGroup to llvm::parallel::TaskGroup
* Add llvm::parallel::TaskGroup::execute.
* Change writeSections to declare TaskGroup and pass it to writeTo.

Speed-up with --threads=8:

* clang -DCMAKE_BUILD_TYPE=Release: 1.11x as fast
* clang -DCMAKE_BUILD_TYPE=Debug: 1.10x as fast
* chrome -DCMAKE_BUILD_TYPE=Release: 1.04x as fast
* scylladb build/release: 1.09x as fast

On M1, many benchmarks are a small fraction of a percentage faster. Mozilla showed the largest difference with the patch being about 1.03x as fast.

Differential Revision: https://reviews.llvm.org/D131247
2022-08-24 09:40:03 -07:00
Fangrui Song
85cfd91723 [ELF] Optimize some non-constant alignTo with alignToPowerOf2. NFC
My x86-64 lld executable is 2KiB smaller. .eh_frame writing gets faster as there
were lots of divisions.
2022-07-24 11:20:49 -07:00
Fangrui Song
b95cca03cd [ELF] Improve compound assignment tests
Also use strchr instead of is_contained.
2022-06-25 22:30:52 -07:00
Fangrui Song
0a0effdd5b [ELF] Support -= *= /= <<= >>= &= |= in symbol assignments 2022-06-25 22:22:59 -07:00
Fangrui Song
77295c5486 [ELF] Allow ? without adjacent space
GNU ld allows 1 ? 2?3:4 : 5?6 :7
2022-06-25 21:16:59 -07:00
Fangrui Song
e3f3d2abf0 [ELF][test] Improve expression test 2022-06-25 21:11:32 -07:00
Fangrui Song
21bf6bb3d3 [ELF] Fix assertion failure when PROVIDE/HIDDEN/PROVIDE_HIDDEN does not have = 2022-06-25 20:26:47 -07:00
Fangrui Song
fe0de25b21 [ELF] Allow an expression to follow = in a symbol assignment
GNU ld doesn't require whitespace before =. Match it.
2022-06-25 20:25:34 -07:00
Fangrui Song
b0d6dd3905 [ELF] Fix precedence of ? when there are 2 or more operators on the left hand side
For 1 != 1 <= 1 ? 1 : 2, the current code incorrectly considers that ?
has a higher precedence than != (minPrec).

Also, add a test for right associativity.
2022-06-25 13:48:52 -07:00
Fangrui Song
d479b2e4db [ELF] Fix precedence of == and != in expressions
In GNU ld, the == and != operators have lower precedence than < > <= >=.
This behavior matches C.
2022-06-25 13:47:32 -07:00
Fangrui Song
4cb05dc3cb [ELF] Support quoted name in the TARGET command 2022-06-25 12:31:20 -07:00
Fangrui Song
363b29567e [ELF] Support quoted symbol in the ENTRY command
This matches GNU ld and matches other places we unquote the symbol name.

Fixes #56208
2022-06-25 12:19:45 -07:00
Fangrui Song
c5578fca16 [ELF][test] Improve linkerscript/entry.s 2022-06-25 12:14:47 -07:00
Ben Shi
8527f32f0a [lld][ELF] Support BFD name elf32-avr
Reviewed By: MaskRay

differential Revision: https://reviews.llvm.org/D125544
2022-05-18 00:00:14 +00:00
Fangrui Song
912f5f7183 [ELF][test] Add an input section description test with "()" in the filename 2022-05-13 12:02:14 -07:00
Fangrui Song
82482e709f [ELF][test] Clean up linkerscript/{filename-spec.s,group.s} 2022-05-13 11:53:03 -07:00
Fangrui Song
177fd72f5f [ELF] Disallow input section description without a filename
GNU ld does not allow `.foo : { (*foo) }`, but we may recognize it as three
input section descriptions: file "(" with any section name, file "*foo" with
any section name, file ")" with any section name. Disallow the error-prone usage.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D125523
2022-05-13 11:06:01 -07:00
Fangrui Song
b3d5bb3b30 [ELF] Change (NOLOAD) type mismatch to use SHT_NOBITS instead of SHT_PROGBITS
Placing a non-SHT_NOBITS input section in an output section specified with
(NOLOAD) is fishy but used by some projects. D118840 changed the output type to
SHT_PROGBITS, but using the specified type seems to make more sense and improve
GNU ld compatibility: `(NOLOAD)` seems to change the output section type
regardless of input.

I think we should keep the current type mismatch warning as it does indicate an
error-prone usage.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D125074
2022-05-06 07:49:42 -07:00
Fangrui Song
5a44980f0a [ELF] Support custom sections between DATA_SEGMENT_ALIGN and DATA_SEGMENT_RELRO_END
We currently hard code RELRO sections. When a custom section is between
DATA_SEGMENT_ALIGN and DATA_SEGMENT_RELRO_END, we may report a spurious
`error: section: ... is not contiguous with other relro sections`. GNU ld
makes such sections RELRO.

glibc recently switched to default --with-default-link=no. This configuration
places `__libc_atexit` and others between DATA_SEGMENT_ALIGN and
DATA_SEGMENT_RELRO_END. This patch allows such a ld.bfd --verbose
linker script to be fed into lld.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D124656
2022-05-04 01:10:46 -07:00
Fangrui Song
4007756499 [ELF][test] Improve data-segment-relro.test 2022-04-28 22:29:39 -07:00
Fangrui Song
f4a3569d0a [ELF] Fix spurious GOT/PLT assertion failure when .dynsym is discarded
Linux kernel arch/arm64/kernel/vmlinux.lds.S discards .dynsym . D123985 triggers
a spurious assertion failure. Detect the case with
`!mainPart->dynSymTab->getParent()`.
2022-04-20 22:49:49 -07:00
Fangrui Song
1db59dc8e2 [ELF] Fix llvm_unreachable failure when COMMON is placed in SHT_PROGBITS output section
Fix a regression in aa27bab5a1: COMMON in an
SHT_PROGBITS output section caused llvm_unreachable failure.
2022-03-28 11:05:52 -07:00
Fangrui Song
93e2b59c07 [ELF][test] Avoid non-portable |& in notest.s 2022-02-18 12:32:27 -08:00
Fangrui Song
cb0a4bb5be [ELF] Change (NOLOAD) section type mismatch error to warning
Making a (NOLOAD) section SHT_PROGBITS is fishy (the user may expect all-zero
content, but the linker does not check that), but some projects (e.g. Linux
kernel https://github.com/ClangBuiltLinux/linux/issues/1597) traditionally rely
on the behavior. Issue a warning to not break them.
2022-02-18 11:20:36 -08:00
Fangrui Song
66f8ac8d36 [ELF] Support (TYPE=<value>) to customize the output section type
The current output section type allows to set the ELF section type to
SHT_PROGBITS or SHT_NOLOAD. This patch allows an arbitrary section value
to be specified. Some common SHT_* literal names are supported as well.

```
SECTIONS {
  note (TYPE=SHT_NOTE) : { BYTE(8) *(note) }
  init_array ( TYPE=14 ) : { QUAD(14) }
  fini_array (TYPE = SHT_FINI_ARRAY) : { QUAD(15) }
}
```

When `sh_type` is specified, it is an error if an input section has a different type.

Our syntax is compatible with GNU ld 2.39 (https://sourceware.org/bugzilla/show_bug.cgi?id=28841).

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D118840
2022-02-17 12:10:58 -08:00
Fangrui Song
fbf2f66400 [ELF] Update flag propagation rule to ignore discarded output sections
See the updated insert-before.test for the effects: many synthetic
sections are SHF_ALLOC|SHF_WRITE. If they are discarded, we don't want
to propagate their flags to subsequent output section descriptions.

`getFirstInputSection(sec) == nullptr` can technically be merged into
`isDiscardable` but I'd like to postpone that as not sharing code may give more
refactoring opportunity.

Depends on D118529.

Reviewed By: peter.smith, bluca

Differential Revision: https://reviews.llvm.org/D118530
2022-02-01 10:19:30 -08:00
Fangrui Song
a0318711c8 [ELF] Rename adjustSectionsBeforeSorting to adjustOutputSections and make it affect INSERT commands
adjustSectionsBeforeSorting updates some output section attributes
(alignment/flags) and removes discardable empty sections. When it is called,
INSERT commands have not been processed. Therefore the flags propagation rule
may not affect output sections defined in an INSERT command properly.

Fix this by moving processInsertCommands before adjustSectionsBeforeSorting.

adjustSectionsBeforeSorting is somewhat misnamed. The order between it and
sortInputSections does not matter. With the pass shuffle, the name of
adjustSectionsBeforeSorting becomes wrong. Therefore rename it. The new
name is not set into stone. The function mixes several tasks and the
code may be refactored in a way that we may give them more meaningful
names.

With this patch, I think the behavior of attribute propagation becomes more
reasonable. In particular, in the absence of non-INSERT SECTIONS,
inserting a section after a SHF_ALLOC one will give us a SHF_ALLOC section,
not a non-SHF_ALLOC one (see linkerscript/insert-after.test).

Reviewed By: peter.smith, bluca

Differential Revision: https://reviews.llvm.org/D118529
2022-02-01 10:16:12 -08:00
Fangrui Song
f097c108b8 [ELF][test] Improve INSERT [AFTER|BEFORE] and adjustSectionsBeforeSorting tests 2022-01-28 22:21:13 -08:00
Fangrui Song
b592cbf329 [ELF][test] Improve discard-gnu-hash.s to check DT_HASH and DT_GNU_HASH 2022-01-12 12:43:49 -08:00
Fangrui Song
bf9c8636f2 [ELF] Support discarding .relr.dyn
db08df0570 does not work because part.relrDyn is
a unique_ptr and `reset` destroys the object which may still be referenced.

This commit uses the D114180 approach. Also improve the test to check that there
is no R_X86_64_RELATIVE.
2022-01-12 11:55:22 -08:00
Fangrui Song
d8b7ae947d [ELF][test] Temporarily remove .relr.dyn test which is not working 2022-01-12 11:43:56 -08:00
Fangrui Song
f8476fd47b [llvm-ar][test] Test that --plugin is ignored 2022-01-12 11:32:31 -08:00