35 Commits

Author SHA1 Message Date
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
Franklin
6e8a1a45a7 [BOLT] Detect Linux kernel version if the binary is a Linux kernel (#119088)
This makes it easier to handle differences (e.g. of exception table
entry size) between versions of Linux kernel
2024-12-26 09:54:23 -08:00
Maksim Panchenko
21684e38ee [BOLT][Linux] Refactor reading of PC-relative addresses. NFCI (#120491)
Fix evaluation order problem identified in
https://github.com/llvm/llvm-project/pull/119088.
2024-12-19 10:40:25 -08:00
Maksim Panchenko
d16b21b17d [BOLT][Linux] Support ORC for alternative instructions (#96709)
Alternative instruction sequences in the Linux kernel can modify the
stack and thus they need their own ORC unwind entries. Since there's
only one ORC table, it has to be "shared" among multiple instruction
sequences. The kernel achieves this by putting a restriction on
instruction boundaries. If ORC state changes at a given IP, only one of
the alternative sequences can have an instruction starting/ending at
this IP. Then, developers can insert NOPs to guarantee the above
requirement is met.

The most common use of ORC with alternatives is "pushf; pop %rax"
sequence used for paravirtualization. Note that newer kernel versions
no longer use .parainstructions; instead, they utilize alternatives for
the same purpose.

Before we implement a better support for alternatives, we can safely
skip ORC entries associated with them.

Fixes #87052.
2024-06-27 19:26:11 -07:00
Maksim Panchenko
ad2905e52c [BOLT] Skip optimization of functions with alt instructions (#95172)
Alternative instructions in the Linux kernel may modify control flow in
a function. As such, it is unsafe to optimize functions with alternative
instructions until we properly support CFG alternatives.

Previously, we marked functions with alt instructions before the
emission, but that could be too late if we remove or replace
instructions with alternatives. We could have marked functions as
non-simple immediately after reading .altinstructions, but it's nice to
be able to view functions after CFG is built. Thus assign the non-simple
status after building CFG.
2024-06-18 12:33:37 -07:00
Maksim Panchenko
1ebda11731 [BOLT] Fix duplicate diagnostic message (#95167)
Print .altinstructions parsing stats only once.
2024-06-13 14:56:01 -07:00
Maksim Panchenko
540893e43f [BOLT] Add auto parsing for Linux kernel .altinstructions (#95068)
.altinstructions section contains a list of structures where fields can
have different sizes while other fields could be present or not
depending on the kernel version. Add automatic detection of such
variations and use it by default. The user can still overwrite the
automatic detection with `--alt-inst-has-padlen` and
`--alt-inst-feature-size` options.
2024-06-11 10:52:51 -07:00
Amir Ayupov
c460e454d1 [BOLT][NFCI] Fix return type of BC::getSignedValueAtAddress (#91664) 2024-05-24 16:04:06 -07:00
Maksim Panchenko
99b4532b8b [BOLT] Add support for Linux kernel .smp_locks section (#90798)
Parse .smp_locks section entries and create fixups that are going to be
used to update the section before the binary emission.
2024-05-02 13:08:37 -07:00
Maksim Panchenko
59ab29213d [BOLT] Register Linux kernel dynamic branch offsets (#90677)
To match profile data to code we need to know branch instruction offsets
within a function. For this reason, we mark branches with the "Offset"
annotation while disassembling the code. However, _dynamic_ branches in
the Linux kernel could be NOPs in disassembled code, and we ignore them
while adding annotations. We need to explicitly add the "Offset"
annotation while creating dynamic branches.

Note that without this change, `getInstructionAtOffset()` would still
return a branch instruction if the offset matched the last instruction
in a basic block (and the profile data was matched correctly). However,
the function failed for cases when the searched instruction was followed
by an unconditional jump. "Offset" annotation solves this case.
2024-05-01 21:56:55 -07:00
Maksim Panchenko
dd09a7db03 [BOLT] Add split function support for the Linux kernel (#90541)
While rewriting the Linux kernel, we try to fit optimized functions into
their original boundaries. When a function becomes larger, we skip it
during the rewrite and end up with less than optimal code layout. To
overcome that issue, add support for --split-function option so that hot
part of the function could be fit into the original space. The cold part
should go to reserved space in the binary.
2024-05-01 21:45:44 -07:00
Kazu Hirata
805e08ef26 [BOLT] Fix a warning
This patch fixes:

  bolt/lib/Rewrite/LinuxKernelRewriter.cpp:855:12: error: variable
  'PrevIP' set but not used [-Werror,-Wunused-but-set-variable]
2024-04-30 15:16:01 -07:00
Maksim Panchenko
c665e49911 [BOLT] Add ORC validation for the Linux kernel (#90660)
The Linux kernel expects ORC tables to be sorted by IP address (for
binary search to work). Add a post-emit pass in LinuxKernelRewriter that
validates the written .orc_unwind_ip against that expectation.
2024-04-30 14:17:33 -07:00
Maksim Panchenko
35e7d458c9 [BOLT] Add rewriting support for Linux kernel __bug_table (#86908)
Update instruction locations in the __bug_table section after new code
is emitted. If an instruction with associated bug ID was deleted,
overwrite its location with zero.
2024-03-28 10:30:27 -07:00
Maksim Panchenko
56197d732e [BOLT] Skip functions with unsupported Linux kernel features (#86345)
Do not overwrite functions with alternative and paravirtual instructions
until a proper update support is implemented.
2024-03-22 15:28:54 -07:00
Kazu Hirata
4865dab04c [BOLT] Fix unused variable warnings
This patch fixes:

  bolt/lib/Rewrite/LinuxKernelRewriter.cpp:1664:20: error: unused
  variable 'TargetAddress' [-Werror,-Wunused-variable]

  bolt/lib/Rewrite/LinuxKernelRewriter.cpp:1666:20: error: unused
  variable 'KeyAddress' [-Werror,-Wunused-variable]
2024-03-21 20:21:12 -07:00
Maksim Panchenko
6b1cf00400 [BOLT] Add support for Linux kernel static keys jump table (#86090)
Runtime code modification used by static keys is the most ubiquitous
self-modifying feature of the Linux kernel. The idea is to to eliminate
the condition check and associated conditional jump on a hot path if
that condition (based on a boolean value of a static key) does not
change often. Whenever they condition changes, the kernel runtime
modifies all code paths associated with that key flipping the code
between nop and (unconditional) jump.
2024-03-21 14:05:21 -07:00
Maksim Panchenko
fd32e744a5 [BOLT] Add support for Linux kernel PCI fixup section (#84982)
.pci_fixup section contains a table with entries allowing to invoke a
fixup hook whenever a problem is encountered with a PCI device. The
hookup code typically points to the start of a function. As we are not
relocating functions in the kernel (at least not yet), verify this
assumption while reading the table and ignore any functions with a fixup
code in the middle.
2024-03-12 15:52:27 -07:00
Maksim Panchenko
a9b0d7590b [BOLT] Properly propagate Cursor errors (#84378)
Handle out-of-bounds reading errors correctly in LinuxKernelRewriter.
2024-03-07 15:29:38 -08:00
Maksim Panchenko
143afb405a [BOLT] Add reading support for Linux kernel .altinstructions section (#84283)
Read .altinstructions and annotate instructions that have alternative
sequences with "AltInst" annotation. Note that some instructions may
have more than one alternatives, in which case they will have multiple
annotations in the form "AltInst", "AltInst2", "AltInst3", etc.
2024-03-07 13:04:02 -08:00
Maksim Panchenko
02629793a4 [BOLT] Add reading support for Linux kernel __bug_table section (#84082)
Read __bug_table section and annotate ud2 instructions with a
corresponding bug entry ID.
2024-03-06 23:34:03 -08:00
Maksim Panchenko
f51ade25b9 [BOLT] Add reading support for Linux kernel .parainstructions section (#83965)
Read .parainstruction section and mark call instructions with ParaSite
annotations.
2024-03-05 13:57:55 -08:00
Maksim Panchenko
ccf0c8da1a [BOLT] Add reading support for Linux kernel exception table (#83100)
Read Linux exception table and ignore functions with exceptions for now.
Proper support requires an introduction of new control flow since some
instructions with memory access can cause a control flow change.

Hence looking at disassembly or CFG with exceptions annotations is
valuable for code analysis, delay marking functions with exceptions as
non-simple until immediately before emitting the code.
2024-03-04 17:24:16 -08:00
Maksim Panchenko
7c206c7812 [BOLT] Refactor interface for instruction labels. NFCI (#83209)
To avoid accidentally setting the label twice for the same instruction,
which can lead to a "lost" label, introduce getOrSetInstLabel()
function. Rename existing functions to getInstLabel()/setInstLabel() to
make it explicit that they operate on instruction labels. Add an
assertion in setInstLabel() that the instruction did not have a prior
label set.
2024-02-27 18:44:28 -08:00
Maksim Panchenko
0ce0171243 [BOLT][NFC] Switch logging in LinuxKernelRewriter (#82195)
Use journaling streams introduced in #81524 for LinuxKernelRewriter.
2024-02-19 03:24:04 +00:00