diff options
-rw-r--r-- | llvm/test/tools/dsymutil/ARM/dummy-debug-map-amr64.map | 15 | ||||
-rw-r--r-- | llvm/test/tools/dsymutil/ARM/inlined-low_pc.c | 15 | ||||
-rw-r--r-- | llvm/test/tools/dsymutil/ARM/lit.local.cfg | 3 | ||||
-rw-r--r-- | llvm/test/tools/dsymutil/Inputs/inlined-low_pc/1.o | bin | 0 -> 1960 bytes | |||
-rw-r--r-- | llvm/tools/dsymutil/DwarfLinker.cpp | 17 |
5 files changed, 47 insertions, 3 deletions
diff --git a/llvm/test/tools/dsymutil/ARM/dummy-debug-map-amr64.map b/llvm/test/tools/dsymutil/ARM/dummy-debug-map-amr64.map new file mode 100644 index 00000000000..a23e0c34c3f --- /dev/null +++ b/llvm/test/tools/dsymutil/ARM/dummy-debug-map-amr64.map @@ -0,0 +1,15 @@ +# This is a dummy debug map used for some tests where the contents of the +# map are just an implementation detail. The tests wanting to use that file +# should put all there object files in an explicitely named sub-directory +# of Inputs, and they should be named 1.o, 2.o, ... +# As not finding an object file or symbols isn't a fatal error for dsymutil, +# you can extend this file with as much object files and symbols as needed. + +--- +triple: 'arm64-apple-darwin' +objects: + - filename: 1.o + symbols: + - { sym: _bar, objAddr: 0x0, binAddr: 0x10000, size: 0x10 } +... + diff --git a/llvm/test/tools/dsymutil/ARM/inlined-low_pc.c b/llvm/test/tools/dsymutil/ARM/inlined-low_pc.c new file mode 100644 index 00000000000..7ade33e3e44 --- /dev/null +++ b/llvm/test/tools/dsymutil/ARM/inlined-low_pc.c @@ -0,0 +1,15 @@ +/* Compiled with: clang -arch=arm64 -O2 -g -c inlined_low_pc.c */ + +static int foo(int i) { return 42 + i; } +int bar(int a) { return foo(a); } + +// RUN: llvm-dsymutil -f -y %p/dummy-debug-map-amr64.map -oso-prepend-path %p/../Inputs/inlined-low_pc -o - | llvm-dwarfdump - | FileCheck %s + +// CHECK: DW_TAG_subprogram +// CHECK: DW_AT_low_pc{{.*}}0x0000000000010000 +// CHECK: DW_AT_name{{.*}}"bar" +// CHECK-NOT: NULL +// CHECK: DW_TAG_inlined_subroutine +// CHECK-NEXT: DW_AT_abstract_origin{{.*}}"foo" +// CHECK-NEXT: DW_AT_low_pc{{.*}}0x0000000000010000 + diff --git a/llvm/test/tools/dsymutil/ARM/lit.local.cfg b/llvm/test/tools/dsymutil/ARM/lit.local.cfg index b704ac4031f..442cd554bfe 100644 --- a/llvm/test/tools/dsymutil/ARM/lit.local.cfg +++ b/llvm/test/tools/dsymutil/ARM/lit.local.cfg @@ -2,3 +2,6 @@ if not 'ARM' in config.root.targets: config.unsupported = True if not 'AArch64' in config.root.targets: config.unsupported = True + +config.suffixes = ['.test', '.cpp', '.c'] + diff --git a/llvm/test/tools/dsymutil/Inputs/inlined-low_pc/1.o b/llvm/test/tools/dsymutil/Inputs/inlined-low_pc/1.o Binary files differnew file mode 100644 index 00000000000..7ab4e9205bb --- /dev/null +++ b/llvm/test/tools/dsymutil/Inputs/inlined-low_pc/1.o diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp index 0be12375b26..1e171db44c4 100644 --- a/llvm/tools/dsymutil/DwarfLinker.cpp +++ b/llvm/tools/dsymutil/DwarfLinker.cpp @@ -1206,6 +1206,7 @@ private: const char *Name, *MangledName; ///< Names. uint32_t NameOffset, MangledNameOffset; ///< Offsets in the string pool. + uint64_t OrigLowPc; ///< Value of AT_low_pc in the input DIE uint64_t OrigHighPc; ///< Value of AT_high_pc in the input DIE int64_t PCOffset; ///< Offset to apply to PC addresses inside a function. @@ -1214,8 +1215,8 @@ private: AttributesInfo() : Name(nullptr), MangledName(nullptr), NameOffset(0), - MangledNameOffset(0), OrigHighPc(0), PCOffset(0), HasLowPc(false), - IsDeclaration(false) {} + MangledNameOffset(0), OrigLowPc(UINT64_MAX), OrigHighPc(0), + PCOffset(0), HasLowPc(false), IsDeclaration(false) {} }; /// \brief Helper for cloneDIE. @@ -2274,7 +2275,12 @@ unsigned DwarfLinker::cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec, 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; + // The low_pc of a block or inline subroutine might get + // relocated because it happens to match the low_pc of the + // enclosing subprogram. To prevent issues with that, always use + // the low_pc from the input DIE if relocations have been applied. + Addr = (Info.OrigLowPc != UINT64_MAX ? Info.OrigLowPc : Addr) + + Info.PCOffset; else if (Die.getTag() == dwarf::DW_TAG_compile_unit) { Addr = Unit.getLowPc(); if (Addr == UINT64_MAX) @@ -2522,6 +2528,11 @@ DIE *DwarfLinker::cloneDIE(const DWARFDebugInfoEntryMinimal &InputDIE, // high_pc value is done in cloneAddressAttribute(). AttrInfo.OrigHighPc = InputDIE.getAttributeValueAsAddress(&U, dwarf::DW_AT_high_pc, 0); + // Also store the low_pc. It might get relocated in an + // inline_subprogram that happens at the beginning of its + // inlining function. + AttrInfo.OrigLowPc = + InputDIE.getAttributeValueAsAddress(&U, dwarf::DW_AT_low_pc, UINT64_MAX); } // Reset the Offset to 0 as we will be working on the local copy of |