const uint8_t* data;
};
- dwarf::Form Form; // Form for this value.
+ dwarf::Form Form; // Form for this value.
ValueType Value; // Contains all data for the form.
+ const DWARFUnit *U; // Remember the DWARFUnit at extract time.
public:
- DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {}
+ DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F), U(nullptr) {}
dwarf::Form getForm() const { return Form; }
bool isFormClass(FormClass FC) const;
-
- void dump(raw_ostream &OS, const DWARFUnit *U) const;
+ const DWARFUnit *getUnit() const { return U; }
+ void dump(raw_ostream &OS) const;
/// \brief extracts a value in data at offset *offset_ptr.
///
/// case no relocation processing will be performed and some
/// kind of forms that depend on Unit information are disallowed.
/// \returns whether the extraction succeeded.
- bool extractValue(DataExtractor data, uint32_t *offset_ptr,
- const DWARFUnit *u);
+ bool extractValue(const DataExtractor &Data, uint32_t *OffsetPtr,
+ const DWARFUnit *U);
bool isInlinedCStr() const {
return Value.data != nullptr && Value.data == (const uint8_t*)Value.cstr;
}
/// getAsFoo functions below return the extracted value as Foo if only
/// DWARFFormValue has form class is suitable for representing Foo.
- Optional<uint64_t> getAsReference(const DWARFUnit *U) const;
+ Optional<uint64_t> getAsReference() const;
Optional<uint64_t> getAsUnsignedConstant() const;
Optional<int64_t> getAsSignedConstant() const;
- Optional<const char *> getAsCString(const DWARFUnit *U) const;
- Optional<uint64_t> getAsAddress(const DWARFUnit *U) const;
+ Optional<const char *> getAsCString() const;
+ Optional<uint64_t> getAsAddress() const;
Optional<uint64_t> getAsSectionOffset() const;
Optional<ArrayRef<uint8_t>> getAsBlock() const;
bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr,
- const DWARFUnit *u) const;
+ const DWARFUnit *U) const;
static bool skipValue(dwarf::Form form, DataExtractor debug_info_data,
uint32_t *offset_ptr, const DWARFUnit *u);
static bool skipValue(dwarf::Form form, DataExtractor debug_info_data,
static ArrayRef<uint8_t> getFixedFormSizes(uint8_t AddrSize,
uint16_t Version);
private:
- void dumpString(raw_ostream &OS, const DWARFUnit *U) const;
+ void dumpString(raw_ostream &OS) const;
};
}
return Abbrevs;
}
uint8_t getAddressByteSize() const { return AddrSize; }
+ uint8_t getRefAddrByteSize() const {
+ // FIXME: Support DWARF64.
+ return (Version == 2) ? AddrSize : 4;
+ }
uint64_t getBaseAddress() const { return BaseAddr; }
void setBaseAddress(uint64_t base_addr) {
for (auto &Atom : AtomForms) {
OS << format("{Atom[%d]: ", i++);
if (Atom.extractValue(AccelSection, &DataOffset, nullptr))
- Atom.dump(OS, nullptr);
+ Atom.dump(OS);
else
OS << "Error extracting the value";
OS << "} ";
else if (attr == DW_AT_decl_line || attr == DW_AT_call_line)
OS << *formValue.getAsUnsignedConstant();
else
- formValue.dump(OS, u);
+ formValue.dump(OS);
// We have dumped the attribute raw value. For some attributes
// having both the raw value and the pretty-printed value is
// interesting. These attributes are handled below.
if (attr == DW_AT_specification || attr == DW_AT_abstract_origin) {
- Optional<uint64_t> Ref = formValue.getAsReference(u);
+ Optional<uint64_t> Ref = formValue.getAsReference();
if (Ref.hasValue()) {
uint32_t RefOffset = Ref.getValue();
DWARFDebugInfoEntryMinimal DIE;
DWARFFormValue FormValue;
if (!getAttributeValue(U, Attr, FormValue))
return FailValue;
- Optional<const char *> Result = FormValue.getAsCString(U);
+ Optional<const char *> Result = FormValue.getAsCString();
return Result.hasValue() ? Result.getValue() : FailValue;
}
DWARFFormValue FormValue;
if (!getAttributeValue(U, Attr, FormValue))
return FailValue;
- Optional<uint64_t> Result = FormValue.getAsAddress(U);
+ Optional<uint64_t> Result = FormValue.getAsAddress();
return Result.hasValue() ? Result.getValue() : FailValue;
}
DWARFFormValue FormValue;
if (!getAttributeValue(U, Attr, FormValue))
return FailValue;
- Optional<uint64_t> Result = FormValue.getAsReference(U);
+ Optional<uint64_t> Result = FormValue.getAsReference();
return Result.hasValue() ? Result.getValue() : FailValue;
}
FC == FC_SectionOffset;
}
-bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
+bool DWARFFormValue::extractValue(const DataExtractor &data,
+ uint32_t *offset_ptr,
const DWARFUnit *cu) {
+ U = cu;
bool indirect = false;
bool is_block = false;
Value.data = nullptr;
switch (Form) {
case DW_FORM_addr:
case DW_FORM_ref_addr: {
- if (!cu)
+ if (!U)
return false;
uint16_t AddrSize =
(Form == DW_FORM_addr)
- ? cu->getAddressByteSize()
- : getRefAddrSize(cu->getAddressByteSize(), cu->getVersion());
- RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr);
- if (AI != cu->getRelocMap()->end()) {
+ ? U->getAddressByteSize()
+ : U->getRefAddrByteSize();
+ RelocAddrMap::const_iterator AI = U->getRelocMap()->find(*offset_ptr);
+ if (AI != U->getRelocMap()->end()) {
const std::pair<uint8_t, int64_t> &R = AI->second;
Value.uval = data.getUnsigned(offset_ptr, AddrSize) + R.second;
} else
case DW_FORM_data4:
case DW_FORM_ref4: {
Value.uval = data.getU32(offset_ptr);
- if (!cu)
+ if (!U)
break;
- RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr-4);
- if (AI != cu->getRelocMap()->end())
+ RelocAddrMap::const_iterator AI = U->getRelocMap()->find(*offset_ptr-4);
+ if (AI != U->getRelocMap()->end())
Value.uval += AI->second.second;
break;
}
case DW_FORM_GNU_strp_alt: {
// FIXME: This is 64-bit for DWARF64.
Value.uval = data.getU32(offset_ptr);
- if (!cu)
+ if (!U)
break;
RelocAddrMap::const_iterator AI =
- cu->getRelocMap()->find(*offset_ptr - 4);
- if (AI != cu->getRelocMap()->end())
+ U->getRelocMap()->find(*offset_ptr - 4);
+ if (AI != U->getRelocMap()->end())
Value.uval += AI->second.second;
break;
}
bool
DWARFFormValue::skipValue(DataExtractor debug_info_data, uint32_t* offset_ptr,
- const DWARFUnit *cu) const {
- return DWARFFormValue::skipValue(Form, debug_info_data, offset_ptr, cu);
+ const DWARFUnit *U) const {
+ return DWARFFormValue::skipValue(Form, debug_info_data, offset_ptr, U);
}
bool
}
void
-DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const {
+DWARFFormValue::dump(raw_ostream &OS) const {
uint64_t uvalue = Value.uval;
bool cu_relative_offset = false;
case DW_FORM_GNU_addr_index: {
OS << format(" indexed (%8.8x) address = ", (uint32_t)uvalue);
uint64_t Address;
- if (cu->getAddrOffsetSectionItem(uvalue, Address))
+ if (U == nullptr)
+ OS << "<invalid dwarf unit>";
+ else if (U->getAddrOffsetSectionItem(uvalue, Address))
OS << format("0x%016" PRIx64, Address);
else
OS << "<no .debug_addr section>";
case DW_FORM_udata: OS << Value.uval; break;
case DW_FORM_strp: {
OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
- dumpString(OS, cu);
+ dumpString(OS);
break;
}
case DW_FORM_GNU_str_index: {
OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue);
- dumpString(OS, cu);
+ dumpString(OS);
break;
}
case DW_FORM_GNU_strp_alt: {
OS << format("alt indirect string, offset: 0x%" PRIx64 "", uvalue);
- dumpString(OS, cu);
+ dumpString(OS);
break;
}
case DW_FORM_ref_addr:
if (cu_relative_offset) {
OS << " => {";
WithColor(OS, syntax::Address).get()
- << format("0x%8.8" PRIx64, uvalue + (cu ? cu->getOffset() : 0));
+ << format("0x%8.8" PRIx64, uvalue + (U ? U->getOffset() : 0));
OS << "}";
}
}
-void DWARFFormValue::dumpString(raw_ostream &OS, const DWARFUnit *U) const {
- Optional<const char *> DbgStr = getAsCString(U);
+void DWARFFormValue::dumpString(raw_ostream &OS) const {
+ Optional<const char *> DbgStr = getAsCString();
if (DbgStr.hasValue()) {
raw_ostream &COS = WithColor(OS, syntax::String);
COS << '"';
}
}
-Optional<const char *> DWARFFormValue::getAsCString(const DWARFUnit *U) const {
+Optional<const char *> DWARFFormValue::getAsCString() const {
if (!isFormClass(FC_String))
return None;
if (Form == DW_FORM_string)
return None;
}
-Optional<uint64_t> DWARFFormValue::getAsAddress(const DWARFUnit *U) const {
+Optional<uint64_t> DWARFFormValue::getAsAddress() const {
if (!isFormClass(FC_Address))
return None;
if (Form == DW_FORM_GNU_addr_index) {
return Value.uval;
}
-Optional<uint64_t> DWARFFormValue::getAsReference(const DWARFUnit *U) const {
+Optional<uint64_t> DWARFFormValue::getAsReference() const {
if (!isFormClass(FC_Reference))
return None;
switch (Form) {
DWARFFormValue NameVal;
const char *Name = "";
if (TD->getAttributeValue(this, llvm::dwarf::DW_AT_name, NameVal))
- if (auto ON = NameVal.getAsCString(this))
+ if (auto ON = NameVal.getAsCString())
Name = *ON;
if (SummarizeTypes) {
const DWARFFormValue &RefValue, const DWARFUnit &Unit,
const DWARFDebugInfoEntryMinimal &DIE, CompileUnit *&RefCU) {
assert(RefValue.isFormClass(DWARFFormValue::FC_Reference));
- uint64_t RefOffset = *RefValue.getAsReference(&Unit);
+ uint64_t RefOffset = *RefValue.getAsReference();
if ((RefCU = getUnitForOffset(Units, RefOffset)))
if (const auto *RefDie = RefCU->getOrigUnit().getDIEForOffset(RefOffset))
llvm_unreachable("Invalid Tag");
}
-static unsigned getRefAddrSize(const DWARFUnit &U) {
- if (U.getVersion() == 2)
- return U.getAddressByteSize();
- return 4;
-}
-
void DwarfLinker::startDebugObject(DWARFContext &Dwarf, DebugMapObject &Obj) {
Units.reserve(Dwarf.getNumCompileUnits());
// Iterate over the debug map entries and put all the ones that are
uint64_t HighPc;
if (HighPcValue.isFormClass(DWARFFormValue::FC_Address)) {
- HighPc = *HighPcValue.getAsAddress(&OrigUnit);
+ HighPc = *HighPcValue.getAsAddress();
} else {
assert(HighPcValue.isFormClass(DWARFFormValue::FC_Constant));
HighPc = LowPc + *HighPcValue.getAsUnsignedConstant();
const DWARFFormValue &Val,
const DWARFUnit &U) {
// Switch everything to out of line strings.
- const char *String = *Val.getAsCString(&U);
+ const char *String = *Val.getAsCString();
unsigned Offset = Linker.StringPool.getStringOffset(String);
Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), dwarf::DW_FORM_strp,
DIEInteger(Offset));
AttributeSpec AttrSpec, unsigned AttrSize, const DWARFFormValue &Val,
CompileUnit &Unit) {
const DWARFUnit &U = Unit.getOrigUnit();
- uint32_t Ref = *Val.getAsReference(&U);
+ uint32_t Ref = *Val.getAsReference();
DIE *NewRefDie = nullptr;
CompileUnit *RefUnit = nullptr;
DeclContext *Ctxt = nullptr;
DIEInteger Attr(Ctxt->getCanonicalDIEOffset());
Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
dwarf::DW_FORM_ref_addr, Attr);
- return getRefAddrSize(U);
+ return U.getRefAddrByteSize();
}
}
Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
dwarf::DW_FORM_ref_addr, DIEInteger(Attr)));
}
- return getRefAddrSize(U);
+ return U.getRefAddrByteSize();
}
Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
unsigned DwarfLinker::DIECloner::cloneAddressAttribute(
DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val,
const CompileUnit &Unit, AttributesInfo &Info) {
- uint64_t Addr = *Val.getAsAddress(&Unit.getOrigUnit());
+ uint64_t Addr = *Val.getAsAddress();
if (AttrSpec.Attr == dwarf::DW_AT_low_pc) {
if (Die.getTag() == dwarf::DW_TAG_inlined_subroutine ||
Die.getTag() == dwarf::DW_TAG_lexical_block)