Don't abort on unknown CFI instructions.

Summary:
If we see an unknown CFI instruction, skip processing the function
containing it instead of aborting execution.

(cherry picked from FBD2964557)
This commit is contained in:
Maksim Panchenko 2016-02-22 18:25:43 -08:00
parent 7f7d4af7e0
commit 73e9afe99c
3 changed files with 29 additions and 16 deletions

View File

@ -492,11 +492,11 @@ void BinaryFunction::emitLSDA(MCStreamer *Streamer) {
const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
void CFIReaderWriter::fillCFIInfoFor(BinaryFunction &Function) const {
bool CFIReaderWriter::fillCFIInfoFor(BinaryFunction &Function) const {
uint64_t Address = Function.getAddress();
auto I = FDEs.find(Address);
if (I == FDEs.end())
return;
return true;
const FDE &CurFDE = *I->second;
if (Function.getSize() != CurFDE.getAddressRange()) {
@ -613,33 +613,41 @@ void CFIReaderWriter::fillCFIInfoFor(BinaryFunction &Function) const {
break;
case DW_CFA_val_offset_sf:
case DW_CFA_val_offset:
llvm_unreachable("DWARF val_offset() unimplemented");
break;
errs() << "BOLT-WARNING: DWARF val_offset() unimplemented\n";
return false;
case DW_CFA_expression:
case DW_CFA_def_cfa_expression:
case DW_CFA_val_expression:
llvm_unreachable("DWARF CFA expressions unimplemented");
break;
errs() << "BOLT-WARNING: DWARF CFA expressions unimplemented\n";
return false;
case DW_CFA_MIPS_advance_loc8:
llvm_unreachable("DW_CFA_MIPS_advance_loc unimplemented");
break;
errs() << "BOLT-WARNING: DW_CFA_MIPS_advance_loc unimplemented\n";
return false;
case DW_CFA_GNU_window_save:
case DW_CFA_lo_user:
case DW_CFA_hi_user:
llvm_unreachable("DW_CFA_GNU_* and DW_CFA_*_user unimplemented");
break;
errs() <<
"BOLT-WARNING: DW_CFA_GNU_* and DW_CFA_*_user unimplemented\n";
return false;
default:
llvm_unreachable("Unrecognized CFI instruction");
errs() << "BOLT-WARNING: Unrecognized CFI instruction\n";
return false;
}
return true;
};
for (const FrameEntry::Instruction &Instr : *(CurFDE.getLinkedCIE())) {
decodeFrameInstruction(Instr);
if (!decodeFrameInstruction(Instr))
return false;
}
for (const FrameEntry::Instruction &Instr : CurFDE) {
decodeFrameInstruction(Instr);
if (!decodeFrameInstruction(Instr))
return false;
}
return true;
}
void CFIReaderWriter::rewriteHeaderFor(StringRef EHFrame,

View File

@ -44,7 +44,7 @@ public:
using FDEsMap = std::map<uint64_t, const dwarf::FDE *>;
void fillCFIInfoFor(BinaryFunction &Function) const;
bool fillCFIInfoFor(BinaryFunction &Function) const;
// Include a new EHFrame, updating the .eh_frame_hdr
void rewriteHeaderFor(StringRef EHFrame, uint64_t EHFrameAddress,

View File

@ -706,8 +706,13 @@ void RewriteInstance::disassembleFunctions() {
continue;
// Fill in CFI information for this function
if (EHFrame->ParseError.empty() && Function.isSimple()) {
CFIRdWrt->fillCFIInfoFor(Function);
if (EHFrame->ParseError.empty()) {
if (!CFIRdWrt->fillCFIInfoFor(Function)) {
errs() << "BOLT-WARNING: unable to fill CFI for function "
<< Function.getName() << '\n';
Function.setSimple(false);
continue;
}
}
// Parse LSDA.