763 Commits

Author SHA1 Message Date
YafetBeyene
fda24dbc16
[BOLT] Add dump-dot-func option for selective function CFG dumping (#153007)
## Change:
* Added `--dump-dot-func` command-line option that allows users to dump
CFGs only for specific functions instead of dumping all functions (the
current only available option being `--dump-dot-all`)

## Usage:
* Users can now specify function names or regex patterns (e.g.,
`--dump-dot-func=main,helper` or `--dump-dot-func="init.*`") to generate
.dot files only for functions of interest
* Aims to save time when analysing specific functions in large binaries
(e.g., only dumping graphs for performance-critical functions identified
through profiling) and we can now avoid reduce output clutter from
generating thousands of unnecessary .dot files when analysing large
binaries

## Testing
The introduced test `dump-dot-func.test` confirms the new option does
the following:

- [x] 1. `dump-dot-func` can correctly filter a specified functions
- [x] 2. Can achieve the above with regexes
- [x] 3. Can do 1. with a list of functions
- [x] No option specified creates no dot files
- [x] Passing in a non-existent function generates no dumping messages
- [x] `dump-dot-all` continues to work as expected
2025-08-22 10:51:09 +01:00
YongKang Zhu
5c4f506cca
[BOLT] Validate extra entry point by querying data marker symbols (#154611)
Look up marker symbols and decide whether candidate is really
extra entry point in `adjustFunctionBoundaries()`.
2025-08-20 14:18:56 -07:00
Maksim Panchenko
0d9b9d1eef
[BOLT] Keep X86 HLT instruction as a terminator in user mode (#154402)
This is a follow-up to #150963. X86 HLT instruction may appear in the
user-level code, in which case we should treat it as a terminator.
Handle it as a non-terminator in the Linux kernel mode.
2025-08-19 14:41:13 -07:00
Haibo Jiang
21a5729b87
[BOLT] Do not use HLT as split point when build the CFG (#150963)
For x86, the halt instruction is defined as a terminator instruction.
When building the CFG, the instruction sequence following the hlt
instruction is treated as an independent MBB. Since there is no jump
information, the predecessor of this MBB cannot be identified, and it is
considered an unreachable MBB that will be removed.

Using this fix, the instruction sequences before and after hlt are
refused to be placed in different blocks.
2025-08-15 14:35:13 -07:00
Paschalis Mpeis
6ebb8901cc
[BOLT][AArch64] Refuse to run FrameOptimizer pass (#152309)
FrameOptimizer pass runs by default on all targets, however, it defaults
to --frame-opt=none. This patch prevents the pass from running on
non-x86 targets when any other value (hot, full) is specified.
2025-08-08 11:30:42 +03:00
Dmitry Vasilyev
c233deb794
[BOLT] Use llvm-nm by default on Windows (#151805)
Use `llvm-nm` by default instead of `nm` in case of Windows host.
2025-08-05 11:33:26 +04:00
Dmitry Vasilyev
c00df536e3
[BOLT] Fixed cmdline-args.test to work on Windows (#151209)
Added regex to ignore `.exe` in the executable name. 
Ignored OS-dependent message "No such file or directory".
2025-07-31 18:25:39 +04:00
Dmitry Vasilyev
c39b1aedd1
[BOLT] Fixed calling clang++ in tests on Windows (#151193)
`RUN: %clang++ ` tried to execute `clang.exe++` on Windows. Use `%clangxx` instead.
2025-07-31 18:25:09 +04:00
Maksim Panchenko
1e0edb072a
[BOLT][AArch64] Compensate for missing code markers (#151060)
Code written in assembly can have missing code markers. In BOLT, we can
compensate by recognizing that a function entry point should start a
code sequence.

Seen such code in lua jit library.
2025-07-29 12:01:06 -07:00
Aiden Grossman
a7516dd38c
[BOLT] Remove Uses of %T From Lit Tests (#150716)
This patch removes all uses of %T from lit tests within bolt/. %T has
been listed as deprecated for ~7 years and should not be used given it
is not unique per test which means tests that use the same filenames can
race.
2025-07-26 10:13:12 -07:00
Amir Ayupov
a850912de1
[BOLT] Require CFG in BAT mode (#150488)
`getFallthroughsInTrace` requires CFG for functions not covered by BAT,
even in BAT/fdata mode. BAT-covered functions go through special
handling in fdata (`BAT->getFallthroughsInTrace`) and YAML
(`DataAggregator::writeBATYAML`) modes.

Since all modes (BAT/no-BAT, YAML/fdata) now need disassembly/CFG
construction:
- drop special BAT/fdata handling that omitted disassembly/CFG in
  `RewriteInstance::run`, enabling *CFG for all non-BAT functions*,
- switch `getFallthroughsInTrace` to check if a function has CFG,
- which *allows emitting profile for non-simple functions* in all modes.

Previously, traces in non-simple functions were reported as invalid/
mismatching disassembled function contents. This change reduces the
number of such invalid traces and increases the number of profiled
functions. These functions may participate in function reordering via
call graph profile.

Test Plan: updated unclaimed-jt-entries.s
2025-07-25 13:54:37 +02:00
Asher Dobrescu
c8c0e90233
[BOLT] Ensure remember and restore CFIs are in the same list (#144348)
In `addCFIInstruction`, we split the CFI information
between `CFIInstrMapType CIEFrameInstructions` and `CFIInstrMapType
FrameInstructions`. In some cases we can end up with the remember CFI in
`CIEFrameInstructions` and the restore CFI in `FrameInstructions`. This
patch adds a check to make sure we do not split remember and restore
states and fixes https://github.com/llvm/llvm-project/issues/133501.
2025-07-10 15:48:57 +01:00
Maksim Panchenko
fb24b4d46a
[BOLT] Push code to higher addresses under options (#146180)
When --hot-functions-at-end is used in combination with --use-old-text,
allocate code at the highest possible addresses withing old .text.

This feature is mostly useful for HHVM, where it is beneficial to have
hot static code placed as close as possible to jitted code.
2025-06-28 13:53:56 -07:00
Maksim Panchenko
54a7d53227 [BOLT] Fix program-header.test 2025-06-27 19:51:51 -07:00
Maksim Panchenko
d00c83ef22
[BOLT] Skip creation of new segments (#146023)
When all section contents are updated in-place, we can skip creation of
new segment(s), save disk space, and free up low memory addresses.

Currently, this feature only works with --use-gnu-stack.
2025-06-27 09:12:08 -07:00
Anatoly Trosinenko
7a5af4f6b8
[BOLT] Gadget scanner: detect untrusted LR before tail call (#137224)
Implement the detection of tail calls performed with untrusted link
register, which violates the assumption made on entry to every function.

Unlike other pauth gadgets, detection of this one involves some amount
of guessing which branch instructions should be checked as tail calls.
2025-06-26 12:37:25 +03:00
Paschalis Mpeis
249f074b22
[BOLT][AArch64] Make gs-pacret-autiasp.s deterministic (#145527)
In gs-pacret-autiasp.s, the undefined call `bl g` causes inconsistent
basic block splitting: in some platforms BOLT emits two blocks, on some
others one.

Defining a dummy `g` symbol forces a single basic block everywhere.
2025-06-26 09:33:49 +01:00
Amir Ayupov
49847148d4
[BOLT] Fix density for jump-through functions (#145619)
Address the issue that stems from how the density is computed.

Binary *function* density is the ratio of its total dynamic number of
executed bytes over the static size in bytes. The meaning of it is the
amount of dynamic profile information relative to its static size.

Binary *profile* density is the minimum *function* density among *well-
-profiled* functions, taken as functions covering p99 samples, or, in
other words, excluding functions in the tail 1% of samples. p99 is an
arbitrary cutoff. The meaning of profile density is the *minimum amount
of profile information per function* to be able to optimize the program
well. The threshold for profile density is set empirically.

The dynamically executed bytes are taken directly from LBR fall-throughs
and for LBRs recorded in trampoline functions, such as
```
000000001a941ec0 <Sleef_expf8_u10>:
1a941ec0: jmpq *0x37b911fa(%rip) # <pnt_expf8_u10>
1a941ec6: nopw %cs:(%rax,%rax)
```
the fall-through has zero length:
```
# Branch   Target   NextBranch  Count
T 1b171cf6 1a941ec0 1a941ec0    568562
```

But it's not correct to say this function has zero executed bytes, just
the size of the next branch is not included in the fall-through.

If such functions have non-trivial sample count, they will fall in p99
samples, and cause the profile density to be zero.

To solve this, we can either:
1. Include fall-through end jump size into executed bytes:
   is logically sound but technically challenging: the size needs to
   come from disassembly (expensive), and the threshold need to be
   reevaluated with updated definition of binary function density.
2. Exclude pass-through functions from density computation:
   follows the intent of profile density which is to set the amount of 
   profile information needed to optimize the function well. Single
   instruction pass-through functions don't need samples many times 
   the size to be optimized well.

Go with option 2 as a reasonable compromise.

Test Plan: added bolt/test/X86/zero-density.s
2025-06-25 22:20:37 -07:00
Anatoly Trosinenko
a8a2c6fa88
[BOLT] Gadget scanner: fix LR to be safe in leaf functions without CFG (#141824)
After a label in a function without CFG information, use a reasonably
pessimistic estimation of register state (assume that any register that
can be clobbered in this function was actually clobbered) instead of the
most pessimistic "all registers are unsafe". This is the same estimation
as used by the dataflow variant of the analysis when the preceding
instruction is not known for sure.

Without this, leaf functions without CFG information are likely to have
false positive reports about non-protected return instructions, as
1) LR is unlikely to be signed and authenticated in a leaf function and
2) LR is likely to be used by a return instruction near the end of the
   function and
3) the register state is likely to be reset at least once during the
   linear scan through the function
2025-06-25 13:11:23 +03:00
Anatoly Trosinenko
20a72083fd
[BOLT] Gadget scanner: improve handling of unreachable basic blocks (#136183)
Instead of refusing to analyze an instruction completely when it is
unreachable according to the CFG reconstructed by BOLT, use pessimistic
assumption of register state when possible. Nevertheless, unreachable
basic blocks found in optimized code likely means imprecise CFG
reconstruction, thus report a warning once per function.
2025-06-25 12:29:41 +03:00
Paschalis Mpeis
08513281bd
[BOLT][test] Drop toolname from X86/perf2bolt-spe.test (#145515) 2025-06-24 15:12:16 +01:00
Amir Ayupov
4959e8a1da
[BOLT][NFCI] Use heuristic for matching split global functions (#90429)
This change speeds up fragment matching for large BOLTed binaries where
all fragments of global parent functions are put under `bolt-pseudo.o`
file symbol:
- before: iterating over symbols under `bolt-pseudo.o` only to fail
  to find a parent,
- after: bail out immediately and use a global parent by name.

Test Plan: NFC, updated register-fragments-bolt-symbols.s
2025-06-20 12:46:56 -07:00
Amir Ayupov
770b16cd49
[BOLT][test] Update X86/perf2bolt-spe.test (#145061)
Address NFC mismatches caused by running perf2bolt from under the
wrapper script:
https://lab.llvm.org/buildbot/#/builders/92/builds/20938
> <stdin>:2:64: note: possible intended match here
>
/home/worker/bolt-worker2/bolt-x86_64-ubuntu-nfc/build/bin/llvm-bolt.old:
-spe is available only on AArch64.

Test Plan:
ninja check-bolt
2025-06-20 09:07:08 -07:00
Amir Ayupov
7085065c02
[BOLT] Support pre-aggregated returns (#143296)
Intel's Architectural LBR supports capturing branch type information
as part of LBR stack (SDM Vol 3B, part 2, October 2024):
```
20.1.3.2 Branch Types
The IA32_LBR_x_INFO.BR_TYPE and IA32_LER_INFO.BR_TYPE fields encode
the branch types as shown in Table 20-3.

Table 20-3. IA32_LBR_x_INFO and IA32_LER_INFO Branch Type Encodings

Encoding | Branch Type
  0000B  | COND
  0001B  | NEAR_IND_JMP
  0010B  | NEAR_REL_JMP
  0011B  | NEAR_IND_CALL
  0100B  | NEAR_REL_CALL
  0101B  | NEAR_RET
  011xB  | Reserved
  1xxxB  | OTHER_BRANCH

For a list of branch operations that fall into the categories above,
see Table 20-2. 

Table 20-2. Branch Type Filtering Details
Branch Type   | Operations Recorded
COND          | Jcc, J*CXZ, and LOOP*
NEAR_IND_JMP  | JMP r/m*
NEAR_REL_JMP  | JMP rel*
NEAR_IND_CALL | CALL r/m*
NEAR_REL_CALL | CALL rel* (excluding CALLs to the next sequential IP)
NEAR_RET      | RET (0C3H)
OTHER_BRANCH  | JMP/CALL ptr*, JMP/CALL m*, RET (0C8H), SYS*, 
interrupts, exceptions (other than debug exceptions), IRET, INT3, 
INTn, INTO, TSX Abort, EENTER, ERESUME, EEXIT, AEX, INIT, SIPI, RSM
```

Linux kernel can preserve branch type when `save_type` is enabled,
even if CPU does not support Architectural LBR:

f09079bd04/tools/perf/Documentation/perf-record.txt (L457-L460)

> - save_type: save branch type during sampling in case binary is not
available later.
For the platforms with Intel Arch LBR support (12th-Gen+ client or
4th-Gen Xeon+ server), the save branch type is unconditionally enabled
when the taken branch stack sampling is enabled.

Kernel-reported branch type values:

8c6bc74c7f/include/uapi/linux/perf_event.h (L251-L269)

This information is needed to disambiguate external returns (from
DSO/JIT) to an entry point or a landing pad, when BOLT can't
disassemble the branch source.

This patch adds new pre-aggregated types:
- return trace (R),
- external return fall-through (r).

For such types, the checks for fall-through start (not an entry or
a landing pad) are relaxed.

Depends on #143295.

Test Plan: updated callcont-fallthru.s
2025-06-20 03:17:08 -07:00
Ádám Kallai
f75973949b
[BOLT][AArch64] Add support for SPE brstack format (#129231)
Since Linux 6.14, Perf gained the ability to report SPE branch events
using the `brstack` format, which matches the layout of LBR/BRBE.

This patch reuses the existing LBR parsing logic to support SPE.

Example SPE brstack format:
```bash
perf script -i perf.data -F pid,brstack --itrace=bl
```
```
  PID       FROM / TO / PREDICTED

16984  0x72e342e5f4/0x72e36192d0/M/-/-/11/RET/-
16984  0x72e7b8b3b4/0x72e7b8b3b8/PN/-/-/11/COND/-
16984  0x72e7b92b48/0x72e7b92b4c/PN/-/-/8/COND/-
16984  0x72eacc6b7c/0x760cc94b00/P/-/-/9/RET/-
16984  0x72e3f210fc/0x72e3f21068/P/-/-/4//-
16984  0x72e39b8c5c/0x72e3627b24/P/-/-/4//-
16984  0x72e7b89d20/0x72e7b92bbc/P/-/-/4/RET/-
```

SPE brstack flags can be two characters long: `PN` or `MN`:
- `P` = predicted branch
- `M` = mispredicted branch
- `N` = optionally appears when the branch is NOT-TAKEN
    - flag is relevant only to  conditional branches


Example of usage with BOLT:

1. Capture SPE branch events:
```bash
perf record -e 'arm_spe_0/branch_filter=1/u' -- binary
```

2. Convert profile for BOLT:
```bash
perf2bolt -p perf.data -o perf.fdata --spe binary
```

3. Run BOLT Optimization:
```bash
llvm-bolt binary -o binary.bolted --data   perf.fdata ...
```

A unit test verifies the parsing of the 'SPE brstack format'.

---------

Co-authored-by: Paschalis Mpeis <paschalis.mpeis@arm.com>
2025-06-20 10:40:35 +01:00
Maksim Panchenko
b8d3efa189
[BOLT][Linux] Fix linux_banner lookup (#144962)
While detecting the Linux kernel version, look for `linux_banner` symbol
with local visibility if the global one was not found.

Fixes #144847
2025-06-19 23:09:34 -07:00
Anatoly Trosinenko
e873fd157e
[BOLT] Gadget scanner: do not crash on debug-printing CFI instructions (#136151)
Some instruction-printing code used under LLVM_DEBUG does not handle CFI
instructions well. While CFI instructions seem to be harmless for the
correctness of the analysis results, they do not convey any useful
information to the analysis either, so skip them early.
2025-06-19 15:52:54 +03:00
Anatoly Trosinenko
2b4d757290
[BOLT] Gadget scanner: detect authentication oracles (#135663)
Implement the detection of authentication instructions whose results can
be inspected by an attacker to know whether authentication succeeded.

As the properties of output registers of authentication instructions are
inspected, add a second set of analysis-related classes to iterate over
the instructions in reverse order.
2025-06-19 15:15:26 +03:00
Paschalis Mpeis
50a7511138
[BOLT][AArch64] Fix PREL Relocs on RHEL8 (#144505) 2025-06-19 08:51:08 +01:00
Amir Ayupov
9fed480f18
[BOLT] Explicitly check for returns when extending call continuation profile (#143295)
Call continuation logic relies on assumptions about fall-through origin:
- the branch is external to the function,
- fall-through start is at the beginning of the block,
- the block is not an entry point or a landing pad.

Leverage trace information to explicitly check whether the origin is a
return instruction, and defer to checks above only in case of
DSO-external branch source.

This covers both regular and BAT cases, addressing call continuation
fall-through undercounting in the latter mode, which improves BAT
profile quality metrics. For example, for one large binary:
- CFG discontinuity 21.83% -> 0.00%,
- CFG flow imbalance 10.77%/100.00% -> 3.40%/13.82% (weighted/worst)
- CG flow imbalance 8.49% —> 8.49%.

Depends on #143289.

Test Plan: updated callcont-fallthru.s
2025-06-17 06:28:27 -07:00
Paschalis Mpeis
41b9d28327
[BOLT][NFC] Using target_triple in lit config (#144078) 2025-06-17 07:42:57 +01:00
Paschalis Mpeis
686ec6cfe8
[BOLT][AArch64] Fix adr-relaxation.s test (#143151)
On some AArch64 machines the splitting was inconsistent.
This causes cold `foo` to have a `mov` instruction before adrp.
    
```
<foo.cold.0>:
  mov     x0, #0x0                // =0
  adrp    x1, 0x600000 <_start>
  add     x1, x1, #0x14
  ret
```
    
This patch removes the `mov` instruction right above .L2, making
splitting deterministic.
2025-06-11 08:24:10 +01:00
Amir Ayupov
0c77468288
[BOLT] Expose external entry count for functions (#141674)
Record the number of function invocations from external code - code
outside the binary, which may include JIT code and DSOs. Accounting
external entry counts improves the fidelity of call graph flow 
conservation analysis.

Test Plan: updated shrinkwrapping.test
2025-06-10 14:31:22 -07:00
Amir Ayupov
03bbd04bb7
[BOLT][NFCI] Skip validation in parseLBRSample (#143288)
Parsed branches and fall-throughs are validated in `doBranch` and
`doTrace` respectively. Simplify parseLBRSample by omitting the
validation. This also speeds up perf data processing as checks are only
done once for aggregated branches/fall-throughs and not individual LBR
entries.

Since invalid/external addresses are no longer sanitized during parsing,
sanitize them in `doBranch`.

Test Plan: updated X86/pre-aggregated-perf.test
2025-06-08 17:50:02 -07:00
Amir Ayupov
dcd2ac7ef2
[BOLT] Sort EntryData (#143308)
Aggregated branch data has two containers: `Data` for local branches,
and `EntryData` for external branches. Fix the omission and sort
`EntryData` to ensure stable output fdata profiles.

Test Plan: updated pre-aggregated-perf.test
2025-06-08 17:43:44 -07:00
Amir Ayupov
dc513fa8dc
[BOLT] Zero initialize pre-aggregated counters (#142698)
#140196 introduced UB by using uninitialized misprediction count for
pre-aggregated traces. Fix by zero initializing both counters.

Test Plan: updated entry-point-fallthru.s
2025-06-03 20:50:19 -07:00
Maksim Panchenko
8d869637e8
[BOLT][AArch64] Fix error message for failed ADR relaxation (#142533)
Do not recommend the strict mode to the user when ADR relaxation fails
on a non-simple function, i.e. a function with unknown CFG.

We cannot rely on relocations to reconstruct compiler-generated jump
tables for AArch64, hence strict mode does not work as intended.
2025-06-03 11:27:00 -07:00
Maksim Panchenko
06f13f8684
[BOLT] Fix references in ignored functions in CFG state (#140678)
When we call setIgnored() on functions that already have CFG built,
these functions are not going to get emitted and we risk missing
external function references being updated.

To mitigate the potential issues, run scanExternalRefs() on such
functions to create patches/relocations.

Since scanExternalRefs() relies on function relocations, we have to
preserve relocations until the function is emitted. As a result, the
memory overhead without debug info update could reach up to 2%.
2025-06-02 12:33:54 -07:00
Amir Ayupov
18e51314c4
[BOLT] Support pre-aggregated basic sample profile (#140196)
Define a pre-aggregated basic sample format:
```
E <event name>
S <location> <count>
```

`-nl` flag is required to use parsed basic samples.

Test Plan: update pre-aggregated-perf.test
2025-06-02 11:43:48 -07:00
Paschalis Mpeis
f2582c95fe
[BOLT][NFC] Align fdata pattern ordering in link_fdata.py (#142102)
The mispred and execnt values were originally recorded in reverse order
and then consumed in the opposite order to compensate.

This patch records and uses them in the same order (FDATA) for clarity.
That order is:
```
<is symbol?> <closest ELF symbol or DSO name> <relative FROM address> 
<is symbol?> <closest ELF symbol or DSO name> <relative TO address> 
<number of mispredictions> <number of branches>
```
2025-06-02 08:22:45 +01:00
Amir Ayupov
5047a33cd8
[BOLT][heatmap] Produce zoomed-out heatmaps (#140153)
Add a capability to produce multiple heatmaps with given bucket sizes.

The default heatmap block size (64B) could be too fine-grained for
large binaries. Extend the option `block-size` to accept a list of
bucket sizes for additional heatmaps with coarser granularity. The
heatmap is simply rescaled so provided sizes should be multiples of
each other. Human-readable suffixes can be used, e.g. 4K, 16kb, 1MiB.

New defaults: 64B (base bucket size), 4KB (default page size),
256KB (for large binaries).

Test Plan: updated heatmap-preagg.test
2025-05-30 16:20:19 -07:00
Maksim Panchenko
c9022a29b4
[BOLT][AArch64] Detect veneers with missing data markers (#142069)
The linker may omit data markers for long absolute veneers causing BOLT
to treat data as code. Detect such veneers and introduce data markers
artificially before BOLT's disassembler kicks in.
2025-05-29 19:24:34 -07:00
Anatoly Trosinenko
e1328fd9ad
[BOLT] Gadget scanner: clarify MCPlusBuilder callbacks interface (#136147)
Clarify the semantics of `getAuthenticatedReg` and remove a redundant
`isAuthenticationOfReg` method, as combined auth+something instructions
(such as `retaa` on AArch64) should be handled carefully, especially
when searching for authentication oracles: usually, such instructions
cannot be authentication oracles and only some of them actually write an
authenticated pointer to a register (such as "ldra x0, [x1]!").

Use `std::optional<MCPhysReg>` returned type instead of plain MCPhysReg
and returning `getNoRegister()` as a "not applicable" indication.

Document a few existing methods, add information about preconditions.
2025-05-26 18:31:20 +03:00
Fangrui Song
bb03cdcb44
RISCV: Remove shouldForceRelocation and unneeded relocations
Follow-up to #140494

`shouldForceRelocation` is conservative and produces redundant
relocations.

For example, RISCVAsmBackend::ForceRelocs (introduced to support mixed
relax/norelax code) leads to redundant relocations in the following
example adapted from #77436

```
.option norelax
j label
// For assembly input, RISCVAsmParser::ParseInstruction sets ForceRelocs (https://reviews.llvm.org/D46423).
// For direct object emission, RISCVELFStreamer sets ForceRelocs (#77436)
.option relax
call foo  // linker-relaxable

.option norelax
j label   // redundant relocation due to ForceRelocs
.option relax

label:
```

Root problem: The `isSymbolRefDifferenceFullyResolvedImpl` condition in
MCAssembler::evaluateFixup does not check whether two locations are
separated by a fragment whose size can be indeterminate due to linker
instruction (e.g. MCDataFragment with relaxation, or MCAlignFragment
due to indeterminate start offst).

This patch

* Updates the fragment walk code in
  `attemptToFoldSymbolOffsetDifference` to treat MCRelaxableFragment
  (for --riscv-asm-relax-branches) as fixed size after finishLayout.
* Adds a condition in `addReloc` to complement
  `isSymbolRefDifferenceFullyResolvedImpl`.
* Removes the no longer needed `shouldForceRelocation`.

This fragment walk code path handles nicely handles
mixed relax/norelax case from
https://discourse.llvm.org/t/possible-problem-related-to-subtarget-usage/75283
and allows us to remove `MCSubtargetInfo` argument (#73721) as a follow-up.

This fragment walk code should be avoided in the absence of
linker-relaxable fragments within the current section.

Adjust two bolt/test/RISCV tests (#141310)

Pull Request: https://github.com/llvm/llvm-project/pull/140692
2025-05-23 18:44:15 -07:00
Maksim Panchenko
778801cc84
[BOLT] Never call fixBranches() on non-simple functions (#141112)
We should never call fixBranches() on a function with invalid CFG. E.g.,
ValidateInternalCalls modifies CFG for its internal analysis purposes.
At the same time, it marks the function as non-simple with an assumption
that fixBranches() will never run on that function.

However, calculateEmittedSize() by default calls fixBranches() which can
lead to all sorts of issues, including assertions firing in
fixBranches().

The fix is to use the original size for non-simple functions in
calculateEmittedSize() since we are supposed to emit the function
unmodified. Additionally, add an assertion at the start of
fixBranches().
2025-05-22 14:01:54 -07:00
Anatoly Trosinenko
f578f56fea
[BOLT] Gadget scanner: refactor issue reporting (#135662)
Remove `getAffectedRegisters` and `setOverwritingInstrs` methods from
the base `Report` class. Instead, rename the `Report` class to
`Diagnostic` and make it always represent the brief version of the
report, which is kept unchanged since initially found. Throughout its
life-cycle, an instance of `Diagnostic` is first wrapped into
`PartialReport<ReqT>` together with an optional request for extra
details. Then, on the second run of the analysis, it is re-wrapped into
`FinalReport` together with the requested detailed information.
2025-05-22 18:27:46 +03:00
Fangrui Song
744a469bba
[BOLT,test] Add --image-base to tests that use --section-start
When using -no-pie without a SECTIONS command, the linker uses the
target's default image base. If -Ttext= or --section-start specifies an
output section address below this base, the result is likely unintended.
LLD will give a diagnostic (#140187) and may change the behavior in the future.
It's good to set an explicit image base to avoid relying on its current
behavior. BOLT doesn't seem to care whether a PT_PHDR segment is
present.

Pull Request: https://github.com/llvm/llvm-project/pull/140570
2025-05-20 17:41:27 -07:00
Maksim Panchenko
51e222ef48
[BOLT][AArch64] Fix crash for conditional tail calls (#140669)
When conditional tail call is located in old code while BOLT is
operating in lite mode, the call will require optional pending
relocation with a type that is currently not supported resulting in a
build-time crash.

Before a proper fix is implemented, ignore conditional tail calls for
relocation purposes and mark their target functions to be patched, i.e.
to be served as veneers/thunks.
2025-05-20 10:38:00 -07:00
Anatoly Trosinenko
48a2836b4d
[BOLT] Gadget scanner: detect signing oracles (#134146)
Implement the detection of signing oracles. In this patch, a signing
oracle is defined as a sign instruction that accepts a "non-protected"
pointer, but for a slightly different definition of "non-protected"
compared to control flow instructions.

A second BitVector named TrustedRegs is added to the register state
computed by the data-flow analysis. The difference between a
"safe-to-dereference" and a "trusted" register states is that to make
an unsafe register trusted by authentication, one has to make sure
that the authentication succeeded. For example, on AArch64 without
FEAT_PAuth2 and FEAT_EPAC, an authentication instruction produces an
invalid pointer on failure, so that subsequent memory access triggers
an error, but re-signing such pointer would "fix" the signature.

Note that while a separate "trusted" register state may be redundant
depending on the specific semantics of auth and sign operations, it is
still important to check signing operations: while code like this

    resign:
      autda x0, x1
      pacda x0, x2
      ret

is probably safe provided `autda` generates an error on authentication
failure, this function

    sign_anything:
      pacda x0, x1
      ret

is inherently unsafe.
2025-05-20 13:42:53 +03:00
Anatoly Trosinenko
f5401c6a16
[BOLT] Gadget scanner: analyze functions without CFG information (#133461)
Support simple analysis of the functions for which BOLT is unable to
reconstruct the CFG. This patch is inspired by the approach implemented
by Kristof Beyls in the original prototype of gadget scanner, but a
CFG-unaware counterpart of the data-flow analysis is implemented
instead of separate version of gadget detector, as multiple gadget kinds
are detected now.
2025-05-20 13:01:04 +03:00