/* Read AIX xcoff symbol tables and convert to internal format, for GDB.
- Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 1997
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
Derived from coffread.c, dbxread.c, and a lot of hacking.
Contributed by IBM Corporation.
#include "coff/internal.h"
#include "libcoff.h" /* FIXME, internal data from BFD */
+#include "coff/xcoff.h"
+#include "libxcoff.h"
#include "coff/rs6000.h"
#include "symtab.h"
#include "buildsym.h"
#include "stabsread.h"
#include "expression.h"
-#include "language.h" /* Needed inside partial-stab.h */
#include "complaints.h"
#include "gdb-stabs.h"
/* For interface with stabsread.c. */
#include "aout/stab_gnu.h"
-/* For interface with partial-stab.h. */
-#define N_UNDF 0 /* Undefined symbol */
-#undef N_ABS
-#define N_ABS 2
-#define N_TEXT 4 /* Text sym -- defined at offset in text seg */
-#define N_DATA 6 /* Data sym -- defined at offset in data seg */
-#define N_BSS 8 /* BSS sym -- defined at offset in zero'd seg */
-#define N_COMM 0x12 /* Common symbol (visible after shared lib dynlink) */
-#define N_FN 0x1f /* File name of .o file */
-#define N_FN_SEQ 0x0C /* N_FN from Sequent compilers (sigh) */
-/* Note: N_EXT can only be usefully OR-ed with N_UNDF, N_ABS, N_TEXT,
- N_DATA, or N_BSS. When the low-order bit of other types is set,
- (e.g. N_WARNING versus N_FN), they are two different types. */
-#define N_EXT 1 /* External symbol (as opposed to local-to-this-file) */
-#define N_INDR 0x0a
-
-/* The following symbols refer to set elements.
- All the N_SET[ATDB] symbols with the same name form one set.
- Space is allocated for the set in the text section, and each set
- elements value is stored into one word of the space.
- The first word of the space is the length of the set (number of elements).
-
- The address of the set is made into an N_SETV symbol
- whose name is the same as the name of the set.
- This symbol acts like a N_DATA global symbol
- in that it can satisfy undefined external references. */
-
-/* These appear as input to LD, in a .o file. */
-#define N_SETA 0x14 /* Absolute set element symbol */
-#define N_SETT 0x16 /* Text set element symbol */
-#define N_SETD 0x18 /* Data set element symbol */
-#define N_SETB 0x1A /* Bss set element symbol */
-
-/* This is output from LD. */
-#define N_SETV 0x1C /* Pointer to set vector in data area. */
\f
/* We put a pointer to this structure in the read_symtab_private field
of the psymtab. */
static void find_targ_sec (bfd *, asection *, void *);
static void
-find_targ_sec (abfd, sect, obj)
- bfd *abfd;
- asection *sect;
- PTR obj;
+find_targ_sec (bfd *abfd, asection *sect, PTR obj)
{
struct find_targ_sec_arg *args = (struct find_targ_sec_arg *) obj;
struct objfile *objfile = args->objfile;
else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
*args->resultp = SECT_OFF_DATA (objfile);
else
- *args->resultp = SECT_OFF_BSS (objfile);
+ *args->resultp = sect->index;
*args->bfd_sect = sect;
}
}
/* Return the section number (SECT_OFF_*) that CS points to. */
static int
-secnum_to_section (secnum, objfile)
- int secnum;
- struct objfile *objfile;
+secnum_to_section (int secnum, struct objfile *objfile)
{
int off = SECT_OFF_TEXT (objfile);
asection *sect = NULL;
/* Return the BFD section that CS points to. */
static asection *
-secnum_to_bfd_section (secnum, objfile)
- int secnum;
- struct objfile *objfile;
+secnum_to_bfd_section (int secnum, struct objfile *objfile)
{
int off = SECT_OFF_TEXT (objfile);
asection *sect = NULL;
#if 0
static void
-add_stab_to_list (stabname, stabvector)
- char *stabname;
- struct pending_stabs **stabvector;
+add_stab_to_list (char *stabname, struct pending_stabs **stabvector)
{
if (*stabvector == NULL)
{
/* compare line table entry addresses. */
static int
-compare_lte (lte1p, lte2p)
- const void *lte1p;
- const void *lte2p;
+compare_lte (const void *lte1p, const void *lte2p)
{
struct linetable_entry *lte1 = (struct linetable_entry *) lte1p;
struct linetable_entry *lte2 = (struct linetable_entry *) lte2p;
sort_linevec = 1 to end_symtab. */
static struct linetable *
-arrange_linetable (oldLineTb)
- struct linetable *oldLineTb; /* old linetable */
+arrange_linetable (struct linetable *oldLineTb)
{
int ii, jj, newline, /* new line count */
function_count; /* # of functions */
if (function_count == 0)
{
- free (fentry);
+ xfree (fentry);
return oldLineTb;
}
else if (function_count > 1)
++jj, ++newline)
newLineTb->item[newline] = oldLineTb->item[jj];
}
- free (fentry);
+ xfree (fentry);
newLineTb->nitems = oldLineTb->nitems - function_count;
return newLineTb;
}
static void allocate_include_entry (void);
static void
-record_include_begin (cs)
- struct coff_symbol *cs;
+record_include_begin (struct coff_symbol *cs)
{
if (inclDepth)
{
}
static void
-record_include_end (cs)
- struct coff_symbol *cs;
+record_include_end (struct coff_symbol *cs)
{
InclTable *pTbl;
}
static void
-allocate_include_entry ()
+allocate_include_entry (void)
{
if (inclTable == NULL)
{
at times) process its lines and create appropriate line vectors. */
static void
-process_linenos (start, end)
- CORE_ADDR start, end;
+process_linenos (CORE_ADDR start, CORE_ADDR end)
{
int offset, ii;
file_ptr max_offset =
}
else
{
- free (lv);
+ xfree (lv);
current_subfile->line_vector = lineTb;
}
if (fakename == NULL)
fakename = " ?";
start_subfile (fakename, (char *) 0);
- free (current_subfile->name);
+ xfree (current_subfile->name);
}
current_subfile->name = xstrdup (inclTable[ii].name);
#endif
}
else
{
- free (lv);
+ xfree (lv);
current_subfile->line_vector = lineTb;
}
}
void
-aix_process_linenos ()
+aix_process_linenos (void)
{
/* process line numbers and enter them into line vector */
process_linenos (last_source_start_addr, cur_src_end_addr);
attention to. */
static void
-enter_line_range (subfile, beginoffset, endoffset, startaddr, endaddr,
- firstLine)
- struct subfile *subfile;
- unsigned beginoffset, endoffset; /* offsets to line table */
- CORE_ADDR startaddr, endaddr;
- unsigned *firstLine;
+enter_line_range (struct subfile *subfile, unsigned beginoffset, unsigned endoffset, /* offsets to line table */
+ CORE_ADDR startaddr, /* offsets to line table */
+ CORE_ADDR endaddr, unsigned *firstLine)
{
unsigned int curoffset;
CORE_ADDR addr;
while (curoffset <= limit_offset)
{
bfd_seek (abfd, curoffset, SEEK_SET);
- bfd_read (ext_lnno, linesz, 1, abfd);
+ bfd_bread (ext_lnno, linesz, abfd);
bfd_coff_swap_lineno_in (abfd, ext_lnno, &int_lnno);
/* Find the address this line represents. */
continuations. */
static char *
-xcoff_next_symbol_text (objfile)
- struct objfile *objfile;
+xcoff_next_symbol_text (struct objfile *objfile)
{
struct internal_syment symbol;
static struct complaint msg =
/* Read symbols for a given partial symbol table. */
static void
-read_xcoff_symtab (pst)
- struct partial_symtab *pst;
+read_xcoff_symtab (struct partial_symtab *pst)
{
struct objfile *objfile = pst->objfile;
bfd *abfd = objfile->obfd;
char *strtbl = ((struct coff_symfile_info *) objfile->sym_private)->strtbl;
char *debugsec =
((struct coff_symfile_info *) objfile->sym_private)->debugsec;
- char *debugfmt = xcoff_data (abfd)->xcoff64 ? "XCOFF64" : "XCOFF";
+ char *debugfmt = bfd_xcoff_is_xcoff64 (abfd) ? "XCOFF64" : "XCOFF";
struct internal_syment symbol[1];
union internal_auxent main_aux;
/* done with all files, everything from here on is globals */
}
- /* if explicitly specified as a function, treat is as one. */
- if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
- {
- bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
- 0, cs->c_naux, &main_aux);
- goto function_entry_point;
- }
-
if ((cs->c_sclass == C_EXT || cs->c_sclass == C_HIDEXT)
&& cs->c_naux == 1)
{
SECT_OFF_TEXT (objfile));
file_end_addr = file_start_addr + CSECT_LEN (&main_aux);
- if (cs->c_name && cs->c_name[0] == '.')
+ if (cs->c_name && (cs->c_name[0] == '.'
+ || cs->c_name[0] == '@'))
{
last_csect_name = cs->c_name;
last_csect_val = cs->c_value;
}
}
+ /* If explicitly specified as a function, treat is as one. This check
+ evaluates to true for @FIX* bigtoc CSECT symbols, so it must occur
+ after the above CSECT check. */
+ if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
+ {
+ bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
+ 0, cs->c_naux, &main_aux);
+ goto function_entry_point;
+ }
+
switch (cs->c_sclass)
{
/* process one xcoff symbol. */
static struct symbol *
-process_xcoff_symbol (cs, objfile)
- register struct coff_symbol *cs;
- struct objfile *objfile;
+process_xcoff_symbol (register struct coff_symbol *cs, struct objfile *objfile)
{
struct symbol onesymbol;
register struct symbol *sym = &onesymbol;
Result is in static storage and is only good for temporary use. */
static char *
-coff_getfilename (aux_entry, objfile)
- union internal_auxent *aux_entry;
- struct objfile *objfile;
+coff_getfilename (union internal_auxent *aux_entry, struct objfile *objfile)
{
static char buffer[BUFSIZ];
/* Set *SYMBOL to symbol number symno in symtbl. */
static void
-read_symbol (symbol, symno)
- struct internal_syment *symbol;
- int symno;
+read_symbol (struct internal_syment *symbol, int symno)
{
int nsyms =
((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private)
/* Get value corresponding to symbol number symno in symtbl. */
static CORE_ADDR
-read_symbol_nvalue (symno)
- int symno;
+read_symbol_nvalue (int symno)
{
struct internal_syment symbol[1];
symno is the symbol pointed to by the linetable. */
static int
-read_symbol_lineno (symno)
- int symno;
+read_symbol_lineno (int symno)
{
struct objfile *objfile = this_symtab_psymtab->objfile;
- boolean xcoff64 = xcoff_data (objfile->obfd)->xcoff64;
+ boolean xcoff64 = bfd_xcoff_is_xcoff64 (objfile->obfd);
struct coff_symfile_info *info =
(struct coff_symfile_info *)objfile->sym_private;
* mainline code can read the whole thing for efficiency.
*/
static void
-find_linenos (abfd, asect, vpinfo)
- bfd *abfd;
- sec_ptr asect;
- PTR vpinfo;
+find_linenos (bfd *abfd, sec_ptr asect, PTR vpinfo)
{
struct coff_symfile_info *info;
int size, count;
static void xcoff_psymtab_to_symtab_1 (struct partial_symtab *);
static void
-xcoff_psymtab_to_symtab_1 (pst)
- struct partial_symtab *pst;
+xcoff_psymtab_to_symtab_1 (struct partial_symtab *pst)
{
struct cleanup *old_chain;
int i;
Be verbose about it if the user wants that. */
static void
-xcoff_psymtab_to_symtab (pst)
- struct partial_symtab *pst;
+xcoff_psymtab_to_symtab (struct partial_symtab *pst)
{
bfd *sym_bfd;
}
\f
static void
-xcoff_new_init (objfile)
- struct objfile *objfile;
+xcoff_new_init (struct objfile *objfile)
{
stabsread_new_init ();
buildsym_new_init ();
uses BFD's determination to vector to us. */
static void
-xcoff_symfile_init (objfile)
- struct objfile *objfile;
+xcoff_symfile_init (struct objfile *objfile)
{
/* Allocate struct to keep track of the symfile */
objfile->sym_private = xmmalloc (objfile->md,
objfile struct from the global list of known objfiles. */
static void
-xcoff_symfile_finish (objfile)
- struct objfile *objfile;
+xcoff_symfile_finish (struct objfile *objfile)
{
if (objfile->sym_private != NULL)
{
- mfree (objfile->md, objfile->sym_private);
+ xmfree (objfile->md, objfile->sym_private);
}
/* Start with a fresh include table for the next objfile. */
if (inclTable)
{
- free (inclTable);
+ xfree (inclTable);
inclTable = NULL;
}
inclIndx = inclLength = inclDepth = 0;
static void
-init_stringtab (abfd, offset, objfile)
- bfd *abfd;
- file_ptr offset;
- struct objfile *objfile;
+init_stringtab (bfd *abfd, file_ptr offset, struct objfile *objfile)
{
long length;
int val;
error ("cannot seek to string table in %s: %s",
bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
- val = bfd_read ((char *) lengthbuf, 1, sizeof lengthbuf, abfd);
+ val = bfd_bread ((char *) lengthbuf, sizeof lengthbuf, abfd);
length = bfd_h_get_32 (abfd, lengthbuf);
/* If no string table is needed, then the file may end immediately
if (length == sizeof lengthbuf)
return;
- val = bfd_read (strtbl + sizeof lengthbuf, 1, length - sizeof lengthbuf,
- abfd);
+ val = bfd_bread (strtbl + sizeof lengthbuf, length - sizeof lengthbuf, abfd);
if (val != length - sizeof lengthbuf)
error ("cannot read string table from %s: %s",
(normal). */
static struct partial_symtab *
-xcoff_start_psymtab (objfile, filename, first_symnum, global_syms,
- static_syms)
- struct objfile *objfile;
- char *filename;
- int first_symnum;
- struct partial_symbol **global_syms;
- struct partial_symbol **static_syms;
+xcoff_start_psymtab (struct objfile *objfile, char *filename, int first_symnum,
+ struct partial_symbol **global_syms,
+ struct partial_symbol **static_syms)
{
struct partial_symtab *result =
start_psymtab_common (objfile, objfile->section_offsets,
are the information for includes and dependencies. */
static struct partial_symtab *
-xcoff_end_psymtab (pst, include_list, num_includes, capping_symbol_number,
- dependency_list, number_dependencies, textlow_not_set)
- struct partial_symtab *pst;
- char **include_list;
- int num_includes;
- int capping_symbol_number;
- struct partial_symtab **dependency_list;
- int number_dependencies;
- int textlow_not_set;
+xcoff_end_psymtab (struct partial_symtab *pst, char **include_list,
+ int num_includes, int capping_symbol_number,
+ struct partial_symtab **dependency_list,
+ int number_dependencies, int textlow_not_set)
{
int i;
struct objfile *objfile = pst->objfile;
the symbol and its auxents. */
static void
-swap_sym (symbol, aux, name, raw, symnump, objfile)
- struct internal_syment *symbol;
- union internal_auxent *aux;
- char **name;
- char **raw;
- unsigned int *symnump;
- struct objfile *objfile;
+swap_sym (struct internal_syment *symbol, union internal_auxent *aux,
+ char **name, char **raw, unsigned int *symnump,
+ struct objfile *objfile)
{
bfd_coff_swap_sym_in (objfile->obfd, *raw, symbol);
if (symbol->n_zeroes)
}
static void
-scan_xcoff_symtab (objfile)
- struct objfile *objfile;
+scan_xcoff_symtab (struct objfile *objfile)
{
CORE_ADDR toc_offset = 0; /* toc offset value in data section. */
char *filestring = NULL;
while (ssymnum < nsyms)
{
int sclass;
- /* This is the type we pass to partial-stab.h. A less kludgy solution
- would be to break out partial-stab.h into its various parts--shuffle
- off the DBXREAD_ONLY stuff to dbxread.c, and make separate
- pstab-norm.h (for most types), pstab-sol.h (for N_SOL), etc. */
- int stype;
QUIT;
objfile->static_psymbols.next);
}
}
- if (namestring && namestring[0] == '.')
+ /* Activate the misc_func_recorded mechanism for
+ compiler- and linker-generated CSECTs like ".strcmp"
+ and "@FIX1". */
+ if (namestring && (namestring[0] == '.'
+ || namestring[0] == '@'))
{
last_csect_name = namestring;
last_csect_val = symbol.n_value;
break;
case XMC_RW:
+ case XMC_TD:
/* Data variables are recorded in the minimal symbol
table, except for section symbols. */
if (*namestring != '.')
break;
case C_BINCL:
- stype = N_SOL;
- goto pstab;
+ {
+ /* Mark down an include file in the current psymtab */
+ enum language tmp_language;
+ swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
+ &ssymnum, objfile);
+ tmp_language = deduce_language_from_filename (namestring);
+
+ /* Only change the psymtab's language if we've learned
+ something useful (eg. tmp_language is not language_unknown).
+ In addition, to match what start_subfile does, never change
+ from C++ to C. */
+ if (tmp_language != language_unknown
+ && (tmp_language != language_c
+ || psymtab_language != language_cplus))
+ psymtab_language = tmp_language;
+
+ /* In C++, one may expect the same filename to come round many
+ times, when code is coming alternately from the main file
+ and from inline functions in other files. So I check to see
+ if this is a file we've seen before -- either the main
+ source file, or a previously included file.
+
+ This seems to be a lot of time to be spending on N_SOL, but
+ things like "break c-exp.y:435" need to work (I
+ suppose the psymtab_include_list could be hashed or put
+ in a binary tree, if profiling shows this is a major hog). */
+ if (pst && STREQ (namestring, pst->filename))
+ continue;
+ {
+ register int i;
+ for (i = 0; i < includes_used; i++)
+ if (STREQ (namestring, psymtab_include_list[i]))
+ {
+ i = -1;
+ break;
+ }
+ if (i == -1)
+ continue;
+ }
+ psymtab_include_list[includes_used++] = namestring;
+ if (includes_used >= includes_allocated)
+ {
+ char **orig = psymtab_include_list;
+
+ psymtab_include_list = (char **)
+ alloca ((includes_allocated *= 2) *
+ sizeof (char *));
+ memcpy ((PTR) psymtab_include_list, (PTR) orig,
+ includes_used * sizeof (char *));
+ }
+ continue;
+ }
case C_FUN:
/* The value of the C_FUN is not the address of the function (it
appears to be the address before linking), but as long as it
case C_ECOML:
case C_DECL:
case C_STSYM:
- stype = N_LSYM;
- pstab:
- swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
- &ssymnum, objfile);
-#define CUR_SYMBOL_TYPE stype
-#define CUR_SYMBOL_VALUE symbol.n_value
-
-/* START_PSYMTAB and END_PSYMTAB are never used, because they are only
- called from DBXREAD_ONLY or N_SO code. Likewise for the symnum
- variable. */
-#define START_PSYMTAB(ofile,fname,low,symoff,global_syms,static_syms) 0
-#define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps,textlow_not_set)\
- do {} while (0)
-/* We have already set the namestring. */
-#define SET_NAMESTRING() /* */
-
-#include "partial-stab.h"
+ {
+
+ static struct complaint function_outside_compilation_unit = {
+ "function `%s' appears to be defined outside of all compilation units", 0, 0
+ };
+
+ char *p;
+ swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
+ &ssymnum, objfile);
+
+ p = (char *) strchr (namestring, ':');
+ if (!p)
+ continue; /* Not a debugging symbol. */
+
+ /* Main processing section for debugging symbols which
+ the initial read through the symbol tables needs to worry
+ about. If we reach this point, the symbol which we are
+ considering is definitely one we are interested in.
+ p must also contain the (valid) index into the namestring
+ which indicates the debugging type symbol. */
+
+ switch (p[1])
+ {
+ case 'S':
+ symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+#ifdef STATIC_TRANSFORM_NAME
+ namestring = STATIC_TRANSFORM_NAME (namestring);
+#endif
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->static_psymbols,
+ 0, symbol.n_value,
+ psymtab_language, objfile);
+ continue;
+
+ case 'G':
+ symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ /* The addresses in these entries are reported to be
+ wrong. See the code that reads 'G's for symtabs. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->global_psymbols,
+ 0, symbol.n_value,
+ psymtab_language, objfile);
+ continue;
+
+ case 'T':
+ /* When a 'T' entry is defining an anonymous enum, it
+ may have a name which is the empty string, or a
+ single space. Since they're not really defining a
+ symbol, those shouldn't go in the partial symbol
+ table. We do pick up the elements of such enums at
+ 'check_enum:', below. */
+ if (p >= namestring + 2
+ || (p == namestring + 1
+ && namestring[0] != ' '))
+ {
+ add_psymbol_to_list (namestring, p - namestring,
+ STRUCT_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ symbol.n_value, 0,
+ psymtab_language, objfile);
+ if (p[2] == 't')
+ {
+ /* Also a typedef with the same name. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ symbol.n_value, 0,
+ psymtab_language, objfile);
+ p += 1;
+ }
+ /* The semantics of C++ state that "struct foo { ... }"
+ also defines a typedef for "foo". Unfortuantely, cfront
+ never makes the typedef when translating from C++ to C.
+ We make the typedef here so that "ptype foo" works as
+ expected for cfront translated code. */
+ else if (psymtab_language == language_cplus)
+ {
+ /* Also a typedef with the same name. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ symbol.n_value, 0,
+ psymtab_language, objfile);
+ }
+ }
+ goto check_enum;
+
+ case 't':
+ if (p != namestring) /* a name is there, not just :T... */
+ {
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ symbol.n_value, 0,
+ psymtab_language, objfile);
+ }
+ check_enum:
+ /* If this is an enumerated type, we need to
+ add all the enum constants to the partial symbol
+ table. This does not cover enums without names, e.g.
+ "enum {a, b} c;" in C, but fortunately those are
+ rare. There is no way for GDB to find those from the
+ enum type without spending too much time on it. Thus
+ to solve this problem, the compiler needs to put out the
+ enum in a nameless type. GCC2 does this. */
+
+ /* We are looking for something of the form
+ <name> ":" ("t" | "T") [<number> "="] "e"
+ {<constant> ":" <value> ","} ";". */
+
+ /* Skip over the colon and the 't' or 'T'. */
+ p += 2;
+ /* This type may be given a number. Also, numbers can come
+ in pairs like (0,26). Skip over it. */
+ while ((*p >= '0' && *p <= '9')
+ || *p == '(' || *p == ',' || *p == ')'
+ || *p == '=')
+ p++;
+
+ if (*p++ == 'e')
+ {
+ /* The aix4 compiler emits extra crud before the members. */
+ if (*p == '-')
+ {
+ /* Skip over the type (?). */
+ while (*p != ':')
+ p++;
+
+ /* Skip over the colon. */
+ p++;
+ }
+
+ /* We have found an enumerated type. */
+ /* According to comments in read_enum_type
+ a comma could end it instead of a semicolon.
+ I don't know where that happens.
+ Accept either. */
+ while (*p && *p != ';' && *p != ',')
+ {
+ char *q;
+
+ /* Check for and handle cretinous dbx symbol name
+ continuation! */
+ if (*p == '\\' || (*p == '?' && p[1] == '\0'))
+ p = next_symbol_text (objfile);
+
+ /* Point to the character after the name
+ of the enum constant. */
+ for (q = p; *q && *q != ':'; q++)
+ ;
+ /* Note that the value doesn't matter for
+ enum constants in psymtabs, just in symtabs. */
+ add_psymbol_to_list (p, q - p,
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols, 0,
+ 0, psymtab_language, objfile);
+ /* Point past the name. */
+ p = q;
+ /* Skip over the value. */
+ while (*p && *p != ',')
+ p++;
+ /* Advance past the comma. */
+ if (*p)
+ p++;
+ }
+ }
+ continue;
+
+ case 'c':
+ /* Constant, e.g. from "const" in Pascal. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols, symbol.n_value,
+ 0, psymtab_language, objfile);
+ continue;
+
+ case 'f':
+ if (! pst)
+ {
+ int name_len = p - namestring;
+ char *name = xmalloc (name_len + 1);
+ memcpy (name, namestring, name_len);
+ name[name_len] = '\0';
+ complain (&function_outside_compilation_unit, name);
+ xfree (name);
+ }
+ symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->static_psymbols,
+ 0, symbol.n_value,
+ psymtab_language, objfile);
+ continue;
+
+ /* Global functions were ignored here, but now they
+ are put into the global psymtab like one would expect.
+ They're also in the minimal symbol table. */
+ case 'F':
+ if (! pst)
+ {
+ int name_len = p - namestring;
+ char *name = xmalloc (name_len + 1);
+ memcpy (name, namestring, name_len);
+ name[name_len] = '\0';
+ complain (&function_outside_compilation_unit, name);
+ xfree (name);
+ }
+ symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->global_psymbols,
+ 0, symbol.n_value,
+ psymtab_language, objfile);
+ continue;
+
+ /* Two things show up here (hopefully); static symbols of
+ local scope (static used inside braces) or extensions
+ of structure symbols. We can ignore both. */
+ case 'V':
+ case '(':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ case '#': /* for symbol identification (used in live ranges) */
+ /* added to support cfront stabs strings */
+ case 'Z': /* for definition continuations */
+ case 'P': /* for prototypes */
+ continue;
+
+ case ':':
+ /* It is a C++ nested symbol. We don't need to record it
+ (I don't think); if we try to look up foo::bar::baz,
+ then symbols for the symtab containing foo should get
+ read in, I think. */
+ /* Someone says sun cc puts out symbols like
+ /foo/baz/maclib::/usr/local/bin/maclib,
+ which would get here with a symbol type of ':'. */
+ continue;
+
+ default:
+ /* Unexpected symbol descriptor. The second and subsequent stabs
+ of a continued stab can show up here. The question is
+ whether they ever can mimic a normal stab--it would be
+ nice if not, since we certainly don't want to spend the
+ time searching to the end of every string looking for
+ a backslash. */
+
+ complain (&unknown_symchar_complaint, p[1]);
+
+ /* Ignore it; perhaps it is an extension that we don't
+ know about. */
+ continue;
+ }
+ }
}
}
/* Return the toc offset value for a given objfile. */
CORE_ADDR
-get_toc_offset (objfile)
- struct objfile *objfile;
+get_toc_offset (struct objfile *objfile)
{
if (objfile)
return ((struct coff_symfile_info *) objfile->sym_private)->toc_offset;
table (as opposed to a shared lib or dynamically loaded file). */
static void
-xcoff_initial_scan (objfile, mainline)
- struct objfile *objfile;
- int mainline; /* FIXME comments above */
+xcoff_initial_scan (struct objfile *objfile, int mainline)
{
bfd *abfd;
int val;
((struct coff_symfile_info *) objfile->sym_private)->symtbl_num_syms =
num_symbols;
- val = bfd_read (((struct coff_symfile_info *) objfile->sym_private)->symtbl,
- size, 1, abfd);
+ val = bfd_bread (((struct coff_symfile_info *) objfile->sym_private)->symtbl,
+ size, abfd);
if (val != size)
perror_with_name ("reading symbol table");
/* If we are reinitializing, or if we have never loaded syms yet, init */
if (mainline
- || objfile->global_psymbols.size == 0
- || objfile->static_psymbols.size == 0)
+ || (objfile->global_psymbols.size == 0
+ && objfile->static_psymbols.size == 0))
/* I'm not sure how how good num_symbols is; the rule of thumb in
init_psymbol_list was developed for a.out. On the one hand,
num_symbols includes auxents. On the other hand, it doesn't
}
\f
static void
-xcoff_symfile_offsets (objfile, addrs)
- struct objfile *objfile;
- struct section_addr_info *addrs;
+xcoff_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs)
{
asection *sect = NULL;
int i;
sensibly), so just ignore the addr parameter and use 0.
rs6000-nat.c will set the correct section offsets via
objfile_relocate. */
- ANOFFSET (objfile->section_offsets, i) = 0;
+ (objfile->section_offsets)->offsets[i] = 0;
}
}
};
void
-_initialize_xcoffread ()
+_initialize_xcoffread (void)
{
add_symtab_fns (&xcoff_sym_fns);