[llvm] r232193 - [dsymutil] Fix handling of cross-cu forward references.
Frederic Riss
friss at apple.com
Fri Mar 13 11:35:57 PDT 2015
Author: friss
Date: Fri Mar 13 13:35:57 2015
New Revision: 232193
URL: http://llvm.org/viewvc/llvm-project?rev=232193&view=rev
Log:
[dsymutil] Fix handling of cross-cu forward references.
We recorded the forward references in the CU that holds the referenced
DIE, but this is wrong as those will get resoled *after* the CU that
holds the reference. Record the references in their originating CU along
with a pointer to the remote CU to be able to compute the fixed up
offset at the right time.
Modified:
llvm/trunk/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test
llvm/trunk/tools/dsymutil/DwarfLinker.cpp
Modified: llvm/trunk/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test?rev=232193&r1=232192&r2=232193&view=diff
==============================================================================
--- llvm/trunk/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test (original)
+++ llvm/trunk/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test Fri Mar 13 13:35:57 2015
@@ -5,7 +5,6 @@ CHECK: file format Mach-O 64-bit x86-64
CHECK: debug_info contents
CHECK: Compile Unit: {{.*}} version = 0x0004
-
CHECK: DW_TAG_compile_unit [1] *
CHECK: DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000001] = "clang version 3.7.0 ")
CHECK: DW_AT_language [DW_FORM_data2] (DW_LANG_C99)
@@ -19,15 +18,19 @@ CHECK: DW_AT_high_pc [DW_FORM_data4
CHECK: DW_AT_frame_base [DW_FORM_exprloc] (<0x1> 56 )
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000027] = "main")
CHECK: DW_AT_prototyped [DW_FORM_flag_present] (true)
+CHECK: DW_AT_type [DW_FORM_ref_addr] (0x00000000000000a1)
CHECK: DW_AT_external [DW_FORM_flag_present] (true)
CHECK: DW_TAG_formal_parameter [3]
CHECK: DW_AT_location [DW_FORM_exprloc] (<0x3> 55 93 04 )
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000002c] = "argc")
+CHECK: DW_AT_type [DW_FORM_ref_addr] (0x00000000000000a1)
CHECK: DW_TAG_formal_parameter [4]
CHECK: DW_AT_location [DW_FORM_exprloc] (<0x1> 54 )
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000031] = "argv")
+CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x0060 => {0x00000060})
CHECK: NULL
-CHECK: DW_TAG_pointer_type [5]
+CHECK: DW_TAG_pointer_type [5]
+CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x0065 => {0x00000065})
CHECK: DW_TAG_pointer_type [5]
CHECK: DW_TAG_const_type [6]
CHECK: DW_TAG_base_type [7]
Modified: llvm/trunk/tools/dsymutil/DwarfLinker.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=232193&r1=232192&r2=232193&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/DwarfLinker.cpp (original)
+++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp Fri Mar 13 13:35:57 2015
@@ -33,6 +33,7 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include <string>
+#include <tuple>
namespace llvm {
namespace dsymutil {
@@ -70,8 +71,8 @@ public:
};
CompileUnit(DWARFUnit &OrigUnit)
- : OrigUnit(OrigUnit), LowPc(UINT64_MAX), HighPc(0), RangeAlloc(),
- Ranges(RangeAlloc) {
+ : OrigUnit(OrigUnit), LowPc(UINT64_MAX), HighPc(0), RangeAlloc(),
+ Ranges(RangeAlloc) {
Info.resize(OrigUnit.getNumDIEs());
}
@@ -106,10 +107,11 @@ public:
/// debug_info section size).
uint64_t computeNextUnitOffset();
- /// \brief Keep track of a forward reference to DIE \p Die by
- /// \p Attr. The attribute should be fixed up later to point to the
- /// absolute offset of \p Die in the debug_info section.
- void noteForwardReference(DIE *Die, DIEInteger *Attr);
+ /// \brief Keep track of a forward reference to DIE \p Die in \p
+ /// RefUnit by \p Attr. The attribute should be fixed up later to
+ /// point to the absolute offset of \p Die in the debug_info section.
+ void noteForwardReference(DIE *Die, const CompileUnit *RefUnit,
+ DIEInteger *Attr);
/// \brief Apply all fixups recored by noteForwardReference().
void fixupForwardReferences();
@@ -133,9 +135,10 @@ private:
/// a DIE in the debug_info section.
///
/// The offsets for the attributes in this array couldn't be set while
- /// cloning because for forward refences the target DIE's offset isn't
- /// known you emit the reference attribute.
- std::vector<std::pair<DIE *, DIEInteger *>> ForwardDIEReferences;
+ /// cloning because for cross-cu forward refences the target DIE's
+ /// offset isn't known you emit the reference attribute.
+ std::vector<std::tuple<DIE *, const CompileUnit *, DIEInteger *>>
+ ForwardDIEReferences;
HalfOpenIntervalMap<uint64_t, int64_t>::Allocator RangeAlloc;
/// \brief The ranges in that interval map are the PC ranges for
@@ -154,15 +157,22 @@ uint64_t CompileUnit::computeNextUnitOff
return NextUnitOffset;
}
-/// \brief Keep track of a forward reference to \p Die.
-void CompileUnit::noteForwardReference(DIE *Die, DIEInteger *Attr) {
- ForwardDIEReferences.emplace_back(Die, Attr);
+/// \brief Keep track of a forward cross-cu reference from this unit
+/// to \p Die that lives in \p RefUnit.
+void CompileUnit::noteForwardReference(DIE *Die, const CompileUnit *RefUnit,
+ DIEInteger *Attr) {
+ ForwardDIEReferences.emplace_back(Die, RefUnit, Attr);
}
/// \brief Apply all fixups recorded by noteForwardReference().
void CompileUnit::fixupForwardReferences() {
- for (const auto &Ref : ForwardDIEReferences)
- Ref.second->setValue(Ref.first->getOffset() + getStartOffset());
+ for (const auto &Ref : ForwardDIEReferences) {
+ DIE *RefDie;
+ const CompileUnit *RefUnit;
+ DIEInteger *Attr;
+ std::tie(RefDie, RefUnit, Attr) = Ref;
+ Attr->setValue(RefDie->getOffset() + RefUnit->getStartOffset());
+ }
}
void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
@@ -598,7 +608,7 @@ private:
cloneDieReferenceAttribute(DIE &Die,
const DWARFDebugInfoEntryMinimal &InputDIE,
AttributeSpec AttrSpec, unsigned AttrSize,
- const DWARFFormValue &Val, const DWARFUnit &U);
+ const DWARFFormValue &Val, CompileUnit &Unit);
/// \brief Helper for cloneDIE.
unsigned cloneBlockAttribute(DIE &Die, AttributeSpec AttrSpec,
@@ -1169,8 +1179,8 @@ unsigned DwarfLinker::cloneStringAttribu
unsigned DwarfLinker::cloneDieReferenceAttribute(
DIE &Die, const DWARFDebugInfoEntryMinimal &InputDIE,
AttributeSpec AttrSpec, unsigned AttrSize, const DWARFFormValue &Val,
- const DWARFUnit &U) {
- uint32_t Ref = *Val.getAsReference(&U);
+ CompileUnit &Unit) {
+ uint32_t Ref = *Val.getAsReference(&Unit.getOrigUnit());
DIE *NewRefDie = nullptr;
CompileUnit *RefUnit = nullptr;
const DWARFDebugInfoEntryMinimal *RefDie = nullptr;
@@ -1182,7 +1192,7 @@ unsigned DwarfLinker::cloneDieReferenceA
AttributeString = "DW_AT_???";
reportWarning(Twine("Missing DIE for ref in attribute ") + AttributeString +
". Dropping.",
- &U, &InputDIE);
+ &Unit.getOrigUnit(), &InputDIE);
return 0;
}
@@ -1211,7 +1221,7 @@ unsigned DwarfLinker::cloneDieReferenceA
} else {
// A forward reference. Note and fixup later.
Attr = new (DIEAlloc) DIEInteger(0xBADDEF);
- RefUnit->noteForwardReference(NewRefDie, Attr);
+ Unit.noteForwardReference(NewRefDie, RefUnit, Attr);
}
Die.addValue(dwarf::Attribute(AttrSpec.Attr), dwarf::DW_FORM_ref_addr,
Attr);
@@ -1346,7 +1356,7 @@ unsigned DwarfLinker::cloneAttribute(DIE
case dwarf::DW_FORM_ref4:
case dwarf::DW_FORM_ref8:
return cloneDieReferenceAttribute(Die, InputDIE, AttrSpec, AttrSize, Val,
- U);
+ Unit);
case dwarf::DW_FORM_block:
case dwarf::DW_FORM_block1:
case dwarf::DW_FORM_block2:
More information about the llvm-commits
mailing list