Commit Graph

235 Commits

Author SHA1 Message Date
Jared Wyles
2ccf7ed277 [JITLink] Switch to SymbolStringPtr for Symbol names (#115796)
Use SymbolStringPtr for Symbol names in LinkGraph. This reduces string interning
on the boundary between JITLink and ORC, and allows pointer comparisons (rather
than string comparisons) between Symbol names. This should improve the
performance and readability of code that bridges between JITLink and ORC (e.g.
ObjectLinkingLayer and ObjectLinkingLayer::Plugins).

To enable use of SymbolStringPtr a std::shared_ptr<SymbolStringPool> is added to
LinkGraph and threaded through to its construction sites in LLVM and Bolt. All
LinkGraphs that are to have symbol names compared by pointer equality must point
to the same SymbolStringPool instance, which in ORC sessions should be the pool
attached to the ExecutionSession.
---------

Co-authored-by: Lang Hames <lhames@gmail.com>
2024-12-06 10:22:09 +11:00
Peter Waller
b5ed375f9d [BOLT] Skip _init; avoiding GOT breakage for static binaries (#117751)
_init is used during startup of binaires. Unfortunately, its
address can be shared (at least on AArch64 glibc static binaries) with a
data
reference that lives in the GOT. The GOT rewriting is currently unable
to distinguish between data addresses and function addresses. This leads
to the data address being incorrectly rewritten, causing a crash on
startup of the binary:

  Unexpected reloc type in static binary.

To avoid this, don't consider _init for being moved, by skipping it.

~We could add further conditions to narrow the skipped case for known
crashes, but as a straw man I thought it'd be best to keep the condition
as simple as possible and see if there any objections to this.~
(Edit: this broke the test
bolt/test/runtime/X86/retpoline-synthetic.test,
because _init was skipped from the retpoline pass and it has an indirect
call in it, so I include a check for static binaries now, which avoids
the test failure,
but perhaps this could/should be narrowed further?)

For now, skip _init for static binaries on any architecture; we could
add further conditions to narrow the skipped case for known crashes, but
as a straw man I thought it'd be best to keep the condition as simple as
possible and see if there any objections to this.

Updates #100096.
2024-11-28 14:59:07 +00:00
Maksim Panchenko
996553228f [BOLT] Overwrite .eh_frame and .gcc_except_table (#116755)
Under --use-old-text or --strict, we completely rewrite contents of EH
frames and exception tables sections. If new contents of either section
do not exceed the size of the original section, rewrite the section
in-place.
2024-11-19 12:59:05 -08:00
Maksim Panchenko
08ef939637 [BOLT] Overwrite .eh_frame_hdr in-place (#116730)
If the new EH frame header can fit into the original .eh_frame_hdr
section, overwrite it in-place and pad with zeroes.
2024-11-18 20:42:38 -08:00
Maksim Panchenko
1b8e0cf090 [BOLT] Never emit "large" functions (#115974)
"Large" functions are functions that are too big to fit into their
original slots after code modifications. CheckLargeFunctions pass is
designed to prevent such functions from emission. Extend this pass to
work with functions with constant islands.

Now that CheckLargeFunctions covers all functions, it guarantees that we
will never see such functions after code emission on all platforms
(previously it was guaranteed on x86 only). Hence, we can get rid of
RewriteInstance extensions that were meant to support "large" functions.
2024-11-13 09:58:44 -08:00
Jacob Bramley
16cd5cdf4d [BOLT] Ignore AArch64 markers outside their sections. (#74106)
AArch64 uses $d and $x symbols to delimit data embedded in code.
However, sometimes we see $d symbols, typically in .eh_frame, with
addresses that belong to different sections. These occasionally fall
inside .text functions and cause BOLT to stop disassembling, which in
turn causes DWARF CFA processing to fail.

As a workaround, we just ignore symbols with addresses outside the
section they belong to. This behaviour is consistent with objdump and
similar tools.
2024-11-07 15:16:14 +03:00
Youngsuk Kim
0a5edb4de4 [bolt] Don't call llvm::raw_string_ostream::flush() (NFC)
Don't call raw_string_ostream::flush(), which is essentially a no-op.
As specified in the docs, raw_string_ostream is always unbuffered.
( 65b13610a5 for further reference )
2024-09-23 17:07:11 -05:00
Kristof Beyls
6d216fb7b8 [perf2bolt] Improve heuristic to map in-process addresses to specific… (#109397)
… segments in Elf binary.

The heuristic is improved by also taking into account that only
executable segments should contain instructions.

Fixes #109384.
2024-09-23 15:14:51 +02:00
sinan
31ac3d092b [BOLT] Add .iplt support to x86 (#106513)
Add X86 support for parsing .iplt section and symbols.
2024-09-23 18:22:43 +08:00
Davide Italiano
e49549ff19 Revert "[BOLT] Abort on out-of-section symbols in GOT (#100801)"
This reverts commit a4900f0d93.
2024-08-07 20:52:19 -07:00
Sayhaan Siddiqui
62e894e0d7 [BOLT][DWARF][NFC] Move Arch assignment out of createBinaryContext (#102054)
Moves the assignment of Arch out of createBinaryContext to prevent data
races when parallelized.
2024-08-07 16:55:39 +00:00
Vladislav Khmelevsky
a4900f0d93 [BOLT] Abort on out-of-section symbols in GOT (#100801)
This patch aborts BOLT execution if it finds out-of-section (section
end) symbol in GOT table. In order to handle such situations properly in
future, we would need to have an arch-dependent way to analyze
relocations or its sequences, e.g., for ARM it would probably be ADRP +
LDR analysis in order to get GOT entry address. Currently, it is also
challenging because GOT-related relocation symbols are replaced to
__BOLT_got_zero. Anyway, it seems to be quite a rare case, which seems
to be only? related to static binaries. For the most part, it seems that
it should be handled on the linker stage, since static binary should not
have GOT table at all. LLD linker with relaxations enabled would replace
instruction addresses from GOT directly to target symbols, which
eliminates the problem.

Anyway, in order to achieve detection of such cases, this patch fixes a
few things in BOLT:
1. For the end symbols, we're now using the section provided by ELF
binary. Previously it would be tied with a wrong section found by symbol
address.
2. The end symbols would have limited registration we would only
add them in name->data GlobalSymbols map, since using address->data
BinaryDataMap map would likely be impossible due to address duality of
such symbols.
3. The outdated BD->getSection (currently returning refence, not
pointer) check in postProcessSymbolTable is replaced by getSize check in
order to allow zero-sized top-level symbols if they are located in
zero-sized sections. For the most part, such things could only be found
in tests, but I don't see a reason not to handle such cases.
4. Updated section-end-sym test and removed x86_64 requirement since
there is no reason for this (tested on aarch64 linux)

The test was provided by peterwaller-arm (thank you) in #100096 and
slightly modified by me.
2024-08-07 16:26:12 +04:00
Vladislav Khmelevsky
097ddd3565 [BOLT] Fix relocations handling (#100890)
After porting BOLT to RISCV some of the relocations were broken on both
AArch64 and X86.
On AArch64 the example of broken relocations would be GOT, during
handling them, we should replace the symbol to __BOLT_got_zero in order
to address GOT entry, not the symbol that addresses this entry. This is
done further in code, so it is too early to add rel here.
On X86 it is a mistake to add relocations without addend. This is the
exact problem that is raised on #97937. Due to different code generation
I had to use gcc-generated yaml test, since with clang I wasn't able to
reproduce problem.
Added tests for both architectures and made the problematic condition
riscV-specific.
2024-08-07 16:25:46 +04:00
sinan
6c8933e1a0 [BOLT] Skip PLT search for zero-value weak reference symbols (#69136)
Take a common weak reference pattern for example
```
    __attribute__((weak)) void undef_weak_fun();
    
      if (&undef_weak_fun)
        undef_weak_fun();
```
    
In this case, an undefined weak symbol `undef_weak_fun` has an address
of zero, and Bolt incorrectly changes the relocation for the
corresponding symbol to symbol@PLT, leading to incorrect runtime
behavior.
2024-08-07 18:02:42 +08:00
sinan
734c0488b6 [BOLT] Support map other function entry address (#101466)
Allow BOLT to map the old address to a new binary address if the old
address is the entry of the function.
2024-08-07 15:57:25 +08:00
Amir Ayupov
3f51bec466 [BOLT][NFC] Print timers in perf2bolt invocation
When BOLT is run in AggregateOnly mode (perf2bolt), it exits with code
zero so destructors are not run thus TimerGroup never prints the timers.

Add explicit printing just before the exit to honor options requesting
timers (`--time-rewrite`, `--time-aggr`).

Test Plan: updated bolt/test/timers.c

Reviewers: ayermolo, maksfb, rafaelauler, dcci

Reviewed By: dcci

Pull Request: https://github.com/llvm/llvm-project/pull/101270
2024-07-31 22:14:52 -07:00
Amir Ayupov
fb97b4f962 [BOLT][NFC] Add timers for MetadataManager invocations
Test Plan: added bolt/test/timers.c

Reviewers: ayermolo, maksfb, rafaelauler, dcci

Reviewed By: dcci

Pull Request: https://github.com/llvm/llvm-project/pull/101267
2024-07-31 22:12:34 -07:00
Amir Ayupov
9b007a199d [BOLT] Expose pseudo probe function checksum and GUID (#99389)
Add a BinaryFunction field for pseudo probe function GUID.
Populate it during pseudo probe section parsing, and emit it in YAML
profile (both regular and BAT), along with function checksum.

To be used for stale function matching.

Test Plan: update pseudoprobe-decoding-inline.test
2024-07-18 20:58:16 -07:00
Vladislav Khmelevsky
51122fb446 [BOLT][NFC] Fix build (#99361)
On clang 14 the build is failing with:
reference to local binding 'ParentName' declared in enclosing function
'llvm::bolt::RewriteInstance::registerFragments'
2024-07-17 23:17:12 +04:00
Amir Ayupov
3fe50b6dde [BOLT] Store FileSymRefs in a multimap
With aggressive ICF, it's possible to have different local symbols
(under different FILE symbols) to be mapped to the same address.

FileSymRefs only keeps a single SymbolRef per address, which prevents
fragment matching from finding the correct symbol to perform parent
function lookup.

Work around this issue by switching FileSymRefs to a multimap. In
future, uses of FileSymRefs can be replaced with SortedSymbols which
keeps essentially the same information.

Test Plan: added ambiguous_fragment.test

Reviewers: dcci, ayermolo, maksfb, rafaelauler

Reviewed By: rafaelauler

Pull Request: https://github.com/llvm/llvm-project/pull/98992
2024-07-16 22:14:43 -07:00
Amir Ayupov
344228ebf4 [BOLT] Drop macro-fusion alignment (#97358)
9d0754ada5 dropped MC support required for
optimal macro-fusion alignment in BOLT. Remove the support in BOLT as
performance measurements with large binaries didn't show a significant
improvement.

Test Plan:
macro-fusion alignment was never upstreamed, so no upstream tests are
affected.
2024-07-02 09:20:41 -07:00
Fangrui Song
e3e0df391c [BOLT] Replace the MCAsmLayout parameter with MCAssembler
Continue the MCAsmLayout removal work started by 67957a45ee.
2024-07-01 18:02:34 -07:00
Shaw Young
49fdbbcfed [BOLT] Match functions with exact hash (#96572)
Added flag '--match-profile-with-function-hash' to match functions 
based on exact hash. After identical and LTO name matching, more 
functions can be recovered for inference with exact hash, in the case
of function renaming with no functional changes. Collisions are 
possible in the unlikely case where multiple functions share the same
exact hash. The flag is off by default as it requires the processing of 
all binary functions and subsequently is expensive.

Test Plan: added hashing-based-function-matching.test.
2024-06-29 21:19:00 -07:00
shawbyoung
902952ae04 Revert "[𝘀𝗽𝗿] initial version"
This reverts commit bb5ab1ffe7.
2024-06-25 08:30:29 -07:00
shawbyoung
c097e643ef Revert "Added opts::Lite to RewriteInstance"
This reverts commit 020f69cd10.
2024-06-25 08:07:45 -07:00
shawbyoung
020f69cd10 Added opts::Lite to RewriteInstance 2024-06-25 08:05:29 -07:00
shawbyoung
bb5ab1ffe7 [𝘀𝗽𝗿] initial version
Created using spr 1.3.4
2024-06-25 08:05:29 -07:00
shaw young
32e4906c28 Revert "[BOLT] Hash-based function matching" (#96568)
Reverts llvm/llvm-project#95821
2024-06-24 18:44:24 -04:00
shaw young
5e097c79d8 [BOLT] Hash-based function matching (#95821)
Using the hashes of binary and profiled functions
to recover functions with changed names.

Test Plan: added 
hashing-based-function-matching.test.
2024-06-24 15:29:44 -07:00
Maksim Panchenko
8ea59ec607 [BOLT] Use rewriter interface for updating binary build ID (#94273)
Move functionality for patching build ID into a separate rewriter class
and change the way we do the patching. Support build ID in different
note sections in order to update the build ID in the Linux kernel binary
which puts in into ".notes" section instead of ".note.gnu.build-id".
2024-06-03 21:39:47 -07:00
Amir Ayupov
e9954ec087 [BOLT] Detect .warm split functions as cold fragments (#93759)
CDSplit splits functions up to three ways: main fragment with no suffix,
and fragments with .cold and .warm suffixes.

Add .warm suffix to the regex used to recognize split fragments.

Test Plan: updated register-fragments-bolt-symbols.s
2024-05-30 17:48:12 -07:00
Amir Ayupov
83b3e13e89 [BOLT] Allow processing of binaries with stripped FILE symbols mismatching the profile (#93238)
Reintroduce allow-stripped as a fallback mechanism after enforcement of
HasSymbolsWithFileName was fixed in
https://github.com/llvm/llvm-project/pull/92625.

This partially reverts commit ccabbfff86.
2024-05-23 16:40:08 -07:00
Amir Ayupov
a79acb0ce5 [BOLT] Fix setHasSymbolsWithFileName (#92625)
The function is used to ignore the parameter and set
`HasSymbolsWithFileName` unconditionally.
2024-05-22 13:57:52 -07:00
Amir Ayupov
1529ec085a [BOLT][NFC] Move out PrintProgramStats from Profile into Rewrite (#93075)
Eliminate the dependence of Profile on Passes.

Test Plan: NFC
2024-05-22 13:53:41 -07:00
shaw young
96378b3da8 [BOLT] Add NamedRegionTimer to inferStaleProfile (#93078) 2024-05-22 11:04:12 -07:00
Amir Ayupov
935b946b1f [BOLT] Process cross references between ignored functions in BAT mode (#92484)
To align YAML and fdata profiles produced in BAT mode, lift two
restrictions applied in non-relocation mode when BAT is present:
1) register secondary entry points from ignored functions,
2) treat functions with secondary entry points as simple.

This allows constructing CFG for non-simple functions in non-relocation
mode and emitting YAML profile for them, which can then be used for
optimizations in relocation mode.

Test Plan: added test ignored-interprocedural-reference.s
2024-05-21 20:22:12 -07:00
Amir Ayupov
32c9d5ef4f Revert "[BOLT] Add NamedRegionTimer to inferStaleProfile (#92621)"
This reverts commit 9f2313829f.

Creates a dependency cycle: lib/Rewrite depends on lib/Profile.
2024-05-21 13:55:32 -07:00
shaw young
9f2313829f [BOLT] Add NamedRegionTimer to inferStaleProfile (#92621) 2024-05-21 13:26:57 -07:00
Amir Ayupov
bb627b0a0c [BOLT] Ignore special symbols as function aliases in updateELFSymbolTable
Exempt special symbols (hot text/data and _end symbol) from normal
handling. We only need to set their value and make them absolute.

If these symbols are handled as normal symbols and if they alias
functions we may create non-sensical symbols, e.g. __hot_start.cold.

Test Plan: updated hot-end-symbol.s

Reviewers: maksfb, rafaelauler, ayermolo, dcci

Reviewed By: dcci, maksfb

Pull Request: https://github.com/llvm/llvm-project/pull/92713
2024-05-20 16:55:11 -07:00
Maksim Panchenko
9cd218e427 [BOLT] Refactor BOLT reserved space discovery (#90893)
Move code that checks for __bolt_reserved_{start,end} into a new
discoverBOLTReserved() function and call it from discoverFileObjects()
so that the reserved space info is accessible to passes. NFC for the
current set of binaries.
2024-05-02 13:17:29 -07:00
Maksim Panchenko
ad7ee900c7 [BOLT][NFC] Add BOLTReserved to BinaryContext (#90766)
Use BOLTReserved to track binary space preallocated for BOLT.
2024-05-01 18:22:38 -07:00
Maksim Panchenko
49bb993959 [BOLT] Fix build-time assertion in RewriteInstance (#90540)
We use pwrite() in RewriteInstance to update contents of existing
sections. pwrite() requires file position to be set past the written
offset which we guarantee at the start of rewriteFile(). Then we had an
implicit assumption in patchBuildID() that the file position will be set
again in patchELFSymTabs() after being reset in patchELFPHDRTable().
That assumption was broken in #90300. The fix is to save and restore
file position in patchELFPHDRTable(). Then we don't have to update it
again in patchELFSymTabs().
2024-04-30 10:51:08 -07:00
Amir Ayupov
c4c4e17c99 [BOLT] Use heuristic for matching split local functions (#90424)
Use known order of BOLT split function symbols: fragment symbols
immediately precede the parent fragment symbol.

Depends On: https://github.com/llvm/llvm-project/pull/89648

Test Plan: Added register-fragments-bolt-symbols.s
2024-04-29 16:18:13 -07:00
Maksim Panchenko
3a0d894faf [BOLT] Add support for BOLT-reserved space in a binary (#90300)
Allow the user to allocate space in a binary that could be used by BOLT
for allocating new sections. The reservation is specified by two special
symbols recognizable by BOLT: __bolt_reserved_{start,end}.

The reserved space will be useful for optimizing the Linux kernel where
we cannot allocate a new executable segment. However, the support is not
limited to kernel binaries as some user-space application may find it
useful too.
2024-04-29 14:44:04 -07:00
Amir Ayupov
a1e9608b0f [BOLT] Use symbol table info in registerFragment (#89648)
Fragment matching relies on symbol names to identify and register split
function fragments. However, as split fragments are often local symbols,
name aliasing is possible. For such cases, use symbol table to resolve
ambiguities.

This requires the presence of FILE symbols in the input binary. As BOLT
requires non-stripped binary, this is a reasonable assumption. Note that
`strip -g` removes FILE symbols by default, but `--keep-file-symbols`
can be used to preserve them.

Depends on: https://github.com/llvm/llvm-project/pull/89861

Test Plan:
Updated X86/fragment-lite.s
2024-04-29 11:14:31 -07:00
Maksim Panchenko
3ec858bc5d [BOLT] Refactor patchELFPHDRTable() (#90290)
Mostly NFC accept for one assertion that was converted into an error.
2024-04-26 16:29:42 -07:00
Maksim Panchenko
12d322db46 [BOLT][NFC] Use getEHFrameHdrSectionName() (#90257)
Reference section name via wrapper.
2024-04-26 14:13:23 -07:00
Fangrui Song
e982032199 [BOLT,RISCV] Remove empty name special case from #68977
The special case is unneeded after #89693.

Pull Request: https://github.com/llvm/llvm-project/pull/90004
2024-04-25 20:42:40 -07:00
Amir Ayupov
090c92e015 [BOLT] Emit synthetic FILE symbol for local cold fragments of global symbols (#89794) 2024-04-25 04:53:15 +02:00
Maksim Panchenko
418e4b0c4f [BOLT] Detect incorrect update of dynamic relocations (#89681)
When we rewrite dynamic relocations, there could be cases where they
reference code locations inside functions that were rewritten. When this
happens, we need to precisely map old address to a new one. Until we can
reliably perform the mapping, detect such condition and issue an error
refusing to write a broken binary.
2024-04-24 14:03:33 -07:00