#include "DWARFDebugInfoEntry.h"
#include "DWARFDebugRangeList.h"
#include "DWARFRelocMap.h"
+#include "DWARFSection.h"
#include <vector>
namespace llvm {
class DWARFContext;
class DWARFDebugAbbrev;
+class DWARFUnit;
class StringRef;
class raw_ostream;
-class DWARFUnit;
/// Base class for all DWARFUnitSection classes. This provides the
/// functionality common to all unit types.
/// same section this Unit originated from.
virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0;
- virtual ~DWARFUnitSectionBase() {}
+ void parse(DWARFContext &C, const DWARFSection &Section);
+ void parseDWO(DWARFContext &C, const DWARFSection &DWOSection);
+
+protected:
+ virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section,
+ const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
+ StringRef SOS, StringRef AOS, bool isLittleEndian) = 0;
+
+ ~DWARFUnitSectionBase() {}
};
/// Concrete instance of DWARFUnitSection, specialized for one Unit type.
template<typename UnitType>
-class DWARFUnitSection : public SmallVector<std::unique_ptr<UnitType>, 1>,
- public DWARFUnitSectionBase {
+class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>,
+ public DWARFUnitSectionBase {
struct UnitOffsetComparator {
- bool operator()(const std::unique_ptr<UnitType> &LHS,
- const std::unique_ptr<UnitType> &RHS) const {
- return LHS->getOffset() < RHS->getOffset();
- }
- bool operator()(const std::unique_ptr<UnitType> &LHS,
- uint32_t RHS) const {
- return LHS->getOffset() < RHS;
- }
bool operator()(uint32_t LHS,
const std::unique_ptr<UnitType> &RHS) const {
- return LHS < RHS->getOffset();
+ return LHS < RHS->getNextUnitOffset();
}
};
+ bool Parsed;
+
public:
+ DWARFUnitSection() : Parsed(false) {}
+ DWARFUnitSection(DWARFUnitSection &&DUS) :
+ SmallVector<std::unique_ptr<UnitType>, 1>(std::move(DUS)), Parsed(DUS.Parsed) {}
+
typedef llvm::SmallVectorImpl<std::unique_ptr<UnitType>> UnitVector;
typedef typename UnitVector::iterator iterator;
typedef llvm::iterator_range<typename UnitVector::iterator> iterator_range;
- UnitType *getUnitForOffset(uint32_t Offset) const {
- auto *CU = std::lower_bound(this->begin(), this->end(), Offset,
+ UnitType *getUnitForOffset(uint32_t Offset) const override {
+ auto *CU = std::upper_bound(this->begin(), this->end(), Offset,
UnitOffsetComparator());
if (CU != this->end())
return CU->get();
return nullptr;
}
+
+private:
+ void parseImpl(DWARFContext &Context, const DWARFSection &Section,
+ const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
+ StringRef SOS, StringRef AOS, bool LE) override {
+ if (Parsed)
+ return;
+ DataExtractor Data(Section.Data, LE, 0);
+ uint32_t Offset = 0;
+ while (Data.isValidOffset(Offset)) {
+ auto U = llvm::make_unique<UnitType>(Context, Section, DA, RS, SS, SOS,
+ AOS, LE, *this);
+ if (!U->extract(Data, &Offset))
+ break;
+ this->push_back(std::move(U));
+ Offset = this->back()->getNextUnitOffset();
+ }
+ Parsed = true;
+ }
};
class DWARFUnit {
DWARFContext &Context;
+ // Section containing this DWARFUnit.
+ const DWARFSection &InfoSection;
const DWARFDebugAbbrev *Abbrev;
- StringRef InfoSection;
StringRef RangeSection;
uint32_t RangeSectionBase;
StringRef StringSection;
StringRef StringOffsetSection;
StringRef AddrOffsetSection;
uint32_t AddrOffsetSectionBase;
- const RelocAddrMap *RelocMap;
bool isLittleEndian;
const DWARFUnitSectionBase &UnitSection;
virtual uint32_t getHeaderSize() const { return 11; }
public:
- DWARFUnit(DWARFContext& Context, const DWARFDebugAbbrev *DA, StringRef IS,
- StringRef RS, StringRef SS, StringRef SOS, StringRef AOS,
- const RelocAddrMap *M, bool LE, const DWARFUnitSectionBase &UnitSection);
+ DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
+ const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
+ StringRef SOS, StringRef AOS, bool LE,
+ const DWARFUnitSectionBase &UnitSection);
virtual ~DWARFUnit();
bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const;
DataExtractor getDebugInfoExtractor() const {
- return DataExtractor(InfoSection, isLittleEndian, AddrSize);
+ return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize);
}
DataExtractor getStringExtractor() const {
return DataExtractor(StringSection, false, 0);
}
- const RelocAddrMap *getRelocMap() const { return RelocMap; }
+ const RelocAddrMap *getRelocMap() const { return &InfoSection.Relocs; }
bool extract(DataExtractor debug_info, uint32_t* offset_ptr);