diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 4c225a9cff..696fbcdf69 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,30 @@ +2003-01-31 Daniel Jacobowitz + + * dbxread.c (stabs_data): New static variable. + (fill_symbuf): Support an in-memory buffer for stabs data. + (stabs_seek): New function. + (dbx_psymtab_to_symtab): Relocate the stabs data if necessary. + (read_ofile_symtab): Use stabs_seek. + (elfstab_build_psymtabs): Take an asection* instead of + an offset and size. Relocate the stabs data if necessary. + Save the section* for dbx_psymtab_to_symtab. + * dwarf2read.c: Add section variables for each debug section. + (dwarf2_locate_sections): Fill them in. + (dwarf2_read_section): Take an asection* argument. + Relocate the section contents if necessary. + (dwarf2_build_psymtabs, dwarf2_build_psymtabs_easy): Update callers. + * dwarf2cfi.c (parse_frame_info): Take a section argument and pass + it to dwarf2_read_section. + (dwarf2_build_frame_info): Update callers. + * elfread.c (elf_symfile_read): Update call to + elfstab_build_psymtabs. + * gdb-stabs.h (struct dbx_symfile_info): Add stab_section. + (DBX_STAB_SECTION): New macro. + * stabsread.h (elfstab_build_psymtabs): Update prototype. + * symfile.c (symfile_dummy_outputs): New function. + (symfile_relocate_debug_section): New function. + * symfile.h (symfile_relocate_debug_section): Add prototype. + 2003-01-31 Richard Henderson * alpha-nat.c (REGISTER_PTRACE_ADDR): Merge into ... diff --git a/gdb/dbxread.c b/gdb/dbxread.c index c533eb4c29..2a1d4e20c6 100644 --- a/gdb/dbxread.c +++ b/gdb/dbxread.c @@ -893,6 +893,10 @@ static struct stab_section_list *symbuf_sections; static unsigned int symbuf_left; static unsigned int symbuf_read; +/* This variable stores a global stabs buffer, if we read stabs into + memory in one chunk in order to process relocations. */ +static bfd_byte *stabs_data; + /* Refill the symbol table input buffer and set the variables that control fetching entries from it. Reports an error if no data available. @@ -905,8 +909,18 @@ fill_symbuf (bfd *sym_bfd) unsigned int count; int nbytes; - if (symbuf_sections == NULL) - count = sizeof (symbuf); + if (stabs_data) + { + nbytes = sizeof (symbuf); + if (nbytes > symbuf_left) + nbytes = symbuf_left; + memcpy (symbuf, stabs_data + symbuf_read, nbytes); + } + else if (symbuf_sections == NULL) + { + count = sizeof (symbuf); + nbytes = bfd_bread (symbuf, count, sym_bfd); + } else { if (symbuf_left <= 0) @@ -922,9 +936,9 @@ fill_symbuf (bfd *sym_bfd) count = symbuf_left; if (count > sizeof (symbuf)) count = sizeof (symbuf); + nbytes = bfd_bread (symbuf, count, sym_bfd); } - nbytes = bfd_bread (symbuf, count, sym_bfd); if (nbytes < 0) perror_with_name (bfd_get_filename (sym_bfd)); else if (nbytes == 0) @@ -935,6 +949,18 @@ fill_symbuf (bfd *sym_bfd) symbuf_read += nbytes; } +static void +stabs_seek (int sym_offset) +{ + if (stabs_data) + { + symbuf_read += sym_offset; + symbuf_left -= sym_offset; + } + else + bfd_seek (symfile_bfd, sym_offset, SEEK_CUR); +} + #define INTERNALIZE_SYMBOL(intern, extern, abfd) \ { \ (intern).n_type = bfd_h_get_8 (abfd, (extern)->e_type); \ @@ -2473,6 +2499,7 @@ static void dbx_psymtab_to_symtab (struct partial_symtab *pst) { bfd *sym_bfd; + struct cleanup *back_to = NULL; if (!pst) return; @@ -2498,8 +2525,21 @@ dbx_psymtab_to_symtab (struct partial_symtab *pst) next_symbol_text_func = dbx_next_symbol_text; + if (DBX_STAB_SECTION (pst->objfile)) + { + stabs_data + = symfile_relocate_debug_section (pst->objfile->obfd, + DBX_STAB_SECTION (pst->objfile), + NULL); + if (stabs_data) + back_to = make_cleanup (free_current_contents, (void *) &stabs_data); + } + dbx_psymtab_to_symtab_1 (pst); + if (back_to) + do_cleanups (back_to); + /* Match with global symbols. This only needs to be done once, after all of the symtabs and dependencies have been read in. */ scan_file_globals (pst->objfile); @@ -2548,6 +2588,8 @@ read_ofile_symtab (struct partial_symtab *pst) abfd = objfile->obfd; symfile_bfd = objfile->obfd; /* Implicit param to next_text_symbol */ symbuf_end = symbuf_idx = 0; + symbuf_read = 0; + symbuf_left = sym_offset + sym_size; /* It is necessary to actually read one symbol *before* the start of this symtab's symbols, because the GCC_COMPILED_FLAG_SYMBOL @@ -2557,7 +2599,7 @@ read_ofile_symtab (struct partial_symtab *pst) would slow down initial readin, so we look for it here instead. */ if (!processing_acc_compilation && sym_offset >= (int) symbol_size) { - bfd_seek (symfile_bfd, sym_offset - symbol_size, SEEK_CUR); + stabs_seek (sym_offset - symbol_size); fill_symbuf (abfd); bufp = &symbuf[symbuf_idx++]; INTERNALIZE_SYMBOL (nlist, bufp, abfd); @@ -2600,7 +2642,7 @@ read_ofile_symtab (struct partial_symtab *pst) /* The N_SO starting this symtab is the first symbol, so we better not check the symbol before it. I'm not this can happen, but it doesn't hurt to check for it. */ - bfd_seek (symfile_bfd, sym_offset, SEEK_CUR); + stabs_seek (sym_offset); processing_gcc_compilation = 0; } @@ -3460,8 +3502,7 @@ coffstab_build_psymtabs (struct objfile *objfile, int mainline, the base address of the text segment). MAINLINE is true if we are reading the main symbol table (as opposed to a shared lib or dynamically loaded file). - STABOFFSET and STABSIZE define the location in OBJFILE where the .stab - section exists. + STABSECT is the BFD section information for the .stab section. STABSTROFFSET and STABSTRSIZE define the location in OBJFILE where the .stabstr section exists. @@ -3470,13 +3511,14 @@ coffstab_build_psymtabs (struct objfile *objfile, int mainline, void elfstab_build_psymtabs (struct objfile *objfile, int mainline, - file_ptr staboffset, unsigned int stabsize, + asection *stabsect, file_ptr stabstroffset, unsigned int stabstrsize) { int val; bfd *sym_bfd = objfile->obfd; char *name = bfd_get_filename (sym_bfd); struct dbx_symfile_info *info; + struct cleanup *back_to = NULL; /* There is already a dbx_symfile_info allocated by our caller. It might even contain some info from the ELF symtab to help us. */ @@ -3488,9 +3530,11 @@ elfstab_build_psymtabs (struct objfile *objfile, int mainline, #define ELF_STABS_SYMBOL_SIZE 12 /* XXX FIXME XXX */ DBX_SYMBOL_SIZE (objfile) = ELF_STABS_SYMBOL_SIZE; - DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile); + DBX_SYMCOUNT (objfile) + = bfd_section_size (objfile->obfd, stabsect) / DBX_SYMBOL_SIZE (objfile); DBX_STRINGTAB_SIZE (objfile) = stabstrsize; - DBX_SYMTAB_OFFSET (objfile) = staboffset; + DBX_SYMTAB_OFFSET (objfile) = stabsect->filepos; + DBX_STAB_SECTION (objfile) = stabsect; if (stabstrsize > bfd_get_size (sym_bfd)) error ("ridiculous string table size: %d bytes", stabstrsize); @@ -3515,10 +3559,19 @@ elfstab_build_psymtabs (struct objfile *objfile, int mainline, processing_acc_compilation = 1; + symbuf_read = 0; + symbuf_left = bfd_section_size (objfile->obfd, stabsect); + stabs_data = symfile_relocate_debug_section (objfile->obfd, stabsect, NULL); + if (stabs_data) + back_to = make_cleanup (free_current_contents, (void *) &stabs_data); + /* In an elf file, we've already installed the minimal symbols that came from the elf (non-stab) symbol table, so always act like an incremental load here. */ dbx_symfile_read (objfile, 0); + + if (back_to) + do_cleanups (back_to); } /* Scan and build partial symbols for a file with special sections for stabs diff --git a/gdb/dwarf2cfi.c b/gdb/dwarf2cfi.c index 79ba41872f..c92885574c 100644 --- a/gdb/dwarf2cfi.c +++ b/gdb/dwarf2cfi.c @@ -170,10 +170,13 @@ extern file_ptr dwarf_frame_offset; extern unsigned int dwarf_frame_size; extern file_ptr dwarf_eh_frame_offset; extern unsigned int dwarf_eh_frame_size; +extern asection *dwarf_frame_section; +extern asection *dwarf_eh_frame_section; + extern char *dwarf2_read_section (struct objfile *objfile, file_ptr offset, - unsigned int size); + unsigned int size, asection* sectp); static struct fde_unit *fde_unit_alloc (void); static struct cie_unit *cie_unit_alloc (void); @@ -1368,7 +1371,8 @@ compare_fde_unit (const void *a, const void *b) -- mludvig */ static void parse_frame_info (struct objfile *objfile, file_ptr frame_offset, - unsigned int frame_size, int eh_frame) + unsigned int frame_size, asection *frame_section, + int eh_frame) { bfd *abfd = objfile->obfd; asection *curr_section_ptr; @@ -1383,7 +1387,8 @@ parse_frame_info (struct objfile *objfile, file_ptr frame_offset, unwind_tmp_obstack_init (); - frame_buffer = dwarf2_read_section (objfile, frame_offset, frame_size); + frame_buffer = dwarf2_read_section (objfile, frame_offset, frame_size, + frame_section); start = frame_buffer; end = frame_buffer + frame_size; @@ -1636,12 +1641,14 @@ dwarf2_build_frame_info (struct objfile *objfile) if (dwarf_frame_offset) { parse_frame_info (objfile, dwarf_frame_offset, - dwarf_frame_size, 0 /* = debug_frame */ ); + dwarf_frame_size, dwarf_frame_section, + 0 /* = debug_frame */ ); after_debug_frame = 1; } if (dwarf_eh_frame_offset) parse_frame_info (objfile, dwarf_eh_frame_offset, dwarf_eh_frame_size, + dwarf_eh_frame_section, 1 /* = eh_frame */ + after_debug_frame); } diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index fdc05e1447..a876043589 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1,5 +1,5 @@ /* DWARF 2 debugging format support for GDB. - Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, @@ -149,6 +149,18 @@ static unsigned int dwarf_ranges_size; unsigned int dwarf_frame_size; unsigned int dwarf_eh_frame_size; +static asection *dwarf_info_section; +static asection *dwarf_abbrev_section; +static asection *dwarf_line_section; +static asection *dwarf_pubnames_section; +static asection *dwarf_aranges_section; +static asection *dwarf_loc_section; +static asection *dwarf_macinfo_section; +static asection *dwarf_str_section; +static asection *dwarf_ranges_section; +asection *dwarf_frame_section; +asection *dwarf_eh_frame_section; + /* names of the debugging sections */ #define INFO_SECTION ".debug_info" @@ -658,7 +670,8 @@ static void dwarf2_psymtab_to_symtab (struct partial_symtab *); static void psymtab_to_symtab_1 (struct partial_symtab *); -char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int); +char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int, + asection *); static void dwarf2_read_abbrevs (bfd *abfd, struct comp_unit_head *cu_header); @@ -929,51 +942,61 @@ dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr) { dwarf_info_offset = sectp->filepos; dwarf_info_size = bfd_get_section_size_before_reloc (sectp); + dwarf_info_section = sectp; } else if (STREQ (sectp->name, ABBREV_SECTION)) { dwarf_abbrev_offset = sectp->filepos; dwarf_abbrev_size = bfd_get_section_size_before_reloc (sectp); + dwarf_abbrev_section = sectp; } else if (STREQ (sectp->name, LINE_SECTION)) { dwarf_line_offset = sectp->filepos; dwarf_line_size = bfd_get_section_size_before_reloc (sectp); + dwarf_line_section = sectp; } else if (STREQ (sectp->name, PUBNAMES_SECTION)) { dwarf_pubnames_offset = sectp->filepos; dwarf_pubnames_size = bfd_get_section_size_before_reloc (sectp); + dwarf_pubnames_section = sectp; } else if (STREQ (sectp->name, ARANGES_SECTION)) { dwarf_aranges_offset = sectp->filepos; dwarf_aranges_size = bfd_get_section_size_before_reloc (sectp); + dwarf_aranges_section = sectp; } else if (STREQ (sectp->name, LOC_SECTION)) { dwarf_loc_offset = sectp->filepos; dwarf_loc_size = bfd_get_section_size_before_reloc (sectp); + dwarf_loc_section = sectp; } else if (STREQ (sectp->name, MACINFO_SECTION)) { dwarf_macinfo_offset = sectp->filepos; dwarf_macinfo_size = bfd_get_section_size_before_reloc (sectp); + dwarf_loc_section = sectp; } else if (STREQ (sectp->name, STR_SECTION)) { dwarf_str_offset = sectp->filepos; dwarf_str_size = bfd_get_section_size_before_reloc (sectp); + dwarf_str_section = sectp; } else if (STREQ (sectp->name, FRAME_SECTION)) { dwarf_frame_offset = sectp->filepos; dwarf_frame_size = bfd_get_section_size_before_reloc (sectp); + dwarf_frame_section = sectp; } else if (STREQ (sectp->name, EH_FRAME_SECTION)) { dwarf_eh_frame_offset = sectp->filepos; dwarf_eh_frame_size = bfd_get_section_size_before_reloc (sectp); + dwarf_eh_frame_section = sectp; } else if (STREQ (sectp->name, RANGES_SECTION)) { @@ -992,36 +1015,42 @@ dwarf2_build_psymtabs (struct objfile *objfile, int mainline) dwarf_info_buffer = dwarf2_read_section (objfile, dwarf_info_offset, - dwarf_info_size); + dwarf_info_size, + dwarf_info_section); dwarf_abbrev_buffer = dwarf2_read_section (objfile, dwarf_abbrev_offset, - dwarf_abbrev_size); + dwarf_abbrev_size, + dwarf_abbrev_section); if (dwarf_line_offset) dwarf_line_buffer = dwarf2_read_section (objfile, dwarf_line_offset, - dwarf_line_size); + dwarf_line_size, + dwarf_line_section); else dwarf_line_buffer = NULL; if (dwarf_str_offset) dwarf_str_buffer = dwarf2_read_section (objfile, dwarf_str_offset, - dwarf_str_size); + dwarf_str_size, + dwarf_str_section); else dwarf_str_buffer = NULL; if (dwarf_macinfo_offset) dwarf_macinfo_buffer = dwarf2_read_section (objfile, dwarf_macinfo_offset, - dwarf_macinfo_size); + dwarf_macinfo_size, + dwarf_macinfo_section); else dwarf_macinfo_buffer = NULL; if (dwarf_ranges_offset) dwarf_ranges_buffer = dwarf2_read_section (objfile, dwarf_ranges_offset, - dwarf_ranges_size); + dwarf_ranges_size, + dwarf_ranges_section); else dwarf_ranges_buffer = NULL; @@ -1063,7 +1092,8 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline) pubnames_buffer = dwarf2_read_section (objfile, dwarf_pubnames_offset, - dwarf_pubnames_size); + dwarf_pubnames_size, + dwarf_pubnames_section); pubnames_ptr = pubnames_buffer; while ((pubnames_ptr - pubnames_buffer) < dwarf_pubnames_size) { @@ -1083,7 +1113,8 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline) aranges_buffer = dwarf2_read_section (objfile, dwarf_aranges_offset, - dwarf_aranges_size); + dwarf_aranges_size, + dwarf_aranges_section); } #endif @@ -3584,15 +3615,20 @@ make_cleanup_free_die_list (struct die_info *dies) char * dwarf2_read_section (struct objfile *objfile, file_ptr offset, - unsigned int size) + unsigned int size, asection *sectp) { bfd *abfd = objfile->obfd; - char *buf; + char *buf, *retbuf; if (size == 0) return NULL; buf = (char *) obstack_alloc (&objfile->psymbol_obstack, size); + retbuf + = (char *) symfile_relocate_debug_section (abfd, sectp, (bfd_byte *) buf); + if (retbuf != NULL) + return retbuf; + if ((bfd_seek (abfd, offset, SEEK_SET) != 0) || (bfd_bread (buf, size, abfd) != size)) { diff --git a/gdb/elfread.c b/gdb/elfread.c index 5eaeed0242..b96d6e7ff2 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -591,8 +591,7 @@ elf_symfile_read (struct objfile *objfile, int mainline) if (str_sect) elfstab_build_psymtabs (objfile, mainline, - ei.stabsect->filepos, - bfd_section_size (abfd, ei.stabsect), + ei.stabsect, str_sect->filepos, bfd_section_size (abfd, str_sect)); } diff --git a/gdb/gdb-stabs.h b/gdb/gdb-stabs.h index d2da2d11d9..abe2d3365b 100644 --- a/gdb/gdb-stabs.h +++ b/gdb/gdb-stabs.h @@ -70,6 +70,9 @@ struct dbx_symfile_info asection *text_section; asection *data_section; asection *bss_section; + + /* Pointer to the separate ".stab" section, if there is one. */ + asection *stab_section; }; #define DBX_SYMFILE_INFO(o) ((o)->sym_stab_info) @@ -83,5 +86,6 @@ struct dbx_symfile_info #define DBX_TEXT_SECTION(o) (DBX_SYMFILE_INFO(o)->text_section) #define DBX_DATA_SECTION(o) (DBX_SYMFILE_INFO(o)->data_section) #define DBX_BSS_SECTION(o) (DBX_SYMFILE_INFO(o)->bss_section) +#define DBX_STAB_SECTION(o) (DBX_SYMFILE_INFO(o)->stab_section) #endif /* GDBSTABS_H */ diff --git a/gdb/stabsread.h b/gdb/stabsread.h index 9f15642f24..62fd77601a 100644 --- a/gdb/stabsread.h +++ b/gdb/stabsread.h @@ -181,7 +181,7 @@ extern void process_one_symbol (int, int, CORE_ADDR, char *, extern void elfstab_build_psymtabs (struct objfile *objfile, int mainline, - file_ptr staboff, unsigned int stabsize, + asection *stabsect, file_ptr stabstroffset, unsigned int stabstrsize); diff --git a/gdb/symfile.c b/gdb/symfile.c index 81e1f7446f..95da6f1241 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" +#include "bfdlink.h" #include "symtab.h" #include "gdbtypes.h" #include "gdbcore.h" @@ -3562,6 +3563,45 @@ simple_overlay_update (struct obj_section *osect) } } +/* Set the output sections and output offsets for section SECTP in + ABFD. The relocation code in BFD will read these offsets, so we + need to be sure they're initialized. We map each section to itself, + with no offset; this means that SECTP->vma will be honored. */ + +static void +symfile_dummy_outputs (bfd *abfd, asection *sectp, void *dummy) +{ + sectp->output_section = sectp; + sectp->output_offset = 0; +} + +/* Relocate the contents of a debug section SECTP in ABFD. The + contents are stored in BUF if it is non-NULL, or returned in a + malloc'd buffer otherwise. + + For some platforms and debug info formats, shared libraries contain + relocations against the debug sections (particularly for DWARF-2; + one affected platform is PowerPC GNU/Linux, although it depends on + the version of the linker in use). Also, ELF object files naturally + have unresolved relocations for their debug sections. We need to apply + the relocations in order to get the locations of symbols correct. */ + +bfd_byte * +symfile_relocate_debug_section (bfd *abfd, asection *sectp, bfd_byte *buf) +{ + /* We're only interested in debugging sections with relocation + information. */ + if ((sectp->flags & SEC_RELOC) == 0) + return NULL; + if ((sectp->flags & SEC_DEBUGGING) == 0) + return NULL; + + /* We will handle section offsets properly elsewhere, so relocate as if + all sections begin at 0. */ + bfd_map_over_sections (abfd, symfile_dummy_outputs, NULL); + + return bfd_simple_get_relocated_section_contents (abfd, sectp, buf); +} void _initialize_symfile (void) diff --git a/gdb/symfile.h b/gdb/symfile.h index 060eb4cdee..267146375c 100644 --- a/gdb/symfile.h +++ b/gdb/symfile.h @@ -1,6 +1,6 @@ /* Definitions for reading symbol files into GDB. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001 + 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -300,6 +300,9 @@ extern void symbol_file_add_main (char *args, int from_tty); /* Clear GDB symbol tables. */ extern void symbol_file_clear (int from_tty); +extern bfd_byte *symfile_relocate_debug_section (bfd *abfd, asection *sectp, + bfd_byte *buf); + /* From dwarfread.c */ extern void