forked from OSchip/llvm-project
[dsymutil] Add relocation of compile_units low_pc/high_pc.
They need to be handled specifically as they could vary pretty widely depending on how the linker moves functions around. llvm-svn: 232192
This commit is contained in:
parent
111a0a8305
commit
5a62dc3793
|
@ -17,6 +17,7 @@ CHECK: DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000001] = "Apple LL
|
|||
CHECK: DW_AT_language [DW_FORM_data2] (DW_LANG_C99)
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000040] = "basic1.c")
|
||||
CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000049] = "/Inputs")
|
||||
CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000100000ea0)
|
||||
CHECK: DW_TAG_subprogram [2] *
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000051] = "main")
|
||||
CHECK: DW_AT_decl_line [DW_FORM_data1] (23)
|
||||
|
@ -61,6 +62,7 @@ CHECK: DW_TAG_compile_unit [1] *
|
|||
CHECK: DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000001] = "Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)")
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000069] = "basic2.c")
|
||||
CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000049] = "/Inputs")
|
||||
CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000100000ed0)
|
||||
CHECK: DW_TAG_base_type [4]
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000060] = "int")
|
||||
CHECK: DW_TAG_variable [7]
|
||||
|
@ -97,6 +99,7 @@ CHECK: DW_TAG_compile_unit [1] *
|
|||
CHECK: DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000001] = "Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)")
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000008e] = "basic3.c")
|
||||
CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000049] = "/Inputs")
|
||||
CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000100000f40)
|
||||
CHECK: DW_TAG_variable [9]
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000097] = "val")
|
||||
CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x003c => {0x00000162})
|
||||
|
|
|
@ -11,6 +11,8 @@ CHECK: DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000001] = "clang versio
|
|||
CHECK: DW_AT_language [DW_FORM_data2] (DW_LANG_C99)
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000016] = "basic1.c")
|
||||
CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x0000001f] = "/Inputs")
|
||||
CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000100000f40)
|
||||
CHECK: DW_AT_high_pc [DW_FORM_data4] (0x0000000b)
|
||||
CHECK: DW_TAG_subprogram [2] *
|
||||
CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000100000f40)
|
||||
CHECK: DW_AT_high_pc [DW_FORM_data4] (0x0000000b)
|
||||
|
@ -40,6 +42,8 @@ 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)
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000003b] = "basic2.c")
|
||||
CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000100000f50)
|
||||
CHECK: DW_AT_high_pc [DW_FORM_data4] (0x00000037)
|
||||
CHECK: DW_TAG_base_type [7]
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000044] = "int")
|
||||
CHECK: DW_TAG_variable [8]
|
||||
|
@ -74,6 +78,8 @@ 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_name [DW_FORM_strp] ( .debug_str[0x00000064] = "basic3.c")
|
||||
CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000100000f90)
|
||||
CHECK: DW_AT_high_pc [DW_FORM_data4] (0x00000024)
|
||||
CHECK: DW_TAG_variable [13]
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000006d] = "val")
|
||||
CHECK: DW_AT_location [DW_FORM_exprloc] (<0x9> 03 04 10 00 00 01 00 00 00 )
|
||||
|
|
|
@ -11,6 +11,7 @@ CHECK: DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000001] = "Apple LL
|
|||
CHECK: DW_AT_language [DW_FORM_data2] (DW_LANG_C99)
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000040] = "basic1.c")
|
||||
CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000049] = "/Inputs")
|
||||
CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000100000f40)
|
||||
CHECK: DW_TAG_subprogram [2] *
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000051] = "main")
|
||||
CHECK: DW_AT_decl_line [DW_FORM_data1] (23)
|
||||
|
@ -52,6 +53,7 @@ CHECK: DW_TAG_compile_unit [1] *
|
|||
CHECK: DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000001] = "Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)")
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000069] = "basic2.c")
|
||||
CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000049] = "/Inputs")
|
||||
CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000100000f50)
|
||||
CHECK: DW_TAG_variable [7]
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000072] = "private_int")
|
||||
CHECK: DW_AT_type [DW_FORM_ref_addr] (0x0000000000000063)
|
||||
|
@ -87,6 +89,7 @@ CHECK: DW_TAG_compile_unit [1] *
|
|||
CHECK: DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000001] = "Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)")
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000008e] = "basic3.c")
|
||||
CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000049] = "/Inputs")
|
||||
CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000100000f90)
|
||||
CHECK: DW_TAG_variable [12]
|
||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000097] = "val")
|
||||
CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x003c => {0x00000176})
|
||||
|
|
|
@ -70,7 +70,8 @@ public:
|
|||
};
|
||||
|
||||
CompileUnit(DWARFUnit &OrigUnit)
|
||||
: OrigUnit(OrigUnit), RangeAlloc(), Ranges(RangeAlloc) {
|
||||
: OrigUnit(OrigUnit), LowPc(UINT64_MAX), HighPc(0), RangeAlloc(),
|
||||
Ranges(RangeAlloc) {
|
||||
Info.resize(OrigUnit.getNumDIEs());
|
||||
}
|
||||
|
||||
|
@ -94,6 +95,9 @@ public:
|
|||
uint64_t getStartOffset() const { return StartOffset; }
|
||||
uint64_t getNextUnitOffset() const { return NextUnitOffset; }
|
||||
|
||||
uint64_t getLowPc() const { return LowPc; }
|
||||
uint64_t getHighPc() const { return HighPc; }
|
||||
|
||||
void setStartOffset(uint64_t DebugInfoSize) { StartOffset = DebugInfoSize; }
|
||||
|
||||
/// \brief Compute the end offset for this unit. Must be
|
||||
|
@ -122,6 +126,9 @@ private:
|
|||
uint64_t StartOffset;
|
||||
uint64_t NextUnitOffset;
|
||||
|
||||
uint64_t LowPc;
|
||||
uint64_t HighPc;
|
||||
|
||||
/// \brief A list of attributes to fixup with the absolute offset of
|
||||
/// a DIE in the debug_info section.
|
||||
///
|
||||
|
@ -158,9 +165,11 @@ void CompileUnit::fixupForwardReferences() {
|
|||
Ref.second->setValue(Ref.first->getOffset() + getStartOffset());
|
||||
}
|
||||
|
||||
void CompileUnit::addFunctionRange(uint64_t LowPC, uint64_t HighPC,
|
||||
int64_t PCOffset) {
|
||||
Ranges.insert(LowPC, HighPC, PCOffset);
|
||||
void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
|
||||
int64_t PcOffset) {
|
||||
Ranges.insert(FuncLowPc, FuncHighPc, PcOffset);
|
||||
this->LowPc = std::min(LowPc, FuncLowPc + PcOffset);
|
||||
this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
|
||||
}
|
||||
|
||||
/// \brief A string table that doesn't need relocations.
|
||||
|
@ -603,7 +612,7 @@ private:
|
|||
/// \brief Helper for cloneDIE.
|
||||
unsigned cloneScalarAttribute(DIE &Die,
|
||||
const DWARFDebugInfoEntryMinimal &InputDIE,
|
||||
const DWARFUnit &U, AttributeSpec AttrSpec,
|
||||
const CompileUnit &U, AttributeSpec AttrSpec,
|
||||
const DWARFFormValue &Val, unsigned AttrSize);
|
||||
|
||||
/// \brief Helper for cloneDIE.
|
||||
|
@ -1258,16 +1267,27 @@ unsigned DwarfLinker::cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec,
|
|||
const DWARFFormValue &Val,
|
||||
const CompileUnit &Unit,
|
||||
AttributesInfo &Info) {
|
||||
int64_t Addr = *Val.getAsAddress(&Unit.getOrigUnit());
|
||||
uint64_t Addr = *Val.getAsAddress(&Unit.getOrigUnit());
|
||||
if (AttrSpec.Attr == dwarf::DW_AT_low_pc) {
|
||||
if (Die.getTag() == dwarf::DW_TAG_inlined_subroutine ||
|
||||
Die.getTag() == dwarf::DW_TAG_lexical_block)
|
||||
Addr += Info.PCOffset;
|
||||
else if (Die.getTag() == dwarf::DW_TAG_compile_unit) {
|
||||
Addr = Unit.getLowPc();
|
||||
if (Addr == UINT64_MAX)
|
||||
return 0;
|
||||
}
|
||||
} else if (AttrSpec.Attr == dwarf::DW_AT_high_pc) {
|
||||
// If we have a high_pc recorded for the input DIE, use
|
||||
// it. Otherwise (when no relocations where applied) just use the
|
||||
// one we just decoded.
|
||||
Addr = (Info.OrigHighPc ? Info.OrigHighPc : Addr) + Info.PCOffset;
|
||||
if (Die.getTag() == dwarf::DW_TAG_compile_unit) {
|
||||
if (uint64_t HighPc = Unit.getHighPc())
|
||||
Addr = HighPc;
|
||||
else
|
||||
return 0;
|
||||
} else
|
||||
// If we have a high_pc recorded for the input DIE, use
|
||||
// it. Otherwise (when no relocations where applied) just use the
|
||||
// one we just decoded.
|
||||
Addr = (Info.OrigHighPc ? Info.OrigHighPc : Addr) + Info.PCOffset;
|
||||
}
|
||||
|
||||
Die.addValue(static_cast<dwarf::Attribute>(AttrSpec.Attr),
|
||||
|
@ -1279,18 +1299,25 @@ unsigned DwarfLinker::cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec,
|
|||
/// \brief Clone a scalar attribute and add it to \p Die.
|
||||
/// \returns the size of the new attribute.
|
||||
unsigned DwarfLinker::cloneScalarAttribute(
|
||||
DIE &Die, const DWARFDebugInfoEntryMinimal &InputDIE, const DWARFUnit &U,
|
||||
AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize) {
|
||||
DIE &Die, const DWARFDebugInfoEntryMinimal &InputDIE,
|
||||
const CompileUnit &Unit, AttributeSpec AttrSpec, const DWARFFormValue &Val,
|
||||
unsigned AttrSize) {
|
||||
uint64_t Value;
|
||||
if (AttrSpec.Form == dwarf::DW_FORM_sec_offset)
|
||||
if (AttrSpec.Attr == dwarf::DW_AT_high_pc &&
|
||||
Die.getTag() == dwarf::DW_TAG_compile_unit) {
|
||||
if (Unit.getLowPc() == -1ULL)
|
||||
return 0;
|
||||
// Dwarf >= 4 high_pc is an size, not an address.
|
||||
Value = Unit.getHighPc() - Unit.getLowPc();
|
||||
} else if (AttrSpec.Form == dwarf::DW_FORM_sec_offset)
|
||||
Value = *Val.getAsSectionOffset();
|
||||
else if (AttrSpec.Form == dwarf::DW_FORM_sdata)
|
||||
Value = *Val.getAsSignedConstant();
|
||||
else if (auto OptionalValue = Val.getAsUnsignedConstant())
|
||||
Value = *OptionalValue;
|
||||
else {
|
||||
reportWarning("Unsupported scalar attribute form. Dropping attribute.", &U,
|
||||
&InputDIE);
|
||||
reportWarning("Unsupported scalar attribute form. Dropping attribute.",
|
||||
&Unit.getOrigUnit(), &InputDIE);
|
||||
return 0;
|
||||
}
|
||||
Die.addValue(dwarf::Attribute(AttrSpec.Attr), dwarf::Form(AttrSpec.Form),
|
||||
|
@ -1337,7 +1364,7 @@ unsigned DwarfLinker::cloneAttribute(DIE &Die,
|
|||
case dwarf::DW_FORM_sec_offset:
|
||||
case dwarf::DW_FORM_flag:
|
||||
case dwarf::DW_FORM_flag_present:
|
||||
return cloneScalarAttribute(Die, InputDIE, U, AttrSpec, Val, AttrSize);
|
||||
return cloneScalarAttribute(Die, InputDIE, Unit, AttrSpec, Val, AttrSize);
|
||||
default:
|
||||
reportWarning("Unsupported attribute form in cloneAttribute. Dropping.", &U,
|
||||
&InputDIE);
|
||||
|
|
Loading…
Reference in New Issue