From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20538 invoked by alias); 4 Apr 2002 22:06:07 -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 20530 invoked from network); 4 Apr 2002 22:06:03 -0000 Received: from unknown (HELO nevyn.them.org) (128.2.145.6) by sources.redhat.com with SMTP; 4 Apr 2002 22:06:03 -0000 Received: from drow by nevyn.them.org with local (Exim 3.35 #1 (Debian)) id 16tFMw-000151-00 for ; Thu, 04 Apr 2002 17:06:10 -0500 Date: Thu, 04 Apr 2002 14:06:00 -0000 From: Daniel Jacobowitz To: gdb-patches@sources.redhat.com Subject: [RFA] Relocate debug information in object files (e.g. add-symbol-file) Message-ID: <20020404170610.A3717@nevyn.them.org> Mail-Followup-To: gdb-patches@sources.redhat.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.23i X-SW-Source: 2002-04/txt/msg00136.txt.bz2 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 * 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