Commit Graph

267 Commits

Author SHA1 Message Date
Alexander Yermolovich
e22ff52c10 [BOLT][DWARF] Change rangelists to use DW_RLE_offset_pair
Before we always used DW_RLE_startx_length. This is not very efficient and leads
to bigger .debug_addr section. Changed it to use
DW_RLE_base_addressx/DW_RLE_offset_pair.

clang-16 build in debug mode
llvm-bolt ran on it with --update-debug-sections
| section | before | after | diff | % decrease |
| .debug_rnglists | 32732292 | 31986051 | -746241 | 2.3% |
| .debug_addr | 14415808 | 14184128 |  -231680 | 1.6% |

Reviewed By: maksfb

Differential Revision: https://reviews.llvm.org/D140439
2023-01-06 13:45:43 -08:00
Amir Ayupov
6b05a62a6b [BOLT] Check no-LBR samples in mayHaveProfileData
No-LBR mode wasn't tested and slipped when mayHaveProfileData was added for
Lite mode. This enables processing of profiles collected without LBR and
converted with `perf2bolt -nl` option.

Test Plan:
bin/llvm-lit -a tools/bolt/test/X86/nolbr.s
https://github.com/rafaelauler/bolt-tests/pull/20

Reviewed By: #bolt, rafauler

Differential Revision: https://reviews.llvm.org/D140256
2023-01-03 14:43:36 -08:00
Amir Ayupov
703d94d8f0 [BOLT] Respect -function-order in lite mode
Process functions listed in -function-order file even in lite mode.

Reviewed By: #bolt, maksfb

Differential Revision: https://reviews.llvm.org/D140435
2022-12-28 20:50:20 -08:00
Amir Ayupov
0224bdce92 [BOLT][TEST] Limit iterations in X86/exceptions-pic.test
The test has 3 invocations with 1M iterations each, which adds delay to fast
check-bolt testing. Reduce the number to 1K.

Reviewed By: #bolt, rafauler

Differential Revision: https://reviews.llvm.org/D139651
2022-12-22 19:47:28 -08:00
Vladislav Khmelevsky
17ed8f2928 [BOLT][AArch64] Handle adrp+ld64 linker relaxations
Linker might relax adrp + ldr got address loading to adrp + add for
local non-preemptible symbols (e.g. hidden/protected symbols in
executable). As usually linker doesn't change relocations properly after
relaxation, so we have to handle such cases by ourselves. To do that
during relocations reading we change LD64 reloc to ADD if instruction
mismatch found and introduce FixRelaxationPass that searches for ADRP+ADD
pairs and after performing some checks we're replacing ADRP target symbol
to already fixed ADDs one.

Vladislav Khmelevsky,
Advanced Software Technology Lab, Huawei

Differential Revision: https://reviews.llvm.org/D138097
2022-12-23 01:20:18 +04:00
Alexander Yermolovich
2afc90a2de [BOLT][DWARF] Fix for Handle zero size DW_TAG_inlined_subroutine
Managed to introduce an error when changing code to fix other tests and the unit
test was no adequate due to --nostdlib being passed in in llvm testing
enviroment.
Original diff: https://reviews.llvm.org/D132059

Updated a test to make sure that original address and the new address are
different.

Reviewed By: maksfb, #bolt

Differential Revision: https://reviews.llvm.org/D132782
2022-12-14 09:02:43 -08:00
Maksim Panchenko
0f915826cc [BOLT] Handle access errors while reading profile
When the user does not have permissions to access the profile, consume
the error contained in Expected<> to avoid dumping stack to the user.

Differential Revision: https://reviews.llvm.org/D139480
2022-12-07 17:11:30 -08:00
Alexander Yermolovich
f7a2131766 [BOLT][DWARF] Don't create extra .debug_str_offsets contributions
With ThinLTO mutliple CUs can share the same .debug_str_offsets contribution. We
were creating a new one for each CU. This lead to a binary size increase.

Reviewed By: maksfb

Differential Revision: https://reviews.llvm.org/D139214
2022-12-07 13:08:35 -08:00
Nico Weber
4ffc6f3b83 [bolt] Stop setting config.llvm_plugin_ext in lit.site.cfg.py.in
config.llvm_plugin_ext is used by lit to set the %pluginext
substitution. bolt's tests don't use %pluginext, so they don't
need to set config.llvm_plugin_ext.

Differential Revision: https://reviews.llvm.org/D138325
2022-11-22 20:29:14 -05:00
Alexander Yermolovich
4ff1bc2f53 [BOLT][DWARF] Re-enable DWARF5 for asm-func-debug tests
Now that BOLT supports DWARF5 re-enabling it for these two tests. This is update
to https://reviews.llvm.org/D125366

Reviewed By: rafauler

Differential Revision: https://reviews.llvm.org/D138338
2022-11-22 16:30:33 -08:00
Nico Weber
685f671e1d [bolt] Pass %cflags in test/X86/is-strip.s
Without this, clang builds a binary for macOS on a macOS host, and
then the linker complains that it doesn't know the -q flag.

Differential Revision: https://reviews.llvm.org/D138306
2022-11-18 12:09:07 -05:00
Nico Weber
59b9673b45 [bolt] Make test/X86/end-symbol.test not use "tac"
"tac" doesn't exist on macOS, so this makes the test pass there.

Differential Revision: https://reviews.llvm.org/D138305
2022-11-18 12:08:33 -05:00
Nico Weber
187729ce9f [bolt] Clean up lit site cfg files a bit
* Stop setting config.python_executable in Unit/lit.site.cfg.py.in.
  All other projects only set this in the main lit config, not in the
  one for unit tests. (Unit tests don't spawn Python.)
* Set config.python_executable to Python3_EXECUTABLE in main
  lit.site.cfg.py.in instead of PYTHON_EXECUTABLE. All other files
  did this in c4c3883b00.
* Stop setting enable_abi_breaking_checks, enable_backtrace, enable_shared.
  Nothing in bolt's tests (or in lit) reads them.

Differential Revision: https://reviews.llvm.org/D138299
2022-11-18 12:07:10 -05:00
Rafael Auler
3698994492 [BOLT] Always move JTs in jump-table=move
We should always move jump tables when requested. Previously,
we were not moving jump tables of non-simple functions in relocation
mode. That caused a bug detailed in the attached test case: in PIC
jump tables, we force jump tables to be moved, but if they are not
moved because the function is not simple, we could incorrectly update
original entries in .rodata, corrupting it under special circumstances
(see testcase).

Reviewed By: #bolt, maksfb

Differential Revision: https://reviews.llvm.org/D137357
2022-11-04 13:20:11 -07:00
Alexey Moksyakov
1fb186198a adds huge pages support of PIE/no-PIE binaries
This patch adds the huge pages support (-hugify) for PIE/no-PIE
binaries. Also returned functionality to support the kernels < 5.10
where there is a problem in a dynamic loader with the alignment of
pages addresses.

Differential Revision: https://reviews.llvm.org/D129107
2022-11-04 15:14:21 +03:00
Daniel Thornburgh
75cdab6dc2 [llvm-objdump] Add --no-print-imm-hex to tests depending on it.
This prepares for an upcoming change to make --print-imm-hex the default
behavior of llvm-objdump. These tests were updated in a semi-automatic
fashion.

See D136972 for details.
2022-10-29 15:40:26 -07:00
Amir Ayupov
1464e30704 [BOLT][TEST] Add pseudoprobe-decoding tests
Upstream internal tests, leveraging llvm-profgen binaries.

Reviewed By: hoy

Differential Revision: https://reviews.llvm.org/D136729
2022-10-25 21:33:59 -07:00
Maksim Panchenko
20204db503 [BOLT] Add mold-style PLT support
mold linker creates symbols for PLT entries and that caught BOLT by
surprise. Add the support for marked PLT entries.

Fixes: #58498

Reviewed By: yota9

Differential Revision: https://reviews.llvm.org/D136655
2022-10-25 11:03:52 -07:00
Alexander Yermolovich
fcd7717ddf [BOLT][DWARF] Add support for DW_FORM_addr for DW_AT_call_return_pc
GCC 12 produces DW_FORM_addr for DW_AT_call_return_pc. Added support for that.
Fixes facebookincubator/BOLT#307

Reviewed By: maksfb

Differential Revision: https://reviews.llvm.org/D136204
2022-10-19 10:44:09 -07:00
Maksim Panchenko
bcc4c90954 [BOLT] Fix instruction encoding validation
Always use non-symbolizing disassembler for instruction encoding
validation as symbols will be treated as undefined/zeros be the encoder
and causing byte sequence mismatches.

Reviewed By: Amir

Differential Revision: https://reviews.llvm.org/D136118
2022-10-18 13:50:00 -07:00
Maksim Panchenko
4d3a0cade2 [BOLT] Section-handling refactoring/overhaul
Simplify the logic of handling sections in BOLT. This change brings more
direct and predictable mapping of BinarySection instances to sections in
the input and output files.

* Only sections from the input binary will have a non-null SectionRef.
  When a new section is created as a copy of the input section,
  its SectionRef is reset to null.

* RewriteInstance::getOutputSectionName() is removed as the section name
  in the output file is now defined by BinarySection::getOutputName().

* Querying BinaryContext for sections by name uses their original name.
  E.g., getUniqueSectionByName(".rodata") will return the original
  section even if the new .rodata section was created.

* Input file sections (with relocations applied) are emitted via MC with
  ".bolt.org" prefix. However, their name in the output binary is
  unchanged unless a new section with the same name is created.

* New sections are emitted internally with ".bolt.new" prefix if there's
  a name conflict with an input file section. Their original name is
  preserved in the output file.

* Section header string table is properly populated with section names
  that are actually used. Previously we used to include discarded
  section names as well.

* Fix the problem when dynamic relocations were propagated to a new
  section with a name that matched a section in the input binary.
  E.g., the new .rodata with jump tables had dynamic relocations from
  the original .rodata.

Reviewed By: rafauler

Differential Revision: https://reviews.llvm.org/D135494
2022-10-13 23:10:39 -07:00
Rafael Auler
4f158995b9 [BOLT] Add pass to fix ambiguous memory references
This adds a round of checks to memory references, looking for
incorrect references to jump table objects. Fix them by replacing the
jump table reference with another object reference + offset.

This solves bugs related to regular data references in code
accidentally being bound to a jump table, and this reference being
updated to a new (incorrect) location because we moved this jump
table.

Fixes #55004

Reviewed By: #bolt, maksfb

Differential Revision: https://reviews.llvm.org/D134098
2022-10-12 18:39:50 -07:00
Maksim Panchenko
978f11c8e8 [BOLT][TEST] Fix section order test
.bss section emitted by llvm-bolt (e.g. with instrumentation) is not a
real BSS section, i.e. it takes space in the output file. Hence the
order with respect to .data is not defined. Remove .bss from the test
and fix the buildbot failure.

Reviewed By: Amir

Differential Revision: https://reviews.llvm.org/D135475
2022-10-07 14:38:49 -07:00
Rafael Auler
696b8ea05f [BOLT] Testcase to repro dyn reloc bug
Add a new testcase that shows a bug in BOLT when writing out
dynamic relocations. This is currently marked as XFAIL as we work on
solving it. This bug happens when the current strategy fails to
recognize that the original dynamic relocation in the input should
reference the original .bolt.org.rodata section instead of the new one
.rodata created by BOLT after moving jump tables. This bug started
happening after 729d29e167.

Reviewed By: Amir

Differential Revision: https://reviews.llvm.org/D125941
2022-10-07 11:27:23 -07:00
Maksim Panchenko
5fca9c5763 [BOLT] Change order of new sections
While the order of new sections in the output binary was deterministic
in the past (i.e. there was no run-to-run variation), it wasn't always
rational as we used size to define the precedence of allocatable
sections within "code" or "data" groups (probably unintentionally).
Fix that by defining stricter section-ordering rules.

Other than the order of sections, this should be NFC.

Reviewed By: rafauler

Differential Revision: https://reviews.llvm.org/D135235
2022-10-07 11:20:42 -07:00
Maksim Panchenko
0b213c9090 [BOLT] Fix writing out unmarked .eh_frame section
When BOLT updates .eh_frame section, it concatenates newly-generated
contents (from CFI directives) with the original .eh_frame that has
relocations applied to it. However, if no new content is generated,
the original .eh_frame has to be left intact. In that case, BOLT was
still writing out the relocatable copy of the original .eh_frame section
to the new segment, even though this copy was never used and was not
even marked in the section header table.

Detect the scenario above and skip allocating extra space for .eh_frame.

Reviewed By: rafauler

Differential Revision: https://reviews.llvm.org/D135223
2022-10-07 11:19:51 -07:00
Maksim Panchenko
c683e281cd [BOLT] Properly set _end symbol
To properly set the "_end" symbol, we need to track the last allocatable
address. Simply emitting "_end" at the end of some section is not
sufficient since the order of section allocation is unknown during the
emission step.

Reviewed By: rafauler

Differential Revision: https://reviews.llvm.org/D135121
2022-10-07 11:19:14 -07:00
Amir Ayupov
39336fc09c [BOLT] Control aggregation mode output profile file format
In perf2bolt and `-aggregate-only` BOLT mode, the output profile file is written
in fdata format by default. Provide a knob `-profile-format=[fdata,yaml]` to
control the format.
Note that `-w` option still dumps in YAML format.

Reviewed By: #bolt, maksfb

Differential Revision: https://reviews.llvm.org/D133995
2022-09-19 13:37:10 -07:00
Maksim Panchenko
9742c25b98 [BOLT] Fix empty function emission in non-relocation mode
In non-relocation mode, every function is emitted in its own section. If
a function is empty, RuntimeDyld will still allocate 1-byte section
for the function and initialize it with zero. As a result, we will
overwrite the first byte of the original function contents with zero.
Such scenario can happen when the input function had only NOP
instructions which BOLT removes by default. Even though such functions
likely cause undefined behavior, it's better to preserve their contents.

Reviewed By: yota9

Differential Revision: https://reviews.llvm.org/D133978
2022-09-16 13:38:32 -07:00
Amir Ayupov
e002523b65 [BOLT] Verify externally referenced blocks against jump table targets
For functions with references to internal offsets from data, verify externally
referenced blocks against the set of jump table targets. Mark the function
as non-simple if there are any unclaimed data to code references.

Reviewed By: #bolt, maksfb

Differential Revision: https://reviews.llvm.org/D132495
2022-09-16 11:44:33 -07:00
revunov.denis@huawei.com
553c238952 [BOLT] Preserve original LSDA type encoding
In non-pie binaries BOLT unconditionally converted type encoding
from indirect to absptr, which broke std exceptions since pointers
to their typeinfo were only assigned at runtime in .data section.
In this patch we preserve original encoding so that indirect
remains indirect and can be resolved at runtime, and absolute remains absolute.

Reviewed By: rafauler, maksfb

Differential Revision: https://reviews.llvm.org/D132484
2022-09-14 16:33:47 +00:00
Fabian Parzefall
579a5a47a9 [BOLT] Add test checking LP trampolines in multi-split
This adds a test to verify that when splitting all blocks, landing pad
trampolines are inserted in all blocks.

Reviewed By: maksfb

Differential Revision: https://reviews.llvm.org/D132426
2022-09-08 17:10:38 -07:00
Fabian Parzefall
3ac46f377a [BOLT] Emit LSDA call sites for all fragments
For exception handling, LSDA call sites have to be emitted for each
fragment individually. With this patch, call sites and respective LSDA
symbols are generated and associated with each fragment of their
function, such that they can be used by the emitter.

Reviewed By: maksfb

Differential Revision: https://reviews.llvm.org/D132052
2022-09-08 17:10:29 -07:00
Amir Ayupov
a80e1e493f [BOLT][TEST] Remove functions with dynamic exception specification
Clang has switched to gnu++17 by default with https://reviews.llvm.org/D131465.
C++17 removes dynamic exception specification. Remove its use as it wasn't
properly tested.

Reviewed By: maksfb

Differential Revision: https://reviews.llvm.org/D133467
2022-09-07 20:45:41 -07:00
Alexander Yermolovich
1ee74064e0 [BOLT][DWARF] Fix updating CU that has no entry in .debug_addr
We were trying to process .debug_addr for CU that doesn't have it. This resulted
in assert. Example came from GCC that also doesn't use DW_OP_addrx in
DW_FORM_exprloc.

Reviewed By: maksfb

Differential Revision: https://reviews.llvm.org/D132422
2022-08-25 17:03:11 -07:00
Denis Revunov
6040415ef9 [BOLT][AArch64] Handle references to the middle of Constant Islands
Fix BinaryContext::handleAddressRef to properly detect references to
other function's Constant islands.

Revieved By: rafauler, yota9

Differential Revision: https://reviews.llvm.org/D132376
2022-08-25 04:32:35 -04:00
Simon Tatham
79f99bf622 [bolt] Fix a test affected by D131589.
This test contained some data tables that llvm-objdump was
disassembling as code, so the test was recovering the 32-bit values in
the table from the instruction encoding column of the disassembly.

D131589 changed how llvm-objdump decides what to disassemble as code
or as data. As a result, these data tables are now being disassembled
as data, which I think is actually more sensible -- but the test
wasn't expecting it, and got confused.
2022-08-24 15:52:06 +01:00
Alexander Yermolovich
928c2ba179 [DWARF][BOLT] Fix handling of converting range accesss from ofset to index.
Wasn't handling correctly creating DW_AT_rnglists_base in UnitDie when
converting access pattern for DW_AT_ranges from offset to index for DWARF5.

Reviewed By: rafauler

Differential Revision: https://reviews.llvm.org/D132087
2022-08-19 15:28:12 -07:00
Fabian Parzefall
48ff38ce5d [BOLT] Add randomN split strategy
This adds a strategy to split functions into a random number of
fragments at randomly chosen split points.

Reviewed By: rafauler

Differential Revision: https://reviews.llvm.org/D130647
2022-08-18 21:55:07 -07:00
Fabian Parzefall
f428db7a00 [BOLT] Add split all blocks strategy
This adds a function splitting strategy that splits each outlineable
basic block into its own fragment. This is exposed through a new command
line option `--split-strategy`.

Reviewed By: rafauler

Differential Revision: https://reviews.llvm.org/D129827
2022-08-18 21:55:07 -07:00
Denis Revunov
d0e29e87cd [BOLT][AArch64] Ignore functions with islandsInfo during VeneerEliminarion and ICF
Differential Revision: https://reviews.llvm.org/D131881

Reviewed By: yota9
2022-08-18 11:08:47 -04:00
Alexander Yermolovich
ccbf28b09d [BOLT][DWARF] Handle zero size DW_TAG_inlined_subroutine
We were resetting DW_AT_low_pc to zero when DW_AT_high_pc was zero, or
DW_AT_low_pc == DW_AT_high_pc. This resulted in LLDB to print error "adding
range [0x0-0x0) which has a base that is less than the function's low PC".

Changed it so that when this case arises we set DW_AT_low_pc to the start
address.

Reviewed By: rafauler

Differential Revision: https://reviews.llvm.org/D132059
2022-08-17 17:29:53 -07:00
Fabian Parzefall
fd159c2316 [BOLT] Fix ignored LP at fragment start
If the first block of a fragment is also a landing pad, the landing pad
is not used if an exception is thrown. This is because the landing pad
is at the same start address that the corresponding LSDA describes. In
that case, the offset in the call site records to refer to that landing
pad is zero, and a zero offset is interpreted by the personality
function as "no handler" and ignored.

Reviewed By: Amir

Differential Revision: https://reviews.llvm.org/D132053
2022-08-17 16:34:44 -07:00
Alexander Yermolovich
b786e01f93 [DWARF][BOLT] Handle getBinaryFunctionContainingAddress returning nullptr for DW_TAG_call_site
DW_TAG_call_site/DW_AT_call_return_pc can contain address that is not in any
function. In this case getBinaryFunctionContainingAddress returns nullptr. For
this case preserving original address.

Reviewed By: rafauler

Differential Revision: https://reviews.llvm.org/D132057
2022-08-17 16:04:34 -07:00
Alexander Yermolovich
dd29b3c542 [BOLT][DWARF] Fix handling of multiple DW_OP_addrx in an expression
We were not handling correclty multiple DW_OP_addrx in the location expression.
This was exposed by clang-15 build in release mode with debug information.

Reviewed By: maksfb

Differential Revision: https://reviews.llvm.org/D130812
2022-08-01 14:38:47 -07:00
Amir Ayupov
468d4f6d18 Revert "[BOLT] Ignore functions accessing false positive jump tables"
This diff uncovers an ASAN leak in getOrCreateJumpTable:
```
Indirect leak of 264 byte(s) in 1 object(s) allocated from:
    #1 0x4f6e48c in llvm::bolt::BinaryContext::getOrCreateJumpTable ...
```
The removal of an assertion needs to be accompanied by proper deallocation of
a `JumpTable` object for which `analyzeJumpTable` was unsuccessful.

This reverts commit 52cd00cabf.
2022-07-30 10:39:46 -07:00
Rafael Auler
fc0ced73dc Add BAT testing framework
This patch refactors BAT to be testable as a library, so we
can have open-source tests on it. This further fixes an issue with
basic blocks that lack a valid input offset, making BAT omit those
when writing translation tables.

Test Plan: new testcases added, new testing tool added (llvm-bat-dump)

Differential Revision: https://reviews.llvm.org/D129382
2022-07-29 14:55:04 -07:00
Huan Nguyen
52cd00cabf [BOLT] Ignore functions accessing false positive jump tables
Disassembly and branch target analysis are not decoupled, so any
analysis that depends on disassembly may not operate properly.

In specific, analyzeJumpTable uses instruction bounds check property.
A jump table was analyzed twice: (a) during disassembly, and (b) after
disassembly, so there are potentially some mismatched results.

In this update, functions that access JTs which fail the second check
will be marked as ignored.

Test Plan:
```
ninja check-bolt
```

Reviewed By: Amir

Differential Revision: https://reviews.llvm.org/D130431
2022-07-28 23:22:17 -07:00
Huan Nguyen
986362d4a3 [BOLT] Add BinaryContext::IsStripped
Determine stripped status of a binary based on .symtab

Test Plan:
```
ninja check-bolt
```

Reviewed By: Amir

Differential Revision: https://reviews.llvm.org/D130034
2022-07-28 23:11:03 -07:00
Simon Tatham
0db13e10c5 [bolt,AArch64] Fix one more test failure from D130358.
This one actually makes the test simpler, because lit doesn't have to
reconstitute a 32-bit little-endian value from individual bytes any
more: llvm-objdump is printing the desired 32-bit value in the first
place, so we can move straight on to doing the arithmetic on it.
2022-07-26 16:41:09 +01:00