summaryrefslogtreecommitdiffstats
path: root/llvm/tools
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools')
-rw-r--r--llvm/tools/llvm-objdump/MachODump.cpp264
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp14
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.h2
3 files changed, 21 insertions, 259 deletions
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index 258c0b520a3..fbb116b4e12 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -1214,6 +1214,12 @@ static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF,
printLazyBindTable(MachOOF);
if (WeakBind)
printWeakBindTable(MachOOF);
+
+ if (DwarfDumpType != DIDT_Null) {
+ std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(*MachOOF));
+ // Dump the complete DWARF structure.
+ DICtx->dump(outs(), DwarfDumpType, true /* DumpEH */);
+ }
}
// printUnknownCPUType() helps print_fat_headers for unknown CPU's.
@@ -6750,262 +6756,6 @@ static void printMachOUnwindInfoSection(const MachOObjectFile *Obj,
}
}
-static unsigned getSizeForEncoding(bool is64Bit,
- unsigned symbolEncoding) {
- unsigned format = symbolEncoding & 0x0f;
- switch (format) {
- default: llvm_unreachable("Unknown Encoding");
- case dwarf::DW_EH_PE_absptr:
- case dwarf::DW_EH_PE_signed:
- return is64Bit ? 8 : 4;
- case dwarf::DW_EH_PE_udata2:
- case dwarf::DW_EH_PE_sdata2:
- return 2;
- case dwarf::DW_EH_PE_udata4:
- case dwarf::DW_EH_PE_sdata4:
- return 4;
- case dwarf::DW_EH_PE_udata8:
- case dwarf::DW_EH_PE_sdata8:
- return 8;
- }
-}
-
-static uint64_t readPointer(const char *&Pos, bool is64Bit, unsigned Encoding) {
- switch (getSizeForEncoding(is64Bit, Encoding)) {
- case 2:
- return readNext<uint16_t>(Pos);
- break;
- case 4:
- return readNext<uint32_t>(Pos);
- break;
- case 8:
- return readNext<uint64_t>(Pos);
- break;
- default:
- llvm_unreachable("Illegal data size");
- }
-}
-
-static void printMachOEHFrameSection(const MachOObjectFile *Obj,
- std::map<uint64_t, SymbolRef> &Symbols,
- const SectionRef &EHFrame) {
- if (!Obj->isLittleEndian()) {
- outs() << "warning: cannot handle big endian __eh_frame section\n";
- return;
- }
-
- bool is64Bit = Obj->is64Bit();
-
- outs() << "Contents of __eh_frame section:\n";
-
- StringRef Contents;
- EHFrame.getContents(Contents);
-
- /// A few fields of the CIE are used when decoding the FDE's. This struct
- /// will cache those fields we need so that we don't have to decode it
- /// repeatedly for each FDE that references it.
- struct DecodedCIE {
- Optional<uint32_t> FDEPointerEncoding;
- Optional<uint32_t> LSDAPointerEncoding;
- bool hasAugmentationLength;
- };
-
- // Map from the start offset of the CIE to the cached data for that CIE.
- DenseMap<uint64_t, DecodedCIE> CachedCIEs;
-
- for (const char *Pos = Contents.data(), *End = Contents.end(); Pos != End; ) {
-
- const char *EntryStartPos = Pos;
-
- uint64_t Length = readNext<uint32_t>(Pos);
- if (Length == 0xffffffff)
- Length = readNext<uint64_t>(Pos);
-
- // Save the Pos so that we can check the length we encoded against what we
- // end up decoding.
- const char *PosAfterLength = Pos;
- const char *EntryEndPos = PosAfterLength + Length;
-
- assert(EntryEndPos <= End &&
- "__eh_frame entry length exceeds section size");
-
- uint32_t ID = readNext<uint32_t>(Pos);
- if (ID == 0) {
- // This is a CIE.
-
- uint32_t Version = readNext<uint8_t>(Pos);
-
- // Parse a null terminated augmentation string
- SmallString<8> AugmentationString;
- for (uint8_t Char = readNext<uint8_t>(Pos); Char;
- Char = readNext<uint8_t>(Pos))
- AugmentationString.push_back(Char);
-
- // Optionally parse the EH data if the augmentation string says it's there.
- Optional<uint64_t> EHData;
- if (StringRef(AugmentationString).count("eh"))
- EHData = is64Bit ? readNext<uint64_t>(Pos) : readNext<uint32_t>(Pos);
-
- unsigned ULEBByteCount;
- uint64_t CodeAlignmentFactor = decodeULEB128((const uint8_t *)Pos,
- &ULEBByteCount);
- Pos += ULEBByteCount;
-
- int64_t DataAlignmentFactor = decodeSLEB128((const uint8_t *)Pos,
- &ULEBByteCount);
- Pos += ULEBByteCount;
-
- uint32_t ReturnAddressRegister = readNext<uint8_t>(Pos);
-
- Optional<uint64_t> AugmentationLength;
- Optional<uint32_t> LSDAPointerEncoding;
- Optional<uint32_t> PersonalityEncoding;
- Optional<uint64_t> Personality;
- Optional<uint32_t> FDEPointerEncoding;
- if (!AugmentationString.empty() && AugmentationString.front() == 'z') {
- AugmentationLength = decodeULEB128((const uint8_t *)Pos,
- &ULEBByteCount);
- Pos += ULEBByteCount;
-
- // Walk the augmentation string to get all the augmentation data.
- for (unsigned i = 1, e = AugmentationString.size(); i != e; ++i) {
- char Char = AugmentationString[i];
- switch (Char) {
- case 'e':
- assert((i + 1) != e && AugmentationString[i + 1] == 'h' &&
- "Expected 'eh' in augmentation string");
- break;
- case 'L':
- assert(!LSDAPointerEncoding && "Duplicate LSDA encoding");
- LSDAPointerEncoding = readNext<uint8_t>(Pos);
- break;
- case 'P': {
- assert(!Personality && "Duplicate personality");
- PersonalityEncoding = readNext<uint8_t>(Pos);
- Personality = readPointer(Pos, is64Bit, *PersonalityEncoding);
- break;
- }
- case 'R':
- assert(!FDEPointerEncoding && "Duplicate FDE encoding");
- FDEPointerEncoding = readNext<uint8_t>(Pos);
- break;
- case 'z':
- llvm_unreachable("'z' must be first in the augmentation string");
- }
- }
- }
-
- outs() << "CIE:\n";
- outs() << " Length: " << Length << "\n";
- outs() << " CIE ID: " << ID << "\n";
- outs() << " Version: " << Version << "\n";
- outs() << " Augmentation String: " << AugmentationString << "\n";
- if (EHData)
- outs() << " EHData: " << *EHData << "\n";
- outs() << " Code Alignment Factor: " << CodeAlignmentFactor << "\n";
- outs() << " Data Alignment Factor: " << DataAlignmentFactor << "\n";
- outs() << " Return Address Register: " << ReturnAddressRegister << "\n";
- if (AugmentationLength) {
- outs() << " Augmentation Data Length: " << *AugmentationLength << "\n";
- if (LSDAPointerEncoding) {
- outs() << " FDE LSDA Pointer Encoding: "
- << *LSDAPointerEncoding << "\n";
- }
- if (Personality) {
- outs() << " Personality Encoding: " << *PersonalityEncoding << "\n";
- outs() << " Personality: " << *Personality << "\n";
- }
- if (FDEPointerEncoding) {
- outs() << " FDE Address Pointer Encoding: "
- << *FDEPointerEncoding << "\n";
- }
- }
- // FIXME: Handle instructions.
- // For now just emit some bytes
- outs() << " Instructions:\n ";
- dumpBytes(makeArrayRef((const uint8_t*)Pos, (const uint8_t*)EntryEndPos),
- outs());
- outs() << "\n";
- Pos = EntryEndPos;
-
- // Cache this entry.
- uint64_t Offset = EntryStartPos - Contents.data();
- CachedCIEs[Offset] = { FDEPointerEncoding, LSDAPointerEncoding,
- AugmentationLength.hasValue() };
- continue;
- }
-
- // This is an FDE.
- // The CIE pointer for an FDE is the same location as the ID which we
- // already read.
- uint32_t CIEPointer = ID;
-
- const char *CIEStart = PosAfterLength - CIEPointer;
- assert(CIEStart >= Contents.data() &&
- "FDE points to CIE before the __eh_frame start");
-
- uint64_t CIEOffset = CIEStart - Contents.data();
- auto CIEIt = CachedCIEs.find(CIEOffset);
- if (CIEIt == CachedCIEs.end())
- llvm_unreachable("Couldn't find CIE at offset in to __eh_frame section");
-
- const DecodedCIE &CIE = CIEIt->getSecond();
- assert(CIE.FDEPointerEncoding &&
- "FDE references CIE which did not set pointer encoding");
-
- uint64_t PCPointerSize = getSizeForEncoding(is64Bit,
- *CIE.FDEPointerEncoding);
-
- uint64_t PCBegin = readPointer(Pos, is64Bit, *CIE.FDEPointerEncoding);
- uint64_t PCRange = readPointer(Pos, is64Bit, *CIE.FDEPointerEncoding);
-
- Optional<uint64_t> AugmentationLength;
- uint32_t LSDAPointerSize;
- Optional<uint64_t> LSDAPointer;
- if (CIE.hasAugmentationLength) {
- unsigned ULEBByteCount;
- AugmentationLength = decodeULEB128((const uint8_t *)Pos,
- &ULEBByteCount);
- Pos += ULEBByteCount;
-
- // Decode the LSDA if the CIE augmentation string said we should.
- if (CIE.LSDAPointerEncoding) {
- LSDAPointerSize = getSizeForEncoding(is64Bit, *CIE.LSDAPointerEncoding);
- LSDAPointer = readPointer(Pos, is64Bit, *CIE.LSDAPointerEncoding);
- }
- }
-
- outs() << "FDE:\n";
- outs() << " Length: " << Length << "\n";
- outs() << " CIE Offset: " << CIEOffset << "\n";
-
- if (PCPointerSize == 8) {
- outs() << format(" PC Begin: %016" PRIx64, PCBegin) << "\n";
- outs() << format(" PC Range: %016" PRIx64, PCRange) << "\n";
- } else {
- outs() << format(" PC Begin: %08" PRIx64, PCBegin) << "\n";
- outs() << format(" PC Range: %08" PRIx64, PCRange) << "\n";
- }
- if (AugmentationLength) {
- outs() << " Augmentation Data Length: " << *AugmentationLength << "\n";
- if (LSDAPointer) {
- if (LSDAPointerSize == 8)
- outs() << format(" LSDA Pointer: %016\n" PRIx64, *LSDAPointer);
- else
- outs() << format(" LSDA Pointer: %08\n" PRIx64, *LSDAPointer);
- }
- }
-
- // FIXME: Handle instructions.
- // For now just emit some bytes
- outs() << " Instructions:\n ";
- dumpBytes(makeArrayRef((const uint8_t*)Pos, (const uint8_t*)EntryEndPos),
- outs());
- outs() << "\n";
- Pos = EntryEndPos;
- }
-}
-
void llvm::printMachOUnwindInfo(const MachOObjectFile *Obj) {
std::map<uint64_t, SymbolRef> Symbols;
for (const SymbolRef &SymRef : Obj->symbols()) {
@@ -7026,8 +6776,6 @@ void llvm::printMachOUnwindInfo(const MachOObjectFile *Obj) {
printMachOCompactUnwindSection(Obj, Symbols, Section);
else if (SectName == "__unwind_info")
printMachOUnwindInfoSection(Obj, Symbols, Section);
- else if (SectName == "__eh_frame")
- printMachOEHFrameSection(Obj, Symbols, Section);
}
}
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index d5ae5de4b5a..83ad0e11180 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -22,6 +22,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/CodeGen/FaultMaps.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler.h"
@@ -181,6 +182,11 @@ cl::opt<bool>
cl::opt<bool> PrintFaultMaps("fault-map-section",
cl::desc("Display contents of faultmap section"));
+cl::opt<DIDumpType> llvm::DwarfDumpType(
+ "dwarf", cl::init(DIDT_Null), cl::desc("Dump of dwarf debug sections:"),
+ cl::values(clEnumValN(DIDT_Frames, "frames", ".debug_frame"),
+ clEnumValEnd));
+
static StringRef ToolName;
namespace {
@@ -1561,6 +1567,11 @@ static void DumpObject(const ObjectFile *o) {
printRawClangAST(o);
if (PrintFaultMaps)
printFaultMaps(o);
+ if (DwarfDumpType != DIDT_Null) {
+ std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(*o));
+ // Dump the complete DWARF structure.
+ DICtx->dump(outs(), DwarfDumpType, true /* DumpEH */);
+ }
}
/// @brief Dump each object file in \a a;
@@ -1654,7 +1665,8 @@ int main(int argc, char **argv) {
&& !(DylibId && MachOOpt)
&& !(ObjcMetaData && MachOOpt)
&& !(FilterSections.size() != 0 && MachOOpt)
- && !PrintFaultMaps) {
+ && !PrintFaultMaps
+ && DwarfDumpType == DIDT_Null) {
cl::PrintHelpMessage();
return 2;
}
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h
index 60cabbc98e2..c50caae5b58 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.h
+++ b/llvm/tools/llvm-objdump/llvm-objdump.h
@@ -10,6 +10,7 @@
#define LLVM_TOOLS_LLVM_OBJDUMP_LLVM_OBJDUMP_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/DIContext.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
@@ -55,6 +56,7 @@ extern cl::opt<bool> SectionContents;
extern cl::opt<bool> SymbolTable;
extern cl::opt<bool> UnwindInfo;
extern cl::opt<bool> PrintImmHex;
+extern cl::opt<DIDumpType> DwarfDumpType;
// Various helper functions.
void error(std::error_code ec);
OpenPOWER on IntegriCloud