584 Commits

Author SHA1 Message Date
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
255ea48608 [ELF] Merge verdefIndex into versionId. NFC (#72208)
The two fields are similar.

`versionId` is the Verdef index in the output file. It is set for
`--exclude-id=`, version script patterns, and `sym@ver` symbols.

`verdefIndex` is the Verdef index of a Sharedfile (SharedSymbol or a
copy-relocated Defined), the default value -1 is also used to indicate
that the symbol has not been matched by a version script pattern
(https://reviews.llvm.org/D65716).

It seems confusing to have two fields. Merge them so that we can
allocate one bit for #70130 (suppress --no-allow-shlib-undefined
error in the presence of a DSO definition).
2023-11-16 01:03:52 -08:00
Fangrui Song
e84575449f
Revert "[ELF] Merge verdefIndex into versionId. NFC" #72208 (#72484)
Reverts llvm/llvm-project#72208

If a unversioned Defined preempts a versioned DSO definition, the
version ID will not be reset.
2023-11-15 23:14:07 -08:00
Fangrui Song
667ea2ca40
[ELF] Merge verdefIndex into versionId. NFC (#72208)
The two fields are similar.

`versionId` is the Verdef index in the output file. It is set for
version script patterns and `sym@ver` symbols.

`verdefIndex` is the Verdef index of a SharedSymbol. The default value
-1 is also used to indicate that the symbol has not been matched by a
version script pattern (https://reviews.llvm.org/D65716).

It seems confusing to have two fields. Merge them so that we can
allocate one bit for #70130 (suppress --no-allow-shlib-undefined
error in the presence of a DSO definition).
2023-11-14 10:20:21 -08:00
Fangrui Song
21ac457f3f [ELF] Priorize the last catch-all pattern in version scripts
When there are multiple catch-all patterns (i.e. a single `*`), GNU ld and gold
select the last pattern. Match their behavior.

This change was inspired by a correction made by Michael Kerrisk to a blog post
I wrote at https://maskray.me/blog/2020-11-26-all-about-symbol-versioning ,
following the current lld rules.

Note: GNU ld prefers global: patterns to local: patterns, which might seem
awkward (https://www.airs.com/blog/archives/300). gold doesn't follow this
behavior, and we do not either.
2023-09-09 23:47:01 -07:00
Nick Desaulniers
8abbc17ff3 reland: [Demangle] make llvm::demangle take std::string_view rather than const std::string&
As suggested by @erichkeane in
https://reviews.llvm.org/D141451#inline-1429549

There's potential for a lot more cleanups around these APIs. This is
just a start.

Callers need to be more careful about sub-expressions producing strings
that don't outlast the expression using `llvm::demangle`. Add a
release note.

Differential Revision: https://reviews.llvm.org/D149104
2023-06-06 10:18:06 -07:00
Fangrui Song
40eb8a7864 [ELF] findAllByVersion: optimize a find('@') with hasVersionSuffix. NFC 2023-05-25 21:23:23 -07:00
Nick Desaulniers
3e3c6f24ff Revert "[Demangle] make llvm::demangle take std::string_view rather than const std::string&"
This reverts commit c117c2c8ba4afd45a006043ec6dd858652b2ffcc.

itaniumDemangle calls std::strlen with the results of
std::string_view::data() which may not be NUL-terminated. This causes
lld/test/wasm/why-extract.s  to fail when "expensive checks" are enabled
via -DLLVM_ENABLE_EXPENSIVE_CHECKS=ON. See D149675 for further
discussion. Back this out until the individual demanglers are converted
to use std::string_view.
2023-05-02 15:54:09 -07:00
Nick Desaulniers
c117c2c8ba [Demangle] make llvm::demangle take std::string_view rather than const std::string&
As suggested by @erichkeane in
https://reviews.llvm.org/D141451#inline-1429549

There's potential for a lot more cleanups around these APIs. This is
just a start.

Callers need to be more careful about sub-expressions producing strings
that don't outlast the expression using ``llvm::demangle``. Add a
release note.

Reviewed By: MaskRay, #lld-macho

Differential Revision: https://reviews.llvm.org/D149104
2023-05-02 11:20:15 -07:00
Jez Ng
32647c8f53 [lld][nfc] Remove lld::demangle() (partial revert of D116279)
{D116279}, in addition to adding support for other demanglers, also
factored out some of the demangling logic. However, I don't think the
abstraction really carries its weight -- after {D135942}, only the ELF
and WASM backends call it with anything other than a non-constant
`shouldDemangle` argument. The COFF and Mach-O backends were already
doing the should-demangle check before calling `demangle()`.

Reviewed By: MaskRay, #lld-macho

Differential Revision: https://reviews.llvm.org/D135943
2022-10-14 15:28:47 -04:00
Fangrui Song
9c626d4a0d [ELF] Remove symtab indirection. NFC
Add LLVM_LIBRARY_VISIBILITY to remove unneeded GOT and unique_ptr indirection.
2022-10-01 14:46:49 -07:00
Fangrui Song
e3ecc6a912 [ELF] Make symAux[0] a sentinel
And default auxIdx to 0.
2022-09-29 00:50:19 -07:00
Fangrui Song
9e6840ccba [ELF] Remove resolve => resolve{Defined,Common,Shared,Lazy,Undefined} indirection. NFC 2022-09-28 20:01:41 -07:00
Fangrui Song
7a58dd1046 [ELF] Refactor Symbol initialization and overwriting
Symbol::replace intends to overwrite a few fields (mostly Elf{32,64}_Sym
fields), but the implementation copies all fields then restores some old fields.
This is error-prone and wasteful. Add Symbol::overwrite to copy just the
needed fields and add other overwrite member functions to copy the extra
fields.
2022-09-28 13:11:31 -07:00
Fangrui Song
82ed93ea05 [ELF] Use stOther to track visibility
This simplifies SymbolTableSection<ELFT>::writeTo. Add dsoProtected to be used
in canDefineSymbolInExecutable and get the side benefit that the protected DSO
preemption diagnostic is clearer.
2022-09-04 17:27:35 -07:00
Shoaib Meenai
2a04f5c455 [ELF] Drop unused original symbol after wrapping if not defined
We were previously only omitting the original of a wrapped symbol if it
was not used by an object file and undefined. We can tighten the second
condition to drop any symbol that isn't defined instead, which lets us
drop a previous check (added in https://reviews.llvm.org/D118756) that
was only covering some such symbols.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D124065
2022-04-22 16:47:15 -07:00
Shoaib Meenai
1af25a9860 [ELF] Fix wrapping symbols produced during LTO codegen
We were previously not correctly wrapping symbols that were only
produced during LTO codegen and unreferenced before then, or symbols
only referenced from such symbols. The root cause was that we weren't
marking the wrapped symbol as used if we only saw the use after LTO
codegen, leading to the failed wrapping.

Fix this by explicitly tracking whether a symbol will become referenced
after wrapping is done. We can use this property to tell LTO to preserve
such symbols, instead of overload isUsedInRegularObj for this purpose.
Since we're no longer setting isUsedInRegularObj for all symbols which
will be wrapped, its value at the time of performing the wrapping in the
symbol table will accurately reflect whether the symbol was actually
used in an object (including in an LTO-generated object), and we can
propagate that value to the wrapped symbol and thereby ensure we wrap
correctly.

This incorrect wrapping was the only scenario I was aware of where we
produced an invalid PLT relocation, which D123985 started diagnosing,
and with it fixed, we lose the test for that diagnosis. I think it's
worth keeping the diagnosis though, in case we run into other issues in
the future which would be caught by it.

Fixes PR50675.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D124056
2022-04-22 16:45:21 -07:00
Fangrui Song
8ca46bba23 [ELF] Move isUsedInRegularObj assignment from ctor to call sites. NFC
This removes the tricky
`isUsedInRegularObj(!file || file->kind() == InputFile::ObjKind)`
and the copy from `Symbol::mergeProperties`.
2022-02-23 21:32:50 -08:00
Fangrui Song
38fbedab32 [ELF] Don't rely on Symbols.h's transitive inclusion of InputFiles.h. NFC 2022-02-23 20:44:34 -08:00
Fangrui Song
88d66f6ed1 [ELF] Move duplicate symbol check after input file parsing
https://discourse.llvm.org/t/parallel-input-file-parsing/60164

To decouple symbol initialization and section initialization, `Defined::section`
assignment should be postponed after input file parsing. To avoid spurious
duplicate definition error due to two definitions in COMDAT groups of the same
signature, we should postpone the duplicate symbol check.

The function is called postScan instead of a more specific name like
checkDuplicateSymbols, because we may merge Symbol::mergeProperties into
postScan. It is placed after compileBitcodeFiles to apply to ET_REL files
produced by LTO. This causes minor diagnostic regression
for skipLinkedOutput configurations: ld.lld --thinlto-index-only a.bc b.o
(bitcode definition prevails) won't detect duplicate symbol error. I think this
is an acceptable compromise. The important cases where (a) both files are
bitcode or (b) --thinlto-index-only is unused are still detected.

Reviewed By: ikudrin

Differential Revision: https://reviews.llvm.org/D119908
2022-02-22 10:07:58 -08:00
Fangrui Song
27bb799095 [ELF] Clean up headers. NFC 2022-02-07 21:53:34 -08:00
Fangrui Song
73f55fba76 [ELF] Reorder Symbol members to improve access locality. NFC
* partition and isPreemptible are frequently used. Move it to the front
* move used beside isUsedInRegularObj. They are similar and accessed together in .symtab finalizing
* move auxIdx/dynsymIndex/verdefIndex to the end.

This decreases code size.
2022-02-05 14:11:37 -08:00
Fangrui Song
7c675923c7 [ELF] Merge canInline into scriptDefined
They perform similar tasks and are essentially the same after
d28c26bbdd9e6e55cc0a6156e9879f7e0ca36329.
2022-02-05 12:00:34 -08:00
Fangrui Song
7288b85cc8 [ELF] --wrap: don't copy exportDynamic
For -no-pie/-pie, when `__real_foo` is interposable in a shared object, `foo` is
exported. This rule does not match GNU ld and is unneeded because:

* the exported `foo` does not interpose `__real_foo` at run-time
* the similar `__wrap_foo` <-> `foo` relation does not have the rule
2022-02-05 09:56:29 -08:00
Luís Ferreira
10e40a4ea3 [lld] Add support for other demanglers other than Itanium
LLVM core library supports demangling other mangled symbols other than itanium,
such as D and Rust. LLD should use those demanglers in order to output pretty
demangled symbols on error messages.

Reviewed By: MaskRay, #lld-macho

Differential Revision: https://reviews.llvm.org/D116279
2022-01-05 03:25:41 +00:00
Luís Ferreira
8792cd75d0 Revert "[lld] Add support for other demanglers other than Itanium"
This reverts commit e60d6dfd5acdc821d391ad5af2c706397bdfd36a.

clang-ppc64le-rhel buildbot failed (https://lab.llvm.org/buildbot#builders/57/builds/13424):

    tools/lld/MachO/CMakeFiles/lldMachO.dir/Symbols.cpp.o: In function `lld::demangle(llvm::StringRef, bool)':
    Symbols.cpp:(.text._ZN3lld8demangleEN4llvm9StringRefEb[_ZN3lld8demangleEN4llvm9StringRefEb]+0x90): undefined reference to `llvm::demangle(std::string const&)'
2021-12-30 18:04:21 +00:00
Luís Ferreira
e60d6dfd5a [lld] Add support for other demanglers other than Itanium
LLVM core library supports demangling other mangled symbols other than itanium,
such as D and Rust. LLD should use those demanglers in order to output pretty
demangled symbols on error messages.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D116279
2021-12-30 17:52:38 +00:00
Fangrui Song
7924b3814f [ELF] Add Symbol::hasVersionSuffix
"Process symbol versions" may take 2+% time.
"Redirect symbols" may take 0.6% time.
This change speeds up the two passes and makes `*sym.getVersionSuffix()
== '@'` in the `undefined reference` diagnostic cleaner.

Linking chrome (no debug info) and another large program is 1.5% faster.

For empty-ver2.s: the behavior now matches GNU ld, though I'd consider the input
invalid and the exact behavior does not matter.
2021-12-26 17:25:54 -08:00
Fangrui Song
1abbbc7b24 [ELF] scanVersionScript: remove unused variable 2021-12-23 18:18:25 -08:00
Fangrui Song
a2baf634a1 [ELF] Simplify SymbolTable::insert. NFC 2021-12-23 17:59:25 -08:00
Fangrui Song
417cd2e5c5 [ELF] SymbolTable: change some vector<Symbol *> to SmallVector
The generated assembly for Symbol::insert is much shorter (std::vector resize is
inefficient) and enables some inlining.
2021-12-23 16:49:38 -08:00
Fangrui Song
5fc4323eda [ELF] Change some global pointers to unique_ptr
Currently the singleton `config` is assigned by `config = make<Configuration>()`
and (if `canExitEarly` is false) destroyed by `lld::freeArena`.

`make<Configuration>` allocates a stab with `malloc(4096)`. This both wastes
memory and bloats the executable (every type instantiates `BumpPtrAllocator`
which costs more than 1KiB code on x86-64).

(No need to worry about `clang::no_destroy`. Regular invocations (`canExitEarly`
is true) call `_Exit` via llvm::sys::Process::ExitNoCleanup.)

Reviewed By: lichray

Differential Revision: https://reviews.llvm.org/D116143
2021-12-22 14:36:14 -08:00
Fangrui Song
b0211de5e3 [ELF] Change Symbol::verdefIndex from uint32_t to uint16_t
The SHT_GNU_version index is 16-bit, so the 32-bit value is a waste.
Technically non-default version index 0x7fff uses version index 0xffff,
but it is impossible in practice.

This change decreases sizeof(SymbolUnion) from 80 to 72 on ELF64 platforms.
Memory usage decreases by 1% when linking a large executable.
2021-12-15 17:59:30 -08:00
Fangrui Song
2bdad16303 [ELF] SymbolTable::insert: keep @@ in the name
* Avoid the name truncation quirk in SymbolTable::insert: the truncated name will be replaced by @@ again.
* Allow foo and foo@@v1 in different files to be diagnosed as duplicate definition error (GNU ld behavior)
* Avoid potential redundant strlen on symbol name due to StringRefZ in ObjFile<ELFT>::initializeSymbols
2021-12-15 15:19:35 -08:00
Fangrui Song
89661a0e89 [ELF] Remove dead code from SymbolTable::find 2021-12-14 22:41:52 -08:00
Fangrui Song
09401dfcf1 [ELF] Rename fetch to extract
The canonical term is "extract" (GNU ld documentation, Solaris's `-z *extract`
options). Avoid inventing a term and match --why-extract. (ld64 prefers "load"
but the word is overloaded too much)

Mostly MFC, except for --help messages and the header row in
--print-archive-stats output.
2021-11-26 10:58:50 -08: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
00809c8889 [ELF] Apply version script patterns to non-default version symbols
Currently version script patterns are ignored for .symver produced
non-default version (single @) symbols. This makes such symbols
not localizable by `local:`, e.g.

```
.symver foo3_v1,foo3@v1
.globl foo_v1
foo3_v1:

ld.lld --version-script=a.ver -shared a.o
```

This patch adds the support:

* Move `config->versionDefinitions[VER_NDX_LOCAL].patterns` to `config->versionDefinitions[versionId].localPatterns`
* Rename `config->versionDefinitions[versionId].patterns` to `config->versionDefinitions[versionId].nonLocalPatterns`
* Allow `findAllByVersion` to find non-default version symbols when `includeNonDefault` is true. (Note: `symtab` keys do not have `@@`)
* Make each pattern check both the unversioned `pat.name` and the versioned `${pat.name}@${v.name}`
* `localPatterns` can localize `${pat.name}@${v.name}`. `nonLocalPatterns` can prevent localization by assigning `verdefIndex` (before `parseSymbolVersion`).

---

If a user notices new `undefined symbol` errors with a version script containing
`local: *;`, the issue is likely due to a missing `global:` pattern.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D107234
2021-08-04 23:52:56 -07:00
Fangrui Song
a533eb7423 Revert "[ELF] Apply version script patterns to non-default version symbols"
This reverts commit 7ed22a6fa90cbdc70d6806c1121a0c50c1978dce.

buf is not cleared so the commit misses some cases.
2021-08-04 23:52:55 -07:00
Fangrui Song
7ed22a6fa9 [ELF] Apply version script patterns to non-default version symbols
Currently version script patterns are ignored for .symver produced
non-default version (single @) symbols. This makes such symbols
not localizable by `local:`, e.g.

```
.symver foo3_v1,foo3@v1
.globl foo_v1
foo3_v1:

ld.lld --version-script=a.ver -shared a.o
# In a.out, foo3@v1 is incorrectly exported.
```

This patch adds the support:

* Move `config->versionDefinitions[VER_NDX_LOCAL].patterns` to `config->versionDefinitions[versionId].localPatterns`
* Rename `config->versionDefinitions[versionId].patterns` to `config->versionDefinitions[versionId].nonLocalPatterns`
* Allow `findAllByVersion` to find non-default version symbols when `includeNonDefault` is true. (Note: `symtab` keys do not have `@@`)
* Make each pattern check both the unversioned `pat.name` and the versioned `${pat.name}@${v.name}`
* `localPatterns` can localize `${pat.name}@${v.name}`. `nonLocalPatterns` can prevent localization by assigning `verdefIndex` (before `parseSymbolVersion`).

---

If a user notices new `undefined symbol` errors with a version script containing
`local: *;`, the issue is likely due to a missing `global:` pattern.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D107234
2021-08-04 09:02:11 -07:00
Fangrui Song
7c74ce3c68 [ELF] --wrap: don't clear sym->isUsedInRegularObj if real->isUsedInRegularObj; set wrap's initial binding to sym's
Fix PR49897: if `__real_foo` has the isUsedInRegularObj bit set, we need to
retain `foo` in .symtab, even if `foo` is undefined. The new behavior will match
GNU ld.

Before the patch, we produced an R_X86_64_JUMP_SLOT relocation referencing the
index 0 undefined symbol, which would be erroed by glibc
(see f96ff3c0f8ebd941b3f6b345164c3d858b781484).

While here, fix another bug: if `__wrap_foo` does not exist, its initial binding
should be `foo`'s.
2021-04-17 00:29:51 -07:00
Fangrui Song
0334578edc [ELF] --wrap: don't leave the original symbol as SHN_UNDEF in .symtab or .dynsym 2020-08-08 18:18:20 -07:00
William S. Moses
dc6b3f03a8 [ELF] Drop an unneeded reference to symtab from SymbolTable::addSymbol
The Symbol Table in LLD references the global object to add a symbol rather than adding it to itself.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D83184
2020-07-06 12:05:54 -07:00
Fangrui Song
a6ae333a0c [ELF] --wrap: don't error undefined reference to __real_foo (--no-allow-shlib-undefined) if foo is a wrapped definition
This is a regression after D51283.

Also, export `foo` if `__real_foo` is referenced by a shared object.
2020-06-01 23:00:51 -07:00
Rui Ueyama
54d2896852 [ELF] --wrap: Drop __real_ symbol from the symbol table
In D34993, we discussed and concluded that we should drop `__real_
symbol from the symbol table, but I did the opposite in D50569.
This patch is to drop `__real_` symbol.

MaskRay's note: omitting `__real_` is important if it is undefined:
otherwise a subsequent link may error due to the undefined `__real_` in .dynsym

Differential Revision: https://reviews.llvm.org/D51283
2020-05-27 16:58:00 -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
bd8cfe65f5fee4ad573adc2172359c9552e8cdc0 (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
Fangrui Song
c1c679e2d2 [ELF] Make --version-script/--dynamic-list work for lazy symbols fetched by LTO libcalls
Fixes https://bugs.llvm.org/show_bug.cgi?id=45391

The LTO code generator happens after version script scanning and may
create references which will fetch some lazy symbols.

Currently a version script does not assign VER_NDX_LOCAL to lazy symbols
and such symbols will be made global after they are fetched.

Change findByVersion and findAllByVersion to work on lazy symbols.
For unfetched lazy symbols, we should keep them non-local (D35263).
Check isDefined() in computeBinding() as a compensation.

This patch fixes a companion bug that --dynamic-list does not export
libcall fetched symbols.

Reviewed By: grimar

Differential Revision: https://reviews.llvm.org/D77280
2020-04-06 09:47:06 -07:00
Thomas Preud'homme
c42fe24754 [lld/ELF] PR44498: Support input filename in double quote
Summary:
Linker scripts allow filenames to be put in double quotes to prevent
characters in filenames that are part of the linker script syntax from
having their special meaning. Case in point the * wildcard character.

Availability of double quoting filenames also allows to fix a failure in
ELF/linkerscript/filename-spec.s when the path contain a @ which the
lexer consider as a special characters and thus break up a filename
containing it. This may happens under Jenkins which createspath such as
pipeline@2.

To avoid the need for escaping GlobPattern metacharacters in filename
in double quotes, GlobPattern::create is augmented with a new parameter
to request literal matching instead of relying on the presence of a
wildcard character in the pattern.

Reviewers: jhenderson, MaskRay, evgeny777, espindola, alexshap

Reviewed By: MaskRay

Subscribers: peter.smith, grimar, ruiu, emaste, arichardson, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D72517
2020-01-22 12:03:10 +00:00
Nico Weber
5976a3f5aa Fix a few typos in lld/ELF to cycle bots 2019-10-28 21:41:47 -04:00
Fangrui Song
bd8cfe65f5 [ELF] Wrap things in namespace lld { namespace elf {, NFC
This makes it clear `ELF/**/*.cpp` files define things in the `lld::elf`
namespace and simplifies `elf::foo` to `foo`.

Reviewed By: atanasyan, grimar, ruiu

Differential Revision: https://reviews.llvm.org/D68323

llvm-svn: 373885
2019-10-07 08:31:18 +00:00