352 Commits

Author SHA1 Message Date
Jacek Caban
482ee33a63 [lld] Use correct machine type in ARM64EC COFF headers.
This adds very minimal support for ARM64EC/ARM64X targets,
just enough for interesting test cases. Next patches in the
series extend llvm-objdump and llvm-readobj to provide
better tests. Those will also be useful for testing further
ARM64EC LLD support.

Differential Revision: https://reviews.llvm.org/D149086
2023-05-29 19:42:24 +02:00
Haohai Wen
c384fcd3ea [lld] Partially revert "Always emit symbol table when dwarf section exists in COFF"
This reverts part of commit 44363f2ff2736e4edf4a260f442b513ceac661fc.

Fixup for NO symbol table test has been reserved.

Reviewed By: wxiao3

Differential Revision: https://reviews.llvm.org/D151417
2023-05-29 09:23:51 +08:00
Phoebe Wang
360d0cd0a2 [LLD] Do not assume /guard:cf always set together with /guard:ehcont
MS link accepts *.obj with ehcont bit set only. LLD should match this
behavoir too.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D150508
2023-05-16 23:12:03 +08:00
Haohai Wen
44363f2ff2 Always emit symbol table when dwarf section exists in COFF
This also fixes check prefix NO which is pointless in symtab.test

Reviewed By: mstorsjo

Differential Revision: https://reviews.llvm.org/D149235
2023-04-27 09:42:47 +08:00
Jacek Caban
a5988034a4 [lld] Fill .text section gaps with INT3 only on x86 targets.
It doesn't make sense on ARM and using default 0 fill is compatible
with MSVC.

(It's more noticeable ARM64EC targets, where additional padding mixed
with alignment is used for entry thunk association, so there are more
gaps).

Reviewed By: mstorsjo

Differential Revision: https://reviews.llvm.org/D145962
2023-03-23 13:43:21 +02:00
Jez Ng
3df4c5a92f [NFC] Optimize vector usage in lld
By using emplace_back, as well as converting some loops to for-each, we can do more efficient vectorization.

Make copy constructor for TemporaryFile noexcept.

Reviewed By: #lld-macho, int3

Differential Revision: https://reviews.llvm.org/D139552
2023-01-26 20:31:42 -05:00
Joe Loser
a288d7f937 [llvm][ADT] Replace uses of makeMutableArrayRef with deduction guides
Similar to how `makeArrayRef` is deprecated in favor of deduction guides, do the
same for `makeMutableArrayRef`.

Once all of the places in-tree are using the deduction guides for
`MutableArrayRef`, we can mark `makeMutableArrayRef` as deprecated.

Differential Revision: https://reviews.llvm.org/D141814
2023-01-16 14:49:37 -07:00
serge-sans-paille
c512eda38e
[lld][COFF] Provide unwinding information for Chunk injected by /delayloaded
For each symbol in a /delayloaded library, lld injects a small piece of
code to handle the symbol lazy loading. This code doesn't have unwind
information, which may be troublesome.

Provide these information for AMD64.

Thanks to Yannis Juglaret <yjuglaret@mozilla.com> for contributing the
unwinding info and for his support while crafting this patch.

Fix #59639

Differential Revision: https://reviews.llvm.org/D141691
2023-01-16 18:39:21 +01:00
Benjamin Kramer
931d04be2f [ADT] Make StringRef::compare like std::string_view::compare
string_view has a slightly weaker contract, which only specifies whether
the value is bigger or smaller than 0. Adapt users accordingly and just
forward to the standard function (that also compiles down to memcmp)
2023-01-15 20:59:21 +01:00
Amy Huang
5a58b19f9c [LLD] Remove global state in lld/COFF
Remove globals from the lldCOFF library, by moving globals into a context class.
This patch mostly moves the config object into COFFLinkerContext.

See https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html for
context about removing globals from LLD.

Reviewed By: aganea

Differential Revision: https://reviews.llvm.org/D110450
2023-01-09 23:39:30 -05:00
Martin Storsjö
398c2ad6f6 Revert "[LLD] Remove global state in lld/COFF"
This reverts commit 7370ff624d217b0f8f7512ca5b651a9b8095a411.
(and 47fb8ae2f9a4075de05433ef24f459b6befd1730).

This commit broke the symbol type in import libraries generated
for mingw autoexported symbols, when the source files were built
with LTO. I'll commit a testcase that showcases this issue after
the revert.
2023-01-09 16:04:44 +02:00
Amy Huang
7370ff624d [LLD] Remove global state in lld/COFF
Remove globals from the lldCOFF library, by moving globals into a context class.
This patch mostly moves the config object into COFFLinkerContext.

See https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html for
context about removing globals from LLD.

Reviewed By: aganea

Differential Revision: https://reviews.llvm.org/D110450
2023-01-08 18:43:13 -05:00
Qfrost
3f55853edf [LLD][Windows]Feature "checksum" for Windows PE
Differential Revision: https://reviews.llvm.org/D139184
2023-01-02 17:20:15 +08:00
Kazu Hirata
7e937d08e1 Don't include StringSwitch (NFC)
These files do not use llvm::StringSwitch.
2022-12-14 21:50:34 -08:00
Fangrui Song
9da7aee7c9 [COFF] Change most Optional to std::optional 2022-11-27 16:39:40 -08:00
Alvin Wong
37bd099daf [LLD][COFF] Fix absolute & synthetic symbols in COFF symbol table
Absolute symbol should contain its absolute value, but LLD had been
writing its RVA instead. Write its VA instead.

DefinedSynthetic were being skipped before with the reasoning "Relative
symbols are unrepresentable in a COFF symbol table", which is only true
if the RVA points to outside of a section. LLD does create synthetic
symbols which points to actual data chunks (typical for symbols embedded
into the load config directory). Write these symbols to the COFF symbol
table too.

Reviewed By: mstorsjo

Differential Revision: https://reviews.llvm.org/D134462
2022-09-26 11:05:41 +03:00
Alvin Wong
365d0a5cd8 [LLD][COFF] Add load config checks to warn if incorrect for CFGuard
Control Flow Guard requires specific flags and VA's be included in the
load config directory to be functional. In case CFGuard is enabled via
linker flags, we can check to make sure this is the case and give the
user a warning if otherwise.

MSVC provides a proper `_load_config_used` by default, so this is more
relevant for the MinGW target in which current versions of mingw-w64
does not provide this symbol.

The checks (only if CFGuard is enabled) include:

- The `_load_config_used` struct shall exist.
- Alignment of the `_load_config_used` struct (shall be aligned to
  pointer size.)
- The `_load_config_used` struct shall be large enough to contain the
  required fields.
- The values of the following fields are checked against the expected
  values:
  - GuardCFFunctionTable
  - GuardCFFunctionCount
  - GuardFlags
  - GuardAddressTakenIatEntryTable
  - GuardAddressTakenIatEntryCount
  - GuardLongJumpTargetTable
  - GuardLongJumpTargetCount
  - GuardEHContinuationTable
  - GuardEHContinuationCount

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D133099
2022-09-20 10:49:01 +03:00
Alvin Wong
9509f4e657 [LLD][COFF] Improve symbol table info for import thunk
Import thunks themselves contain a jump or branch, which is code by
nature. Therefore the import thunk symbol should be marked as function
type in the symbol table to help with debugging.

The `__imp_` import symbol associated to the import thunk is also useful
for debugging. However, when the import symbol isn't directly referenced
outside of the import thunk, it doesn't normally get added to the symbol
table. This change teaches LLD to add the import symbol explicitly.

Reviewed By: mstorsjo

Differential Revision: https://reviews.llvm.org/D134169
2022-09-20 10:44:45 +03:00
Nico Weber
cd7ffa2e52 lld: Include name of output file in "failed to write output" diag
Differential Revision: https://reviews.llvm.org/D133110
2022-09-14 14:57:47 -04:00
Jan Ole Hüser
4e5a59a383 [LLD][COFF] Fix writing a map file when range extension thunks are inserted
Bug: An assertion fails:

    Assertion failed: isa<To>(Val) && "cast<Ty>() argument of incompatible type!",
    file C:\Users\<user>\prog\llvm\llvm-git-lld-bug\llvm\include\llvm/Support/Casting.h, line 578

Bug is triggered, if

    - a map file is requested with /MAP, and
    - Architecture is ARMv7, Thumb, and
    - a relative jump (branch instruction) is greater than 16 MiB (2^24)

The reason for the Bug is:

    - a Thunk is created for the jump
    - a Symbol for the Thunk is created
        - of type `DefinedSynthetic`
        - in file `Writer.cpp`
        - in function `getThunk`
    - the Symbol has no name
    - when creating the map file, the name of the Symbol is queried
    - the function `Symbol::computeName` of the base class `Symbol`
      casts the `this` pointer to type `DefinedCOFF` (a derived type),
      but the acutal type is `DefinedSynthetic`
    - The in the llvm::cast an assertion fails

Changes:

- Modify regression test to trigger this bug
- Give the symbol pointing to the thunk a name, to fix the bug
- Add assertion, that only DefinedCOFF symbols are allowed to have an
  empty name, when the constructor of the base class Symbol is executed

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D133201
2022-09-07 09:26:41 +03:00
Alvin Wong
12d865415f [COFF] Use the more accurate GuardFlags definition everywhere
This also modifies llvm-readobj to be more future-proof when printing
the guard FIDs table by calculating the entry size correctly according
to MS docs.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D132924
2022-08-31 15:11:34 +03:00
Nico Weber
aa1abd7684 [lld/win] Use C++17 structured bindings
No behavior change.

Differential Revision: https://reviews.llvm.org/D131403
2022-08-08 11:51:38 -04:00
Martin Storsjö
4d2eda2bb3 Revert "[LLD] [COFF] Use StringTableBuilder to optimize the string table"
This reverts commit 9ffeaaa0ea54307db309104696a0b6cce6ddda38.

This fixes debugging large executables with lldb and gdb.

When StringTableBuilder is used, the string offsets for any string
can point anywhere in the string table - while previously, all strings
were inserted in order (without deduplication and tail merging).

For symbols, there's no complications in encoding the string offset;
the offset is encoded as a raw 32 bit binary number in half of the
symbol name field.

For sections, the string table offset is written as
"/<decimaloffset>", but if the decimal offset would be larger than
7 digits, it's instead written as "//<base64offset>". Tools that
operate on object files can handle the base64 offset format, but
apparently neither lldb nor gdb expect that syntax when locating the
debug information section. Prior to the reverted commit, all long
section names were located at the start of the string table, so
their offset never exceeded the range for the decimal syntax.

Just reverting this change for now, as the actual benefit from it
was fairly modest.

Longer term, lld could write all long section names unoptimized
at the start of the string table, followed by all the strings for
symbol names, with deduplication and tail merging. And lldb and
gdb could be fixed to handle sections with the base64 offset syntax.

This fixes https://github.com/mstorsjo/llvm-mingw/issues/289.
2022-06-21 13:25:08 +03:00
Martin Storsjö
4c3b74b7f5 [LLD] [COFF] Order .debug_* sections at the end, to avoid leaving gaps if stripped
So far, we sort all discardable sections at the end, with only some
extra logic to make sure that the .reloc section is at the start
of that group of sections. But if there are other discardable
sections, other than .reloc, they must also be ordered before
.debug_* sections, to avoid leaving gaps if the executable is
stripped.

(Stripping executables doesn't remove all discardable sections,
only the ones named .debug_*).

Rust binaries seem to include a .rmeta section, which is marked
discardable. This fixes stripping such binaries if built with
dwarf debug info included.

This fixes issues observed in MSYS2 in
https://github.com/msys2/MINGW-packages/pull/10555.

Differential Revision: https://reviews.llvm.org/D120805
2022-03-03 10:08:51 +02:00
Martin Storsjö
9ffeaaa0ea [LLD] [COFF] Use StringTableBuilder to optimize the string table
This does tail merging (and deduplication) of the strings.

On a statically linked clang.exe, this shrinks the ~17 MB string
table by around 0.5 MB. This adds ~160 ms to the linking time
which originally was around 950 ms.

For cases where `-debug:symtab` or `-debug:dwarf` isn't set, the
string table is only used for long section names, where this
shouldn't make any difference at all.

Differential Revision: https://reviews.llvm.org/D120677
2022-03-01 18:44:03 +02:00
Martin Storsjö
9dd2d50984 [LLD] [COFF] Use the new encodeSectionName() helper for long section names
The previous code used an unbounded sprintf, which in theory can
overflow, writing either the null terminator or the last digits
into the next struct member.

In practice, in LLD, all long section names are written sequentially
first at the start of the string table, followed by all the long
symbol names. Due to this, even if the total string table would
end up large, the long section names have fairly short offsets,
which is why this hasn't been an issue in practice.

I don't think it's worth trying to write a test that produces an
executable with enough long section names to make the section names
themselves exceed 10^6 bytes, which is currently necessary to trigger
faults with the previous form.

Differential Revision: https://reviews.llvm.org/D120676
2022-03-01 11:33:02 +02:00
Nico Weber
746bd89000 fix comment typo to cycle bots 2022-02-22 16:25:51 -05:00
Alexandre Ganea
83d59e05b2 Re-land [LLD] Remove global state in lldCommon
Move all variables at file-scope or function-static-scope into a hosting structure (lld::CommonLinkerContext) that lives at lldMain()-scope. Drivers will inherit from this structure and add their own global state, in the same way as for the existing COFFLinkerContext.

See discussion in https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html

The previous land f860fe362282ed69b9d4503a20e5d20b9a041189 caused issues in https://lab.llvm.org/buildbot/#/builders/123/builds/8383, fixed by 22ee510dac9440a74b2e5b3fe3ff13ccdbf55af3.

Differential Revision: https://reviews.llvm.org/D108850
2022-01-20 14:53:26 -05:00
Alexandre Ganea
e6b153947d Revert [LLD] Remove global state in lldCommon
It seems to be causing issues on https://lab.llvm.org/buildbot/#/builders/123/builds/8383
2022-01-16 11:03:06 -05:00
Alexandre Ganea
f860fe3622 [LLD] Remove global state in lldCommon
Move all variables at file-scope or function-static-scope into a hosting structure (lld::CommonLinkerContext) that lives at lldMain()-scope. Drivers will inherit from this structure and add their own global state, in the same way as for the existing COFFLinkerContext.

See discussion in https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html

Differential Revision: https://reviews.llvm.org/D108850
2022-01-16 08:57:57 -05:00
Kazu Hirata
8afcfbfb8f Use true/false instead of 1/0 (NFC)
Identified by modernize-use-bool-literals.
2022-01-09 12:21:06 -08:00
Martin Storsjö
d703b92296 [LLD] [COFF] Omit section symbols and IMAGE_SYM_CLASS_LABEL from the PE symbol table
The section symbols aren't of much practical use when looking at
a linked image. This shrinks one observed mingw style unstripped
binary by 14%.

IMAGE_SYM_CLASS_LABEL is in spirit the same as a temporary assembler
label that isn't emitted on the object file level at all.

Differential Revision: https://reviews.llvm.org/D113866
2021-11-23 10:17:04 +02:00
Kazu Hirata
8568ca789e Use llvm::erase_if (NFC) 2021-10-18 09:33:42 -07:00
Amy Huang
6f7483b1ec Reland "[LLD] Remove global state in lld/COFF" after fixing asan and msan test failures
Original commit description:

  [LLD] Remove global state in lld/COFF

  This patch removes globals from the lldCOFF library, by moving globals
  into a context class (COFFLinkingContext) and passing it around wherever
  it's needed.

  See https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html for
  context about removing globals from LLD.

  I also haven't moved the `driver` or `config` variables yet.

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

This reverts commit a2fd05ada9030eab2258fff25e77a05adccae128.

Original commits were b4fa71eed34d967195514fe9b0a5211fca2bc5bc
and e03c7e367adb8f228332e3c2ef8f45484597b719.
2021-09-17 17:18:42 -07:00
Amy Huang
a2fd05ada9 Temporarily revert "[LLD] Remove global state in lld/COFF" and "[lld] Add test to
check for timer output"

Seems to be causing a number of asan test failures.

This reverts commit b4fa71eed34d967195514fe9b0a5211fca2bc5bc
and e03c7e367adb8f228332e3c2ef8f45484597b719.
2021-09-16 11:58:11 -07:00
Amy Huang
b4fa71eed3 [LLD] Remove global state in lld/COFF
This patch removes globals from the lldCOFF library, by moving globals
into a context class (COFFLinkingContext) and passing it around wherever
it's needed.

See https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html for
context about removing globals from LLD.

I also haven't moved the `driver` or `config` variables yet.

Differential Revision: https://reviews.llvm.org/D109634
2021-09-16 11:00:23 -07:00
Martin Storsjö
a9ff1ce1b9 [LLD] [COFF] Support linking directly against DLLs in MinGW mode
GNU ld.bfd supports linking directly against DLLs without using an
import library, and some projects have picked up on this habit.
(There's no one single unsurmountable issue with using import
libraries, but this is a regularly surfacing missing feature.)

As long as one is linking by name (instead of by ordinal), the DLL
export table contains most of the information needed. (One can
inspect what section a symbol points at, to see if it's a function
or data symbol. The practical implementation of this loops over all
sections for each symbol, but as long as they're not very many, that
should hopefully be tolerable performance wise.)

One exception where the information in the DLL isn't entirely enough
is on i386 with stdcall functions; depending on how they're done,
the exported function name can be a plain undecorated name, while
the import library would contain the full decorated symbol name. This
issue is addressed separately in a different patch.

This is implemented mimicing the structure of a regular import library,
with one InputFile corresponding to the static archive that just adds
lazy symbols, which then are fetched when they are needed. When such
a symbol is fetched, we synthesize a coff_import_header structure
in memory and create a regular ImportFile out of it.

The implementation could be even smaller by just creating ImportFiles
for every symbol available immediately, but that would have the
drawback of actually ending up importing all symbols unless running
with GC enabled (and mingw mode defaults to having it disabled for
historical reasons).

Differential Revision: https://reviews.llvm.org/D104530
2021-07-02 09:49:13 +03:00
Fangrui Song
50225112b5 [lld-link] Fix -Wunused-but-set-variable in -DLLVM_ENABLE_ASSERTIONS=off build. NFC 2021-06-20 11:35:02 -07:00
Zequan Wu
aa80955f63 [lld-link] Warn on exported deleting dtor
MSVC linker has this [[ https://docs.microsoft.com/en-us/cpp/error-messages/tool-errors/linker-tools-warning-lnk4102?view=msvc-160 | warning]], so lld-link should also warn on this.

Differential Revision: https://reviews.llvm.org/D100606
2021-04-20 14:06:31 -07:00
Pengfei Wang
184377da5c [LLD] Implement /guard:[no]ehcont
Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D99078
2021-04-14 15:06:49 +08:00
Andrew Paverd
0139c8af8d [CFGuard] Add address-taken IAT tables and delay-load support
This patch adds support for creating Guard Address-Taken IAT Entry Tables (.giats$y sections) in object files, matching the behavior of MSVC. These contain lists of address-taken imported functions, which are used by the linker to create the final GIATS table.
Additionally, if any DLLs are delay-loaded, the linker must look through the .giats tables and add the respective load thunks of address-taken imports to the GFIDS table, as these are also valid call targets.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D87544
2020-11-17 18:24:45 -08:00
Hans Wennborg
418f18c6cd Revert "Reland [CFGuard] Add address-taken IAT tables and delay-load support"
This broke both Firefox and Chromium (PR47905) due to what seems like dllimport
function not being handled correctly.

> This patch adds support for creating Guard Address-Taken IAT Entry Tables (.giats$y sections) in object files, matching the behavior of MSVC. These contain lists of address-taken imported functions, which are used by the linker to create the final GIATS table.
> Additionally, if any DLLs are delay-loaded, the linker must look through the .giats tables and add the respective load thunks of address-taken imports to the GFIDS table, as these are also valid call targets.
>
> Reviewed By: rnk
>
> Differential Revision: https://reviews.llvm.org/D87544

This reverts commit cfd8481da1adba1952e0f6ecd00440986e49a946.
2020-11-11 16:03:33 +01:00
Peter Penzin
e59726220f [LLD] [COFF] Align all debug directories
Match MSVC linker output - align all debug directories on four bytes,
while removing debug directory alignment. This would have the same
effect on CETCOMPAT support as D89919.

Chromium bug: https://crbug.com/1136664

Differential Revision: https://reviews.llvm.org/D89921
2020-11-02 10:47:51 -08:00
Luqman Aden
6a73d6564a [LLD] Set alignment as part of Characteristics in TLS table.
Fixes https://bugs.llvm.org/show_bug.cgi?id=46473

LLD wasn't previously specifying any specific alignment in the TLS table's Characteristics field so the loader would just assume the default value (16 bytes). This works most of the time except if you have thread locals that want specific higher alignments (e.g. 32 as in the bug) *even* if they specify an alignment on the thread local. This change updates LLD to take the max alignment from tls section.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D88637
2020-10-15 00:22:40 -07:00
Luqman Aden
f87c98def8 Revert "[LLD] Set alignment as part of Characteristics in TLS table."
Revert individual wip commits and will instead follow up with a
single commit with all the changes. Makes cherry-picking easier
and will contain all the right tags.

This reverts commit 32a4ad3b6ce6028a371b028cf06fa5feff9534bf.
This reverts commit 7fe13af676678815989a6d0ece684687953245e7.
This reverts commit 51fbc1bef657bb0f5808986555ec3517a84768c4.
This reverts commit f80950a8bb985c082b26534b0e157447bf803935.
This reverts commit 0778cad9f325df4d7b32b22f3dba201a16a0b8fe.
This reverts commit 8b70d527d7ec1c8b9e921177119a0d906ffad4f0.
2020-10-15 00:21:36 -07:00
Luqman Aden
32a4ad3b6c [LLD] Set alignment as part of Characteristics in TLS table.
Fixes https://bugs.llvm.org/show_bug.cgi?id=46473

LLD wasn't previously specifying any specific alignment in the TLS table's Characteristics field so the loader would just assume the default value (16 bytes). This works most of the time except if you have thread locals that want specific higher alignments (e.g. 32 as in the bug) *even* if they specify an alignment on the thread local. This change updates LLD to take the max alignment from tls section.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D88637
2020-10-14 19:41:03 -07:00
Luqman Aden
7fe13af676 Nit: Use early return to reduce indentation. 2020-10-14 19:34:32 -07:00
Luqman Aden
8b70d527d7 [LLD] Set alignment as part of Characteristics in TLS table.
Differential Revision: https://reviews.llvm.org/D88637
2020-10-14 19:34:31 -07:00
Andrew Paverd
cfd8481da1 Reland [CFGuard] Add address-taken IAT tables and delay-load support
This patch adds support for creating Guard Address-Taken IAT Entry Tables (.giats$y sections) in object files, matching the behavior of MSVC. These contain lists of address-taken imported functions, which are used by the linker to create the final GIATS table.
Additionally, if any DLLs are delay-loaded, the linker must look through the .giats tables and add the respective load thunks of address-taken imports to the GFIDS table, as these are also valid call targets.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D87544
2020-10-13 13:20:52 -07:00
Martin Storsjö
45c4c54003 [LLD] [COFF] Add a private option for setting the os version separately from subsystem version
The MinGW driver has separate options for OS and subsystem version.
Having this available in lld-link allows the MinGW driver to both match
GNU ld better and simplifies the code for merging two (potentially
mismatching) arguments into one.

Differential Revision: https://reviews.llvm.org/D88802
2020-10-05 23:08:01 +03:00