[BOLT][AArch64] Handle data at the beginning of a function when disassembling and building CFG.
This patch adds getFirstInstructionOffset method for BinaryFunction which is used to properly handle cases where data is at zero offset in a function. The main change is that we add basic block at first instruction offset when disassembling, which prevents assertion failures in buildCFG. Reviewed By: yota9, rafauler Differential Revision: https://reviews.llvm.org/D127111
This commit is contained in:
parent
7bdd3722f2
commit
0b7e8baf83
|
@ -982,6 +982,15 @@ public:
|
|||
return const_cast<BinaryFunction *>(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);
|
||||
|
|
|
@ -1383,6 +1383,9 @@ add_instruction:
|
|||
// Reset symbolizer for the disassembler.
|
||||
BC.SymbolicDisAsm->setSymbolizer(nullptr);
|
||||
|
||||
if (uint64_t Offset = getFirstInstructionOffset())
|
||||
Labels[Offset] = BC.Ctx->createNamedTempSymbol();
|
||||
|
||||
clearList(Relocations);
|
||||
|
||||
if (!IsSimple) {
|
||||
|
@ -1895,7 +1898,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:
|
||||
|
@ -1999,9 +2002,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);
|
||||
|
|
|
@ -493,7 +493,7 @@ bool CFIReaderWriter::fillCFIInfoFor(BinaryFunction &Function) const {
|
|||
Optional<uint64_t> 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()) {
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue