diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 17 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 183 |
2 files changed, 185 insertions, 15 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 83dd892..d05a095 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,20 @@ +2004-05-03 J. Brobecker <brobecker@gnat.com> + + * dwarf2read.c (line_header): Add new included_p field in + field file_names. + (partial_die_info): New field has_stmt_list. New field line_offset. + (dwarf2_create_include_psymtab): New function. + (dwarf2_build_include_psymtabs): New function. + (add_file_name): Add forward declaration. Initialize new field. + (dwarf_decode_lines): Add new parameter. Enhance this procedure + to be able to determine the list of files included by the + given unit, and build their associated psymtabs. + (dwarf2_build_psymtabs_hard): Build the psymtabs for the included + files as well. + (psymtab_to_symtab_1): Build the symtabs of all dependencies as well. + (read_file_scope): Update call to dwarf_decode_lines. + (read_partial_die): Handle DW_AT_stmt_list attributes. + 2004-05-02 Michael Chastain <mec.gnu@mindspring.com> Unfix PR gdb/1626. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index da20b97..f9081a3 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -341,6 +341,7 @@ struct line_header unsigned int dir_index; unsigned int mod_time; unsigned int length; + int included_p; /* Non-zero if referenced by the Line Number Program. */ } *file_names; /* The start and end of the statement program following this @@ -368,6 +369,7 @@ struct partial_die_info unsigned int is_declaration : 1; unsigned int has_type : 1; unsigned int has_specification : 1; + unsigned int has_stmt_list : 1; unsigned int has_pc_info : 1; /* Flag set if the SCOPE field of this structure has been @@ -400,6 +402,9 @@ struct partial_die_info DW_AT_extension). */ unsigned int spec_offset; + /* If HAS_STMT_LIST, the offset of the Line Number Information data. */ + unsigned int line_offset; + /* Pointers to this DIE's parent, first child, and next sibling, if any. */ struct partial_die_info *die_parent, *die_child, *die_sibling; @@ -631,6 +636,13 @@ static void dwarf2_locate_sections (bfd *, asection *, void *); static void dwarf2_build_psymtabs_easy (struct objfile *, int); #endif +static void dwarf2_create_include_psymtab (char *, struct partial_symtab *, + struct objfile *); + +static void dwarf2_build_include_psymtabs (struct dwarf2_cu *, + struct partial_die_info *, + struct partial_symtab *); + static void dwarf2_build_psymtabs_hard (struct objfile *, int); static void scan_partial_symbols (struct partial_die_info *, @@ -739,12 +751,15 @@ static struct die_info *die_specification (struct die_info *die, static void free_line_header (struct line_header *lh); +static void add_file_name (struct line_header *, char *, unsigned int, + unsigned int, unsigned int); + static struct line_header *(dwarf_decode_line_header (unsigned int offset, bfd *abfd, struct dwarf2_cu *cu)); static void dwarf_decode_lines (struct line_header *, char *, bfd *, - struct dwarf2_cu *); + struct dwarf2_cu *, struct partial_symtab *); static void dwarf2_start_subfile (char *, char *); @@ -1194,6 +1209,68 @@ partial_read_comp_unit_head (struct comp_unit_head *header, char *info_ptr, return info_ptr; } +/* Allocate a new partial symtab for file named NAME and mark this new + partial symtab as being an include of PST. */ + +static void +dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst, + struct objfile *objfile) +{ + struct partial_symtab *subpst = allocate_psymtab (name, objfile); + + subpst->section_offsets = pst->section_offsets; + subpst->textlow = 0; + subpst->texthigh = 0; + + subpst->dependencies = (struct partial_symtab **) + obstack_alloc (&objfile->objfile_obstack, + sizeof (struct partial_symtab *)); + subpst->dependencies[0] = pst; + subpst->number_of_dependencies = 1; + + subpst->globals_offset = 0; + subpst->n_global_syms = 0; + subpst->statics_offset = 0; + subpst->n_static_syms = 0; + subpst->symtab = NULL; + subpst->read_symtab = pst->read_symtab; + subpst->readin = 0; + + /* No private part is necessary for include psymtabs. This property + can be used to differentiate between such include psymtabs and + the regular ones. If it ever happens that a regular psymtab can + legitimally have a NULL PST_PRIVATE part, then we'll have to add a + dedicated field for that in the dwarf2_pinfo structure. */ + PST_PRIVATE (subpst) = NULL; +} + +/* Read the Line Number Program data and extract the list of files + included by the source file represented by PST. Build an include + partial symtab for each of these included files. + + This procedure assumes that there *is* a Line Number Program in + the given CU. Callers should check that PDI->HAS_STMT_LIST is set + before calling this procedure. */ + +static void +dwarf2_build_include_psymtabs (struct dwarf2_cu *cu, + struct partial_die_info *pdi, + struct partial_symtab *pst) +{ + struct objfile *objfile = cu->objfile; + bfd *abfd = objfile->obfd; + struct line_header *lh; + + lh = dwarf_decode_line_header (pdi->line_offset, abfd, cu); + if (lh == NULL) + return; /* No linetable, so no includes. */ + + dwarf_decode_lines (lh, NULL, abfd, cu, pst); + + free_line_header (lh); +} + + /* Build the partial symbol table by doing a quick pass through the .debug_info and .debug_abbrev sections. */ @@ -1321,6 +1398,13 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) also happen.) This happens in VxWorks. */ free_named_symtabs (pst->filename); + if (comp_unit_die.has_stmt_list) + { + /* Get the list of files included in the current compilation unit, + and build a psymtab for each of them. */ + dwarf2_build_include_psymtabs (&cu, &comp_unit_die, pst); + } + info_ptr = beg_of_comp_unit + cu.header.length + cu.header.initial_length_size; @@ -2006,6 +2090,32 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) struct cleanup *back_to; struct attribute *attr; CORE_ADDR baseaddr; + int i; + + for (i = 0; i < pst->number_of_dependencies; i++) + if (!pst->dependencies[i]->readin) + { + /* Inform about additional files that need to be read in. */ + if (info_verbose) + { + fputs_filtered (" ", gdb_stdout); + wrap_here (""); + fputs_filtered ("and ", gdb_stdout); + wrap_here (""); + printf_filtered ("%s...", pst->dependencies[i]->filename); + wrap_here (""); /* Flush output */ + gdb_flush (gdb_stdout); + } + psymtab_to_symtab_1 (pst->dependencies[i]); + } + + if (PST_PRIVATE (pst) == NULL) + { + /* It's an include file, no symbols to read for it. + Everything is in the parent symtab. */ + pst->readin = 1; + return; + } dwarf2_per_objfile = objfile_data (pst->objfile, dwarf2_objfile_data_key); @@ -2294,7 +2404,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) { make_cleanup ((make_cleanup_ftype *) free_line_header, (void *) line_header); - dwarf_decode_lines (line_header, comp_dir, abfd, cu); + dwarf_decode_lines (line_header, comp_dir, abfd, cu, NULL); } } @@ -4826,6 +4936,10 @@ read_partial_die (struct partial_die_info *part_die, part_die->sibling = dwarf2_per_objfile->info_buffer + dwarf2_get_ref_die_offset (&attr, cu); break; + case DW_AT_stmt_list: + part_die->has_stmt_list = 1; + part_die->line_offset = DW_UNSND (&attr); + break; default: break; } @@ -5628,6 +5742,7 @@ add_file_name (struct line_header *lh, fe->dir_index = dir_index; fe->mod_time = mod_time; fe->length = length; + fe->included_p = 0; } @@ -5785,13 +5900,27 @@ check_cu_functions (CORE_ADDR address, struct dwarf2_cu *cu) return fn->lowpc; } -/* Decode the line number information for the compilation unit whose - line number info is at OFFSET in the .debug_line section. - The compilation directory of the file is passed in COMP_DIR. */ +/* Decode the Line Number Program (LNP) for the given line_header + structure and CU. The actual information extracted and the type + of structures created from the LNP depends on the value of PST. + + 1. If PST is NULL, then this procedure uses the data from the program + to create all necessary symbol tables, and their linetables. + The compilation directory of the file is passed in COMP_DIR, + and must not be NULL. + + 2. If PST is not NULL, this procedure reads the program to determine + the list of files included by the unit represented by PST, and + builds all the associated partial symbol tables. In this case, + the value of COMP_DIR is ignored, and can thus be NULL (the COMP_DIR + is not used to compute the full name of the symtab, and therefore + omitting it when building the partial symtab does not introduce + the potential for inconsistency - a partial symtab and its associated + symbtab having a different fullname -). */ static void dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, - struct dwarf2_cu *cu) + struct dwarf2_cu *cu, struct partial_symtab *pst) { char *line_ptr; char *line_end; @@ -5799,6 +5928,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, unsigned char op_code, extended_op, adj_opcode; CORE_ADDR baseaddr; struct objfile *objfile = cu->objfile; + const int decode_for_pst_p = (pst != NULL); baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); @@ -5817,9 +5947,9 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, int basic_block = 0; int end_sequence = 0; - /* Start a subfile for the current file of the state machine. */ - if (lh->num_file_names >= file) + if (!decode_for_pst_p && lh->num_file_names >= file) { + /* Start a subfile for the current file of the state machine. */ /* lh->include_dirs and lh->file_names are 0-based, but the directory and file name numbers in the statement program are 1-based. */ @@ -5844,9 +5974,12 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, address += (adj_opcode / lh->line_range) * lh->minimum_instruction_length; line += lh->line_base + (adj_opcode % lh->line_range); - /* append row to matrix using current values */ - record_line (current_subfile, line, - check_cu_functions (address, cu)); + if (!decode_for_pst_p) + { + /* append row to matrix using current values */ + record_line (current_subfile, line, + check_cu_functions (address, cu)); + } basic_block = 1; } else switch (op_code) @@ -5859,7 +5992,8 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, { case DW_LNE_end_sequence: end_sequence = 1; - record_line (current_subfile, 0, address); + if (!decode_for_pst_p) + record_line (current_subfile, 0, address); break; case DW_LNE_set_address: address = read_address (abfd, line_ptr, cu, &bytes_read); @@ -5892,8 +6026,9 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, } break; case DW_LNS_copy: - record_line (current_subfile, line, - check_cu_functions (address, cu)); + if (!decode_for_pst_p) + record_line (current_subfile, line, + check_cu_functions (address, cu)); basic_block = 0; break; case DW_LNS_advance_pc: @@ -5915,11 +6050,13 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; fe = &lh->file_names[file - 1]; + fe->included_p = 1; if (fe->dir_index) dir = lh->include_dirs[fe->dir_index - 1]; else dir = comp_dir; - dwarf2_start_subfile (fe->name, dir); + if (!decode_for_pst_p) + dwarf2_start_subfile (fe->name, dir); } break; case DW_LNS_set_column: @@ -5957,6 +6094,22 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, } } } + + if (decode_for_pst_p) + { + int file_index; + + /* Now that we're done scanning the Line Header Program, we can + create the psymtab of each included file. */ + for (file_index = 0; file_index < lh->num_file_names; file_index++) + if (lh->file_names[file_index].included_p == 1) + { + char *include_name = lh->file_names [file_index].name; + + if (strcmp (include_name, pst->filename) != 0) + dwarf2_create_include_psymtab (include_name, pst, objfile); + } + } } /* Start a subfile for DWARF. FILENAME is the name of the file and |