561 Commits

Author SHA1 Message Date
Fangrui Song
f61e1e46ff [MC] Make MCContext::getAsmInfo return a reference. NFC (#194523)
The MAI member is non-null. #194280 made this clearer by making the
MCContext constructor take MCAsmInfo by reference. Convert getAsmInfo to
return const MCAsmInfo & and the member to a reference.
2026-04-28 03:57:47 +00:00
Fangrui Song
13e98d8341 [MC] Take MCAsmInfo by reference in MCContext and TargetMachine. NFC (#194280)
Both MCContext::MCContext and TargetMachine::getMCAsmInfo treat
MCAsmInfo as a pointer that must be non-null. Make the contract
explicit:

* MCContext's constructor takes `const MCAsmInfo &MAI`.
* TargetMachine::getMCAsmInfo returns `const MCAsmInfo &`.

Make this change now since the MCContext ctor has recently been updated.
2026-04-27 07:48:54 +00:00
Fangrui Song
33f2036f35 [MC] Add MCTargetOptions to MCAsmInfo constructor. NFC (#194200)
Since #180464 the canonical MCTargetOptions pointer is stored in
MCAsmInfo, but it is bound after construction via `setTargetOptions`
called from TargetRegistry::createMCAsmInfo.

Direct constructions in unit tests can leave the pointer null, leading
to a runtime assert failure. Add MCTargetOptions to every MCAsmInfo
subclass constructor, store it as a reference in MCAsmInfo, and remove
`setTargetOptions()`.
2026-04-26 05:52:32 +00:00
Farid Zakaria
ec1e3aef9a [BOLT] Update LSDA encoding for x86-64 large code model (#190685)
BOLT hardcoded 4-byte LSDA (exception table) encoding for x86-64. This
is insufficient for large code model binaries where functions in .ltext
sections may be placed at addresses above 2GB, exceeding the range of
DW_EH_PE_udata4/DW_EH_PE_sdata4 encodings.

Detect large code model by checking for .ltext sections
(SHF_X86_64_LARGE) and update LSDAEncoding to use 8-byte pointers:
- Non-PIC: DW_EH_PE_absptr (8-byte absolute)
- PIC: DW_EH_PE_pcrel | DW_EH_PE_sdata8 (8-byte PC-relative)

This was pulled out from
https://github.com/llvm/llvm-project/pull/190637
2026-04-16 00:34:08 -07:00
Sergei Barannikov
f4e1a51d10 [bolt] Remove unused argument of DataExtractor constructor (NFC) (#191841)
`AddressSize` parameter is not used by `DataExtractor` and will be
removed in the future. See #190519 for more context.

I took the liberty of switching from using the `StringRef` constructor
overload to `ArrayRef` where appropriate.
2026-04-14 08:13:54 +03:00
Sergei Barannikov
b6ff43f1ec [Support] Remove address-extraction methods from DataExtractor (NFC) (#190519)
Most clients don't have a notion of "address" and pass arbitrary values
(including `0` and `sizeof(void *)`) to `DataExtractor` constructors.
This makes address-extraction methods dangerous to use.

Those clients that do have a notion of address can use other methods
like `getUnsigned()` to extract an address, or they can derive from
`DataExtractor` and add convenience methods if extracting an address is
routine. `DWARFDataExtractor` is an example, where the removed methods
were actually moved.

This does not remove `AddressSize` argument of `DataExtractor`
constructors yet, but makes it unused and overloads constructors in
preparation for their deletion. I'll be removing uses of the
to-be-deleted constructors in follow-up patches.
2026-04-13 16:44:51 +03:00
Fangrui Song
1578bc684e [MC] Move MCTargetOptions pointer from MCContext to MCAsmInfo (#180464)
Except MC-internal `MCAsmInfo()` uses, MCAsmInfo is always constructed
with `const MCTargetOptions &` via `TargetRegistry::createMCAsmInfo`
(https://reviews.llvm.org/D41349). Store the pointer in MCAsmInfo and
change `MCContext::getTargetOptions()` to retrieve it from there,
removing the `MCTargetOptions const *TargetOptions` member from
MCContext.

MCContext's constructor still accepts an MCTargetOptions parameter
for now but is often omitted by call sites.
A subsequent change will remove this parameter and update all callers.
2026-04-08 04:35:58 +00:00
Fangrui Song
d1b9b4c548 [MC] Remove unused NoExecStack parameter from MCStreamer::initSections. NFC (#188184)
Unused after commit 34bc5d580b
2026-03-24 07:42:09 +00:00
Fangrui Song
c889454f1d [MC] Rename PrivateGlobalPrefix to InternalSymbolPrefix. NFC (#185164)
The "private global" terminology, likely came from
llvm/lib/IR/Mangler.cpp, is misleading: "private" is the opposite of
"global", and these prefixed symbols are not global in the object file
format sense (e.g. ELF has STB_GLOBAL while these symbols are always
STB_LOCAL). The term "internal symbol" better describes their purpose:
symbols for internal use by compilers and assemblers, not meant to be
visible externally.

This rename is a step toward adopting the "internal symbol prefix"
terminology agreed with GNU as
(https://sourceware.org/pipermail/binutils/2026-March/148448.html).
2026-03-10 01:03:27 -07:00
Asher Dobrescu
7bce678ec1 [BOLT] Check if symbol is in data area of function (#160143)
There are cases in which `getEntryIDForSymbol` is called, where the
given Symbol is in a constant island, and so BOLT can not find its
function. This causes BOLT to reach `llvm_unreachable("symbol not
found")` and crash. This patch adds a check that avoids this crash.
2026-03-06 10:37:54 +00:00
YongKang Zhu
95685ca52e [BOLT] Retain certain local symbols (#184074)
BOLT currently strips all STT_NOTYPE STB_LOCAL zero-sized symbols
that fall inside function bodies. Certain such symbols are named
labels (loop markers and subroutine entry points) or local function
symbols in hand-written assembly. We now keep them in local symbol
table in BOLT processed binaries for better symbolication.
2026-03-05 00:34:36 -08:00
YongKang Zhu
14bcb1a009 [BOLT] Make sure IOAddressMap exist before lookup (NFC) (#183184)
`BinaryFunction::translateInputToOutputAddress()` contains fallback
logic in case that querying `IOAddressMap` doesn't yield an output
address. Because this function could be called in scenarios where
`IOAddressMap` won't be set up, we should check if the map actually
exists before lookup.
2026-03-01 23:27:39 -08:00
Fangrui Song
6f0b0ecaba [NFC] Ensure MCTargetOptions outlives MCAsmInfo at createMCAsmInfo call sites (#180465)
Preparatory change for storing the MCTargetOptions pointer in MCAsmInfo
(#180464)
2026-02-17 21:48:22 -08:00
Maksim Panchenko
f80e3b3d7e [BOLT] Keep folded functions in BinaryFunctions map. NFC (#180392)
In relocation mode, keep folded functions in the BinaryFunctions map
instead of erasing them. Mark them as folded using setFolded() and skip
emitting them.
2026-02-10 14:56:26 -08:00
Gergely Bálint
4193c404ca [BOLT][BTI] Disassemble PLT entries when processing BTI binaries (#169663)
PLT entries are PseudoFunctions, and are not disassembled or emitted.
For BTI, we need to check the first MCInst of PLT entries, to see
if indirectly calling them is safe or not.

This patch disassembles PLTs for binaries using BTI, while not changing
the behaviour for binaries without BTI.

The PLTs are only disassembled, not emitted.

---------

Co-authored-by: Paschalis Mpeis <paschalis.mpeis@arm.com>
2026-01-16 07:40:05 +01:00
Austin Jiang
e6cdfb75ac Fix typos and spelling errors across codebase (#156270)
Corrected various spelling mistakes such as 'occurred', 'receiver',
'initialized', 'length', and others in comments, variable names,
function names, and documentation throughout the project. These
changes improve code readability and maintain consistency in naming
and documentation.

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2026-01-13 11:52:46 -05:00
Harald van Dijk
e720636120 [BOLT] Avoid UB due to misaligned access. (#174990)
There is no guarantee that PatchOffset is suitably aligned for uint32_t,
and in BOLT's own tests, it is not aligned for uint32_t.

Fixes test failures seen with LLVM_USE_SANITIZER=Undefined.
2026-01-10 03:45:13 +00:00
Maksim Panchenko
4a8e6a36b6 [BOLT][AArch64] Speed up ICF pass (#172783)
Add hashing support for MCSpecifierExpr, which is frequently used as an
operand in AArch64 instructions. Proper hashing reduces collisions when
placing functions into buckets, resulting in shorter Identical Code
Folding (ICF) pass runtime.

In one benchmark, the ICF wall time decreased from 272s to 124s.
2025-12-17 21:05:54 -08:00
Maksim Panchenko
adaca1348e [BOLT] Introduce getOutputBinaryFunctions(). NFCI (#172174)
To gain better control over the functions that go into the output file
and their order, introduce `BinaryContext::getOutputBinaryFunctions()`.

The new API returns a modifiable list of functions in output order.

This list is filled by a new `PopulateOutputFunctions` pass and includes
emittable functions from the input file, plus functions added by BOLT
(injected functions).

The new functionality allows to freely intermix input functions with
injected ones in the output, which will be used in new PRs.

The new function replaces `BinaryContext::getSortedFunctions()`, but
unlike its predecessor, it includes injected functions in the returned
list.
2025-12-14 16:29:01 -08:00
Maksim Panchenko
3c2f81820c [BOLT] Introduce BinaryFunctionListType. NFC (#172128)
Use `BinaryFunctionListType` as an alias for `std::vector<BinaryFunction *>`.
2025-12-13 11:52:36 -08:00
Maksim Panchenko
6470d1bb98 [BOLT] Exclude BOLT injected functions from AssignSections. NFCI (#171579)
Assign output sections for injected functions explicitly, and don't
reassign in AssignSections pass.

This change is a prerequisite for further PRs where veneer functions are
created as injected functions and their code section depends on their
placement.
2025-12-10 10:30:07 -08:00
Maksim Panchenko
28ff941a2c [BOLT][AArch64] Always cover veneers in lite mode (#171534)
If a veneer is not disassembled in lite mode, the veneer elimination
pass will not recognize it as such and the call to such veneer will
remain unchanged.

Later, we may need to insert a new veneer for such code ending up with a
double veneer.

To avoid such suboptimal code generation, always disassemble veneers and
guarantee that they are converted to direct calls in BOLT.
2025-12-10 09:54:37 -08:00
Maksim Panchenko
dda715df2d [BOLT][DWARF] Improve reporting on missing DWOs (#171506)
List all required missing DWO files and report a summary with
recommendations on how to proceed.
2025-12-09 15:46:43 -08:00
Jinjie Huang
33e0301b07 [BOLT] Add validation for direct call/branch targets (#165406)
In some edge cases, a binary may contain direct `branch` or `call`
instructions whose target do not point to a valid executable
instruction. This can occur due to compiler bugs, hand-written assembly,
obfuscation technique, **or when control flow targets a data by
mistake.**

We also encountered the problems as described in this
[issue](https://github.com/llvm/llvm-project/issues/149382), where "data
in code" within OpenSSL's hand-written assembly was misidentified as
instructions(island identification seems fail due to the absence of a
corresponding data symbol). The problem occurred because a data sequence
was incorrectly disassembled as a "jb" instruction.

The point here is that the data should not be pointed to by any edge, so
this patch tries to address this by validating the destination address
for **direct branches and calls**. If the target instruction is
invalid(implies a corrupted control flow), this function will be set
ignored.

Although this approach appears helpful for addressing the 'data in code'
problem, its validation might be compromised if the data can be
disassembled as normal instruction.
2025-12-09 16:17:19 +08:00
Maksim Panchenko
02482f4273 [BOLT] Properly validate relocations against internals of a function (#167451)
Validation of data relocations targeting internals of a function was
happening based on offsets inside a function. As a result, if multiple
relocations were targeting the same offset, and one of the relocations
was verified, e.g. as belonging to a jump table, then all relocations
targeting the offset would be considered verified and valid.

Now that we are tracking relocations pointing inside every function, we
can do a better validation based on the location of the relocation.
E.g., if a relocation belongs to a jump table only that relocation will
be accounted for and other relocations pointing to the same address will
be evaluated independently.
2025-12-06 14:39:08 -08:00
Maksim Panchenko
97c4f367b8 [BOLT] Fix comments for interprocedural branches. NFC (#170745) 2025-12-05 10:53:38 -08:00
Maksim Panchenko
47de55f284 [BOLT] Minor code refactoring. NFC (#170746) 2025-12-04 14:17:58 -08:00
Gergely Bálint
a25e3674ae [BOLT] Rename Pointer Auth DWARF rewriter passes (#164622)
Rename passes to names that better reflect their intent, 
and describe their relationship to each other.

InsertNegateRAStatePass renamed to PointerAuthCFIFixup,
MarkRAStates renamed to PointerAuthCFIAnalyzer.

Added the --print-<passname> flags for these passes.
2025-12-04 11:29:40 +01:00
YongKang Zhu
ac6daa8181 [BOLT][print] Add option '--print-only-file' (NFC) (#168023)
With this option we can pass to BOLT names of functions to be printed
through a file instead of specifying them all on command line.
2025-11-14 10:26:21 -08:00
YongKang Zhu
4cd16f2a0c [BOLT][AArch64] Add more heuristics on epilogue determination (#167077)
Add more heuristics to check if a basic block is an AArch64 epilogue. We
assume instructions that load from stack or adjust stack pointer as
valid epilogue code sequence if and only if they immediately precede the
branch instruction that ends the basic block.
2025-11-10 09:50:44 -08:00
Gergely Bálint
cd68056d13 [BOLT] Simplify RAState helpers (NFCI) (#162820)
- unify isRAStateSigned and isRAStateUnsigned to a common getRAState,
- unify setRASigned and setRAUnsigned into setRAState(MCInst, bool),
- update users of these to match the new implementations.
2025-11-10 16:45:39 +01:00
Kazu Hirata
7b1a74cd79 [BOLT] Use DenseMap::contains (NFC) (#167169)
Identified with readability-container-contains.
2025-11-08 14:44:40 -08:00
Maksim Panchenko
af456dfa11 [BOLT] Refactor tracking internals of BinaryFunction. NFCI (#167074)
In addition to tracking offsets inside a `BinaryFunction` that are
referenced by data relocations, we need to track those relocations too.
Plus, we will need to map symbols referenced by such relocations back to
the containing function.

This change introduces `BinaryFunction::InternalRefDataRelocations` to
track the aforementioned relocations and expands
`BinaryContext::SymbolToFunctionMap` to include local/temp symbols
involved in relocation processing.

There is no functional change introduced that should affect the output.
Future PRs will use the new tracking capabilities.
2025-11-08 00:31:03 -08:00
Maksim Panchenko
7af2b56dd5 [BOLT] Refactor undefined symbols handling. NFCI (#167075)
Remove internal undefined symbol tracking and instead rely on the
emission state of `MCSymbol` while processing data-to-code relocations.

Note that `CleanMCState` pass resets the state of all `MCSymbol`s prior
to code emission.
2025-11-07 19:42:05 -08:00
Kazu Hirata
bddab8359e [BOLT] Remove redundant declarations (NFC) (#166893)
In C++17, static constexpr members are implicitly inline, so they no
longer require an out-of-line definition.

Identified with readability-redundant-declaration.
2025-11-07 07:58:24 -08:00
YongKang Zhu
6fce53af84 [BOLT][AArch64] Skip as many zeros as possible in padding validation (#166467)
We are skipping four zero's at a time when validating code padding in
case that the next zero would be part of an instruction or constant
island, and for functions that have large amount of padding (like due to
hugify), this could be very slow. We now change the validation to skip
as many as possible but still need to be 4's exact multiple number of
zero's. No valid instruction has encoding as 0x00000000 and even if we
stumble into some constant island, the API
`BinaryFunction::isInConstantIsland()` has been made to find the size
between the asked address and the end of island (#164037), so this
should be safe.
2025-11-06 09:38:25 -08:00
Maksim Panchenko
5f1b9023a8 [BOLT][AArch64] Fix printing of relocation types (#166621)
Enumeration of relocation types is not always sequential, e.g. on
AArch64 the first real relocation type is 0x101. As such, the existing
code in `Relocation::print()` was crashing while printing AArch64
relocations. Fix it by using `llvm::object::getELFRelocationTypeName()`.
2025-11-05 12:36:57 -08:00
YongKang Zhu
562e3bfcd4 [BOLT] Add an option for constant island cloning (#165778)
Avoid cloning constant island helps to reduce app size, especially for
BOLT optimization in which cloning would happen when a function is split
into multiple fragments. Add an option to make the cloning optional, and
we will introduce a new pass to handle the reference too far error that
may result from disabling constant island cloning (#165787).
2025-11-03 14:44:05 -08:00
Maksim Panchenko
97660c1094 [BOLT] Issue error on unclaimed PC-relative relocation (#166098)
Replace assert with an error and improve the report when unclaimed
PC-relative relocation is left in strict mode.
2025-11-03 09:19:33 -08:00
Maksim Panchenko
7c01a90545 [BOLT] Refactor handling of branch targets. NFCI (#165828)
Refactor code that verifies external branch destinations and creates
secondary entry points.
2025-10-31 08:56:30 -07:00
Jinjie Huang
6ba2127a5c [BOLT] Add constant island check in scanExternalRefs() (#165577)
The [previous patch](https://github.com/llvm/llvm-project/pull/163418)
has added a check to prevent adding an entry point into a constant
island, but only for successfully disassembled functions.

Because scanExternalRefs() is also called when a function fails to be
disassembled or is skipped, it can still attempt to add an entry point
at constant islands. The same issue may occur if without a check for it

So, this patch complements the 'constant island' check in
scanExternalRefs().
2025-10-31 10:29:00 +08:00
Maksim Panchenko
cd27741c11 [BOLT] Remove CreatePastEnd parameter in getOrCreateLocalLabel(). NFC (#165065)
CreatePastEnd parameter had no effect on the label creation. Remove it.
2025-10-25 22:16:15 -07:00
YongKang Zhu
e1ae126401 [BOLT][AArch64] Validate code padding (#164037)
Check whether AArch64 function code padding is valid,
and add an option to treat invalid code padding as error.
2025-10-22 20:25:06 -07:00
Asher Dobrescu
2bbc4ae850 [BOLT] Check entry point address is not in constant island (#163418)
There are cases where `addEntryPointAtOffset` is called with a given
`Offset` that points to an address within a constant island. This
triggers `assert(!isInConstantIsland(EntryPointAddress)` and causes BOLT
to crash. This patch adds a check which ignores functions that would add
such entry points and warns the user.
2025-10-21 11:08:10 +01:00
Kazu Hirata
9be674420d [BOLT] Replace LLVM_ATTRIBUTE_UNUSED with [[maybe_unused]] (NFC) (#163700)
This patch replaces LLVM_ATTRIBUTE_UNUSED with [[maybe_unused]],
introduced as part of C++17.
2025-10-16 13:06:58 -07:00
Christian Clauss
0fc05aa1c6 [bolt] Fix typos discovered by codespell (#124726)
https://github.com/codespell-project/codespell
```bash
codespell bolt --skip="*.yaml,Maintainers.txt" --write-changes \
    --ignore-words-list=acount,alledges,ans,archtype,defin,iself,mis,mmaped,othere,outweight,vas
```
2025-10-14 14:45:40 +02:00
Gergely Bálint
889bfd9172 Reapply "[BOLT][AArch64] Handle OpNegateRAState to enable optimizing binaries with pac-ret hardening" (#162353) (#162435)
Reapply "[BOLT][AArch64] Handle OpNegateRAState to enable optimizing
binaries with pac-ret hardening (#120064)" (#162353)

This reverts commit c7d776b068.

#120064 was reverted for breaking builders.

Fix: changed the mismatched type in MarkRAStates.cpp to `auto`.

---

Original message:

OpNegateRAState is an AArch64-specific DWARF CFI used to change the value
of the RA_SIGN_STATE pseudoregister. The RA_SIGN_STATE register records
whether the current return address has been signed with PAC.

OpNegateRAState requires special handling in BOLT because its placement
depends on the function layout. Since BOLT reorders basic blocks during
optimization, these CFIs must be regenerated after layout is finalized.

This patch introduces two new passes:

- MarkRAStates (runs before optimizations): assigns a signedness annotation to each
  instruction based on OpNegateRAState CFIs in the input binary.

- InsertNegateRAStates (runs after optimizations): reads the annotations and emits
  new OpNegateRAState CFIs where RA state changes between instructions.

Design details are described in: `bolt/docs/PacRetDesign.md`.
2025-10-08 11:05:41 +02:00
Gergely Bálint
c7d776b068 Revert "[BOLT][AArch64] Handle OpNegateRAState to enable optimizing binaries with pac-ret hardening" (#162353)
Reverts llvm/llvm-project#120064.

@gulfemsavrun reported that the patch broke toolchain builders.
2025-10-07 21:59:18 +02:00
Gergely Bálint
32eaf5b59c [BOLT][AArch64] Handle OpNegateRAState to enable optimizing binaries with pac-ret hardening (#120064)
OpNegateRAState is an AArch64-specific DWARF CFI used to change the value
of the RA_SIGN_STATE pseudoregister. The RA_SIGN_STATE register records
if the current return address has been signed with PAC.

OpNegateRAState requires special handling in BOLT because its placement
depends on the function layout. Since BOLT reorders basic blocks during
optimization, these CFIs must be regenerated after layout is finalized.

This patch introduces two new passes:

- MarkRAStates (runs before optimizations): assigns a signedness annotation to each
  instruction based on OpNegateRAState CFIs in the input binary.

- InsertNegateRAStates (runs after optimizations): reads the annotations and emits
  new OpNegateRAState CFIs where RA state changes between instructions.

Design details are described in: `bolt/docs/PacRetDesign.md`.
2025-10-07 10:22:14 +02:00
Maksim Panchenko
9f4b6375b4 [BOLT][AArch64] Skip R_AARCH64_TLSDESC_CALL relocation (#161610)
R_AARCH64_TLSDESC_CALL is a relocation emitted as a hint for a linker to
replace `blr r` instruction with nop. BOLT does not currently require
any special handling for it.

Note that previously existing extraction of the relocated value was
incorrect.
2025-10-01 19:28:18 -07:00