util/llvmdisassembler: fix section end symbols

Somehow, while iterating symbols in a section, it can happen that the last
symbol start address is equal to the section size, which means it is beyond
the section end.
In this case the LLVM getInstruction() method does not return a failure, but a
zero-size instruction, resulting in an infinite loop.

Now, if beyond section limits, the iteration is aborted.
Additionally, an assertion checks for disassembled zero-size instructions.

Change-Id: Id8a355475161150d3ee919cd6cf603d4ff26b228
This commit is contained in:
Florian Lukas
2014-04-03 14:56:41 +02:00
parent 940fa6035d
commit ba774a258c

View File

@ -85,7 +85,10 @@ void LLVMDisassembler::disassemble()
uint64_t End; uint64_t End;
// The end is either the size of the section or the beginning of the next // The end is either the size of the section or the beginning of the next
// symbol. // symbol.
if (si == se - 1) if (Start >= SectSize)
// we are beyond the end of the section
break;
else if (si == se - 1)
End = SectSize; End = SectSize;
// Make sure this symbol takes up space. // Make sure this symbol takes up space.
else if (Symbols[si + 1].first != Start) else if (Symbols[si + 1].first != Start)
@ -98,7 +101,7 @@ void LLVMDisassembler::disassemble()
MCInst Inst; MCInst Inst;
if (disas->getInstruction(Inst, Size, memoryObject, Index, if (disas->getInstruction(Inst, Size, memoryObject, Index,
nulls(), nulls())) { nulls(), nulls()) == MCDisassembler::Success) {
const MCInstrDesc &desc = this->instr_info->get(Inst.getOpcode()); const MCInstrDesc &desc = this->instr_info->get(Inst.getOpcode());
// Inst.dump(); // Inst.dump();
Instr instr_info; Instr instr_info;
@ -107,6 +110,8 @@ void LLVMDisassembler::disassemble()
instr_info.address = SectionAddr + Index; instr_info.address = SectionAddr + Index;
instr_info.conditional_branch = desc.isConditionalBranch(); instr_info.conditional_branch = desc.isConditionalBranch();
assert( Size > 0 && "zero size instruction disassembled" );
unsigned int pos = 0; unsigned int pos = 0;
for (MCInst::iterator it = Inst.begin(); it != Inst.end(); ++it) { for (MCInst::iterator it = Inst.begin(); it != Inst.end(); ++it) {