--- /dev/null
+# 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 }
+...
+
--- /dev/null
+/* 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
+
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.
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.
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)
// 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