From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11940 invoked by alias); 4 Oct 2008 20:55:31 -0000 Received: (qmail 11931 invoked by uid 22791); 4 Oct 2008 20:55:30 -0000 X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.33.17) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sat, 04 Oct 2008 20:54:15 +0000 Received: from wpaz1.hot.corp.google.com (wpaz1.hot.corp.google.com [172.24.198.65]) by smtp-out.google.com with ESMTP id m94Ks50w024120 for ; Sat, 4 Oct 2008 21:54:05 +0100 Received: from localhost (ruffy.corp.google.com [172.18.118.116]) by wpaz1.hot.corp.google.com with ESMTP id m94Ks3VC009062 for ; Sat, 4 Oct 2008 13:54:04 -0700 Received: by localhost (Postfix, from userid 67641) id 7D5A141267A; Sat, 4 Oct 2008 13:54:03 -0700 (PDT) To: gdb-patches@sourceware.org Subject: fix dwarf2read.c offset-is-in-cu calculation Message-Id: <20081004205403.7D5A141267A@localhost> Date: Sat, 04 Oct 2008 20:55:00 -0000 From: dje@google.com (Doug Evans) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-10/txt/msg00113.txt.bz2 Some calculations for whether an offset is within a CU don't take into account initial_length_size. The error is innocuous because GDB will still lookup the correct CU, but it didn't have to do the lookup. The error also causes the CU to be made a dependency of itself which is unnecessary. This also changes the name of a label in dw2-intercu.S to improve readability. Ok to check in? 2008-10-04 Doug Evans * dwarf2read.c (offset_in_cu_p): New function. (find_partial_die,follow_die_ref): Use it. * 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. Index: dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.285 diff -u -p -d -u -r1.285 dwarf2read.c --- dwarf2read.c 30 Sep 2008 16:57:37 -0000 1.285 +++ dwarf2read.c 4 Oct 2008 20:41:13 -0000 @@ -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 objfi } #endif +/* Return TRUE if OFFSET is within CU. */ + +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_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 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); Index: testsuite/gdb.dwarf2/dw2-cu-size.S =================================================================== RCS file: testsuite/gdb.dwarf2/dw2-cu-size.S diff -N testsuite/gdb.dwarf2/dw2-cu-size.S --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.dwarf2/dw2-cu-size.S 4 Oct 2008 20:41:13 -0000 @@ -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 . */ + +/* 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 */ Index: testsuite/gdb.dwarf2/dw2-cu-size.exp =================================================================== RCS file: testsuite/gdb.dwarf2/dw2-cu-size.exp diff -N testsuite/gdb.dwarf2/dw2-cu-size.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.dwarf2/dw2-cu-size.exp 4 Oct 2008 20:41:13 -0000 @@ -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 . + +# 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" Index: testsuite/gdb.dwarf2/dw2-intercu.S =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.dwarf2/dw2-intercu.S,v retrieving revision 1.5 diff -u -p -d -u -r1.5 dw2-intercu.S --- testsuite/gdb.dwarf2/dw2-intercu.S 1 Jan 2008 22:53:19 -0000 1.5 +++ testsuite/gdb.dwarf2/dw2-intercu.S 4 Oct 2008 20:41:13 -0000 @@ -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 */