From be391dcafc991c4761cb8447f629263decfd55b4 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 10 Mar 2010 18:37:24 +0000 Subject: [PATCH] * elfread.c (elf_symfile_read): Don't call dwarf2_build_frame_info. * dwarf2read.c (struct dwarf2_section_info) : New field. (struct dwarf2_per_objfile) : New field. (dwarf2_has_info): Now idempotent. Set objfile field. (dwarf2_read_section): Check and set readin field. Call posix_madvise. (dwarf2_build_psymtabs): Don't read all sections. (read_type_comp_unit_head): Read types section. (create_debug_types_hash_table): Likewise. (init_cu_die_reader): Add asserts. (process_type_comp_unit): Add assert. (dwarf2_build_psymtabs_hard): Read info section. (load_partial_comp_unit): Add assert. (create_all_comp_units): Read info section. (load_full_comp_unit): Likewise. (dwarf2_ranges_read): Read ranges section. (dwarf2_record_block_ranges): Add assert. (dwarf2_read_abbrevs): Read abbrev section. (read_indirect_string): Read str section. (dwarf_decode_line_header): Read line section. (read_signatured_type_at_offset): Read types section. (dwarf_decode_macros): Read macinfo section. (dwarf2_symbol_mark_computed): Read loc section. * dwarf2-frame.c (dwarf2_frame_find_fde): Call dwarf2_build_frame_info. (dwarf2_build_frame_info): Unconditionally set dwarf2_frame_objfile_data on the objfile. * configure.ac: Check for posix_madvise. * config.in, configure: Rebuild. --- gdb/ChangeLog | 35 ++++++++++++++++++- gdb/config.in | 3 ++ gdb/configure | 2 +- gdb/configure.ac | 2 +- gdb/dwarf2-frame.c | 29 +++++++++++----- gdb/dwarf2read.c | 85 ++++++++++++++++++++++++++++++++-------------- gdb/elfread.c | 4 --- 7 files changed, 119 insertions(+), 41 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f898c82958..ddca300eb0 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,36 @@ +2010-03-10 Tom Tromey + + * elfread.c (elf_symfile_read): Don't call + dwarf2_build_frame_info. + * dwarf2read.c (struct dwarf2_section_info) : New field. + (struct dwarf2_per_objfile) : New field. + (dwarf2_has_info): Now idempotent. Set objfile field. + (dwarf2_read_section): Check and set readin field. Call + posix_madvise. + (dwarf2_build_psymtabs): Don't read all sections. + (read_type_comp_unit_head): Read types section. + (create_debug_types_hash_table): Likewise. + (init_cu_die_reader): Add asserts. + (process_type_comp_unit): Add assert. + (dwarf2_build_psymtabs_hard): Read info section. + (load_partial_comp_unit): Add assert. + (create_all_comp_units): Read info section. + (load_full_comp_unit): Likewise. + (dwarf2_ranges_read): Read ranges section. + (dwarf2_record_block_ranges): Add assert. + (dwarf2_read_abbrevs): Read abbrev section. + (read_indirect_string): Read str section. + (dwarf_decode_line_header): Read line section. + (read_signatured_type_at_offset): Read types section. + (dwarf_decode_macros): Read macinfo section. + (dwarf2_symbol_mark_computed): Read loc section. + * dwarf2-frame.c (dwarf2_frame_find_fde): Call + dwarf2_build_frame_info. + (dwarf2_build_frame_info): Unconditionally set + dwarf2_frame_objfile_data on the objfile. + * configure.ac: Check for posix_madvise. + * config.in, configure: Rebuild. + 2010-03-10 Tom Tromey * xcoffread.c (xcoff_start_psymtab): Update. @@ -12,7 +45,7 @@ * dbxread.c (start_psymtab): Update. (end_psymtab): Likewise. -2010-30-10 Tom Tromey +2010-03-10 Tom Tromey * xcoffread.c: Include psymtab.h. (xcoff_sym_fns): Update. diff --git a/gdb/config.in b/gdb/config.in index ebde876dad..5414b089b7 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -294,6 +294,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_POLL_H +/* Define to 1 if you have the `posix_madvise' function. */ +#undef HAVE_POSIX_MADVISE + /* Define to 1 if you have the `pread64' function. */ #undef HAVE_PREAD64 diff --git a/gdb/configure b/gdb/configure index d444b08f54..6b0599331a 100755 --- a/gdb/configure +++ b/gdb/configure @@ -11234,7 +11234,7 @@ for ac_func in canonicalize_file_name realpath getrusage getuid \ getgid pipe poll pread64 sbrk setpgid setpgrp setsid \ sigaction sigprocmask sigsetmask socketpair syscall \ ttrace wborder setlocale iconvlist libiconvlist btowc \ - setrlimit getrlimit + setrlimit getrlimit posix_madvise do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/gdb/configure.ac b/gdb/configure.ac index 8da6867a6a..5e77f59c37 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -802,7 +802,7 @@ AC_CHECK_FUNCS([canonicalize_file_name realpath getrusage getuid \ getgid pipe poll pread64 sbrk setpgid setpgrp setsid \ sigaction sigprocmask sigsetmask socketpair syscall \ ttrace wborder setlocale iconvlist libiconvlist btowc \ - setrlimit getrlimit]) + setrlimit getrlimit posix_madvise]) AM_LANGINFO_CODESET # Check the return and argument types of ptrace. No canned test for diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index 99100d7f9a..7323ca4afe 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -1584,6 +1584,13 @@ dwarf2_frame_find_fde (CORE_ADDR *pc) fde_table = objfile_data (objfile, dwarf2_frame_objfile_data); if (fde_table == NULL) + { + dwarf2_build_frame_info (objfile); + fde_table = objfile_data (objfile, dwarf2_frame_objfile_data); + } + gdb_assert (fde_table != NULL); + + if (fde_table->num_entries == 0) continue; gdb_assert (objfile->section_offsets); @@ -2027,6 +2034,7 @@ dwarf2_build_frame_info (struct objfile *objfile) gdb_byte *frame_ptr; struct dwarf2_cie_table cie_table; struct dwarf2_fde_table fde_table; + struct dwarf2_fde_table *fde_table2; cie_table.num_entries = 0; cie_table.entries = NULL; @@ -2098,9 +2106,17 @@ dwarf2_build_frame_info (struct objfile *objfile) cie_table.num_entries = 0; /* Paranoia. */ } - if (fde_table.num_entries != 0) + /* Copy fde_table to obstack: it is needed at runtime. */ + fde_table2 = (struct dwarf2_fde_table *) + obstack_alloc (&objfile->objfile_obstack, sizeof (*fde_table2)); + + if (fde_table.num_entries == 0) + { + fde_table2->entries = NULL; + fde_table2->num_entries = 0; + } + else { - struct dwarf2_fde_table *fde_table2; struct dwarf2_fde *fde_prev = NULL; struct dwarf2_fde *first_non_zero_fde = NULL; int i; @@ -2109,11 +2125,6 @@ dwarf2_build_frame_info (struct objfile *objfile) qsort (fde_table.entries, fde_table.num_entries, sizeof (fde_table.entries[0]), qsort_fde_cmp); - /* Copy fde_table to obstack: it is needed at runtime. */ - fde_table2 = (struct dwarf2_fde_table *) - obstack_alloc (&objfile->objfile_obstack, sizeof (*fde_table2)); - fde_table2->num_entries = 0; - /* Check for leftovers from --gc-sections. The GNU linker sets the relevant symbols to zero, but doesn't zero the FDE *end* ranges because there's no relocation there. It's (offset, @@ -2140,6 +2151,7 @@ dwarf2_build_frame_info (struct objfile *objfile) /* Since we'll be doing bsearch, squeeze out identical (except for eh_frame_p) fde entries so bsearch result is predictable. Also discard leftovers from --gc-sections. */ + fde_table2->num_entries = 0; for (i = 0; i < fde_table.num_entries; i++) { struct dwarf2_fde *fde = fde_table.entries[i]; @@ -2160,11 +2172,12 @@ dwarf2_build_frame_info (struct objfile *objfile) fde_prev = fde; } fde_table2->entries = obstack_finish (&objfile->objfile_obstack); - set_objfile_data (objfile, dwarf2_frame_objfile_data, fde_table2); /* Discard the original fde_table. */ xfree (fde_table.entries); } + + set_objfile_data (objfile, dwarf2_frame_objfile_data, fde_table2); } /* Provide a prototype to silence -Wmissing-prototypes. */ diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 11f1a91da1..670eff6cc1 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -157,6 +157,8 @@ struct dwarf2_section_info gdb_byte *buffer; bfd_size_type size; int was_mmapped; + /* True if we have tried to read this section. */ + int readin; }; struct dwarf2_per_objfile @@ -174,6 +176,9 @@ struct dwarf2_per_objfile struct dwarf2_section_info frame; struct dwarf2_section_info eh_frame; + /* Back link. */ + struct objfile *objfile; + /* A list of all the compilation units. This is used to locate the target compilation unit of a particular reference. */ struct dwarf2_per_cu_data **all_comp_units; @@ -1164,16 +1169,21 @@ static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu); int dwarf2_has_info (struct objfile *objfile) { - struct dwarf2_per_objfile *data; - - /* Initialize per-objfile state. */ - data = obstack_alloc (&objfile->objfile_obstack, sizeof (*data)); - memset (data, 0, sizeof (*data)); - set_objfile_data (objfile, dwarf2_objfile_data_key, data); - dwarf2_per_objfile = data; + dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key); + if (!dwarf2_per_objfile) + { + /* Initialize per-objfile state. */ + struct dwarf2_per_objfile *data + = obstack_alloc (&objfile->objfile_obstack, sizeof (*data)); + memset (data, 0, sizeof (*data)); + set_objfile_data (objfile, dwarf2_objfile_data_key, data); + dwarf2_per_objfile = data; - bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, NULL); - return (data->info.asection != NULL && data->abbrev.asection != NULL); + bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, NULL); + dwarf2_per_objfile->objfile = objfile; + } + return (dwarf2_per_objfile->info.asection != NULL + && dwarf2_per_objfile->abbrev.asection != NULL); } /* When loading sections, we can either look for ".", or for @@ -1355,8 +1365,11 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info) gdb_byte *buf, *retbuf; unsigned char header[4]; + if (info->readin) + return; info->buffer = NULL; info->was_mmapped = 0; + info->readin = 1; if (info->asection == NULL || info->size == 0) return; @@ -1394,6 +1407,9 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info) { info->was_mmapped = 1; info->buffer = retbuf + (sectp->filepos & (pagesize - 1)) ; +#if HAVE_POSIX_MADVISE + posix_madvise (retbuf, map_length, POSIX_MADV_WILLNEED); +#endif return; } } @@ -1452,17 +1468,6 @@ dwarf2_get_section_info (struct objfile *objfile, const char *section_name, void dwarf2_build_psymtabs (struct objfile *objfile) { - dwarf2_read_section (objfile, &dwarf2_per_objfile->info); - dwarf2_read_section (objfile, &dwarf2_per_objfile->abbrev); - dwarf2_read_section (objfile, &dwarf2_per_objfile->line); - dwarf2_read_section (objfile, &dwarf2_per_objfile->str); - dwarf2_read_section (objfile, &dwarf2_per_objfile->macinfo); - dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges); - dwarf2_read_section (objfile, &dwarf2_per_objfile->types); - dwarf2_read_section (objfile, &dwarf2_per_objfile->loc); - dwarf2_read_section (objfile, &dwarf2_per_objfile->eh_frame); - dwarf2_read_section (objfile, &dwarf2_per_objfile->frame); - if (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0) { init_psymbol_list (objfile, 1024); @@ -1606,6 +1611,7 @@ read_type_comp_unit_head (struct comp_unit_head *cu_header, unsigned int bytes_read; gdb_byte *initial_types_ptr = types_ptr; + dwarf2_read_section (dwarf2_per_objfile->objfile, &dwarf2_per_objfile->types); cu_header->offset = types_ptr - dwarf2_per_objfile->types.buffer; types_ptr = read_comp_unit_head (cu_header, types_ptr, abfd); @@ -1702,9 +1708,12 @@ eq_type_signature (const void *item_lhs, const void *item_rhs) static int create_debug_types_hash_table (struct objfile *objfile) { - gdb_byte *info_ptr = dwarf2_per_objfile->types.buffer; + gdb_byte *info_ptr; htab_t types_htab; + dwarf2_read_section (objfile, &dwarf2_per_objfile->types); + info_ptr = dwarf2_per_objfile->types.buffer; + if (info_ptr == NULL) { dwarf2_per_objfile->signatured_types = NULL; @@ -1810,9 +1819,15 @@ init_cu_die_reader (struct die_reader_specs *reader, reader->abfd = cu->objfile->obfd; reader->cu = cu; if (cu->per_cu->from_debug_types) - reader->buffer = dwarf2_per_objfile->types.buffer; + { + gdb_assert (dwarf2_per_objfile->types.readin); + reader->buffer = dwarf2_per_objfile->types.buffer; + } else - reader->buffer = dwarf2_per_objfile->info.buffer; + { + gdb_assert (dwarf2_per_objfile->info.readin); + reader->buffer = dwarf2_per_objfile->info.buffer; + } } /* Find the base address of the compilation unit for range lists and @@ -2044,6 +2059,7 @@ process_type_comp_unit (void **slot, void *info) this_cu = &entry->per_cu; this_cu->from_debug_types = 1; + gdb_assert (dwarf2_per_objfile->types.readin); process_psymtab_comp_unit (objfile, this_cu, dwarf2_per_objfile->types.buffer, dwarf2_per_objfile->types.buffer + entry->offset, @@ -2071,12 +2087,11 @@ build_type_psymtabs (struct objfile *objfile) static void dwarf2_build_psymtabs_hard (struct objfile *objfile) { - /* Instead of reading this into a big buffer, we should probably use - mmap() on architectures that support it. (FIXME) */ bfd *abfd = objfile->obfd; gdb_byte *info_ptr; struct cleanup *back_to; + dwarf2_read_section (objfile, &dwarf2_per_objfile->info); info_ptr = dwarf2_per_objfile->info.buffer; /* Any cached compilation units will be linked by the per-objfile @@ -2142,6 +2157,7 @@ load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu, gdb_assert (! this_cu->from_debug_types); + gdb_assert (dwarf2_per_objfile->info.readin); info_ptr = dwarf2_per_objfile->info.buffer + this_cu->offset; beg_of_comp_unit = info_ptr; @@ -2199,7 +2215,10 @@ create_all_comp_units (struct objfile *objfile) int n_allocated; int n_comp_units; struct dwarf2_per_cu_data **all_comp_units; - gdb_byte *info_ptr = dwarf2_per_objfile->info.buffer; + gdb_byte *info_ptr; + + dwarf2_read_section (objfile, &dwarf2_per_objfile->info); + info_ptr = dwarf2_per_objfile->info.buffer; n_comp_units = 0; n_allocated = 10; @@ -3101,6 +3120,7 @@ load_full_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile) /* Set local variables from the partial symbol table info. */ offset = per_cu->offset; + dwarf2_read_section (objfile, &dwarf2_per_objfile->info); info_ptr = dwarf2_per_objfile->info.buffer + offset; beg_of_comp_unit = info_ptr; @@ -4078,6 +4098,7 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return, found_base = cu->base_known; base = cu->base_address; + dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges); if (offset >= dwarf2_per_objfile->ranges.size) { complaint (&symfile_complaints, @@ -4380,6 +4401,7 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block, CORE_ADDR base = cu->base_address; int base_known = cu->base_known; + gdb_assert (dwarf2_per_objfile->ranges.readin); if (offset >= dwarf2_per_objfile->ranges.size) { complaint (&symfile_complaints, @@ -6379,6 +6401,8 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu) memset (cu->dwarf2_abbrevs, 0, ABBREV_HASH_SIZE * sizeof (struct abbrev_info *)); + dwarf2_read_section (dwarf2_per_objfile->objfile, + &dwarf2_per_objfile->abbrev); abbrev_ptr = dwarf2_per_objfile->abbrev.buffer + cu_header->abbrev_offset; abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); abbrev_ptr += bytes_read; @@ -7451,6 +7475,7 @@ read_indirect_string (bfd *abfd, gdb_byte *buf, { LONGEST str_offset = read_offset (abfd, buf, cu_header, bytes_read_ptr); + dwarf2_read_section (dwarf2_per_objfile->objfile, &dwarf2_per_objfile->str); if (dwarf2_per_objfile->str.buffer == NULL) { error (_("DW_FORM_strp used without .debug_str section [in module %s]"), @@ -7777,6 +7802,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd, int i; char *cur_dir, *cur_file; + dwarf2_read_section (dwarf2_per_objfile->objfile, &dwarf2_per_objfile->line); if (dwarf2_per_objfile->line.buffer == NULL) { complaint (&symfile_complaints, _("missing .debug_line section")); @@ -10545,6 +10571,8 @@ read_signatured_type_at_offset (struct objfile *objfile, { struct signatured_type *type_sig; + dwarf2_read_section (objfile, &dwarf2_per_objfile->types); + /* We have the section offset, but we need the signature to do the hash table lookup. */ type_sig = lookup_signatured_type_at_offset (objfile, offset); @@ -11151,6 +11179,8 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, enum dwarf_macinfo_record_type macinfo_type; int at_commandline; + dwarf2_read_section (dwarf2_per_objfile->objfile, + &dwarf2_per_objfile->macinfo); if (dwarf2_per_objfile->macinfo.buffer == NULL) { complaint (&symfile_complaints, _("missing .debug_macinfo section")); @@ -11476,6 +11506,9 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, baton->per_cu = cu->per_cu; gdb_assert (baton->per_cu); + dwarf2_read_section (dwarf2_per_objfile->objfile, + &dwarf2_per_objfile->loc); + /* We don't know how long the location list is, but make sure we don't run off the edge of the section. */ baton->size = dwarf2_per_objfile->loc.size - DW_UNSND (attr); diff --git a/gdb/elfread.c b/gdb/elfread.c index e32a1a9b18..97c0163151 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -886,10 +886,6 @@ elf_symfile_read (struct objfile *objfile, int symfile_flags) dwarf2_build_psymtabs (objfile); } - /* FIXME: kettenis/20030504: This still needs to be integrated with - dwarf2read.c in a better way. */ - dwarf2_build_frame_info (objfile); - /* If the file has its own symbol tables it has no separate debug info. `.dynsym'/`.symtab' go to MSYMBOLS, `.debug_info' goes to SYMTABS/PSYMTABS. `.gnu_debuglink' may no longer be present with `.note.gnu.build-id'. */ -- 2.34.1