2012-07-11 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. Index: buildsym.c =================================================================== RCS file: /cvs/src/src/gdb/buildsym.c,v retrieving revision 1.100 diff -u -p -r1.100 buildsym.c --- buildsym.c 10 Jul 2012 20:20:15 -0000 1.100 +++ buildsym.c 12 Jul 2012 04:56:06 -0000 @@ -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. - - 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. - - If EXPANDABLE is non-zero the dictionaries for the global and static - blocks are 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) +/* 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 same as for end_symtab: the address of the end of the + file's text. + + If EXPANDABLE is non-zero the STATIC_BLOCK dictionary is made + 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 && 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 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. Index: buildsym.h =================================================================== RCS file: /cvs/src/src/gdb/buildsym.h,v retrieving revision 1.33 diff -u -p -r1.33 buildsym.h --- buildsym.h 10 Jul 2012 20:20:15 -0000 1.33 +++ buildsym.h 12 Jul 2012 04:56:06 -0000 @@ -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); Index: dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.684 diff -u -p -r1.684 dwarf2read.c --- dwarf2read.c 10 Jul 2012 20:28:32 -0000 1.684 +++ dwarf2read.c 12 Jul 2012 04:56:07 -0000 @@ -6593,6 +6593,7 @@ process_full_comp_unit (struct dwarf2_pe 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_pe 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) {