[dsymutil][DWARFv5] fix DW_FORM_addrx attribute offset calculation.
authorAlexey Lapshin <a.v.lapshin@mail.ru>
Wed, 24 Aug 2022 21:36:13 +0000 (00:36 +0300)
committerAlexey Lapshin <a.v.lapshin@mail.ru>
Fri, 26 Aug 2022 12:26:06 +0000 (15:26 +0300)
DWARFLinker::DIECloner::cloneAddressAttribute() contains call to
relocateIndexedAddr(StartOffset, EndOffset). StartOffset is
incorrectly calculated. Val.getRawUValue() is an index into the
.debug_addr table, so it should be multiplied
by Unit.getOrigUnit().getAddressByteSize().

Differential Revision: https://reviews.llvm.org/D132644

llvm/lib/DWARFLinker/DWARFLinker.cpp
llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5-addrx.o [new file with mode: 0644]
llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5-addrx.out [new file with mode: 0755]
llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5.o [deleted file]
llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5.out [deleted file]
llvm/test/tools/dsymutil/X86/dwarf5-addrx.test [new file with mode: 0644]
llvm/test/tools/dsymutil/X86/dwarf5.test [deleted file]

index 495a582..a6f2100 100644 (file)
@@ -1109,7 +1109,9 @@ unsigned DWARFLinker::DIECloner::cloneAddressAttribute(
   if (Form == dwarf::DW_FORM_addrx) {
     if (Optional<uint64_t> AddrOffsetSectionBase =
             Unit.getOrigUnit().getAddrOffsetSectionBase()) {
-      uint64_t StartOffset = *AddrOffsetSectionBase + Val.getRawUValue();
+      uint64_t StartOffset =
+          *AddrOffsetSectionBase +
+          Val.getRawUValue() * Unit.getOrigUnit().getAddressByteSize();
       uint64_t EndOffset =
           StartOffset + Unit.getOrigUnit().getAddressByteSize();
       if (llvm::Expected<uint64_t> RelocAddr =
@@ -1120,7 +1122,8 @@ unsigned DWARFLinker::DIECloner::cloneAddressAttribute(
     } else
       Linker.reportWarning("no base offset for address table", ObjFile);
 
-    // If this is an indexed address emit the debug_info address.
+    // Generation of DWARFv5 .debug_addr table is not supported yet.
+    // Convert attribute into the dwarf::DW_FORM_addr.
     Form = dwarf::DW_FORM_addr;
   } else
     Addr = *Val.getAsAddress();
diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5-addrx.o b/llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5-addrx.o
new file mode 100644 (file)
index 0000000..d7636e5
Binary files /dev/null and b/llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5-addrx.o differ
diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5-addrx.out b/llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5-addrx.out
new file mode 100755 (executable)
index 0000000..4755103
Binary files /dev/null and b/llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5-addrx.out differ
diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5.o b/llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5.o
deleted file mode 100644 (file)
index 1f47f6a..0000000
Binary files a/llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5.o and /dev/null differ
diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5.out b/llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5.out
deleted file mode 100755 (executable)
index 420395f..0000000
Binary files a/llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5.out and /dev/null differ
diff --git a/llvm/test/tools/dsymutil/X86/dwarf5-addrx.test b/llvm/test/tools/dsymutil/X86/dwarf5-addrx.test
new file mode 100644 (file)
index 0000000..292f760
--- /dev/null
@@ -0,0 +1,89 @@
+## Test that DWARF5 DW_FORM_addrx is correctly recognized
+## and converted into the DW_FORM_addr
+
+## $ cat dwarf5-addrx.c
+## __attribute__ ((optnone)) int foo1 ( ) {
+##   volatile int a = 0x1; return a;
+## }
+##
+## __attribute__ ((optnone)) int foo2 ( ) {
+##   volatile int a = 0x2; return a;
+## }
+##
+## __attribute__ ((optnone)) int foo3 ( ) {
+##   volatile int a = 0x3; return a;
+## }
+##
+## __attribute__ ((optnone)) int foo4 ( ) {
+##   volatile int a = 0x4; return a;
+## }
+##
+## __attribute__ ((optnone)) int foo5 ( ) {
+##   volatile int a = 0x5; return a;
+## }
+##
+## __attribute__ ((optnone)) int foo6 ( ) {
+##   volatile int a = 0x6; return a;
+## }
+##
+## __attribute__ ((optnone)) int foo7 ( ) {
+##   volatile int a = 0x7; return a;
+## }
+##
+## __attribute__ ((optnone)) int foo8 ( ) {
+##   volatile int a = 0x8; return a;
+## }
+##
+## int main ( void ) {
+##   return foo1()+foo2()+foo3()+foo4()+foo5()+foo6()+foo7()+foo8();
+## }
+##
+## $ clang -gdwarf-5 dwarf5-addrx.c -c -o dwarf5-addrx.o
+## $ clang dwarf5-addrx.o -o dwarf5-addrx.out
+
+RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/dwarf5/dwarf5-addrx.out -o %t.dSYM 2>&1 | FileCheck %s --allow-empty
+RUN: llvm-dwarfdump --verify %t.dSYM 2>&1 | FileCheck %s
+CHECK-NOT: error:
+
+RUN: llvm-dwarfdump --verbose %t.dSYM | FileCheck %s --check-prefix DWARF
+DWARF: DW_TAG_compile_unit
+DWARF:   DW_AT_name [DW_FORM_strp]  {{.*}}     "dwarf5-addrx.c"
+DWARF:   DW_AT_low_pc [DW_FORM_addr]     (0x0000000100000eb0)
+DWARF:   DW_AT_high_pc [DW_FORM_data4]   (0x00000103)
+DWARF:   DW_AT_addr_base [DW_FORM_sec_offset]   (0x00000008)
+DWARF:   DW_TAG_subprogram
+DWARF:     DW_AT_low_pc [DW_FORM_addr]     (0x0000000100000eb0)
+DWARF:     DW_AT_high_pc [DW_FORM_data4]   (0x00000010)
+DWARF:     DW_AT_name  [DW_FORM_strp] {{.*}}   "foo1"
+DWARF:   DW_TAG_subprogram
+DWARF:     DW_AT_low_pc [DW_FORM_addr]     (0x0000000100000ec0)
+DWARF:     DW_AT_high_pc [DW_FORM_data4]   (0x00000010)
+DWARF:     DW_AT_name  [DW_FORM_strp] {{.*}}   "foo2"
+DWARF:   DW_TAG_subprogram
+DWARF:     DW_AT_low_pc [DW_FORM_addr]     (0x0000000100000ed0)
+DWARF:     DW_AT_high_pc [DW_FORM_data4]   (0x00000010)
+DWARF:     DW_AT_name  [DW_FORM_strp] {{.*}}   "foo3"
+DWARF:   DW_TAG_subprogram
+DWARF:     DW_AT_low_pc  [DW_FORM_addr]    (0x0000000100000ee0)
+DWARF:     DW_AT_high_pc [DW_FORM_data4]   (0x00000010)
+DWARF:     DW_AT_name  [DW_FORM_strp] {{.*}}   "foo4"
+DWARF:   DW_TAG_subprogram
+DWARF:     DW_AT_low_pc [DW_FORM_addr]     (0x0000000100000ef0)
+DWARF:     DW_AT_high_pc  [DW_FORM_data4]  (0x00000010)
+DWARF:     DW_AT_name  [DW_FORM_strp] {{.*}}   "foo5"
+DWARF:   DW_TAG_subprogram
+DWARF:     DW_AT_low_pc  [DW_FORM_addr]    (0x0000000100000f00)
+DWARF:     DW_AT_high_pc [DW_FORM_data4]   (0x00000010)
+DWARF:     DW_AT_name  [DW_FORM_strp] {{.*}}   "foo6"
+DWARF:   DW_TAG_subprogram
+DWARF:     DW_AT_low_pc  [DW_FORM_addr]    (0x0000000100000f10)
+DWARF:     DW_AT_high_pc [DW_FORM_data4]   (0x00000010)
+DWARF:     DW_AT_name  [DW_FORM_strp] {{.*}}   "foo7"
+DWARF:   DW_TAG_subprogram
+DWARF:     DW_AT_low_pc  [DW_FORM_addr]    (0x0000000100000f20)
+DWARF:     DW_AT_high_pc [DW_FORM_data4]   (0x00000010)
+DWARF:     DW_AT_name  [DW_FORM_strp] {{.*}}   "foo8"
+DWARF:   DW_TAG_subprogram
+DWARF:     DW_AT_low_pc  [DW_FORM_addr]    (0x0000000100000f30)
+DWARF:     DW_AT_high_pc [DW_FORM_data4]   (0x00000083)
+DWARF:     DW_AT_name  [DW_FORM_strp] {{.*}}   "main"
diff --git a/llvm/test/tools/dsymutil/X86/dwarf5.test b/llvm/test/tools/dsymutil/X86/dwarf5.test
deleted file mode 100644 (file)
index a37b4f3..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-Test DWARF5 support in dsymutil. Currently this still generates an empty dSYM.
-
-$ cat dwarf5.c
-__attribute__ ((optnone))
-int foo() {
-  volatile i;
-  return i;
-}
-
-int main(int argc, char** argv) {
-  return foo();
-}
-
-$ clang -gdwarf-5 dwarf5.c -c -o dwarf5.o
-$ clang dwarf5.o -o dwarf5.out
-
-RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/dwarf5/dwarf5.out -o %t.dSYM 2>&1 | FileCheck %s --allow-empty
-RUN: llvm-dwarfdump --verify %t.dSYM 2>&1 | FileCheck %s
-CHECK-NOT: error:
-
-RUN: llvm-dwarfdump %t.dSYM | FileCheck %s --check-prefix DWARF
-DWARF: DW_TAG_compile_unit
-DWARF:   DW_AT_producer    ("clang version 12.0.0
-DWARF:   DW_AT_language    (DW_LANG_C99)
-DWARF:   DW_AT_name        ("dwarf5.c")
-DWARF:   DW_AT_LLVM_sysroot        ("/")
-DWARF:   DW_AT_stmt_list   (0x00000000)
-DWARF:   DW_AT_comp_dir    ("/private/tmp/dwarf5")
-DWARF:   DW_AT_low_pc      (0x0000000100003f80)
-DWARF:   DW_AT_high_pc     (0x0000000100003fb1)
-DWARF:   DW_AT_addr_base   (0x00000008)
-DWARF:   DW_TAG_subprogram
-DWARF:     DW_AT_name      ("foo")
-DWARF:     DW_AT_decl_file (0x00)
-DWARF:     DW_AT_decl_line (2)
-DWARF:     DW_AT_type      (0x00000091 "int")
-DWARF:     DW_AT_external  (true)
-DWARF:     DW_TAG_variable
-DWARF:       DW_AT_name    ("i")
-DWARF:       DW_AT_decl_file       (0x00)
-DWARF:       DW_AT_decl_line       (3)
-DWARF:       DW_AT_type    (0x00000098 "volatile int")
-DWARF:   DW_TAG_subprogram
-DWARF:     DW_AT_name      ("main")
-DWARF:     DW_AT_decl_file (0x00)
-DWARF:     DW_AT_decl_line (7)
-DWARF:     DW_AT_prototyped        (true)
-DWARF:     DW_AT_type      (0x00000091 "int")
-DWARF:     DW_AT_external  (true)
-DWARF:     DW_TAG_formal_parameter
-DWARF:       DW_AT_name    ("argc")
-DWARF:       DW_AT_decl_file       (0x00)
-DWARF:       DW_AT_decl_line       (7)
-DWARF:       DW_AT_type    (0x00000091 "int")
-DWARF:     DW_TAG_formal_parameter
-DWARF:       DW_AT_name    ("argv")
-DWARF:       DW_AT_decl_file       (0x00)
-DWARF:       DW_AT_decl_line       (7)
-DWARF:       DW_AT_type    (0x0000009d "char **")