From 963d19d86cca708957055f3072cbe8473c8e52e3 Mon Sep 17 00:00:00 2001 From: xiongzhou4 Date: Thu, 15 Jun 2023 20:34:42 +0800 Subject: [PATCH] [Backport] [BOLT] [AArch64] Handle data at the beginning of a function when disassembling and building CFG. --- bolt/src/BinaryFunction.cpp | 11 +++++++---- bolt/src/BinaryFunction.h | 9 +++++++++ bolt/src/Exceptions.cpp | 2 +- bolt/test/AArch64/data-at-0-offset.c | 17 +++++++++++++++++ 4 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 bolt/test/AArch64/data-at-0-offset.c diff --git a/bolt/src/BinaryFunction.cpp b/bolt/src/BinaryFunction.cpp index 9414b83ad..93de63d3f 100644 --- a/bolt/src/BinaryFunction.cpp +++ b/bolt/src/BinaryFunction.cpp @@ -1445,6 +1445,9 @@ add_instruction: addInstruction(Offset, std::move(Instruction)); } + if (uint64_t Offset = getFirstInstructionOffset()) + Labels[Offset] = BC.Ctx->createNamedTempSymbol(); + clearList(Relocations); if (!IsSimple) { @@ -1987,7 +1990,7 @@ bool BinaryFunction::buildCFG(MCPlusBuilder::AllocatorIdTy AllocatorId) { return false; assert(BasicBlocks.empty() && "basic block list should be empty"); - assert((Labels.find(0) != Labels.end()) && + assert((Labels.find(getFirstInstructionOffset()) != Labels.end()) && "first instruction should always have a label"); // Create basic blocks in the original layout order: @@ -2087,9 +2090,9 @@ bool BinaryFunction::buildCFG(MCPlusBuilder::AllocatorIdTy AllocatorId) { updateOffset(LastInstrOffset); } } - if (Offset == 0) { - // Add associated CFI pseudos in the first offset (0) - addCFIPlaceholders(0, InsertBB); + if (Offset == getFirstInstructionOffset()) { + // Add associated CFI pseudos in the first offset. + addCFIPlaceholders(Offset, InsertBB); } const bool IsBlockEnd = MIB->isTerminator(Instr); diff --git a/bolt/src/BinaryFunction.h b/bolt/src/BinaryFunction.h index a824f3d58..3b435cfb3 100644 --- a/bolt/src/BinaryFunction.h +++ b/bolt/src/BinaryFunction.h @@ -967,6 +967,15 @@ public: return const_cast(this)->getInstructionAtOffset(Offset); } + /// Return offset for the first instruction. If there is data at the + /// beginning of a function then offset of the first instruction could + /// be different from 0. + uint64_t getFirstInstructionOffset() const { + if (Instructions.empty()) + return 0; + return Instructions.begin()->first; + } + /// Return jump table that covers a given \p Address in memory. JumpTable *getJumpTableContainingAddress(uint64_t Address) { auto JTI = JumpTables.upper_bound(Address); diff --git a/bolt/src/Exceptions.cpp b/bolt/src/Exceptions.cpp index f73054aa8..0a64e3fca 100644 --- a/bolt/src/Exceptions.cpp +++ b/bolt/src/Exceptions.cpp @@ -499,7 +499,7 @@ bool CFIReaderWriter::fillCFIInfoFor(BinaryFunction &Function) const { Optional LSDA = CurFDE.getLSDAAddress(); Function.setLSDAAddress(LSDA ? *LSDA : 0); - uint64_t Offset = 0; + uint64_t Offset = Function.getFirstInstructionOffset(); uint64_t CodeAlignment = CurFDE.getLinkedCIE()->getCodeAlignmentFactor(); uint64_t DataAlignment = CurFDE.getLinkedCIE()->getDataAlignmentFactor(); if (CurFDE.getLinkedCIE()->getPersonalityAddress()) { diff --git a/bolt/test/AArch64/data-at-0-offset.c b/bolt/test/AArch64/data-at-0-offset.c new file mode 100644 index 000000000..e0c689a19 --- /dev/null +++ b/bolt/test/AArch64/data-at-0-offset.c @@ -0,0 +1,17 @@ +// RUN: %clang %cflags -O2 -fPIE -Wl,-q -pie %s -o %t.exe +// RUN: llvm-bolt %t.exe -o %t.bolt 2>&1 | FileCheck %s +// CHECK-NOT: BOLT-WARNING: unable to disassemble instruction at offset + +void extra_space() { + asm volatile(".rept 256\n" + " .byte 0xff\n" + ".endr\n"); + return; +} + +int main(int argc, char **argv) { + void (*fn)(void); + fn = extra_space + 256; + fn(); + return 0; +} -- 2.33.0