From: Kuba Mracek Date: Thu, 1 Aug 2019 15:51:14 +0000 (+0000) Subject: [llvm-objdump] Fix jumptable detection when disassembling Mach-O binaries X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bc12e135d9b18aafb615201d6ce22c9f2504a0a1;p=llvm [llvm-objdump] Fix jumptable detection when disassembling Mach-O binaries - Add LC_SEGMENT_64 handling in getSectionsAndSymbols to be able to find the base segment address from 64-bit Mach-O binaries. - Add "data in code" detection into the !symbolTableWorked case, extract it into a separate function. - Fix uninitialized variable usage on BaseSegmentAddress (initialize to 0). - Add test. Differential Revision: https://reviews.llvm.org/D65491 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367578 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/tools/llvm-objdump/macho-data-in-code.ll b/test/tools/llvm-objdump/macho-data-in-code.ll new file mode 100644 index 00000000000..57877da09f3 --- /dev/null +++ b/test/tools/llvm-objdump/macho-data-in-code.ll @@ -0,0 +1,45 @@ +; RUN: llc -mtriple x86_64-apple-darwin -filetype=obj -O0 %s -o %t.o +; RUN: llvm-objdump -macho -disassemble -no-show-raw-insn %t.o | FileCheck %s + +; CHECK: .long {{[0-9]+}} @ KIND_JUMP_TABLE32 +; CHECK: .long {{[0-9]+}} @ KIND_JUMP_TABLE32 +; CHECK: .long {{[0-9]+}} @ KIND_JUMP_TABLE32 +; CHECK: .long {{[0-9]+}} @ KIND_JUMP_TABLE32 +; CHECK-NOT: invalid instruction encoding +; CHECK-NOT: + +; ModuleID = '-' +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.12.0" + +; Function Attrs: noinline nounwind optnone ssp uwtable +define void @switchfunc(i32 %i) { + switch i32 %i, label %out [ + i32 0, label %case1 + i32 1, label %case2 + i32 2, label %case3 + i32 3, label %case4 + ] + +case1: + call void @foo() + br label %out + +case2: + call void @bar() + br label %out + +case3: + call void @foo() + br label %out + +case4: + call void @bar() + br label %out + +out: + ret void +} + +declare void @foo() +declare void @bar() diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 58ff7be4543..a3f3a9df4c1 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -393,10 +393,40 @@ static void getSectionsAndSymbols(MachOObjectFile *MachOObj, BaseSegmentAddressSet = true; BaseSegmentAddress = SLC.vmaddr; } + } else if (Command.C.cmd == MachO::LC_SEGMENT_64) { + MachO::segment_command_64 SLC = MachOObj->getSegment64LoadCommand(Command); + StringRef SegName = SLC.segname; + if (!BaseSegmentAddressSet && SegName != "__PAGEZERO") { + BaseSegmentAddressSet = true; + BaseSegmentAddress = SLC.vmaddr; + } } } } +static bool DumpAndSkipDataInCode(uint64_t PC, const uint8_t *bytes, + DiceTable &Dices, uint64_t &InstSize) { + // Check the data in code table here to see if this is data not an + // instruction to be disassembled. + DiceTable Dice; + Dice.push_back(std::make_pair(PC, DiceRef())); + dice_table_iterator DTI = + std::search(Dices.begin(), Dices.end(), Dice.begin(), Dice.end(), + compareDiceTableEntries); + if (DTI != Dices.end()) { + uint16_t Length; + DTI->second.getLength(Length); + uint16_t Kind; + DTI->second.getKind(Kind); + InstSize = DumpDataInCode(bytes, Length, Kind); + if ((Kind == MachO::DICE_KIND_JUMP_TABLE8) && + (PC == (DTI->first + Length - 1)) && (Length & 1)) + InstSize++; + return true; + } + return false; +} + static void printRelocationTargetName(const MachOObjectFile *O, const MachO::any_relocation_info &RE, raw_string_ostream &Fmt) { @@ -7203,7 +7233,7 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, std::vector Sections; std::vector Symbols; SmallVector FoundFns; - uint64_t BaseSegmentAddress; + uint64_t BaseSegmentAddress = 0; getSectionsAndSymbols(MachOOF, Sections, Symbols, FoundFns, BaseSegmentAddress); @@ -7496,24 +7526,8 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, if (!NoShowRawInsn || Arch == Triple::arm) outs() << "\t"; - // Check the data in code table here to see if this is data not an - // instruction to be disassembled. - DiceTable Dice; - Dice.push_back(std::make_pair(PC, DiceRef())); - dice_table_iterator DTI = - std::search(Dices.begin(), Dices.end(), Dice.begin(), Dice.end(), - compareDiceTableEntries); - if (DTI != Dices.end()) { - uint16_t Length; - DTI->second.getLength(Length); - uint16_t Kind; - DTI->second.getKind(Kind); - Size = DumpDataInCode(Bytes.data() + Index, Length, Kind); - if ((Kind == MachO::DICE_KIND_JUMP_TABLE8) && - (PC == (DTI->first + Length - 1)) && (Length & 1)) - Size++; + if (DumpAndSkipDataInCode(PC, Bytes.data() + Index, Dices, Size)) continue; - } SmallVector AnnotationsBytes; raw_svector_ostream Annotations(AnnotationsBytes); @@ -7588,6 +7602,10 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, MCInst Inst; uint64_t PC = SectAddress + Index; + + if (DumpAndSkipDataInCode(PC, Bytes.data() + Index, Dices, InstSize)) + continue; + SmallVector AnnotationsBytes; raw_svector_ostream Annotations(AnnotationsBytes); if (DisAsm->getInstruction(Inst, InstSize, Bytes.slice(Index), PC,