mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-05 13:26:55 +00:00
In Dwarf 3 (and Dwarf 2) attributes whose value are offsets into a
section use the form DW_FORM_data4 whilst in Dwarf 4 and later they use the form DW_FORM_sec_offset. This patch updates the places where such attributes are generated to use the appropriate form depending on the Dwarf version. The DIE entries affected have the following tags: DW_AT_stmt_list, DW_AT_ranges, DW_AT_location, DW_AT_GNU_pubnames, DW_AT_GNU_pubtypes, DW_AT_GNU_addr_base, DW_AT_GNU_ranges_base It also adds a hidden command line option "--dwarf-version=<uint>" to llc which allows the version of Dwarf to be generated to override what is specified in the metadata; this makes it possible to update existing tests to check the debugging information generated for both Dwarf 4 (the default) and Dwarf 3 using the same metadata. Patch (slightly modified) by Keith Walker! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195391 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -341,6 +341,7 @@ void DIEDelta::EmitValue(AsmPrinter *AP, dwarf::Form Form) const {
|
||||
///
|
||||
unsigned DIEDelta::SizeOf(AsmPrinter *AP, dwarf::Form Form) const {
|
||||
if (Form == dwarf::DW_FORM_data4) return 4;
|
||||
if (Form == dwarf::DW_FORM_sec_offset) return 4;
|
||||
if (Form == dwarf::DW_FORM_strp) return 4;
|
||||
return AP->getDataLayout().getPointerSize();
|
||||
}
|
||||
|
@@ -245,6 +245,26 @@ void CompileUnit::addLabel(DIEBlock *Die, dwarf::Form Form,
|
||||
addLabel(Die, (dwarf::Attribute)0, Form, Label);
|
||||
}
|
||||
|
||||
/// addSectionLabel - Add a Dwarf section label attribute data and value.
|
||||
///
|
||||
void CompileUnit::addSectionLabel(DIE *Die, dwarf::Attribute Attribute,
|
||||
const MCSymbol *Label) {
|
||||
if (DD->getDwarfVersion() >= 4)
|
||||
addLabel(Die, Attribute, dwarf::DW_FORM_sec_offset, Label);
|
||||
else
|
||||
addLabel(Die, Attribute, dwarf::DW_FORM_data4, Label);
|
||||
}
|
||||
|
||||
/// addSectionOffset - Add an offset into a section attribute data and value.
|
||||
///
|
||||
void CompileUnit::addSectionOffset(DIE *Die, dwarf::Attribute Attribute,
|
||||
uint64_t Integer) {
|
||||
if (DD->getDwarfVersion() >= 4)
|
||||
addUInt(Die, Attribute, dwarf::DW_FORM_sec_offset, Integer);
|
||||
else
|
||||
addUInt(Die, Attribute, dwarf::DW_FORM_data4, Integer);
|
||||
}
|
||||
|
||||
/// addLabelAddress - Add a dwarf label attribute data and value using
|
||||
/// DW_FORM_addr or DW_FORM_GNU_addr_index.
|
||||
///
|
||||
@@ -282,13 +302,15 @@ void CompileUnit::addOpAddress(DIEBlock *Die, const MCSymbol *Sym) {
|
||||
}
|
||||
}
|
||||
|
||||
/// addDelta - Add a label delta attribute data and value.
|
||||
/// addSectionDelta - Add a section label delta attribute data and value.
|
||||
///
|
||||
void CompileUnit::addDelta(DIE *Die, dwarf::Attribute Attribute,
|
||||
dwarf::Form Form, const MCSymbol *Hi,
|
||||
const MCSymbol *Lo) {
|
||||
void CompileUnit::addSectionDelta(DIE *Die, dwarf::Attribute Attribute,
|
||||
const MCSymbol *Hi, const MCSymbol *Lo) {
|
||||
DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
|
||||
Die->addValue(Attribute, Form, Value);
|
||||
if (DD->getDwarfVersion() >= 4)
|
||||
Die->addValue(Attribute, dwarf::DW_FORM_sec_offset, Value);
|
||||
else
|
||||
Die->addValue(Attribute, dwarf::DW_FORM_data4, Value);
|
||||
}
|
||||
|
||||
/// addDIEEntry - Add a DIE attribute data and value.
|
||||
@@ -1814,10 +1836,8 @@ DIE *CompileUnit::constructVariableDIE(DbgVariable &DV, bool isScopeAbstract) {
|
||||
|
||||
unsigned Offset = DV.getDotDebugLocOffset();
|
||||
if (Offset != ~0U) {
|
||||
addLabel(VariableDie, dwarf::DW_AT_location,
|
||||
DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
|
||||
: dwarf::DW_FORM_data4,
|
||||
Asm->GetTempSymbol("debug_loc", Offset));
|
||||
addSectionLabel(VariableDie, dwarf::DW_AT_location,
|
||||
Asm->GetTempSymbol("debug_loc", Offset));
|
||||
DV.setDIE(VariableDie);
|
||||
return VariableDie;
|
||||
}
|
||||
|
@@ -212,6 +212,14 @@ public:
|
||||
|
||||
void addLabel(DIEBlock *Die, dwarf::Form Form, const MCSymbol *Label);
|
||||
|
||||
/// addSectionLabel - Add a Dwarf section label attribute data and value.
|
||||
///
|
||||
void addSectionLabel(DIE *Die, dwarf::Attribute Attribute, const MCSymbol *Label);
|
||||
|
||||
/// addSectionOffset - Add an offset into a section attribute data and value.
|
||||
///
|
||||
void addSectionOffset(DIE *Die, dwarf::Attribute Attribute, uint64_t Integer);
|
||||
|
||||
/// addLabelAddress - Add a dwarf label attribute data and value using
|
||||
/// either DW_FORM_addr or DW_FORM_GNU_addr_index.
|
||||
void addLabelAddress(DIE *Die, dwarf::Attribute Attribute, MCSymbol *Label);
|
||||
@@ -220,9 +228,9 @@ public:
|
||||
/// form given and an op of either DW_FORM_addr or DW_FORM_GNU_addr_index.
|
||||
void addOpAddress(DIEBlock *Die, const MCSymbol *Label);
|
||||
|
||||
/// addDelta - Add a label delta attribute data and value.
|
||||
void addDelta(DIE *Die, dwarf::Attribute Attribute, dwarf::Form Form,
|
||||
const MCSymbol *Hi, const MCSymbol *Lo);
|
||||
/// addSectionDelta - Add a label delta attribute data and value.
|
||||
void addSectionDelta(DIE *Die, dwarf::Attribute Attribute, const MCSymbol *Hi,
|
||||
const MCSymbol *Lo);
|
||||
|
||||
/// addDIEEntry - Add a DIE attribute data and value.
|
||||
void addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIE *Entry);
|
||||
|
@@ -104,6 +104,11 @@ DwarfPubSections("generate-dwarf-pub-sections", cl::Hidden,
|
||||
clEnumVal(Disable, "Disabled"), clEnumValEnd),
|
||||
cl::init(Default));
|
||||
|
||||
static cl::opt<unsigned>
|
||||
DwarfVersionNumber("dwarf-version", cl::Hidden,
|
||||
cl::desc("Generate DWARF for dwarf version."),
|
||||
cl::init(0));
|
||||
|
||||
static const char *const DWARFGroupName = "DWARF Emission";
|
||||
static const char *const DbgTimerName = "DWARF Debug Writer";
|
||||
|
||||
@@ -212,7 +217,9 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
|
||||
else
|
||||
HasDwarfPubSections = DwarfPubSections == Enable;
|
||||
|
||||
DwarfVersion = getDwarfVersionFromModule(MMI->getModule());
|
||||
DwarfVersion = DwarfVersionNumber
|
||||
? DwarfVersionNumber
|
||||
: getDwarfVersionFromModule(MMI->getModule());
|
||||
|
||||
{
|
||||
NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
|
||||
@@ -470,9 +477,9 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU,
|
||||
// .debug_range section has not been laid out yet. Emit offset in
|
||||
// .debug_range as a uint, size 4, for now. emitDIE will handle
|
||||
// DW_AT_ranges appropriately.
|
||||
TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
|
||||
DebugRangeSymbols.size() *
|
||||
Asm->getDataLayout().getPointerSize());
|
||||
TheCU->addSectionOffset(ScopeDIE, dwarf::DW_AT_ranges,
|
||||
DebugRangeSymbols.size() *
|
||||
Asm->getDataLayout().getPointerSize());
|
||||
for (SmallVectorImpl<InsnRange>::const_iterator RI = Ranges.begin(),
|
||||
RE = Ranges.end();
|
||||
RI != RE; ++RI) {
|
||||
@@ -526,9 +533,9 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU,
|
||||
// .debug_range section has not been laid out yet. Emit offset in
|
||||
// .debug_range as a uint, size 4, for now. emitDIE will handle
|
||||
// DW_AT_ranges appropriately.
|
||||
TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
|
||||
DebugRangeSymbols.size() *
|
||||
Asm->getDataLayout().getPointerSize());
|
||||
TheCU->addSectionOffset(ScopeDIE, dwarf::DW_AT_ranges,
|
||||
DebugRangeSymbols.size() *
|
||||
Asm->getDataLayout().getPointerSize());
|
||||
for (SmallVectorImpl<InsnRange>::const_iterator RI = Ranges.begin(),
|
||||
RE = Ranges.end();
|
||||
RI != RE; ++RI) {
|
||||
@@ -766,14 +773,15 @@ CompileUnit *DwarfDebug::constructCompileUnit(DICompileUnit DIUnit) {
|
||||
// The line table entries are not always emitted in assembly, so it
|
||||
// is not okay to use line_table_start here.
|
||||
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
|
||||
NewCU->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset,
|
||||
UseTheFirstCU ? Asm->GetTempSymbol("section_line")
|
||||
: LineTableStartSym);
|
||||
NewCU->addSectionLabel(
|
||||
Die, dwarf::DW_AT_stmt_list,
|
||||
UseTheFirstCU ? Asm->GetTempSymbol("section_line")
|
||||
: LineTableStartSym);
|
||||
else if (UseTheFirstCU)
|
||||
NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);
|
||||
NewCU->addSectionOffset(Die, dwarf::DW_AT_stmt_list, 0);
|
||||
else
|
||||
NewCU->addDelta(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4,
|
||||
LineTableStartSym, DwarfLineSectionSym);
|
||||
NewCU->addSectionDelta(Die, dwarf::DW_AT_stmt_list,
|
||||
LineTableStartSym, DwarfLineSectionSym);
|
||||
|
||||
// If we're using split dwarf the compilation dir is going to be in the
|
||||
// skeleton CU and so we don't need to duplicate it here.
|
||||
@@ -784,22 +792,22 @@ CompileUnit *DwarfDebug::constructCompileUnit(DICompileUnit DIUnit) {
|
||||
// emit it here if we don't have a skeleton CU for split dwarf.
|
||||
if (GenerateGnuPubSections) {
|
||||
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
|
||||
NewCU->addLabel(
|
||||
Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_sec_offset,
|
||||
NewCU->addSectionLabel(
|
||||
Die, dwarf::DW_AT_GNU_pubnames,
|
||||
Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()));
|
||||
else
|
||||
NewCU->addDelta(
|
||||
Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_data4,
|
||||
NewCU->addSectionDelta(
|
||||
Die, dwarf::DW_AT_GNU_pubnames,
|
||||
Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()),
|
||||
DwarfGnuPubNamesSectionSym);
|
||||
|
||||
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
|
||||
NewCU->addLabel(
|
||||
Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_sec_offset,
|
||||
NewCU->addSectionLabel(
|
||||
Die, dwarf::DW_AT_GNU_pubtypes,
|
||||
Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()));
|
||||
else
|
||||
NewCU->addDelta(
|
||||
Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_data4,
|
||||
NewCU->addSectionDelta(
|
||||
Die, dwarf::DW_AT_GNU_pubtypes,
|
||||
Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()),
|
||||
DwarfGnuPubTypesSectionSym);
|
||||
}
|
||||
@@ -2957,11 +2965,10 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const CompileUnit *CU) {
|
||||
// Relocate to the beginning of the addr_base section, else 0 for the
|
||||
// beginning of the one for this compile unit.
|
||||
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
|
||||
NewCU->addLabel(Die, dwarf::DW_AT_GNU_addr_base, dwarf::DW_FORM_sec_offset,
|
||||
DwarfAddrSectionSym);
|
||||
NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_addr_base,
|
||||
DwarfAddrSectionSym);
|
||||
else
|
||||
NewCU->addUInt(Die, dwarf::DW_AT_GNU_addr_base, dwarf::DW_FORM_sec_offset,
|
||||
0);
|
||||
NewCU->addSectionOffset(Die, dwarf::DW_AT_GNU_addr_base, 0);
|
||||
|
||||
// 2.17.1 requires that we use DW_AT_low_pc for a single entry point
|
||||
// into an entity. We're using 0, or a NULL label for this.
|
||||
@@ -2971,10 +2978,10 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const CompileUnit *CU) {
|
||||
// compile unit in debug_line section.
|
||||
// FIXME: Should handle multiple compile units.
|
||||
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
|
||||
NewCU->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset,
|
||||
DwarfLineSectionSym);
|
||||
NewCU->addSectionLabel(Die, dwarf::DW_AT_stmt_list,
|
||||
DwarfLineSectionSym);
|
||||
else
|
||||
NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset, 0);
|
||||
NewCU->addSectionOffset(Die, dwarf::DW_AT_stmt_list, 0);
|
||||
|
||||
if (!CompilationDir.empty())
|
||||
NewCU->addLocalString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
|
||||
@@ -2982,27 +2989,31 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const CompileUnit *CU) {
|
||||
// Flags to let the linker know we have emitted new style pubnames.
|
||||
if (GenerateGnuPubSections) {
|
||||
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
|
||||
NewCU->addLabel(Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_sec_offset,
|
||||
Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()));
|
||||
NewCU->addSectionLabel(
|
||||
Die, dwarf::DW_AT_GNU_pubnames,
|
||||
Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()));
|
||||
else
|
||||
NewCU->addDelta(Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_data4,
|
||||
Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()),
|
||||
DwarfGnuPubNamesSectionSym);
|
||||
NewCU->addSectionDelta(
|
||||
Die, dwarf::DW_AT_GNU_pubnames,
|
||||
Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()),
|
||||
DwarfGnuPubNamesSectionSym);
|
||||
|
||||
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
|
||||
NewCU->addLabel(Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_sec_offset,
|
||||
Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()));
|
||||
NewCU->addSectionLabel(
|
||||
Die, dwarf::DW_AT_GNU_pubtypes,
|
||||
Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()));
|
||||
else
|
||||
NewCU->addDelta(Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_data4,
|
||||
Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()),
|
||||
DwarfGnuPubTypesSectionSym);
|
||||
NewCU->addSectionDelta(
|
||||
Die, dwarf::DW_AT_GNU_pubtypes,
|
||||
Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()),
|
||||
DwarfGnuPubTypesSectionSym);
|
||||
}
|
||||
|
||||
// Flag if we've emitted any ranges and their location for the compile unit.
|
||||
if (DebugRangeSymbols.size()) {
|
||||
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
|
||||
NewCU->addLabel(Die, dwarf::DW_AT_GNU_ranges_base,
|
||||
dwarf::DW_FORM_sec_offset, DwarfDebugRangeSectionSym);
|
||||
NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_ranges_base,
|
||||
DwarfDebugRangeSectionSym);
|
||||
else
|
||||
NewCU->addUInt(Die, dwarf::DW_AT_GNU_ranges_base, dwarf::DW_FORM_data4,
|
||||
0);
|
||||
|
Reference in New Issue
Block a user