diff options
-rw-r--r-- | gdb/ChangeLog | 3 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 25 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/dw2-cu-size.S | 106 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/dw2-cu-size.exp | 53 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/dw2-intercu.S | 4 |
6 files changed, 190 insertions, 9 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1c09d3b..43fa44a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,8 @@ 2008-10-06 Doug Evans <dje@google.com> + * dwarf2read.c (offset_in_cu_p): New function. + (find_partial_die,follow_die_ref): Use it. + * symmisc.c (maintenance_info_symtabs): Watch for ^c. (maintenance_info_psymtabs): Ditto. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 5e4d15f..fe95cdb 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -360,7 +360,9 @@ struct dwarf2_per_cu_data { /* The start offset and length of this compilation unit. 2**30-1 bytes should suffice to store the length of any compilation unit - - if it doesn't, GDB will fall over anyway. */ + - if it doesn't, GDB will fall over anyway. + NOTE: Unlike comp_unit_head.length, this length includes + initial_length_size. */ unsigned long offset; unsigned long length : 30; @@ -1314,6 +1316,18 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline) } #endif +/* Return TRUE if OFFSET is within CU_HEADER. */ + +static inline int +offset_in_cu_p (const struct comp_unit_head *cu_header, unsigned int offset) +{ + unsigned int bottom = cu_header->offset; + unsigned int top = (cu_header->offset + + cu_header->length + + cu_header->initial_length_size); + return (offset >= bottom && offset < top); +} + /* Read in the comp unit header information from the debug_info at info_ptr. */ @@ -5990,8 +6004,7 @@ find_partial_die (unsigned long offset, struct dwarf2_cu *cu) struct dwarf2_per_cu_data *per_cu = NULL; struct partial_die_info *pd = NULL; - if (offset >= cu->header.offset - && offset < cu->header.offset + cu->header.length) + if (offset_in_cu_p (&cu->header, offset)) { pd = find_partial_die_in_comp_unit (offset, cu); if (pd != NULL) @@ -9230,12 +9243,10 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr, offset = dwarf2_get_ref_die_offset (attr, cu); - if (DW_ADDR (attr) < cu->header.offset - || DW_ADDR (attr) >= cu->header.offset + cu->header.length) + if (! offset_in_cu_p (&cu->header, offset)) { struct dwarf2_per_cu_data *per_cu; - per_cu = dwarf2_find_containing_comp_unit (DW_ADDR (attr), - cu->objfile); + per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile); /* If necessary, add it to the queue and load its DIEs. */ maybe_queue_comp_unit (cu, per_cu); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 7681b2a..12d1624 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2008-10-06 Doug Evans <dje@google.com> + + * gdb.dwarf2/dw2-cu-size.exp: New file. + * gdb.dwarf2/dw2-cu-size.S: New file. + + * gdb.dwarf2/dw2-intercu.S (.Ltype_int_in_cu2): Renamed from + .Ltype_int for clarity. + 2008-10-03 Paul Pluzhnikov <ppluzhnikov@google.com> PR gdb/2384: diff --git a/gdb/testsuite/gdb.dwarf2/dw2-cu-size.S b/gdb/testsuite/gdb.dwarf2/dw2-cu-size.S new file mode 100644 index 0000000..30fb616 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-cu-size.S @@ -0,0 +1,106 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2008 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/>. */ + +/* Test inter-cu reference support where the referenced DIE is within + initial_length_size bytes of the end of the CU, but GDB doesn't take + into account initial_length_size. + GDB still gets the correct answer because it goes looking for the + correct CU, but the search is unnecessary. */ + +/* Debug information */ + + .section .debug_info +.Lcu1_begin: + /* CU header */ + .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */ +.Lcu1_start: + .2byte 2 /* DWARF Version */ + .4byte .Labbrev1_begin /* Offset into abbrev section */ + .byte 4 /* Pointer size */ + + /* CU die */ + .uleb128 1 /* Abbrev: DW_TAG_compile_unit */ + .ascii "file1.txt\0" /* DW_AT_name */ + .ascii "GNU C 3.3.3\0" /* DW_AT_producer */ + .byte 1 /* DW_AT_language (C) */ + + .uleb128 2 /* Abbrev: DW_TAG_variable */ + .ascii "noloc\0" /* DW_AT_name */ + .4byte .Ltype_const_int-.Lcu1_begin /* DW_AT_type */ + .byte 1 /* DW_AT_external */ + +.Ltype_int: + .uleb128 3 /* Abbrev: DW_TAG_base_type */ + .ascii "int\0" /* DW_AT_name */ + .byte 4 /* DW_AT_byte_size */ + .byte 5 /* DW_AT_encoding */ + +.Ltype_const_int: + .uleb128 4 /* Abbrev: DW_TAG_const_type */ + .uleb128 .Ltype_int - .Lcu1_begin /* DW_AT_type */ + + .byte 0 /* End of children of CU */ + +.Lcu1_end: + +/* Abbrev table */ + .section .debug_abbrev +.Labbrev1_begin: + .uleb128 1 /* Abbrev code */ + .uleb128 0x11 /* DW_TAG_compile_unit */ + .byte 1 /* has_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x25 /* DW_AT_producer */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x13 /* DW_AT_language */ + .uleb128 0xb /* DW_FORM_data1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 2 /* Abbrev code */ + .uleb128 0x34 /* DW_TAG_variable */ + .byte 0 /* has_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .uleb128 0x3f /* DW_AT_external */ + .uleb128 0xc /* DW_FORM_flag */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 3 /* Abbrev code */ + .uleb128 0x24 /* DW_TAG_base_type */ + .byte 0 /* has_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0xb /* DW_AT_byte_size */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x3e /* DW_AT_encoding */ + .uleb128 0xb /* DW_FORM_data1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 4 /* Abbrev code */ + .uleb128 0x26 /* DW_TAG_const_type */ + .byte 0 /* has_children */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x15 /* DW_FORM_ref_udata */ + + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ diff --git a/gdb/testsuite/gdb.dwarf2/dw2-cu-size.exp b/gdb/testsuite/gdb.dwarf2/dw2-cu-size.exp new file mode 100644 index 0000000..7819806 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-cu-size.exp @@ -0,0 +1,53 @@ +# Copyright 2004, 2005, 2007, 2008 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/>. + +# Test inter-cu references where the referenced DIE is within +# initial_length_size bytes of the end of the CU. +# This catches cases where the code doesn't include initial_length_size +# in the length of the CU. */ + +# This test can only be run on targets which support DWARF-2 and use gas. +# For now pick a sampling of likely targets. +if {![istarget *-*-linux*] + && ![istarget *-*-gnu*] + && ![istarget *-*-elf*] + && ![istarget *-*-openbsd*] + && ![istarget arm-*-eabi*] + && ![istarget powerpc-*-eabi*]} { + return 0 +} + +set testfile "dw2-cu-size" +set srcfile ${testfile}.S +set binfile ${objdir}/${subdir}/${testfile}.x + +if { [gdb_compile "${srcdir}/${subdir}/main.c" "main.o" object {debug}] != "" } { + return -1 +} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${testfile}.o" object {nodebug}] != "" } { + return -1 +} + +if { [gdb_compile "${testfile}.o main.o" "${binfile}" executable {debug}] != "" } { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +gdb_test "ptype noloc" "type = const int" diff --git a/gdb/testsuite/gdb.dwarf2/dw2-intercu.S b/gdb/testsuite/gdb.dwarf2/dw2-intercu.S index 781dadb..a58da47 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-intercu.S +++ b/gdb/testsuite/gdb.dwarf2/dw2-intercu.S @@ -58,7 +58,7 @@ func_cu1: .byte 1 /* DW_AT_decl_file */ .byte 2 /* DW_AT_decl_line */ .ascii "func_cu1\0" /* DW_AT_name */ - .4byte .Ltype_int /* DW_AT_type */ + .4byte .Ltype_int_in_cu2 /* DW_AT_type */ .4byte .Lbegin_func_cu1 /* DW_AT_low_pc */ .4byte .Lend_func_cu1 /* DW_AT_high_pc */ .byte 1 /* DW_AT_frame_base: length */ @@ -83,7 +83,7 @@ func_cu1: .ascii "GNU C 3.3.3\0" /* DW_AT_producer */ .byte 1 /* DW_AT_language (C) */ -.Ltype_int: +.Ltype_int_in_cu2: .uleb128 2 /* Abbrev: DW_TAG_base_type */ .ascii "int\0" /* DW_AT_name */ .byte 4 /* DW_AT_byte_size */ |