[llvm] 3c5e3b7 - llvm-symbolizer: access the base address from the skeleton CU, not the split unit
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Thu May 25 18:03:23 PDT 2023
Author: David Blaikie
Date: 2023-05-26T00:59:40Z
New Revision: 3c5e3b70a3591869526bca72d36fc664aeff02bd
URL: https://github.com/llvm/llvm-project/commit/3c5e3b70a3591869526bca72d36fc664aeff02bd
DIFF: https://github.com/llvm/llvm-project/commit/3c5e3b70a3591869526bca72d36fc664aeff02bd.diff
LOG: llvm-symbolizer: access the base address from the skeleton CU, not the split unit
In Split DWARF, if the unit had a non-trivial base address (a real
low_pc, rather than one with fixed value 0) then computing addresses
needs to access that base address to add to any base address-relative
values. But the code was trying to access the base address in the split
unit, when it's actually in the skeleton unit. So delegate to the
skeleton if it's available.
Fixes #62941
Added:
llvm/test/tools/llvm-symbolizer/split-dwarf-base-addr.s
Modified:
llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
Removed:
################################################################################
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 2fc26fd86ba3d..e2f17ca2e1358 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -1049,7 +1049,7 @@ std::optional<object::SectionedAddress> DWARFUnit::getBaseAddress() {
if (BaseAddr)
return BaseAddr;
- DWARFDie UnitDie = getUnitDIE();
+ DWARFDie UnitDie = (SU ? SU : this)->getUnitDIE();
std::optional<DWARFFormValue> PC =
UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
BaseAddr = toSectionedAddress(PC);
diff --git a/llvm/test/tools/llvm-symbolizer/split-dwarf-base-addr.s b/llvm/test/tools/llvm-symbolizer/split-dwarf-base-addr.s
new file mode 100644
index 0000000000000..79481afaa05eb
--- /dev/null
+++ b/llvm/test/tools/llvm-symbolizer/split-dwarf-base-addr.s
@@ -0,0 +1,351 @@
+# RUN: rm -rf %t
+# RUN: mkdir -p %t
+# RUN: llvm-mc %s -o %t/test.o -filetype=obj
+# RUN: cd %t
+
+# RUN: llvm-symbolizer -e test.o 0x30 | FileCheck %s
+
+# CHECK: f1()
+# CHECK: .{{/|\\}}test.cpp:6:3
+# CHECK: main
+# CHECK: .{{/|\\}}test.cpp:7:3
+
+
+ .text
+ .zero 42
+ .file "test.cpp"
+ .file 0 "./" "test.cpp" md5 0x03b7c6de668697331888d80c6ad0d69e
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+.Lfunc_begin0:
+ .cfi_startproc
+# %bb.0: # %entry
+ .loc 0 6 3 prologue_end # test.cpp:6:3
+ incl i(%rip)
+.Ltmp0:
+ .loc 0 3 3 # test.cpp:3:3
+ incl i(%rip)
+.Ltmp1:
+ .loc 0 8 1 # test.cpp:8:1
+ xorl %eax, %eax
+ retq
+.Ltmp2:
+.Lfunc_end0:
+ .size main, .Lfunc_end0-main
+ .cfi_endproc
+ # -- End function
+ .type i, at object # @i
+ .bss
+ .globl i
+ .p2align 2, 0x0
+i:
+ .long 0 # 0x0
+ .size i, 4
+
+ .section .debug_abbrev,"", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 74 # DW_TAG_skeleton_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .ascii "\264B" # DW_AT_GNU_pubnames
+ .byte 25 # DW_FORM_flag_present
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"", at progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 4 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .quad 6427667746655966506
+ .byte 1 # Abbrev [1] 0x14:0x14 DW_TAG_skeleton_unit
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .byte 0 # DW_AT_comp_dir
+ # DW_AT_GNU_pubnames
+ .byte 1 # DW_AT_dwo_name
+ .byte 1 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+.Ldebug_info_end0:
+ .section .debug_str_offsets,"", at progbits
+ .long 12 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS", at progbits,1
+.Lskel_string0:
+ .asciz "." # string offset=0
+.Lskel_string1:
+ .asciz "test.o" # string offset=43
+ .section .debug_str_offsets,"", at progbits
+ .long .Lskel_string0
+ .long .Lskel_string1
+ .section .debug_str_offsets.dwo,"e", at progbits
+ .long 36 # Length of String Offsets Set
+ .short 5
+ .short 0
+ .section .debug_str.dwo,"eMS", at progbits,1
+.Linfo_string0:
+ .asciz "i" # string offset=0
+.Linfo_string1:
+ .asciz "int" # string offset=2
+.Linfo_string2:
+ .asciz "_Z2f1v" # string offset=6
+.Linfo_string3:
+ .asciz "f1" # string offset=13
+.Linfo_string4:
+ .asciz "main" # string offset=16
+.Linfo_string5:
+ .asciz "clang version 17.0.0 (git at github.com:llvm/llvm-project.git 6963c61f0f6e4be2039cb45e824ea1e83a8f1526)" # string offset=21
+.Linfo_string6:
+ .asciz "test.cpp" # string offset=122
+.Linfo_string7:
+ .asciz "test.o" # string offset=131
+ .section .debug_str_offsets.dwo,"e", at progbits
+ .long 0
+ .long 2
+ .long 6
+ .long 13
+ .long 16
+ .long 21
+ .long 122
+ .long 131
+ .section .debug_info.dwo,"e", at progbits
+ .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+ .short 5 # DWARF version number
+ .byte 5 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad 6427667746655966506
+ .byte 1 # Abbrev [1] 0x14:0x39 DW_TAG_compile_unit
+ .byte 5 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 6 # DW_AT_name
+ .byte 7 # DW_AT_dwo_name
+ .byte 2 # Abbrev [2] 0x1a:0xb DW_TAG_variable
+ .byte 0 # DW_AT_name
+ .long 37 # DW_AT_type
+ # DW_AT_external
+ .byte 0 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 161
+ .byte 0
+ .byte 3 # Abbrev [3] 0x25:0x5 DW_TAG_volatile_type
+ .long 42 # DW_AT_type
+ .byte 4 # Abbrev [4] 0x2a:0x4 DW_TAG_base_type
+ .byte 1 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 5 # Abbrev [5] 0x2e:0x5 DW_TAG_subprogram
+ .byte 2 # DW_AT_linkage_name
+ .byte 3 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ # DW_AT_external
+ # DW_AT_inline
+ .byte 6 # Abbrev [6] 0x33:0x19 DW_TAG_subprogram
+ .byte 1 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_call_all_calls
+ .byte 4 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 5 # DW_AT_decl_line
+ .long 42 # DW_AT_type
+ # DW_AT_external
+ .byte 7 # Abbrev [7] 0x42:0x9 DW_TAG_inlined_subroutine
+ .long 46 # DW_AT_abstract_origin
+ .byte 0 # DW_AT_ranges
+ .byte 0 # DW_AT_call_file
+ .byte 7 # DW_AT_call_line
+ .byte 3 # DW_AT_call_column
+ .byte 0 # End Of Children Mark
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end0:
+ .section .debug_abbrev.dwo,"e", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 53 # DW_TAG_volatile_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 0 # DW_CHILDREN_no
+ .byte 110 # DW_AT_linkage_name
+ .byte 37 # DW_FORM_strx1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 32 # DW_AT_inline
+ .byte 33 # DW_FORM_implicit_const
+ .byte 1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 122 # DW_AT_call_all_calls
+ .byte 25 # DW_FORM_flag_present
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 29 # DW_TAG_inlined_subroutine
+ .byte 0 # DW_CHILDREN_no
+ .byte 49 # DW_AT_abstract_origin
+ .byte 19 # DW_FORM_ref4
+ .byte 85 # DW_AT_ranges
+ .byte 35 # DW_FORM_rnglistx
+ .byte 88 # DW_AT_call_file
+ .byte 11 # DW_FORM_data1
+ .byte 89 # DW_AT_call_line
+ .byte 11 # DW_FORM_data1
+ .byte 87 # DW_AT_call_column
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_rnglists.dwo,"e", at progbits
+ .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
+.Ldebug_list_header_start0:
+ .short 5 # Version
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+ .long 1 # Offset entry count
+.Lrnglists_dwo_table_base0:
+ .long .Ldebug_ranges0-.Lrnglists_dwo_table_base0
+.Ldebug_ranges0:
+ .byte 4 # DW_RLE_offset_pair
+ .uleb128 .Ltmp0-.Lfunc_begin0 # starting offset
+ .uleb128 .Ltmp1-.Lfunc_begin0 # ending offset
+ .byte 0 # DW_RLE_end_of_list
+.Ldebug_list_header_end0:
+ .section .debug_addr,"", at progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad i
+ .quad 42
+.Ldebug_addr_end0:
+ .section .debug_gnu_pubnames,"", at progbits
+ .long .LpubNames_end0-.LpubNames_start0 # Length of Public Names Info
+.LpubNames_start0:
+ .short 2 # DWARF Version
+ .long .Lcu_begin0 # Offset of Compilation Unit Info
+ .long 40 # Compilation Unit Length
+ .long 46 # DIE offset
+ .byte 48 # Attributes: FUNCTION, EXTERNAL
+ .asciz "f1" # External Name
+ .long 26 # DIE offset
+ .byte 32 # Attributes: VARIABLE, EXTERNAL
+ .asciz "i" # External Name
+ .long 51 # DIE offset
+ .byte 48 # Attributes: FUNCTION, EXTERNAL
+ .asciz "main" # External Name
+ .long 0 # End Mark
+.LpubNames_end0:
+ .section .debug_gnu_pubtypes,"", at progbits
+ .long .LpubTypes_end0-.LpubTypes_start0 # Length of Public Types Info
+.LpubTypes_start0:
+ .short 2 # DWARF Version
+ .long .Lcu_begin0 # Offset of Compilation Unit Info
+ .long 40 # Compilation Unit Length
+ .long 42 # DIE offset
+ .byte 144 # Attributes: TYPE, STATIC
+ .asciz "int" # External Name
+ .long 0 # End Mark
+.LpubTypes_end0:
+ .ident "clang version 17.0.0 (git at github.com:llvm/llvm-project.git 6963c61f0f6e4be2039cb45e824ea1e83a8f1526)"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym i
+ .section .debug_line,"", at progbits
+.Lline_table_start0:
More information about the llvm-commits
mailing list