This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [RFA] Relocate debug information in object files (e.g. add-symbol-file)
- From: Elena Zannoni <ezannoni at redhat dot com>
- To: Daniel Jacobowitz <drow at mvista dot com>
- Cc: gdb-patches at sources dot redhat dot com
- Date: Mon, 15 Apr 2002 17:11:01 -0400
- Subject: Re: [RFA] Relocate debug information in object files (e.g. add-symbol-file)
- References: <20020404170610.A3717@nevyn.them.org>
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 <drow@mvista.com>
>
> * 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 <sys/types.h>
> #include <fcntl.h>
> @@ -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