diff options
author | Eric Christopher <echristo@gmail.com> | 2012-11-12 21:40:38 +0000 |
---|---|---|
committer | Eric Christopher <echristo@gmail.com> | 2012-11-12 21:40:38 +0000 |
commit | d1726a4580f3dc42e2debbfea41acb9e815c06be (patch) | |
tree | 7b93c655e87f7362272c5dbbf0367ffd2a1b59b8 /lib/DebugInfo | |
parent | f4e3309e849dd0b89a39363c7f2fac337c6db81e (diff) |
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
Diffstat (limited to 'lib/DebugInfo')
-rw-r--r-- | lib/DebugInfo/DIContext.cpp | 13 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFContext.cpp | 80 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFContext.h | 35 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFFormValue.cpp | 36 |
4 files changed, 105 insertions, 59 deletions
diff --git a/lib/DebugInfo/DIContext.cpp b/lib/DebugInfo/DIContext.cpp index 6484abcfe8..49a44097d3 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 afd614cc35..af11eed90d 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 d3e9470a84..ff161e2aad 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<DWARFCompileUnit, 1> CUs; OwningPtr<DWARFDebugAbbrev> Abbrev; OwningPtr<DWARFDebugAranges> 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 b75b0c17b3..07f7b44643 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<uint8_t, int64_t> &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<uint8_t, int64_t> &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<uint8_t, int64_t> &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<uint8_t, int64_t> &R = AI->second; + Value.uval = R.second; + *offset_ptr += R.first; + } else Value.uval = data.getU32(offset_ptr); break; } |