From 3d5fd2a768c5e5456d8ab19cab037490f4bdf8f9 Mon Sep 17 00:00:00 2001 From: Kevin Enderby Date: Sat, 10 Oct 2015 00:05:01 +0000 Subject: [PATCH] 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249921 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../malformed-machos/mem-crup-0337.macho | Bin 0 -> 9248 bytes test/tools/llvm-objdump/malformed-machos.test | 6 + tools/llvm-objdump/MachODump.cpp | 123 ++++++++++-------- 3 files changed, 72 insertions(+), 57 deletions(-) create mode 100644 test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0337.macho diff --git a/test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0337.macho b/test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0337.macho new file mode 100644 index 0000000000000000000000000000000000000000..cc438414f1121968f2508320693ca7aed318ce52 GIT binary patch literal 9248 zcmeHNO>7%Q6dpGX4I$7?;SivJgHjZr@usMa0#YSAKa~R^N#g_|P&M_>Cf;^`+}*Vr zBPv{#BBH305Bx}+5aQNL4_pu+D#3vp2RP(}dH@upBISTYRSC>{^J9 zkZw}1_Xr)Ofw2}e8;1FwKge|>qKU)^lla(As+dWk)DOxzU&1!~Rs~nMH^3*nhqLa0aHokWRU$m1cAi=!iV++l~TKX9|%7A`$^oHuk2hjodPwT6_?rD8ZRFUzO*1f z9G;`(#+*{4NLM^`9h2~Uw*=n+R};h-!=0oV$5W}Ll+sGZZ-*S?78c^tcr&)x=MzG1<4Lre&9$UZq$mJ9oQ!}5$3cpZfKHU*#b zA7Ygc)}Lt6GGD(8uK{EX^W6&ZAy)Z-WhcHuHpmKlTjOO*v|ixD6T~4tq2U?EF|Hv> zXJ_VKnx2}G@8mewH%1pYzMt1)oTzbkKj3jlxPEv&K4U~L`<`yO`K+Z|W=;=Gr!rEg zKrz9d~CFhJ~OxPCf zlJ7()w#fqY7gK7{JqifNx!(WUA76fb?9X?<$b7W)M0tD&>cFLh^!Bp!jKo+6(g*1* zB!dKBn*E{d)r`)mwzo+Rs3HE}*TKyHn^P$Gq zClx)=A^$j}20!^3kn}Tn7+i}hB9Rgf1}#c^zpucq)_&Z?#Dv=ODd>yyy%Xo}tfvJg z;D3~7Au)dd9%VJrBl1Axfye`q2O zapE!-uU*>S!o7a_%D38?Z|X-rh4SpR$KHo5m8l=O3VE#v5Axfu^?KcO%z)rti}GDo z^4M5%^ab2E02euo?LgEV_bT{}d>nF2tKxeI%ea5+gPt1e4FG5!Vi^?PSR}DEEvEGy z=&2!jNZu4Ya$hRdm!U8$lB~l#{GF-lb}HjO2#1y5yYjnIe(zU7*CP^S4UyxN*yg2C z-LW9~+y&}hc*P*i*pbSqsk^2z*<%h(Kw67Z1c8#e(DDH!!bkmUb8 zAfAJV#6JLzLy~eE3ULV_$Myw$2)P%^4?vRR9ftBjIJ1!FASVQt=OK%L;ZM$!m?8Xj z2!9yD*Ew$Z2aiX@QA-lbaiTB#a5ttecy3^1eSOOC&j)Ua-z?e?A+B=Cs4ItH340G+ zC(5Q(&}W>$@NA=CW&^`lm=igsUNkHi*-*w23Le`2h~s)TTzIaHkI}K?tQkLtOSoj@ t^=1^s@tE!mXb@;~mO->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> 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; -- 2.34.1