Commit Graph

960 Commits

Author SHA1 Message Date
Fangrui Song
bf81bd800f [ELF] Pass Ctx & 2024-10-10 21:36:51 -07:00
Fangrui Song
cfd3289a1f [ELF] Pass Ctx & to some free functions 2024-10-06 19:36:21 -07:00
Fangrui Song
b672071ba5 [ELF] Pass Ctx & to InputFile 2024-10-06 18:09:52 -07:00
Fangrui Song
5f6346190c [ELF] Pass Ctx & to SyntheticSections 2024-10-06 17:23:16 -07:00
Fangrui Song
3590068950 [ELF] Pass Ctx & to OutputSections 2024-10-03 20:06:58 -07:00
Fangrui Song
cc6c059dc1 [ELF] Pass Ctx & to Writer 2024-09-29 15:54:28 -07:00
Fangrui Song
df0864e761 [ELF] Move elf::symtab into Ctx
Remove the global variable `symtab` and add a member variable
(`std::unique_ptr<SymbolTable>`) to `Ctx` instead.

This is one step toward eliminating global states.

Pull Request: https://github.com/llvm/llvm-project/pull/109612
2024-09-23 10:33:43 -07:00
Fangrui Song
b8248dacad [ELF] Replace remnant config-> with ctx.arg. 2024-09-22 18:03:33 -07:00
Fangrui Song
9b7a22ebb5 [ELF] Replace config-> with ctx.arg. in LinkerScript 2024-09-21 10:28:23 -07:00
Fangrui Song
bb0a6f252f [ELF] Pass Ctx to LinkerScript. NFC 2024-09-21 10:22:11 -07:00
Fangrui Song
e88b7ff016 [ELF] Move InStruct into Ctx. NFC
Ctx was introduced in March 2022 as a more suitable place for such
singletons.

llvm/Support/thread.h includes <thread>, which transitively includes
sstream in libc++ and uses ios_base::in, so we cannot use `#define in ctx.sec`.

`symtab, config, ctx` are now the only variables using
LLVM_LIBRARY_VISIBILITY.
2024-09-15 22:15:02 -07:00
Fangrui Song
40e8e4ddcb [ELF] Move partitions into ctx. NFC
Ctx was introduced in March 2022 as a more suitable place for such
singletons.
2024-09-15 14:52:56 -07:00
Fangrui Song
b4feb26606 [ELF] Move target to Ctx. NFC
Ctx was introduced in March 2022 as a more suitable place for such
singletons.

Follow-up to driver (2022-10) and script (2024-08).
2024-08-21 23:53:36 -07:00
Fangrui Song
4629aa1797 [ELF] Move script into Ctx. NFC
Ctx was introduced in March 2022 as a more suitable place for such
singletons.

We now use default-initialization for `LinkerScript` and should pay
attention to non-class types (e.g. `dot` is initialized by commit
503907dc50).
2024-08-21 21:23:28 -07:00
Fangrui Song
796787d07c [ELF] Remove unneeded script->. NFC 2024-08-21 20:27:44 -07:00
Sam Elliott
9b65558d2f [lld][ELF] Combine uniqued small data sections (#104485)
RISC-V GCC with `-fdata-sections` will emit `.sbss.<name>`,
`.srodata.<name>`, and `.sdata.<name>` sections for small data items of
different kinds. Clang/LLVM already emits `.srodata.*` sections, and we
intend to emit the other two section name patterns in #87040.

This change ensures that any input sections starting `.sbss` are
combined into one output section called `.sbss`, and the same
respectively for `.srodata` and `.sdata`. This also allows the existing
RISC-V specific code for determining an output order for `.sbss` and
`.sdata` sections to apply to placing the sections.
2024-08-19 17:51:46 +01:00
Daniel Thornburgh
7e8a9020b1 [LLD] Add CLASS syntax to SECTIONS (#95323)
This allows the input section matching algorithm to be separated from
output section descriptions. This allows a group of sections to be
assigned to multiple output sections, providing an explicit version of
--enable-non-contiguous-regions's spilling that doesn't require altering
global linker script matching behavior with a flag. It also makes the
linker script language more expressive even if spilling is not intended,
since input section matching can be done in a different order than
sections are placed in an output section.

The implementation reuses the backend mechanism provided by
--enable-non-contiguous-regions, so it has roughly similar semantics and
limitations. In particular, sections cannot be spilled into or out of
INSERT, OVERWRITE_SECTIONS, or /DISCARD/. The former two aren't
intrinsic, so it may be possible to relax those restrictions later.
2024-08-05 13:06:45 -07:00
Fangrui Song
2fe3bbdf67 [ELF] Move outputSections into Ctx. NFC
Ctx was introduced in March 2022 as a more suitable place for such
singletons.
2024-08-03 11:50:48 -07:00
Fangrui Song
09dd0febbb [ELF] Move Out into Ctx. NFC
Ctx was introduced in March 2022 as a more suitable place for such
singletons. ctx's hidden visibility optimizes generated instructions.

bufferStart and tlsPhdr, which are not OutputSection, can now be moved
outside of `Out`.
2024-08-03 11:00:11 -07:00
Fangrui Song
0af07c0787 [ELF] Support relocatable files using CREL with explicit addends
... using the temporary section type code 0x40000020
(`clang -c -Wa,--crel,--allow-experimental-crel`). LLVM will change the
code and break compatibility (Clang and lld of different versions are
not guaranteed to cooperate, unlike other features). CREL with implicit
addends are not supported.

---

Introduce `RelsOrRelas::crels` to iterate over SHT_CREL sections and
update users to check `crels`.

(The decoding performance is critical and error checking is difficult.
Follow `skipLeb` and `R_*LEB128` handling, do not use
`llvm::decodeULEB128`, whichs compiles to a lot of code.)

A few users (e.g. .eh_frame, LLDDwarfObj, s390x) require random access. Pass
`/*supportsCrel=*/false` to `relsOrRelas` to allocate a buffer and
convert CREL to RELA (`relas` instead of `crels` will be used). Since
allocating a buffer increases, the conversion is only performed when
absolutely necessary.

---

Non-alloc SHT_CREL sections may be created in -r and --emit-relocs
links. SHT_CREL and SHT_RELA components need reencoding since
r_offset/r_symidx/r_type/r_addend may change. (r_type may change because
relocations referencing a symbol in a discarded section are converted to
`R_*_NONE`).

* SHT_CREL components: decode with `RelsOrRelas` and re-encode (`OutputSection::finalizeNonAllocCrel`)
* SHT_RELA components: convert to CREL (`relToCrel`). An output section can only have one relocation section.
* SHT_REL components: print an error for now.

SHT_REL to SHT_CREL conversion for -r/--emit-relocs is complex and
unsupported yet.

Link: https://discourse.llvm.org/t/rfc-crel-a-compact-relocation-format-for-elf/77600

Pull Request: https://github.com/llvm/llvm-project/pull/98115
2024-08-01 10:22:03 -07:00
Fangrui Song
fdd3196553 [ELF] Make start/stop symbols retain associated discardable output sections
An empty output section specified in the `SECTIONS` command (e.g.
`empty : { *(empty) }`) may be discarded. Due to phase ordering, we
might define `__start_empty`/`__stop_empty` symbols with incorrect
section indexes (usually benign, but could go out of bounds and cause
`readelf -s` to print `BAD`).

```
finalizeSections
  addStartStopSymbols     // __start_empty is defined
  // __start_empty is added to .symtab
  sortSections
    adjustOutputSections  // `empty` is discarded
writeSections
  // __start_empty is Defined with an invalid section index
```

Loaders use `st_value` members of the start/stop symbols and expect no
"undefined symbol" linker error, but do not particularly care whether
the symbols are defined or undefined. Let's retain the associated empty
output section so that start/stop symbols will have correct section
indexes.

The approach allows us to remove `LinkerScript::isDiscarded`
(https://reviews.llvm.org/D114179). Also delete the
`findSection(".text")` special case from https://reviews.llvm.org/D46200,
which is unnecessary even before this patch (`elfHeader` would be fine
even with very large executables).

Note: we should be careful not to unnecessarily retain .ARM.exidx, which
would create an empty PT_ARM_EXIDX. ~40 tests would need to be updated.

---

An alternative is to discard the empty output section and keep the
start/stop symbols undefined. This approach needs more code and requires
`LinkerScript::isDiscarded` before we discard empty sections in
``adjustOutputSections`.

Pull Request: https://github.com/llvm/llvm-project/pull/96343
2024-07-02 10:58:24 -07:00
Fangrui Song
ee4c12f87d [ELF] Postpone more linker script errors
Since `assignAddresses` is executed more than once, error reporting
during `assignAddresses` would be duplicated. Generalize #66854 to cover
more errors.

Note: address-related errors exposed in one invocation might not be
errors in another invocation.

Pull Request: https://github.com/llvm/llvm-project/pull/96361
2024-06-24 10:15:28 -07:00
Fangrui Song
7b6a89f346 [ELF] Detect convergence of output section addresses
Some linker scripts don't converge. https://reviews.llvm.org/D66279
("[ELF] Make LinkerScript::assignAddresses iterative") detected
convergence of symbol assignments.

This patch detects convergence of output section addresses. While input
sections might also have convergence issues, they are less common as
expressions that could cause convergence issues typically involve output
sections and symbol assignments.

GNU ld has an error `non constant or forward reference address expression for section` that
correctly rejects
```
SECTIONS {
  .text ADDR(.data)+0x1000 : { *(.text) }
  .data : { *(.data) }
}
```

but not the following variant:
```
SECTIONS {
  .text foo : { *(.text) }
  .data : { *(.data) }
  foo = ADDR(.data)+0x1000;
}
```

Our approach consistently rejects both cases.

Link: https://discourse.llvm.org/t/lld-and-layout-convergence/79232

Pull Request: https://github.com/llvm/llvm-project/pull/93888
2024-05-31 09:31:15 -07:00
Fangrui Song
d5f077cf52 [ELF] Simplify assignOffsets. NFC 2024-05-30 14:27:47 -07:00
Fangrui Song
3bdc90e3ff [ELF] adjustOutputSections: update sortRank. NFC
... as flags have changed. This allows us to revisit the
`osd->osec.hasInputSections` condition in `getRankProximity` (originally
introduced as `Sec->Live` in https://reviews.llvm.org/D61197).
2024-05-29 14:56:43 -07:00
Igor Kudrin
34b14cc4f8 [lld][ELF] Suppress --orphan-handling=error/warn without SECTIONS (#93630)
Without a linker script, `--orphan-handling=error` or `=warn` reports
all input sections, including even well-known sections like `.text`,
`.bss`, `.dynamic`, or `.symtab`. However, in this case, no sections
should be considered orphans because they all are placed with the same
default rules. This patch suppresses errors/warnings for placing orphan
sections if no linker script with the `SECTIONS` command is provided.

The proposed behavior matches GNU gold. GNU ld in the same scenario only
reports sections that are not in its default linker script, thus, it
avoids complaining about `.text` and similar.
2024-05-29 14:53:29 -07:00
Daniel Thornburgh
66466ff151 Reland: [LLD] Implement --enable-non-contiguous-regions (#90007)
When enabled, input sections that would otherwise overflow a memory
region are instead spilled to the next matching output section.

This feature parallels the one in GNU LD, but there are some differences
from its documented behavior:

- /DISCARD/ only matches previously-unmatched sections (i.e., the flag
does not affect it).

- If a section fails to fit at any of its matches, the link fails
instead of discarding the section.

- The flag --enable-non-contiguous-regions-warnings is not implemented,
as it exists to warn about such occurrences.

The implementation places stubs at possible spill locations, and
replaces them with the original input section when effecting spills.
Spilling decisions occur after address assignment. Sections are spilled
in reverse order of assignment, with each spill naively decreasing the
size of the affected memory regions. This continues until the memory
regions are brought back under size. Spilling anything causes another
pass of address assignment, and this continues to fixed point.

Spilling after rather than during assignment allows the algorithm to
consider the size effects of unspillable input sections that appear
later in the assignment. Otherwise, such sections (e.g. thunks) may
force an overflow, even if spilling something earlier could have avoided
it.

A few notable feature interactions occur:

- Stubs affect alignment, ONLY_IF_RO, etc, broadly as if a copy of the
input section were actually placed there.

- SHF_MERGE synthetic sections use the spill list of their first
contained input section (the one that gives the section its name).

- ICF occurs oblivious to spill sections; spill lists for merged-away
sections become inert and are removed after assignment.

- SHF_LINK_ORDER and .ARM.exidx are ordered according to the final
section ordering, after all spilling has completed.

- INSERT BEFORE/AFTER and OVERWRITE_SECTIONS are explicitly disallowed.
2024-05-13 11:06:54 -07:00
Daniel Thornburgh
81f34afa5c Revert "[LLD] Implement --enable-non-contiguous-regions" (#92005)
Reverts llvm/llvm-project#90007

Broke in merging I think.
2024-05-13 10:38:40 -07:00
Daniel Thornburgh
673114447b [LLD] Implement --enable-non-contiguous-regions (#90007)
When enabled, input sections that would otherwise overflow a memory
region are instead spilled to the next matching output section.

This feature parallels the one in GNU LD, but there are some differences
from its documented behavior:

- /DISCARD/ only matches previously-unmatched sections (i.e., the flag
does not affect it).

- If a section fails to fit at any of its matches, the link fails
instead of discarding the section.

- The flag --enable-non-contiguous-regions-warnings is not implemented,
as it exists to warn about such occurrences.

The implementation places stubs at possible spill locations, and
replaces them with the original input section when effecting spills.
Spilling decisions occur after address assignment. Sections are spilled
in reverse order of assignment, with each spill naively decreasing the
size of the affected memory regions. This continues until the memory
regions are brought back under size. Spilling anything causes another
pass of address assignment, and this continues to fixed point.

Spilling after rather than during assignment allows the algorithm to
consider the size effects of unspillable input sections that appear
later in the assignment. Otherwise, such sections (e.g. thunks) may
force an overflow, even if spilling something earlier could have avoided
it.

A few notable feature interactions occur:

- Stubs affect alignment, ONLY_IF_RO, etc, broadly as if a copy of the
input section were actually placed there.

- SHF_MERGE synthetic sections use the spill list of their first
contained input section (the one that gives the section its name).

- ICF occurs oblivious to spill sections; spill lists for merged-away
sections become inert and are removed after assignment.

- SHF_LINK_ORDER and .ARM.exidx are ordered according to the final
section ordering, after all spilling has completed.

- INSERT BEFORE/AFTER and OVERWRITE_SECTIONS are explicitly disallowed.
2024-05-13 10:30:50 -07:00
Fangrui Song
65c9b8460b [Driver] Remove elf::script indirection. NFC
There are 100+ references.
Use a wrapper similar to a623a4c8b4
2024-05-10 19:45:42 -07:00
luolent
a98a6e95be Add clarifying parenthesis around non-trivial conditions in ternary expressions. (#90391)
Fixes [#85868](https://github.com/llvm/llvm-project/issues/85868)

Parenthesis are added as requested on ternary operators with non trivial conditions.

I used this [precedence table](https://en.cppreference.com/w/cpp/language/operator_precedence) for reference, to make sure we get the expected behavior on each change.
2024-05-04 18:38:45 +01:00
Parth Arora
ebb326a51f [ELF] Fix unnecessary inclusion of unreferenced provide symbols
Previously, linker was unnecessarily including a PROVIDE symbol which
was referenced by another unused PROVIDE symbol. For example, if a
linker script contained the below code and 'not_used_sym' provide symbol
is not included, then linker was still unnecessarily including 'foo' PROVIDE
symbol because it was referenced by 'not_used_sym'. This commit fixes
this behavior.

PROVIDE(not_used_sym = foo)
PROVIDE(foo = 0x1000)

This commit fixes this behavior by using dfs-like algorithm to find
all the symbols referenced in provide expressions of included provide
symbols.

This commit also fixes the issue of unused section not being garbage-collected
if a symbol of the section is referenced by an unused PROVIDE symbol.

Closes #74771
Closes #84730

Co-authored-by: Fangrui Song <i@maskray.me>
2024-03-25 16:11:21 -07:00
Fangrui Song
0e47dfede4 [ELF] Add isStaticRelSecType to simplify SHT_REL/SHT_RELA testing. NFC
and make it easier to introduce a new relocation format.

https://discourse.llvm.org/t/rfc-relleb-a-compact-relocation-format-for-elf/77600

Pull Request: https://github.com/llvm/llvm-project/pull/85893
2024-03-20 09:58:56 -07:00
Fangrui Song
43b13341fb [ELF] Add internal InputFile (#78944)
Based on https://reviews.llvm.org/D45375 . Introduce a new InputFile
kind `InternalKind`, use it for

* `ctx.internalFile`: for linker-defined symbols and some synthesized
`Undefined`
* `createInternalFile`: for symbol assignments and --defsym

I picked "internal" instead of "synthetic" to avoid confusion with
SyntheticSection.

Currently a symbol's file is one of: nullptr, ObjKind, SharedKind,
BitcodeKind, BinaryKind. Now it's non-null (I plan to add an
`assert(file)` to Symbol::Symbol and change `toString(const InputFile
*)`
separately).

Debugging and error reporting gets improved. The immediate user-facing
difference is more descriptive "File" column in the --cref output. This
patch may unlock further simplification.

Currently each symbol assignment gets its own
`createInternalFile(cmd->location)`. Two symbol assignments in a linker
script do not share the same file. Making the file the same would be
nice, but would require non trivial code.
2024-01-22 09:09:46 -08:00
Fangrui Song
0930f62cf6 [ELF] -r: fix crash when SHF_LINK_ORDER linked-to section has a larger index
Fixes: b8dface221

ThinLTO asan build may place `asan_globals` before the associated `.bss.xxx` section.
`rel->getOutputSection()` is nullptr because `rel->parent` hasn't been
set, leading to a crash. Simplify return `s->name` in this case.
2024-01-08 21:13:27 -08:00
Fangrui Song
b8dface221 [ELF] -r: rename orphan SHT_REL/SHT_RELA when the relocated input section is placed in an output section
This ports https://reviews.llvm.org/D40652 (--emit-relocs) to -r and
matches GNU ld.
Close #67910
2023-11-17 22:38:15 -08:00
Fangrui Song
a40f651a06 [ELF] adjustOutputSections: don't copy SHF_EXECINSTR when an output does not contain input sections (#70911)
For an output section with no input section, GNU ld eliminates the
output section when there are only symbol assignments (e.g.
`.foo : { symbol = 42; }`) but not for `.foo : { . += 42; }`
(`SHF_ALLOC|SHF_WRITE`).

We choose to retain such an output section with a symbol assignment
(unless unreferenced `PROVIDE`). We copy the previous section flag (see
https://reviews.llvm.org/D37736) to hopefully make the current PT_LOAD
segment extend to the current output section:

* decrease the number of PT_LOAD segments
* If a new PT_LOAD segment is introduced without a page-size
  alignment as a separator, there may be a run-time crash.

However, this `flags` copying behavior is not suitable for
`.foo : { . += 42; }` when `flags` contains `SHF_EXECINSTR`. The
executable bit is surprising

(https://discourse.llvm.org/t/lld-output-section-flag-assignment-behavior/74359).

I think we should drop SHF_EXECINSTR when copying `flags`. The risk is a
code section followed by `.foo : { symbol = 42; }` will be broken, which
I believe is unrelated as such uses are almost always related to data
sections.

For data-command-only output sections (e.g. `.foo : { QUAD(42) }`), we
keep allowing copyable SHF_WRITE.

Some tests are updated to drop the SHF_EXECINSTR flag. GNU ld doesn't
set SHF_EXECINSTR as well, though it sets SHF_WRITE for some tests while
we don't.
2023-11-01 22:35:28 -07:00
Fangrui Song
ec0e556e67 [ELF] Merge copyLocalSymbols and demoteLocalSymbolsInDiscardedSections (#69425)
Follow-up to #69295: In `Writer<ELFT>::run`, the symbol passes are
flexible:
they can be placed almost everywhere before `scanRelocations`, with a
constraint
that the `computeIsPreemptible` pass must be invoked for linker-defined
non-local symbols.

Merge copyLocalSymbols and demoteLocalSymbolsInDiscardedSections to
simplify
code:

* Demoting local symbols can be made unconditional, not constrainted to
/DISCARD/ uses due to performance concerns
* `includeInSymtab` can be made faster
* Make symbol passes close to each other
* Decrease data cache misses due to saving an iteration over local
symbols

There is no speedup, likely due to the unconditional `dr->section`
access in `demoteAndCopyLocalSymbols`.

`gc-sections-tls.s` no longer reports an error because the TLS symbol is
converted to an Undefined.
2023-10-18 08:56:17 -07:00
Fangrui Song
1981b1b6b9 [ELF] Demote symbols in /DISCARD/ discarded sections to Undefined (#69295)
When an input section is matched by /DISCARD/ in a linker script, GNU ld
reports errors for relocations referencing symbols defined in the section:

    `.aaa' referenced in section `.bbb' of a.o: defined in discarded section `.aaa' of a.o

Implement the error by demoting eligible symbols to `Undefined` and changing
STB_WEAK to STB_GLOBAL. As a side benefit, in relocatable links, relocations
referencing symbols defined relative to /DISCARD/ discarded sections no longer
set symbol/type to zeros.

It's arguable whether a weak reference to a discarded symbol should lead to
errors. GNU ld reports an error and our demoting approach reports an error as
well.

Close #58891

Co-authored-by: Bevin Hansson <bevin.hansson@ericsson.com>
2023-10-17 14:10:52 -07:00
Fangrui Song
0de0b6dded [ELF] Postpone "unable to move location counter backward" error (#66854)
The size of .ARM.exidx may shrink across `assignAddress` calls. It is
possible
that the initial iteration has a larger location counter, causing
`__code_size =
__code_end - .; osec : { . += __code_size; }` to report an error, while
the error would
have been suppressed for subsequent `assignAddress` iterations.

Other sections like .relr.dyn may change sizes across `assignAddress`
calls as
well. However, their initial size is zero, so it is difficiult to
trigger a
similar error.

Similar to https://reviews.llvm.org/D152170, postpone the error
reporting.
Fix #66836. While here, add more information to the error message.
2023-09-20 09:06:45 -07:00
Fangrui Song
9eb1f2d0ac [ELF] Remove a special case from ExprValue::getSectionOffset. NFC
The special cases added by https://reviews.llvm.org/D42911
(defsym-reserved-syms.s) are unneeded after https://reviews.llvm.org/D66717
2023-09-15 17:45:52 -07:00
Fangrui Song
5a58e98c20 [ELF] Align the end of PT_GNU_RELRO associated PT_LOAD to a common-page-size boundary (#66042)
Close #57618: currently we align the end of PT_GNU_RELRO to a
common-page-size
boundary, but do not align the end of the associated PT_LOAD. This is
benign
when runtime_page_size >= common-page-size.

However, when runtime_page_size < common-page-size, it is possible that
`alignUp(end(PT_LOAD), page_size) < alignDown(end(PT_GNU_RELRO),
page_size)`.
In this case, rtld's mprotect call for PT_GNU_RELRO will apply to
unmapped
regions and lead to an error, e.g.

```
error while loading shared libraries: cannot apply additional memory protection after relocation: Cannot allocate memory
```

To fix the issue, add a padding section .relro_padding like mold, which
is contained in the PT_GNU_RELRO segment and the associated PT_LOAD
segment. The section also prevents strip from corrupting PT_LOAD program
headers.

.relro_padding has the largest `sortRank` among RELRO sections.
Therefore, it is naturally placed at the end of `PT_GNU_RELRO` segment
in the absence of `PHDRS`/`SECTIONS` commands.

In the presence of `SECTIONS` commands, we place .relro_padding
immediately before a symbol assignment using DATA_SEGMENT_RELRO_END (see
also https://reviews.llvm.org/D124656), if present.
DATA_SEGMENT_RELRO_END is changed to align to max-page-size instead of
common-page-size.

Some edge cases worth mentioning:

* ppc64-toc-addis-nop.s: when PHDRS is present, do not append
.relro_padding
* avoid-empty-program-headers.s: when the only RELRO section is .tbss,
it is not part of PT_LOAD segment, therefore we do not append
.relro_padding.

---

Close #65002: GNU ld from 2.39 onwards aligns the end of PT_GNU_RELRO to
a
max-page-size boundary (https://sourceware.org/PR28824) so that the last
page is
protected even if runtime_page_size > common-page-size.

In my opinion, losing protection for the last page when the runtime page
size is
larger than common-page-size is not really an issue. Double mapping a
page of up
to max-common-page for the protection could cause undesired VM waste.
Internally
we had users complaining about 2MiB max-page-size applying to shared
objects.

Therefore, the end of .relro_padding is padded to a common-page-size
boundary. Users who are really anxious can set common-page-size to match
their runtime page size.

---

17 tests need updating as there are lots of change detectors.
2023-09-14 10:33:11 -07:00
Fangrui Song
65a15a56d5 [ELF] Respect orders of symbol assignments and DEFINED (#65866)
Fix #64600: the currently implementation is minimal (see
https://reviews.llvm.org/D83758), and an assignment like
`__TEXT_REGION_ORIGIN__ = DEFINED(__TEXT_REGION_ORIGIN__) ? __TEXT_REGION_ORIGIN__ : 0;`
(used by avr-ld[1]) leads to a value of zero (default value in `declareSymbol`),
which is unexpected.

Assign orders to symbol assignments and references so that
for a script-defined symbol, the `DEFINED` results match users'
expectation. I am unclear about GNU ld's exact behavior, but this hopefully
matches its behavior in the majority of cases.

[1]: https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=ld/scripttempl/avr.sc
2023-09-11 10:54:49 -07:00
Amilendra Kodithuwakku
9acbab60e5 [LLD][ELF] Cortex-M Security Extensions (CMSE) Support
This commit provides linker support for Cortex-M Security Extensions (CMSE).
The specification for this feature can be found in ARM v8-M Security Extensions:
Requirements on Development Tools.

The linker synthesizes a security gateway veneer in a special section;
`.gnu.sgstubs`, when it finds non-local symbols `__acle_se_<entry>` and `<entry>`,
defined relative to the same text section and having the same address. The
address of `<entry>` is retargeted to the starting address of the
linker-synthesized security gateway veneer in section `.gnu.sgstubs`.

In summary, the linker translates input:

```
    .text
  entry:
  __acle_se_entry:
    [entry_code]

```
into:

```
    .section .gnu.sgstubs
  entry:
    SG
    B.W __acle_se_entry

    .text
  __acle_se_entry:
    [entry_code]
```

If addresses of `__acle_se_<entry>` and `<entry>` are not equal, the linker
considers that `<entry>` already defines a secure gateway veneer so does not
synthesize one.

If `--out-implib=<out.lib>` is specified, the linker writes the list of secure
gateway veneers into a CMSE import library `<out.lib>`. The CMSE import library
will have 3 sections: `.symtab`, `.strtab`, `.shstrtab`. For every secure gateway
veneer <entry> at address `<addr>`, `.symtab` contains a `SHN_ABS` symbol `<entry>` with
value `<addr>`.

If `--in-implib=<in.lib>` is specified, the linker reads the existing CMSE import
library `<in.lib>` and preserves the entry function addresses in the resulting
executable and new import library.

Reviewed By: MaskRay, peter.smith

Differential Revision: https://reviews.llvm.org/D139092
2023-07-06 11:34:07 +01:00
Mitch Phillips
cd116e0460 Revert "Revert "Revert "[LLD][ELF] Cortex-M Security Extensions (CMSE) Support"""
This reverts commit 9246df7049.

Reason: This patch broke the UBSan buildbots. See more information in
the original phabricator review: https://reviews.llvm.org/D139092
2023-06-22 14:33:57 +02:00
Amilendra Kodithuwakku
9246df7049 Revert "Revert "[LLD][ELF] Cortex-M Security Extensions (CMSE) Support""
This reverts commit a685ddf1d1.

This relands Arm CMSE support (D139092) and fixes the GCC build bot errors.
2023-06-21 22:27:13 +01:00
Amilendra Kodithuwakku
a685ddf1d1 Revert "[LLD][ELF] Cortex-M Security Extensions (CMSE) Support"
This reverts commit c4fea39056.

I am reverting this for now until I figure out how to fix
the build bot errors and warnings.

Errors:
llvm-project/lld/ELF/Arch/ARM.cpp:1300:29: error: expected primary-expression before ‘>’ token
 osec->writeHeaderTo<ELFT>(++sHdrs);

Warnings:
llvm-project/lld/ELF/Arch/ARM.cpp:1306:31: warning: left operand of comma operator has no effect [-Wunused-value]
2023-06-21 16:13:44 +01:00
Amilendra Kodithuwakku
c4fea39056 [LLD][ELF] Cortex-M Security Extensions (CMSE) Support
This commit provides linker support for Cortex-M Security Extensions (CMSE).
The specification for this feature can be found in ARM v8-M Security Extensions:
Requirements on Development Tools.

The linker synthesizes a security gateway veneer in a special section;
`.gnu.sgstubs`, when it finds non-local symbols `__acle_se_<entry>` and `<entry>`,
defined relative to the same text section and having the same address. The
address of `<entry>` is retargeted to the starting address of the
linker-synthesized security gateway veneer in section `.gnu.sgstubs`.

In summary, the linker translates input:

```
    .text
  entry:
  __acle_se_entry:
    [entry_code]

```
into:

```
    .section .gnu.sgstubs
  entry:
    SG
    B.W __acle_se_entry

    .text
  __acle_se_entry:
    [entry_code]
```

If addresses of `__acle_se_<entry>` and `<entry>` are not equal, the linker
considers that `<entry>` already defines a secure gateway veneer so does not
synthesize one.

If `--out-implib=<out.lib>` is specified, the linker writes the list of secure
gateway veneers into a CMSE import library `<out.lib>`. The CMSE import library
will have 3 sections: `.symtab`, `.strtab`, `.shstrtab`. For every secure gateway
veneer <entry> at address `<addr>`, `.symtab` contains a `SHN_ABS` symbol `<entry>` with
value `<addr>`.

If `--in-implib=<in.lib>` is specified, the linker reads the existing CMSE import
library `<in.lib>` and preserves the entry function addresses in the resulting
executable and new import library.

Reviewed By: MaskRay, peter.smith

Differential Revision: https://reviews.llvm.org/D139092
2023-06-21 14:47:34 +01: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