mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 04:33:05 +00:00
Split address information for DWARF5 split dwarf proposal. This involves
using the DW_FORM_GNU_addr_index and a separate .debug_addr section which stays in the executable and is fully linked. Sneak in two other small changes: a) Print out the debug_str_offsets.dwo section. b) Change form we're expecting the entries in the debug_str_offsets.dwo section to take from ULEB128 to U32. Add tests for all of this in the fission-cu.ll test. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172578 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
af50dda410
commit
72f7bfbf0e
@ -115,6 +115,7 @@ protected:
|
||||
const MCSection *DwarfLineDWOSection;
|
||||
const MCSection *DwarfLocDWOSection;
|
||||
const MCSection *DwarfStrOffDWOSection;
|
||||
const MCSection *DwarfAddrSection;
|
||||
|
||||
// Extra TLS Variable Data section. If the target needs to put additional
|
||||
// information for a TLS variable, it'll go here.
|
||||
@ -251,6 +252,9 @@ public:
|
||||
const MCSection *getDwarfStrOffDWOSection() const {
|
||||
return DwarfStrOffDWOSection;
|
||||
}
|
||||
const MCSection *getDwarfAddrSection() const {
|
||||
return DwarfAddrSection;
|
||||
}
|
||||
|
||||
const MCSection *getTLSExtraDataSection() const {
|
||||
return TLSExtraDataSection;
|
||||
|
@ -198,6 +198,7 @@ void DIEInteger::EmitValue(AsmPrinter *Asm, unsigned Form) const {
|
||||
case dwarf::DW_FORM_ref8: // Fall thru
|
||||
case dwarf::DW_FORM_data8: Size = 8; break;
|
||||
case dwarf::DW_FORM_GNU_str_index: Asm->EmitULEB128(Integer); return;
|
||||
case dwarf::DW_FORM_GNU_addr_index: Asm->EmitULEB128(Integer); return;
|
||||
case dwarf::DW_FORM_udata: Asm->EmitULEB128(Integer); return;
|
||||
case dwarf::DW_FORM_sdata: Asm->EmitSLEB128(Integer); return;
|
||||
case dwarf::DW_FORM_addr:
|
||||
@ -222,6 +223,7 @@ unsigned DIEInteger::SizeOf(AsmPrinter *AP, unsigned Form) const {
|
||||
case dwarf::DW_FORM_ref8: // Fall thru
|
||||
case dwarf::DW_FORM_data8: return sizeof(int64_t);
|
||||
case dwarf::DW_FORM_GNU_str_index: return MCAsmInfo::getULEB128Size(Integer);
|
||||
case dwarf::DW_FORM_GNU_addr_index: return MCAsmInfo::getULEB128Size(Integer);
|
||||
case dwarf::DW_FORM_udata: return MCAsmInfo::getULEB128Size(Integer);
|
||||
case dwarf::DW_FORM_sdata: return MCAsmInfo::getSLEB128Size(Integer);
|
||||
case dwarf::DW_FORM_addr: return AP->getDataLayout().getPointerSize();
|
||||
|
@ -170,6 +170,26 @@ void CompileUnit::addLabel(DIE *Die, unsigned Attribute, unsigned Form,
|
||||
Die->addValue(Attribute, Form, Value);
|
||||
}
|
||||
|
||||
/// addLabelAddress - Add a dwarf label attribute data and value using
|
||||
/// DW_FORM_addr or DW_FORM_GNU_addr_index.
|
||||
///
|
||||
void CompileUnit::addLabelAddress(DIE *Die, unsigned Attribute,
|
||||
MCSymbol *Label) {
|
||||
if (!DD->useSplitDwarf()) {
|
||||
if (Label != NULL) {
|
||||
DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
|
||||
Die->addValue(Attribute, dwarf::DW_FORM_addr, Value);
|
||||
} else {
|
||||
DIEValue *Value = new (DIEValueAllocator) DIEInteger(0);
|
||||
Die->addValue(Attribute, dwarf::DW_FORM_addr, Value);
|
||||
}
|
||||
} else {
|
||||
unsigned idx = DU->getAddrPoolIndex(Label);
|
||||
DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx);
|
||||
Die->addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value);
|
||||
}
|
||||
}
|
||||
|
||||
/// addDelta - Add a label delta attribute data and value.
|
||||
///
|
||||
void CompileUnit::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
|
||||
|
@ -207,6 +207,11 @@ public:
|
||||
void addLabel(DIE *Die, unsigned Attribute, unsigned Form,
|
||||
const MCSymbol *Label);
|
||||
|
||||
/// addLabelAddress - Add a dwarf label attribute data and value using
|
||||
/// either DW_FORM_addr or DW_FORM_GNU_addr_index.
|
||||
///
|
||||
void addLabelAddress(DIE *Die, unsigned Attribute, MCSymbol *Label);
|
||||
|
||||
/// addDelta - Add a label delta attribute data and value.
|
||||
///
|
||||
void addDelta(DIE *Die, unsigned Attribute, unsigned Form,
|
||||
|
@ -237,6 +237,15 @@ unsigned DwarfUnits::getStringPoolIndex(StringRef Str) {
|
||||
return Entry.second;
|
||||
}
|
||||
|
||||
unsigned DwarfUnits::getAddrPoolIndex(MCSymbol *Sym) {
|
||||
std::pair<MCSymbol*, unsigned> &Entry = AddressPool[Sym];
|
||||
if (Entry.first) return Entry.second;
|
||||
|
||||
Entry.second = NextAddrPoolNumber++;
|
||||
Entry.first = Sym;
|
||||
return Entry.second;
|
||||
}
|
||||
|
||||
// Define a unique number for the abbreviation.
|
||||
//
|
||||
void DwarfUnits::assignAbbrevNumber(DIEAbbrev &Abbrev) {
|
||||
@ -384,10 +393,12 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU,
|
||||
}
|
||||
}
|
||||
|
||||
SPCU->addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
|
||||
Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()));
|
||||
SPCU->addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
|
||||
Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()));
|
||||
SPCU->addLabelAddress(SPDie, dwarf::DW_AT_low_pc,
|
||||
Asm->GetTempSymbol("func_begin",
|
||||
Asm->getFunctionNumber()));
|
||||
SPCU->addLabelAddress(SPDie, dwarf::DW_AT_high_pc,
|
||||
Asm->GetTempSymbol("func_end",
|
||||
Asm->getFunctionNumber()));
|
||||
const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
|
||||
MachineLocation Location(RI->getFrameRegister(*Asm->MF));
|
||||
SPCU->addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
|
||||
@ -429,16 +440,16 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU,
|
||||
return ScopeDIE;
|
||||
}
|
||||
|
||||
const MCSymbol *Start = getLabelBeforeInsn(RI->first);
|
||||
const MCSymbol *End = getLabelAfterInsn(RI->second);
|
||||
MCSymbol *Start = getLabelBeforeInsn(RI->first);
|
||||
MCSymbol *End = getLabelAfterInsn(RI->second);
|
||||
|
||||
if (End == 0) return 0;
|
||||
|
||||
assert(Start->isDefined() && "Invalid starting label for an inlined scope!");
|
||||
assert(End->isDefined() && "Invalid end label for an inlined scope!");
|
||||
|
||||
TheCU->addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, Start);
|
||||
TheCU->addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, End);
|
||||
TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_low_pc, Start);
|
||||
TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_high_pc, End);
|
||||
|
||||
return ScopeDIE;
|
||||
}
|
||||
@ -462,8 +473,8 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU,
|
||||
}
|
||||
|
||||
SmallVector<InsnRange, 4>::const_iterator RI = Ranges.begin();
|
||||
const MCSymbol *StartLabel = getLabelBeforeInsn(RI->first);
|
||||
const MCSymbol *EndLabel = getLabelAfterInsn(RI->second);
|
||||
MCSymbol *StartLabel = getLabelBeforeInsn(RI->first);
|
||||
MCSymbol *EndLabel = getLabelAfterInsn(RI->second);
|
||||
|
||||
if (StartLabel == 0 || EndLabel == 0) {
|
||||
llvm_unreachable("Unexpected Start and End labels for an inlined scope!");
|
||||
@ -492,10 +503,8 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU,
|
||||
DebugRangeSymbols.push_back(NULL);
|
||||
DebugRangeSymbols.push_back(NULL);
|
||||
} else {
|
||||
TheCU->addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
|
||||
StartLabel);
|
||||
TheCU->addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
|
||||
EndLabel);
|
||||
TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_low_pc, StartLabel);
|
||||
TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_high_pc, EndLabel);
|
||||
}
|
||||
|
||||
InlinedSubprogramDIEs.insert(OriginDIE);
|
||||
@ -646,8 +655,8 @@ CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) {
|
||||
DIUnit.getLanguage());
|
||||
NewCU->addString(Die, dwarf::DW_AT_name, FN);
|
||||
// 2.17.1 requires that we use DW_AT_low_pc for a single entry point
|
||||
// into an entity.
|
||||
NewCU->addUInt(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0);
|
||||
// into an entity. We're using 0 (or a NULL label) for this.
|
||||
NewCU->addLabelAddress(Die, dwarf::DW_AT_low_pc, NULL);
|
||||
// DW_AT_stmt_list is a offset of line number information for this
|
||||
// compile unit in debug_line section.
|
||||
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
|
||||
@ -975,6 +984,9 @@ void DwarfDebug::endModule() {
|
||||
// Emit info into a debug macinfo section.
|
||||
emitDebugMacInfo();
|
||||
|
||||
// Emit DWO addresses.
|
||||
InfoHolder.emitAddresses(Asm->getObjFileLowering().getDwarfAddrSection());
|
||||
|
||||
// Emit inline info.
|
||||
// TODO: When we don't need the option anymore we
|
||||
// can remove all of the code that this section
|
||||
@ -1234,14 +1246,14 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
}
|
||||
|
||||
// Return Label preceding the instruction.
|
||||
const MCSymbol *DwarfDebug::getLabelBeforeInsn(const MachineInstr *MI) {
|
||||
MCSymbol *DwarfDebug::getLabelBeforeInsn(const MachineInstr *MI) {
|
||||
MCSymbol *Label = LabelsBeforeInsn.lookup(MI);
|
||||
assert(Label && "Didn't insert label before instruction");
|
||||
return Label;
|
||||
}
|
||||
|
||||
// Return Label immediately following the instruction.
|
||||
const MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) {
|
||||
MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) {
|
||||
return LabelsAfterInsn.lookup(MI);
|
||||
}
|
||||
|
||||
@ -2158,7 +2170,7 @@ void DwarfUnits::emitStrings(const MCSection *StrSection,
|
||||
if (OffsetSection) {
|
||||
Asm->OutStreamer.SwitchSection(OffsetSection);
|
||||
unsigned offset = 0;
|
||||
unsigned size = 4;
|
||||
unsigned size = 4; // FIXME: DWARF64 is 8.
|
||||
for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
|
||||
Asm->OutStreamer.EmitIntValue(offset, size);
|
||||
offset += Entries[i].second->getKeyLength() + 1;
|
||||
@ -2166,6 +2178,38 @@ void DwarfUnits::emitStrings(const MCSection *StrSection,
|
||||
}
|
||||
}
|
||||
|
||||
// Emit strings into a string section.
|
||||
void DwarfUnits::emitAddresses(const MCSection *AddrSection) {
|
||||
|
||||
if (AddressPool.empty()) return;
|
||||
|
||||
// Start the dwarf addr section.
|
||||
Asm->OutStreamer.SwitchSection(AddrSection);
|
||||
|
||||
// Get all of the string pool entries and put them in an array by their ID so
|
||||
// we can sort them.
|
||||
SmallVector<std::pair<unsigned,
|
||||
std::pair<MCSymbol*, unsigned>* >, 64> Entries;
|
||||
|
||||
for (DenseMap<MCSymbol*, std::pair<MCSymbol*, unsigned> >::iterator
|
||||
I = AddressPool.begin(), E = AddressPool.end();
|
||||
I != E; ++I)
|
||||
Entries.push_back(std::make_pair(I->second.second, &(I->second)));
|
||||
|
||||
array_pod_sort(Entries.begin(), Entries.end());
|
||||
|
||||
for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
|
||||
// Emit a label for reference from debug information entries.
|
||||
MCSymbol *Sym = Entries[i].second->first;
|
||||
if (Sym)
|
||||
Asm->EmitLabelReference(Entries[i].second->first,
|
||||
Asm->getDataLayout().getPointerSize());
|
||||
else
|
||||
Asm->OutStreamer.EmitIntValue(0, Asm->getDataLayout().getPointerSize());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Emit visible names into a debug str section.
|
||||
void DwarfDebug::emitDebugStr() {
|
||||
DwarfUnits &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
|
||||
@ -2402,8 +2446,9 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const MDNode *N) {
|
||||
// FIXME: We also need DW_AT_addr_base and DW_AT_dwo_id.
|
||||
|
||||
// 2.17.1 requires that we use DW_AT_low_pc for a single entry point
|
||||
// into an entity.
|
||||
// into an entity. We're using 0, or a NULL label for this.
|
||||
NewCU->addUInt(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0);
|
||||
|
||||
// DW_AT_stmt_list is a offset of line number information for this
|
||||
// compile unit in debug_line section.
|
||||
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
|
||||
|
@ -195,6 +195,10 @@ public:
|
||||
typedef StringMap<std::pair<MCSymbol*, unsigned>,
|
||||
BumpPtrAllocator&> StrPool;
|
||||
|
||||
// A Symbol->pair<Symbol, unsigned> mapping of addresses used by indirect
|
||||
// references.
|
||||
typedef DenseMap<MCSymbol *, std::pair<MCSymbol *, unsigned> > AddrPool;
|
||||
|
||||
/// \brief Collects and handles information specific to a particular
|
||||
/// collection of units.
|
||||
class DwarfUnits {
|
||||
@ -215,12 +219,17 @@ class DwarfUnits {
|
||||
unsigned NextStringPoolNumber;
|
||||
std::string StringPref;
|
||||
|
||||
// Collection of addresses for this unit and assorted labels.
|
||||
AddrPool AddressPool;
|
||||
unsigned NextAddrPoolNumber;
|
||||
|
||||
public:
|
||||
DwarfUnits(AsmPrinter *AP, FoldingSet<DIEAbbrev> *AS,
|
||||
std::vector<DIEAbbrev *> *A, const char *Pref,
|
||||
BumpPtrAllocator &DA) :
|
||||
Asm(AP), AbbreviationsSet(AS), Abbreviations(A),
|
||||
StringPool(DA), NextStringPoolNumber(0), StringPref(Pref) {}
|
||||
StringPool(DA), NextStringPoolNumber(0), StringPref(Pref),
|
||||
AddressPool(), NextAddrPoolNumber(0) {}
|
||||
|
||||
/// \brief Compute the size and offset of a DIE given an incoming Offset.
|
||||
unsigned computeSizeAndOffset(DIE *Die, unsigned Offset);
|
||||
@ -242,6 +251,9 @@ public:
|
||||
/// \brief Emit all of the strings to the section given.
|
||||
void emitStrings(const MCSection *, const MCSection *, const MCSymbol *);
|
||||
|
||||
/// \brief Emit all of the addresses to the section given.
|
||||
void emitAddresses(const MCSection *);
|
||||
|
||||
/// \brief Returns the entry into the start of the pool.
|
||||
MCSymbol *getStringPoolSym();
|
||||
|
||||
@ -255,6 +267,13 @@ public:
|
||||
|
||||
/// \brief Returns the string pool.
|
||||
StrPool *getStringPool() { return &StringPool; }
|
||||
|
||||
/// \brief Returns the index into the address pool with the given
|
||||
/// label/symbol.
|
||||
unsigned getAddrPoolIndex(MCSymbol *);
|
||||
|
||||
/// \brief Returns the address pool.
|
||||
AddrPool *getAddrPool() { return &AddressPool; }
|
||||
};
|
||||
|
||||
/// \brief Collects and handles dwarf debug information.
|
||||
@ -560,7 +579,7 @@ private:
|
||||
}
|
||||
|
||||
/// \brief Return Label preceding the instruction.
|
||||
const MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
|
||||
MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
|
||||
|
||||
/// \brief Ensure that a label will be emitted after MI.
|
||||
void requestLabelAfterInsn(const MachineInstr *MI) {
|
||||
@ -568,7 +587,7 @@ private:
|
||||
}
|
||||
|
||||
/// \brief Return Label immediately following the instruction.
|
||||
const MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
|
||||
MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
|
||||
|
||||
public:
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -29,6 +29,7 @@ class DWARFCompileUnit {
|
||||
StringRef RangeSection;
|
||||
StringRef StringSection;
|
||||
StringRef StringOffsetSection;
|
||||
StringRef AddrOffsetSection;
|
||||
const RelocAddrMap *RelocMap;
|
||||
bool isLittleEndian;
|
||||
|
||||
@ -43,16 +44,17 @@ class DWARFCompileUnit {
|
||||
public:
|
||||
|
||||
DWARFCompileUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS,
|
||||
StringRef RS, StringRef SS, StringRef SOS,
|
||||
StringRef RS, StringRef SS, StringRef SOS, StringRef AOS,
|
||||
const RelocAddrMap *M, bool LE) :
|
||||
Abbrev(DA), InfoSection(IS), AbbrevSection(AS),
|
||||
RangeSection(RS), StringSection(SS), StringOffsetSection(SOS),
|
||||
RelocMap(M), isLittleEndian(LE) {
|
||||
AddrOffsetSection(AOS), RelocMap(M), isLittleEndian(LE) {
|
||||
clear();
|
||||
}
|
||||
|
||||
StringRef getStringSection() const { return StringSection; }
|
||||
StringRef getStringOffsetSection() const { return StringOffsetSection; }
|
||||
StringRef getAddrOffsetSection() const { return AddrOffsetSection; }
|
||||
const RelocAddrMap *getRelocMap() const { return RelocMap; }
|
||||
DataExtractor getDebugInfoExtractor() const;
|
||||
|
||||
|
@ -86,6 +86,14 @@ void DWARFContext::dump(raw_ostream &OS) {
|
||||
OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
|
||||
strDWOOffset = offset;
|
||||
}
|
||||
|
||||
OS << "\n.debug_str_offsets.dwo contents:\n";
|
||||
DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(), 0);
|
||||
offset = 0;
|
||||
while (offset < getStringOffsetDWOSection().size()) {
|
||||
OS << format("0x%8.8x: ", offset);
|
||||
OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
|
||||
}
|
||||
}
|
||||
|
||||
const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
|
||||
@ -152,7 +160,8 @@ void DWARFContext::parseCompileUnits() {
|
||||
while (DIData.isValidOffset(offset)) {
|
||||
CUs.push_back(DWARFCompileUnit(getDebugAbbrev(), getInfoSection(),
|
||||
getAbbrevSection(), getRangeSection(),
|
||||
getStringSection(), "",
|
||||
getStringSection(), StringRef(),
|
||||
getAddrSection(),
|
||||
&infoRelocMap(),
|
||||
isLittleEndian()));
|
||||
if (!CUs.back().extract(DIData, &offset)) {
|
||||
@ -174,6 +183,7 @@ void DWARFContext::parseDWOCompileUnits() {
|
||||
getRangeDWOSection(),
|
||||
getStringDWOSection(),
|
||||
getStringOffsetDWOSection(),
|
||||
getAddrSection(),
|
||||
&infoDWORelocMap(),
|
||||
isLittleEndian()));
|
||||
if (!DWOCUs.back().extract(DIData, &offset)) {
|
||||
@ -386,6 +396,8 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
|
||||
StringDWOSection = data;
|
||||
else if (name == "debug_str_offsets.dwo")
|
||||
StringOffsetDWOSection = data;
|
||||
else if (name == "debug_addr")
|
||||
AddrSection = data;
|
||||
// Any more debug info sections go here.
|
||||
else
|
||||
continue;
|
||||
|
@ -108,6 +108,7 @@ public:
|
||||
virtual StringRef getStringDWOSection() = 0;
|
||||
virtual StringRef getStringOffsetDWOSection() = 0;
|
||||
virtual StringRef getRangeDWOSection() = 0;
|
||||
virtual StringRef getAddrSection() = 0;
|
||||
virtual const RelocAddrMap &infoDWORelocMap() const = 0;
|
||||
|
||||
static bool isSupportedVersion(unsigned version) {
|
||||
@ -143,6 +144,7 @@ class DWARFContextInMemory : public DWARFContext {
|
||||
StringRef StringDWOSection;
|
||||
StringRef StringOffsetDWOSection;
|
||||
StringRef RangeDWOSection;
|
||||
StringRef AddrSection;
|
||||
|
||||
public:
|
||||
DWARFContextInMemory(object::ObjectFile *);
|
||||
@ -163,6 +165,9 @@ public:
|
||||
return StringOffsetDWOSection;
|
||||
}
|
||||
virtual StringRef getRangeDWOSection() { return RangeDWOSection; }
|
||||
virtual StringRef getAddrSection() {
|
||||
return AddrSection;
|
||||
}
|
||||
virtual const RelocAddrMap &infoDWORelocMap() const {
|
||||
return InfoDWORelocMap;
|
||||
}
|
||||
|
@ -325,6 +325,16 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const {
|
||||
|
||||
switch (Form) {
|
||||
case DW_FORM_addr: OS << format("0x%016" PRIx64, uvalue); break;
|
||||
case DW_FORM_GNU_addr_index: {
|
||||
StringRef AddrOffsetSec = cu->getAddrOffsetSection();
|
||||
OS << format(" indexed (%8.8x) address = ", (uint32_t)uvalue);
|
||||
if (AddrOffsetSec.size() != 0) {
|
||||
DataExtractor DA(AddrOffsetSec, true, cu->getAddressByteSize());
|
||||
OS << format("0x%016" PRIx64, getIndirectAddress(&DA, cu));
|
||||
} else
|
||||
OS << "<no .debug_addr section>";
|
||||
break;
|
||||
}
|
||||
case DW_FORM_flag_present: OS << "true"; break;
|
||||
case DW_FORM_flag:
|
||||
case DW_FORM_data1: OS << format("0x%02x", (uint8_t)uvalue); break;
|
||||
@ -452,10 +462,19 @@ DWARFFormValue::getIndirectCString(const DataExtractor *DS,
|
||||
if (!DS || !DSO) return NULL;
|
||||
|
||||
uint32_t offset = Value.uval * 4;
|
||||
uint32_t soffset = DSO->getULEB128(&offset);
|
||||
uint32_t soffset = DSO->getU32(&offset);
|
||||
return DS->getCStr(&soffset);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
DWARFFormValue::getIndirectAddress(const DataExtractor *DA,
|
||||
const DWARFCompileUnit *cu) const {
|
||||
if (!DA) return 0;
|
||||
|
||||
uint32_t offset = Value.uval * cu->getAddressByteSize();
|
||||
return DA->getAddress(&offset);
|
||||
}
|
||||
|
||||
uint64_t DWARFFormValue::getReference(const DWARFCompileUnit *cu) const {
|
||||
uint64_t die_offset = Value.uval;
|
||||
switch (Form) {
|
||||
|
@ -66,6 +66,8 @@ public:
|
||||
const char *getAsCString(const DataExtractor *debug_str_data_ptr) const;
|
||||
const char *getIndirectCString(const DataExtractor *,
|
||||
const DataExtractor *) const;
|
||||
uint64_t getIndirectAddress(const DataExtractor *,
|
||||
const DWARFCompileUnit *) const;
|
||||
bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr,
|
||||
const DWARFCompileUnit *cu) const;
|
||||
static bool skipValue(uint16_t form, DataExtractor debug_info_data,
|
||||
|
@ -437,6 +437,9 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
|
||||
DwarfStrOffDWOSection =
|
||||
Ctx->getELFSection(".debug_str_offsets.dwo", ELF::SHT_PROGBITS, 0,
|
||||
SectionKind::getMetadata());
|
||||
DwarfAddrSection =
|
||||
Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0,
|
||||
SectionKind::getMetadata());
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,14 +26,52 @@
|
||||
; CHECK: DW_AT_stmt_list [DW_FORM_data4] (0x00000000)
|
||||
; CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000006] = "/usr/local/google/home/echristo/tmp")
|
||||
|
||||
; Check that we're using the right forms.
|
||||
; CHECK: .debug_abbrev.dwo contents:
|
||||
; CHECK: Abbrev table for offset: 0x00000000
|
||||
; CHECK: [1] DW_TAG_compile_unit DW_CHILDREN_yes
|
||||
; CHECK: DW_AT_producer DW_FORM_GNU_str_index
|
||||
; CHECK: DW_AT_language DW_FORM_data2
|
||||
; CHECK: DW_AT_name DW_FORM_GNU_str_index
|
||||
; CHECK: DW_AT_low_pc DW_FORM_GNU_addr_index
|
||||
; CHECK: DW_AT_stmt_list DW_FORM_data4
|
||||
; CHECK: DW_AT_comp_dir DW_FORM_GNU_str_index
|
||||
|
||||
; CHECK: [2] DW_TAG_base_type DW_CHILDREN_no
|
||||
; CHECK: DW_AT_name DW_FORM_GNU_str_index
|
||||
; CHECK: DW_AT_encoding DW_FORM_data1
|
||||
; CHECK: DW_AT_byte_size DW_FORM_data1
|
||||
|
||||
; CHECK: [3] DW_TAG_variable DW_CHILDREN_no
|
||||
; CHECK: DW_AT_name DW_FORM_GNU_str_index
|
||||
; CHECK: DW_AT_type DW_FORM_ref4
|
||||
; CHECK: DW_AT_external DW_FORM_flag_present
|
||||
; CHECK: DW_AT_decl_file DW_FORM_data1
|
||||
; CHECK: DW_AT_decl_line DW_FORM_data1
|
||||
; CHECK: DW_AT_location DW_FORM_block1
|
||||
|
||||
; Check that the rest of the compile units have information.
|
||||
; FIXME: Strings will ultimately be a different form.
|
||||
; CHECK: .debug_info.dwo contents:
|
||||
; CHECK: DW_TAG_compile_unit
|
||||
; CHECK: DW_AT_producer [DW_FORM_GNU_str_index] ( indexed (00000000) string = "clang version 3.3 (trunk 169021) (llvm/trunk 169020)")
|
||||
; CHECK: DW_AT_language [DW_FORM_data2] (0x000c)
|
||||
; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000001) string = "baz.c")
|
||||
; CHECK: DW_AT_low_pc [DW_FORM_GNU_addr_index] ( indexed (00000000) address = 0x0000000000000000)
|
||||
; CHECK: DW_TAG_base_type
|
||||
; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000004) string = "int")
|
||||
; CHECK: DW_TAG_variable
|
||||
; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000003) string = "a")
|
||||
|
||||
; CHECK: .debug_str.dwo contents:
|
||||
; CHECK: 0x00000000: "clang version 3.3 (trunk 169021) (llvm/trunk 169020)"
|
||||
; CHECK: 0x00000035: "baz.c"
|
||||
; CHECK: 0x0000003b: "/usr/local/google/home/echristo/tmp"
|
||||
; CHECK: 0x0000005f: "a"
|
||||
; CHECK: 0x00000061: "int"
|
||||
|
||||
; CHECK: .debug_str_offsets.dwo contents:
|
||||
; CHECK: 0x00000000: 00000000
|
||||
; CHECK: 0x00000004: 00000035
|
||||
; CHECK: 0x00000008: 0000003b
|
||||
; CHECK: 0x0000000c: 0000005f
|
||||
; CHECK: 0x00000010: 00000061
|
||||
|
Loading…
Reference in New Issue
Block a user