Index: dwarf2read.c =================================================================== RCS file: /nile.c/cvs/Dev/gdb/gdb-6.0/gdb/dwarf2read.c,v retrieving revision 1.5 diff -u -p -r1.5 dwarf2read.c --- dwarf2read.c 19 Nov 2003 18:02:23 -0000 1.5 +++ dwarf2read.c 2 Jan 2004 07:10:08 -0000 @@ -693,7 +693,8 @@ static struct abbrev_info *dwarf2_lookup static char *read_partial_die (struct partial_die_info *, bfd *, char *, - const struct comp_unit_head *); + const struct comp_unit_head *, + unsigned int *); static char *read_full_die (struct die_info **, bfd *, char *, const struct comp_unit_head *); @@ -1196,6 +1197,195 @@ read_comp_unit_head (struct comp_unit_he return info_ptr; } +static void +dwarf2_add_include_psymtab (char *name, + struct partial_symtab *pst, + struct objfile *objfile) +{ + struct partial_symtab *subpst = allocate_psymtab (name, objfile); + + /* Copy the private data from the main psymtab. */ + subpst->section_offsets = pst->section_offsets; + PST_PRIVATE (subpst) = + (char *) obstack_alloc (&objfile->psymbol_obstack, + sizeof (struct dwarf2_pinfo)); + *PST_PRIVATE (subpst) = *PST_PRIVATE (pst); + + subpst->textlow = 0; + subpst->texthigh = 0; + + /* We could save slight bits of space by only making one of these, + shared by the entire set of include files. FIXME-someday. */ + subpst->dependencies = (struct partial_symtab **) + obstack_alloc (&objfile->psymbol_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->readin = 0; + subpst->symtab = 0; + subpst->read_symtab = pst->read_symtab; +} + +static void +dwarf2_build_include_psymtabs (struct comp_unit_head *cu_header, + const unsigned int line_offset, + struct partial_symtab *pst, + struct objfile *objfile) +{ + bfd *abfd = objfile->obfd; + struct line_header *lh; + int file_index; + char *line_ptr; + char *line_end; + unsigned int bytes_read; + unsigned char op_code, extended_op, adj_opcode; // All used??? FIXME:JOEL + char *file_included; + + lh = dwarf_decode_line_header (line_offset, abfd, cu_header); + + if (lh == NULL) + return; /* No includes... */ + + line_ptr = lh->statement_program_start; + line_end = lh->statement_program_end; + + /* FIXME: brobecker: Add comments. */ + file_included = alloca (lh->num_file_names * sizeof (char)); + memset (file_included, 0, lh->num_file_names * sizeof (char)); + + /* Read the statement sequences until there's nothing left. */ + while (line_ptr < line_end) + { + /* state machine registers */ + int end_sequence = 0; + + /* Decode the table. */ + while (!end_sequence) + { + op_code = read_1_byte (abfd, line_ptr); + line_ptr += 1; + + if (op_code >= lh->opcode_base) + { /* Special operand. Nothing else to read. */ + } + else switch (op_code) + { + case DW_LNS_extended_op: + line_ptr += 1; /* ignore length */ + extended_op = read_1_byte (abfd, line_ptr); + line_ptr += 1; + switch (extended_op) + { + case DW_LNE_end_sequence: + end_sequence = 1; + break; + case DW_LNE_set_address: + read_address (abfd, line_ptr, cu_header, &bytes_read); + line_ptr += bytes_read; + break; + case DW_LNE_define_file: + { + // char *cur_file; + // unsigned int dir_index, mod_time, length; + + // cur_file = read_string (abfd, line_ptr, &bytes_read); + // line_ptr += bytes_read; + // dir_index = + // read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + // line_ptr += bytes_read; + // mod_time = + // read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + // line_ptr += bytes_read; + // length = + // read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + // line_ptr += bytes_read; + // add_file_name (lh, cur_file, dir_index, mod_time, length); + /* Ignore for now, but the compiler is allowed to + create the list of files via DW_LNE_define_file + entries too. We will likely need to take this + into account someday. */ + read_string (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + } + break; + default: + complaint (&symfile_complaints, + "mangled .debug_line section"); + return; + } + break; + case DW_LNS_copy: + break; + case DW_LNS_advance_pc: + read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + break; + case DW_LNS_advance_line: + read_signed_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + break; + case DW_LNS_set_file: + { + /* lh->include_dirs and lh->file_names are 0-based, + but the directory and file name numbers in the + statement program are 1-based. */ + unsigned int file; + + file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + file_included[file - 1] = 1; + } + break; + case DW_LNS_set_column: + read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + break; + case DW_LNS_negate_stmt: + break; + case DW_LNS_set_basic_block: + break; + case DW_LNS_const_add_pc: + break; + case DW_LNS_fixed_advance_pc: + line_ptr += 2; + break; + default: + { /* Unknown standard opcode, ignore it. */ + int i; + for (i = 0; i < lh->standard_opcode_lengths[op_code]; i++) + { + (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + } + } + } + } + } + + for (file_index = 0; file_index < lh->num_file_names; file_index++) + if (file_included[file_index] == 1) + { + char *include_name = lh->file_names [file_index].name; + + if (strcmp (include_name, pst->filename) != 0) + dwarf2_add_include_psymtab (include_name, pst, objfile); + } + + free_line_header (lh); +} + /* Build the partial symbol table by doing a quick pass through the .debug_info and .debug_abbrev sections. */ @@ -1262,6 +1452,8 @@ dwarf2_build_psymtabs_hard (struct objfi while (info_ptr < dwarf_info_buffer + dwarf_info_size) { struct comp_unit_head cu_header; + unsigned int line_offset = 0; + beg_of_comp_unit = info_ptr; info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd); @@ -1307,7 +1499,7 @@ dwarf2_build_psymtabs_hard (struct objfi /* Read the compilation unit die */ info_ptr = read_partial_die (&comp_unit_die, abfd, info_ptr, - &cu_header); + &cu_header, &line_offset); /* Set the language we're debugging */ set_cu_language (comp_unit_die.language); @@ -1373,6 +1565,10 @@ dwarf2_build_psymtabs_hard (struct objfi info_ptr = beg_of_comp_unit + cu_header.length + cu_header.initial_length_size; + + /* Get the list of files included in the current compilation unit, + and build a psymtab for each of them. */ + dwarf2_build_include_psymtabs (&cu_header, line_offset, pst, objfile); } do_cleanups (back_to); } @@ -1421,7 +1617,7 @@ scan_partial_symbols (char *info_ptr, st while (nesting_level) { - info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header); + info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header, NULL); /* Anonymous namespaces have no name but are interesting. */ @@ -1677,6 +1873,32 @@ psymtab_to_symtab_1 (struct partial_symt struct symtab *symtab; struct cleanup *back_to; struct attribute *attr; + 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->textlow == 0 && pst->texthigh == 0) + { + /* It's an include file, no symbols to read for it. + Everything is in the parent symtab. */ + pst->readin = 1; + return; + } /* Set local variables from the partial symbol table info. */ offset = DWARF_INFO_OFFSET (pst); @@ -4001,7 +4223,8 @@ dwarf2_lookup_abbrev (unsigned int numbe static char * read_partial_die (struct partial_die_info *part_die, bfd *abfd, - char *info_ptr, const struct comp_unit_head *cu_header) + char *info_ptr, const struct comp_unit_head *cu_header, + unsigned int *line_offset) { unsigned int abbrev_number, bytes_read, i; struct abbrev_info *abbrev; @@ -4096,6 +4319,9 @@ read_partial_die (struct partial_die_inf part_die->sibling = dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr); break; + case DW_AT_stmt_list: + if (line_offset != NULL) + *line_offset = DW_UNSND (&attr); default: break; } @@ -4111,7 +4337,7 @@ read_partial_die (struct partial_die_inf int dummy; spec_ptr = dwarf_info_buffer + dwarf2_get_ref_die_offset (&spec_attr); - read_partial_die (&spec_die, abfd, spec_ptr, cu_header); + read_partial_die (&spec_die, abfd, spec_ptr, cu_header, NULL); if (spec_die.name) { part_die->name = spec_die.name;