X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fllvm-objdump%2FMachODump.cpp;h=e0ec9cc172bc3de9212a79c0dfec725e43c7b7b5;hb=b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9;hp=313e763b2bc1bd04b4aea8a149b7ece9b8ea9239;hpb=49ca96d7c2b7ce10e42feb05cb0d9c7457518537;p=oota-llvm.git diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 313e763b2bc..e0ec9cc172b 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -12,12 +12,11 @@ //===----------------------------------------------------------------------===// #include "llvm-objdump.h" -#include "MCFunction.h" -#include "llvm/Support/MachO.h" -#include "llvm/Object/MachOObject.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/Triple.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Triple.h" +#include "llvm/DebugInfo/DIContext.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -25,11 +24,15 @@ #include "llvm/MC/MCInstrAnalysis.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Object/MachO.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Format.h" #include "llvm/Support/GraphWriter.h" +#include "llvm/Support/MachO.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" @@ -41,32 +44,19 @@ using namespace llvm; using namespace object; static cl::opt - CFG("cfg", cl::desc("Create a CFG for every symbol in the object file and" - "write it to a graphviz file (MachO-only)")); + UseDbg("g", cl::desc("Print line information from debug info if available")); + +static cl::opt + DSYMFile("dsym", cl::desc("Use .dSYM file for debug info")); -static const Target *GetTarget(const MachOObject *MachOObj) { +static const Target *GetTarget(const MachOObjectFile *MachOObj) { // Figure out the target triple. - llvm::Triple TT("unknown-unknown-unknown"); - switch (MachOObj->getHeader().CPUType) { - case llvm::MachO::CPUTypeI386: - TT.setArch(Triple::ArchType(Triple::x86)); - break; - case llvm::MachO::CPUTypeX86_64: - TT.setArch(Triple::ArchType(Triple::x86_64)); - break; - case llvm::MachO::CPUTypeARM: - TT.setArch(Triple::ArchType(Triple::arm)); - break; - case llvm::MachO::CPUTypePowerPC: - TT.setArch(Triple::ArchType(Triple::ppc)); - break; - case llvm::MachO::CPUTypePowerPC64: - TT.setArch(Triple::ArchType(Triple::ppc64)); - break; + if (TripleName.empty()) { + llvm::Triple TT("unknown-unknown-unknown"); + TT.setArch(Triple::ArchType(MachOObj->getArch())); + TripleName = TT.str(); } - TripleName = TT.str(); - // Get the target specific parser. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error); @@ -78,38 +68,137 @@ static const Target *GetTarget(const MachOObject *MachOObj) { return 0; } -struct Section { - char Name[16]; - uint64_t Address; - uint64_t Size; - uint32_t Offset; - uint32_t NumRelocs; - uint64_t RelocTableOffset; +struct SymbolSorter { + bool operator()(const SymbolRef &A, const SymbolRef &B) { + SymbolRef::Type AType, BType; + A.getType(AType); + B.getType(BType); + + uint64_t AAddr, BAddr; + if (AType != SymbolRef::ST_Function) + AAddr = 0; + else + A.getAddress(AAddr); + if (BType != SymbolRef::ST_Function) + BAddr = 0; + else + B.getAddress(BAddr); + return AAddr < BAddr; + } }; -struct Symbol { +// Types for the storted data in code table that is built before disassembly +// and the predicate function to sort them. +typedef std::pair DiceTableEntry; +typedef std::vector DiceTable; +typedef DiceTable::iterator dice_table_iterator; + +static bool +compareDiceTableEntries(const DiceTableEntry i, + const DiceTableEntry j) { + return i.first == j.first; +} + +static void DumpDataInCode(const char *bytes, uint64_t Size, + unsigned short Kind) { uint64_t Value; - uint32_t StringIndex; - uint8_t SectionIndex; - bool operator<(const Symbol &RHS) const { return Value < RHS.Value; } -}; -static void DumpAddress(uint64_t Address, ArrayRef
Sections, - MachOObject *MachOObj, raw_ostream &OS) { - for (unsigned i = 0; i != Sections.size(); ++i) { - uint64_t addr = Address-Sections[i].Address; - if (Sections[i].Address <= Address && - Sections[i].Address + Sections[i].Size > Address) { - StringRef bytes = MachOObj->getData(Sections[i].Offset, - Sections[i].Size); - if (!strcmp(Sections[i].Name, "__cstring")) - OS << '"' << bytes.substr(addr, bytes.find('\0', addr)) << '"'; - if (!strcmp(Sections[i].Name, "__cfstring")) - OS << "@\"" << bytes.substr(addr, bytes.find('\0', addr)) << '"'; + switch (Kind) { + case macho::Data: + switch (Size) { + case 4: + Value = bytes[3] << 24 | + bytes[2] << 16 | + bytes[1] << 8 | + bytes[0]; + outs() << "\t.long " << Value; + break; + case 2: + Value = bytes[1] << 8 | + bytes[0]; + outs() << "\t.short " << Value; + break; + case 1: + Value = bytes[0]; + outs() << "\t.byte " << Value; + break; + } + outs() << "\t@ KIND_DATA\n"; + break; + case macho::JumpTable8: + Value = bytes[0]; + outs() << "\t.byte " << Value << "\t@ KIND_JUMP_TABLE8"; + break; + case macho::JumpTable16: + Value = bytes[1] << 8 | + bytes[0]; + outs() << "\t.short " << Value << "\t@ KIND_JUMP_TABLE16"; + break; + case macho::JumpTable32: + Value = bytes[3] << 24 | + bytes[2] << 16 | + bytes[1] << 8 | + bytes[0]; + outs() << "\t.long " << Value << "\t@ KIND_JUMP_TABLE32"; + break; + default: + outs() << "\t@ data in code kind = " << Kind << "\n"; + break; + } +} + +static void +getSectionsAndSymbols(const macho::Header Header, + MachOObjectFile *MachOObj, + std::vector &Sections, + std::vector &Symbols, + SmallVectorImpl &FoundFns, + uint64_t &BaseSegmentAddress) { + error_code ec; + for (symbol_iterator SI = MachOObj->begin_symbols(), + SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec)) + Symbols.push_back(*SI); + + for (section_iterator SI = MachOObj->begin_sections(), + SE = MachOObj->end_sections(); SI != SE; SI.increment(ec)) { + SectionRef SR = *SI; + StringRef SectName; + SR.getName(SectName); + Sections.push_back(*SI); + } + + MachOObjectFile::LoadCommandInfo Command = + MachOObj->getFirstLoadCommandInfo(); + bool BaseSegmentAddressSet = false; + for (unsigned i = 0; ; ++i) { + if (Command.C.Type == macho::LCT_FunctionStarts) { + // We found a function starts segment, parse the addresses for later + // consumption. + macho::LinkeditDataLoadCommand LLC = + MachOObj->getLinkeditDataLoadCommand(Command); + + MachOObj->ReadULEB128s(LLC.DataOffset, FoundFns); + } + else if (Command.C.Type == macho::LCT_Segment) { + macho::SegmentLoadCommand SLC = + MachOObj->getSegmentLoadCommand(Command); + StringRef SegName = SLC.Name; + if(!BaseSegmentAddressSet && SegName != "__PAGEZERO") { + BaseSegmentAddressSet = true; + BaseSegmentAddress = SLC.VMAddress; + } } + + if (i == Header.NumLoadCommands - 1) + break; + else + Command = MachOObj->getNextLoadCommandInfo(Command); } } +static void DisassembleInputMachO2(StringRef Filename, + MachOObjectFile *MachOOF); + void llvm::DisassembleInputMachO(StringRef Filename) { OwningPtr Buff; @@ -118,144 +207,79 @@ void llvm::DisassembleInputMachO(StringRef Filename) { return; } - OwningPtr MachOObj(MachOObject::LoadFromBuffer(Buff.take())); + OwningPtr MachOOF(static_cast( + ObjectFile::createMachOObjectFile(Buff.take()))); - const Target *TheTarget = GetTarget(MachOObj.get()); + DisassembleInputMachO2(Filename, MachOOF.get()); +} + +static void DisassembleInputMachO2(StringRef Filename, + MachOObjectFile *MachOOF) { + const Target *TheTarget = GetTarget(MachOOF); if (!TheTarget) { // GetTarget prints out stuff. return; } - const MCInstrInfo *InstrInfo = TheTarget->createMCInstrInfo(); + OwningPtr InstrInfo(TheTarget->createMCInstrInfo()); OwningPtr - InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo)); + InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo.get())); // Set up disassembler. - OwningPtr AsmInfo(TheTarget->createMCAsmInfo(TripleName)); - - if (!AsmInfo) { - errs() << "error: no assembly info for target " << TripleName << "\n"; - return; - } - + OwningPtr MRI(TheTarget->createMCRegInfo(TripleName)); + OwningPtr AsmInfo( + TheTarget->createMCAsmInfo(*MRI, TripleName)); OwningPtr STI(TheTarget->createMCSubtargetInfo(TripleName, "", "")); - - if (!STI) { - errs() << "error: no subtarget info for target " << TripleName << "\n"; - return; - } - OwningPtr DisAsm(TheTarget->createMCDisassembler(*STI)); - if (!DisAsm) { - errs() << "error: no disassembler for target " << TripleName << "\n"; - return; - } - int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); - OwningPtr IP(TheTarget->createMCInstPrinter( - AsmPrinterVariant, *AsmInfo, *STI)); - if (!IP) { - errs() << "error: no instruction printer for target " << TripleName << '\n'; + OwningPtr + IP(TheTarget->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *InstrInfo, + *MRI, *STI)); + + if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) { + errs() << "error: couldn't initialize disassembler for target " + << TripleName << '\n'; return; } - outs() << '\n'; - outs() << Filename << ":\n\n"; - - const macho::Header &Header = MachOObj->getHeader(); - - const MachOObject::LoadCommandInfo *SymtabLCI = 0; - for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { - const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i); - switch (LCI.Command.Type) { - case macho::LCT_Symtab: - SymtabLCI = &LCI; - break; - } - } + outs() << '\n' << Filename << ":\n\n"; - // Read and register the symbol table data. - InMemoryStruct SymtabLC; - MachOObj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC); - MachOObj->RegisterStringTable(*SymtabLC); + macho::Header Header = MachOOF->getHeader(); - std::vector
Sections; - std::vector Symbols; - std::vector UnsortedSymbols; // FIXME: duplication + // FIXME: FoundFns isn't used anymore. Using symbols/LC_FUNCTION_STARTS to + // determine function locations will eventually go in MCObjectDisassembler. + // FIXME: Using the -cfg command line option, this code used to be able to + // annotate relocations with the referenced symbol's name, and if this was + // inside a __[cf]string section, the data it points to. This is now replaced + // by the upcoming MCSymbolizer, which needs the appropriate setup done above. + std::vector Sections; + std::vector Symbols; SmallVector FoundFns; + uint64_t BaseSegmentAddress; - for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { - const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i); - if (LCI.Command.Type == macho::LCT_Segment) { - InMemoryStruct SegmentLC; - MachOObj->ReadSegmentLoadCommand(LCI, SegmentLC); - - for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) { - InMemoryStruct Sect; - MachOObj->ReadSection(LCI, SectNum, Sect); - - Section S; - memcpy(S.Name, Sect->Name, 16); - S.Address = Sect->Address; - S.Size = Sect->Size; - S.Offset = Sect->Offset; - S.NumRelocs = Sect->NumRelocationTableEntries; - S.RelocTableOffset = Sect->RelocationTableOffset; - Sections.push_back(S); - - for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) { - InMemoryStruct STE; - MachOObj->ReadSymbolTableEntry(SymtabLC->SymbolTableOffset, i, STE); - - Symbol S; - S.StringIndex = STE->StringIndex; - S.SectionIndex = STE->SectionIndex; - S.Value = STE->Value; - Symbols.push_back(S); - UnsortedSymbols.push_back(Symbols.back()); - } - } - } else if (LCI.Command.Type == macho::LCT_Segment64) { - InMemoryStruct Segment64LC; - MachOObj->ReadSegment64LoadCommand(LCI, Segment64LC); - - for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) { - InMemoryStruct Sect64; - MachOObj->ReadSection64(LCI, SectNum, Sect64); - - Section S; - memcpy(S.Name, Sect64->Name, 16); - S.Address = Sect64->Address; - S.Size = Sect64->Size; - S.Offset = Sect64->Offset; - S.NumRelocs = Sect64->NumRelocationTableEntries; - S.RelocTableOffset = Sect64->RelocationTableOffset; - Sections.push_back(S); - - for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) { - InMemoryStruct STE; - MachOObj->ReadSymbol64TableEntry(SymtabLC->SymbolTableOffset, i, STE); - - Symbol S; - S.StringIndex = STE->StringIndex; - S.SectionIndex = STE->SectionIndex; - S.Value = STE->Value; - Symbols.push_back(S); - UnsortedSymbols.push_back(Symbols.back()); - } - } - } else if (LCI.Command.Type == macho::LCT_FunctionStarts) { - InMemoryStruct LLC; - MachOObj->ReadLinkeditDataLoadCommand(LCI, LLC); - - MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns); - } - } - - std::map FunctionMap; + getSectionsAndSymbols(Header, MachOOF, Sections, Symbols, FoundFns, + BaseSegmentAddress); + // Make a copy of the unsorted symbol list. FIXME: duplication + std::vector UnsortedSymbols(Symbols); // Sort the symbols by address, just in case they didn't come in that way. - array_pod_sort(Symbols.begin(), Symbols.end()); + std::sort(Symbols.begin(), Symbols.end(), SymbolSorter()); + + // Build a data in code table that is sorted on by the address of each entry. + uint64_t BaseAddress = 0; + if (Header.FileType == macho::HFT_Object) + Sections[0].getAddress(BaseAddress); + else + BaseAddress = BaseSegmentAddress; + DiceTable Dices; + error_code ec; + for (dice_iterator DI = MachOOF->begin_dices(), DE = MachOOF->end_dices(); + DI != DE; DI.increment(ec)){ + uint32_t Offset; + DI->getOffset(Offset); + Dices.push_back(std::make_pair(BaseAddress + Offset, *DI)); + } + array_pod_sort(Dices.begin(), Dices.end()); #ifndef NDEBUG raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls(); @@ -263,226 +287,182 @@ void llvm::DisassembleInputMachO(StringRef Filename) { raw_ostream &DebugOut = nulls(); #endif - SmallVector Functions; + OwningPtr diContext; + ObjectFile *DbgObj = MachOOF; + // Try to find debug info and set up the DIContext for it. + if (UseDbg) { + // A separate DSym file path was specified, parse it as a macho file, + // get the sections and supply it to the section name parsing machinery. + if (!DSYMFile.empty()) { + OwningPtr Buf; + if (error_code ec = MemoryBuffer::getFileOrSTDIN(DSYMFile, Buf)) { + errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n'; + return; + } + DbgObj = ObjectFile::createMachOObjectFile(Buf.take()); + } + + // Setup the DIContext + diContext.reset(DIContext::getDWARFContext(DbgObj)); + } for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) { - if (strcmp(Sections[SectIdx].Name, "__text")) + + bool SectIsText = false; + Sections[SectIdx].isText(SectIsText); + if (SectIsText == false) continue; - uint64_t VMAddr = Sections[SectIdx].Address - Sections[SectIdx].Offset; - for (unsigned i = 0, e = FoundFns.size(); i != e; ++i) - FunctionMap.insert(std::make_pair(FoundFns[i]+VMAddr, (MCFunction*)0)); + StringRef SectName; + if (Sections[SectIdx].getName(SectName) || + SectName != "__text") + continue; // Skip non-text sections + + DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl(); - StringRef Bytes = MachOObj->getData(Sections[SectIdx].Offset, - Sections[SectIdx].Size); + StringRef SegmentName = MachOOF->getSectionFinalSegmentName(DR); + if (SegmentName != "__TEXT") + continue; + + StringRef Bytes; + Sections[SectIdx].getContents(Bytes); StringRefMemoryObject memoryObject(Bytes); bool symbolTableWorked = false; - std::vector > Relocs; - for (unsigned j = 0; j != Sections[SectIdx].NumRelocs; ++j) { - InMemoryStruct RE; - MachOObj->ReadRelocationEntry(Sections[SectIdx].RelocTableOffset, j, RE); - Relocs.push_back(std::make_pair(RE->Word0, RE->Word1 & 0xffffff)); + // Parse relocations. + std::vector > Relocs; + error_code ec; + for (relocation_iterator RI = Sections[SectIdx].begin_relocations(), + RE = Sections[SectIdx].end_relocations(); RI != RE; RI.increment(ec)) { + uint64_t RelocOffset, SectionAddress; + RI->getOffset(RelocOffset); + Sections[SectIdx].getAddress(SectionAddress); + RelocOffset -= SectionAddress; + + symbol_iterator RelocSym = RI->getSymbol(); + + Relocs.push_back(std::make_pair(RelocOffset, *RelocSym)); } array_pod_sort(Relocs.begin(), Relocs.end()); + // Disassemble symbol by symbol. for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) { - if ((unsigned)Symbols[SymIdx].SectionIndex - 1 != SectIdx) - continue; - - uint64_t Start = Symbols[SymIdx].Value - Sections[SectIdx].Address; - uint64_t End = (SymIdx+1 == Symbols.size() || - Symbols[SymIdx].SectionIndex != Symbols[SymIdx+1].SectionIndex) ? - Sections[SectIdx].Size : - Symbols[SymIdx+1].Value - Sections[SectIdx].Address; - uint64_t Size; + StringRef SymName; + Symbols[SymIdx].getName(SymName); - if (Start >= End) + SymbolRef::Type ST; + Symbols[SymIdx].getType(ST); + if (ST != SymbolRef::ST_Function) continue; - symbolTableWorked = true; + // Make sure the symbol is defined in this section. + bool containsSym = false; + Sections[SectIdx].containsSymbol(Symbols[SymIdx], containsSym); + if (!containsSym) + continue; - if (!CFG) { - outs() << MachOObj->getStringAtIndex(Symbols[SymIdx].StringIndex) - << ":\n"; - for (uint64_t Index = Start; Index < End; Index += Size) { - MCInst Inst; - - if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, - DebugOut, nulls())) { - outs() << format("%8llx:\t", Sections[SectIdx].Address + Index); - DumpBytes(StringRef(Bytes.data() + Index, Size)); - IP->printInst(&Inst, outs(), ""); - outs() << "\n"; - } else { - errs() << "llvm-objdump: warning: invalid instruction encoding\n"; - if (Size == 0) - Size = 1; // skip illegible bytes - } + // Start at the address of the symbol relative to the section's address. + uint64_t SectionAddress = 0; + uint64_t Start = 0; + Sections[SectIdx].getAddress(SectionAddress); + Symbols[SymIdx].getAddress(Start); + Start -= SectionAddress; + + // Stop disassembling either at the beginning of the next symbol or at + // the end of the section. + bool containsNextSym = false; + uint64_t NextSym = 0; + uint64_t NextSymIdx = SymIdx+1; + while (Symbols.size() > NextSymIdx) { + SymbolRef::Type NextSymType; + Symbols[NextSymIdx].getType(NextSymType); + if (NextSymType == SymbolRef::ST_Function) { + Sections[SectIdx].containsSymbol(Symbols[NextSymIdx], + containsNextSym); + Symbols[NextSymIdx].getAddress(NextSym); + NextSym -= SectionAddress; + break; } - } else { - // Create CFG and use it for disassembly. - SmallVector Calls; - MCFunction f = - MCFunction::createFunctionFromMC( - MachOObj->getStringAtIndex(Symbols[SymIdx].StringIndex), - DisAsm.get(), - memoryObject, Start, End, - InstrAnalysis.get(), DebugOut, - Calls); - - Functions.push_back(f); - FunctionMap[Start] = &Functions.back(); - - for (unsigned i = 0, e = Calls.size(); i != e; ++i) - FunctionMap.insert(std::make_pair(Calls[i], (MCFunction*)0)); + ++NextSymIdx; } - } - if (CFG) { - if (!symbolTableWorked) { - // Create CFG and use it for disassembly. - SmallVector Calls; - MCFunction f = - MCFunction::createFunctionFromMC("__TEXT", DisAsm.get(), - memoryObject, 0, Sections[SectIdx].Size, - InstrAnalysis.get(), DebugOut, - Calls); - - Functions.push_back(f); - FunctionMap[Sections[SectIdx].Offset] = &Functions.back(); - - for (unsigned i = 0, e = Calls.size(); i != e; ++i) - FunctionMap.insert(std::make_pair(Calls[i], (MCFunction*)0)); - } - for (std::map::iterator mi = FunctionMap.begin(), - me = FunctionMap.end(); mi != me; ++mi) - if (mi->second == 0) { - SmallVector Calls; - MCFunction f = - MCFunction::createFunctionFromMC("unknown", DisAsm.get(), - memoryObject, mi->first, - Sections[SectIdx].Size, - InstrAnalysis.get(), DebugOut, - Calls); - Functions.push_back(f); - mi->second = &Functions.back(); - for (unsigned i = 0, e = Calls.size(); i != e; ++i) - if (FunctionMap.insert(std::pair(Calls[i],0)) - .second) - mi = FunctionMap.begin(); - } - - DenseSet PrintedBlocks; - for (unsigned ffi = 0, ffe = Functions.size(); ffi != ffe; ++ffi) { - MCFunction &f = Functions[ffi]; - for (MCFunction::iterator fi = f.begin(), fe = f.end(); fi != fe; ++fi){ - if (!PrintedBlocks.insert(fi->first).second) - continue; - bool hasPreds = FunctionMap.find(fi->first) != FunctionMap.end(); - - // Only print blocks that have predecessors. - // FIXME: Slow. - for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe; - ++pi) - if (pi->second.contains(fi->first)) { - hasPreds = true; - break; - } - - // Data block. - if (!hasPreds && fi != f.begin()) { - uint64_t End = llvm::next(fi) == fe ? Sections[SectIdx].Size : - llvm::next(fi)->first; - outs() << "# " << End-fi->first << " bytes of data:\n"; - for (unsigned pos = fi->first; pos != End; ++pos) { - outs() << format("%8x:\t", Sections[SectIdx].Address + pos); - DumpBytes(StringRef(Bytes.data() + pos, 1)); - outs() << format("\t.byte 0x%02x\n", (uint8_t)Bytes[pos]); - } - continue; - } + uint64_t SectSize; + Sections[SectIdx].getSize(SectSize); + uint64_t End = containsNextSym ? NextSym : SectSize; + uint64_t Size; - if (fi->second.contains(fi->first)) - outs() << "# Loop begin:\n"; - - for (unsigned ii = 0, ie = fi->second.getInsts().size(); ii != ie; - ++ii) { - const MCDecodedInst &Inst = fi->second.getInsts()[ii]; - if (FunctionMap.find(Sections[SectIdx].Address + Inst.Address) != - FunctionMap.end()) - outs() << FunctionMap[Sections[SectIdx].Address + Inst.Address]-> - getName() << ":\n"; - outs() << format("%8llx:\t", Sections[SectIdx].Address + - Inst.Address); - DumpBytes(StringRef(Bytes.data() + Inst.Address, Inst.Size)); - // Simple loops. - if (fi->second.contains(fi->first)) - outs() << '\t'; - IP->printInst(&Inst.Inst, outs(), ""); - for (unsigned j = 0; j != Relocs.size(); ++j) - if (Relocs[j].first >= Sections[SectIdx].Address + Inst.Address && - Relocs[j].first < Sections[SectIdx].Address + Inst.Address + - Inst.Size) { - outs() << "\t# " - << MachOObj->getStringAtIndex( - UnsortedSymbols[Relocs[j].second].StringIndex) - << ' '; - DumpAddress(UnsortedSymbols[Relocs[j].second].Value, Sections, - MachOObj.get(), outs()); - } - uint64_t targ = InstrAnalysis->evaluateBranch(Inst.Inst, - Inst.Address, - Inst.Size); - if (targ != -1ULL) - DumpAddress(targ, Sections, MachOObj.get(), outs()); - - outs() << '\n'; - } - } + symbolTableWorked = true; - // Start a new dot file. - std::string Error; - raw_fd_ostream Out((f.getName().str() + ".dot").c_str(), Error); - if (!Error.empty()) { - errs() << "llvm-objdump: warning: " << Error << '\n'; + outs() << SymName << ":\n"; + DILineInfo lastLine; + for (uint64_t Index = Start; Index < End; Index += Size) { + MCInst Inst; + + uint64_t SectAddress = 0; + Sections[SectIdx].getAddress(SectAddress); + outs() << format("%8" PRIx64 ":\t", SectAddress + Index); + + // 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(SectAddress + Index, 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); + DumpBytes(StringRef(Bytes.data() + Index, Length)); + uint16_t Kind; + DTI->second.getKind(Kind); + DumpDataInCode(Bytes.data() + Index, Length, Kind); continue; } - Out << "digraph " << f.getName() << " {\n"; - Out << "graph [ rankdir = \"LR\" ];\n"; - for (MCFunction::iterator i = f.begin(), e = f.end(); i != e; ++i) { - bool hasPreds = false; - // Only print blocks that have predecessors. - // FIXME: Slow. - for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe; - ++pi) - if (pi->second.contains(i->first)) { - hasPreds = true; - break; - } - - if (!hasPreds && i != f.begin()) - continue; - - Out << '"' << i->first << "\" [ label=\""; - // Print instructions. - for (unsigned ii = 0, ie = i->second.getInsts().size(); ii != ie; - ++ii) { - // Escape special chars and print the instruction in mnemonic form. - std::string Str; - raw_string_ostream OS(Str); - IP->printInst(&i->second.getInsts()[ii].Inst, OS, ""); - Out << DOT::EscapeString(OS.str()) << '|'; + if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, + DebugOut, nulls())) { + DumpBytes(StringRef(Bytes.data() + Index, Size)); + IP->printInst(&Inst, outs(), ""); + + // Print debug info. + if (diContext) { + DILineInfo dli = + diContext->getLineInfoForAddress(SectAddress + Index); + // Print valid line info if it changed. + if (dli != lastLine && dli.getLine() != 0) + outs() << "\t## " << dli.getFileName() << ':' + << dli.getLine() << ':' << dli.getColumn(); + lastLine = dli; } - Out << "\" shape=\"record\" ];\n"; - - // Add edges. - for (MCBasicBlock::succ_iterator si = i->second.succ_begin(), - se = i->second.succ_end(); si != se; ++si) - Out << i->first << ":o -> " << *si <<":a\n"; + outs() << "\n"; + } else { + errs() << "llvm-objdump: warning: invalid instruction encoding\n"; + if (Size == 0) + Size = 1; // skip illegible bytes + } + } + } + if (!symbolTableWorked) { + // Reading the symbol table didn't work, disassemble the whole section. + uint64_t SectAddress; + Sections[SectIdx].getAddress(SectAddress); + uint64_t SectSize; + Sections[SectIdx].getSize(SectSize); + uint64_t InstSize; + for (uint64_t Index = 0; Index < SectSize; Index += InstSize) { + MCInst Inst; + + if (DisAsm->getInstruction(Inst, InstSize, memoryObject, Index, + DebugOut, nulls())) { + outs() << format("%8" PRIx64 ":\t", SectAddress + Index); + DumpBytes(StringRef(Bytes.data() + Index, InstSize)); + IP->printInst(&Inst, outs(), ""); + outs() << "\n"; + } else { + errs() << "llvm-objdump: warning: invalid instruction encoding\n"; + if (InstSize == 0) + InstSize = 1; // skip illegible bytes } - Out << "}\n"; } } }