This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[RFA] Relocate debug information in object files (e.g. add-symbol-file)
- From: Daniel Jacobowitz <drow at mvista dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Thu, 4 Apr 2002 17:06:10 -0500
- Subject: [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