diff options
author | Kevin Enderby <enderby@apple.com> | 2015-10-10 00:05:01 +0000 |
---|---|---|
committer | Kevin Enderby <enderby@apple.com> | 2015-10-10 00:05:01 +0000 |
commit | d90a4176ffd84517da1fbb47fa33aef1d5ad6e4c (patch) | |
tree | 98879719c8a907e970f6e46d52db2b155bbfb599 /llvm | |
parent | bfa5b98201dc9c793a48e5a713a2159ed96e72eb (diff) | |
download | bcm5719-llvm-d90a4176ffd84517da1fbb47fa33aef1d5ad6e4c.tar.gz bcm5719-llvm-d90a4176ffd84517da1fbb47fa33aef1d5ad6e4c.zip |
Fix a bugs in the Mach-O disassembler when disassembling from a
malformed Mach-O file that caused a crash. This was because of an
assert where the code was incorrectly attempting to parse relocation
entries off of the sections and the filetype was not an MH_OBJECT.
rdar://22983603
llvm-svn: 249921
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0337.macho | bin | 0 -> 9248 bytes | |||
-rw-r--r-- | llvm/test/tools/llvm-objdump/malformed-machos.test | 6 | ||||
-rw-r--r-- | llvm/tools/llvm-objdump/MachODump.cpp | 123 |
3 files changed, 72 insertions, 57 deletions
diff --git a/llvm/test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0337.macho b/llvm/test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0337.macho Binary files differnew file mode 100644 index 00000000000..cc438414f11 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0337.macho diff --git a/llvm/test/tools/llvm-objdump/malformed-machos.test b/llvm/test/tools/llvm-objdump/malformed-machos.test index 732cdb665b9..a47e43443c5 100644 --- a/llvm/test/tools/llvm-objdump/malformed-machos.test +++ b/llvm/test/tools/llvm-objdump/malformed-machos.test @@ -33,3 +33,9 @@ # RUN: llvm-objdump -macho -objc-meta-data \ # RUN: %p/Inputs/malformed-machos/mem-crup-0261.macho + +# RUN: llvm-objdump -macho -disassemble \ +# RUN: %p/Inputs/malformed-machos/mem-crup-0337.macho \ +# RUN: | FileCheck -check-prefix=m0337 %s + +# m0337: subq $16, %rsp diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp index 0d5993ccd2a..6b70c011c02 100644 --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -1705,8 +1705,15 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, if (Arch == Triple::x86) { if (Size != 1 && Size != 2 && Size != 4 && Size != 0) return 0; - // First search the section's relocation entries (if any) for an entry - // for this section offset. + if (info->O->getHeader().filetype != MachO::MH_OBJECT) { + // TODO: + // Search the external relocation entries of a fully linked image + // (if any) for an entry that matches this segment offset. + // uint32_t seg_offset = (Pc + Offset); + return 0; + } + // In MH_OBJECT filetypes search the section's relocation entries (if any) + // for an entry for this section offset. uint32_t sect_addr = info->S.getAddress(); uint32_t sect_offset = (Pc + Offset) - sect_addr; bool reloc_found = false; @@ -1776,17 +1783,20 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, op_info->Value = offset; return 1; } - // TODO: - // Second search the external relocation entries of a fully linked image - // (if any) for an entry that matches this segment offset. - // uint32_t seg_offset = (Pc + Offset); return 0; } if (Arch == Triple::x86_64) { if (Size != 1 && Size != 2 && Size != 4 && Size != 0) return 0; - // First search the section's relocation entries (if any) for an entry - // for this section offset. + if (info->O->getHeader().filetype != MachO::MH_OBJECT) { + // TODO: + // Search the external relocation entries of a fully linked image + // (if any) for an entry that matches this segment offset. + // uint64_t seg_offset = (Pc + Offset); + return 0; + } + // In MH_OBJECT filetypes search the section's relocation entries (if any) + // for an entry for this section offset. uint64_t sect_addr = info->S.getAddress(); uint64_t sect_offset = (Pc + Offset) - sect_addr; bool reloc_found = false; @@ -1844,17 +1854,20 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, op_info->AddSymbol.Name = name; return 1; } - // TODO: - // Second search the external relocation entries of a fully linked image - // (if any) for an entry that matches this segment offset. - // uint64_t seg_offset = (Pc + Offset); return 0; } if (Arch == Triple::arm) { if (Offset != 0 || (Size != 4 && Size != 2)) return 0; - // First search the section's relocation entries (if any) for an entry - // for this section offset. + if (info->O->getHeader().filetype != MachO::MH_OBJECT) { + // TODO: + // Search the external relocation entries of a fully linked image + // (if any) for an entry that matches this segment offset. + // uint32_t seg_offset = (Pc + Offset); + return 0; + } + // In MH_OBJECT filetypes search the section's relocation entries (if any) + // for an entry for this section offset. uint32_t sect_addr = info->S.getAddress(); uint32_t sect_offset = (Pc + Offset) - sect_addr; DataRefImpl Rel; @@ -1986,8 +1999,15 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, if (Arch == Triple::aarch64) { if (Offset != 0 || Size != 4) return 0; - // First search the section's relocation entries (if any) for an entry - // for this section offset. + if (info->O->getHeader().filetype != MachO::MH_OBJECT) { + // TODO: + // Search the external relocation entries of a fully linked image + // (if any) for an entry that matches this segment offset. + // uint64_t seg_offset = (Pc + Offset); + return 0; + } + // In MH_OBJECT filetypes search the section's relocation entries (if any) + // for an entry for this section offset. uint64_t sect_addr = info->S.getAddress(); uint64_t sect_offset = (Pc + Offset) - sect_addr; auto Reloc = @@ -5574,36 +5594,38 @@ static const char *GuessLiteralPointer(uint64_t ReferenceValue, uint64_t *ReferenceType, struct DisassembleInfo *info) { // First see if there is an external relocation entry at the ReferencePC. - uint64_t sect_addr = info->S.getAddress(); - uint64_t sect_offset = ReferencePC - sect_addr; - bool reloc_found = false; - DataRefImpl Rel; - MachO::any_relocation_info RE; - bool isExtern = false; - SymbolRef Symbol; - for (const RelocationRef &Reloc : info->S.relocations()) { - uint64_t RelocOffset = Reloc.getOffset(); - if (RelocOffset == sect_offset) { - Rel = Reloc.getRawDataRefImpl(); - RE = info->O->getRelocation(Rel); - if (info->O->isRelocationScattered(RE)) - continue; - isExtern = info->O->getPlainRelocationExternal(RE); - if (isExtern) { - symbol_iterator RelocSym = Reloc.getSymbol(); - Symbol = *RelocSym; + if (info->O->getHeader().filetype == MachO::MH_OBJECT) { + uint64_t sect_addr = info->S.getAddress(); + uint64_t sect_offset = ReferencePC - sect_addr; + bool reloc_found = false; + DataRefImpl Rel; + MachO::any_relocation_info RE; + bool isExtern = false; + SymbolRef Symbol; + for (const RelocationRef &Reloc : info->S.relocations()) { + uint64_t RelocOffset = Reloc.getOffset(); + if (RelocOffset == sect_offset) { + Rel = Reloc.getRawDataRefImpl(); + RE = info->O->getRelocation(Rel); + if (info->O->isRelocationScattered(RE)) + continue; + isExtern = info->O->getPlainRelocationExternal(RE); + if (isExtern) { + symbol_iterator RelocSym = Reloc.getSymbol(); + Symbol = *RelocSym; + } + reloc_found = true; + break; } - reloc_found = true; - break; } - } - // If there is an external relocation entry for a symbol in a section - // then used that symbol's value for the value of the reference. - if (reloc_found && isExtern) { - if (info->O->getAnyRelocationPCRel(RE)) { - unsigned Type = info->O->getAnyRelocationType(RE); - if (Type == MachO::X86_64_RELOC_SIGNED) { - ReferenceValue = Symbol.getValue(); + // If there is an external relocation entry for a symbol in a section + // then used that symbol's value for the value of the reference. + if (reloc_found && isExtern) { + if (info->O->getAnyRelocationPCRel(RE)) { + unsigned Type = info->O->getAnyRelocationType(RE); + if (Type == MachO::X86_64_RELOC_SIGNED) { + ReferenceValue = Symbol.getValue(); + } } } } @@ -6071,19 +6093,6 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, bool symbolTableWorked = false; - // Parse relocations. - std::vector<std::pair<uint64_t, SymbolRef>> Relocs; - for (const RelocationRef &Reloc : Sections[SectIdx].relocations()) { - uint64_t RelocOffset = Reloc.getOffset(); - uint64_t SectionAddress = Sections[SectIdx].getAddress(); - RelocOffset -= SectionAddress; - - symbol_iterator RelocSym = Reloc.getSymbol(); - - Relocs.push_back(std::make_pair(RelocOffset, *RelocSym)); - } - array_pod_sort(Relocs.begin(), Relocs.end()); - // Create a map of symbol addresses to symbol names for use by // the SymbolizerSymbolLookUp() routine. SymbolAddressMap AddrMap; |