+2021-04-07 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * gdb.dwarf2/fission-absolute-dwo.c: New file.
+ * gdb.dwarf2/fission-absolute-dwo.exp: New file.
+ * gdb.dwarf2/fission-base.exp: Use build_executable_and_dwo_files
+ instead of build_executable_from_fission_assembler.
+ * gdb.dwarf2/fission-loclists-pie.exp: Likewise.
+ * gdb.dwarf2/fission-loclists.exp: Likewise.
+
+ * gdb.dwarf2/fission-multi-cu.S: Delete file.
+ * gdb.dwarf2/fission-multi-cu.c: New file based on old
+ fission-multi-cu1.c and fission-multi-cu2.c files.
+ * gdb.dwarf2/fission-multi-cu1.c: Delete file.
+ * gdb.dwarf2/fission-multi-cu2.c: Delete file.
+ * gdb.dwarf2/fission-multi-cu.exp: Rewrite to use Dwarf assembler.
+ * gdb.dwarf2/fission-reread.exp: Likewise.
+ * lib/dwarf.exp (extract_dwo_information): New proc.
+ (strip_dwo_information): New proc.
+ (build_executable_and_dwo_files): New proc.
+ (build_executable_from_fission_assembler): Delete.
+ (Dwarf::_debug_addr_index): New variable.
+ (Dwarf::_cu_is_fission): New variable.
+ (Dwarf::_handle_DW_FORM): Handle DW_OP_GNU_addr_index.
+ (Dwarf::_default_form): Supply a default for DW_AT_GNU_addr_base.
+ (Dwarf::_handle_macro_at_range): Use form DW_FORM_GNU_addr_index
+ if this is a fission CU.
+ (Dwarf::_location): Handle DW_OP_GNU_addr_index.
+ (Dwarf::debug_addr_label): New proc.
+ (Dwarf::cu): Initialise _cu_is_fission.
+ (Dwarf::tu): Likewise.
+ (Dwarf::assemble): Initialise _debug_addr_index.
+
2021-04-07 Andrew Burgess <andrew.burgess@embecosm.com>
* gdb.dwarf2/dw2-using-debug-str.exp: Add an additional test.
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2021 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Our fake object. */
+int global_var[100];
+
+int
+main (int argc, char **argv)
+{
+ asm ("main_label: .globl main_label");
+
+ return 0;
+}
--- /dev/null
+# Copyright 2021 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This is a basic first test for using the testsuite's Dwarf assembler to
+# create split debug information. There's not unique feature of GDB being
+# tested here, this exists only as a basic test for the testsuite
+# infrastructure.
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+ return 0
+}
+
+standard_testfile .c -dw.S
+
+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
+ return -1
+}
+
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+ global srcfile binfile objdir
+
+ set debug_addr_lbl ".unknown!!"
+
+ # The information that will be split out into the .dwo file.
+ cu {fission 1} {
+
+ # Capture a label to the current start of the .debug_addr
+ # section. This will be passed to DW_AT_GNU_addr_base in the
+ # non-split CU later.
+ set debug_addr_lbl [debug_addr_label]
+
+ compile_unit {
+ {language @DW_LANG_C}
+ {name ${srcfile}}
+ {DW_AT_comp_dir ${objdir}}
+ {DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8}
+ } {
+ declare_labels int4_type struct_type
+
+ int4_type: DW_TAG_base_type {
+ {DW_AT_byte_size 4 DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_signed}
+ {DW_AT_name integer}
+ }
+
+ struct_type: DW_TAG_structure_type {
+ {DW_AT_name "foo_t"}
+ {DW_AT_byte_size 12 DW_FORM_sdata}
+ } {
+ member {
+ {name "aa"}
+ {type :$int4_type}
+ {data_member_location 0 data1}
+ }
+ member {
+ {name "bb"}
+ {type :$int4_type}
+ {data_member_location 4 data1}
+ }
+ member {
+ {name "cc"}
+ {type :$int4_type}
+ {data_member_location 8 data1}
+ }
+ }
+
+ DW_TAG_variable {
+ {DW_AT_name global_var}
+ {DW_AT_type :$struct_type}
+ {DW_AT_location {
+ DW_OP_GNU_addr_index [gdb_target_symbol global_var]
+ } SPECIAL_expr}
+ {external 1 flag}
+ }
+
+ subprogram {
+ {external 1 flag}
+ {DW_AT_name main DW_FORM_string}
+ {MACRO_AT_func {main}}
+ }
+ }
+ }
+
+ # The information that will remain in the .o file.
+ cu {} {
+ compile_unit {
+ {DW_AT_GNU_dwo_name ${binfile}.dwo DW_FORM_strp}
+ {DW_AT_comp_dir ${objdir}}
+ {DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8}
+ {DW_AT_GNU_addr_base $debug_addr_lbl}
+ } {
+ # Nothing.
+ }
+ }
+}
+
+# Compile both source files to create the executable. As we compile
+# ASM_FILE we split out the debug information into the dwo file.
+set object_file [standard_output_file ${testfile}.o]
+if { [build_executable_and_dwo_files "${testfile}.exp" ${binfile} {nodebug} \
+ [list $asm_file {nodebug split-dwo} ${object_file}] \
+ [list $srcfile {nodebug}]] } {
+ perror "failed to compile ${gdb_test_file_name}"
+ return -1
+}
+
+# Now we can start GDB.
+clean_restart ${testfile}
+
+if ![runto_main] {
+ return -1
+}
+
+# Print the type of global_var. This type information is entirely
+# fictional, it only exists in the DWARF. If we don't have the DWARF
+# information then there's no way we can print this.
+gdb_test "p global_var" " = \\{aa = 0, bb = 0, cc = 0\\}"
standard_testfile .S
-set dwo [standard_output_file "fission-base.dwo"]
-
-if [build_executable_from_fission_assembler \
- "$testfile.exp" "$binfile" "$srcfile" \
- [list nodebug additional_flags=-DDWO=$dwo]] {
+set obj [standard_output_file "${testfile}.o"]
+set dwo [standard_output_file "${testfile}.dwo"]
+if [build_executable_and_dwo_files "$testfile.exp" "${binfile}" {nodebug} \
+ [list $srcfile \
+ [list nodebug split-dwo additional_flags=-DDWO=$dwo] \
+ $obj]] {
return -1
}
standard_testfile .S
-set dwo [standard_output_file "fission-loclists-pie.dwo"]
-
-if [build_executable_from_fission_assembler \
- "$testfile.exp" "$binfile" "$srcfile" \
- [list "nodebug" "ldflags=-pie" additional_flags=-DDWO=$dwo]] {
+set obj [standard_output_file "${testfile}.o"]
+set dwo [standard_output_file "${testfile}.dwo"]
+if [build_executable_and_dwo_files "$testfile.exp" "${binfile}" \
+ {nodebug ldflags=-pie} \
+ [list $srcfile [list nodebug split-dwo additional_flags=-DDWO=$dwo] \
+ $obj]] {
return -1
}
standard_testfile .S
-set dwo [standard_output_file "fission-loclists.dwo"]
-
-if [build_executable_from_fission_assembler \
- "$testfile.exp" "$binfile" "$srcfile" \
- [list nodebug additional_flags=-DDWO=$dwo]] {
+set obj [standard_output_file "${testfile}.o"]
+set dwo [standard_output_file "${testfile}.dwo"]
+if [build_executable_and_dwo_files "$testfile.exp" "${binfile}" {nodebug} \
+ [list $srcfile \
+ [list nodebug split-dwo additional_flags=-DDWO=$dwo] \
+ $obj]] {
return -1
}
+++ /dev/null
-/* This testcase is part of GDB, the GNU debugger.
-
- Copyright 2012-2021 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- This file was created by doing:
-
- clang fission-multi-cu*.c -g -fno-split-dwarf-inlining -emit-llvm -S -c
- llvm-link fission-multi-cu*.ll -S -o fission-multi-cu.ll
- clang-tot fission-multi-cu.ll -gsplit-dwarf -S
-
- and then massaging the output.
-*/
-
-#define XSTR(s) STR(s)
-#define STR(s) #s
-
- .text
- .file "llvm-link"
- .globl func
- .p2align 4, 0x90
- .type func,@function
-func: # @func
-.Lfunc_begin0:
- .file 1 "fission-multi-cu1.c"
- .loc 1 20 0 # fission-multi-cu1.c:20:0
- .cfi_startproc
-# BB#0: # %entry
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- .loc 1 21 10 prologue_end # fission-multi-cu1.c:21:10
- movl -4(%rbp), %edi
- .loc 1 21 14 is_stmt 0 # fission-multi-cu1.c:21:14
- addl $1, %edi
- .loc 1 21 3 # fission-multi-cu1.c:21:3
- movl %edi, %eax
- popq %rbp
- retq
-.Lfunc_end0:
- .size func, .Lfunc_end0-func
- .cfi_endproc
-
- .globl main
- .p2align 4, 0x90
- .type main,@function
-main: # @main
-.Lfunc_begin1:
- .file 2 "fission-multi-cu2.c"
- .loc 2 23 0 is_stmt 1 # fission-multi-cu2.c:23:0
- .cfi_startproc
-# BB#0: # %entry
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl $4294967295, %edi # imm = 0xFFFFFFFF
- .loc 2 24 3 prologue_end # fission-multi-cu2.c:24:3
- movb $0, %al
- callq func
- xorl %eax, %eax
- .loc 2 25 1 # fission-multi-cu2.c:25:1
- popq %rbp
- retq
-.Lfunc_end1:
- .size main, .Lfunc_end1-main
- .cfi_endproc
-
- .section .debug_str,"MS",@progbits,1
-.Lskel_string0:
- .asciz XSTR(DWO) # string offset=0
-.Lskel_string1:
- .asciz "/tmp/src/gdb/testsuite" # string offset=21
- .section .debug_loc.dwo,"",@progbits
- .section .debug_abbrev,"",@progbits
- .byte 1 # Abbreviation Code
- .byte 17 # DW_TAG_compile_unit
- .byte 0 # DW_CHILDREN_no
- .byte 16 # DW_AT_stmt_list
- .byte 23 # DW_FORM_sec_offset
- .ascii "\260B" # DW_AT_GNU_dwo_name
- .byte 14 # DW_FORM_strp
- .byte 27 # DW_AT_comp_dir
- .byte 14 # DW_FORM_strp
- .ascii "\261B" # DW_AT_GNU_dwo_id
- .byte 7 # DW_FORM_data8
- .ascii "\263B" # DW_AT_GNU_addr_base
- .byte 23 # DW_FORM_sec_offset
- .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 0 # EOM(3)
- .section .debug_info,"",@progbits
-.Lcu_begin0:
- .long 44 # Length of Unit
- .short 4 # DWARF version number
- .long .debug_abbrev # Offset Into Abbrev. Section
- .byte 8 # Address Size (in bytes)
- .byte 1 # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit
- .long .Lline_table_start0 # DW_AT_stmt_list
- .long .Lskel_string0 # DW_AT_GNU_dwo_name
- .long .Lskel_string1 # DW_AT_comp_dir
- .quad 7615852067747431413 # DW_AT_GNU_dwo_id
- .long .debug_addr # DW_AT_GNU_addr_base
- .quad .Lfunc_begin0 # DW_AT_low_pc
- .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
-.Lcu_begin1:
- .long 44 # Length of Unit
- .short 4 # DWARF version number
- .long .debug_abbrev # Offset Into Abbrev. Section
- .byte 8 # Address Size (in bytes)
- .byte 1 # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit
- .long .Lline_table_start0 # DW_AT_stmt_list
- .long .Lskel_string0 # DW_AT_GNU_dwo_name
- .long .Lskel_string1 # DW_AT_comp_dir
- .quad 2037650261599692324 # DW_AT_GNU_dwo_id
- .long .debug_addr # DW_AT_GNU_addr_base
- .quad .Lfunc_begin1 # DW_AT_low_pc
- .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
- .section .debug_ranges,"",@progbits
- .section .debug_macinfo,"",@progbits
-.Lcu_macro_begin1:
-.Lcu_macro_begin3:
- .byte 0 # End Of Macro List Mark
- .section .debug_str.dwo,"MS",@progbits,1
-.Linfo_string0:
- .asciz "fission-multi-cu.dwo" # string offset=0
-.Linfo_string1:
- .asciz "clang version 5.0.0 (trunk 302855) (llvm/trunk 302853)" # string offset=21
-.Linfo_string2:
- .asciz "fission-multi-cu1.c" # string offset=76
-.Linfo_string3:
- .asciz "fission-multi-cu2.c" # string offset=96
-.Linfo_string4:
- .asciz "func" # string offset=116
-.Linfo_string5:
- .asciz "int" # string offset=121
-.Linfo_string6:
- .asciz "main" # string offset=125
-.Linfo_string7:
- .asciz "arg" # string offset=130
- .section .debug_str_offsets.dwo,"",@progbits
- .long 0
- .long 21
- .long 76
- .long 96
- .long 116
- .long 121
- .long 125
- .long 130
- .section .debug_info.dwo,"",@progbits
- .long 53 # Length of Unit
- .short 4 # DWARF version number
- .long 0 # Offset Into Abbrev. Section
- .byte 8 # Address Size (in bytes)
- .byte 1 # Abbrev [1] 0xb:0x2e DW_TAG_compile_unit
- .byte 0 # DW_AT_GNU_dwo_name
- .byte 1 # DW_AT_producer
- .short 12 # DW_AT_language
- .byte 2 # DW_AT_name
- .quad 7615852067747431413 # DW_AT_GNU_dwo_id
- .byte 2 # Abbrev [2] 0x19:0x1b DW_TAG_subprogram
- .byte 0 # DW_AT_low_pc
- .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
- .byte 1 # DW_AT_frame_base
- .byte 86
- .byte 4 # DW_AT_name
- .byte 1 # DW_AT_decl_file
- .byte 19 # DW_AT_decl_line
- # DW_AT_prototyped
- .long 52 # DW_AT_type
- # DW_AT_external
- .byte 3 # Abbrev [3] 0x28:0xb DW_TAG_formal_parameter
- .byte 2 # DW_AT_location
- .byte 145
- .byte 124
- .byte 7 # DW_AT_name
- .byte 1 # DW_AT_decl_file
- .byte 19 # DW_AT_decl_line
- .long 52 # DW_AT_type
- .byte 0 # End Of Children Mark
- .byte 4 # Abbrev [4] 0x34:0x4 DW_TAG_base_type
- .byte 5 # DW_AT_name
- .byte 5 # DW_AT_encoding
- .byte 4 # DW_AT_byte_size
- .byte 0 # End Of Children Mark
- .long 41 # Length of Unit
- .short 4 # DWARF version number
- .long 0 # Offset Into Abbrev. Section
- .byte 8 # Address Size (in bytes)
- .byte 1 # Abbrev [1] 0xb:0x22 DW_TAG_compile_unit
- .byte 0 # DW_AT_GNU_dwo_name
- .byte 1 # DW_AT_producer
- .short 12 # DW_AT_language
- .byte 3 # DW_AT_name
- .quad 2037650261599692324 # DW_AT_GNU_dwo_id
- .byte 5 # Abbrev [5] 0x19:0xf DW_TAG_subprogram
- .byte 1 # DW_AT_low_pc
- .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
- .byte 1 # DW_AT_frame_base
- .byte 86
- .byte 6 # DW_AT_name
- .byte 2 # DW_AT_decl_file
- .byte 22 # DW_AT_decl_line
- .long 40 # DW_AT_type
- # DW_AT_external
- .byte 4 # Abbrev [4] 0x28:0x4 DW_TAG_base_type
- .byte 5 # DW_AT_name
- .byte 5 # DW_AT_encoding
- .byte 4 # DW_AT_byte_size
- .byte 0 # End Of Children Mark
- .section .debug_abbrev.dwo,"",@progbits
- .byte 1 # Abbreviation Code
- .byte 17 # DW_TAG_compile_unit
- .byte 1 # DW_CHILDREN_yes
- .ascii "\260B" # DW_AT_GNU_dwo_name
- .ascii "\202>" # DW_FORM_GNU_str_index
- .byte 37 # DW_AT_producer
- .ascii "\202>" # DW_FORM_GNU_str_index
- .byte 19 # DW_AT_language
- .byte 5 # DW_FORM_data2
- .byte 3 # DW_AT_name
- .ascii "\202>" # DW_FORM_GNU_str_index
- .ascii "\261B" # DW_AT_GNU_dwo_id
- .byte 7 # DW_FORM_data8
- .byte 0 # EOM(1)
- .byte 0 # EOM(2)
- .byte 2 # Abbreviation Code
- .byte 46 # DW_TAG_subprogram
- .byte 1 # DW_CHILDREN_yes
- .byte 17 # DW_AT_low_pc
- .ascii "\201>" # DW_FORM_GNU_addr_index
- .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
- .ascii "\202>" # DW_FORM_GNU_str_index
- .byte 58 # DW_AT_decl_file
- .byte 11 # DW_FORM_data1
- .byte 59 # DW_AT_decl_line
- .byte 11 # DW_FORM_data1
- .byte 39 # DW_AT_prototyped
- .byte 25 # DW_FORM_flag_present
- .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 3 # Abbreviation Code
- .byte 5 # DW_TAG_formal_parameter
- .byte 0 # DW_CHILDREN_no
- .byte 2 # DW_AT_location
- .byte 24 # DW_FORM_exprloc
- .byte 3 # DW_AT_name
- .ascii "\202>" # DW_FORM_GNU_str_index
- .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 4 # Abbreviation Code
- .byte 36 # DW_TAG_base_type
- .byte 0 # DW_CHILDREN_no
- .byte 3 # DW_AT_name
- .ascii "\202>" # DW_FORM_GNU_str_index
- .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 17 # DW_AT_low_pc
- .ascii "\201>" # DW_FORM_GNU_addr_index
- .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
- .ascii "\202>" # DW_FORM_GNU_str_index
- .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 0 # EOM(3)
- .section .debug_addr,"",@progbits
- .quad .Lfunc_begin0
- .quad .Lfunc_begin1
- .section .debug_pubnames,"",@progbits
- .long .LpubNames_end0-.LpubNames_begin0 # Length of Public Names Info
-.LpubNames_begin0:
- .short 2 # DWARF Version
- .long .Lcu_begin0 # Offset of Compilation Unit Info
- .long 48 # Compilation Unit Length
- .long 25 # DIE offset
- .asciz "func" # External Name
- .long 0 # End Mark
-.LpubNames_end0:
- .long .LpubNames_end1-.LpubNames_begin1 # Length of Public Names Info
-.LpubNames_begin1:
- .short 2 # DWARF Version
- .long .Lcu_begin1 # Offset of Compilation Unit Info
- .long 48 # Compilation Unit Length
- .long 25 # DIE offset
- .asciz "main" # External Name
- .long 0 # End Mark
-.LpubNames_end1:
- .section .debug_pubtypes,"",@progbits
- .long .LpubTypes_end0-.LpubTypes_begin0 # Length of Public Types Info
-.LpubTypes_begin0:
- .short 2 # DWARF Version
- .long .Lcu_begin0 # Offset of Compilation Unit Info
- .long 48 # Compilation Unit Length
- .long 52 # DIE offset
- .asciz "int" # External Name
- .long 0 # End Mark
-.LpubTypes_end0:
- .long .LpubTypes_end1-.LpubTypes_begin1 # Length of Public Types Info
-.LpubTypes_begin1:
- .short 2 # DWARF Version
- .long .Lcu_begin1 # Offset of Compilation Unit Info
- .long 48 # Compilation Unit Length
- .long 40 # DIE offset
- .asciz "int" # External Name
- .long 0 # End Mark
-.LpubTypes_end1:
-
- .ident "clang version 5.0.0 (trunk 302855) (llvm/trunk 302853)"
- .ident "clang version 5.0.0 (trunk 302855) (llvm/trunk 302853)"
- .section ".note.GNU-stack","",@progbits
- .section .debug_line,"",@progbits
-.Lline_table_start0:
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2012-2021 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#define LL(N) asm ("line_label_" #N ": .globl line_label_" #N)
+
+/* Fake parameter location. */
+int global_param = 0;
+
+int
+func (int arg)
+{
+ asm ("func_label: .globl func_label");
+ LL(4);
+ return arg + 1;
+}
+
+int
+main ()
+{
+ asm ("main_label: .globl main_label");
+ LL(1);
+ global_param = -1;
+ LL(2);
+ func (-1);
+ LL(3);
+ return 0;
+}
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# This test checks that GDB can load DWARF information from two
+# separate split .DWO files.
+
load_lib dwarf.exp
# We run objcopy locally to split out the .dwo file.
return 0
}
-# This test can only be run on x86-64 targets.
-if {![istarget x86_64-*] || ![is_lp64_target]} {
- return 0
+# We place the entire source code for the test into a single .c file,
+# but we generate the DWARF in two separate .S files. Each .S is
+# compiled to a .o, then the DWARF is split into a .dwo file. Finally
+# the all three .o files are merged into a single executable that will
+# reference the two .dwo files.
+standard_testfile .c -1-dw.S -2-cw.S
+
+# Generate the first .S file.
+set asm_file_1 [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file_1 {
+ global srcfile binfile objdir srcdir subdir
+
+ get_func_info func
+
+ declare_labels int4_type lines_table
+
+ set debug_addr_lbl ".unknown!!"
+
+ # The information that will be split out into the .dwo file.
+ cu {fission 1} {
+
+ # Capture a label to the current start of the .debug_addr
+ # section. This will be passed to DW_AT_GNU_addr_base in the
+ # non-split CU later.
+ set debug_addr_lbl [debug_addr_label]
+
+ compile_unit {
+ {language @DW_LANG_C}
+ {name ${srcfile}}
+ {DW_AT_comp_dir ${objdir}}
+ {DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8}
+ } {
+ int4_type: DW_TAG_base_type {
+ {DW_AT_byte_size 4 DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_signed}
+ {DW_AT_name int}
+ }
+
+ subprogram {
+ {external 1 flag}
+ {DW_AT_name func DW_FORM_string}
+ {MACRO_AT_func {func}}
+ {DW_AT_type :$int4_type}
+ } {
+ DW_TAG_formal_parameter {
+ {DW_AT_name arg}
+ {DW_AT_type :$int4_type}
+ {DW_AT_location {
+ DW_OP_GNU_addr_index [gdb_target_symbol global_param]
+ } SPECIAL_expr}
+ }
+ }
+ }
+ }
+
+ lines {version 2} lines_table {
+ include_dir "${srcdir}/${subdir}"
+ file_name "$srcfile" 1
+
+ program {
+ {DW_LNE_set_address $func_start}
+ {DW_LNS_advance_line 24}
+ {DW_LNS_copy}
+
+ {DW_LNE_set_address line_label_4}
+ {DW_LNS_advance_line 3}
+ {DW_LNS_copy}
+
+ {DW_LNE_set_address $func_end}
+ {DW_LNS_advance_line 1}
+ {DW_LNS_copy}
+ {DW_LNE_end_sequence}
+ }
+ }
+
+ # The information that will remain in the .o file.
+ cu {} {
+ compile_unit {
+ {DW_AT_GNU_dwo_name ${binfile}-1-dw.dwo DW_FORM_strp}
+ {DW_AT_comp_dir ${objdir}}
+ {DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8}
+ {DW_AT_GNU_addr_base $debug_addr_lbl}
+ {stmt_list $lines_table DW_FORM_sec_offset}
+ } {
+ # Nothing.
+ }
+ }
}
-standard_testfile .S
-
-set dwo [standard_output_file "fission-multi-cu.dwo"]
+# Generate the second .S file.
+set asm_file_2 [standard_output_file $srcfile3]
+Dwarf::assemble $asm_file_2 {
+ global srcfile binfile objdir srcdir subdir
+
+ set debug_addr_lbl ".unknown!!"
+
+ declare_labels int4_type lines_table
+
+ get_func_info main
+
+ # The information that will be split out into the .dwo file.
+ cu {fission 1} {
+
+ # Capture a label to the current start of the .debug_addr
+ # section. This will be passed to DW_AT_GNU_addr_base in the
+ # non-split CU later.
+ set debug_addr_lbl [debug_addr_label]
+
+ compile_unit {
+ {language @DW_LANG_C}
+ {name ${srcfile}}
+ {DW_AT_comp_dir ${objdir}}
+ {DW_AT_GNU_dwo_id 0x4567 DW_FORM_data8}
+ } {
+ int4_type: DW_TAG_base_type {
+ {DW_AT_byte_size 4 DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_signed}
+ {DW_AT_name int}
+ }
+
+ subprogram {
+ {external 1 flag}
+ {DW_AT_name main DW_FORM_string}
+ {MACRO_AT_func {main}}
+ {DW_AT_type :$int4_type}
+ {DW_AT_decl_file 1 data1}
+ {DW_AT_decl_line 29 data1}
+ }
+ }
+ }
+
+ lines {version 2} lines_table {
+ include_dir "${srcdir}/${subdir}"
+ file_name "$srcfile" 1
+
+ program {
+ {DW_LNE_set_address $main_start}
+ {DW_LNS_advance_line 32}
+ {DW_LNS_copy}
+
+ {DW_LNE_set_address line_label_1}
+ {DW_LNS_advance_line 3}
+ {DW_LNS_copy}
+
+ {DW_LNE_set_address line_label_2}
+ {DW_LNS_advance_line 2}
+ {DW_LNS_copy}
+
+ {DW_LNE_set_address line_label_3}
+ {DW_LNS_advance_line 2}
+ {DW_LNS_copy}
+
+ {DW_LNE_set_address $main_end}
+ {DW_LNS_advance_line 2}
+ {DW_LNS_copy}
+ {DW_LNE_end_sequence}
+ }
+ }
+
+ # The information that will remain in the .o file.
+ cu {} {
+ compile_unit {
+ {DW_AT_GNU_dwo_name ${binfile}-2-dw.dwo DW_FORM_strp}
+ {DW_AT_comp_dir ${objdir}}
+ {DW_AT_GNU_dwo_id 0x4567 DW_FORM_data8}
+ {DW_AT_GNU_addr_base $debug_addr_lbl}
+ {stmt_list $lines_table DW_FORM_sec_offset}
+ } {
+ # Nothing.
+ }
+ }
+}
-if [build_executable_from_fission_assembler \
- "$testfile.exp" "$binfile" "$srcfile" \
- [list nodebug additional_flags=-DDWO=$dwo]] {
+# Compile all of the input files, split the DWARF into the .dwo files.
+set obj1 [standard_output_file "${testfile}-1-dw.o"]
+set obj2 [standard_output_file "${testfile}-2-dw.o"]
+if [build_executable_and_dwo_files "$testfile.exp" "${binfile}" {nodebug} \
+ [list $asm_file_1 [list nodebug split-dwo] $obj1] \
+ [list $asm_file_2 [list nodebug split-dwo] $obj2] \
+ [list $srcfile [list nodebug]]] {
return -1
}
gdb_test "ptype main" "type = int \\(\\)"
gdb_test "ptype func" "type = int \\(int\\)"
-gdb_test "frame" "#0 *main \\(\\) at ${testfile}2\\.c:$decimal.*" \
+gdb_test "frame" "#0 *main \\(\\) at \[^\r\n\]+${srcfile}:$decimal.*" \
"frame in main"
-gdb_test "break func" "Breakpoint.*at.* file .*${testfile}1\\.c, line .*"
+gdb_test "break func" "Breakpoint.*at.* file .*${srcfile}, line .*"
gdb_test "continue" "Breakpoint.* func \\(arg=-1\\).*" \
"continue to func"
-gdb_test "frame" "#0 *func \\(arg=-1\\) at ${testfile}1\\.c:$decimal.*" \
+gdb_test "frame" "#0 *func \\(arg=-1\\) at \[^\r\n\]+${srcfile}:$decimal.*" \
"frame in func"
+++ /dev/null
-/* This testcase is part of GDB, the GNU debugger.
-
- Copyright 2012-2021 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-int
-func (int arg)
-{
- return arg + 1;
-}
+++ /dev/null
-/* This testcase is part of GDB, the GNU debugger.
-
- Copyright 2012-2021 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-void func ();
-
-int
-main ()
-{
- func (-1);
-}
standard_testfile .S
-set dwo [standard_output_file "fission-reread.dwo"]
+set obj [standard_output_file "${testfile}.o"]
+set dwo [standard_output_file "${testfile}.dwo"]
-set options [list]
-lappend options nodebug
+set options [list nodebug]
if { $additional_flags != "" } {
lappend options $additional_flags
}
-lappend options additional_flags=-DDWO=$dwo
-if [build_executable_from_fission_assembler \
- "$testfile.exp" "$binfile" "$srcfile" $options] {
+set dwo_options $options
+lappend dwo_options split-dwo
+lappend dwo_options additional_flags=-DDWO=$dwo
+
+if [build_executable_and_dwo_files "$testfile.exp" "${binfile}" $options \
+ [list $srcfile $dwo_options $obj]] {
return -1
}
return 0
}
-# Build an executable from a fission-based .S file.
-# This handles the extra work of splitting the .o into non-dwo and dwo
-# pieces, making sure the .dwo is available if we're using cc-with-tweaks.sh
-# to build a .dwp file.
-# The arguments and results are the same as for build_executable.
+# Use 'objcopy --extract-dwo to extract DWO information from
+# OBJECT_FILE and place it into DWO_FILE.
#
-# Current restrictions:
-# - only supports one source file
-# - cannot be run on remote hosts
-
-proc build_executable_from_fission_assembler { testname executable sources options } {
- verbose -log "build_executable_from_fission_assembler $testname $executable $sources $options"
- if { [llength $sources] != 1 } {
- error "Only one source file supported."
- }
- if [is_remote host] {
- error "Remote hosts are not supported."
- }
-
- global srcdir subdir
- set source_file ${srcdir}/${subdir}/${sources}
- set root_name [file rootname [file tail $source_file]]
- set output_base [standard_output_file $root_name]
- set object_file ${output_base}.o
- set dwo_file ${output_base}.dwo
- set object_options "object $options"
+# Return 0 on success, otherwise, return -1.
+proc extract_dwo_information { object_file dwo_file } {
set objcopy [gdb_find_objcopy]
-
- set result [gdb_compile $source_file $object_file object $options]
- if { "$result" != "" } {
- return -1
- }
-
set command "$objcopy --extract-dwo $object_file $dwo_file"
verbose -log "Executing $command"
set result [catch "exec $command" output]
if { $result == 1 } {
return -1
}
+ return 0
+}
- set command "$objcopy --strip-dwo $object_file"
+# Use 'objcopy --strip-dwo to remove DWO information from
+# FILENAME.
+#
+# Return 0 on success, otherwise, return -1.
+proc strip_dwo_information { filename } {
+ set objcopy [gdb_find_objcopy]
+ set command "$objcopy --strip-dwo $filename"
verbose -log "Executing $command"
set result [catch "exec $command" output]
verbose -log "objcopy --strip-dwo output: $output"
if { $result == 1 } {
return -1
}
+ return 0
+}
- set result [gdb_compile $object_file $executable executable $options]
- if { "$result" != "" } {
+# Build an executable, with the debug information split out into a
+# separate .dwo file.
+#
+# This function is based on build_executable_from_specs in
+# lib/gdb.exp, but with threading support, and rust support removed.
+#
+# TESTNAME is the name of the test; this is passed to 'untested' if
+# something fails.
+#
+# EXECUTABLE is the executable to create, this can be an absolute
+# path, or a relative path, in which case the EXECUTABLE will be
+# created in the standard output directory.
+#
+# OPTIONS is passed to the final link, using gdb_compile. If OPTIONS
+# contains any option that indicates threads is required, of if the
+# option rust is included, then this function will return failure.
+#
+# ARGS is a series of lists. Each list is a spec for one source file
+# that will be compiled to make EXECUTABLE. Each spec in ARGS has the
+# form:
+# [ SOURCE OPTIONS ]
+# or:
+# [ SOURCE OPTIONS OBJFILE ]
+#
+# Where SOURCE is the path to the source file to compile. This can be
+# absolute, or relative to the standard global ${subdir}/${srcdir}/
+# path.
+#
+# OPTIONS are the options to use when compiling SOURCE into an object
+# file.
+#
+# OBJFILE is optional, if present this is the name of the object file
+# to create for SOURCE. If this is not provided then a suitable name
+# will be auto-generated.
+#
+# If OPTIONS contains the option 'split-dwo' then the debug
+# information is extracted from the object file created by compiling
+# SOURCE and placed into a file with a dwo extension. The name of
+# this file is generated based on the name of the object file that was
+# created (with the .o replaced with .dwo).
+proc build_executable_and_dwo_files { testname executable options args } {
+ global subdir
+ global srcdir
+
+ if { ! [regexp "^/" "$executable"] } then {
+ set binfile [standard_output_file $executable]
+ } else {
+ set binfile $executable
+ }
+
+ set info_options ""
+ if { [lsearch -exact $options "c++"] >= 0 } {
+ set info_options "c++"
+ }
+ if [get_compiler_info ${info_options}] {
+ return -1
+ }
+
+ set func gdb_compile
+ if {[lsearch -regexp $options \
+ {^(pthreads|shlib|shlib_pthreads|openmp)$}] != -1} {
+ # Currently don't support compiling thread based tests here.
+ # If this is required then look to build_executable_from_specs
+ # for inspiration.
return -1
}
+ if {[lsearch -exact $options rust] != -1} {
+ # Currently don't support compiling rust tests here. If this
+ # is required then look to build_executable_from_specs for
+ # inspiration.
+ return -1
+ }
+
+ # Must be run on local host due to use of objcopy.
+ if [is_remote host] {
+ return -1
+ }
+
+ set objects {}
+ set i 0
+ foreach spec $args {
+ if {[llength $spec] < 2} {
+ error "invalid spec length"
+ return -1
+ }
+
+ verbose -log "APB: SPEC: $spec"
+
+ set s [lindex $spec 0]
+ set local_options [lindex $spec 1]
+
+ if { ! [regexp "^/" "$s"] } then {
+ set s "$srcdir/$subdir/$s"
+ }
+
+ if {[llength $spec] > 2} {
+ set objfile [lindex $spec 2]
+ } else {
+ set objfile "${binfile}${i}.o"
+ incr i
+ }
+
+ if { [$func "${s}" "${objfile}" object $local_options] != "" } {
+ untested $testname
+ return -1
+ }
+
+ lappend objects "$objfile"
+
+ if {[lsearch -exact $local_options "split-dwo"] >= 0} {
+ # Split out the DWO file.
+ set dwo_file "[file rootname ${objfile}].dwo"
+
+ if { [extract_dwo_information $objfile $dwo_file] == -1 } {
+ untested $testname
+ return -1
+ }
+
+ if { [strip_dwo_information $objfile] == -1 } {
+ untested $testname
+ return -1
+ }
+ }
+ }
+
+ verbose -log "APB: OBJECTS = $objects"
+
+ set ret [$func $objects "${binfile}" executable $options]
+ if { $ret != "" } {
+ untested $testname
+ return -1
+ }
return 0
}
# The address size for debug ranges section.
variable _debug_ranges_64_bit
+ # The index into the .debug_addr section (used for fission
+ # generation).
+ variable _debug_addr_index
+
+ # Flag, true if the current CU is contains fission information,
+ # otherwise false.
+ variable _cu_is_fission
+
proc _process_one_constant {name value} {
variable _constants
variable _AT
_op .${_cu_addr_size}byte $value
}
+ DW_FORM_GNU_addr_index {
+ variable _debug_addr_index
+ variable _cu_addr_size
+
+ _op .uleb128 ${_debug_addr_index}
+ incr _debug_addr_index
+
+ _defer_output .debug_addr {
+ _op .${_cu_addr_size}byte $value
+ }
+ }
+
DW_FORM_data2 -
DW_FORM_ref2 {
_op .2byte $value
DW_FORM_strx3 -
DW_FORM_strx4 -
- DW_FORM_GNU_addr_index -
DW_FORM_GNU_str_index -
default {
DW_AT_name {
return DW_FORM_string
}
+ DW_AT_GNU_addr_base {
+ return DW_FORM_sec_offset
+ }
}
return ""
}
# Handle macro attribute MACRO_AT_range.
proc _handle_macro_at_range { attr_value } {
+ variable _cu_is_fission
+
if {[llength $attr_value] != 1} {
error "usage: MACRO_AT_range { func }"
}
set src ${srcdir}/${subdir}/${srcfile}
set result [function_range $func $src]
- _handle_attribute DW_AT_low_pc [lindex $result 0] \
- DW_FORM_addr
+ set form DW_FORM_addr
+ if { $_cu_is_fission } {
+ set form DW_FORM_GNU_addr_index
+ }
+
+ _handle_attribute DW_AT_low_pc [lindex $result 0] $form
_handle_attribute DW_AT_high_pc \
- "[lindex $result 0] + [lindex $result 1]" DW_FORM_addr
+ "[lindex $result 0] + [lindex $result 1]" $form
}
# Handle macro attribute MACRO_AT_func.
_op .${addr_size}byte $argvec(size)
}
+ DW_OP_GNU_addr_index {
+ variable _debug_addr_index
+ variable _cu_addr_size
+
+ _op .uleb128 ${_debug_addr_index}
+ incr _debug_addr_index
+
+ _defer_output .debug_addr {
+ _op .${_cu_addr_size}byte [lindex $line 1]
+ }
+ }
+
DW_OP_regx {
_get_args $line $opcode register
_op .uleb128 $argvec(register)
}
}
+ # Return a label that references the current position in the
+ # .debug_addr table. When a user is creating split DWARF they
+ # will define two CUs, the first will be the split DWARF content,
+ # and the second will be the non-split stub CU. The split DWARF
+ # CU fills in the .debug_addr section, but the non-split CU
+ # includes a reference to the start of the section. The label
+ # returned by this proc provides that reference.
+ proc debug_addr_label {} {
+ variable _debug_addr_index
+
+ set lbl [new_label "debug_addr_idx_${_debug_addr_index}_"]
+ _defer_output .debug_addr {
+ define_label $lbl
+ }
+ return $lbl
+ }
+
# Emit a DWARF CU.
# OPTIONS is a list with an even number of elements containing
# option-name and option-value pairs.
variable _cu_version
variable _cu_addr_size
variable _cu_offset_size
+ variable _cu_is_fission
# Establish the defaults.
set is_64 0
set _cu_version 4
set _cu_addr_size default
- set fission 0
+ set _cu_is_fission 0
set section ".debug_info"
set _abbrev_section ".debug_abbrev"
is_64 { set is_64 $value }
version { set _cu_version $value }
addr_size { set _cu_addr_size $value }
- fission { set fission $value }
+ fission { set _cu_is_fission $value }
default { error "unknown option $name" }
}
}
}
}
set _cu_offset_size [expr { $is_64 ? 8 : 4 }]
- if { $fission } {
+ if { $_cu_is_fission } {
set section ".debug_info.dwo"
set _abbrev_section ".debug_abbrev.dwo"
}
variable _cu_version
variable _cu_addr_size
variable _cu_offset_size
+ variable _cu_is_fission
# Establish the defaults.
set is_64 0
set _cu_version 4
set _cu_addr_size default
- set fission 0
+ set _cu_is_fission 0
set section ".debug_types"
set _abbrev_section ".debug_abbrev"
is_64 { set is_64 $value }
version { set _cu_version $value }
addr_size { set _cu_addr_size $value }
- fission { set fission $value }
+ fission { set _cu_is_fission $value }
default { error "unknown option $name" }
}
}
}
}
set _cu_offset_size [expr { $is_64 ? 8 : 4 }]
- if { $fission } {
+ if { $_cu_is_fission } {
set section ".debug_types.dwo"
set _abbrev_section ".debug_abbrev.dwo"
}
variable _line_saw_program
variable _line_header_end_label
variable _debug_ranges_64_bit
+ variable _debug_addr_index
if {!$_initialized} {
_read_constants
set _line_saw_program 0
set _debug_ranges_64_bit [is_64_target]
+ set _debug_addr_index 0
+
# Not "uplevel" here, because we want to evaluate in this
# namespace. This is somewhat bad because it means we can't
# readily refer to outer variables.