--- gdb-5.2.1/gdb/dbxread.c.orig	Fri Sep 26 14:24:22 2003
+++ gdb-5.2.1/gdb/dbxread.c	Tue Sep 30 09:50:07 2003
@@ -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)
@@ -947,10 +961,10 @@ fill_symbuf (bfd *sym_bfd)
 
       count = symbuf_left;
       if (count > sizeof (symbuf))
-	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)
@@ -2537,6 +2551,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);
@@ -2558,6 +2573,17 @@ 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
@@ -2567,7 +2593,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);
@@ -2610,7 +2642,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;
     }
 
@@ -2704,6 +2742,9 @@ read_ofile_symtab (struct partial_symtab
   process_now (objfile);
 
   end_stabs ();
+
+  if (back_to)
+    do_cleanups (back_to);
 }
 
 
@@ -3093,13 +3134,44 @@ process_one_symbol (int type, int desc, 
 
     case_N_STSYM:		/* Static symbol in data seg */
     case N_DSLINE:		/* Source line number, data seg */
-      valu += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
+	{
+	  struct minimal_symbol *asym = NULL;
+	  char *p;
+
+	  p = strchr (name, ':');
+	  if (p != 0 && p[1] == 'S') 
+	    {
+	      *p = '\0';
+	      asym = lookup_minimal_symbol(name, NULL, NULL);
+	    }
+
+	  valu += ANOFFSET (section_offsets, (asym ? asym->ginfo.section : 
+						  SECT_OFF_DATA (objfile)));
+	  if (p)
+	    *p = ':';
+	}
       goto define_a_symbol;
 
     case_N_LCSYM:		/* Static symbol in BSS seg */
     case N_BSLINE:		/* Source line number, bss seg */
       /*   N_BROWS:       overlaps with N_BSLINE */
-      valu += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
+	{
+	  struct minimal_symbol *asym = NULL;
+	  char *p;
+
+	  p = strchr (name, ':');
+	  if (p != 0 && p[1] == 'S') 
+	    {
+	      *p = '\0';
+	      asym = lookup_minimal_symbol(name, NULL, NULL);
+	    }
+
+	  valu += ANOFFSET (section_offsets, (asym ? asym->ginfo.section : 
+						  SECT_OFF_BSS (objfile)));
+		
+	  if (p)
+	    *p = ':';
+	}
       goto define_a_symbol;
 
     case_N_ROSYM:		/* Static symbol in Read-only data seg */
@@ -3449,8 +3521,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.
 
@@ -3459,13 +3530,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.  */
@@ -3477,9 +3549,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);
@@ -3504,10 +3578,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
--- gdb-5.2.1/gdb/dwarf2read.c.orig	Thu Feb 28 12:21:16 2002
+++ gdb-5.2.1/gdb/dwarf2read.c	Mon Sep 29 17:52:27 2003
@@ -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,41 +837,49 @@ 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_macinfo_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))
     {
@@ -883,18 +903,21 @@ 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;
 
@@ -956,6 +979,7 @@ dwarf2_build_psymtabs_easy (struct objfi
 
   aranges_buffer = dwarf2_read_section (objfile,
 					dwarf_aranges_offset,
+					dwarf_aranges_section,
 					dwarf_aranges_size);
 
 }
@@ -3068,15 +3092,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))
     {
--- gdb-5.2.1/gdb/elfread.c.orig	Mon Mar 25 17:50:20 2002
+++ gdb-5.2.1/gdb/elfread.c	Mon Sep 29 15:30:58 2003
@@ -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));
     }
--- gdb-5.2.1/gdb/os9kread.c.orig	Sun Dec  2 23:38:23 2001
+++ gdb-5.2.1/gdb/os9kread.c	Mon Sep 29 15:30:59 2003
@@ -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");
--- gdb-5.2.1/gdb/symfile.c.orig	Mon Sep 29 13:17:56 2003
+++ gdb-5.2.1/gdb/symfile.c	Mon Sep 29 15:31:01 2003
@@ -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>
@@ -3254,6 +3256,146 @@ 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;
+
+  /* 
+   * Zero out these fields. For some reasons 
+   * bfd_get_relocated_section_contents() returns wrong data
+   * on a subsequent calls. This happens with objects generated
+   * from asm.
+   */
+  sectp->relocation = 0;
+  sectp->output_section = 0;
+
+  /* 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;
+#if 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);
+#endif
+  return contents;
+}
+
 void
 _initialize_symfile (void)
 {
--- gdb-5.2.1/gdb/symfile.h.orig	Mon Sep 29 13:35:17 2003
+++ gdb-5.2.1/gdb/symfile.h	Mon Sep 29 15:31:01 2003
@@ -296,6 +296,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
--- gdb-5.2.1/gdb/stabsread.h	Tue Sep 30 10:14:05 2003
+++ gdb-5.2.1/gdb/stabsread.h.orig	Tue Sep 30 10:16:54 2003
@@ -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
 --- gdb-5.2.1/gdb/gdb-stabs.h.orig	Tue Mar  6 09:21:07 2001
+++ gdb-5.2.1/gdb/gdb-stabs.h	Tue Sep 30 14:15:32 2003
@@ -70,6 +70,7 @@ struct dbx_symfile_info
     asection *text_section;
     asection *data_section;
     asection *bss_section;
+    asection *stab_section;
   };
 
 #define DBX_SYMFILE_INFO(o)	((o)->sym_stab_info)
@@ -83,5 +84,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 */
