From 4359dff1c517dc398912c8d3be440b711881b6d6 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Fri, 13 Jul 2012 20:26:11 +0000 Subject: [PATCH] gdb/ * buildsym.c (end_symtab_1): Split it to ... (end_symtab_get_static_block): ... this ... (end_symtab_from_static_block): ... and this function. (end_symtab, end_expandable_symtab): Call them. * buildsym.h (end_symtab_get_static_block) (end_symtab_from_static_block): New declarations. * dwarf2read.c (process_full_comp_unit): New variable static_block. Set its valid CU ranges. gdb/testsuite/ * gdb.dwarf2/dw2-minsym-in-cu.S: New file. * gdb.dwarf2/dw2-minsym-in-cu.exp: New file. --- gdb/ChangeLog | 12 ++ gdb/buildsym.c | 120 ++++++++++++------ gdb/buildsym.h | 9 ++ gdb/dwarf2read.c | 13 +- gdb/testsuite/ChangeLog | 6 + gdb/testsuite/gdb.dwarf2/dw2-minsym-in-cu.S | 108 ++++++++++++++++ gdb/testsuite/gdb.dwarf2/dw2-minsym-in-cu.exp | 34 +++++ 7 files changed, 263 insertions(+), 39 deletions(-) create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-minsym-in-cu.S create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-minsym-in-cu.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index dec252b8557..b8884893ba2 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2012-07-13 Jan Kratochvil + Doug Evans + + * buildsym.c (end_symtab_1): Split it to ... + (end_symtab_get_static_block): ... this ... + (end_symtab_from_static_block): ... and this function. + (end_symtab, end_expandable_symtab): Call them. + * buildsym.h (end_symtab_get_static_block) + (end_symtab_from_static_block): New declarations. + * dwarf2read.c (process_full_comp_unit): New variable static_block. + Set its valid CU ranges. + 2012-07-13 Jan Kratochvil * dwarf2loc.c (disassemble_dwarf_expression): Handle diff --git a/gdb/buildsym.c b/gdb/buildsym.c index c94a9db3fff..d547012166b 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -957,42 +957,28 @@ reset_symtab_globals (void) } } -/* Finish the symbol definitions for one main source file, close off - all the lexical contexts for that file (creating struct block's for - them), then make the struct symtab for that file and put it in the - list of all such. +/* Implementation of the first part of end_symtab. It allows modifying + STATIC_BLOCK before it gets finalized by end_symtab_from_static_block. + If the returned value is NULL there is no blockvector created for + this symtab (you still must call end_symtab_from_static_block). - END_ADDR is the address of the end of the file's text. SECTION is - the section number (in objfile->section_offsets) of the blockvector - and linetable. + END_ADDR is the same as for end_symtab: the address of the end of the + file's text. - If EXPANDABLE is non-zero the dictionaries for the global and static - blocks are made expandable. + If EXPANDABLE is non-zero the STATIC_BLOCK dictionary is made + expandable. */ - Note that it is possible for end_symtab() to return NULL. In - particular, for the DWARF case at least, it will return NULL when - it finds a compilation unit that has exactly one DIE, a - TAG_compile_unit DIE. This can happen when we link in an object - file that was compiled from an empty source file. Returning NULL - is probably not the correct thing to do, because then gdb will - never know about this empty file (FIXME). */ - -static struct symtab * -end_symtab_1 (CORE_ADDR end_addr, struct objfile *objfile, int section, - int expandable) +struct block * +end_symtab_get_static_block (CORE_ADDR end_addr, struct objfile *objfile, + int expandable) { - struct symtab *symtab = NULL; - struct blockvector *blockvector; - struct subfile *subfile; - struct context_stack *cstk; - struct subfile *nextsub; - /* Finish the lexical context of the last function in the file; pop the context stack. */ if (context_stack_depth > 0) { - cstk = pop_context (); + struct context_stack *cstk = pop_context (); + /* Make a block for the local symbols within. */ finish_block (cstk->name, &local_symbols, cstk->old_blocks, cstk->start_addr, end_addr, objfile); @@ -1058,18 +1044,51 @@ end_symtab_1 (CORE_ADDR end_addr, struct objfile *objfile, int section, && have_line_numbers == 0 && pending_macros == NULL) { - /* Ignore symtabs that have no functions with real debugging - info. */ + /* Ignore symtabs that have no functions with real debugging info. */ + return NULL; + } + else + { + /* Define the STATIC_BLOCK. */ + return finish_block_internal (NULL, &file_symbols, NULL, + last_source_start_addr, end_addr, objfile, + 0, expandable); + } +} + +/* Implementation of the second part of end_symtab. Pass STATIC_BLOCK + as value returned by end_symtab_get_static_block. + + SECTION is the same as for end_symtab: the section number + (in objfile->section_offsets) of the blockvector and linetable. + + If EXPANDABLE is non-zero the GLOBAL_BLOCK dictionary is made + expandable. */ + +struct symtab * +end_symtab_from_static_block (struct block *static_block, + struct objfile *objfile, int section, + int expandable) +{ + struct symtab *symtab = NULL; + struct blockvector *blockvector; + struct subfile *subfile; + struct subfile *nextsub; + + if (static_block == NULL) + { + /* Ignore symtabs that have no functions with real debugging info. */ blockvector = NULL; } else { - /* Define the STATIC_BLOCK & GLOBAL_BLOCK, and build the + CORE_ADDR end_addr = BLOCK_END (static_block); + + /* Define after STATIC_BLOCK also GLOBAL_BLOCK, and build the blockvector. */ - finish_block_internal (0, &file_symbols, 0, last_source_start_addr, - end_addr, objfile, 0, expandable); - finish_block_internal (0, &global_symbols, 0, last_source_start_addr, - end_addr, objfile, 1, expandable); + finish_block_internal (NULL, &global_symbols, NULL, + last_source_start_addr, end_addr, objfile, + 1, expandable); blockvector = make_blockvector (objfile); } @@ -1251,21 +1270,46 @@ end_symtab_1 (CORE_ADDR end_addr, struct objfile *objfile, int section, return symtab; } -/* See end_symtab_1 for details. */ +/* Finish the symbol definitions for one main source file, close off + all the lexical contexts for that file (creating struct block's for + them), then make the struct symtab for that file and put it in the + list of all such. + + END_ADDR is the address of the end of the file's text. SECTION is + the section number (in objfile->section_offsets) of the blockvector + and linetable. + + Note that it is possible for end_symtab() to return NULL. In + particular, for the DWARF case at least, it will return NULL when + it finds a compilation unit that has exactly one DIE, a + TAG_compile_unit DIE. This can happen when we link in an object + file that was compiled from an empty source file. Returning NULL + is probably not the correct thing to do, because then gdb will + never know about this empty file (FIXME). + + If you need to modify STATIC_BLOCK before it is finalized you should + call end_symtab_get_static_block and end_symtab_from_static_block + yourself. */ struct symtab * end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) { - return end_symtab_1 (end_addr, objfile, section, 0); + struct block *static_block; + + static_block = end_symtab_get_static_block (end_addr, objfile, 0); + return end_symtab_from_static_block (static_block, objfile, section, 0); } -/* See end_symtab_1 for details. */ +/* Same as end_symtab except create a symtab that can be later added to. */ struct symtab * end_expandable_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) { - return end_symtab_1 (end_addr, objfile, section, 1); + struct block *static_block; + + static_block = end_symtab_get_static_block (end_addr, objfile, 1); + return end_symtab_from_static_block (static_block, objfile, section, 1); } /* Subroutine of augment_type_symtab to simplify it. diff --git a/gdb/buildsym.h b/gdb/buildsym.h index df5cc930a5a..162ee8c79df 100644 --- a/gdb/buildsym.h +++ b/gdb/buildsym.h @@ -258,6 +258,15 @@ extern void push_subfile (void); extern char *pop_subfile (void); +extern struct block *end_symtab_get_static_block (CORE_ADDR end_addr, + struct objfile *objfile, + int expandable); + +extern struct symtab *end_symtab_from_static_block (struct block *static_block, + struct objfile *objfile, + int section, + int expandable); + extern struct symtab *end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section); diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 9e3be9f4c61..1d51db25007 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -6593,6 +6593,7 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu, struct symtab *symtab; struct cleanup *back_to, *delayed_list_cleanup; CORE_ADDR baseaddr; + struct block *static_block; baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); @@ -6623,7 +6624,17 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu, it, by scanning the DIE's below the compilation unit. */ get_scope_pc_bounds (cu->dies, &lowpc, &highpc, cu); - symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile)); + static_block = end_symtab_get_static_block (highpc + baseaddr, objfile, 0); + + /* If the comp unit has DW_AT_ranges, it may have discontiguous ranges. + Also, DW_AT_ranges may record ranges not belonging to any child DIEs + (such as virtual method tables). Record the ranges in STATIC_BLOCK's + addrmap to help ensure it has an accurate map of pc values belonging to + this comp unit. */ + dwarf2_record_block_ranges (cu->dies, static_block, baseaddr, cu); + + symtab = end_symtab_from_static_block (static_block, objfile, + SECT_OFF_TEXT (objfile), 0); if (symtab != NULL) { diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index c422fc6a357..1205a51b5ed 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-07-13 Jan Kratochvil + Doug Evans + + * gdb.dwarf2/dw2-minsym-in-cu.S: New file. + * gdb.dwarf2/dw2-minsym-in-cu.exp: New file. + 2012-07-13 Jan Kratochvil Fix gdbserver run regression. diff --git a/gdb/testsuite/gdb.dwarf2/dw2-minsym-in-cu.S b/gdb/testsuite/gdb.dwarf2/dw2-minsym-in-cu.S new file mode 100644 index 00000000000..2f8068eacc7 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-minsym-in-cu.S @@ -0,0 +1,108 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2004, 2007-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 . */ + + .text +.Lbegin_text1: + + .globl main + .type main, %function +main: +.Lbegin_main: + .int 0 +.Lend_main: + .size main, .-main + + .globl func2 + .type func2, %function +func2: + .int 0 + .size func2, .-func2 + +.Lend_text1: + +/* 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 */ + .4byte .Lend_text1 /* DW_AT_high_pc */ + .4byte .Lbegin_text1 /* DW_AT_low_pc */ + .ascii "file1.txt\0" /* DW_AT_name */ + .ascii "GNU C 3.3.3\0" /* DW_AT_producer */ + .byte 1 /* DW_AT_language (C) */ + + /* main */ + .uleb128 2 /* Abbrev: DW_TAG_subprogram */ + .byte 1 /* DW_AT_external */ + .ascii "main\0" /* DW_AT_name */ + .4byte .Ldebug_ranges /* DW_AT_ranges */ + + .byte 0 /* End of children of CU */ +.Lcu1_end: + +/* DW_AT_ranges. */ + .section .debug_ranges +.Ldebug_ranges: + .4byte .Lbegin_main + .4byte .Lend_main - 1 + /* Make it slightly more interesting to set pending_addrmap_interesting. */ + .4byte .Lend_main - 1 + .4byte .Lend_main + .4byte 0 + .4byte 0 + +/* Abbrev table */ + .section .debug_abbrev +.Labbrev1_begin: + .uleb128 1 /* Abbrev code */ + .uleb128 0x11 /* DW_TAG_compile_unit */ + .byte 1 /* has_children */ + .uleb128 0x12 /* DW_AT_high_pc */ + .uleb128 0x1 /* DW_FORM_addr */ + .uleb128 0x11 /* DW_AT_low_pc */ + .uleb128 0x1 /* DW_FORM_addr */ + .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 0x2e /* DW_TAG_subprogram */ + .byte 0 /* has_children */ + .uleb128 0x3f /* DW_AT_external */ + .uleb128 0xc /* DW_FORM_flag */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x55 /* DW_AT_ranges */ + .uleb128 0x6 /* DW_FORM_data4 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ diff --git a/gdb/testsuite/gdb.dwarf2/dw2-minsym-in-cu.exp b/gdb/testsuite/gdb.dwarf2/dw2-minsym-in-cu.exp new file mode 100644 index 00000000000..7df47bdee80 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-minsym-in-cu.exp @@ -0,0 +1,34 @@ +# Copyright 2004-2005, 2007-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 testfile has reproducibility only with cc-with-index.sh. + +set testfile "dw2-minsym-in-cu" +set srcfile ${testfile}.S +set executable ${testfile} + +if [prepare_for_testing ${testfile}.exp ${executable} ${srcfile}] { + return -1 +} + +# Ask for address which is still located in this CU but not described by +# any DIE. +gdb_test "info fun func2" {All functions matching regular expression "func2":} -- 2.30.2