[PATCH] D43438: [dsymutil] Correctly handle DW_TAG_label
Jonas Devlieghere via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 18 05:02:46 PST 2018
JDevlieghere created this revision.
JDevlieghere added reviewers: aprantl, davide.
This patch contains logic for handling DW_TAG_label that's present in darwin's dsymutil implementation, but not yet upstream.
It's missing a test case because I'm unable to generate a DW_TAG_label (https://llvm.org/PR36420). I'd like to get that fixed before checking this in, but I figured I'd already created the diff.
Repository:
rL LLVM
https://reviews.llvm.org/D43438
Files:
tools/dsymutil/DwarfLinker.cpp
Index: tools/dsymutil/DwarfLinker.cpp
===================================================================
--- tools/dsymutil/DwarfLinker.cpp
+++ tools/dsymutil/DwarfLinker.cpp
@@ -327,6 +327,7 @@
uint64_t getLowPc() const { return LowPc; }
uint64_t getHighPc() const { return HighPc; }
+ bool hasLabelAt(uint64_t Addr) const { return Labels.count(Addr); }
Optional<PatchLocation> getUnitRangesAttribute() const {
return UnitRangeAttribute;
@@ -366,6 +367,10 @@
/// Apply all fixups recored by noteForwardReference().
void fixupForwardReferences();
+ /// Add the low_pc of a label that is relocatad by applying
+ /// offset \p PCOffset.
+ void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset);
+
/// Add a function range [\p LowPC, \p HighPC) that is relocatad by applying
/// offset \p PCOffset.
void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset);
@@ -471,6 +476,9 @@
/// to the addresses to get the linked address.
FunctionIntervals Ranges;
+ /// The DW_AT_low_pc of each DW_TAG_label.
+ SmallDenseMap<uint64_t, uint64_t, 1> Labels;
+
/// DW_AT_ranges attributes to patch after we have gathered
/// all the unit's function addresses.
/// @{
@@ -585,6 +593,10 @@
}
}
+void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
+ Labels.insert({LabelLowPc, PcOffset});
+}
+
void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
int64_t PcOffset) {
Ranges.insert(FuncLowPc, FuncHighPc, PcOffset);
@@ -2458,7 +2470,7 @@
return Flags;
uint32_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
- const DWARFUnit &OrigUnit = Unit.getOrigUnit();
+ DWARFUnit &OrigUnit = Unit.getOrigUnit();
uint32_t LowPcOffset, LowPcEndOffset;
std::tie(LowPcOffset, LowPcEndOffset) =
getAttributeOffsets(Abbrev, *LowPcIdx, Offset, OrigUnit);
@@ -2476,6 +2488,21 @@
DIE.dump(outs(), 8 /* Indent */, DumpOpts);
}
+ if (DIE.getTag() == dwarf::DW_TAG_label) {
+ if (Unit.hasLabelAt(*LowPc))
+ return Flags;
+ // FIXME: dsymutil-classic compat. dsymutil-classic doesn't
+ // consider labels that don't fall into the CU's aranges. This is
+ // wrong IMO. Debug info generation bugs pu aside, this is really
+ // wrong in the case of labels, where a label marking the end of a
+ // function will have a PC == CU's high_pc.
+ if (dwarf::toAddress(OrigUnit.getUnitDIE().find(dwarf::DW_AT_high_pc))
+ .getValueOr(UINT64_MAX) <= LowPc)
+ return Flags;
+ Unit.addLabelLowPc(*LowPc, MyInfo.AddrAdjust);
+ return Flags | TF_Keep;
+ }
+
Flags |= TF_Keep;
Optional<uint64_t> HighPc = DIE.getHighPC(*LowPc);
@@ -2503,6 +2530,7 @@
case dwarf::DW_TAG_variable:
return shouldKeepVariableDIE(RelocMgr, DIE, Unit, MyInfo, Flags);
case dwarf::DW_TAG_subprogram:
+ case dwarf::DW_TAG_label:
return shouldKeepSubprogramDIE(RelocMgr, DIE, Unit, MyInfo, Flags);
case dwarf::DW_TAG_imported_module:
case dwarf::DW_TAG_imported_declaration:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D43438.134831.patch
Type: text/x-patch
Size: 3083 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180218/9b11ec3d/attachment-0001.bin>
More information about the llvm-commits
mailing list