726 Commits

Author SHA1 Message Date
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
Paschalis Mpeis
6090c0e0ee
[BOLT][test] Fix disabling of the PLT check in callcont-fallthru (#140026)
PR #139953 used `DONTRUN` to disable some run lines, but that didn't
work. Now switching to `RUN-DISABLED` for disabling the tests until
llvm-nm support is landed (#138232).
2025-05-15 13:49:12 +01:00
Amir Ayupov
e24d8662e8
[BOLT][test] Disable PLT check in callcont-fallthru (#139953)
Some testing configurations don't support `nm --synthetic` option (where
nm is a symlink to llvm-nm), which prevents us from resolving `puts@plt`
symbol address in profile generation inside the test.
Disable the check until llvm-nm support is landed (#138232).

Test Plan: bin/llvm-lit -a tools/bolt/test/X86/callcont-fallthru.s
2025-05-14 13:43:39 -07:00
Amir Ayupov
9d5d715330
[BOLT][heatmap] Add synthetic hot text section (#139824)
In heatmap mode, report samples and utilization of the section(s)
between hot text markers `[__hot_start, __hot_end)`.

The intended use is with multi-way splitting where there are several
sections that contain "hot" code (e.g. `.text.warm` with CDSplit).

Addresses the comment on #139193

https://github.com/llvm/llvm-project/pull/139193#pullrequestreview-2835274682

Test Plan: updated heatmap-preagg.test
2025-05-14 09:47:14 -07:00
Amir Ayupov
0289ca09be
[BOLT] Print heatmap from perf2bolt (#139194)
Add perf2bolt `--heatmap` option to produce heatmaps during profile
aggregation.

Distinguish exclusive mode (`llvm-bolt-heatmap`) and optional mode 
(`perf2bolt --heatmap`), which impacts perf.data handling:
exclusive mode covers all addresses, whereas optional mode consumes
attached profile only covering function addresses.

Test Plan: updated per2bolt tests:
- pre-aggregated-perf.test: pre-aggregated data,
- bolt-address-translation-yaml.test: pre-aggregated + BOLTed input,
- perf_test.test: no-LBR perf data.
2025-05-13 13:23:18 -07:00
Amir Ayupov
7f4febde10
[BOLT][heatmap] Compute section utilization and partition score (#139193)
Heatmap groups samples into buckets of configurable size (`--block-size`
flag with 64 bytes as the default =X86 cache line size). Buckets are
mapped to containing sections; for buckets that cover multiple sections,
they are attributed to the first overlapping section. Buckets not mapped
to a section are reported as unmapped.

Heatmap reports **section hotness** which is a percentage of samples
attributed to the section.

Define **section utilization** as a percentage of buckets with non-zero
samples relative to the total number of section buckets.

Also define section **partition score** as a product of section hotness
(where total excludes unmapped buckets) and mapped utilization, ranging 
from 0 to 1 (higher is better).

The intended use of new metrics is with **production profile** collected
from BOLT-optimized binary. In this case the partition score of .text
(hot text if function splitting is enabled) reflects **optimization
profile** representativeness and the quality of hot-cold splitting.
Partition score of 1 means that all samples fall into hot text, and all
buckets (cache lines) in hot text are exercised, equivalent to perfect
hot-cold splitting.

Test Plan: updated heatmap-preagg.test
2025-05-13 13:20:13 -07:00
Amir Ayupov
416c782cc6 [BOLT][test] Fix perf_test
The interaction between `--show-density` and NFC testing wrapper is a
bit subtle. ShowDensity is enabled by default in perf2bolt mode, which
is detected based on executable name. NFC wrapper however replaces
the invocation of perf2bolt with `llvm-bolt --aggregate-only`, and so
ShowDensity is not enabled, which caused NFC test to fail:
https://lab.llvm.org/buildbot/#/builders/92/builds/18656

Add show-density flag explicitly to work around the issue.

Test Plan:
```
../llvm-project/bolt/utils/nfc-check-setup.py
bin/llvm-lit -a tools/bolt/test/perf2bolt/perf_test.test
```
2025-05-12 20:50:45 -07:00
Amir Ayupov
fbdb5aeff6
[BOLT] Build heatmap with pre-aggregated data (#138798)
Reuse data structures used by perf data reader for pre-aggregated data.
Combined with #136531 this allows using pre-aggregated data for heatmap.

Test Plan: heatmap-preagg.test
2025-05-12 18:04:10 -07:00
Amir Ayupov
e039d16ee5
[BOLT][NFC] Disambiguate sample as basic sample (#139350)
Sample is a general term covering both basic (IP) and branch (LBR)
profiles. Find and replace ambiguous uses of sample in a basic sample
sense.

Rename `RawBranchCount` into `RawSampleCount` reflecting its use for
both kinds of profile.

Rename `PF_LBR` profile type as `PF_BRANCH` reflecting non-LBR based
branch profiles (non-brstack SPE, synthesized brstack ETM/PT).

Follow-up to #137644.

Test Plan: NFC
2025-05-12 17:15:16 -07:00
Amir Ayupov
8f31c6dde7
[BOLT] Support profile density with basic samples (#137644)
For profile with LBR samples, binary function profile density is
computed as a ratio of executed bytes to function size in bytes.

For profile with IP samples, use the size of basic block containing the
sample IP as a numerator.

Test Plan: updated perf_test.test
2025-05-10 21:01:49 -07:00
Fangrui Song
8893d407a6 MC: Support quoted symbol names
gas has supported " quoted symbols since 2015.
Both \ and " need to be escaped.
https://sourceware.org/pipermail/binutils/2015-August/090003.html

We don't unescape \\ or \" in assembly strings, leading to clang -c
--save-temps vs clang -c difference for the following C code:

```
int x asm("a\"\\b");
```

Fix #138390

MC/COFF/safeseh.h looks incorrect. \01 in `.safeseh "\01foo"` is not a
correct escape sequence. Change it to \\

Pull Request: https://github.com/llvm/llvm-project/pull/138817
2025-05-09 19:00:17 -07:00
Maksim Panchenko
254c13d872
[BOLT][AArch64] Patch functions targeted by optional relocs (#138750)
On AArch64, we create optional/weak relocations that may not be
processed due to the relocated value overflow. When the overflow
happens, we used to enforce patching for all functions in the binary via
--force-patch option. This PR relaxes the requirement, and enforces
patching only for functions that are target of optional relocations.
Moreover, if the compact code model is used, the relocation overflow is
guaranteed not to happen and the patching will be skipped.
2025-05-08 10:53:47 -07:00
Amir Ayupov
54aa16d293
[BOLT] Drop converting return profile to call cont (#129477)
The workaround was not implemented for BAT case, and it is no longer
needed with pre-aggregated traces, alternatively, the effect can be
achieved with `infer-fall-throughs` with old pre-aggregated format
(branches + ranges).

Test Plan: updated callcont-fallthru.s
2025-05-06 22:21:53 -07:00
Elvina Yakubova
5cec6f6f2d
[BOLT][NFC] Add keep-nops option to non-empty-debug-line.test (#137812)
On openSUSE distribution test is failing due to different .debug_line
size without the keep-nops option
2025-04-29 18:16:36 +01:00
YongKang Zhu
316a6ff3d0
[BOLT][RelVTable] Skip special handling on non virtual function pointer relocations (#137406)
Besides virtual function pointers vtable could contain other kinds of
entries like those for RTTI data that also require relocations. We need
to skip special handling on relocations for non virtual function pointers
in relative vtable.

Co-authored-by: Maksim Panchenko <maks@meta.com>
2025-04-29 08:13:44 -07:00
ShatianWang
ce2b3ce3b6
[BOLT] Improve profile quality reporting (#130810)
Improve profile quality reporting by 1) fixing a format issue for small
binaries, 2) adding new stats for exception handling usage, 3) excluding
selected blocks when computing the CFG flow conservation score.

More specifically for 3), we are excluding blocks that satisfy at least
one of the following characteristics: a) is a landing pad, b) has at
least one landing pad with non-zero execution counts, c) ends with a
recursive call. The reason for a) and b) is because the thrower -->
landing pad edges are not explicitly represented in the CFG. The reason
for c) is because the call-continuation fallthrough edge count is not
important in case of recursive calls.

Modified test `bolt/test/X86/profile-quality-reporting.test`.
Added test `bolt/test/X86/profile-quality-reporting-small-binary.s`.
2025-04-22 15:42:47 -04:00
YongKang Zhu
2dca9e80ff
[BOLT][test] Resolve symlink for nm tool (NFC) (#136722)
Handle the case where nm could be a symlink to llvm-nm.
2025-04-22 12:08:56 -07:00
Rafael Auler
3bcb724903
[BOLT] Add --custom-allocation-vma flag (#136385)
Add an advanced-user flag so we are able to rewrite binaries when we fail
to identify a suitable location to put new code. User then can supply a
custom location via --custom-allocation-vma. This happens more obviously if the
binary has segments mapped to very high addresses.
2025-04-18 21:02:09 -07:00
Rafael Auler
5c4e6c6113
[BOLT] Don't choke on nobits symbols (#136384) 2025-04-18 17:29:24 -07:00
Maksim Panchenko
0977a7130b
[BOLT] Skip FDE emission for patch functions (#136224)
Patch functions are used to fix instructions in the original code, i.e.,
they are not functions in a traditional sense, but rather pieces of
emitted code that are embedded into real functions.

We used to emit FDEs for all functions, including patch functions.
However, FDEs for patches are not only unnecessary, but they can lead to
problems with libraries and runtimes that consume FDEs, e.g. C++
exception handling runtime.

Note that we use named patches to fix function entry points and in that
case they behave more like regular functions. Thus we issue FDEs for
those.
2025-04-17 19:58:32 -07:00
wangjue
dbb79c30c9
[BOLT][Instrumentation] Initial instrumentation support for RISCV64 (#133882)
This patch adds code generation for RISCV64 instrumentation.The work
    involved includes the following three points:

a) Implements support for instrumenting direct function call and jump
    on RISC-V which relies on , Atomic instructions
    (used to increment counters) are only available on RISC-V when the A
    extension is used.

b) Implements support for instrumenting direct function inderect call
    by implementing the createInstrumentedIndCallHandlerEntryBB and
createInstrumentedIndCallHandlerExitBB interfaces. In this process, we
    need to accurately record the target address and IndCallID to ensure
    the correct recording of the indirect call counters.

c)Implemented the RISCV64 Bolt runtime library, implemented some system
call interfaces through embedded assembly. Get the difference between
runtime addrress of .text section andstatic address in section header
table, which in turn can be used to search for indirect call
description.

However, the community code currently has problems with relocation in
    some scenarios, but this has nothing to do with instrumentation. We
    may continue to submit patches to fix the related bugs.
2025-04-16 23:01:00 -07:00
YongKang Zhu
823adc7a2d
[BOLT] Validate secondary entry point (#135731)
Some functions have their sizes as zero in input binary's symbol
table, like those compiled by assembler. When figuring out function
sizes, we may create label symbol if it doesn't point to any constant
island. However, before function size is known, marker symbol can
not be correctly associated to a function and therefore all such
checks would fail and we could end up adding a code label pointing
to constant island as secondary entry point and later mistakenly
marking the function as not simple.

Querying the global marker symbol array has big throughput overhead.
Instead we can run an extra check when post processing entry points
to identify such label symbols that actually point to constant islands.
2025-04-15 13:19:15 -07:00
alekuz01
38faf32d23
[BOLT] Enable hugify for AArch64 (#117158)
Add required hugify instrumentation and runtime libraries support for AArch64.
Fixes #58226
Unblocks #62695
2025-04-15 12:59:05 +01:00
YongKang Zhu
2a83c0cc13
[BOLT] Support relative vtable (#135449)
To handle relative vftable, which is enabled with clang option
`-fexperimental-relative-c++-abi-vtables`, we look for PC relative
relocations whose fixup locations fall in vtable address ranges.
For such relocations, actual target is just virtual function itself,
and the addend is to record the distance between vtable slot for
target virtual function and the first virtual function slot in vtable,
which is to match generated code that calls virtual function. So
we can skip the logic of handling "function + offset" and directly
save such relocations for future fixup after new layout is known.
2025-04-14 10:24:47 -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
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
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
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
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
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
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
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