From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18619 invoked by alias); 15 Apr 2002 21:11:27 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 18602 invoked from network); 15 Apr 2002 21:11:24 -0000 Received: from unknown (HELO cygnus.com) (205.180.83.203) by sources.redhat.com with SMTP; 15 Apr 2002 21:11:24 -0000 Received: from localhost.redhat.com (romulus.sfbay.redhat.com [172.16.27.251]) by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id OAA14976 for ; Mon, 15 Apr 2002 14:11:23 -0700 (PDT) Received: by localhost.redhat.com (Postfix, from userid 469) id 4F2F311438; Mon, 15 Apr 2002 17:11:02 -0400 (EDT) From: Elena Zannoni MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <15547.16869.937738.748385@localhost.redhat.com> Date: Mon, 15 Apr 2002 14:11:00 -0000 To: Daniel Jacobowitz Cc: gdb-patches@sources.redhat.com Subject: Re: [RFA] Relocate debug information in object files (e.g. add-symbol-file) In-Reply-To: <20020404170610.A3717@nevyn.them.org> References: <20020404170610.A3717@nevyn.them.org> X-SW-Source: 2002-04/txt/msg00540.txt.bz2 Daniel Jacobowitz writes: > This fixes a nasty problem debugging kernel modules on PowerPC. The test is > in my previous message to this list today; it fixes: > FAIL: gdb.base/relocate.exp: static variables have different addresses > > The problem goes like this: We know, when loading a new file at a specified > offset, that addresses in debug info are going to be a bit off. We shift > them all by the appropriate constants (well, sometimes the appropriate > constants. PowerPC has other problems with .data vs .sdata occasionally). > Shifting by constant section offsets is all we do. > > On i386 and many other targets this suffices. Why? Because the debug info > looks like this: > 22 STSYM 0 1 00000000 934 static_foo:S(0,1) > 23 STSYM 0 2 00000004 952 static_bar:S(0,1) > 0000011c 00000301 R_386_32 00000000 .data > 00000128 00000301 R_386_32 00000000 .data > > On PowerPC, it doesn't look like that at all. I believe the reason has to > do with the ABI allowing .sdata optimizations. It may also show up on other > architectures that use RELA; even though the offset will still be against > the section in that case, it will be shifted into the relocation entry > instead of the debug info directly. Instead we have: > 22 STSYM 0 1 00000000 948 static_foo:S(0,1) > 23 STSYM 0 2 00000000 966 static_bar:S(0,1) > 0000011c 00601 R_PPC_ADDR32 00000000 static_foo + 0 > 00000128 00701 R_PPC_ADDR32 00000004 static_bar + 0 > > The important changes are: the +4 in static_bar's stab has disappeared, and > the relocations are now against symbols. > > The only way to make sense of this is to relocate the section. It turned > out to be easier than I feared. BFD provides (almost) the perfect hooks; we > need to fake a couple of data structures in order to pretend that we're a > linker, but that's it. One consequence is that (in the case of an object > file only, not in the unchanged normal case) we preread the entire stabs > debug section. Since this will only happen for individual object files, and > we don't keep it around, the memory increase doesn't worry me. The > relocation itself is blindingly fast (imperceptible on a module I have here > with 4000 relocations and tons of symbols). > > How does this patch look? OK to commit? > Sorry, I don't like it too much. You are using PTR, I would prefer if you didn't. True/false were both eliminated from gdb. Also, I don't really like the idea to introduce the dummy functions. Would it be possible to add something to bfd to provide a better interface that is not just taylored to the linker? For instance bfd has the file linker.c to provide such an interface. Could we have a debugger.c file? How about writing a simplified version of bfd_generic_get_relocated_section_contents so the need of the dummy parameters would be eliminated? In a sense you already have started that in symfile_relocate_debug_section. I also am not sure about the use of the global stabs_data. I know dbxread.c is not the best written file in gdb, but... Maybe you can have accessor functions? Don't know, stabs_seek ? Stabs_seek would decide whether to do a bfd_seek or a buffer pointer/counter adjustment. Elena > -- > Daniel Jacobowitz Carnegie Mellon University > MontaVista Software Debian GNU/Linux Developer > > 2002-04-02 Daniel Jacobowitz > > * dbxread.c (stabs_data): New static variable. > (fill_symbuf): Support an in-memory buffer for stabs data. > (read_ofile_symtab): Relocate the stabs data if necessary. > (elfstab_build_psymtabs): Take an asection* instead of > an offset and size. Relocate the stabs data if necessary. > Save the section* for read_ofile_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 (dwarf2_build_frame_info): Likewise. > * 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. > * os9kread.c (os9k_symfile_init): Initialize dbx_symfile_info > properly. > * symfile.c (symfile_dummy_outputs, symfile_dummy_warning) > (symfile_dummy_undefined_symbol, symfile_dummy_reloc_overflow) > (symfile_dummy_reloc_dangerous, symfile_dummy_unattached_reloc): > New dummy functions. > (symfile_relocate_debug_section): New function. > * symfile.h (symfile_relocate_debug_section): Add prototype. > > Index: dbxread.c > =================================================================== > RCS file: /cvs/src/src/gdb/dbxread.c,v > retrieving revision 1.31 > diff -u -p -r1.31 dbxread.c > --- dbxread.c 2002/03/21 19:48:54 1.31 > +++ dbxread.c 2002/04/04 21:51:19 > @@ -919,6 +919,10 @@ static struct stab_section_list *symbuf_ > static unsigned int symbuf_left; > static unsigned int symbuf_read; > > +/* This variable stores a global stabs buffer, if we already read stabs into > + memory. */ > +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. > @@ -931,8 +935,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 ((PTR) symbuf, count, sym_bfd); > + } > else > { > if (symbuf_left <= 0) > @@ -948,9 +962,9 @@ fill_symbuf (bfd *sym_bfd) > count = symbuf_left; > if (count > sizeof (symbuf)) > count = sizeof (symbuf); > + nbytes = bfd_bread ((PTR) symbuf, count, sym_bfd); > } > > - nbytes = bfd_bread ((PTR) symbuf, count, sym_bfd); > if (nbytes < 0) > perror_with_name (bfd_get_filename (sym_bfd)); > else if (nbytes == 0) > @@ -2497,6 +2511,7 @@ read_ofile_symtab (struct partial_symtab > CORE_ADDR text_offset; /* Start of text segment for symbols */ > int text_size; /* Size of text segment for symbols */ > struct section_offsets *section_offsets; > + struct cleanup *back_to = NULL; > > objfile = pst->objfile; > sym_offset = LDSYMOFF (pst); > @@ -2518,7 +2533,18 @@ read_ofile_symtab (struct partial_symtab > 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; > > + if (DBX_STAB_SECTION (objfile)) > + { > + stabs_data = symfile_relocate_debug_section (objfile->obfd, > + DBX_STAB_SECTION (objfile), > + NULL); > + if (stabs_data) > + back_to = make_cleanup (free_current_contents, (void *) &stabs_data); > + } > + > /* It is necessary to actually read one symbol *before* the start > of this symtab's symbols, because the GCC_COMPILED_FLAG_SYMBOL > occurs before the N_SO symbol. > @@ -2527,7 +2553,13 @@ read_ofile_symtab (struct partial_symtab > 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); > + if (stabs_data) > + { > + symbuf_read += sym_offset - symbol_size; > + symbuf_left -= sym_offset - symbol_size; > + } > + else > + bfd_seek (symfile_bfd, sym_offset - symbol_size, SEEK_CUR); > fill_symbuf (abfd); > bufp = &symbuf[symbuf_idx++]; > INTERNALIZE_SYMBOL (nlist, bufp, abfd); > @@ -2570,7 +2602,13 @@ read_ofile_symtab (struct partial_symtab > /* 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); > + if (stabs_data) > + { > + symbuf_read += sym_offset; > + symbuf_left -= sym_offset; > + } > + else > + bfd_seek (symfile_bfd, sym_offset, SEEK_CUR); > processing_gcc_compilation = 0; > } > > @@ -2664,6 +2702,9 @@ read_ofile_symtab (struct partial_symtab > process_now (objfile); > > end_stabs (); > + > + if (back_to) > + do_cleanups (back_to); > } > > > @@ -3399,8 +3440,7 @@ coffstab_build_psymtabs (struct objfile > 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. > > @@ -3409,13 +3449,14 @@ coffstab_build_psymtabs (struct objfile > > 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. */ > @@ -3427,9 +3468,11 @@ elfstab_build_psymtabs (struct objfile * > > #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); > @@ -3454,10 +3497,19 @@ elfstab_build_psymtabs (struct objfile * > > 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 > Index: dwarf2cfi.c > =================================================================== > RCS file: /cvs/src/src/gdb/dwarf2cfi.c,v > retrieving revision 1.2 > diff -u -p -r1.2 dwarf2cfi.c > --- dwarf2cfi.c 2002/03/27 14:32:08 1.2 > +++ dwarf2cfi.c 2002/04/04 21:51:19 > @@ -188,12 +188,14 @@ 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; > > static char *dwarf_frame_buffer; > > > 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); > @@ -1362,7 +1364,8 @@ dwarf2_build_frame_info (struct objfile > { > dwarf_frame_buffer = dwarf2_read_section (objfile, > dwarf_frame_offset, > - dwarf_frame_size); > + dwarf_frame_size, > + dwarf_frame_section); > > start = dwarf_frame_buffer; > end = dwarf_frame_buffer + dwarf_frame_size; > @@ -1371,7 +1374,8 @@ dwarf2_build_frame_info (struct objfile > { > dwarf_frame_buffer = dwarf2_read_section (objfile, > dwarf_eh_frame_offset, > - dwarf_eh_frame_size); > + dwarf_eh_frame_size, > + dwarf_eh_frame_section); > > start = dwarf_frame_buffer; > end = dwarf_frame_buffer + dwarf_eh_frame_size; > Index: dwarf2read.c > =================================================================== > RCS file: /cvs/src/src/gdb/dwarf2read.c,v > retrieving revision 1.51 > diff -u -p -r1.51 dwarf2read.c > --- dwarf2read.c 2002/03/21 00:53:44 1.51 > +++ dwarf2read.c 2002/04/04 21:51:20 > @@ -146,6 +146,17 @@ static unsigned int dwarf_str_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; > +asection *dwarf_frame_section; > +asection *dwarf_eh_frame_section; > + > /* names of the debugging sections */ > > #define INFO_SECTION ".debug_info" > @@ -582,7 +593,8 @@ static void dwarf2_psymtab_to_symtab (st > > 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 *, unsigned int); > > @@ -825,51 +837,61 @@ dwarf2_locate_sections (bfd *ignore_abfd > { > 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; > } > } > > @@ -883,18 +905,22 @@ dwarf2_build_psymtabs (struct objfile *o > > 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); > dwarf_line_buffer = dwarf2_read_section (objfile, > dwarf_line_offset, > - dwarf_line_size); > + dwarf_line_size, > + dwarf_line_section); > > 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; > > @@ -936,7 +962,8 @@ dwarf2_build_psymtabs_easy (struct objfi > > 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) > { > @@ -956,7 +983,8 @@ dwarf2_build_psymtabs_easy (struct objfi > > aranges_buffer = dwarf2_read_section (objfile, > dwarf_aranges_offset, > - dwarf_aranges_size); > + dwarf_aranges_size, > + dwarf_aranges_section); > > } > #endif > @@ -3082,15 +3110,20 @@ make_cleanup_free_die_list (struct die_i > > 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)) > { > Index: elfread.c > =================================================================== > RCS file: /cvs/src/src/gdb/elfread.c,v > retrieving revision 1.21 > diff -u -p -r1.21 elfread.c > --- elfread.c 2002/03/19 19:00:03 1.21 > +++ elfread.c 2002/04/04 21:51:21 > @@ -612,8 +612,7 @@ elf_symfile_read (struct objfile *objfil > 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)); > } > Index: gdb-stabs.h > =================================================================== > RCS file: /cvs/src/src/gdb/gdb-stabs.h,v > retrieving revision 1.5 > diff -u -p -r1.5 gdb-stabs.h > --- gdb-stabs.h 2001/03/06 08:21:07 1.5 > +++ gdb-stabs.h 2002/04/04 21:51:21 > @@ -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 */ > Index: os9kread.c > =================================================================== > RCS file: /cvs/src/src/gdb/os9kread.c,v > retrieving revision 1.12 > diff -u -p -r1.12 os9kread.c > --- os9kread.c 2001/12/02 22:38:23 1.12 > +++ os9kread.c 2002/04/04 21:51:21 > @@ -392,6 +392,9 @@ os9k_symfile_init (struct objfile *objfi > /* Allocate struct to keep track of the symfile */ > objfile->sym_stab_info = (struct dbx_symfile_info *) > xmmalloc (objfile->md, sizeof (struct dbx_symfile_info)); > + memset ((char *) objfile->sym_stab_info, 0, > + sizeof (struct dbx_symfile_info)); > + > DBX_SYMFILE_INFO (objfile)->stab_section_info = NULL; > > text_sect = bfd_get_section_by_name (sym_bfd, ".text"); > Index: stabsread.h > =================================================================== > RCS file: /cvs/src/src/gdb/stabsread.h,v > retrieving revision 1.6 > diff -u -p -r1.6 stabsread.h > --- stabsread.h 2001/09/05 02:54:15 1.6 > +++ stabsread.h 2002/04/04 21:51:21 > @@ -189,7 +189,7 @@ process_one_symbol (int, int, CORE_ADDR, > extern void elfstab_build_psymtabs > (struct objfile *objfile, > int mainline, > - file_ptr staboff, unsigned int stabsize, > + asection *stabsect, > file_ptr stabstroffset, unsigned int stabstrsize); > > extern void coffstab_build_psymtabs > Index: symfile.c > =================================================================== > RCS file: /cvs/src/src/gdb/symfile.c,v > retrieving revision 1.58 > diff -u -p -r1.58 symfile.c > --- symfile.c 2002/03/29 01:09:27 1.58 > +++ symfile.c 2002/04/04 21:51:22 > @@ -23,6 +23,7 @@ > Boston, MA 02111-1307, USA. */ > > #include "defs.h" > +#include "bfdlink.h" > #include "symtab.h" > #include "gdbtypes.h" > #include "gdbcore.h" > @@ -40,6 +41,7 @@ > #include "gdb-stabs.h" > #include "obstack.h" > #include "completer.h" > +#include "gdb_assert.h" > > #include > #include > @@ -3215,6 +3217,137 @@ simple_overlay_update (struct obj_sectio > } > } > > + > +static void > +symfile_dummy_outputs (bfd *abfd, asection *sectp, void *dummy) > +{ > + sectp->output_section = sectp; > + sectp->output_offset = 0; > +} > + > +static boolean > +symfile_dummy_warning (struct bfd_link_info *link_info, > + const char *warning, const char *symbol, > + bfd *abfd, asection *section, > + bfd_vma address) > +{ > + return true; > +} > + > +static boolean > +symfile_dummy_undefined_symbol (struct bfd_link_info *link_info, > + const char *name, bfd *abfd, > + asection *section, > + bfd_vma address, > + boolean fatal) > +{ > + return true; > +} > + > +static boolean > +symfile_dummy_reloc_overflow (struct bfd_link_info *link_info, > + const char *name, > + const char *reloc_name, bfd_vma addend, > + bfd *abfd, asection *section, > + bfd_vma address) > +{ > + return true; > +} > + > +static boolean > +symfile_dummy_reloc_dangerous (struct bfd_link_info *link_info, > + const char *message, > + bfd *abfd, asection *section, > + bfd_vma address) > +{ > + return true; > +} > + > +static boolean > +symfile_dummy_unattached_reloc (struct bfd_link_info *link_info, > + const char *name, > + bfd *abfd, asection *section, > + bfd_vma address) > +{ > + return true; > +} > + > +bfd_byte * > +symfile_relocate_debug_section (bfd *abfd, asection *sectp, bfd_byte *buf) > +{ > + struct bfd_link_info link_info; > + struct bfd_link_order link_order; > + struct bfd_link_callbacks callbacks; > + bfd_byte *contents, *data; > + int storage_needed, number_of_symbols; > + asymbol **symbol_table; > + > + /* 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; > + > + /* In order to use bfd_get_relocated_section_contents, we need > + to forge some data structures that it expects. */ > + > + /* Fill in the bare minimum number of fields for our purposes. */ > + memset (&link_info, 0, sizeof (link_info)); > + link_info.input_bfds = abfd; > + > + link_info.hash = bfd_link_hash_table_create (abfd); > + link_info.callbacks = &callbacks; > + callbacks.warning = symfile_dummy_warning; > + callbacks.undefined_symbol = symfile_dummy_undefined_symbol; > + callbacks.reloc_overflow = symfile_dummy_reloc_overflow; > + callbacks.reloc_dangerous = symfile_dummy_reloc_dangerous; > + callbacks.unattached_reloc = symfile_dummy_unattached_reloc; > + > + memset (&link_order, 0, sizeof (link_order)); > + link_order.next = NULL; > + link_order.type = bfd_indirect_link_order; > + link_order.offset = 0; > + link_order.size = bfd_section_size (abfd, sectp); > + link_order.u.indirect.section = sectp; > + > + bfd_map_over_sections (abfd, symfile_dummy_outputs, NULL); > + > + data = NULL; > + if (buf == NULL) > + { > + data = xmalloc (bfd_section_size (abfd, sectp)); > + buf = data; > + } > + bfd_link_add_symbols (abfd, &link_info); > + > + storage_needed = bfd_get_symtab_upper_bound (abfd); > + symbol_table = (asymbol **) xmalloc (storage_needed); > + number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); > + > + contents = bfd_get_relocated_section_contents (abfd, > + &link_info, > + &link_order, > + buf, > + 0, > + symbol_table); > + if (contents == NULL && data != NULL) > + xfree (data); > + > + /* Foul hack to prevent bfd_section_size aborts. This flag only controls > + that macro (and the related size macros), selecting between _raw_size > + and _cooked_size. Debug sections won't change size while we're only > + relocating. There may be trouble here someday if it tries to run > + relaxation unexpectedly, so make sure. */ > + gdb_assert (sectp->_raw_size == sectp->_cooked_size); > + sectp->reloc_done = 0; > + > + /* On some targets this may be a smallish memory leak. If so, that means > + the target needs a customized implementation of this function in BFD. */ > + bfd_link_hash_table_free (abfd, link_info.hash); > + > + return contents; > +} > > void > _initialize_symfile (void) > Index: symfile.h > =================================================================== > RCS file: /cvs/src/src/gdb/symfile.h,v > retrieving revision 1.12 > diff -u -p -r1.12 symfile.h > --- symfile.h 2002/02/01 01:14:20 1.12 > +++ symfile.h 2002/04/04 21:51:22 > @@ -293,6 +293,9 @@ extern void symbol_file_add_main (char * > /* 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