From: Doug Evans Date: Thu, 28 Jun 2012 01:10:38 +0000 (+0000) Subject: * dwarf2read.c (dwarf2_cu): Add ranges_base. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2e3cf129e630bec707b68e85b388b056ba3bbda2;p=binutils-gdb.git * dwarf2read.c (dwarf2_cu): Add ranges_base. Delete have_addr_base, unused. All uses updated. (init_cutu_and_read_dies): Process DW_AT_GNU_ranges_base. (dwarf2_get_pc_bounds): Add ranges_base. (dwarf2_record_block_ranges): Ditto. testsuite/ * gdb.dwarf2/fission-base.c: New file. * gdb.dwarf2/fission-base.S: New file. * gdb.dwarf2/fission-base.exp: New file. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0e1cd3c6711..abb6b565214 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2012-06-27 Doug Evans + + * dwarf2read.c (dwarf2_cu): Add ranges_base. + Delete have_addr_base, unused. All uses updated. + (init_cutu_and_read_dies): Process DW_AT_GNU_ranges_base. + (dwarf2_get_pc_bounds): Add ranges_base. + (dwarf2_record_block_ranges): Ditto. + 2012-06-27 Tom Tromey PR macros/7961: diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 4b43adf3350..4744107f1fc 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -459,6 +459,13 @@ struct dwarf2_cu Note this value comes from the stub CU/TU's DIE. */ ULONGEST addr_base; + /* The DW_AT_ranges_base attribute if present, zero otherwise + (zero is a valid value though). + Note this value comes from the stub CU/TU's DIE. + Also note that the value is zero in the non-DWO case so this value can + be used without needing to know whether DWO files are in use or not. */ + ULONGEST ranges_base; + /* Mark used when releasing cached dies. */ unsigned int mark : 1; @@ -475,10 +482,6 @@ struct dwarf2_cu unsigned int checked_producer : 1; unsigned int producer_is_gxx_lt_4_6 : 1; unsigned int producer_is_icc : 1; - - /* Non-zero if DW_AT_addr_base was found. - Used when processing DWO files. */ - unsigned int have_addr_base : 1; }; /* Persistent data held for a compilation unit, even when not @@ -3996,13 +3999,16 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, /* There should be a DW_AT_addr_base attribute here (if needed). We need the value before we can process DW_FORM_GNU_addr_index. */ cu->addr_base = 0; - cu->have_addr_base = 0; attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_addr_base, cu); if (attr) - { - cu->addr_base = DW_UNSND (attr); - cu->have_addr_base = 1; - } + cu->addr_base = DW_UNSND (attr); + + /* There should be a DW_AT_ranges_base attribute here (if needed). + We need the value before we can process DW_AT_ranges. */ + cu->ranges_base = 0; + attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_ranges_base, cu); + if (attr) + cu->ranges_base = DW_UNSND (attr); if (this_cu->is_debug_types) { @@ -8249,9 +8255,11 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, attr = dwarf2_attr (die, DW_AT_ranges, cu); if (attr != NULL) { + unsigned int ranges_offset = DW_UNSND (attr) + cu->ranges_base; + /* Value of the DW_AT_ranges attribute is the offset in the .debug_ranges section. */ - if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, pst)) + if (!dwarf2_ranges_read (ranges_offset, &low, &high, cu, pst)) return 0; /* Found discontinuous range of addresses. */ ret = -1; @@ -8411,7 +8419,7 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block, /* The value of the DW_AT_ranges attribute is the offset of the address range list in the .debug_ranges section. */ - unsigned long offset = DW_UNSND (attr); + unsigned long offset = DW_UNSND (attr) + cu->ranges_base; gdb_byte *buffer = dwarf2_per_objfile->ranges.buffer + offset; /* For some target architectures, but not others, the diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 77c907bdca6..339cb0af073 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-06-27 Doug Evans + + * gdb.dwarf2/fission-base.c: New file. + * gdb.dwarf2/fission-base.S: New file. + * gdb.dwarf2/fission-base.exp: New file. + 2012-06-27 Jan Kratochvil * gdb.dwarf2/callframecfa.exp: Replace $testname by $testfile. diff --git a/gdb/testsuite/gdb.dwarf2/fission-base.S b/gdb/testsuite/gdb.dwarf2/fission-base.S new file mode 100644 index 00000000000..94ba06834cb --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/fission-base.S @@ -0,0 +1,364 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2012 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 . + + This file was created by doing: + gcc -gdwarf-4 -gsplit-debug -S -dA fission-base.c + and then massaging the output. +*/ + + .file "fission-base.c" + + .text +.Ltext0: + + .globl func + .type func, @function +func: +.LFB0: + .file 1 "fission-base.c" + # fission-base.c:20 + .loc 1 20 0 + .cfi_startproc + pushq %rbp # + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp #, + .cfi_def_cfa_register 6 + movl %edi, -4(%rbp) # arg, arg + # fission-base.c:21 + .loc 1 21 0 + movl -4(%rbp), %eax # arg, tmp61 + addl $1, %eax #, D.1617 + # fission-base.c:22 + .loc 1 22 0 + popq %rbp # + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size func, .-func + .globl main + .type main, @function +main: +.LFB1: + # fission-base.c:26 + .loc 1 26 0 + .cfi_startproc + pushq %rbp # + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp #, + .cfi_def_cfa_register 6 + # fission-base.c:27 + .loc 1 27 0 + movl $-1, %edi #, + call func # + # fission-base.c:28 + .loc 1 28 0 + popq %rbp # + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size main, .-main +.Letext0: + .section .debug_info.dwo,"",@progbits +.Ldebug_info0: + .4byte .Ldebug_info0_end - .Ldebug_info0 - 4 # Length of Compilation Unit Info + .2byte 0x4 # DWARF version number + .4byte .Ldebug_abbrev0 # Offset Into Abbrev. Section + .byte 0x8 # Pointer Size (in bytes) + .uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit) + .ascii "GNU C 4.6.x-fission\0" # DW_AT_producer + .byte 0x1 # DW_AT_language + .ascii "fission-base.c\0" # DW_AT_name + .ascii "/tmp/src/gdb/testsuite/gdb.dwarf2\0" # DW_AT_comp_dir + .byte 0 # DW_AT_GNU_dwo_id + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .uleb128 0x2 # (DIE (0x89) DW_TAG_subprogram) + # DW_AT_external + .ascii "func\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (fission-base.c) + .byte 0x13 # DW_AT_decl_line + # DW_AT_prototyped + .4byte .Ldebug_info0_int # DW_AT_type + .4byte 0x0 # DW_AT_ranges + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + .4byte .Ldebug_info0_int # DW_AT_sibling + .uleb128 0x3 # (DIE (0xa4) DW_TAG_formal_parameter) + .ascii "arg\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (fission-base.c) + .byte 0x13 # DW_AT_decl_line + .4byte .Ldebug_info0_int # DW_AT_type + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -20 + .byte 0 # end of children of DIE 0x89 +.Ldebug_info0_int: + .uleb128 0x4 # (DIE (0xb3) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .ascii "int\0" # DW_AT_name + .uleb128 0x5 # (DIE (0xba) DW_TAG_subprogram) + # DW_AT_external + .ascii "main\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (fission-base.c) + .byte 0x19 # DW_AT_decl_line + .4byte .Ldebug_info0_int # DW_AT_type + .uleb128 0x1 # DW_AT_low_pc + .8byte .LFE1-.LFB1 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + .byte 0 # end of children of DIE 0xb +.Ldebug_info0_end: + .section .debug_info,"",@progbits +.Lskeleton_debug_info0: + .4byte .Lskeleton_debug_info0_end - .Lskeleton_debug_info0 - 4 # Length of Compilation Unit Info + .2byte 0x4 # DWARF version number + .4byte .Lskeleton_debug_abbrev0 # Offset Into Abbrev. Section + .byte 0x8 # Pointer Size (in bytes) + .uleb128 0x1 # (DIE (0) DW_TAG_compile_unit) + .8byte .Ltext0 # DW_AT_low_pc + .8byte .Letext0-.Ltext0 # DW_AT_high_pc + .4byte .Ldebug_line0 # DW_AT_stmt_list + .ascii "/tmp/src/gdb/testsuite/gdb.dwarf2\0" # DW_AT_comp_dir + # Normally dwo_name would be "fission-base.dwo". + # Simplification: Leave the DWO contents in the executable. + .ascii "fission-base\0" # DW_AT_GNU_dwo_name + .4byte .Ldebug_pubnames0 # DW_AT_GNU_pubnames + .4byte .Ldebug_pubtypes0 # DW_AT_GNU_pubtypes + .4byte .Ldebug_addr0_begin # DW_AT_GNU_addr_base + .4byte .Ldebug_ranges0_begin # DW_AT_GNU_ranges_base + .byte 0 # DW_AT_GNU_dwo_id + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 +.Lskeleton_debug_info0_end: + .section .debug_abbrev,"",@progbits +.Lskeleton_debug_abbrev0: + .uleb128 0x1 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0 # DW_children_no + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x10 # (DW_AT_stmt_list) + .uleb128 0x17 # (DW_FORM_sec_offset) + .uleb128 0x1b # (DW_AT_comp_dir) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x2130 # (DW_AT_GNU_dwo_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x2134 # (DW_AT_GNU_pubnames) + .uleb128 0x17 # (DW_FORM_sec_offset) + .uleb128 0x2135 # (DW_AT_GNU_pubtypes) + .uleb128 0x17 # (DW_FORM_sec_offset) + .uleb128 0x2133 # (DW_AT_GNU_addr_base) + .uleb128 0x17 # (DW_FORM_sec_offset) + .uleb128 0x2132 # (DW_AT_GNU_ranges_base) + .uleb128 0x17 # (DW_FORM_sec_offset) + .uleb128 0x2131 # (DW_AT_GNU_dwo_id) + .uleb128 0x7 # (DW_FORM_data8) + .byte 0 + .byte 0 + .byte 0 # end of skeleton .debug_abbrev + .section .debug_abbrev.dwo,"",@progbits +.Ldebug_abbrev0: + .uleb128 0x1 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0x1 # DW_children_yes + .uleb128 0x25 # (DW_AT_producer) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x13 # (DW_AT_language) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x1b # (DW_AT_comp_dir) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x2131 # (DW_AT_GNU_dwo_id) + .uleb128 0x7 # (DW_FORM_data8) + .byte 0 + .byte 0 + .uleb128 0x2 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x55 # (DW_AT_ranges) + .uleb128 0x17 # (DW_FORM_sec_offset) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x3 # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .uleb128 0x4 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .byte 0 + .byte 0 + .uleb128 0x5 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0 # DW_children_no + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1f01 # (DW_FORM_GNU_addr_index) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .byte 0 + .section .debug_pubnames,"",@progbits +.Ldebug_pubnames0: + .4byte 0x20 # Length of Public Names Info + .2byte 0x2 # DWARF Version + .4byte .Lskeleton_debug_info0 # Offset of Compilation Unit Info + .4byte 0xd2 # Compilation Unit Length + .4byte 0x89 # DIE offset + .ascii "func\0" # external name + .4byte 0xba # DIE offset + .ascii "main\0" # external name + .4byte 0 + .section .debug_pubtypes,"",@progbits +.Ldebug_pubtypes0: + .4byte 0x16 # Length of Public Type Names Info + .2byte 0x2 # DWARF Version + .4byte .Lskeleton_debug_info0 # Offset of Compilation Unit Info + .4byte 0xd2 # Compilation Unit Length + .4byte .Ldebug_info0_int # DIE offset + .ascii "int\0" # external name + .4byte 0 + .section .debug_aranges,"",@progbits + .4byte 0x2c # Length of Address Ranges Info + .2byte 0x2 # DWARF Version + .4byte .Lskeleton_debug_info0 # Offset of Compilation Unit Info + .byte 0x8 # Size of Address + .byte 0 # Size of Segment Descriptor + .2byte 0 # Pad to 16 byte boundary + .2byte 0 + .8byte .Ltext0 # Address + .8byte .Letext0-.Ltext0 # Length + .8byte 0 + .8byte 0 + .section .debug_line,"",@progbits +.Ldebug_line0: + .section .debug_line.dwo,"",@progbits +.Lskeleton_debug_line0: + .4byte .LELT0-.LSLT0 # Length of Source Line Info +.LSLT0: + .2byte 0x4 # DWARF Version + .4byte .LELTP0-.LASLTP0 # Prolog Length +.LASLTP0: + .byte 0x1 # Minimum Instruction Length + .byte 0x1 # Maximum Operations Per Instruction + .byte 0x1 # Default is_stmt_start flag + .byte 0xf6 # Line Base Value (Special Opcodes) + .byte 0xf5 # Line Range Value (Special Opcodes) + .byte 0xa # Special Opcode Base + .byte 0 # opcode: 0x1 has 0 args + .byte 0x1 # opcode: 0x2 has 1 args + .byte 0x1 # opcode: 0x3 has 1 args + .byte 0x1 # opcode: 0x4 has 1 args + .byte 0x1 # opcode: 0x5 has 1 args + .byte 0 # opcode: 0x6 has 0 args + .byte 0 # opcode: 0x7 has 0 args + .byte 0 # opcode: 0x8 has 0 args + .byte 0x1 # opcode: 0x9 has 1 args + .byte 0 # End directory table + .ascii "fission-base.c\0" # File Entry: 0x1 + .uleb128 0 + .uleb128 0 + .uleb128 0 + .byte 0 # End file name table +.LELTP0: +.LELT0: + .section .debug_addr,"",@progbits +.Ldebug_addr0: + # Shift the real entries down by a non-zero amount to test + # DW_AT_GNU_addr_base. + .8byte 0,0 +.Ldebug_addr0_begin: + .8byte .LFB0 # DW_AT_low_pc + .8byte .LFB1 # DW_AT_low_pc + + .section .debug_ranges,"",@progbits +.Ldebug_ranges0: + # Shift the real entries down by a non-zero amount to test + # DW_AT_GNU_ranges_base. + .8byte 0,0 +.Ldebug_ranges0_begin: + # Note: Since the DW_TAG_compile_unit specifies low_pc, that sets + # the base address, and thus we have to subtract it here. + .8byte .LFB0 - .Ltext0 # Offset 0 + .8byte .LFE0 - .Ltext0 + .8byte 0 + .8byte 0 + + .section .note.GNU-stack,"",@progbits diff --git a/gdb/testsuite/gdb.dwarf2/fission-base.c b/gdb/testsuite/gdb.dwarf2/fission-base.c new file mode 100644 index 00000000000..f2eb3873591 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/fission-base.c @@ -0,0 +1,28 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2012 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 . */ + +int +func (int arg) +{ + return arg + 1; +} + +int +main () +{ + return func (-1); +} diff --git a/gdb/testsuite/gdb.dwarf2/fission-base.exp b/gdb/testsuite/gdb.dwarf2/fission-base.exp new file mode 100644 index 00000000000..2bd274828e1 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/fission-base.exp @@ -0,0 +1,64 @@ +# Copyright 2012 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 . + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +if ![dwarf2_support] { + return 0 +} + +# This test can only be run on x86-64 targets. +if {![istarget x86_64-*] || ![is_lp64_target]} { + return 0 +} + +set basename "fission-base" + +standard_testfile .S + +# IWBN to use prepare_for_testing here, but we need to set debug-file-directory +# before we load the binary. + +if { [build_executable "$testfile.exp" "$testfile" "$srcfile" {nodebug}] } { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +# Set debug-file-directory so we find the dwo file. +gdb_test_no_output "set debug-file-directory $subdir" +gdb_load [standard_output_file $testfile] + +if ![runto_main] { + return -1 +} + +# Do a few basic things to verify we're finding the DWO debug info. + +gdb_test "ptype main" "type = int \\(\\)" +gdb_test "ptype func" "type = int \\(int\\)" + +gdb_test "frame" "#0 *main \\(\\) at $testfile\\.c:$decimal.*" \ + "frame in main" + +gdb_test "break func" "Breakpoint.*at.* file .*$testfile\\.c, line .*" + +gdb_test "continue" "Breakpoint.* func \\(arg=-1\\).*" \ + "continue to func" + +gdb_test "frame" "#0 *func \\(arg=-1\\) at $testfile\\.c:$decimal.*" \ + "frame in func"