This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] Relocate debug information in object files (e.g. add-symbol-file)


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?

-- 
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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]