From 2670f34d21cbd859050111686f945b73f005a70d Mon Sep 17 00:00:00 2001 From: John Gilmore Date: Sat, 4 Jul 1992 13:59:03 +0000 Subject: [PATCH] Relocate symbols using an array of section_offsets, rather than a single `addr' or `offset'. This makes Solaris-2 support work, and permits better VxWorks (and maybe xcoff) support later. See ChangeLog. --- gdb/ChangeLog | 69 ++++++++++++ gdb/Makefile.in | 1 + gdb/buildsym.h | 8 +- gdb/dwarfread.c | 21 ++-- gdb/elfread.c | 262 +++++++++++++++++++++++++++++++++++++++++---- gdb/gdb-stabs.h | 86 +++++++++++++++ gdb/partial-stab.h | 40 ++++--- gdb/symmisc.c | 11 +- gdb/symtab.h | 24 ++++- gdb/xcoffread.c | 33 +++++- 10 files changed, 500 insertions(+), 55 deletions(-) create mode 100644 gdb/gdb-stabs.h diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9f07240d582..60829d853ef 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,72 @@ +Sat Jul 4 03:43:38 1992 John Gilmore (gnu at cygnus.com) + + Relocate symbols using an array of section_offsets, rather than a + single `addr' or `offset'. This makes Solaris-2 support work, and + permits better VxWorks (and maybe xcoff) support later. + + * symtab.h (struct section_offsets): New structure for keeping + a set of offsets, rather than a single one. + (struct objfile): Replace addr with section_offsets member. + * symfile.h: Add sym_offsets to struct sym_fns. Conforming changes. + * gdb-stabs.h: New include file with `symbol type specific' + parameters for psymtabs and objfiles. + * Makefile.in (HFILES): Add gdb-stabs.h. + * buildsym.h (start_psymtab, process_one_symbol): Fix prototypes. + * coffread.c: Conforming changes. Fake offset array always 0. + * dbxread.c: Conforming changes. + (struct dbx_symfile_info): Move to gdb-stabs.h. + (start_psymtab): Call elfstab_offset_sections to calculate good + offsets for this source file, based on the ELF symbol table info. + (read_ofile_symtab): Yank N_CATCH, which is dead. + (process_one_symbol, N_CATCH): Yank. + (", N_FUN, N_FNAME, N_FN, N_FN_SEQ, N_SO, N_SOL, N_ENTRY): + Relocate with SECT_OFF_TEXT. + (", N_STSYM, N_LCSYM, N_ROSYM): Grope around in the stab string + to distinguish relocatable from absolute symbols. Then, if not + absolute, do: + (", N_STSYM, N_DSLINE): SECT_OFF_DATA. + (", N_LCSYM, N_BSLINE): SECT_OFF_BSS. + (", N_ROSYM): SECT_OFF_RODATA. + (elfstab_build_psymtabs): Caller has allocated dbx_symfile_info. + (dbx_symfile_offsets): Add to translate addr to offset. + * dwarfread.c: Conforming changes. Single offset currently used. + * elfread.c: Add various complaints about elf/stab stuff. + #include gdb-stabs.h. Conforming changes, using a single offset. + (elf_symtab_read): Record info from BSF_FILE symbols, and local + variables called "Bbss.bss", "Ddata.data", and "Drodata.rodata", + for later use in building psymtabs. + (elf_symfile_read): Allocate dbx_symfile_info here, to keep + the info collected in elf_symtab_read. Cleanup calls free_elfinfo. + (free_elfinfo): New fn, frees all chained stab_section_infos + in an objfile, and zaps the start-of-chain pointer. + (elfstab_offset_sections): New fn, looks in stab_section_info + chain to determine section bases to relocate a psymtab's worth + of symbols, as they are being read. + * mipsread.c: Conforming changes. Stabs-reading will relocate + using one offset. MIPS-reading will not relocate at all. + * partial-stab.h: Relocate different symbol types using different + offsets from section_offsets. + * symfile.c: Conforming changes. + (find_lowest_section): Unused function to use later + to free us from the Tyranny of the Text Section. + (syms_from_objfile): Translate absolute arg ADDR to offsets used + in all lower layers of symbol reading. Call format-specific + sym_offsets function to initialize offsets for high speed symbol + reading. + (symbol_file_add): Call reinit_frame_cache so callers don't have to. + (symbol_file_command, add_symbol_file_command): Callers changed. + * symmisc.c (dump_psymtab): Print new relocation parameters. + * xcoffread.c: Corresponding changes. + + * buildsym.c: Tidy innerblock_complaint and blockvector_complaint. + * main.c (main): Read the $HOME/.gdbinit file before processing + the argv arguments (e.g. reading symbol files or core + files). This allows global parameters to be set, which will apply + during the symbol reading. The ./.gdbinit is still read after + argv processing. + * symtab.c (list_symbols): `i variables' shouldn't show enum values. + * xcoffexec.c: Clean up quote inside comment. + Fri Jul 3 20:18:26 1992 Fred Fish (fnf@cygnus.com) * breakpoint.c, buildsym.c, c-exp.y, coffread.c, command.c, diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 90ca97569ff..3b76f6a9c8b 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -238,6 +238,7 @@ SFILES_KGDB = $(SFILES) stuff.c kdb-start.c # Header files that are not named in config/* Makefile fragments go here. HFILES= breakpoint.h buildsym.h call-cmds.h command.h defs.h demangle.h \ environ.h expression.h frame.h gdbcmd.h gdbcore.h gdbtypes.h \ + gdb-stabs.h \ ieee-float.h inferior.h minimon.h objfiles.h partial-stab.h \ serial.h signals.h symfile.h symtab.h solib.h xcoffsolib.h \ target.h terminal.h tm-68k.h tm-i960.h tm-sunos.h tm-sysv4.h \ diff --git a/gdb/buildsym.h b/gdb/buildsym.h index 8c660f3b9ef..21087ac3972 100644 --- a/gdb/buildsym.h +++ b/gdb/buildsym.h @@ -338,7 +338,8 @@ extern struct symbol * define_symbol PARAMS ((unsigned int, char *, int, int, struct objfile *)); extern struct partial_symtab * -start_psymtab PARAMS ((struct objfile *, CORE_ADDR, char *, CORE_ADDR, int, +start_psymtab PARAMS ((struct objfile *, struct section_offsets *, char *, + CORE_ADDR, int, struct partial_symbol *, struct partial_symbol *)); extern void @@ -346,9 +347,8 @@ end_psymtab PARAMS ((struct partial_symtab *, char **, int, int, CORE_ADDR, struct partial_symtab **, int)); extern void -process_one_symbol PARAMS ((int, int, CORE_ADDR, char *, int, - struct objfile *)); - +process_one_symbol PARAMS ((int, int, CORE_ADDR, char *, + struct section_offsets *, struct objfile *)); extern int hashname PARAMS ((char *)); diff --git a/gdb/dwarfread.c b/gdb/dwarfread.c index b825143ee8c..0b022883143 100644 --- a/gdb/dwarfread.c +++ b/gdb/dwarfread.c @@ -206,8 +206,14 @@ static char *lnbase; /* Base pointer to line section */ static int isreg; /* Kludge to identify register variables */ static int offreg; /* Kludge to identify basereg references */ +/* This value is added to each symbol value. FIXME: Generalize to + the section_offsets structure used by dbxread. */ static CORE_ADDR baseaddr; /* Add to each symbol value */ +/* The section offsets used in the current psymtab or symtab. FIXME, + only used to pass one value (baseaddr) at the moment. */ +static struct section_offsets *base_section_offsets; + /* Each partial symbol table entry contains a pointer to private data for the read_symtab() function to use when expanding a partial symbol table entry to a full symbol table entry. For DWARF debugging info, this data is @@ -412,7 +418,8 @@ GLOBAL FUNCTION SYNOPSIS - void dwarf_build_psymtabs (int desc, char *filename, CORE_ADDR addr, + void dwarf_build_psymtabs (int desc, char *filename, + struct section_offsets *section_offsets, int mainline, unsigned int dbfoff, unsigned int dbsize, unsigned int lnoffset, unsigned int lnsize, struct objfile *objfile) @@ -437,11 +444,11 @@ RETURNS */ void -dwarf_build_psymtabs (desc, filename, addr, mainline, dbfoff, dbsize, +dwarf_build_psymtabs (desc, filename, section_offsets, mainline, dbfoff, dbsize, lnoffset, lnsize, objfile) int desc; char *filename; - CORE_ADDR addr; + struct section_offsets *section_offsets; int mainline; unsigned int dbfoff; unsigned int dbsize; @@ -474,7 +481,8 @@ dwarf_build_psymtabs (desc, filename, addr, mainline, dbfoff, dbsize, /* Save the relocation factor where everybody can see it. */ - baseaddr = addr; + base_section_offsets = section_offsets; + baseaddr = ANOFFSET (section_offsets, 0); /* Follow the compilation unit sibling chain, building a partial symbol table entry for each one. Save enough information about each compilation @@ -1943,7 +1951,8 @@ read_ofile_symtab (pst) dbbase = xmalloc (DBLENGTH(pst)); dbroff = DBROFF(pst); foffset = DBFOFF(pst) + dbroff; - baseaddr = pst -> addr; + base_section_offsets = pst->section_offsets; + baseaddr = ANOFFSET (pst->section_offsets, 0); if (bfd_seek (abfd, foffset, 0) || (bfd_read (dbbase, DBLENGTH(pst), 1, abfd) != DBLENGTH(pst))) { @@ -2454,7 +2463,7 @@ scan_compilation_units (filename, thisdie, enddie, dbfoff, lnoffset, objfile) /* First allocate a new partial symbol table structure */ - pst = start_psymtab_common (objfile, baseaddr, di.at_name, + pst = start_psymtab_common (objfile, base_section_offsets, di.at_name, di.at_low_pc, objfile -> global_psymbols.next, objfile -> static_psymbols.next); diff --git a/gdb/elfread.c b/gdb/elfread.c index a89e556c0bc..7075f0f5b59 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -43,8 +43,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "objfiles.h" #include "buildsym.h" +#include /* For off_t for gdb-stabs.h */ +#include "gdb-stabs.h" + #define STREQ(a,b) (strcmp((a),(b))==0) +/* The struct elfinfo is available only during ELF symbol table and + psymtab reading. It is destroyed at the complation of psymtab-reading. + It's local to elf_symfile_read. */ + struct elfinfo { unsigned int dboffset; /* Offset to dwarf debug section */ unsigned int dbsize; /* Size of dwarf debug section */ @@ -54,6 +61,20 @@ struct elfinfo { asection *stabindexsect; /* Section pointer for .stab.index section */ }; +/* Various things we might complain about... */ + +struct complaint section_info_complaint = + {"elf/stab section information %s without a preceding file symbol", 0, 0}; + +struct complaint section_info_dup_complaint = + {"duplicated elf/stab section information for %s", 0, 0}; + +struct complaint stab_info_mismatch_complaint = + {"elf/stab section information missing for %s", 0, 0}; + +struct complaint stab_info_questionable_complaint = + {"elf/stab section information questionable for %s", 0, 0}; + static void elf_symfile_init PARAMS ((struct objfile *)); @@ -61,7 +82,7 @@ static void elf_new_init PARAMS ((struct objfile *)); static void -elf_symfile_read PARAMS ((struct objfile *, CORE_ADDR, int)); +elf_symfile_read PARAMS ((struct objfile *, struct section_offsets *, int)); static void elf_symfile_finish PARAMS ((struct objfile *)); @@ -69,6 +90,12 @@ elf_symfile_finish PARAMS ((struct objfile *)); static void elf_symtab_read PARAMS ((bfd *, CORE_ADDR, struct objfile *)); +static void +free_elfinfo PARAMS ((PTR)); + +static struct section_offsets * +elf_symfile_offsets PARAMS ((struct objfile *, CORE_ADDR)); + #if 0 static void record_minimal_symbol PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type, @@ -221,6 +248,12 @@ DESCRIPTION or not (may be shared library for example), add all the global function and data symbols to the minimal symbol table. + In stabs-in-ELF, as implemented by Sun, there are some local symbols + defined in the ELF symbol table, which can be used to locate + the beginnings of sections from each ".o" file that was linked to + form the executable objfile. We gather any such info and record it + in data structures hung off the objfile's private data. + */ static void @@ -234,9 +267,18 @@ elf_symtab_read (abfd, addr, objfile) asymbol **symbol_table; unsigned int number_of_symbols; unsigned int i; + int index; struct cleanup *back_to; CORE_ADDR symaddr; enum minimal_symbol_type ms_type; + /* If sectinfo is nonzero, it contains section info that should end up + filed in the objfile. */ + struct stab_section_info *sectinfo = 0; + /* If filesym is nonzero, it points to a file symbol, but we haven't + seen any section info for it yet. */ + asymbol *filesym = 0; + struct dbx_symfile_info *dbx = (struct dbx_symfile_info *) + objfile->sym_private; storage_needed = get_symtab_upper_bound (abfd); @@ -248,7 +290,7 @@ elf_symtab_read (abfd, addr, objfile) for (i = 0; i < number_of_symbols; i++) { - sym = *symbol_table++; + sym = symbol_table[i]; /* Select global/weak symbols that are defined in a specific section. Note that bfd now puts abs symbols in their own section, so all symbols we are interested in will have a section. */ @@ -258,9 +300,8 @@ elf_symtab_read (abfd, addr, objfile) symaddr = sym -> value; /* Relocate all non-absolute symbols by base address. */ if (sym -> section != &bfd_abs_section) - { - symaddr += addr; - } + symaddr += addr; + /* For non-absolute symbols, use the type of the section they are relative to, to intuit text/data. Bfd provides no way of figuring this out for absolute symbols. */ @@ -285,6 +326,69 @@ elf_symtab_read (abfd, addr, objfile) record_minimal_symbol_and_info ((char *) sym -> name, symaddr, ms_type, sym->udata, objfile); } + + /* See if this is a debugging symbol that helps Solaris + stabs-in-elf debugging. */ + + else if (sym->flags & BSF_FILE) + { + /* Chain any old one onto the objfile; remember new sym. */ + if (sectinfo) + { + sectinfo->next = dbx->stab_section_info; + dbx->stab_section_info = sectinfo; + sectinfo = 0; + } + filesym = sym; + } + else if ((sym->flags & BSF_LOCAL) && + (sym->section) && + (sym->section->flags & SEC_DATA) && + (sym->name)) + { + /* Named Local variable in a Data section. Check its name. */ + index = -1; + switch (sym->name[1]) + { + case 'b': + if (!strcmp ("Bbss.bss", sym->name)) + index = SECT_OFF_BSS; + break; + case 'd': + if (!strcmp ("Ddata.data", sym->name)) + index = SECT_OFF_DATA; + break; + case 'r': + if (!strcmp ("Drodata.rodata", sym->name)) + index = SECT_OFF_RODATA; + break; + } + if (index > 0) + { + /* We have some new info. Allocate a sectinfo, if + needed, and fill it in. */ + if (!sectinfo) + { + sectinfo = (struct stab_section_info *) + xmmalloc (objfile -> md, + sizeof (*sectinfo)); + memset ((PTR) sectinfo, 0, sizeof (*sectinfo)); + if (!filesym) + complain (§ion_info_complaint, (char *)sym->name); + else + sectinfo->filename = (char *)filesym->name; + } + if (sectinfo->sections[index]) + complain (§ion_info_dup_complaint, + (char *)sectinfo->filename); + + symaddr = sym -> value; + /* Relocate all non-absolute symbols by base address. */ + if (sym -> section != &bfd_abs_section) + symaddr += addr; + sectinfo->sections[index] = symaddr; + } + } } do_cleanups (back_to); } @@ -294,8 +398,9 @@ elf_symtab_read (abfd, addr, objfile) We have been initialized by a call to elf_symfile_init, which currently does nothing. - ADDR is the address relative to which the symbols in it are (e.g. - the base address of the text segment). + SECTION_OFFSETS is a set of offsets to apply to relocate the symbols + in each section. We simplify it down to a single offset for all + symbols. FIXME. MAINLINE is true if we are reading the main symbol table (as opposed to a shared lib or dynamically loaded file). @@ -321,13 +426,14 @@ elf_symtab_read (abfd, addr, objfile) capability even for files compiled without -g. */ static void -elf_symfile_read (objfile, addr, mainline) +elf_symfile_read (objfile, section_offsets, mainline) struct objfile *objfile; - CORE_ADDR addr; + struct section_offsets *section_offsets; int mainline; { bfd *abfd = objfile->obfd; struct elfinfo ei; + struct dbx_symfile_info *dbx; struct cleanup *back_to; asection *text_sect; CORE_ADDR offset; @@ -335,29 +441,32 @@ elf_symfile_read (objfile, addr, mainline) init_minimal_symbol_collection (); back_to = make_cleanup (discard_minimal_symbols, 0); - /* Compute the amount to relocate all symbols by. The value passed in - as ADDR is typically either the actual address of the text section, - or a user specified address. By subtracting off the actual address - of the text section, we can compute the relocation amount. */ + memset ((char *) &ei, 0, sizeof (ei)); - text_sect = bfd_get_section_by_name (objfile -> obfd, ".text"); - offset = addr - bfd_section_vma (objfile -> obfd, text_sect); + /* Allocate struct to keep track of the symfile */ + objfile->sym_private = (PTR) + xmmalloc (objfile -> md, sizeof (struct dbx_symfile_info)); + memset ((char *) objfile->sym_private, 0, sizeof (struct dbx_symfile_info)); + make_cleanup (free_elfinfo, (PTR) objfile); - /* Process the normal ELF symbol table first. */ + /* Process the normal ELF symbol table first. This may write some + chain of info into the dbx_symfile_info in objfile->sym_private, + which can later be used by elfstab_offset_sections. */ + /* FIXME, should take a section_offsets param, not just an offset. */ + offset = ANOFFSET (section_offsets, 0); elf_symtab_read (abfd, offset, objfile); /* Now process debugging information, which is contained in special ELF sections. We first have to find them... */ - memset ((char *) &ei, 0, sizeof (ei)); bfd_map_over_sections (abfd, elf_locate_sections, (PTR) &ei); if (ei.dboffset && ei.lnoffset) { /* DWARF sections */ dwarf_build_psymtabs (fileno ((FILE *)(abfd -> iostream)), bfd_get_filename (abfd), - offset, mainline, + section_offsets, mainline, ei.dboffset, ei.dbsize, ei.lnoffset, ei.lnsize, objfile); } @@ -376,7 +485,7 @@ elf_symfile_read (objfile, addr, mainline) elf_sect = bfd_elf_find_section (abfd, ".stabstr"); if (elf_sect) elfstab_build_psymtabs (objfile, - addr, /* We really pass the text seg addr, not the offset, here. */ + section_offsets, mainline, ei.stabsect->filepos, /* .stab offset */ bfd_get_section_size_before_reloc (ei.stabsect),/* .stab size */ @@ -399,6 +508,30 @@ elf_symfile_read (objfile, addr, mainline) do_cleanups (back_to); } +/* This cleans up the objfile's sym_private pointer, and the chain of + stab_section_info's, that might be dangling from it. */ + +static void +free_elfinfo (objp) + PTR objp; +{ + struct objfile *objfile = (struct objfile *)objp; + struct dbx_symfile_info *dbxinfo = (struct dbx_symfile_info *) + objfile->sym_private; + struct stab_section_info *ssi, *nssi; + + ssi = dbxinfo->stab_section_info; + while (ssi) + { + nssi = ssi->next; + mfree (objfile->md, ssi); + ssi = nssi; + } + + dbxinfo->stab_section_info = 0; /* Just say No mo info about this. */ +} + + /* Initialize anything that needs initializing when a completely new symbol file is specified (not just adding some symbols from another file, e.g. a shared library). @@ -442,6 +575,96 @@ elf_symfile_init (ignore) { } +/* ELF specific parsing routine for section offsets. + + Plain and simple for now. */ + +static +struct section_offsets * +elf_symfile_offsets (objfile, addr) + struct objfile *objfile; + CORE_ADDR addr; +{ + struct section_offsets *section_offsets; + int i; + + section_offsets = (struct section_offsets *) + obstack_alloc (&objfile -> psymbol_obstack, + sizeof (struct section_offsets) + + sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1)); + + for (i = 0; i < SECT_OFF_MAX; i++) + ANOFFSET (section_offsets, i) = addr; + + return section_offsets; +} + +/* When handling an ELF file that contains Sun STABS debug info, + some of the debug info is relative to the particular chunk of the + section that was generated in its individual .o file. E.g. + offsets to static variables are relative to the start of the data + segment *for that module before linking*. This information is + painfully squirreled away in the ELF symbol table as local symbols + with wierd names. Go get 'em when needed. */ + +void +elfstab_offset_sections (objfile, pst) + struct objfile *objfile; + struct partial_symtab *pst; +{ + char *filename = pst->filename; + struct dbx_symfile_info *dbx = (struct dbx_symfile_info *) + objfile->sym_private; + struct stab_section_info *maybe = dbx->stab_section_info; + struct stab_section_info *questionable = 0; + int i; + char *p; + + /* The ELF symbol info doesn't include path names, so strip the path + (if any) from the psymtab filename. */ + while (0 != (p = strchr (filename, '/'))) + filename = p+1; + + /* FIXME: This linear search could speed up significantly + if it was chained in the right order to match how we search it, + and if we unchained when we found a match. */ + for (; maybe; maybe = maybe->next) + { + if (filename[0] == maybe->filename[0] + && !strcmp (filename, maybe->filename)) + { + /* We found a match. But there might be several source files + (from different directories) with the same name. */ + if (0 == maybe->found) + break; + questionable = maybe; /* Might use it later. */ + } + } + + if (maybe == 0 && questionable != 0) + { + complain (&stab_info_questionable_complaint, filename); + maybe = questionable; + } + + if (maybe) + { + /* Found it! Allocate a new psymtab struct, and fill it in. */ + maybe->found++; + pst->section_offsets = (struct section_offsets *) + obstack_alloc (&objfile -> psymbol_obstack, + sizeof (struct section_offsets) + + sizeof (pst->section_offsets->offsets) * (SECT_OFF_MAX-1)); + + for (i = 0; i < SECT_OFF_MAX; i++) + ANOFFSET (pst->section_offsets, i) = maybe->sections[i]; + return; + } + + /* We were unable to find any offsets for this file. Complain. */ + if (dbx->stab_section_info) /* If there *is* any info, */ + complain (&stab_info_mismatch_complaint, filename); +} /* Register that we are able to handle ELF object file formats and DWARF debugging formats. @@ -467,6 +690,7 @@ static struct sym_fns elf_sym_fns = elf_symfile_init, /* sym_init: read initial info, setup for sym_read() */ elf_symfile_read, /* sym_read: read a symbol file into symtab */ elf_symfile_finish, /* sym_finish: finished with file, cleanup */ + elf_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */ NULL /* next: pointer to next struct sym_fns */ }; diff --git a/gdb/gdb-stabs.h b/gdb/gdb-stabs.h new file mode 100644 index 00000000000..28ee98d28a5 --- /dev/null +++ b/gdb/gdb-stabs.h @@ -0,0 +1,86 @@ +/* Definitions for symbol-reading containing "stabs", for GDB. + Copyright 1992 Free Software Foundation, Inc. + Contributed by Cygnus Support. Written by John Gilmore. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This file exists to hold the common definitions required of all the + symbol-readers that end up using stabs. The common use of these + `symbol-type-specific' customizations of the generic data structures + makes the stabs-oriented symbol readers able to call each others' + functions as required. */ + +#if !defined (GDBSTABS_H) +#define GDBSTABS_H + +/* Offsets in the psymtab's section_offsets array for various kinds of + stabs symbols. Every psymtab built from stabs will have these offsets + filled in by these guidelines, so that when actually reading symbols, the + proper offset can simply be selected and added to the symbol value. */ + +#define SECT_OFF_TEXT 0 +#define SECT_OFF_DATA 1 +#define SECT_OFF_BSS 2 +#define SECT_OFF_RODATA 3 +#define SECT_OFF_MAX 4 /* Count of possible values */ + +/* The stab_section_info chain remembers info from the ELF symbol table, + while psymtabs are being built for the other symbol tables in the + objfile. It is destroyed at the complation of psymtab-reading. + Any info that was used from it has been copied into psymtabs. */ + +struct stab_section_info { + char *filename; + CORE_ADDR sections[SECT_OFF_MAX]; + struct stab_section_info *next; + int found; /* Count of times it's found in searching */ +}; + +/* Information is passed among various dbxread routines for accessing + symbol files. A pointer to this structure is kept in the sym_private + field of the objfile struct. */ + +struct dbx_symfile_info { + asection *text_sect; /* Text section accessor */ + int symcount; /* How many symbols are there in the file */ + char *stringtab; /* The actual string table */ + int stringtab_size; /* Its size */ + off_t symtab_offset; /* Offset in file to symbol table */ + int symbol_size; /* Bytes in a single symbol */ + struct stab_section_info *stab_section_info; /* section starting points + of the original .o files before linking. */ +/* FIXME: HP kludges that shouldn't be here, probably. */ + int hp_symcount; + char *hp_stringtab; + int hp_stringtab_size; + off_t hp_symtab_offset; +}; + +#define DBX_SYMFILE_INFO(o) ((struct dbx_symfile_info *)((o)->sym_private)) +#define DBX_TEXT_SECT(o) (DBX_SYMFILE_INFO(o)->text_sect) +#define DBX_SYMCOUNT(o) (DBX_SYMFILE_INFO(o)->symcount) +#define DBX_STRINGTAB(o) (DBX_SYMFILE_INFO(o)->stringtab) +#define DBX_STRINGTAB_SIZE(o) (DBX_SYMFILE_INFO(o)->stringtab_size) +#define DBX_SYMTAB_OFFSET(o) (DBX_SYMFILE_INFO(o)->symtab_offset) +#define DBX_SYMBOL_SIZE(o) (DBX_SYMFILE_INFO(o)->symbol_size) +/* We don't use a macro for stab_section_info. */ +#define HP_SYMCOUNT(o) (DBX_SYMFILE_INFO(o)->hp_symcount) +#define HP_STRINGTAB(o) (DBX_SYMFILE_INFO(o)->hp_stringtab) +#define HP_STRINGTAB_SIZE(o) (DBX_SYMFILE_INFO(o)->hp_stringtab_size) +#define HP_SYMTAB_OFFSET(o) (DBX_SYMFILE_INFO(o)->hp_symtab_offset) + +#endif /* GDBSTABS_H */ diff --git a/gdb/partial-stab.h b/gdb/partial-stab.h index cd07a97cd79..a0ad20d1591 100644 --- a/gdb/partial-stab.h +++ b/gdb/partial-stab.h @@ -35,16 +35,23 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ case N_TEXT | N_EXT: case N_NBTEXT | N_EXT: + CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT); + goto record_it; + + case N_DATA | N_EXT: case N_NBDATA | N_EXT: + CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA); + goto record_it; + + case N_BSS | N_EXT: case N_NBBSS | N_EXT: - case N_SETV | N_EXT: + case N_SETV | N_EXT: /* FIXME, is this in BSS? */ + CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_BSS); + goto record_it; + case N_ABS | N_EXT: - case N_DATA | N_EXT: - case N_BSS | N_EXT: + record_it: #ifdef DBXREAD_ONLY - - CUR_SYMBOL_VALUE += addr; /* Relocate */ - SET_NAMESTRING(); bss_ext_symbol: @@ -66,7 +73,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ case N_FN_SEQ: case N_TEXT: #ifdef DBXREAD_ONLY - CUR_SYMBOL_VALUE += addr; /* Relocate */ + CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT); SET_NAMESTRING(); if ((namestring[0] == '-' && namestring[1] == 'l') || (namestring [(nsl = strlen (namestring)) - 1] == 'o' @@ -79,8 +86,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ { #ifndef hp9000s800 if (objfile -> ei.entry_point < CUR_SYMBOL_VALUE && - objfile -> ei.entry_point >= last_o_file_start && - addr == 0) /* FIXME nogood nomore */ + objfile -> ei.entry_point >= last_o_file_start) { objfile -> ei.entry_file_lowpc = last_o_file_start; objfile -> ei.entry_file_highpc = CUR_SYMBOL_VALUE; @@ -107,7 +113,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ case N_DATA: #ifdef DBXREAD_ONLY - CUR_SYMBOL_VALUE += addr; /* Relocate */ + CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA); SET_NAMESTRING (); /* Check for __DYNAMIC, which is used by Sun shared libraries. Record it even if it's local, not global, so we can find it. @@ -115,10 +121,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ if ((namestring[8] == 'C' && (strcmp ("__DYNAMIC", namestring) == 0)) || VTBL_PREFIX_P ((namestring+HASH_OFFSET))) { - /* Not really a function here, but... */ record_minimal_symbol (namestring, CUR_SYMBOL_VALUE, CUR_SYMBOL_TYPE, objfile); /* Always */ - } + } #endif /* DBXREAD_ONLY */ continue; @@ -202,7 +207,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ SET_NAMESTRING(); - valu += addr; /* Relocate */ + valu += ANOFFSET (section_offsets, SECT_OFF_TEXT); if (pst) { @@ -239,7 +244,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ tmp = dir_so_symnum; else tmp = symnum; - pst = START_PSYMTAB (objfile, addr, + pst = START_PSYMTAB (objfile, section_offsets, namestring, valu, tmp * symbol_size, objfile -> global_psymbols.next, @@ -320,6 +325,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ case N_LSYM: /* Typedef or automatic variable. */ case N_STSYM: /* Data seg var -- static */ case N_LCSYM: /* BSS " */ + case N_ROSYM: /* Read-only data seg var -- static. */ case N_NBSTS: /* Gould nobase. */ case N_NBLCS: /* symbols. */ @@ -430,7 +436,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ case N_FUN: case N_GSYM: /* Global (extern) variable; can be - data or bss (sigh). */ + data or bss (sigh FIXME). */ /* Following may probably be ignored; I'll leave them here for now (until I do Pascal and Modula 2 extensions). */ @@ -463,13 +469,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ objfile->static_psymbols, CUR_SYMBOL_VALUE); continue; case 'S': - CUR_SYMBOL_VALUE += addr; /* Relocate */ + CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA); ADD_PSYMBOL_ADDR_TO_LIST (namestring, p - namestring, VAR_NAMESPACE, LOC_STATIC, objfile->static_psymbols, CUR_SYMBOL_VALUE); continue; case 'G': - CUR_SYMBOL_VALUE += addr; /* Relocate */ + CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA); /* The addresses in these entries are reported to be wrong. See the code that reads 'G's for symtabs. */ ADD_PSYMBOL_ADDR_TO_LIST (namestring, p - namestring, diff --git a/gdb/symmisc.c b/gdb/symmisc.c index b460734fa86..73d72e8dcf9 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -264,8 +264,15 @@ dump_psymtab (objfile, psymtab, outfile) " Full symtab was read (at 0x%x by function at 0x%x)\n", psymtab -> symtab, psymtab -> read_symtab); } - fprintf_filtered (outfile, " Relocate symbols by 0x%x\n", - psymtab -> addr); + + /* FIXME, we need to be able to print the relocation stuff. */ + /* This prints some garbage for anything but stabs right now. FIXME. */ + fprintf_filtered (outfile, " Relocate symbols by 0x%x, 0x%x, 0x%x, 0x%x.\n", + ANOFFSET (psymtab->section_offsets, 0), + ANOFFSET (psymtab->section_offsets, 1), + ANOFFSET (psymtab->section_offsets, 2), + ANOFFSET (psymtab->section_offsets, 3)); + fprintf_filtered (outfile, " Symbols cover text addresses 0x%x-0x%x\n", psymtab -> textlow, psymtab -> texthigh); fprintf_filtered (outfile, " Depends on %d other partial symtabs.\n", diff --git a/gdb/symtab.h b/gdb/symtab.h index 5909d5f26a0..6b9c402828b 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -334,6 +334,23 @@ struct source struct linetable contents; }; +/* How to relocate the symbols from each section in a symbol file. + Each struct contains an array of offsets. + The ordering and meaning of the offsets is file-type-dependent; + typically it is indexed by section numbers or symbol types or + something like that. + + To give us flexibility in changing the internal representation + of these offsets, the ANOFFSET macro must be used to insert and + extract offset values in the struct. */ + +struct section_offsets + { + CORE_ADDR offsets[1]; /* As many as needed. */ + }; + +#define ANOFFSET(secoff, whichone) (secoff->offsets[whichone]) + /* Each source file is represented by a struct symtab. These objects are chained through the `next' field. */ @@ -404,10 +421,9 @@ struct partial_symtab /* Information about the object file from which symbols should be read. */ struct objfile *objfile; - /* Address relative to which the symbols in this file are. Need to - relocate by this amount when reading in symbols from the symbol - file. */ - CORE_ADDR addr; + /* Set of relocation offsets to apply to each section. */ + struct section_offsets *section_offsets; + /* Range of text addresses covered by this file; texthigh is the beginning of the next section. */ CORE_ADDR textlow, texthigh; diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c index 429fcc510b3..ddbf02c4ca0 100644 --- a/gdb/xcoffread.c +++ b/gdb/xcoffread.c @@ -45,6 +45,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "symfile.h" #include "objfiles.h" #include "buildsym.h" +#include "gdb-stabs.h" #include "coff/internal.h" /* FIXME, internal data from BFD */ #include "libcoff.h" /* FIXME, internal data from BFD */ @@ -182,11 +183,14 @@ static void aixcoff_new_init PARAMS ((struct objfile *)); static void -aixcoff_symfile_read PARAMS ((struct objfile *, CORE_ADDR, int)); +aixcoff_symfile_read PARAMS ((struct objfile *, struct section_offset *, int)); static void aixcoff_symfile_finish PARAMS ((struct objfile *)); +static struct section_offset * +aixcoff_symfile_offsets PARAMS ((struct objfile *, CORE_ADDR)); + static int init_lineno PARAMS ((bfd *, long, int)); @@ -2238,9 +2242,9 @@ free_debugsection() /* aixcoff version of symbol file read. */ static void -aixcoff_symfile_read (objfile, addr, mainline) +aixcoff_symfile_read (objfile, section_offset, mainline) struct objfile *objfile; - CORE_ADDR addr; + struct section_offset *section_offset; int mainline; { int num_symbols; /* # of symbols */ @@ -2320,6 +2324,28 @@ aixcoff_symfile_read (objfile, addr, mainline) select_source_symtab (0); } +/* XCOFF-specific parsing routine for section offsets. + Plain and simple for now. */ + +static +struct section_offsets * +aixcoff_symfile_offsets (objfile, addr) + struct objfile *objfile; + CORE_ADDR addr; +{ + struct section_offsets *section_offsets; + int i; + + section_offsets = (struct section_offsets *) + obstack_alloc (&objfile -> psymbol_obstack, + sizeof (struct section_offsets) + + sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1)); + + for (i = 0; i < SECT_OFF_MAX; i++) + ANOFFSET (section_offsets, i) = addr; + + return section_offsets; +} /* Register our ability to parse symbols for aixcoff BFD files. */ static struct sym_fns aixcoff_sym_fns = @@ -2330,6 +2356,7 @@ static struct sym_fns aixcoff_sym_fns = aixcoff_symfile_init, /* sym_init: read initial info, setup for sym_read() */ aixcoff_symfile_read, /* sym_read: read a symbol file into symtab */ aixcoff_symfile_finish, /* sym_finish: finished with file, cleanup */ + aixcoff_symfile_offsets, /* sym_offsets: xlate offsets ext->int form */ NULL /* next: pointer to next struct sym_fns */ }; -- 2.30.2