-/* Read AIXcoff symbol tables and convert to internal format, for GDB.
- Copyright (C) 1986-1991 Free Software Foundation, Inc.
+/* Read AIX xcoff symbol tables and convert to internal format, for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993
+ Free Software Foundation, Inc.
Derived from coffread.c, dbxread.c, and a lot of hacking.
Contributed by IBM Corporation.
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+/* Native only: Need struct tbtable in <sys/debug.h> from host, and
+ need xcoff_add_toc_to_loadinfo in rs6000-tdep.c from target.
+ need xcoff_init_loadinfo ditto.
+ However, if you grab <sys/debug.h> and make it available on your
+ host, and define FAKING_RS6000, then this code will compile. */
+
#include "defs.h"
#include "bfd.h"
-#ifdef IBM6000_HOST
-/* Native only: Need struct tbtable in <sys/debug.h>. */
-
-/* AIX COFF names have a preceeding dot `.' */
-#define NAMES_HAVE_DOT 1
-
#include <sys/types.h>
#include <fcntl.h>
#include <ctype.h>
#include "symfile.h"
#include "objfiles.h"
#include "buildsym.h"
+#include "stabsread.h"
+#include "complaints.h"
#include "coff/internal.h" /* FIXME, internal data from BFD */
#include "libcoff.h" /* FIXME, internal data from BFD */
#include "coff/rs6000.h" /* FIXME, raw file-format guts of xcoff */
-
-/* Define this if you want gdb use the old xcoff symbol processing. This
- way it won't use common `define_symbol()' function and Sun dbx stab
- string grammar. And likely it won't be able to do G++ debugging. */
-
-/* #define NO_DEFINE_SYMBOL 1 */
+/* For interface with stabsread.c. */
+#include "aout/stab_gnu.h"
/* Define this if you want gdb to ignore typdef stabs. This was needed for
one of Transarc, to reduce the size of the symbol table. Types won't be
recognized, but tag names will be. */
-/* #define NO_TYPES 1 */
+/* #define NO_TYPEDEFS 1 */
/* Simplified internal version of coff symbol table information */
int c_symnum; /* symbol number of this entry */
int c_nsyms; /* 0 if syment only, 1 if syment + auxent */
long c_value;
- int c_sclass;
+ unsigned char c_sclass;
int c_secnum;
unsigned int c_type;
};
/* pointer to the a.out symbol table */
static char *symtbl;
+/* Number of symbols in symtbl. */
+static int symtbl_num_syms;
+
/* initial symbol-table-debug-string vector length */
#define INITIAL_STABVECTOR_LENGTH 40
-struct pending_stabs *global_stabs;
-
-
/* Nonzero if within a function (so symbols should be local,
if nothing says specifically). */
static unsigned local_symesz;
-
-/* coff_symfile_init()
- is the coff-specific initialization routine for reading symbols.
- It is passed a struct sym_fns which contains, among other things,
- the BFD for the file whose symbols are being read, and a slot for
- a pointer to "private data" which we fill with cookies and other
- treats for coff_symfile_read().
-
- We will only be called if this is a COFF or COFF-like file.
- BFD handles figuring out the format of the file, and code in symtab.c
- uses BFD's determination to vector to us.
-
- The ultimate result is a new symtab (or, FIXME, eventually a psymtab). */
-
struct coff_symfile_info {
file_ptr min_lineno_offset; /* Where in file lowest line#s are */
file_ptr max_lineno_offset; /* 1+last byte of line#s in file */
};
+static struct complaint rsym_complaint =
+ {"Non-stab C_RSYM `%s' needs special handling", 0, 0};
+
+static struct complaint storclass_complaint =
+ {"Unexpected storage class: %d", 0, 0};
+
+static struct complaint bf_notfound_complaint =
+ {"line numbers off, `.bf' symbol not found", 0, 0};
static void
enter_line_range PARAMS ((struct subfile *, unsigned, unsigned,
init_debugsection PARAMS ((bfd *));
static int
-init_stringtab PARAMS ((bfd *, long, struct objfile *));
+init_stringtab PARAMS ((bfd *, file_ptr, struct objfile *));
static void
-aixcoff_symfile_init PARAMS ((struct objfile *));
+xcoff_symfile_init PARAMS ((struct objfile *));
static void
-aixcoff_new_init PARAMS ((struct objfile *));
+xcoff_new_init PARAMS ((struct objfile *));
+
+#ifdef __STDC__
+struct section_offset;
+#endif
static void
-aixcoff_symfile_read PARAMS ((struct sym_fns *, CORE_ADDR, int));
+xcoff_symfile_read PARAMS ((struct objfile *, struct section_offset *, int));
static void
-aixcoff_symfile_finish PARAMS ((struct objfile *));
+xcoff_symfile_finish PARAMS ((struct objfile *));
+
+static struct section_offsets *
+xcoff_symfile_offsets PARAMS ((struct objfile *, CORE_ADDR));
static int
-init_lineno PARAMS ((bfd *, long, int));
+init_lineno PARAMS ((bfd *, file_ptr, int));
static void
find_linenos PARAMS ((bfd *, sec_ptr, PTR));
+static void
+read_symbol PARAMS ((struct internal_syment *, int));
+
static int
-read_symbol_lineno PARAMS ((char *, int));
+read_symbol_lineno PARAMS ((int));
static int
-read_symbol_nvalue PARAMS ((char *, int));
+read_symbol_nvalue PARAMS ((int));
static struct symbol *
process_xcoff_symbol PARAMS ((struct coff_symbol *, struct objfile *));
static void
add_stab_to_list PARAMS ((char *, struct pending_stabs **));
-static void
-sort_syms PARAMS ((void));
-
-static int
-compare_symbols PARAMS ((const void *, const void *));
-
-/* Call sort_syms to sort alphabetically
- the symbols of each block of each symtab. */
-
-static int
-compare_symbols (s1p, s2p)
- const PTR s1p;
- const PTR s2p;
-{
- /* Names that are less should come first. */
- register struct symbol **s1 = (struct symbol **) s1p;
- register struct symbol **s2 = (struct symbol **) s2p;
- register int namediff = strcmp (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2));
- if (namediff != 0)
- return namediff;
-
- /* For symbols of the same name, registers should come first. */
- return ((SYMBOL_CLASS (*s2) == LOC_REGISTER)
- - (SYMBOL_CLASS (*s1) == LOC_REGISTER));
-}
-
-
-/* Sort a vector of symbols by their value. */
-
-static void
-sort_syms ()
-{
- register struct symtab *s;
- register struct objfile *objfile;
- register int i, nbl;
- register struct blockvector *bv;
- register struct block *b;
-
- for (objfile = object_files; objfile != NULL; objfile = objfile -> next)
- {
- for (s = objfile -> symtabs; s != NULL; s = s -> next)
- {
- bv = BLOCKVECTOR (s);
- nbl = BLOCKVECTOR_NBLOCKS (bv);
- for (i = 0; i < nbl; i++)
- {
- b = BLOCKVECTOR_BLOCK (bv, i);
- if (BLOCK_SHOULD_SORT (b))
- {
- qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b),
- sizeof (struct symbol *), compare_symbols);
- }
- }
- }
- }
-}
-
-
/* add a given stab string into given stab vector. */
static void
}
(*stabvector)->stab [(*stabvector)->count++] = stabname;
}
+\f
+/* Linenos are processed on a file-by-file basis.
+
+ Two reasons:
+
+ 1) xlc (IBM's native c compiler) postpones static function code
+ emission to the end of a compilation unit. This way it can
+ determine if those functions (statics) are needed or not, and
+ can do some garbage collection (I think). This makes line
+ numbers and corresponding addresses unordered, and we end up
+ with a line table like:
+
+
+ lineno addr
+ foo() 10 0x100
+ 20 0x200
+ 30 0x300
+
+ foo3() 70 0x400
+ 80 0x500
+ 90 0x600
+
+ static foo2()
+ 40 0x700
+ 50 0x800
+ 60 0x900
+
+ and that breaks gdb's binary search on line numbers, if the
+ above table is not sorted on line numbers. And that sort
+ should be on function based, since gcc can emit line numbers
+ like:
+
+ 10 0x100 - for the init/test part of a for stmt.
+ 20 0x200
+ 30 0x300
+ 10 0x400 - for the increment part of a for stmt.
+ arrange_linetable() will do this sorting.
-#if 0
-/* for all the stabs in a given stab vector, build appropriate types
- and fix their symbols in given symbol vector. */
-
-void
-patch_block_stabs (symbols, stabs)
-struct pending *symbols;
-struct pending_stabs *stabs;
-{
- int ii;
-
- if (!stabs)
- return;
+ 2) aix symbol table might look like:
- /* for all the stab entries, find their corresponding symbols and
- patch their types! */
-
- for (ii=0; ii < stabs->count; ++ii) {
- char *name = stabs->stab[ii];
- char *pp = (char*) index (name, ':');
- struct symbol *sym = find_symbol_in_list (symbols, name, pp-name);
- if (!sym) {
- ;
- /* printf ("ERROR! stab symbol not found!\n"); */ /* FIXME */
- /* The above is a false alarm. There are cases the we can have
- a stab, without its symbol. xlc generates this for the extern
- definitions in inner blocks. */
- }
- else {
- pp += 2;
-
- if (*(pp-1) == 'F' || *(pp-1) == 'f')
- SYMBOL_TYPE (sym) = lookup_function_type (read_type (&pp));
- else
- SYMBOL_TYPE (sym) = read_type (&pp, objfile);
- }
- }
-}
-#endif
+ c_file // beginning of a new file
+ .bi // beginning of include file
+ .ei // end of include file
+ .bi
+ .ei
+ basically, .bi/.ei pairs do not necessarily encapsulate
+ their scope. They need to be recorded, and processed later
+ on when we come the end of the compilation unit.
+ Include table (inclTable) and process_linenos() handle
+ that. */
/* compare line table entry addresses. */
- static int
+static int
compare_lte (lte1, lte2)
- struct linetable_entry *lte1, *lte2;
+ struct linetable_entry *lte1, *lte2;
{
return lte1->pc - lte2->pc;
}
fentry_size = NUM_OF_FUNCTIONS;
fentry = (struct linetable_entry*)
- malloc (fentry_size * sizeof (struct linetable_entry));
+ xmalloc (fentry_size * sizeof (struct linetable_entry));
for (function_count=0, ii=0; ii <oldLineTb->nitems; ++ii) {
if (function_count >= fentry_size) { /* make sure you have room. */
fentry_size *= 2;
fentry = (struct linetable_entry*)
- realloc (fentry, fentry_size * sizeof (struct linetable_entry));
+ xrealloc (fentry, fentry_size * sizeof (struct linetable_entry));
}
fentry[function_count].line = ii;
fentry[function_count].pc = oldLineTb->item[ii].pc;
qsort (fentry, function_count, sizeof(struct linetable_entry), compare_lte);
/* allocate a new line table. */
- newLineTb = (struct linetable*) malloc (sizeof (struct linetable) +
- (oldLineTb->nitems - function_count) * sizeof (struct linetable_entry));
+ newLineTb = (struct linetable *)
+ xmalloc
+ (sizeof (struct linetable) +
+ (oldLineTb->nitems - function_count) * sizeof (struct linetable_entry));
/* if line table does not start with a function beginning, copy up until
a function begin. */
typedef struct _inclTable {
char *name; /* include filename */
- int begin, end; /* offsets to the line table */
+
+ /* Offsets to the line table. end points to the last entry which is
+ part of this include file. */
+ int begin, end;
+
struct subfile *subfile;
unsigned funStartLine; /* start line # of its function */
} InclTable;
record_include_begin (cs)
struct coff_symbol *cs;
{
- /* In aixcoff, we assume include files cannot be nested (not in .c files
- of course, but in corresponding .s files.) */
-
if (inclDepth)
- fatal ("aix internal: pending include file exists.");
-
+ {
+ /* In xcoff, we assume include files cannot be nested (not in .c files
+ of course, but in corresponding .s files.). */
+
+ /* This can happen with old versions of GCC.
+ GCC 2.3.3-930426 does not exhibit this on a test case which
+ a user said produced the message for him. */
+ static struct complaint msg = {"Nested C_BINCL symbols", 0, 0};
+ complain (&msg);
+ }
++inclDepth;
/* allocate an include file, or make room for the new entry */
InclTable *pTbl;
if (inclDepth == 0)
- fatal ("aix internal: Mismatch C_BINCL/C_EINCL pair found.");
+ {
+ static struct complaint msg = {"Mismatched C_BINCL/C_EINCL pair", 0, 0};
+ complain (&msg);
+ }
pTbl = &inclTable [inclIndx];
pTbl->end = cs->c_value;
/* start_subfile (inclTable[ii].name, (char*)0); */
start_subfile (" ?", (char*)0);
- current_subfile->name =
- obsavestring (inclTable[ii].name, strlen (inclTable[ii].name),
- ¤t_objfile->symbol_obstack);
+ free (current_subfile->name);
+ current_subfile->name = strdup (inclTable[ii].name);
if (lv == lineTb) {
current_subfile->line_vector = (struct linetable *)
/* Enter a given range of lines into the line vector.
can be called in the following two ways:
enter_line_range (subfile, beginoffset, endoffset, startaddr, 0, firstLine) or
- enter_line_range (subfile, beginoffset, 0, startaddr, endaddr, firstLine) */
+ enter_line_range (subfile, beginoffset, 0, startaddr, endaddr, firstLine)
+
+ endoffset points to the last line table entry that we should pay
+ attention to. */
static void
enter_line_range (subfile, beginoffset, endoffset, startaddr, endaddr, firstLine)
#define P_LINESYM(PP) (*(long*)((struct external_lineno*)(PP))->l_addr.l_symndx)
pp = &linetab [beginoffset - linetab_offset];
+ if (endoffset != 0 && endoffset - linetab_offset >= linetab_size)
+ {
+ static struct complaint msg =
+ {"Bad line table offset in C_EINCL directive", 0, 0};
+ complain (&msg);
+ return;
+ }
limit = endoffset ? &linetab [endoffset - linetab_offset]
: &linetab [linetab_size -1];
/* find the address this line represents */
addr = P_LINENO(pp) ?
- P_LINEADDR(pp) : read_symbol_nvalue (symtbl, P_LINESYM(pp));
+ P_LINEADDR(pp) : read_symbol_nvalue (P_LINESYM(pp));
- if (addr < startaddr || (endaddr && addr > endaddr))
+ if (addr < startaddr || (endaddr && addr >= endaddr))
return;
if (P_LINENO(pp) == 0) {
- *firstLine = read_symbol_lineno (symtbl, P_LINESYM(pp));
+ *firstLine = read_symbol_lineno (P_LINESYM(pp));
record_line (subfile, 0, addr);
--(*firstLine);
}
struct coff_symbol *cs;
{
#define TBTABLE_BUFSIZ 2000
-#define MIN_TBTABSIZ 50 /* minimum buffer size to hold a
- traceback table. */
static TracebackInfo tbInfo;
struct tbtable *ptb;
/* keep reading blocks of data from the text section, until finding a zero
word and a traceback table. */
- while (
- bufferbytes = (
- (TBTABLE_BUFSIZ < (textsec->_raw_size - functionstart - bytesread)) ?
- TBTABLE_BUFSIZ : (textsec->_raw_size - functionstart - bytesread))
-
- && bfd_get_section_contents (abfd, textsec, buffer,
- (file_ptr)(functionstart + bytesread), bufferbytes))
+ /* Note: The logical thing way to write this code would be to assign
+ to bufferbytes within the while condition. But that triggers a
+ compiler (xlc in AIX 3.2) bug, so simplify it... */
+ bufferbytes =
+ (TBTABLE_BUFSIZ < (textsec->_raw_size - functionstart - bytesread) ?
+ TBTABLE_BUFSIZ : (textsec->_raw_size - functionstart - bytesread));
+ while (bufferbytes
+ && (bfd_get_section_contents
+ (abfd, textsec, buffer,
+ (file_ptr)(functionstart + bytesread), bufferbytes)))
{
bytesread += bufferbytes;
pinsn = (int*) buffer;
if (!tbInfo.framesize)
return NULL;
+
}
/* look for a zero word. */
/* if we don't have the whole traceback table in the buffer, re-read
the whole thing. */
+ /* This is how much to read to get the traceback table.
+ 8 bytes of the traceback table are always present, plus we
+ look at parminfo. */
+#define MIN_TBTABSIZ 12
+
if ((char*)pinsn > (buffer + bufferbytes - MIN_TBTABSIZ)) {
/* In case if we are *very* close to the end of the text section
and cannot read properly from that point on, abort by returning
NULL.
+
+ This could happen if the traceback table is only 8 bytes,
+ but we try to read 12 bytes of it.
Handle this case more graciously -- FIXME */
if (!bfd_get_section_contents (
tbInfo.parminfo = ptb->tb_ext.parminfo;
return &tbInfo;
}
+ bufferbytes =
+ (TBTABLE_BUFSIZ < (textsec->_raw_size - functionstart - bytesread) ?
+ TBTABLE_BUFSIZ : (textsec->_raw_size - functionstart - bytesread));
}
return NULL;
}
/* Reading symbol table has to be fast! Keep the followings as macros, rather
than functions. */
-#define RECORD_MINIMAL_SYMBOL(NAME, ADDR, TYPE, ALLOCED) \
+#define RECORD_MINIMAL_SYMBOL(NAME, ADDR, TYPE, ALLOCED, SECTION) \
{ \
char *namestr; \
if (ALLOCED) \
obstack_copy0 (&objfile->symbol_obstack, (NAME) + 1, strlen ((NAME)+1)); \
(ALLOCED) = 1; \
} \
- prim_record_minimal_symbol (namestr, (ADDR), (TYPE)); \
+ prim_record_minimal_symbol_and_info (namestr, (ADDR), (TYPE), \
+ (char *)NULL, (SECTION)); \
misc_func_recorded = 1; \
}
-/* A parameter template, used by ADD_PARM_TO_PENDING. */
+/* A parameter template, used by ADD_PARM_TO_PENDING. It is initialized
+ in our initializer function at the bottom of the file, to avoid
+ dependencies on the exact "struct symbol" format. */
-static struct symbol parmsym = { /* default parameter symbol */
- "", /* name */
- VAR_NAMESPACE, /* namespace */
- LOC_ARG, /* class */
- NULL, /* type */
- 0, /* line number */
- 0, /* value */
-};
+static struct symbol parmsym;
/* Add a parameter to a given pending symbol list. */
}
-/* aixcoff has static blocks marked in `.bs', `.es' pairs. They cannot be
+/* xcoff has static blocks marked in `.bs', `.es' pairs. They cannot be
nested. At any given time, a symbol can only be in one static block.
This is the base address of current static block, zero if non exists. */
static int static_block_base = 0;
+/* Section number for the current static block. */
+
+static int static_block_section = -1;
+
/* true if space for symbol name has been allocated. */
static int symname_alloced = 0;
char *last_csect_name; /* last seen csect's name and value */
CORE_ADDR last_csect_val;
+ int last_csect_sec;
int misc_func_recorded; /* true if any misc. function */
current_objfile = objfile;
N_BTSHFT = coff_data (abfd)->local_n_btshft;
local_symesz = coff_data (abfd)->local_symesz;
- last_source_file = 0;
+ last_source_file = NULL;
last_csect_name = 0;
last_csect_val = 0;
misc_func_recorded = 0;
+ start_stabs ();
start_symtab (filestring, (char *)NULL, file_start_addr);
symnum = 0;
first_object_file_end = 0;
size = coff_data (abfd)->local_symesz * nsyms;
symtbl = xmalloc (size);
+ symtbl_num_syms = nsyms;
val = bfd_read (symtbl, size, 1, abfd);
if (val != size)
/* READ_ONE_SYMBOL (symbol, cs, symname_alloced); */
/* read one symbol into `cs' structure. After processing the whole symbol
table, only string table will be kept in memory, symbol table and debug
- section of aixcoff will be freed. Thus we can mark symbols with names
+ section of xcoff will be freed. Thus we can mark symbols with names
in string table as `alloced'. */
{
int ii;
pointed to by cs->c_name will persist throughout xcoffread. If
we use the new field, it gets overwritten for each symbol. */
cs->c_name = ((struct external_syment *)raw_symbol)->e.e_name;
+ /* If it's exactly E_SYMNMLEN characters long it isn't
+ '\0'-terminated. */
+ if (cs->c_name[E_SYMNMLEN - 1] != '\0')
+ {
+ char *p;
+ p = obstack_alloc (&objfile->symbol_obstack, E_SYMNMLEN + 1);
+ strncpy (p, cs->c_name, E_SYMNMLEN);
+ p[E_SYMNMLEN] = '\0';
+ cs->c_name = p;
+ symname_alloced = 1;
+ }
} else if (symbol->n_sclass & 0x80) {
cs->c_name = debugsec + symbol->n_offset;
symname_alloced = 0;
symname_alloced = 1;
}
cs->c_value = symbol->n_value;
- cs->c_sclass = symbol->n_sclass & 0xff;
+ cs->c_sclass = symbol->n_sclass;
cs->c_secnum = symbol->n_scnum;
cs->c_type = (unsigned)symbol->n_type;
if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE) {
if (last_source_file)
- end_symtab (cur_src_end_addr, 1, 0, objfile);
+ {
+ end_symtab (cur_src_end_addr, 1, 0, objfile, textsec->target_index);
+ end_stabs ();
+ }
+ start_stabs ();
start_symtab ("_globals_", (char *)NULL, (CORE_ADDR)0);
cur_src_end_addr = first_object_file_end;
/* done with all files, everything from here on is globals */
case XMC_PR : /* a `.text' csect. */
{
- /* A program csect is seen.
-
- We have to allocate one symbol table for each program csect. Normally
- gdb prefers one symtab for each compilation unit (CU). In case of AIX, one
- CU might include more than one prog csect, and they don't have to be
- adjacent in terms of the space they occupy in memory. Thus, one single
- CU might get fragmented in the memory and gdb's file start and end address
- approach does not work! */
+ /* A program csect is seen. We have to allocate one
+ symbol table for each program csect. Normally gdb
+ prefers one symtab for each source file. In case
+ of AIX, one source file might include more than one
+ [PR] csect, and they don't have to be adjacent in
+ terms of the space they occupy in memory. Thus, one
+ single source file might get fragmented in the
+ memory and gdb's file start and end address
+ approach does not work! GCC (and I think xlc) seem
+ to put all the code in the unnamed program csect. */
if (last_csect_name) {
if (!misc_func_recorded) {
int alloced = 0;
RECORD_MINIMAL_SYMBOL (last_csect_name, last_csect_val,
- mst_text, alloced);
+ mst_text, alloced, last_csect_sec);
}
complete_symtab (filestring, file_start_addr);
cur_src_end_addr = file_end_addr;
- end_symtab (file_end_addr, 1, 0, objfile);
- start_symtab ((char *)NULL, (char *)NULL, (CORE_ADDR)0);
+ end_symtab (file_end_addr, 1, 0, objfile,
+ textsec->target_index);
+ end_stabs ();
+ start_stabs ();
+ /* Give all csects for this source file the same
+ name. */
+ start_symtab (filestring, (char *)NULL, (CORE_ADDR)0);
}
/* If this is the very first csect seen, basically `__start'. */
if (cs->c_name && cs->c_name[0] == '.') {
last_csect_name = cs->c_name;
last_csect_val = cs->c_value;
+ last_csect_sec = cs->c_secnum;
}
}
misc_func_recorded = 0;
function_entry_point:
RECORD_MINIMAL_SYMBOL (cs->c_name, cs->c_value, mst_text,
- symname_alloced);
+ symname_alloced, cs->c_secnum);
fcn_line_offset = main_aux->x_sym.x_fcnary.x_fcn.x_lnnoptr;
fcn_start_addr = cs->c_value;
/* Recording this entry is necessary. Single stepping relies on
this vector to get an idea about function address boundaries. */
- prim_record_minimal_symbol (0, cs->c_value, mst_unknown);
+ prim_record_minimal_symbol_and_info
+ ("<trampoline>", cs->c_value, mst_unknown,
+ (char *)NULL, cs->c_secnum);
#else
/* record trampoline code entries as mst_unknown symbol. When we
int alloced = 0;
RECORD_MINIMAL_SYMBOL (last_csect_name, last_csect_val,
- mst_text, alloced);
+ mst_text, alloced, last_csect_sec);
}
/* c_value field contains symnum of next .file entry in table
/* complete symbol table for last object file containing
debugging information. */
- /* Whether or not there was a csect in the previous file, we have
- to call `end_symtab' and `start_symtab' to reset type_vector,
+ /* Whether or not there was a csect in the previous file, we have to call
+ `end_stabs' and `start_stabs' to reset type_vector,
line_vector, etc. structures. */
complete_symtab (filestring, file_start_addr);
cur_src_end_addr = file_end_addr;
- end_symtab (file_end_addr, 1, 0, objfile);
+ end_symtab (file_end_addr, 1, 0, objfile, textsec->target_index);
+ end_stabs ();
+ start_stabs ();
start_symtab (cs->c_name, (char *)NULL, (CORE_ADDR)0);
last_csect_name = 0;
case C_FUN:
-
-#ifdef NO_DEFINE_SYMBOL
- /* For a function stab, just save its type in `fcn_type_saved', and leave
- it for the `.bf' processing. */
- {
- char *pp = (char*) index (cs->c_name, ':');
-
- if (!pp || ( *(pp+1) != 'F' && *(pp+1) != 'f'))
- fatal ("Unrecognized stab");
- pp += 2;
-
- if (fcn_type_saved)
- fatal ("Unprocessed function type");
-
- fcn_type_saved = lookup_function_type (read_type (&pp, objfile));
- }
-#else
fcn_stab_saved = *cs;
-#endif
break;
case C_FCN:
- if (strcmp (cs->c_name, ".bf") == 0) {
+ if (STREQ (cs->c_name, ".bf")) {
bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
main_aux);
within_function = 1;
- /* Linenos are now processed on a file-by-file, not fn-by-fn, basis.
- Metin did it, I'm not sure why. FIXME. -- gnu@cygnus.com */
-
- /* Two reasons:
-
- 1) xlc (IBM's native c compiler) postpones static function code
- emission to the end of a compilation unit. This way it can
- determine if those functions (statics) are needed or not, and
- can do some garbage collection (I think). This makes line
- numbers and corresponding addresses unordered, and we end up
- with a line table like:
-
-
- lineno addr
- foo() 10 0x100
- 20 0x200
- 30 0x300
-
- foo3() 70 0x400
- 80 0x500
- 90 0x600
-
- static foo2()
- 40 0x700
- 50 0x800
- 60 0x900
-
- and that breaks gdb's binary search on line numbers, if the
- above table is not sorted on line numbers. And that sort
- should be on function based, since gcc can emit line numbers
- like:
-
- 10 0x100 - for the init/test part of a for stmt.
- 20 0x200
- 30 0x300
- 10 0x400 - for the increment part of a for stmt.
-
- arrange_linenos() will do this sorting.
-
-
- 2) aix symbol table might look like:
-
- c_file // beginning of a new file
- .bi // beginning of include file
- .ei // end of include file
- .bi
- .ei
-
- basically, .bi/.ei pairs do not necessarily encapsulate
- their scope. They need to be recorded, and processed later
- on when we come the end of the compilation unit.
- Include table (inclTable) and process_linenos() handle
- that.
- */
mark_first_line (fcn_line_offset, cs->c_symnum);
new = push_context (0, fcn_start_addr);
-#ifdef NO_DEFINE_SYMBOL
- new->name = process_xcoff_symbol (&fcn_cs_saved, objfile);
-
- /* Between a function symbol and `.bf', there always will be a function
- stab. We save function type when processing that stab. */
-
- if (fcn_type_saved == NULL) {
- printf ("Unknown function type: symbol 0x%x\n", cs->c_symnum);
- SYMBOL_TYPE (new->name) = lookup_function_type (builtin_type_int);
- }
- else {
- SYMBOL_TYPE (new->name) = fcn_type_saved;
- fcn_type_saved = NULL;
- }
-#else
new->name = define_symbol
(fcn_cs_saved.c_value, fcn_stab_saved.c_name, 0, 0, objfile);
-#endif
+ if (new->name != NULL)
+ SYMBOL_SECTION (new->name) = cs->c_secnum;
}
- else if (strcmp (cs->c_name, ".ef") == 0) {
+ else if (STREQ (cs->c_name, ".ef")) {
bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
main_aux);
break;
case C_BSTAT : /* begin static block */
- static_block_base = read_symbol_nvalue (symtbl, cs->c_value);
+ {
+ struct internal_syment symbol;
+
+ read_symbol (&symbol, cs->c_value);
+ static_block_base = symbol.n_value;
+ static_block_section = symbol.n_scnum;
+ }
break;
case C_ESTAT : /* end of static block */
static_block_base = 0;
+ static_block_section = -1;
break;
case C_ARG : /* These are not implemented. */
break;
case C_BLOCK :
- if (strcmp (cs->c_name, ".bb") == 0) {
+ if (STREQ (cs->c_name, ".bb")) {
depth++;
new = push_context (depth, cs->c_value);
}
- else if (strcmp (cs->c_name, ".eb") == 0) {
+ else if (STREQ (cs->c_name, ".eb")) {
new = pop_context ();
if (depth != new->depth)
error ("Invalid symbol data: .bb/.eb symbol mismatch at symbol %d.",
break;
default :
- (void) process_xcoff_symbol (cs, objfile);
+ process_xcoff_symbol (cs, objfile);
break;
}
} /* while */
if (last_source_file)
- end_symtab (cur_src_end_addr, 1, 0, objfile);
+ {
+ end_symtab (cur_src_end_addr, 1, 0, objfile, textsec->target_index);
+ end_stabs ();
+ }
free (symtbl);
current_objfile = NULL;
If no XMC_TC0 is found, toc_offset should be zero. Another place to obtain
this information would be file auxiliary header. */
+#ifndef FAKING_RS6000
xcoff_add_toc_to_loadinfo (toc_offset);
+#endif
}
#define SYMBOL_DUP(SYMBOL1, SYMBOL2) \
/* default assumptions */
SYMBOL_VALUE (sym) = cs->c_value;
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_SECTION (sym) = cs->c_secnum;
if (ISFCN (cs->c_type)) {
case C_DECL: /* a type decleration?? */
-#if defined(NO_TYPEDEFS) || defined(NO_DEFINE_SYMBOL)
- qq = (char*) strchr (name, ':');
- if (!qq) /* skip if there is no ':' */
- return NULL;
-
- nameless = (qq == name);
-
- struct_and_type_combined = (qq[1] == 'T' && qq[2] == 't');
- pp = qq + (struct_and_type_combined ? 3 : 2);
-
-
- /* To handle GNU C++ typename abbreviation, we need to be able to fill
- in a type's name as soon as space for that type is allocated. */
-
- if (struct_and_type_combined && name != qq) {
-
- int typenums[2];
- struct type *tmp_type;
- char *tmp_pp = pp;
-
- read_type_number (&tmp_pp, typenums);
- tmp_type = dbx_alloc_type (typenums, objfile);
-
- if (tmp_type && !TYPE_NAME (tmp_type) && !nameless)
- TYPE_NAME (tmp_type) = SYMBOL_NAME (sym) =
- obsavestring (name, qq-name,
- &objfile->symbol_obstack);
- }
- ttype = SYMBOL_TYPE (sym) = read_type (&pp);
-
- /* if there is no name for this typedef, you don't have to keep its
- symbol, since nobody could ask for it. Otherwise, build a symbol
- and add it into symbol_list. */
-
- if (nameless)
- return;
-
-#ifdef NO_TYPEDEFS
- /* Transarc wants to eliminate type definitions from the symbol table.
- Limited debugging capabilities, but faster symbol table processing
- and less memory usage. Note that tag definitions (starting with
- 'T') will remain intact. */
-
- if (qq[1] != 'T' && (!TYPE_NAME (ttype) || *(TYPE_NAME (ttype)) == '\0')) {
-
- if (SYMBOL_NAME (sym))
- TYPE_NAME (ttype) = SYMBOL_NAME (sym);
- else
- TYPE_NAME (ttype) = obsavestring (name, qq-name);
-
- return;
- }
-
-#endif /* !NO_TYPEDEFS */
-
- /* read_type() will return null if type (or tag) definition was
- unnnecessarily duplicated. Also, if the symbol doesn't have a name,
- there is no need to keep it in symbol table. */
- /* The above argument no longer valid. read_type() never returns NULL. */
-
- if (!ttype)
- return NULL;
-
- /* if there is no name for this typedef, you don't have to keep its
- symbol, since nobody could ask for it. Otherwise, build a symbol
- and add it into symbol_list. */
-
- if (qq[1] == 'T')
- SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
- else if (qq[1] == 't')
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- else {
- warning ("Unrecognized stab string.\n");
- return NULL;
- }
-
- SYMBOL_CLASS (sym) = LOC_TYPEDEF;
- if (!SYMBOL_NAME (sym))
- SYMBOL_NAME (sym) = obsavestring (name, qq-name);
-
- SYMBOL_DUP (sym, sym2);
- add_symbol_to_list
- (sym2, within_function ? &local_symbols : &file_symbols);
-
- /* For a combination of struct and type, add one more symbol
- for the type. */
-
- if (struct_and_type_combined) {
- SYMBOL_DUP (sym, sym2);
- SYMBOL_NAMESPACE (sym2) = VAR_NAMESPACE;
- add_symbol_to_list
- (sym2, within_function ? &local_symbols : &file_symbols);
- }
-
- /* assign a name to the type node. */
-
- if (!TYPE_NAME (ttype) || *(TYPE_NAME (ttype)) == '\0') {
- if (struct_and_type_combined)
- TYPE_NAME (ttype) = SYMBOL_NAME (sym);
- else if (qq[1] == 'T') /* struct namespace */
- TYPE_NAME (ttype) = concat (
- TYPE_CODE (ttype) == TYPE_CODE_UNION ? "union " :
- TYPE_CODE (ttype) == TYPE_CODE_STRUCT? "struct " : "enum ",
- SYMBOL_NAME (sym), NULL);
- }
- break;
-
-#else /* !NO_DEFINE_SYMBOL */
- return define_symbol (cs->c_value, cs->c_name, 0, 0, objfile);
-#endif
+ sym = define_symbol (cs->c_value, cs->c_name, 0, 0, objfile);
+ if (sym != NULL)
+ SYMBOL_SECTION (sym) = cs->c_secnum;
+ return sym;
case C_GSYM:
add_stab_to_list (name, &global_stabs);
case C_PSYM:
case C_RPSYM:
-#ifdef NO_DEFINE_SYMBOL
- if (*name == ':' || (pp = (char *) strchr (name, ':')) == NULL)
- return NULL;
- SYMBOL_NAME (sym) = obsavestring (name, pp-name, &objfile -> symbol_obstack);
- SYMBOL_CLASS (sym) = (cs->c_sclass == C_PSYM) ? LOC_ARG : LOC_REGPARM;
- pp += 2;
- SYMBOL_TYPE (sym) = read_type (&pp, objfile);
- SYMBOL_DUP (sym, sym2);
- add_symbol_to_list (sym2, &local_symbols);
- break;
-#else
- sym = define_symbol (cs->c_value, cs->c_name, 0, 0, objfile);
- SYMBOL_CLASS (sym) = (cs->c_sclass == C_PSYM) ? LOC_ARG : LOC_REGPARM;
- return sym;
-#endif
+ sym = define_symbol (cs->c_value, cs->c_name, 0, 0, objfile);
+ if (sym != NULL)
+ {
+ SYMBOL_SECTION (sym) = cs->c_secnum;
+ }
+ return sym;
case C_STSYM:
-#ifdef NO_DEFINE_SYMBOL
- if (*name == ':' || (pp = (char *) strchr (name, ':')) == NULL)
- return NULL;
- SYMBOL_NAME (sym) = obsavestring (name, pp-name, &objfile -> symbol_obstack);
- SYMBOL_CLASS (sym) = LOC_STATIC;
- SYMBOL_VALUE (sym) += static_block_base;
- pp += 2;
- SYMBOL_TYPE (sym) = read_type (&pp, objfile);
- SYMBOL_DUP (sym, sym2);
- add_symbol_to_list
- (sym2, within_function ? &local_symbols : &file_symbols);
- break;
-#else
/* If we are going to use Sun dbx's define_symbol(), we need to
massage our stab string a little. Change 'V' type to 'S' to be
comparible with Sun. */
+ /* FIXME: I believe this is to avoid a Sun-specific hack somewhere.
+ Needs more investigation. */
if (*name == ':' || (pp = (char *) index (name, ':')) == NULL)
return NULL;
++pp;
if (*pp == 'V') *pp = 'S';
sym = define_symbol (cs->c_value, cs->c_name, 0, 0, objfile);
- SYMBOL_VALUE (sym) += static_block_base;
+ if (sym != NULL)
+ {
+ SYMBOL_VALUE (sym) += static_block_base;
+ SYMBOL_SECTION (sym) = static_block_section;
+ }
return sym;
-#endif
case C_LSYM:
- if (*name == ':' || (pp = (char *) strchr (name, ':')) == NULL)
- return NULL;
- SYMBOL_NAME (sym) = obsavestring (name, pp-name, &objfile -> symbol_obstack);
- SYMBOL_CLASS (sym) = LOC_LOCAL;
- pp += 1;
- SYMBOL_TYPE (sym) = read_type (&pp, objfile);
- SYMBOL_DUP (sym, sym2);
- add_symbol_to_list (sym2, &local_symbols);
- break;
+ sym = define_symbol (cs->c_value, cs->c_name, 0, N_LSYM, objfile);
+ if (sym != NULL)
+ {
+ SYMBOL_SECTION (sym) = cs->c_secnum;
+ }
+ return sym;
case C_AUTO:
SYMBOL_CLASS (sym) = LOC_LOCAL;
SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced);
+ SYMBOL_SECTION (sym) = cs->c_secnum;
SYMBOL_DUP (sym, sym2);
add_symbol_to_list (sym2, &local_symbols);
break;
case C_EXT:
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced);
+ SYMBOL_SECTION (sym) = cs->c_secnum;
SYMBOL_DUP (sym, sym2);
add_symbol_to_list (sym2, &global_symbols);
break;
case C_STAT:
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced);
+ SYMBOL_SECTION (sym) = cs->c_secnum;
SYMBOL_DUP (sym, sym2);
add_symbol_to_list
(sym2, within_function ? &local_symbols : &file_symbols);
printf ("ERROR! C_REG is not fully implemented!\n");
SYMBOL_CLASS (sym) = LOC_REGISTER;
SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced);
+ SYMBOL_SECTION (sym) = cs->c_secnum;
SYMBOL_DUP (sym, sym2);
add_symbol_to_list (sym2, &local_symbols);
break;
case C_RSYM:
-
-#ifdef NO_DEFINE_SYMBOL
pp = (char*) strchr (name, ':');
- SYMBOL_CLASS (sym) = LOC_REGISTER;
- SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (cs->c_value);
- if (pp) {
- SYMBOL_NAME (sym) = obsavestring (name, pp-name, &objfile -> symbol_obstack);
- pp += 2;
- if (*pp)
- SYMBOL_TYPE (sym) = read_type (&pp, objfile);
- }
- else
- /* else this is not a stab entry, suppose the type is either
- `int' or `float', depending on the register class. */
-
- SYMBOL_TYPE (sym) = (SYMBOL_VALUE (sym) < 32)
- ? lookup_fundamental_type (objfile, FT_INTEGER)
- : lookup_fundamental_type (objfile, FT_FLOAT);
-
- SYMBOL_DUP (sym, sym2);
- add_symbol_to_list (sym2, &local_symbols);
- break;
-#else
if (pp) {
sym = define_symbol (cs->c_value, cs->c_name, 0, 0, objfile);
+ if (sym != NULL)
+ SYMBOL_SECTION (sym) = cs->c_secnum;
return sym;
}
else {
- warning ("A non-stab C_RSYM needs special handling.");
+ complain (&rsym_complaint, name);
return NULL;
}
-#endif
default :
- warning ("Unexpected storage class: %d.", cs->c_sclass);
+ complain (&storclass_complaint, cs->c_sclass);
return NULL;
}
}
return sym2;
}
+/* Set *SYMBOL to symbol number symno in symtbl. */
+static void
+read_symbol (symbol, symno)
+ struct internal_syment *symbol;
+ int symno;
+{
+ if (symno < 0 || symno >= symtbl_num_syms)
+ {
+ static struct complaint msg =
+ {"Invalid symbol offset", 0, 0};
+ complain (&msg);
+ symbol->n_value = 0;
+ symbol->n_scnum = -1;
+ return;
+ }
+ bfd_coff_swap_sym_in (symfile_bfd, symtbl + (symno*local_symesz), symbol);
+}
+
+/* Get value corresponding to symbol number symno in symtbl. */
static int
-read_symbol_nvalue (symtable, symno)
- char *symtable;
+read_symbol_nvalue (symno)
int symno;
{
struct internal_syment symbol[1];
- bfd_coff_swap_sym_in (symfile_bfd, symtable + (symno*local_symesz), symbol);
+ read_symbol (symbol, symno);
return symbol->n_value;
}
+/* Find the address of the function corresponding to symno, where
+ symno is the symbol pointed to by the linetable. */
+
static int
-read_symbol_lineno (symtable, symno)
- char *symtable;
+read_symbol_lineno (symno)
int symno;
{
struct internal_syment symbol[1];
union internal_auxent main_aux[1];
- int ii;
+ /* Note that just searching for a short distance (e.g. 50 symbols)
+ is not enough, at least in the following case.
+
+ .extern foo
+ [many .stabx entries]
+ [a few functions, referring to foo]
+ .globl foo
+ .bf
- for (ii = 0; ii < 50; ii++) {
+ What happens here is that the assembler moves the .stabx entries
+ to right before the ".bf" for foo, but the symbol for "foo" is before
+ all the stabx entries. See PR gdb/2222. */
+ while (symno < symtbl_num_syms) {
bfd_coff_swap_sym_in (symfile_bfd,
- symtable + (symno*local_symesz), symbol);
- if (symbol->n_sclass == C_FCN && 0 == strcmp (symbol->n_name, ".bf"))
+ symtbl + (symno*local_symesz), symbol);
+ if (symbol->n_sclass == C_FCN && STREQ (symbol->n_name, ".bf"))
goto gotit;
symno += symbol->n_numaux+1;
}
- printf ("GDB Error: `.bf' not found.\n");
+ complain (&bf_notfound_complaint);
return 0;
gotit:
/* take aux entry and return its lineno */
symno++;
- bfd_coff_swap_aux_in (symfile_bfd, symtable+(symno*local_symesz),
+ bfd_coff_swap_aux_in (symfile_bfd, symtbl+(symno*local_symesz),
symbol->n_type, symbol->n_sclass, main_aux);
return main_aux->x_sym.x_misc.x_lnsz.x_lnno;
count = asect->lineno_count;
- if (strcmp (asect->name, ".text") || count == 0)
+ if (!STREQ (asect->name, ".text") || count == 0)
return;
size = count * coff_data (symfile_bfd)->local_linesz;
static int
init_lineno (abfd, offset, size)
bfd *abfd;
- long offset;
+ file_ptr offset;
int size;
{
int val;
- if (bfd_seek(abfd, offset, 0) < 0)
+ if (bfd_seek(abfd, offset, L_SET) < 0)
return -1;
linetab = (char *) xmalloc(size);
(a \ at the end of the text of a name)
call this function to get the continuation. */
/* So far, I haven't seen this happenning xlc output. I doubt we'll need this
- for aixcoff. */
+ for xcoff. */
#undef next_symbol_text
#define next_symbol_text() \
printf ("Gdb Error: symbol names on multiple lines not implemented.\n")
-/* xlc/dbx combination uses a set of builtin types, starting from -1. return
- the proper type node fora given builtin type #. */
-
-struct type *
-builtin_type (pp)
-char **pp;
-{
- int typenums[2];
-
- if (**pp != '-') {
- printf ("ERROR!, unknown built-in type!\n");
- return NULL;
- }
- *pp += 1;
- read_type_number (pp, typenums);
-
- /* default types are defined in dbxstclass.h. */
- switch ( typenums[1] ) {
- case 1:
- return lookup_fundamental_type (current_objfile, FT_INTEGER);
- case 2:
- return lookup_fundamental_type (current_objfile, FT_CHAR);
- case 3:
- return lookup_fundamental_type (current_objfile, FT_SHORT);
- case 4:
- return lookup_fundamental_type (current_objfile, FT_LONG);
- case 5:
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
- case 6:
- return lookup_fundamental_type (current_objfile, FT_SIGNED_CHAR);
- case 7:
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);
- case 8:
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
- case 9:
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
- case 10:
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
- case 11:
- return lookup_fundamental_type (current_objfile, FT_VOID);
- case 12:
- return lookup_fundamental_type (current_objfile, FT_FLOAT);
- case 13:
- return lookup_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
- case 14:
- return lookup_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
- case 15:
- /* requires a builtin `integer' */
- return lookup_fundamental_type (current_objfile, FT_INTEGER);
- case 16:
- return lookup_fundamental_type (current_objfile, FT_BOOLEAN);
- case 17:
- /* requires builtin `short real' */
- return lookup_fundamental_type (current_objfile, FT_FLOAT);
- case 18:
- /* requires builtin `real' */
- return lookup_fundamental_type (current_objfile, FT_FLOAT);
- default :
- printf ("ERROR! Unknown builtin type -%d\n", typenums[1]);
- return NULL;
- }
-}
-
-#if 0 /* Seems to be unused, don't bother converting from old misc function
- vector usage to new minimal symbol tables. FIXME: Delete this? */
-
-/* if we now nothing about a function but its address, make a function symbol
- out of it with the limited knowladge you have. This will be used when
- somebody refers to a function, which doesn't exist in the symbol table,
- but is in the minimal symbol table. */
-
-struct symbol *
-build_function_symbol (ind, objfile)
- int ind;
+static void
+xcoff_new_init (objfile)
struct objfile *objfile;
{
- struct symbol *sym =
- (struct symbol *) obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
- SYMBOL_NAME (sym) = misc_function_vector[ind].name;
- /* SYMBOL_VALUE (sym) = misc_function_vector[ind].address; */
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- SYMBOL_CLASS (sym) = LOC_BLOCK;
- SYMBOL_TYPE (sym) = lookup_function_type (lookup_fundamental_type (current_objfile, FT_INTEGER));
- SYMBOL_BLOCK_VALUE (sym) = (struct block *)
- obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
- BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) = misc_function_vector[ind].address;
- return sym;
}
-#endif
-static void
-aixcoff_new_init (objfile)
- struct objfile *objfile;
-{
-}
+/* xcoff_symfile_init()
+ is the xcoff-specific initialization routine for reading symbols.
+ It is passed an objfile which contains, among other things,
+ the BFD for the file whose symbols are being read, and a slot for
+ a pointer to "private data" which we fill with cookies and other
+ treats for xcoff_symfile_read().
+
+ We will only be called if this is an XCOFF or XCOFF-like file.
+ BFD handles figuring out the format of the file, and code in symfile.c
+ uses BFD's determination to vector to us.
+
+ The ultimate result is a new symtab (or, FIXME, eventually a psymtab). */
static void
-aixcoff_symfile_init (objfile)
+xcoff_symfile_init (objfile)
struct objfile *objfile;
{
bfd *abfd = objfile->obfd;
objfile struct from the global list of known objfiles. */
static void
-aixcoff_symfile_finish (objfile)
+xcoff_symfile_finish (objfile)
struct objfile *objfile;
{
if (objfile -> sym_private != NULL)
static int
init_stringtab(abfd, offset, objfile)
bfd *abfd;
- long offset;
+ file_ptr offset;
struct objfile *objfile;
{
long length;
int val;
unsigned char lengthbuf[4];
- if (bfd_seek(abfd, offset, 0) < 0)
+ if (bfd_seek(abfd, offset, L_SET) < 0)
return -1;
val = bfd_read((char *)lengthbuf, 1, sizeof lengthbuf, abfd);
}
-/* aixcoff version of symbol file read. */
+/* xcoff version of symbol file read. */
static void
-aixcoff_symfile_read (objfile, addr, mainline)
+xcoff_symfile_read (objfile, section_offset, mainline)
struct objfile *objfile;
- CORE_ADDR addr;
+ struct section_offset *section_offset;
int mainline;
{
- int num_symbols; /* # of symbols */
- int symtab_offset; /* symbol table and */
- int stringtab_offset; /* string table file offsets */
+ int num_symbols; /* # of symbols */
+ file_ptr symtab_offset; /* symbol table and */
+ file_ptr stringtab_offset; /* string table file offsets */
int val;
bfd *abfd;
struct coff_symfile_info *info;
/* only read in the line # table if one exists */
val = init_lineno(abfd, info->min_lineno_offset,
- info->max_lineno_offset - info->min_lineno_offset);
+ (int) (info->max_lineno_offset - info->min_lineno_offset));
if (val < 0)
error("\"%s\": error reading line numbers\n", name);
}
- val = init_stringtab(abfd, stringtab_offset, objfile);
- if (val < 0) {
- error ("\"%s\": can't get string table", name);
- }
+ if (num_symbols > 0)
+ {
+ val = init_stringtab(abfd, stringtab_offset, objfile);
+ if (val < 0) {
+ error ("\"%s\": can't get string table", name);
+ }
- if (init_debugsection(abfd) < 0) {
- error ("Error reading .debug section of `%s'\n", name);
- }
+ if (init_debugsection(abfd) < 0) {
+ error ("Error reading .debug section of `%s'\n", name);
+ }
+ }
/* Position to read the symbol table. Do not read it all at once. */
- val = bfd_seek(abfd, (long)symtab_offset, 0);
+ val = bfd_seek(abfd, symtab_offset, L_SET);
if (val < 0)
perror_with_name(name);
init_minimal_symbol_collection ();
make_cleanup (discard_minimal_symbols, 0);
+#ifndef FAKING_RS6000
/* Initialize load info structure. */
if (mainline)
xcoff_init_loadinfo ();
+#endif
/* Now that the executable file is positioned at symbol table,
process it and define symbols accordingly. */
free_debugsection ();
/* Sort symbols alphabetically within each block. */
- sort_syms ();
+ sort_all_symtab_syms ();
/* Install any minimal symbols that have been collected as the current
minimal symbols for this objfile. */
install_minimal_symbols (objfile);
+}
+
+/* XCOFF-specific parsing routine for section offsets. */
+
+static int largest_section;
- /* Make a default for file to list. */
- select_source_symtab (0);
+static void
+note_one_section (abfd, asect, ptr)
+ bfd *abfd;
+ asection *asect;
+ PTR ptr;
+{
+ if (asect->target_index > largest_section)
+ largest_section = asect->target_index;
}
-/* Register our ability to parse symbols for aixcoff BFD files. */
+static
+struct section_offsets *
+xcoff_symfile_offsets (objfile, addr)
+ struct objfile *objfile;
+ CORE_ADDR addr;
+{
+ struct section_offsets *section_offsets;
+ int i;
+
+ largest_section = 0;
+ bfd_map_over_sections (objfile->obfd, note_one_section, NULL);
+ objfile->num_sections = largest_section + 1;
+ section_offsets = (struct section_offsets *)
+ obstack_alloc
+ (&objfile -> psymbol_obstack,
+ sizeof (struct section_offsets)
+ + sizeof (section_offsets->offsets) * (objfile->num_sections));
+
+ /* syms_from_objfile kindly subtracts from addr the bfd_section_vma
+ of the .text section. This strikes me as wrong--whether the
+ offset to be applied to symbol reading is relative to the start
+ address of the section depends on the symbol format. In any
+ event, this whole "addr" concept is pretty broken (it doesn't
+ handle any section but .text sensibly), so just ignore the addr
+ parameter and use 0. That matches the fact that xcoff_symfile_read
+ ignores the section_offsets). */
+ for (i = 0; i < objfile->num_sections; i++)
+ ANOFFSET (section_offsets, i) = 0;
+
+ return section_offsets;
+}
+/* Register our ability to parse symbols for xcoff BFD files. */
-static struct sym_fns aixcoff_sym_fns =
+static struct sym_fns xcoff_sym_fns =
{
"aixcoff-rs6000", /* sym_name: name or name prefix of BFD target type */
15, /* sym_namelen: number of significant sym_name chars */
- aixcoff_new_init, /* sym_new_init: init anything gbl to entire symtab */
- 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 */
+ xcoff_new_init, /* sym_new_init: init anything gbl to entire symtab */
+ xcoff_symfile_init, /* sym_init: read initial info, setup for sym_read() */
+ xcoff_symfile_read, /* sym_read: read a symbol file into symtab */
+ xcoff_symfile_finish, /* sym_finish: finished with file, cleanup */
+ xcoff_symfile_offsets, /* sym_offsets: xlate offsets ext->int form */
NULL /* next: pointer to next struct sym_fns */
};
void
_initialize_xcoffread ()
{
- add_symtab_fns(&aixcoff_sym_fns);
-}
-
-
-/* In order to handle forward type references, we needed to have this old
- routine. Try printing the type of member `p' in the following structure
- in a dbx environment.
-
- struct s {
- ...
- struct s *p;
- };
-*/
-
-
-/* Smash TYPE to be a type of pointers to TO_TYPE.
- If TO_TYPE is not permanent and has no pointer-type yet,
- record TYPE as its pointer-type. */
-
-void
-smash_to_pointer_type (type, to_type)
- struct type *type, *to_type;
-{
-/* int type_permanent = (TYPE_FLAGS (type) & TYPE_FLAG_PERM); */
-
- bzero (type, sizeof (struct type));
- TYPE_TARGET_TYPE (type) = to_type;
- /* We assume the machine has only one representation for pointers! */
- TYPE_LENGTH (type) = sizeof (char *);
- TYPE_CODE (type) = TYPE_CODE_PTR;
-
-/* ??? TYPE_TARGET_TYPE and TYPE_MAIN_VARIANT are the same. You can't do
- this. It will break the target type!!!
- TYPE_MAIN_VARIANT (type) = type;
-
- if (type_permanent)
- TYPE_FLAGS (type) |= TYPE_FLAG_PERM;
-*/
-
- if (TYPE_POINTER_TYPE (to_type) == 0)
-#if 0
- && (!(TYPE_FLAGS (to_type) & TYPE_FLAG_PERM)
- || type_permanent))
-#endif /* 0 */
- {
- TYPE_POINTER_TYPE (to_type) = type;
- }
-}
-
-#else /* IBM6000_HOST */
-struct type *
-builtin_type (ignore)
-char **ignore;
-{
- fatal ("GDB internal eror: builtin_type called on non-RS/6000!");
+ add_symtab_fns(&xcoff_sym_fns);
+
+ /* Initialize symbol template later used for arguments. */
+ SYMBOL_NAME (&parmsym) = "";
+ SYMBOL_INIT_LANGUAGE_SPECIFIC (&parmsym, language_c);
+ SYMBOL_NAMESPACE (&parmsym) = VAR_NAMESPACE;
+ SYMBOL_CLASS (&parmsym) = LOC_ARG;
+ /* Its other fields are zero, or are filled in later. */
}
-#endif /* IBM6000_HOST */