`clang -g -gpubnames -fdebug-types-section` now emits .debug_names
section with references to local type unit entries defined in COMDAT
.debug_info sections.
```
.section .debug_info,"G",@progbits,5657452045627120676,comdat
.Ltu_begin0:
...
.section .debug_names,"",@progbits
...
// DWARF32
.long .Ltu_begin0 # Type unit 0
// DWARF64
// .long .Ltu_begin0 # Type unit 0
```
When `.Ltu_begin0` is relative to a non-prevailing .debug_info section,
the relocation resolves to 0, which is a valid offset within the
.debug_info section.
```
cat > a.cc <<e
struct A { int x; };
inline A foo() { return {1}; }
int main() { foo(); }
e
cat > b.cc <<e
struct A { int x; };
inline A foo() { return {1}; }
void use() { foo(); }
e
clang++ -g -gpubnames -fdebug-types-section -fuse-ld=lld a.cc b.cc -o old
```
```
% llvm-dwarfdump old
...
Local Type Unit offsets [
LocalTU[0]: 0x00000000
]
...
Local Type Unit offsets [
LocalTU[0]: 0x00000000 // indistinguishable from a valid offset within .debug_info
]
```
https://dwarfstd.org/issues/231013.1.html proposes that we use a
tombstone value instead to inform consumers. This patch implements the
idea. The second LocalTU entry will now use 0xffffffff.
https://reviews.llvm.org/D84825 has a TODO that we should switch the
tombstone value for most `.debug_*` sections to UINT64_MAX. We have
postponed the change for more than three years for consumers to migrate.
At some point we shall make the change, so that .debug_names is no long
different from other debug section that is not .debug_loc/.debug_ranges.
Co-authored-by: Alexander Yermolovich <ayermolo@meta.com>
Non-LTO compiles set the buffer name to "<inline asm>"
(`AsmPrinter::addInlineAsmDiagBuffer`) and pass diagnostics to
`ClangDiagnosticHandler` (through the `MCContext` handler in
`MachineModuleInfoWrapperPass::doInitialization`) to ensure that
the exit code is 1 in the presence of errors. In contrast, LTO compiles
spuriously succeed even if error messages are printed.
```
% cat a.c
void _start() {}
asm("unknown instruction");
% clang -c a.c
<inline asm>:1:1: error: invalid instruction mnemonic 'unknown'
1 | unknown instruction
| ^
1 error generated.
% clang -c -flto a.c; echo $? # -flto=thin is the same
error: invalid instruction mnemonic 'unknown'
unknown instruction
^~~~~~~
error: invalid instruction mnemonic 'unknown'
unknown instruction
^~~~~~~
0
```
`CollectAsmSymbols` parses inline assembly and is transitively called by
both `ModuleSummaryIndexAnalysis::run` and `WriteBitcodeToFile`, leading
to duplicate diagnostics.
This patch updates `CollectAsmSymbols` to be similar to non-LTO
compiles.
```
% clang -c -flto=thin a.c; echo $?
<inline asm>:1:1: error: invalid instruction mnemonic 'unknown'
1 | unknown instruction
| ^
1 errors generated.
1
```
The `HasErrors` check does not prevent duplicate warnings but assembler
warnings are very uncommon.
It is beneficial to preallocate a certain number of pages in the linear
memory (i. e. use the "minimum" field of WASM memories) so that fewer
"memory.grow"s are needed at startup.
So far, the way to do that has been to pass the "--initial-memory"
option to the linker. It works, but has the very significant downside of
requiring the user to know the size of static data beforehand, as it
must not exceed the number of bytes passed-in as "--initial-memory".
The new "--initial-heap" option avoids this downside by simply appending
the specified number of pages to static data (and stack), regardless of
how large they already are.
Ref: https://github.com/emscripten-core/emscripten/issues/20888.
This allows avoiding including some stray DWARF sections (e.g. from
toolchain provided files), when writing a PDB file.
While that probably could be considered reasonable default behaviour,
PDB writing and including DWARF sections are two entirely orthogonal
concepts, and GNU ld (which can generate PDB files these days) does
include DWARF unless -S/-s is passed, when creating a PDB.
Most option handling is like it was before; the last /debug: option
takes effect.
However, the options /debug:dwarf or /debug:symtab don't reset all flags
into the specific behaviour they chose before - e.g. if an earlier
option enables writing a PDB, a later /debug:dwarf or /debug:symtab
doesn't disable that. This allows combining these options with options
for controlling PDB writing, for finetuning what is done.
Don't treat the options as unique enum items, but more as flags that can
be composed, like the /opt: options.
This still only processes the last option on the command line though, so
the behaviour should still remain exactly as it was, in all corner
cases.
This shouldn't have any user visible effect, but makes the logic within
the linker implementation more explicit.
Note how DWARF debug info sections were retained even if enabling a link
with PDB info only; that behaviour is preserved.
After #71433, lld-link is able to always generate build id even when PDB
is not generated.
This adds the `__buildid` symbol to points to the start of 16 bytes guid
(which is after `RSDS`) and allows profile runtime to access it and dump
it to raw profile.
This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.
I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
Branch-absolute instructions are currently printed in decimal, and
negative addresses are printed as positive numbers.
With this change, addresses are printed in hex and negative addresses
are converted to an unsigned 32- or 64-bit address.
Copy relocations and canonical PLT entries are for symbols defined in a
DSO. Currently we create them even for a `Defined`, possibly leading to
an output that won't work at run-time (e.g. R_X86_64_JUMP_SLOT
referencing a null symbol).
```
% cat a.s
.globl _start, main
.type main, @function
_start: main: ret
.rodata
.quad main
% clang -fuse-ld=lld -pie -nostdlib a.s
% readelf -Wr a.out
Relocation section '.rela.plt' at offset 0x290 contains 1 entry:
Offset Info Type Symbol's Value Symbol's Name + Addend
00000000000033b8 0000000000000007 R_X86_64_JUMP_SLOT 12b0
```
Report an error instead for the default `-z text` mode. GNU ld reports
an error in `-z text` mode as well.
This patch renames {starts,ends}with to {starts,ends}_with for
consistency with std::{string,string_view}::{starts,ends}_with in
C++20. Since there are only a handful of occurrences, this patch
skips the deprecation phase and simply renames them.
relocateNonAlloc is costly for .debug_* section relocating. We don't
want to burn CPU cycles on other targets' workarounds.
Remove a temporary workaround for Linux objtool after a proper fix
https://git.kernel.org/linus/b8ec60e1186cdcfce41e7db4c827cb107e459002
Move the R_386_GOTPC workaround for GCC<8 beside the R_PC workaround.
Add 32-bit test for -z dead-reloc-in-nonalloc= and add tests for a
non-x86 64-bit (x86-64 is unique in discerning signed/unsigned 32-bit
absolute relocations (R_X86_64_32/R_X86_64_32S).
AArch64/PPC64/RISC-V/etc don't have the distinction). Having a test will
improve coverage for #74686
[RFC](https://discourse.llvm.org/t/rfc-add-build-id-flag-to-lld-link/74661)
Before, lld-link only generate the debug directory containing guid when
generating PDB with the hash of PDB content.
With this change, lld-link can generate the debug directory when only
`/build-id` is given:
1. If generating PDB, `/build-id` is ignored. Same behaviour as before.
2. Not generating PDB, using hash of the binary.
- Not under MinGW, the debug directory is still in `.rdata` section.
- Under MinGW, place the debug directory into new `.buildid` section.
ARM64EC needs to handle both ARM and x86_64 exception tables. This is
achieved by separating their chunks and sorting them separately.
EXCEPTION_TABLE directory references x86_64 variant, while ARM variant
is exposed using CHPE metadata, which references
__arm64x_extra_rfe_table and __arm64x_extra_rfe_table_size symbols.
This redoes the fix from 3ab6209a3f
differently, without the unwanted effect of preserving unnecessary
`__imp_` prefixed symbols.
If the referencing object is a regular object, the `__imp_` symbol will
have `isUsedInRegularObj` set on it from that already. If the
referencing object is an LTO object, we set `isUsedInRegularObj` for any
symbol starting with `__imp_`.
If the object file defining the `__imp_` symbol is a regular object, the
`isUsedInRegularObj` flag has no effect. If it is an LTO object, it
causes the symbol to be preserved.
This fixes a mis-link when mixing compressed and non-compressed input to
LLD. When relaxing calls, we must respect the source file that the
section came from when deciding whether it's legal to use compressed
instructions. If the call in question comes from a non-rvc source, then it will not
expect 2-byte alignments and cascading failures may result.
This fixes https://github.com/llvm/llvm-project/issues/63964. The symptom
seen there is that a latter RISCV_ALIGN can't be satisfied and we either
fail an assert or produce a totally bogus link result. (It can be easily
reproduced by putting .p2align 5 right before the nop in the reduced
test case and running check-lld on an assertions enabled build.) However,
it's important to note this is just one possible symptom of the problem.
If the resulting binary has a runtime switch between rvc and non-rvc
routines (via e.g. ifuncs), then even if we manage to link we may execute invalid
instructions on a machine which doesn't implement compressed instructions.
Dead store elimination pass may fold malloc + memset calls into a single
call to calloc. If calloc is not preserved and is not being called
it can be marked dead which results in link error.
Similar to https://reviews.llvm.org/D50017: malloc+memset references can
be combined to a calloc reference, which is not explicit in the
referencer's IR symbol table. If calloc is defined in a lazy bitcode
file, we should extract the archive member to satisfy possible
references from LTO generated object files; otherwise (current status,
which will be fixed by #72673), `calloc` as a LazyObject symbol will be
resolved by compileBitcodeFiles generated Undefined, leading to an
incorrectly-extracted Defined symbol without section, which will lower
to an SHN_ABS symbol at address 0.
When doing LTO on multiple archives, the order with which bitcodes are
linked to the LTO module is hard to control, given that processing
undefined symbols can lead to parsing of an object file, which in turn
lead to parsing of another object file before finishing parsing of the
previous file. This can result in encountering a non-prevailing comdat
first when linking, which can make the the symbol undefined, and the
real definition is added later with an additional prefix to avoid
duplication (e.g. `__cxx_global_var_init` and `__cxx_global_var_init.2`)
So this one-line fix ensures we compile bitcodes in the order that we
process comdats, so that when multiple archived bitcode files have the
same variable with the same comdat, we make sure that the prevailing
comdat will be linked first in the LTO.
Fixes#62243.
This showed up when simplifying some large testcase, where the cfi directives
became out of sync with the proc's they enclose.
Now restricted to platforms that support .subsections_via_symbols.
This reverts commit 797b68c0ba.
Fixes: #72802
Differential revision: https://reviews.llvm.org/D153167
rdar://111459507
For a label difference like `.uleb128 A-B`, MC generates a pair of
R_RISCV_SET_ULEB128/R_RISCV_SUB_ULEB128 if A-B cannot be folded as a
constant. GNU assembler generates a pair of relocations in more cases
(when A or B is in a code section with linker relaxation).
`.uleb128 A-B` is primarily used by DWARF v5
.debug_loclists/.debug_rnglists (DW_LLE_offset_pair/DW_RLE_offset_pair
entry kinds) implemented in Clang and GCC.
`.uleb128 A-B` can be used in SHF_ALLOC sections as well (e.g.
`.gcc_except_table`). This patch does not handle SHF_ALLOC.
`-z dead-reloc-in-nonalloc=` can be used to change the relocated value,
if the R_RISCV_SET_ULEB128 symbol is in a discarded section. We don't
check the R_RISCV_SUB_ULEB128 symbol since for the expected cases A and
B should be defined in the same input section.
Commit b963c0b658 fixed LTO compilation of
cases where one translation unit is calling a function with the
dllimport attribute, and another translation unit provides this function
locally within the same linked module (i.e. not actually dllimported);
see https://github.com/llvm/llvm-project/issues/37453 or
https://bugs.llvm.org/show_bug.cgi?id=38105 for full context.
This was fixed by aliasing their GlobalResolution structs, for the
`__imp_` prefixed and non prefixed symbols.
I believe this fix to be wrong.
This patch reverts that fix, and fixes the same issue differently,
within LLD instead.
The fix assumed that one can treat the `__imp_` prefixed and unprefixed
symbols as equal, referencing SVN r240620
(d766653534). However that referenced
commit had mistaken how this logic works, which was corrected later in
SVN r240622 (88e0f9206b); those symbols
aren't direct aliases for each other - but if there's a need for the
`__imp_` prefixed one and the other one exists, the `__imp_` prefixed
one is created, as a pointer to the other one.
However this fix only works if both translation units are compiled as
LTO; if the caller is compiled as a regular object file and the callee
is compiled as LTO, the fix fails, as the LTO compilation doesn't know
that the unprefixed symbol is needed.
The only level that knows of the potential relationship between the
`__imp_` prefixed and unprefixed symbol, across regular and bitcode
object files, is LLD itself.
Therefore, revert the original fix from
b963c0b658, and fix the issue differently
- when concluding that we can fulfill an undefined symbol starting with
`__imp_`, mark the corresponding non prefixed symbol as used in a
regular object for the LTO compilation, to make sure that this non
prefixed symbol exists after the LTO compilation, to let LLD do the
fixup of the local import.
Extend the testcase to test a regular object file calling an LTO object
file, which previously failed.
This change also fixes another issue; an object file can provide both
unprefixed and prefixed versions of the same symbol, like this:
void importedFunc(void) {
}
void (*__imp_importedFunc)(void) = importedFunc;
That allows the function to be called both with and without dllimport
markings. (The concept of automatically resolving a reference to
`__imp_func` to a locally defined `func` only is done in MSVC style
linkers, but not in GNU ld, therefore MinGW mode code often uses this
construct.)
Previously, the aliasing of global resolutions at the LTO level would
trigger a failed assert with "Multiple prevailing defs are not allowed"
for this case, as both `importedFunc` and `__imp_importedFunc` could be
prevailing. Add a case to the existing LLD test case lto-imp-prefix.ll
to test this as well.
This change (together with previous change in
3ab6209a3f) completes LLD to work with
mingw-w64-crt files (the base glue code for a mingw-w64 toolchain) built
with LTO.
The commit 3ab6209a3f had the undesired
effect of retaining every `__imp_` symbol, even if it isn't referenced
in any way. Add a testcase to observe this behaviour, to serve as
a reference point if this behaviour were to be improved later.
Port the testcase from b963c0b658 from
the llvm/LTO testsuite into LLD as a preparation for changing that fix;
the moved testcase has a comment for one case which doesn't work
currently.
The testcase is ported mostly as is, but with symbol mangling
simplified, rewriting function names from MSVC C++ mangling to plain
C, and unnecessary debug info is removed.
Add a case of a dllimported data symbol, in addition to the existing
call of a dllimported function.
Also extend the testcase to test combinations of both regular
object files and LTO objects. Leave out one combination which currently
fails, with a comment.
This reverts commit 4323da926f.
This broke building libffi for ARM on Windows (and probably Darwin),
where one extern function intentionally falls through to another
one, while sharing one CFI region.
As long as one isn't using .subsections_via_symbols on MachO,
this probably shouldn't be a hard error.
Secondly, the tested pattern only produces an error on MachO and
COFF targets, but not for ELF, making the error case even more
inconsistent.
Reverting this commit for now, to figure out the best way forward.