aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog27
-rw-r--r--gdb/dbxread.c73
-rw-r--r--gdb/dwarf2cfi.c15
-rw-r--r--gdb/dwarf2read.c60
-rw-r--r--gdb/elfread.c3
-rw-r--r--gdb/gdb-stabs.h4
-rw-r--r--gdb/stabsread.h2
-rw-r--r--gdb/symfile.c40
-rw-r--r--gdb/symfile.h5
9 files changed, 199 insertions, 30 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4c225a9..696fbcd 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,30 @@
+2003-01-31 Daniel Jacobowitz <drow@mvista.com>
+
+ * dbxread.c (stabs_data): New static variable.
+ (fill_symbuf): Support an in-memory buffer for stabs data.
+ (stabs_seek): New function.
+ (dbx_psymtab_to_symtab): Relocate the stabs data if necessary.
+ (read_ofile_symtab): Use stabs_seek.
+ (elfstab_build_psymtabs): Take an asection* instead of
+ an offset and size. Relocate the stabs data if necessary.
+ Save the section* for dbx_psymtab_to_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 (parse_frame_info): Take a section argument and pass
+ it to dwarf2_read_section.
+ (dwarf2_build_frame_info): Update callers.
+ * 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.
+ * symfile.c (symfile_dummy_outputs): New function.
+ (symfile_relocate_debug_section): New function.
+ * symfile.h (symfile_relocate_debug_section): Add prototype.
+
2003-01-31 Richard Henderson <rth@redhat.com>
* alpha-nat.c (REGISTER_PTRACE_ADDR): Merge into ...
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index c533eb4..2a1d4e2 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -893,6 +893,10 @@ static struct stab_section_list *symbuf_sections;
static unsigned int symbuf_left;
static unsigned int symbuf_read;
+/* This variable stores a global stabs buffer, if we read stabs into
+ memory in one chunk in order to process relocations. */
+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.
@@ -905,8 +909,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 (symbuf, count, sym_bfd);
+ }
else
{
if (symbuf_left <= 0)
@@ -922,9 +936,9 @@ fill_symbuf (bfd *sym_bfd)
count = symbuf_left;
if (count > sizeof (symbuf))
count = sizeof (symbuf);
+ nbytes = bfd_bread (symbuf, count, sym_bfd);
}
- nbytes = bfd_bread (symbuf, count, sym_bfd);
if (nbytes < 0)
perror_with_name (bfd_get_filename (sym_bfd));
else if (nbytes == 0)
@@ -935,6 +949,18 @@ fill_symbuf (bfd *sym_bfd)
symbuf_read += nbytes;
}
+static void
+stabs_seek (int sym_offset)
+{
+ if (stabs_data)
+ {
+ symbuf_read += sym_offset;
+ symbuf_left -= sym_offset;
+ }
+ else
+ bfd_seek (symfile_bfd, sym_offset, SEEK_CUR);
+}
+
#define INTERNALIZE_SYMBOL(intern, extern, abfd) \
{ \
(intern).n_type = bfd_h_get_8 (abfd, (extern)->e_type); \
@@ -2473,6 +2499,7 @@ static void
dbx_psymtab_to_symtab (struct partial_symtab *pst)
{
bfd *sym_bfd;
+ struct cleanup *back_to = NULL;
if (!pst)
return;
@@ -2498,8 +2525,21 @@ dbx_psymtab_to_symtab (struct partial_symtab *pst)
next_symbol_text_func = dbx_next_symbol_text;
+ if (DBX_STAB_SECTION (pst->objfile))
+ {
+ stabs_data
+ = symfile_relocate_debug_section (pst->objfile->obfd,
+ DBX_STAB_SECTION (pst->objfile),
+ NULL);
+ if (stabs_data)
+ back_to = make_cleanup (free_current_contents, (void *) &stabs_data);
+ }
+
dbx_psymtab_to_symtab_1 (pst);
+ if (back_to)
+ do_cleanups (back_to);
+
/* Match with global symbols. This only needs to be done once,
after all of the symtabs and dependencies have been read in. */
scan_file_globals (pst->objfile);
@@ -2548,6 +2588,8 @@ read_ofile_symtab (struct partial_symtab *pst)
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;
/* It is necessary to actually read one symbol *before* the start
of this symtab's symbols, because the GCC_COMPILED_FLAG_SYMBOL
@@ -2557,7 +2599,7 @@ read_ofile_symtab (struct partial_symtab *pst)
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);
+ stabs_seek (sym_offset - symbol_size);
fill_symbuf (abfd);
bufp = &symbuf[symbuf_idx++];
INTERNALIZE_SYMBOL (nlist, bufp, abfd);
@@ -2600,7 +2642,7 @@ read_ofile_symtab (struct partial_symtab *pst)
/* 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);
+ stabs_seek (sym_offset);
processing_gcc_compilation = 0;
}
@@ -3460,8 +3502,7 @@ coffstab_build_psymtabs (struct objfile *objfile, int mainline,
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.
@@ -3470,13 +3511,14 @@ coffstab_build_psymtabs (struct objfile *objfile, int mainline,
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. */
@@ -3488,9 +3530,11 @@ elfstab_build_psymtabs (struct objfile *objfile, int mainline,
#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);
@@ -3515,10 +3559,19 @@ elfstab_build_psymtabs (struct objfile *objfile, int mainline,
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
diff --git a/gdb/dwarf2cfi.c b/gdb/dwarf2cfi.c
index 79ba418..c928855 100644
--- a/gdb/dwarf2cfi.c
+++ b/gdb/dwarf2cfi.c
@@ -170,10 +170,13 @@ 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;
+
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);
@@ -1368,7 +1371,8 @@ compare_fde_unit (const void *a, const void *b)
-- mludvig */
static void
parse_frame_info (struct objfile *objfile, file_ptr frame_offset,
- unsigned int frame_size, int eh_frame)
+ unsigned int frame_size, asection *frame_section,
+ int eh_frame)
{
bfd *abfd = objfile->obfd;
asection *curr_section_ptr;
@@ -1383,7 +1387,8 @@ parse_frame_info (struct objfile *objfile, file_ptr frame_offset,
unwind_tmp_obstack_init ();
- frame_buffer = dwarf2_read_section (objfile, frame_offset, frame_size);
+ frame_buffer = dwarf2_read_section (objfile, frame_offset, frame_size,
+ frame_section);
start = frame_buffer;
end = frame_buffer + frame_size;
@@ -1636,12 +1641,14 @@ dwarf2_build_frame_info (struct objfile *objfile)
if (dwarf_frame_offset)
{
parse_frame_info (objfile, dwarf_frame_offset,
- dwarf_frame_size, 0 /* = debug_frame */ );
+ dwarf_frame_size, dwarf_frame_section,
+ 0 /* = debug_frame */ );
after_debug_frame = 1;
}
if (dwarf_eh_frame_offset)
parse_frame_info (objfile, dwarf_eh_frame_offset, dwarf_eh_frame_size,
+ dwarf_eh_frame_section,
1 /* = eh_frame */ + after_debug_frame);
}
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index fdc05e1..a876043 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -1,5 +1,5 @@
/* DWARF 2 debugging format support for GDB.
- Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
@@ -149,6 +149,18 @@ static unsigned int dwarf_ranges_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;
+static asection *dwarf_ranges_section;
+asection *dwarf_frame_section;
+asection *dwarf_eh_frame_section;
+
/* names of the debugging sections */
#define INFO_SECTION ".debug_info"
@@ -658,7 +670,8 @@ static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
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 *abfd, struct comp_unit_head *cu_header);
@@ -929,51 +942,61 @@ dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr)
{
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;
}
else if (STREQ (sectp->name, RANGES_SECTION))
{
@@ -992,36 +1015,42 @@ dwarf2_build_psymtabs (struct objfile *objfile, int mainline)
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);
if (dwarf_line_offset)
dwarf_line_buffer = dwarf2_read_section (objfile,
dwarf_line_offset,
- dwarf_line_size);
+ dwarf_line_size,
+ dwarf_line_section);
else
dwarf_line_buffer = NULL;
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;
if (dwarf_macinfo_offset)
dwarf_macinfo_buffer = dwarf2_read_section (objfile,
dwarf_macinfo_offset,
- dwarf_macinfo_size);
+ dwarf_macinfo_size,
+ dwarf_macinfo_section);
else
dwarf_macinfo_buffer = NULL;
if (dwarf_ranges_offset)
dwarf_ranges_buffer = dwarf2_read_section (objfile,
dwarf_ranges_offset,
- dwarf_ranges_size);
+ dwarf_ranges_size,
+ dwarf_ranges_section);
else
dwarf_ranges_buffer = NULL;
@@ -1063,7 +1092,8 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline)
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)
{
@@ -1083,7 +1113,8 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline)
aranges_buffer = dwarf2_read_section (objfile,
dwarf_aranges_offset,
- dwarf_aranges_size);
+ dwarf_aranges_size,
+ dwarf_aranges_section);
}
#endif
@@ -3584,15 +3615,20 @@ make_cleanup_free_die_list (struct die_info *dies)
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))
{
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 5eaeed0..b96d6e7 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -591,8 +591,7 @@ elf_symfile_read (struct objfile *objfile, int mainline)
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));
}
diff --git a/gdb/gdb-stabs.h b/gdb/gdb-stabs.h
index d2da2d1..abe2d33 100644
--- a/gdb/gdb-stabs.h
+++ b/gdb/gdb-stabs.h
@@ -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 */
diff --git a/gdb/stabsread.h b/gdb/stabsread.h
index 9f15642..62fd776 100644
--- a/gdb/stabsread.h
+++ b/gdb/stabsread.h
@@ -181,7 +181,7 @@ extern void process_one_symbol (int, int, CORE_ADDR, char *,
extern void elfstab_build_psymtabs (struct objfile *objfile,
int mainline,
- file_ptr staboff, unsigned int stabsize,
+ asection *stabsect,
file_ptr stabstroffset,
unsigned int stabstrsize);
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 81e1f74..95da6f1 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -23,6 +23,7 @@
Boston, MA 02111-1307, USA. */
#include "defs.h"
+#include "bfdlink.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "gdbcore.h"
@@ -3562,6 +3563,45 @@ simple_overlay_update (struct obj_section *osect)
}
}
+/* Set the output sections and output offsets for section SECTP in
+ ABFD. The relocation code in BFD will read these offsets, so we
+ need to be sure they're initialized. We map each section to itself,
+ with no offset; this means that SECTP->vma will be honored. */
+
+static void
+symfile_dummy_outputs (bfd *abfd, asection *sectp, void *dummy)
+{
+ sectp->output_section = sectp;
+ sectp->output_offset = 0;
+}
+
+/* Relocate the contents of a debug section SECTP in ABFD. The
+ contents are stored in BUF if it is non-NULL, or returned in a
+ malloc'd buffer otherwise.
+
+ For some platforms and debug info formats, shared libraries contain
+ relocations against the debug sections (particularly for DWARF-2;
+ one affected platform is PowerPC GNU/Linux, although it depends on
+ the version of the linker in use). Also, ELF object files naturally
+ have unresolved relocations for their debug sections. We need to apply
+ the relocations in order to get the locations of symbols correct. */
+
+bfd_byte *
+symfile_relocate_debug_section (bfd *abfd, asection *sectp, bfd_byte *buf)
+{
+ /* 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;
+
+ /* We will handle section offsets properly elsewhere, so relocate as if
+ all sections begin at 0. */
+ bfd_map_over_sections (abfd, symfile_dummy_outputs, NULL);
+
+ return bfd_simple_get_relocated_section_contents (abfd, sectp, buf);
+}
void
_initialize_symfile (void)
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 060eb4c..2671463 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -1,6 +1,6 @@
/* Definitions for reading symbol files into GDB.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001
+ 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
This file is part of GDB.
@@ -300,6 +300,9 @@ extern void symbol_file_add_main (char *args, int from_tty);
/* 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