From c79296b4514b69ebe2db80c5006d8c87c5947690 Mon Sep 17 00:00:00 2001 From: Andy Yankovsky Date: Tue, 2 Mar 2021 14:28:34 +0100 Subject: [PATCH] [lldb] Fix handling of `DW_AT_decl_file` according to D91014 (attempt #2) Apply changes from https://reviews.llvm.org/D91014 to other places where DWARF entries are being processed. Test case is provided by @jankratochvil. The test is marked to run only on x64 and exclude Windows and Darwin, because the assembly is not OS-independent. (First attempt https://reviews.llvm.org/D96778 broke the build bots) Reviewed By: jankratochvil Differential Revision: https://reviews.llvm.org/D97765 --- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 3 +- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 4 +- ...decl_file-DW_AT_abstract_origin-crosscu1.s | 171 ++++++++++++++++++ ...decl_file-DW_AT_abstract_origin-crosscu2.s | 160 ++++++++++++++++ 4 files changed, 335 insertions(+), 3 deletions(-) create mode 100644 lldb/test/Shell/SymbolFile/DWARF/DW_TAG_variable-DW_AT_decl_file-DW_AT_abstract_origin-crosscu1.s create mode 100644 lldb/test/Shell/SymbolFile/DWARF/Inputs/DW_TAG_variable-DW_AT_decl_file-DW_AT_abstract_origin-crosscu2.s diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 188a667ca564..af01a8f53518 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -2201,7 +2201,8 @@ size_t DWARFASTParserClang::ParseChildEnumerators( case DW_AT_description: default: case DW_AT_decl_file: - decl.SetFile(die.GetCU()->GetFile(form_value.Unsigned())); + decl.SetFile(attributes.CompileUnitAtIndex(i)->GetFile( + form_value.Unsigned())); break; case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 7d273cb7df1b..587550961ec9 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3126,8 +3126,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, continue; switch (attr) { case DW_AT_decl_file: - decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( - form_value.Unsigned())); + decl.SetFile( + attributes.CompileUnitAtIndex(i)->GetFile(form_value.Unsigned())); break; case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); diff --git a/lldb/test/Shell/SymbolFile/DWARF/DW_TAG_variable-DW_AT_decl_file-DW_AT_abstract_origin-crosscu1.s b/lldb/test/Shell/SymbolFile/DWARF/DW_TAG_variable-DW_AT_decl_file-DW_AT_abstract_origin-crosscu1.s new file mode 100644 index 000000000000..ef1481bbf800 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/DW_TAG_variable-DW_AT_decl_file-DW_AT_abstract_origin-crosscu1.s @@ -0,0 +1,171 @@ +# Check that DW_AT_decl_file of DW_AT_variable which is inherited by +# DW_AT_abstract_origin from a different DW_TAG_compile_unit is using the +# DW_TAG_compile_unit->DW_AT_stmt_list where the DW_AT_decl_file is located (and +# not where the DW_AT_abstract_origin is located). +# DW_TAG_variable in CU 1 is using DW_AT_decl_file 3. +# CU 1 has files: +# file_names[ 1]: name: "inlinevarother.h" +# file_names[ 2]: name: "inlinevar1.c" +# file_names[ 3]: name: "inlinevar.h" +# CU 2 has files: +# file_names[ 1]: name: "inlinevar2.c" +# file_names[ 2]: name: "inlinevar.h" + +# UNSUPPORTED: system-darwin, system-windows +# REQUIRES: target-x86_64 + +# RUN: %clang_host -o %t %s \ +# RUN: %S/Inputs/DW_TAG_variable-DW_AT_decl_file-DW_AT_abstract_origin-crosscu2.s + +# RUN: %lldb %t \ +# RUN: -o 'b other' -o r -o disas -o 'frame variable --show-declaration' \ +# RUN: -o exit | FileCheck %s + +# CHECK: inlinevar.h:2: (int) var = {{.*}} +# Unfixed LLDB did show only: (int) var = {{.*}} + + .text + .file "inlinevar1.c" + .file 1 "" "./inlinevarother.h" + .globl main # -- Begin function main + .type main,@function +main: # @main +.Lfunc_begin1: + .file 2 "" "inlinevar1.c" + .loc 2 4 0 # inlinevar1.c:4:0 +.Ltmp2: + .file 3 "" "./inlinevar.h" + .loc 3 2 16 prologue_end # ./inlinevar.h:2:16 + movl $42, %eax + pushq %rax + .loc 3 3 10 # ./inlinevar.h:3:10 +.Ltmp3: + .loc 2 5 20 # inlinevar1.c:5:20 + callq other + popq %rcx + .loc 2 5 19 # inlinevar1.c:5:19 + addl %ecx, %eax + .loc 2 5 3 # inlinevar1.c:5:3 + retq +.Ltmp4: +.Lfunc_end1: + .size main, .Lfunc_end1-main + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 14 # DW_FORM_strp + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .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 32 # DW_AT_inline + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .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 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .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 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] DW_TAG_compile_unit + .long .Linfo_string0 # DW_AT_producer + .short 0xc # DW_AT_language + .long .Linfo_string1 # DW_AT_name + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Linfo_string2 # DW_AT_comp_dir + .quad .Lfunc_begin1 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .globl debuginfo_func_inlined +debuginfo_func_inlined: +.Lfunc_inlined: + .byte 3 # Abbrev [3] DW_TAG_subprogram + .long .Linfo_string4 # DW_AT_name + .byte 3 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .long .Ltype_int-.Lcu_begin0 # DW_AT_type + .byte 1 # DW_AT_inline + .globl debuginfo_var_var +debuginfo_var_var: +.Lvar_var: + .byte 4 # Abbrev [4] DW_TAG_variable + .long .Linfo_string6 # DW_AT_name + .byte 3 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long .Ltype_int-.Lcu_begin0 # DW_AT_type + .byte 0 # End Of Children Mark +.Ltype_int: + .byte 5 # Abbrev [5] DW_TAG_base_type + .long .Linfo_string5 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 11.0.0 + hand coding" +.Linfo_string1: + .asciz "inlinevar1.c" +.Linfo_string2: + .asciz "" +.Linfo_string4: + .asciz "inlined" +.Linfo_string5: + .asciz "int" +.Linfo_string6: + .asciz "var" + .section ".note.GNU-stack","",@progbits + .addrsig + .addrsig_sym other + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lldb/test/Shell/SymbolFile/DWARF/Inputs/DW_TAG_variable-DW_AT_decl_file-DW_AT_abstract_origin-crosscu2.s b/lldb/test/Shell/SymbolFile/DWARF/Inputs/DW_TAG_variable-DW_AT_decl_file-DW_AT_abstract_origin-crosscu2.s new file mode 100644 index 000000000000..6a8dfa3eb63f --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/Inputs/DW_TAG_variable-DW_AT_decl_file-DW_AT_abstract_origin-crosscu2.s @@ -0,0 +1,160 @@ + .text + .file "inlinevar2.c" + .globl other # -- Begin function other + .type other,@function +other: # @other +.Lfunc_begin0: + .file 1 "" "inlinevar2.c" + .loc 1 3 0 # inlinevar2.c:3:0 +.Ltmp0: + .file 2 "" "./inlinevar.h" + .loc 2 2 16 prologue_end # ./inlinevar.h:2:16 + movl $42, %eax + .loc 2 3 10 # ./inlinevar.h:3:10 + .loc 1 3 41 # inlinevar2.c:3:41 + retq +.Ltmp1: +.Ltmp2: +.Lfunc_end0: + .size other, .Lfunc_end0-other + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 14 # DW_FORM_strp + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .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 14 # DW_FORM_strp + .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 6 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .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 1 # DW_CHILDREN_yes + .byte 49 # DW_AT_abstract_origin + .byte 0x10 # DW_FORM_ref_addr + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .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 8 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 49 # DW_AT_abstract_origin + .byte 0x10 # DW_FORM_ref_addr + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] DW_TAG_compile_unit + .long .Linfo_string0 # DW_AT_producer + .short 0xc # DW_AT_language + .long .Linfo_string1 # DW_AT_name + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Linfo_string2 # DW_AT_comp_dir + .quad .Lfunc_begin0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc +.Ltype_int: + .byte 4 # Abbrev [4] DW_TAG_base_type + .long .Linfo_string5 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 6 # Abbrev [6] DW_TAG_subprogram + .quad .Lfunc_begin0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .long .Linfo_string8 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .long .Ltype_int-.Lcu_begin0 # DW_AT_type + # DW_AT_external + .byte 7 # Abbrev [7] DW_TAG_inlined_subroutine + .long debuginfo_func_inlined # DW_AT_abstract_origin + .quad .Ltmp0 # DW_AT_low_pc + .long .Ltmp1-.Ltmp0 # DW_AT_high_pc + .byte 1 # DW_AT_call_file + .byte 3 # DW_AT_call_line + .byte 48 # DW_AT_call_column + .byte 8 # Abbrev [8] DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .long debuginfo_var_var # DW_AT_abstract_origin + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 11.0.0 + hand coding" +.Linfo_string1: + .asciz "inlinevar2.c" +.Linfo_string2: + .asciz "" +.Linfo_string5: + .asciz "int" +.Linfo_string8: + .asciz "other" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: