2463 Commits

Author SHA1 Message Date
Kazu Hirata
7940b0546b [BOLT] Fix warning
This patch fixes:

  bolt/lib/Core/BinaryContext.cpp:582:8: error: unused variable
  'printEntryDiagnostics' [-Werror,-Wunused-variable]

  bolt/lib/Core/BinaryContext.cpp:842:10: error: unused variable
  'isSibling' [-Werror,-Wunused-variable]
2025-04-12 23:35:49 -07:00
Amir Ayupov
fa4ac19f0f
[BOLT] Accept PLT fall-throughs as valid traces (#129481)
We used to report PLT traces as invalid (mismatching disassembled
function contents) because PLT functions are marked as pseudo and
ignored, thus missing CFG. However, such traces are not mismatching
the function contents. Accept them without attaching the profile.

Test Plan: updated callcont-fallthru.s
2025-04-11 21:26:19 -07:00
Fangrui Song
c04d9d57ee
MCAsmStreamer: Replace the MCInstPrinter * parameter with unique_ptr
... to clarify ownership, aligning with other parameters. Using
`std::unique_ptr` encourages users to manage `createMCInstPrinter` with
a unique_ptr instead of a raw pointer, reducing the risk of memory
leaks.

* llvm-mc: fix a leak and update llvm/test/tools/llvm-mc/disassembler-options.test
* #121078 copied the llvm-mc code to CodeGenTargetMachineImpl and made
  the same mistake. Fixed by 2b8cc651dca0c000ee18ec79bd5de4826156c9d6

Using unique_ptr requires #include MCInstPrinter.h in a few translation
units.

* Delete a createAsmStreamer overload I deprecated in 2024
* SystemZMCTargetDesc.cpp: rename to `createSystemZAsmStreamer` to fix
  an overload conflict.

Pull Request: https://github.com/llvm/llvm-project/pull/135128
2025-04-10 21:25:35 -07:00
Amir Ayupov
ba93fe97c2
[BOLT][NFC] Simplify getOrCreate/analyze/populate/emitJumpTable (#132108) 2025-04-10 21:17:04 -07:00
Anatoly Trosinenko
2927050dd4
[BOLT] Gadget scanner: refine class names and debug output (NFC) (#135073)
Scanning functions without CFG information as well as the detection of
authentication oracles requires introducing more classes related to
register state analysis. To make the future code easier to understand,
rename several classes beforehand.

To detect authentication oracles, one has to query the properties of
*output* operands of authentication instructions *after* the instruction
is executed - this requires adding another analysis that iterates over
the instructions in reverse order, and a corresponding state class.

As the main difference of the existing `State` class is that it stores
the properties of source register operands of the instructions before
the instruction's execution, rename it to `SrcState` and
`PacRetAnalysis` to `SrcSafetyAnalysis`.

Apply minor adjustments to the debug output along the way.
2025-04-10 20:54:05 +03:00
Anatoly Trosinenko
8521bd2424
[BOLT][AArch64] Handle PAuth call instructions in isIndirectCall (#133227)
Handle `BLRA*` opcodes in AArch64MCPlusBuilder::isIndirectCall, update
getRegUsedAsCallDest accordingly.
2025-04-08 13:23:10 +03:00
Anatoly Trosinenko
2c107238d5
[BOLT] Make DataflowAnalysis::getStateBefore() const (NFC) (#133308) 2025-04-07 13:37:34 +03:00
Anatoly Trosinenko
0fc7aec349
[BOLT] Gadget scanner: detect address materialization and arithmetic (#132540)
In addition to authenticated pointers, consider the contents of a
register safe if it was
* written by PC-relative address computation
* updated by an arithmetic instruction whose input address is safe
2025-04-07 13:13:11 +03:00
Maksim Panchenko
e4cbb7780b
[BOLT][AArch64] Fix symbolization of unoptimized TLS access (#134332)
TLS relocations may not have a valid BOLT symbol associated with them.
While symbolizing the operand, we were checking for the symbol value,
and since there was no symbol the check resulted in a crash.

Handle TLS case while performing operand symbolization on AArch64.
2025-04-04 11:42:21 -07:00
Paschalis Mpeis
3d24046b33
[BOLT] Skip out-of-range pending relocations (#116964)
When a pending relocation is created it is also marked whether it is
optional or not. It can be optional when such relocation is added as
part of an optimization (i.e., `scanExternalRefs`).

When bolt tries to `flushPendingRelocations`, it safely skips any
optional relocations that cannot be encoded due to being out of
range. A pre-requisite to that is the usage of the `-force-patch`
flag. Alternatrively, BOLT will bail out with a relevant message.

Background:
BOLT, as part of scanExternalRefs, identifies external references from
calls and creates some pending relocations for them. Those when
flushed will update references to point to the optimized functions.
This optimization can be disabled using `--no-scan`.

BOLT can assert if any of these pending relocations cannot be encoded.

This patch does not disable this optimization but instead selectively
applies it given that a pending relocation is optional and `-force-patch`
was enabled.
2025-04-04 17:31:14 +01:00
Rodrigo Rocha
b9891715af
[BOLT] Handle generation of compare and jump sequences (#131949)
This patch fixes the following two issues with the createCmpJE for
AArch64:
1. Avoids overwriting the value of the input register RegNo by use XZR
as the destination register.
   subs xzr, RegNo, #Imm
   which is equivalent to a simple
   cmp RegNo, #Imm
2. The immediate operand to the Bcc instruction must be EQ instead of
#Imm.

This patch also adds a new function for createCmpJNE and unit tests for
the both createCmpJE and createCmpJNE for X86 and AArch64.
2025-04-03 18:34:24 -07:00
Anatoly Trosinenko
c818ae7399
[BOLT] Gadget scanner: detect non-protected indirect calls (#131899)
Implement the detection of non-protected indirect calls and branches
similar to pac-ret scanner.
2025-04-03 16:40:34 +03:00
Alexey Moksyakov
19a319667b
[bolt][aarch64] Adding test with unsupported indirect branches (#127655)
This test contains the set of common indirect branch patterns.
Adding the support will be step by step
2025-04-01 13:49:09 +03:00
Maksim Panchenko
b2d272ccfb
[BOLT][X86] Fix getTargetSymbol() (#133834)
In 96e5ee2, I inadvertently broke the way non-trivial symbol references
got updated from non-optimized code. The breakage was a consequence of
`getTargetSymbol(MCExpr *)` not returning a symbol when the parameter
was a binary expression. Fix `getTargetSymbol()` to cover such cases.
2025-03-31 18:31:33 -07:00
Kazu Hirata
0c7be9392f
[BOLT] Use *Set::insert_range (NFC) (#133601) 2025-03-29 16:52:16 -07:00
Paschalis Mpeis
427725508b
[BOLT] Add getter for optional relocations (#133085)
Minor refactoring on comments.
2025-03-28 14:07:51 +00:00
Maksim Panchenko
96e5ee23a7
[BOLT][AArch64] Add partial support for lite mode (#133014)
In lite mode, we only emit code for a subset of functions while
preserving the original code in .bolt.org.text. This requires updating
code references in non-emitted functions to ensure that:

* Non-optimized versions of the optimized code never execute.
* Function pointer comparison semantics is preserved.

On x86-64, we can update code references in-place using "pending
relocations" added in scanExternalRefs(). However, on AArch64, this is
not always possible due to address range limitations and linker address
"relaxation".

There are two types of code-to-code references: control transfer (e.g.,
calls and branches) and function pointer materialization.
AArch64-specific control transfer instructions are covered by #116964.

For function pointer materialization, simply changing the immediate
field of an instruction is not always sufficient. In some cases, we need
to modify a pair of instructions, such as undoing linker relaxation and
converting NOP+ADR into ADRP+ADD sequence.

To achieve this, we use the instruction patch mechanism instead of
pending relocations. Instruction patches are emitted via the regular MC
layer, just like regular functions. However, they have a fixed address
and do not have an associated symbol table entry. This allows us to make
more complex changes to the code, ensuring that function pointers are
correctly updated. Such mechanism should also be portable to RISC-V and
other architectures.

To summarize, for AArch64, we extend the scanExternalRefs() process to
undo linker relaxation and use instruction patches to partially
overwrite unoptimized code.
2025-03-27 21:33:25 -07:00
Ash Dobrescu
a308d421aa
Remove -no-pie case from indirect-goto-relocs.test (#133067)
This test was added in PR:
https://github.com/llvm/llvm-project/pull/120267. The -no-pie case in
the above mentioned test needs to be removed as subsequent changes have
caused it to fail.
2025-03-26 11:11:55 +00:00
Anatoly Trosinenko
b6b40e9ac9
[BOLT] Gadget scanner: reformulate the state for data-flow analysis (#131898)
In preparation for implementing support for detection of non-protected
call instructions, refine the definition of state which is computed for
each register by data-flow analysis.

Explicitly marking the registers which are known to be trusted at
function entry is crucial for finding non-protected calls. In addition,
it fixes less-common false negatives for pac-ret, such as `ret x1` in
`f_nonx30_ret_non_auted` test case.
2025-03-25 21:45:02 +03:00
Kazu Hirata
993311799b [BOLT] Fix a warning
This patch fixes:

  bolt/lib/Passes/PAuthGadgetScanner.cpp:438:18: error: unused
  variable 'BC' [-Werror,-Wunused-variable]
2025-03-21 11:08:27 -07:00
Anatoly Trosinenko
72d1058af0
[BOLT] Gadget scanner: refactor analysis of RET instructions (#131897)
In preparation for implementing detection of more gadget kinds,
refactor checking for non-protected return instructions.
2025-03-21 19:54:57 +03:00
Paschalis Mpeis
6bbd45dec7
[NFC][BOLT] Refactor ForcePatch option (#127812)
Move force-patch flag to CommandLineOpts and add details on
PatchEntries.
2025-03-21 15:55:09 +00:00
Anatoly Trosinenko
03557169e0
[BOLT] Gadget scanner: streamline issue reporting (#131896)
In preparation for adding more gadget kinds to detect, streamline
issue reporting.

Rename classes representing issue reports. In particular, rename
`Annotation` base class to `Report`, as it has nothing to do with
"annotations" in `MCPlus` terms anymore. Remove references to "return
instructions" from variable names and report messages, use generic
terms instead. Rename NonPacProtectedRetAnalysis to PAuthGadgetScanner.

Remove `GeneralDiagnostic` as a separate class, make `GenericReport`
(former `GenDiag`) store `std::string Text` directly. Remove unused
`operator=` and `operator==` methods, as `Report`s are created on the
heap and referenced via `shared_ptr`s.

Introduce `GadgetKind` class - currently, it only wraps a `const char *`
description to display to the user. This description is intended to be
a per-gadget-kind constant (or a few hard-coded constants), so no need
to store it to `std::string` field in each report instance. To handle
both free-form `GenericReport`s and statically-allocated messages
without unnecessary overhead, move printing of the report header to the
base class (and take the message argument as a `StringRef`).
2025-03-21 11:19:53 +03:00
Fangrui Song
42a8813757 [RISCV] Rename VariantKind to Specifier
Follow the X86 and Mips renaming.

> "Relocation modifier" suggests adjustments happen during the linker's relocation step rather than the assembler's expression evaluation.
> "Relocation specifier" is clear, aligns with Arm and IBM AIX's documentation, and fits the assembler's role seamlessly.

In addition, rename *MCExpr::getKind, which confusingly shadows the base class getKind.
2025-03-20 22:25:57 -07:00
Paschalis Mpeis
5f6d9b45e9
[BOLT] Make Relocations a class and add optional field (#131638)
This patch converts `Relocations` from a struct to a class, and
introduces the `Optional` field. Patch #116964 will use it.

Some optimizations, like `scanExternalRefs`, create relocations that
patch the old code. Under certain circumstances these may be skipped
without correctness implications.
2025-03-20 17:16:14 +00:00
Kazu Hirata
10624e67c3 [BOLT] Fix warnings
bolt/lib/Passes/NonPacProtectedRetAnalysis.cpp:62:13: error: unused
  function 'traceInst' [-Werror,-Wunused-function]

  bolt/lib/Passes/NonPacProtectedRetAnalysis.cpp:68:13: error: unused
  function 'traceReg' [-Werror,-Wunused-function]

  bolt/lib/Passes/NonPacProtectedRetAnalysis.cpp:80:13: error: unused
  function 'traceRegMask' [-Werror,-Wunused-function]
2025-03-20 10:12:46 -07:00
Anatoly Trosinenko
482b95217e
[BOLT] Gadget scanner: factor out utility code (#131895)
Factor out the code for mapping from physical registers to consecutive
array indexes.

Introduce helper functions to print instructions and registers to
prevent mixing of analysis logic and implementation details of debug
output.

Removed the debug printing from `Gadget::generateReport`, as it doesn't
seem to add important information to what was already printed in the
report itself.
2025-03-20 19:35:31 +03:00
Ash Dobrescu
3bba268013
[BOLT] Support computed goto and allow map addrs inside functions (#120267)
Create entry points for addresses referenced by dynamic relocations and
allow getNewFunctionOrDataAddress to map addrs inside functions. By
adding addresses referenced by dynamic relocations as entry points. This
patch fixes an issue where bolt fails on code using computing goto's.
This also fixes a mapping issue with the bugfix from this PR:
https://github.com/llvm/llvm-project/pull/117766.
2025-03-19 14:55:59 +00:00
Maksim Panchenko
70bf5e514b
[BOLT][AArch64] Symbolize ADRP after relaxation (#131414)
When the linker relaxes a GOT load, it changes ADRP+LDR instruction pair
into ADRP+ADD. It is relatively straightforward to detect and symbolize
the second instruction in the disassembler. However, it is not always
possible to properly symbolize the ADRP instruction without looking at
the second instruction. Hence, we have the FixRelaxationPass that adjust
the operand of ADRP by looking at the corresponding ADD.

This PR tries to properly symbolize ADRP earlier in the pipeline, i.e.
in AArch64MCSymbolizer. This change makes it easier to adjust the
instruction once we add AArch64 support in `scanExternalRefs()`.
Additionally, we get a benefit of looking at proper operands while
observing the function state prior to running FixRelaxationPass.

To disambiguate the operand of ADRP that has a GOT relocation against
it, we look at the contents/value of the operand. If it contains an
address of a page that is valid for GOT, we assume that the operand
wasn't modified by the linker and leave it up to FixRelaxationPass to do
a proper adjustment. If the page referenced by ADRP cannot point to GOT,
then it's an indication that the linker has modified the operand and we
substitute the operand with a non-GOT reference to the symbol.
2025-03-18 14:31:31 -07:00
Kazu Hirata
c72f7958b0 [BOLT] Fix the build
This is a follow-up for:

  commit 3c4b9317916ccd2e18c30b1540589518a4c7c88a
  Author: Fangrui Song <i@maskray.me>
  Date:   Mon Mar 17 20:05:28 2025 -0700
2025-03-17 20:18:34 -07:00
Anatoly Trosinenko
4f2ee07454
[BOLT][AArch64] Do not crash on authenticated branch instructions (#129898)
When an indirect branch instruction is decoded, analyzeIndirectBranch
method is asked if this is a well-known code pattern. On AArch64, the
only special pattern which is detected is Jump Table, emitted as a
branch to the sum of a constant base address and a variable offset.
Therefore, `Inst.getOpcode()` being one of `AArch64::BRA*` means Inst
cannot belong to such Jump Table pattern, thus returning early.
2025-03-17 12:00:05 +03:00
Kazu Hirata
4b1b629d60 [BOLT] Fix a warning
This patch fixes:

  bolt/lib/Target/AArch64/AArch64MCSymbolizer.cpp:128:20: error:
  unused variable 'SymbolPageAddr' [-Werror,-Wunused-variable]
2025-03-14 19:20:03 -07:00
Maksim Panchenko
bac21719a8
[BOLT] Pass unfiltered relocations to disassembler. NFCI (#131202)
Instead of filtering and modifying relocations in readRelocations(),
preserve the relocation info and use it in the symbolizing disassembler.
This change mostly affects AArch64, where we need to look at original
linker relocations in order to properly symbolize instruction operands.
2025-03-14 18:44:33 -07:00
Paschalis Mpeis
2f9d94981c
[BOLT] Change Relocation Type to 32-bit NFCI (#130792) 2025-03-14 18:15:59 +00:00
Kazu Hirata
03614b9a8a
[BOLT] Workaround failures (#131245)
These tests have been failing since:

  commit 1cfca53b9f2eadbf864b85995ec7f819d7f29b5e
  Author: Arthur Eubanks <aeubanks@google.com>
  Date:   Wed Mar 12 16:20:13 2025 -0700

This patch works around the failures by removing some FileCheck
directives.  Hopefully, BOLT folks can chime in and commit a right
fix.
2025-03-13 20:55:43 -07:00
Nikita Popov
f137c3d592
[TargetRegistry] Accept Triple in createTargetMachine() (NFC) (#130940)
This avoids doing a Triple -> std::string -> Triple round trip in lots
of places, now that the Module stores a Triple.
2025-03-12 17:35:09 +01:00
Maksim Panchenko
a28daa7c1a
[BOLT][AArch64] Keep relocations for linker-relaxed instructions. NFCI (#129980)
We used to filter out relocations corresponding to NOP+ADR instruction
pairs that were a result of linker "relaxation" optimization. However,
these relocations will be useful for reversing the linker optimization.
Keep the relocations and ignore them while symbolizing ADR instruction
operands.
2025-03-05 23:06:01 -08:00
chrisPyr
038fff3f24
[NFC][BOLT] Make file-local cl::opt global variables static (#126472)
#125983
2025-03-05 22:11:05 -08:00
Yevhen Babiichuk (DustDFG)
36cd60144b
[BOLT] Remove unexisting targets from bolt dockerfile (#122321)
`perf2bolt` and `llvm-boltdiff` are now not separate targets but just
symlinks to `llvm-bolt` created when you install `llvm-bolt` itself so
when you try to build it ninja reports there are no targets for both of
them
2025-03-05 09:23:06 +00:00
Eric Wang
fcb65ad2a2
[BOLT] Fix kernel version check for THP in hugify (#129380)
BOLT --hugify does not work in kernel 6.x.

Co-authored-by: rfwang07 <wangrufeng5@huawei.com>
2025-03-04 20:38:41 -08:00
Maksim Panchenko
b971d4d7c8
[BOLT][AArch64] Add symbolizer for AArch64 disassembler. NFCI (#127969)
Add AArch64MCSymbolizer that symbolizes `MCInst` operands during
disassembly. The symbolization was previously done in
`BinaryFunction::disassemble()`, but it is also required by
`scanExternalRefs()` for "lite" mode functionality. Hence, similar to
x86, I've implemented the symbolizer interface that uses
`BinaryFunction` relocations to properly create instruction operands. I
expect the result of the disassembly to be identical after the change.

AArch64 disassembler was not calling `tryAddingSymbolicOperand()` for
`MOV` instructions. Fix that. Additionally, the disassembler marks `ldr`
instructions as branches by setting `IsBranch` parameter to true. Ignore
the parameter and rely on `MCPlusBuilder` interface instead.

I've modified `--check-encoding` flag to check symolization of operands
of instructions that have relocations against them.
2025-03-03 12:44:28 -08:00
Maksim Panchenko
6a161cbfd4
[BOLT] Remove BinaryFunction::IsPatched. NFC (#129461)
BinaryFunction::IsPatched is no longer used.
2025-03-02 23:40:02 -08:00
Fangrui Song
74638f1634 [test] Replace .data.rel.ro with .section .data.rel.ro,"aw"
to avoid using the extension unsupported by gas.
2025-03-01 20:55:17 -08:00
Maksim Panchenko
5a11912ece
[BOLT] Refactor interface for creating instruction patches. NFCI (#129404)
Add BinaryContext::createInstructionPatch() interface for patching parts
of the original binary with new instruction sequences. Refactor
PatchEntries pass to use the new interface.
2025-03-01 19:20:17 -08:00
Maksim Panchenko
8910e41c86
[BOLT][AArch64] Refactor ADR to ADRP+ADD conversion pass. NFCI (#129399)
In preparation of using the new interface in more places, refactor the
ADR conversion pass.
2025-03-01 14:10:59 -08:00
Maksim Panchenko
074c2c6713
[BOLT] Refactor MCInst target symbol lookup. NFCI (#129131)
In analyzeInstructionForFuncReference(), use MCPlusBuilder interface
while scanning symbolic operands of MCInst. Should be NFC on x86, but
will make the function work on other architectures. Note that it's
currently unused on non-x86 as its functionality is exclusive to safe
ICF that runs on x86 only.
2025-02-28 17:57:54 -08:00
ShatianWang
7e33bebe7c
[BOLT] Report flow conservation scores (#127954)
Add two additional profile quality stats for CG (call graph) and CFG
(control flow graph) flow conservations besides the CFG discontinuity
stats introduced in #109683. The two new stats quantify how different
"in-flow" is from "out-flow" in the following cases where they should be
equal. The smaller the reported stats, the better the flow conservations
are.

CG flow conservation: for each function that is not a program entry, the
number of times the function is called according to CG ("in-flow")
should be equal to the number of times the transition from an entry
basic block of the function to another basic block within the function
is recorded ("out-flow").

CFG flow conservation: for each basic block that is not a function entry
or exit, the number of times the transition into this basic block from
another basic block within the function is recorded ("in-flow") should
be equal to the number of times the transition from this basic block to
another basic block within the function is recorded ("out-flow").

Use `-v=1` for more detailed bucketed stats, and use `-v=2` to dump
functions / basic blocks with bad flow conservations.
2025-02-28 11:06:52 -05:00
YongKang Zhu
5401c675eb
[BOLT][instr] Avoid WX segment (#128982)
BOLT instrumented binary today has a readable (R), writeable (W) and also
executable (X) segment, which Android system won't load due to its WX
attribute. Such RWX segment was produced because BOLT has a two step linking,
first for everything in the updated or rewritten input binary and next for
runtime library. Each linking will layout sections in the order of RX sections
followed by RO sections and then followed by RW sections. So we could end up
having a RW section `.bolt.instr.counters` surrounded by a number of RO and RX
sections, and a new text segment was then formed by including all RX sections
which includes the RW section in the middle, and hence the RWX segment. One
way to fix this is to separate the RW `.bolt.instr.counters` section into its
own segment by a). assigning the starting addresses for section
`.bolt.instr.counters` and its following section with regular page aligned
addresses and b). creating two extra program headers accordingly.
2025-02-27 16:13:57 -08:00
Amir Ayupov
f567524399
[BOLT] Fix doTrace in BAT mode (#128546)
When processing BOLTed binaries with BAT section, we used to
indiscriminately use `BAT->getFallthroughsInTrace` to record
fall-throughs, even if the function is not covered by BAT.

Fix that by using non-BAT CFG-based `getFallthroughsInTrace` if the
function is not in BAT.

Test Plan: updated bolt-address-translation-yaml.test
2025-02-25 10:56:13 -08:00
Amir Ayupov
3968ebd00d
[BOLT] Keep multi-entry functions simple in aggregation mode (#128253)
BOLT used to mark multi-entry functions non-simple in non-relocation
mode with the reasoning that we can't move them due to potentially
undetected references. However, in aggregation mode it doesn't apply as
BOLT doesn't perform optimizations.

Relax this constraint in case of an aggregation job.

Test Plan: added entry-point-fallthru.s
2025-02-25 10:53:45 -08:00