[llvm-profgen] Enable all AArch64 instructions for disassembly (#204619)
llvm-profgen builds its MCSubtargetInfo from `ObjectFile::getFeatures()`. For AArch64 ELF objects this often produces an empty feature set, so the disassembler falls back to the baseline Armv8.0-A ISA and rejects valid feature-gated instructions such as LSE atomics and RCPC loads. `llvm-objdump` already handles this by [adding +all for AArch64 disassembly](https://github.com/llvm/llvm-project/blob/1e2d1bbc12f6a5f5931c77d39894ee1b8679f5f8/llvm/tools/llvm-objdump/llvm-objdump.cpp#L2823-L2824) when neither -mattr nor -mcpu is specified. Match that behavior in `llvm-profgen` so valid AArch64 instructions are not reported as invalid and their addresses are preserved in profgen's code and branch maps. Add a regression test covering an AArch64 binary containing `ldaddal` and `ldapr` without object-level feature metadata. --------- Co-authored-by: Kunal Pathak <kupathak@fb.com>
This commit is contained in:
1 parent
04baf7ed88
commit
738fecbc68
2 files changed
+56
No files matched your search
@@ -0,0 +1,46 @@
|
||||
# REQUIRES: aarch64-registered-target
|
||||
|
||||
# RUN: yaml2obj %s -o %t.exe
|
||||
# RUN: llvm-profgen --binary=%t.exe --output=/dev/null --show-disassembly-only 2>&1 \
|
||||
# RUN: | FileCheck %s
|
||||
|
||||
# CHECK-NOT: invalid instructions
|
||||
# CHECK: Disassembly of section .text
|
||||
# CHECK-NOT: <unknown>
|
||||
# CHECK: <foo>:
|
||||
# CHECK-NEXT: {{[0-9a-f]+}}: ldaddal w0, w1, [x2]
|
||||
# CHECK-NEXT: {{[0-9a-f]+}}: ldapr x3, [x4]
|
||||
# CHECK-NEXT: {{[0-9a-f]+}}: ret
|
||||
# CHECK-NOT: <unknown>
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
Machine: EM_AARCH64
|
||||
Entry: 0x0000000000401000
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
Address: 0x0000000000401000
|
||||
AddressAlign: 0x4
|
||||
## ldaddal w0, w1, [x2]
|
||||
## ldapr x3, [x4]
|
||||
## ret
|
||||
Content: 4100E0B883C0BFF8C0035FD6
|
||||
ProgramHeaders:
|
||||
- Type: PT_LOAD
|
||||
Flags: [ PF_X, PF_R ]
|
||||
VAddr: 0x0000000000400000
|
||||
Align: 0x1000
|
||||
FirstSec: .text
|
||||
LastSec: .text
|
||||
Symbols:
|
||||
- Name: foo
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Binding: STB_GLOBAL
|
||||
Value: 0x0000000000401000
|
||||
Size: 0x000000000000000C
|
||||
@@ -745,6 +745,16 @@ void ProfiledBinary::setUpDisassembler(const ObjectFile *Obj) {
|
||||
Expected<SubtargetFeatures> Features = Obj->getFeatures();
|
||||
if (!Features)
|
||||
exitWithError(Features.takeError(), FileName);
|
||||
// AArch64 object files do not generally carry complete ISA feature metadata,
|
||||
// so the subtarget would default to the baseline (Armv8.0-A) feature set.
|
||||
// That disassembler cannot decode feature-gated instructions (LSE atomics,
|
||||
// RCPC loads, SVE, ...) that are pervasive in modern AArch64 binaries; they
|
||||
// would be miscounted as "invalid instructions" and, worse, their addresses
|
||||
// would be absent from the code/branch maps used for sample attribution.
|
||||
// Enable all instructions so the disassembler recognizes whatever the
|
||||
// compiler emitted, matching llvm-objdump's default for AArch64.
|
||||
if (TheTriple.isAArch64())
|
||||
Features->AddFeature("+all");
|
||||
STI.reset(
|
||||
TheTarget->createMCSubtargetInfo(TheTriple, "", Features->getString()));
|
||||
if (!STI)
|
||||
|
||||
Reference in new issue
Block a user