summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/llvm-objdump/MachODump.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2014-03-21 17:53:59 +0000
committerdim <dim@FreeBSD.org>2014-03-21 17:53:59 +0000
commit9cedb8bb69b89b0f0c529937247a6a80cabdbaec (patch)
treec978f0e9ec1ab92dc8123783f30b08a7fd1e2a39 /contrib/llvm/tools/llvm-objdump/MachODump.cpp
parent03fdc2934eb61c44c049a02b02aa974cfdd8a0eb (diff)
downloadFreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.zip
FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.tar.gz
MFC 261991:
Upgrade our copy of llvm/clang to 3.4 release. This version supports all of the features in the current working draft of the upcoming C++ standard, provisionally named C++1y. The code generator's performance is greatly increased, and the loop auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The PowerPC backend has made several major improvements to code generation quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ backends have all seen major feature work. Release notes for llvm and clang can be found here: <http://llvm.org/releases/3.4/docs/ReleaseNotes.html> <http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html> MFC 262121 (by emaste): Update lldb for clang/llvm 3.4 import This commit largely restores the lldb source to the upstream r196259 snapshot with the addition of threaded inferior support and a few bug fixes. Specific upstream lldb revisions restored include: SVN git 181387 779e6ac 181703 7bef4e2 182099 b31044e 182650 f2dcf35 182683 0d91b80 183862 15c1774 183929 99447a6 184177 0b2934b 184948 4dc3761 184954 007e7bc 186990 eebd175 Sponsored by: DARPA, AFRL MFC 262186 (by emaste): Fix mismerge in r262121 A break statement was lost in the merge. The error had no functional impact, but restore it to reduce the diff against upstream. MFC 262303: Pull in r197521 from upstream clang trunk (by rdivacky): Use the integrated assembler by default on FreeBSD/ppc and ppc64. Requested by: jhibbits MFC 262611: Pull in r196874 from upstream llvm trunk: Fix a crash that occurs when PWD is invalid. MCJIT needs to be able to run in hostile environments, even when PWD is invalid. There's no need to crash MCJIT in this case. The obvious fix is to simply leave MCContext's CompilationDir empty when PWD can't be determined. This way, MCJIT clients, and other clients that link with LLVM don't need a valid working directory. If we do want to guarantee valid CompilationDir, that should be done only for clients of getCompilationDir(). This is as simple as checking for an empty string. The only current use of getCompilationDir is EmitGenDwarfInfo, which won't conceivably run with an invalid working dir. However, in the purely hypothetically and untestable case that this happens, the AT_comp_dir will be omitted from the compilation_unit DIE. This should help fix assertions occurring with ports-mgmt/tinderbox, when it is using jails, and sometimes invalidates clang's current working directory. Reported by: decke MFC 262809: Pull in r203007 from upstream clang trunk: Don't produce an alias between destructors with different calling conventions. Fixes pr19007. (Please note that is an LLVM PR identifier, not a FreeBSD one.) This should fix Firefox and/or libxul crashes (due to problems with regparm/stdcall calling conventions) on i386. Reported by: multiple users on freebsd-current PR: bin/187103 MFC 263048: Repair recognition of "CC" as an alias for the C++ compiler, since it was silently broken by upstream for a Windows-specific use-case. Apparently some versions of CMake still rely on this archaic feature... Reported by: rakuco MFC 263049: Garbage collect the old way of adding the libstdc++ include directories in clang's InitHeaderSearch.cpp. This has been superseded by David Chisnall's commit in r255321. Moreover, if libc++ is used, the libstdc++ include directories should not be in the search path at all. These directories are now only used if you pass -stdlib=libstdc++.
Diffstat (limited to 'contrib/llvm/tools/llvm-objdump/MachODump.cpp')
-rw-r--r--contrib/llvm/tools/llvm-objdump/MachODump.cpp456
1 files changed, 156 insertions, 300 deletions
diff --git a/contrib/llvm/tools/llvm-objdump/MachODump.cpp b/contrib/llvm/tools/llvm-objdump/MachODump.cpp
index 6797e2d..86923fd 100644
--- a/contrib/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/contrib/llvm/tools/llvm-objdump/MachODump.cpp
@@ -12,9 +12,9 @@
//===----------------------------------------------------------------------===//
#include "llvm-objdump.h"
-#include "MCFunction.h"
#include "llvm/ADT/OwningPtr.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"
@@ -44,10 +44,6 @@ using namespace llvm;
using namespace object;
static cl::opt<bool>
- CFG("cfg", cl::desc("Create a CFG for every symbol in the object file and"
- " write it to a graphviz file (MachO-only)"));
-
-static cl::opt<bool>
UseDbg("g", cl::desc("Print line information from debug info if available"));
static cl::opt<std::string>
@@ -91,105 +87,73 @@ struct SymbolSorter {
}
};
-// Print additional information about an address, if available.
-static void DumpAddress(uint64_t Address, ArrayRef<SectionRef> Sections,
- const MachOObjectFile *MachOObj, raw_ostream &OS) {
- for (unsigned i = 0; i != Sections.size(); ++i) {
- uint64_t SectAddr = 0, SectSize = 0;
- Sections[i].getAddress(SectAddr);
- Sections[i].getSize(SectSize);
- uint64_t addr = SectAddr;
- if (SectAddr <= Address &&
- SectAddr + SectSize > Address) {
- StringRef bytes, name;
- Sections[i].getContents(bytes);
- Sections[i].getName(name);
- // Print constant strings.
- if (!name.compare("__cstring"))
- OS << '"' << bytes.substr(addr, bytes.find('\0', addr)) << '"';
- // Print constant CFStrings.
- if (!name.compare("__cfstring"))
- OS << "@\"" << bytes.substr(addr, bytes.find('\0', addr)) << '"';
- }
- }
-}
+// Types for the storted data in code table that is built before disassembly
+// and the predicate function to sort them.
+typedef std::pair<uint64_t, DiceRef> DiceTableEntry;
+typedef std::vector<DiceTableEntry> DiceTable;
+typedef DiceTable::iterator dice_table_iterator;
-typedef std::map<uint64_t, MCFunction*> FunctionMapTy;
-typedef SmallVector<MCFunction, 16> FunctionListTy;
-static void createMCFunctionAndSaveCalls(StringRef Name,
- const MCDisassembler *DisAsm,
- MemoryObject &Object, uint64_t Start,
- uint64_t End,
- MCInstrAnalysis *InstrAnalysis,
- uint64_t Address,
- raw_ostream &DebugOut,
- FunctionMapTy &FunctionMap,
- FunctionListTy &Functions) {
- SmallVector<uint64_t, 16> Calls;
- MCFunction f =
- MCFunction::createFunctionFromMC(Name, DisAsm, Object, Start, End,
- InstrAnalysis, DebugOut, Calls);
- Functions.push_back(f);
- FunctionMap[Address] = &Functions.back();
-
- // Add the gathered callees to the map.
- for (unsigned i = 0, e = Calls.size(); i != e; ++i)
- FunctionMap.insert(std::make_pair(Calls[i], (MCFunction*)0));
+static bool
+compareDiceTableEntries(const DiceTableEntry i,
+ const DiceTableEntry j) {
+ return i.first == j.first;
}
-// Write a graphviz file for the CFG inside an MCFunction.
-static void emitDOTFile(const char *FileName, const MCFunction &f,
- MCInstPrinter *IP) {
- // Start a new dot file.
- std::string Error;
- raw_fd_ostream Out(FileName, Error);
- if (!Error.empty()) {
- errs() << "llvm-objdump: warning: " << Error << '\n';
- return;
- }
-
- 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=\"<a>";
- // 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()) << '|';
+static void DumpDataInCode(const char *bytes, uint64_t Size,
+ unsigned short Kind) {
+ uint64_t Value;
+
+ switch (Kind) {
+ case MachO::DICE_KIND_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;
}
- Out << "<o>\" 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() << "\t@ KIND_DATA\n";
+ break;
+ case MachO::DICE_KIND_JUMP_TABLE8:
+ Value = bytes[0];
+ outs() << "\t.byte " << Value << "\t@ KIND_JUMP_TABLE8";
+ break;
+ case MachO::DICE_KIND_JUMP_TABLE16:
+ Value = bytes[1] << 8 |
+ bytes[0];
+ outs() << "\t.short " << Value << "\t@ KIND_JUMP_TABLE16";
+ break;
+ case MachO::DICE_KIND_JUMP_TABLE32:
+ 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;
}
- Out << "}\n";
}
static void
-getSectionsAndSymbols(const macho::Header Header,
+getSectionsAndSymbols(const MachO::mach_header Header,
MachOObjectFile *MachOObj,
std::vector<SectionRef> &Sections,
std::vector<SymbolRef> &Symbols,
- SmallVectorImpl<uint64_t> &FoundFns) {
+ SmallVectorImpl<uint64_t> &FoundFns,
+ uint64_t &BaseSegmentAddress) {
error_code ec;
for (symbol_iterator SI = MachOObj->begin_symbols(),
SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec))
@@ -205,17 +169,27 @@ getSectionsAndSymbols(const macho::Header Header,
MachOObjectFile::LoadCommandInfo Command =
MachOObj->getFirstLoadCommandInfo();
+ bool BaseSegmentAddressSet = false;
for (unsigned i = 0; ; ++i) {
- if (Command.C.Type == macho::LCT_FunctionStarts) {
+ if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) {
// We found a function starts segment, parse the addresses for later
// consumption.
- macho::LinkeditDataLoadCommand LLC =
+ MachO::linkedit_data_command LLC =
MachOObj->getLinkeditDataLoadCommand(Command);
- MachOObj->ReadULEB128s(LLC.DataOffset, FoundFns);
+ MachOObj->ReadULEB128s(LLC.dataoff, FoundFns);
+ }
+ else if (Command.C.cmd == MachO::LC_SEGMENT) {
+ MachO::segment_command SLC =
+ MachOObj->getSegmentLoadCommand(Command);
+ StringRef SegName = SLC.segname;
+ if(!BaseSegmentAddressSet && SegName != "__PAGEZERO") {
+ BaseSegmentAddressSet = true;
+ BaseSegmentAddress = SLC.vmaddr;
+ }
}
- if (i == Header.NumLoadCommands - 1)
+ if (i == Header.ncmds - 1)
break;
else
Command = MachOObj->getNextLoadCommandInfo(Command);
@@ -251,11 +225,12 @@ static void DisassembleInputMachO2(StringRef Filename,
InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo.get()));
// Set up disassembler.
- OwningPtr<const MCAsmInfo> AsmInfo(TheTarget->createMCAsmInfo(TripleName));
+ OwningPtr<const MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
+ OwningPtr<const MCAsmInfo> AsmInfo(
+ TheTarget->createMCAsmInfo(*MRI, TripleName));
OwningPtr<const MCSubtargetInfo>
STI(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
- OwningPtr<const MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
OwningPtr<MCInstPrinter>
IP(TheTarget->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *InstrInfo,
@@ -269,19 +244,41 @@ static void DisassembleInputMachO2(StringRef Filename,
outs() << '\n' << Filename << ":\n\n";
- macho::Header Header = MachOOF->getHeader();
+ MachO::mach_header Header = MachOOF->getHeader();
+ // 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<SectionRef> Sections;
std::vector<SymbolRef> Symbols;
SmallVector<uint64_t, 8> FoundFns;
+ uint64_t BaseSegmentAddress;
- getSectionsAndSymbols(Header, MachOOF, Sections, Symbols, FoundFns);
+ getSectionsAndSymbols(Header, MachOOF, Sections, Symbols, FoundFns,
+ BaseSegmentAddress);
- // Make a copy of the unsorted symbol list. FIXME: duplication
- std::vector<SymbolRef> UnsortedSymbols(Symbols);
// Sort the symbols by address, just in case they didn't come in that way.
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::MH_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();
#else
@@ -296,7 +293,7 @@ static void DisassembleInputMachO2(StringRef Filename,
// get the sections and supply it to the section name parsing machinery.
if (!DSYMFile.empty()) {
OwningPtr<MemoryBuffer> Buf;
- if (error_code ec = MemoryBuffer::getFileOrSTDIN(DSYMFile.c_str(), Buf)) {
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(DSYMFile, Buf)) {
errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n';
return;
}
@@ -307,31 +304,24 @@ static void DisassembleInputMachO2(StringRef Filename,
diContext.reset(DIContext::getDWARFContext(DbgObj));
}
- FunctionMapTy FunctionMap;
- FunctionListTy Functions;
-
for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {
+
+ bool SectIsText = false;
+ Sections[SectIdx].isText(SectIsText);
+ if (SectIsText == false)
+ continue;
+
StringRef SectName;
if (Sections[SectIdx].getName(SectName) ||
SectName != "__text")
continue; // Skip non-text sections
DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl();
+
StringRef SegmentName = MachOOF->getSectionFinalSegmentName(DR);
if (SegmentName != "__TEXT")
continue;
- // Insert the functions from the function starts segment into our map.
- uint64_t VMAddr;
- Sections[SectIdx].getAddress(VMAddr);
- for (unsigned i = 0, e = FoundFns.size(); i != e; ++i) {
- StringRef SectBegin;
- Sections[SectIdx].getContents(SectBegin);
- uint64_t Offset = (uint64_t)SectBegin.data();
- FunctionMap.insert(std::make_pair(VMAddr + FoundFns[i]-Offset,
- (MCFunction*)0));
- }
-
StringRef Bytes;
Sections[SectIdx].getContents(Bytes);
StringRefMemoryObject memoryObject(Bytes);
@@ -347,10 +337,9 @@ static void DisassembleInputMachO2(StringRef Filename,
Sections[SectIdx].getAddress(SectionAddress);
RelocOffset -= SectionAddress;
- SymbolRef RelocSym;
- RI->getSymbol(RelocSym);
+ symbol_iterator RelocSym = RI->getSymbol();
- Relocs.push_back(std::make_pair(RelocOffset, RelocSym));
+ Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
}
array_pod_sort(Relocs.begin(), Relocs.end());
@@ -402,52 +391,56 @@ static void DisassembleInputMachO2(StringRef Filename,
symbolTableWorked = true;
- if (!CFG) {
- // Normal disassembly, print addresses, bytes and mnemonic form.
- StringRef SymName;
- Symbols[SymIdx].getName(SymName);
-
- outs() << SymName << ":\n";
- DILineInfo lastLine;
- for (uint64_t Index = Start; Index < End; Index += Size) {
- MCInst Inst;
-
- if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
- DebugOut, nulls())) {
- uint64_t SectAddress = 0;
- Sections[SectIdx].getAddress(SectAddress);
- outs() << format("%8" PRIx64 ":\t", SectAddress + Index);
-
- 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;
- }
- outs() << "\n";
- } else {
- errs() << "llvm-objdump: warning: invalid instruction encoding\n";
- if (Size == 0)
- Size = 1; // skip illegible bytes
+ 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;
+ }
+
+ 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;
}
+ outs() << "\n";
+ } else {
+ errs() << "llvm-objdump: warning: invalid instruction encoding\n";
+ if (Size == 0)
+ Size = 1; // skip illegible bytes
}
- } else {
- // Create CFG and use it for disassembly.
- StringRef SymName;
- Symbols[SymIdx].getName(SymName);
- createMCFunctionAndSaveCalls(
- SymName, DisAsm.get(), memoryObject, Start, End,
- InstrAnalysis.get(), Start, DebugOut, FunctionMap, Functions);
}
}
- if (!CFG && !symbolTableWorked) {
+ if (!symbolTableWorked) {
// Reading the symbol table didn't work, disassemble the whole section.
uint64_t SectAddress;
Sections[SectIdx].getAddress(SectAddress);
@@ -470,142 +463,5 @@ static void DisassembleInputMachO2(StringRef Filename,
}
}
}
-
- if (CFG) {
- if (!symbolTableWorked) {
- // Reading the symbol table didn't work, create a big __TEXT symbol.
- uint64_t SectSize = 0, SectAddress = 0;
- Sections[SectIdx].getSize(SectSize);
- Sections[SectIdx].getAddress(SectAddress);
- createMCFunctionAndSaveCalls("__TEXT", DisAsm.get(), memoryObject,
- 0, SectSize,
- InstrAnalysis.get(),
- SectAddress, DebugOut,
- FunctionMap, Functions);
- }
- for (std::map<uint64_t, MCFunction*>::iterator mi = FunctionMap.begin(),
- me = FunctionMap.end(); mi != me; ++mi)
- if (mi->second == 0) {
- // Create functions for the remaining callees we have gathered,
- // but we didn't find a name for them.
- uint64_t SectSize = 0;
- Sections[SectIdx].getSize(SectSize);
-
- SmallVector<uint64_t, 16> Calls;
- MCFunction f =
- MCFunction::createFunctionFromMC("unknown", DisAsm.get(),
- memoryObject, mi->first,
- SectSize,
- InstrAnalysis.get(), DebugOut,
- Calls);
- Functions.push_back(f);
- mi->second = &Functions.back();
- for (unsigned i = 0, e = Calls.size(); i != e; ++i) {
- std::pair<uint64_t, MCFunction*> p(Calls[i], (MCFunction*)0);
- if (FunctionMap.insert(p).second)
- mi = FunctionMap.begin();
- }
- }
-
- DenseSet<uint64_t> 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; // We already printed this block.
-
- // We assume a block has predecessors when it's the first block after
- // a symbol.
- bool hasPreds = FunctionMap.find(fi->first) != FunctionMap.end();
-
- // See if this block has predecessors.
- // FIXME: Slow.
- for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe;
- ++pi)
- if (pi->second.contains(fi->first)) {
- hasPreds = true;
- break;
- }
-
- uint64_t SectSize = 0, SectAddress;
- Sections[SectIdx].getSize(SectSize);
- Sections[SectIdx].getAddress(SectAddress);
-
- // No predecessors, this is a data block. Print as .byte directives.
- if (!hasPreds) {
- uint64_t End = llvm::next(fi) == fe ? SectSize :
- llvm::next(fi)->first;
- outs() << "# " << End-fi->first << " bytes of data:\n";
- for (unsigned pos = fi->first; pos != End; ++pos) {
- outs() << format("%8x:\t", SectAddress + pos);
- DumpBytes(StringRef(Bytes.data() + pos, 1));
- outs() << format("\t.byte 0x%02x\n", (uint8_t)Bytes[pos]);
- }
- continue;
- }
-
- if (fi->second.contains(fi->first)) // Print a header for simple loops
- outs() << "# Loop begin:\n";
-
- DILineInfo lastLine;
- // Walk over the instructions and print them.
- for (unsigned ii = 0, ie = fi->second.getInsts().size(); ii != ie;
- ++ii) {
- const MCDecodedInst &Inst = fi->second.getInsts()[ii];
-
- // If there's a symbol at this address, print its name.
- if (FunctionMap.find(SectAddress + Inst.Address) !=
- FunctionMap.end())
- outs() << FunctionMap[SectAddress + Inst.Address]-> getName()
- << ":\n";
-
- outs() << format("%8" PRIx64 ":\t", SectAddress + Inst.Address);
- DumpBytes(StringRef(Bytes.data() + Inst.Address, Inst.Size));
-
- if (fi->second.contains(fi->first)) // Indent simple loops.
- outs() << '\t';
-
- IP->printInst(&Inst.Inst, outs(), "");
-
- // Look for relocations inside this instructions, if there is one
- // print its target and additional information if available.
- for (unsigned j = 0; j != Relocs.size(); ++j)
- if (Relocs[j].first >= SectAddress + Inst.Address &&
- Relocs[j].first < SectAddress + Inst.Address + Inst.Size) {
- StringRef SymName;
- uint64_t Addr;
- Relocs[j].second.getAddress(Addr);
- Relocs[j].second.getName(SymName);
-
- outs() << "\t# " << SymName << ' ';
- DumpAddress(Addr, Sections, MachOOF, outs());
- }
-
- // If this instructions contains an address, see if we can evaluate
- // it and print additional information.
- uint64_t targ = InstrAnalysis->evaluateBranch(Inst.Inst,
- Inst.Address,
- Inst.Size);
- if (targ != -1ULL)
- DumpAddress(targ, Sections, MachOOF, outs());
-
- // Print debug info.
- if (diContext) {
- DILineInfo dli =
- diContext->getLineInfoForAddress(SectAddress + Inst.Address);
- // Print valid line info if it changed.
- if (dli != lastLine && dli.getLine() != 0)
- outs() << "\t## " << dli.getFileName() << ':'
- << dli.getLine() << ':' << dli.getColumn();
- lastLine = dli;
- }
-
- outs() << '\n';
- }
- }
-
- emitDOTFile((f.getName().str() + ".dot").c_str(), f, IP.get());
- }
- }
}
}
OpenPOWER on IntegriCloud