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:
Eric Christopher
2013-01-15 23:56:56 +00:00
parent af50dda410
commit 72f7bfbf0e
13 changed files with 204 additions and 28 deletions

View File

@ -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())