From d1726a4580f3dc42e2debbfea41acb9e815c06be Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Mon, 12 Nov 2012 21:40:38 +0000 Subject: [PATCH] Rewrite DIContext interface to take an object. Update all callers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167757 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/DebugInfo/DIContext.h | 11 +-- lib/DebugInfo/DIContext.cpp | 13 +--- lib/DebugInfo/DWARFContext.cpp | 80 +++++++++++++++++++ lib/DebugInfo/DWARFContext.h | 35 +++------ lib/DebugInfo/DWARFFormValue.cpp | 36 ++++----- tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 94 +---------------------- tools/llvm-objdump/MachODump.cpp | 45 +---------- tools/llvm-symbolizer/llvm-symbolizer.cpp | 66 +--------------- 8 files changed, 116 insertions(+), 264 deletions(-) diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index 23223414bfa..9bfb19d693b 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -19,6 +19,8 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Object/RelocVisitor.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -102,14 +104,7 @@ public: virtual ~DIContext(); /// getDWARFContext - get a context for binary DWARF data. - static DIContext *getDWARFContext(bool isLittleEndian, - StringRef infoSection, - StringRef abbrevSection, - StringRef aRangeSection = StringRef(), - StringRef lineSection = StringRef(), - StringRef stringSection = StringRef(), - StringRef rangeSection = StringRef(), - const RelocAddrMap *Map = 0); + static DIContext *getDWARFContext(object::ObjectFile *); virtual void dump(raw_ostream &OS) = 0; diff --git a/lib/DebugInfo/DIContext.cpp b/lib/DebugInfo/DIContext.cpp index 6484abcfe82..49a44097d3e 100644 --- a/lib/DebugInfo/DIContext.cpp +++ b/lib/DebugInfo/DIContext.cpp @@ -13,15 +13,6 @@ using namespace llvm; DIContext::~DIContext() {} -DIContext *DIContext::getDWARFContext(bool isLittleEndian, - StringRef infoSection, - StringRef abbrevSection, - StringRef aRangeSection, - StringRef lineSection, - StringRef stringSection, - StringRef rangeSection, - const RelocAddrMap *Map) { - return new DWARFContextInMemory(isLittleEndian, infoSection, abbrevSection, - aRangeSection, lineSection, stringSection, - rangeSection, Map); +DIContext *DIContext::getDWARFContext(object::ObjectFile *Obj) { + return new DWARFContextInMemory(Obj); } diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index afd614cc356..af11eed90d3 100644 --- a/lib/DebugInfo/DWARFContext.cpp +++ b/lib/DebugInfo/DWARFContext.cpp @@ -298,4 +298,84 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address, return InliningInfo; } +DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) : + IsLittleEndian(true /* FIXME */) { + error_code ec; + for (object::section_iterator i = Obj->begin_sections(), + e = Obj->end_sections(); + i != e; i.increment(ec)) { + StringRef name; + i->getName(name); + StringRef data; + i->getContents(data); + + if (name.startswith("__DWARF,")) + name = name.substr(8); // Skip "__DWARF," prefix. + name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes. + if (name == "debug_info") + InfoSection = data; + else if (name == "debug_abbrev") + AbbrevSection = data; + else if (name == "debug_line") + LineSection = data; + else if (name == "debug_aranges") + ARangeSection = data; + else if (name == "debug_str") + StringSection = data; + else if (name == "debug_ranges") + RangeSection = data; + // Any more debug info sections go here. + else + continue; + + // TODO: For now only handle relocations for the debug_info section. + if (name != "debug_info") + continue; + + if (i->begin_relocations() != i->end_relocations()) { + uint64_t SectionSize; + i->getSize(SectionSize); + for (object::relocation_iterator reloc_i = i->begin_relocations(), + reloc_e = i->end_relocations(); + reloc_i != reloc_e; reloc_i.increment(ec)) { + uint64_t Address; + reloc_i->getAddress(Address); + uint64_t Type; + reloc_i->getType(Type); + + object::RelocVisitor V(Obj->getFileFormatName()); + // The section address is always 0 for debug sections. + object::RelocToApply R(V.visit(Type, *reloc_i)); + if (V.error()) { + SmallString<32> Name; + error_code ec(reloc_i->getTypeName(Name)); + if (ec) { + errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n"; + } + errs() << "error: failed to compute relocation: " + << Name << "\n"; + continue; + } + + if (Address + R.Width > SectionSize) { + errs() << "error: " << R.Width << "-byte relocation starting " + << Address << " bytes into section " << name << " which is " + << SectionSize << " bytes long.\n"; + continue; + } + if (R.Width > 8) { + errs() << "error: can't handle a relocation of more than 8 bytes at " + "a time.\n"; + continue; + } + DEBUG(dbgs() << "Writing " << format("%p", R.Value) + << " at " << format("%p", Address) + << " with width " << format("%d", R.Width) + << "\n"); + RelocMap[Address] = std::make_pair(R.Width, R.Value); + } + } + } +} + void DWARFContextInMemory::anchor() { } diff --git a/lib/DebugInfo/DWARFContext.h b/lib/DebugInfo/DWARFContext.h index d3e9470a849..ff161e2aadd 100644 --- a/lib/DebugInfo/DWARFContext.h +++ b/lib/DebugInfo/DWARFContext.h @@ -25,9 +25,6 @@ namespace llvm { /// information parsing. The actual data is supplied through pure virtual /// methods that a concrete implementation provides. class DWARFContext : public DIContext { - bool IsLittleEndian; - const RelocAddrMap *RelocMap; - SmallVector CUs; OwningPtr Abbrev; OwningPtr Aranges; @@ -38,10 +35,9 @@ class DWARFContext : public DIContext { /// Read compile units from the debug_info section and store them in CUs. void parseCompileUnits(); -protected: - DWARFContext(bool isLittleEndian, const RelocAddrMap *Map) : - IsLittleEndian(isLittleEndian), RelocMap(Map) {} + public: + DWARFContext() {} virtual void dump(raw_ostream &OS); /// Get the number of compile units in this context. @@ -72,9 +68,8 @@ public: virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier = DILineInfoSpecifier()); - bool isLittleEndian() const { return IsLittleEndian; } - const RelocAddrMap *relocMap() const { return RelocMap; } - + virtual bool isLittleEndian() const = 0; + virtual const RelocAddrMap &relocMap() const = 0; virtual StringRef getInfoSection() = 0; virtual StringRef getAbbrevSection() = 0; virtual StringRef getARangeSection() = 0; @@ -99,6 +94,8 @@ private: /// pointers to it. class DWARFContextInMemory : public DWARFContext { virtual void anchor(); + bool IsLittleEndian; + RelocAddrMap RelocMap; StringRef InfoSection; StringRef AbbrevSection; StringRef ARangeSection; @@ -106,23 +103,9 @@ class DWARFContextInMemory : public DWARFContext { StringRef StringSection; StringRef RangeSection; public: - DWARFContextInMemory(bool isLittleEndian, - StringRef infoSection, - StringRef abbrevSection, - StringRef aRangeSection, - StringRef lineSection, - StringRef stringSection, - StringRef rangeSection, - const RelocAddrMap *Map = 0) - : DWARFContext(isLittleEndian, Map), - InfoSection(infoSection), - AbbrevSection(abbrevSection), - ARangeSection(aRangeSection), - LineSection(lineSection), - StringSection(stringSection), - RangeSection(rangeSection) - {} - + DWARFContextInMemory(object::ObjectFile *); + virtual bool isLittleEndian() const { return IsLittleEndian; } + virtual const RelocAddrMap &relocMap() const { return RelocMap; } virtual StringRef getInfoSection() { return InfoSection; } virtual StringRef getAbbrevSection() { return AbbrevSection; } virtual StringRef getARangeSection() { return ARangeSection; } diff --git a/lib/DebugInfo/DWARFFormValue.cpp b/lib/DebugInfo/DWARFFormValue.cpp index b75b0c17b38..07f7b446431 100644 --- a/lib/DebugInfo/DWARFFormValue.cpp +++ b/lib/DebugInfo/DWARFFormValue.cpp @@ -100,17 +100,13 @@ DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr, switch (Form) { case DW_FORM_addr: case DW_FORM_ref_addr: { - bool InRelocMap = false; - if (const RelocAddrMap *RelocMap = cu->getContext().relocMap()) { - RelocAddrMap::const_iterator AI = RelocMap->find(*offset_ptr); - if (AI != RelocMap->end()) { - const std::pair &R = AI->second; - Value.uval = R.second; - *offset_ptr += R.first; - InRelocMap = true; - } - } - if (!InRelocMap) + RelocAddrMap::const_iterator AI + = cu->getContext().relocMap().find(*offset_ptr); + if (AI != cu->getContext().relocMap().end()) { + const std::pair &R = AI->second; + Value.uval = R.second; + *offset_ptr += R.first; + } else Value.uval = data.getUnsigned(offset_ptr, cu->getAddressByteSize()); break; } @@ -152,17 +148,13 @@ DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr, Value.sval = data.getSLEB128(offset_ptr); break; case DW_FORM_strp: { - bool InRelocMap = false; - if (const RelocAddrMap *RelocMap = cu->getContext().relocMap()) { - RelocAddrMap::const_iterator AI = RelocMap->find(*offset_ptr); - if (AI != RelocMap->end()) { - const std::pair &R = AI->second; - Value.uval = R.second; - *offset_ptr += R.first; - InRelocMap = true; - } - } - if (!InRelocMap) + RelocAddrMap::const_iterator AI + = cu->getContext().relocMap().find(*offset_ptr); + if (AI != cu->getContext().relocMap().end()) { + const std::pair &R = AI->second; + Value.uval = R.second; + *offset_ptr += R.first; + } else Value.uval = data.getU32(offset_ptr); break; } diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index c0e3491509d..2229a3aa987 100644 --- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -69,100 +69,8 @@ static void DumpInput(const StringRef &Filename) { } OwningPtr Obj(ObjectFile::createObjectFile(Buff.take())); + OwningPtr dictx(DIContext::getDWARFContext(Obj.get())); - StringRef DebugInfoSection; - RelocAddrMap RelocMap; - StringRef DebugAbbrevSection; - StringRef DebugLineSection; - StringRef DebugArangesSection; - StringRef DebugStringSection; - StringRef DebugRangesSection; - - error_code ec; - for (section_iterator i = Obj->begin_sections(), - e = Obj->end_sections(); - i != e; i.increment(ec)) { - StringRef name; - i->getName(name); - StringRef data; - i->getContents(data); - - if (name.startswith("__DWARF,")) - name = name.substr(8); // Skip "__DWARF," prefix. - name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes. - if (name == "debug_info") - DebugInfoSection = data; - else if (name == "debug_abbrev") - DebugAbbrevSection = data; - else if (name == "debug_line") - DebugLineSection = data; - else if (name == "debug_aranges") - DebugArangesSection = data; - else if (name == "debug_str") - DebugStringSection = data; - else if (name == "debug_ranges") - DebugRangesSection = data; - // Any more debug info sections go here. - else - continue; - - // TODO: For now only handle relocations for the debug_info section. - if (name != "debug_info") - continue; - - if (i->begin_relocations() != i->end_relocations()) { - uint64_t SectionSize; - i->getSize(SectionSize); - for (relocation_iterator reloc_i = i->begin_relocations(), - reloc_e = i->end_relocations(); - reloc_i != reloc_e; reloc_i.increment(ec)) { - uint64_t Address; - reloc_i->getAddress(Address); - uint64_t Type; - reloc_i->getType(Type); - - RelocVisitor V(Obj->getFileFormatName()); - // The section address is always 0 for debug sections. - RelocToApply R(V.visit(Type, *reloc_i)); - if (V.error()) { - SmallString<32> Name; - error_code ec(reloc_i->getTypeName(Name)); - if (ec) { - errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n"; - } - errs() << "error: failed to compute relocation: " - << Name << "\n"; - continue; - } - - if (Address + R.Width > SectionSize) { - errs() << "error: " << R.Width << "-byte relocation starting " - << Address << " bytes into section " << name << " which is " - << SectionSize << " bytes long.\n"; - continue; - } - if (R.Width > 8) { - errs() << "error: can't handle a relocation of more than 8 bytes at " - "a time.\n"; - continue; - } - DEBUG(dbgs() << "Writing " << format("%p", R.Value) - << " at " << format("%p", Address) - << " with width " << format("%d", R.Width) - << "\n"); - RelocMap[Address] = std::make_pair(R.Width, R.Value); - } - } - } - - OwningPtr dictx(DIContext::getDWARFContext(/*FIXME*/true, - DebugInfoSection, - DebugAbbrevSection, - DebugArangesSection, - DebugLineSection, - DebugStringSection, - DebugRangesSection, - &RelocMap)); if (Address == -1ULL) { outs() << Filename << ":\tfile format " << Obj->getFileFormatName() << "\n\n"; diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 1feea421f23..46e71ceb4db 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -309,16 +309,10 @@ void llvm::DisassembleInputMachO(StringRef Filename) { raw_ostream &DebugOut = nulls(); #endif - StringRef DebugAbbrevSection, DebugInfoSection, DebugArangesSection, - DebugLineSection, DebugStrSection; OwningPtr diContext; - OwningPtr DSYMObj; - MachOObject *DbgInfoObj = MachOObj; + ObjectFile *DbgObj = MachOOF.get(); // Try to find debug info and set up the DIContext for it. if (UseDbg) { - ArrayRef DebugSections = Sections; - std::vector DSYMSections; - // 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()) { @@ -327,42 +321,11 @@ void llvm::DisassembleInputMachO(StringRef Filename) { errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n'; return; } - DSYMObj.reset(static_cast( - ObjectFile::createMachOObjectFile(Buf.take()))); - const macho::Header &Header = DSYMObj->getObject()->getHeader(); - - std::vector Symbols; - SmallVector FoundFns; - getSectionsAndSymbols(Header, DSYMObj.get(), 0, DSYMSections, Symbols, - FoundFns); - DebugSections = DSYMSections; - DbgInfoObj = DSYMObj.get()->getObject(); - } - - // Find the named debug info sections. - for (unsigned SectIdx = 0; SectIdx != DebugSections.size(); SectIdx++) { - StringRef SectName; - if (!DebugSections[SectIdx].getName(SectName)) { - if (SectName.equals("__DWARF,__debug_abbrev")) - DebugSections[SectIdx].getContents(DebugAbbrevSection); - else if (SectName.equals("__DWARF,__debug_info")) - DebugSections[SectIdx].getContents(DebugInfoSection); - else if (SectName.equals("__DWARF,__debug_aranges")) - DebugSections[SectIdx].getContents(DebugArangesSection); - else if (SectName.equals("__DWARF,__debug_line")) - DebugSections[SectIdx].getContents(DebugLineSection); - else if (SectName.equals("__DWARF,__debug_str")) - DebugSections[SectIdx].getContents(DebugStrSection); - } + DbgObj = ObjectFile::createMachOObjectFile(Buf.take()); } - // Setup the DIContext. - diContext.reset(DIContext::getDWARFContext(DbgInfoObj->isLittleEndian(), - DebugInfoSection, - DebugAbbrevSection, - DebugArangesSection, - DebugLineSection, - DebugStrSection)); + // Setup the DIContext + diContext.reset(DIContext::getDWARFContext(DbgObj)); } FunctionMapTy FunctionMap; diff --git a/tools/llvm-symbolizer/llvm-symbolizer.cpp b/tools/llvm-symbolizer/llvm-symbolizer.cpp index f3e365981e4..f3335a3fc36 100644 --- a/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -170,18 +170,6 @@ typedef ModuleMapTy::iterator ModuleMapIter; static ModuleMapTy Modules; -static bool isFullNameOfDwarfSection(const StringRef &FullName, - const StringRef &ShortName) { - static const char kDwarfPrefix[] = "__DWARF,"; - StringRef Name = FullName; - // Skip "__DWARF," prefix. - if (Name.startswith(kDwarfPrefix)) - Name = Name.substr(strlen(kDwarfPrefix)); - // Skip . and _ prefixes. - Name = Name.substr(Name.find_first_not_of("._")); - return (Name == ShortName); -} - // Returns true if the object endianness is known. static bool getObjectEndianness(const ObjectFile *Obj, bool &IsLittleEndian) { @@ -190,41 +178,6 @@ static bool getObjectEndianness(const ObjectFile *Obj, return true; } -static void getDebugInfoSections(const ObjectFile *Obj, - StringRef &DebugInfoSection, - StringRef &DebugAbbrevSection, - StringRef &DebugLineSection, - StringRef &DebugArangesSection, - StringRef &DebugStringSection, - StringRef &DebugRangesSection) { - if (Obj == 0) - return; - error_code ec; - for (section_iterator i = Obj->begin_sections(), - e = Obj->end_sections(); - i != e; i.increment(ec)) { - if (error(ec)) break; - StringRef Name; - if (error(i->getName(Name))) continue; - StringRef Data; - if (error(i->getContents(Data))) continue; - if (isFullNameOfDwarfSection(Name, "debug_info")) - DebugInfoSection = Data; - else if (isFullNameOfDwarfSection(Name, "debug_abbrev")) - DebugAbbrevSection = Data; - else if (isFullNameOfDwarfSection(Name, "debug_line")) - DebugLineSection = Data; - // Don't use debug_aranges for now, as address ranges contained - // there may not cover all instructions in the module - // else if (isFullNameOfDwarfSection(Name, "debug_aranges")) - // DebugArangesSection = Data; - else if (isFullNameOfDwarfSection(Name, "debug_str")) - DebugStringSection = Data; - else if (isFullNameOfDwarfSection(Name, "debug_ranges")) - DebugRangesSection = Data; - } -} - static ObjectFile *getObjectFile(const std::string &Path) { OwningPtr Buff; MemoryBuffer::getFile(Path, Buff); @@ -246,6 +199,7 @@ static ModuleInfo *getOrCreateModuleInfo(const std::string &ModuleName) { return I->second; ObjectFile *Obj = getObjectFile(ModuleName); + ObjectFile *DbgObj = Obj; if (Obj == 0) { // Module name doesn't point to a valid object file. Modules.insert(make_pair(ModuleName, (ModuleInfo*)0)); @@ -255,15 +209,6 @@ static ModuleInfo *getOrCreateModuleInfo(const std::string &ModuleName) { DIContext *Context = 0; bool IsLittleEndian; if (getObjectEndianness(Obj, IsLittleEndian)) { - StringRef DebugInfo; - StringRef DebugAbbrev; - StringRef DebugLine; - StringRef DebugAranges; - StringRef DebugString; - StringRef DebugRanges; - getDebugInfoSections(Obj, DebugInfo, DebugAbbrev, DebugLine, - DebugAranges, DebugString, DebugRanges); - // On Darwin we may find DWARF in separate object file in // resource directory. if (isa(Obj)) { @@ -271,14 +216,9 @@ static ModuleInfo *getOrCreateModuleInfo(const std::string &ModuleName) { ModuleName); ObjectFile *ResourceObj = getObjectFile(ResourceName); if (ResourceObj != 0) - getDebugInfoSections(ResourceObj, DebugInfo, DebugAbbrev, DebugLine, - DebugAranges, DebugString, DebugRanges); + DbgObj = ResourceObj; } - - Context = DIContext::getDWARFContext( - IsLittleEndian, DebugInfo, DebugAbbrev, - DebugAranges, DebugLine, DebugString, - DebugRanges); + Context = DIContext::getDWARFContext(DbgObj); assert(Context); } -- 2.34.1