Reapply DW_AT_low/high_pc patch:

Use the range machinery for DW_AT_ranges and DW_AT_high/lo_pc.

    This commit moves us from a single range per subprogram to extending
    ranges if we are:

    a) In the same section, and
    b) In the same enclosing CU.

    This means we have more fine grained ranges for compile units, and fewer
    ranges overall when we have multiple functions in the same CU
    adjacent to each other in the object file.

    Also remove all of the earlier hacks around this functionality for
    function sections etc. Also update all of the testcases to take into
    account the merging functionality.

with a fix for location entries in the debug_loc section:

Make sure that debug loc entries are relative to the low_pc
of the compile unit. This means that when we only have a single
range that the offset should be just relative to the low_pc
of the unit, for multiple ranges for a CU this means that we'll be
relative to 0 which we emit along with DW_AT_ranges.

This mostly shows up with linked binaries, so add a testcase with
multiple CUs so that our location is going to be offset of a CU
with a non-zero low_pc.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204377 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Christopher
2014-03-20 19:16:16 +00:00
parent 0b087184ce
commit 8b97f004cb
11 changed files with 398 additions and 164 deletions

View File

@ -282,22 +282,31 @@ void DwarfUnit::addSectionOffset(DIE *Die, dwarf::Attribute Attribute,
/// DW_FORM_addr or DW_FORM_GNU_addr_index.
///
void DwarfCompileUnit::addLabelAddress(DIE *Die, dwarf::Attribute Attribute,
MCSymbol *Label) {
const MCSymbol *Label) {
if (!DD->useSplitDwarf())
return addLocalLabelAddress(Die, Attribute, Label);
if (Label)
DD->addArangeLabel(SymbolCU(this, Label));
if (!DD->useSplitDwarf()) {
if (Label) {
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);
}
unsigned idx = DU->getAddrPoolIndex(Label);
DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx);
Die->addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value);
}
void DwarfCompileUnit::addLocalLabelAddress(DIE *Die,
dwarf::Attribute Attribute,
const MCSymbol *Label) {
if (Label)
DD->addArangeLabel(SymbolCU(this, Label));
if (Label) {
DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
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);
DIEValue *Value = new (DIEValueAllocator) DIEInteger(0);
Die->addValue(Attribute, dwarf::DW_FORM_addr, Value);
}
}
@ -2034,6 +2043,27 @@ void DwarfUnit::emitHeader(const MCSection *ASection,
Asm->EmitInt8(Asm->getDataLayout().getPointerSize());
}
void DwarfUnit::addRange(RangeSpan Range) {
// Only add a range for this unit if we're emitting full debug.
if (getCUNode().getEmissionKind() == DIBuilder::FullDebug) {
// If we have no current ranges just add the range and return, otherwise,
// check the current section and CU against the previous section and CU we
// emitted into and the subprogram was contained within. If these are the
// same then extend our current range, otherwise add this as a new range.
if (CURanges.size() == 0 ||
this != DD->getPrevCU() ||
Asm->getCurrentSection() != DD->getPrevSection()) {
CURanges.push_back(Range);
return;
}
assert(&(CURanges.back().getEnd()->getSection()) ==
&(Range.getEnd()->getSection()) &&
"We can only append to a range in the same section!");
CURanges.back().setEnd(Range.getEnd());
}
}
void DwarfCompileUnit::initStmtList(MCSymbol *DwarfLineSectionSym) {
// Define start line table label for each Compile Unit.
MCSymbol *LineTableStartSym =