[BOLT] Skip disassembly of padding at function end.

Summary:
Some functions coming from assembly may not have been marked
with size. We assume the size to include all bytes up to
the next function/object in the file. As a result,
function body will include any padding inserted by the linker.
If linker inserts 0-value bytes this could be misinterpreted
as invalid instruction and BOLT will bail out on such functions
in non-relocation mode, and give up on a binary in relocation
mode.

This diff detects zero-padding, ignores it, and continues processing
as normal.

(cherry picked from FBD4528893)
This commit is contained in:
Maksim Panchenko
2017-02-08 09:14:10 -08:00
parent 6b0b5bbae7
commit 734a7a5437

View File

@@ -976,12 +976,24 @@ void BinaryFunction::disassemble(ArrayRef<uint8_t> FunctionData) {
AbsoluteInstrAddr,
nulls(),
nulls())) {
// Ignore this function. Skip to the next one in non-relocs mode.
errs() << "BOLT-ERROR: unable to disassemble instruction at offset 0x"
<< Twine::utohexstr(Offset) << " (address 0x"
<< Twine::utohexstr(AbsoluteInstrAddr) << ") in function "
<< *this << '\n';
IsSimple = false;
// Functions with "soft" boundaries, e.g. coming from assembly source,
// can have 0-byte padding at the end.
bool IsZeroPadding = true;
for (auto I = Offset; I < getSize(); ++I) {
if (FunctionData[I] != 0) {
IsZeroPadding = false;
break;
}
}
if (!IsZeroPadding) {
// Ignore this function. Skip to the next one in non-relocs mode.
errs() << "BOLT-ERROR: unable to disassemble instruction at offset 0x"
<< Twine::utohexstr(Offset) << " (address 0x"
<< Twine::utohexstr(AbsoluteInstrAddr) << ") in function "
<< *this << '\n';
IsSimple = false;
}
break;
}