Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This module provides three functions: mipscoff_symfile_init,
- which initializes to read a symbol file; mipscoff_new_init, which
+ which initializes to read a symbol file; mipscoff_new_init, which
discards existing cached information when all symbols are being
discarded; and mipscoff_symfile_read, which reads a symbol table
from a file.
This module can read all four of the known byte-order combinations,
on any type of host. However, it does make (and check) the assumption
- that the external form of a symbol table structure (on disk)
+ that the external form of a symbol table structure (on disk)
occupies the same number of bytes as the internal form (in a struct).
Fixing this is possible but requires larger structural changes. */
#include "gdbtypes.h"
#include "gdbcore.h"
#include "symfile.h"
+#include "objfiles.h"
#include "obstack.h"
#include "buildsym.h"
+
+#ifdef USG
+#include <sys/types.h>
+#define L_SET 0
+#define L_INCR 1
+#endif
+
#include <sys/param.h>
#include <sys/file.h>
#include <sys/stat.h>
-#ifdef CMUCS
-#include <mips/syms.h>
-#else /* not CMUCS */
-#ifndef LANGUAGE_C
-#define LANGUAGE_C
-#endif
-#include "symconst.h"
-#include "sym.h"
-#endif /* not CMUCS */
-#include "coff/mips.h"
-#include "libaout.h" /* FIXME Secret internal BFD stuff for a.out */
+#include "coff/mips.h" /* COFF-like aspects of ecoff files */
+#include "coff/ecoff-ext.h" /* External forms of ecoff sym structures */
+
+#include "libbfd.h" /* FIXME Secret internal BFD stuff (bfd_read) */
+#include "libaout.h" /* FIXME Secret internal BFD stuff for a.out */
#include "aout/aout64.h"
-#include "aout/stab_gnu.h" /* We always use GNU stabs, not native, now */
-#include "coff/ecoff-ext.h"
+#include "aout/stab_gnu.h" /* STABS information */
struct coff_exec {
struct external_filehdr f;
/* Things we import explicitly from other modules */
extern int info_verbose;
-extern struct block *block_for_pc();
-extern void sort_symtab_syms();
/* Various complaints about symbol reading that don't abort the process */
-
-struct complaint bad_file_number_complaint =
+
+struct complaint bad_file_number_complaint =
{"bad file number %d", 0, 0};
-struct complaint unknown_ext_complaint =
+struct complaint index_complaint =
+ {"bad aux index at symbol %s", 0, 0};
+
+struct complaint aux_index_complaint =
+ {"bad proc end in aux found from symbol %s", 0, 0};
+
+struct complaint unknown_ext_complaint =
{"unknown external symbol %s", 0, 0};
-struct complaint unknown_sym_complaint =
+struct complaint unknown_sym_complaint =
{"unknown local symbol %s", 0, 0};
-struct complaint unknown_st_complaint =
+struct complaint unknown_st_complaint =
{"with type %d", 0, 0};
-struct complaint block_overflow_complaint =
+struct complaint block_overflow_complaint =
{"block containing %s overfilled", 0, 0};
-struct complaint basic_type_complaint =
+struct complaint basic_type_complaint =
{"cannot map MIPS basic type 0x%x", 0, 0};
-struct complaint unknown_type_qual_complaint =
+struct complaint unknown_type_qual_complaint =
{"unknown type qualifier 0x%x", 0, 0};
-struct complaint array_bitsize_complaint =
+struct complaint array_bitsize_complaint =
{"size of array target type not known, assuming %d bits", 0, 0};
-struct complaint bad_tag_guess_complaint =
- {"guessed tag type incorrectly", 0, 0};
+struct complaint bad_tag_guess_complaint =
+ {"guessed tag type of %s incorrectly", 0, 0};
+
+struct complaint block_member_complaint =
+ {"declaration block contains unhandled symbol type %d", 0, 0};
+
+struct complaint stEnd_complaint =
+ {"stEnd with storage class %d not handled", 0, 0};
+
+struct complaint unknown_mips_symtype_complaint =
+ {"unknown symbol type 0x%x", 0, 0};
+
+struct complaint stab_unknown_complaint =
+ {"unknown stabs symbol %s", 0, 0};
+
+struct complaint pdr_for_nonsymbol_complaint =
+ {"PDR for %s, but no symbol", 0, 0};
+
+struct complaint pdr_static_symbol_complaint =
+ {"can't handle PDR for static proc at 0x%x", 0, 0};
/* Macros and extra defs */
\f
/* Things that really are local to this module */
-/* GDB symtable for the current compilation unit */
-
-static struct symtab *cur_stab;
-
/* MIPS symtab header for the current file */
static HDRR *cur_hdr;
/* Forward declarations */
static void
-fixup_symtab ();
+fixup_symtab PARAMS ((HDRR *, char *, int, bfd *));
+
+static void
+read_mips_symtab PARAMS ((struct objfile *));
static void
-read_mips_symtab ();
+read_the_mips_symtab PARAMS ((bfd *, CORE_ADDR *));
static int
-upgrade_type ();
+upgrade_type PARAMS ((struct type **, int, union aux_ext *, int));
+
+static void
+parse_partial_symbols PARAMS ((int, struct objfile *));
+
+static int
+cross_ref PARAMS ((union aux_ext *, struct type **, enum type_code, char **,
+ int));
+
+static void
+fixup_sigtramp PARAMS ((void));
+
+static struct symbol *
+new_symbol PARAMS ((char *));
+
+static struct type *
+new_type PARAMS ((char *));
+
+static struct block *
+new_block PARAMS ((int));
+
+static struct symtab *
+new_symtab PARAMS ((char *, int, int, struct objfile *));
+
+static struct linetable *
+new_linetable PARAMS ((int));
+
+static struct blockvector *
+new_bvect PARAMS ((int));
+
+static struct type *
+parse_type PARAMS ((union aux_ext *, int *, int));
+
+static struct symbol *
+mylookup_symbol PARAMS ((char *, struct block *, enum namespace,
+ enum address_class));
+
+static struct block *
+shrink_block PARAMS ((struct block *, struct symtab *));
+
+static PTR
+xzalloc PARAMS ((unsigned int));
static void
-parse_partial_symbols();
+sort_blocks PARAMS ((struct symtab *));
static int
-cross_ref();
+compare_blocks PARAMS ((const void *, const void *));
+
+static struct partial_symtab *
+new_psymtab PARAMS ((char *, struct objfile *));
+
+#if 0
+static struct partial_symtab *
+parse_fdr PARAMS ((int, int, struct objfile *));
+#endif
static void
-fixup_sigtramp();
-
-static struct symbol *new_symbol();
-static struct type *new_type();
-static struct block *new_block();
-static struct symtab *new_symtab();
-static struct linetable *new_linetable();
-static struct blockvector *new_bvect();
-
-static struct type *parse_type();
-static struct symbol *mylookup_symbol();
-static struct block *shrink_block();
-static void sort_blocks();
-
-static int compare_symtabs();
-static int compare_psymtabs();
-static int compare_blocks();
-
-static struct partial_symtab *new_psymtab();
-static struct partial_symtab *parse_fdr();
-static int compare_psymbols();
-
-static void psymtab_to_symtab_1();
-static void add_block();
-static void add_symbol();
-static int add_line();
-static struct linetable *shrink_linetable();
-static char* mips_next_symbol_text ();
+psymtab_to_symtab_1 PARAMS ((struct partial_symtab *, char *));
+static void
+add_block PARAMS ((struct block *, struct symtab *));
+
+static void
+add_symbol PARAMS ((struct symbol *, struct block *));
+
+static int
+add_line PARAMS ((struct linetable *, int, CORE_ADDR, int));
+
+static struct linetable *
+shrink_linetable PARAMS ((struct linetable *));
+
+static char *
+mips_next_symbol_text PARAMS ((void));
\f
/* Things we export to other modules */
CORE_ADDR sigtramp_address, sigtramp_end;
-/* The entry point (starting address) of the file, if it is an executable. */
-
-extern CORE_ADDR startup_file_start; /* From blockframe.c */
-extern CORE_ADDR startup_file_end; /* From blockframe.c */
-
-void
-mipscoff_new_init()
+static void
+mipscoff_new_init (ignore)
+ struct objfile *ignore;
{
- /* If we have a file symbol header lying around, blow it away. */
- if (cur_hdr)
- free ((char *)cur_hdr);
- cur_hdr = 0;
}
-void
-mipscoff_symfile_init (sf)
- struct sym_fns *sf;
+static void
+mipscoff_symfile_init (objfile)
+ struct objfile *objfile;
{
- sf->sym_private = NULL;
+ if (objfile -> sym_private != NULL)
+ {
+ mfree (objfile -> md, objfile -> sym_private);
+ }
+ objfile -> sym_private = NULL;
}
-void
-mipscoff_symfile_read(sf, addr, mainline)
- struct sym_fns *sf;
+static void
+mipscoff_symfile_read (objfile, addr, mainline)
+ struct objfile *objfile;
CORE_ADDR addr;
int mainline;
{
- struct coff_symfile_info *info = (struct coff_symfile_info *)sf->sym_private;
- bfd *abfd = sf->objfile->obfd;
- char *name = bfd_get_filename (abfd);
- int desc;
- register int val;
- int symtab_offset;
- int stringtab_offset;
-
-/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
- desc = fileno ((FILE *)(abfd->iostream)); /* Raw file descriptor */
-/* End of warning */
-
- /* Position to read the symbol table. */
- val = lseek (desc, (long)symtab_offset, 0);
- if (val < 0)
- perror_with_name (name);
-
init_minimal_symbol_collection ();
make_cleanup (discard_minimal_symbols, 0);
/* Now that the executable file is positioned at symbol table,
process it and define symbols accordingly. */
- read_mips_symtab(sf->objfile, desc);
+ read_mips_symtab(objfile);
/* Install any minimal symbols that have been collected as the current
minimal symbols for this objfile. */
- install_minimal_symbols (sf -> objfile);
+ install_minimal_symbols (objfile);
}
-
+
+/* Perform any local cleanups required when we are done with a particular
+ objfile. I.E, we are in the process of discarding all symbol information
+ for an objfile, freeing up all memory held for it, and unlinking the
+ objfile struct from the global list of known objfiles. */
+
+static void
+mipscoff_symfile_finish (objfile)
+ struct objfile *objfile;
+{
+ if (objfile -> sym_private != NULL)
+ {
+ mfree (objfile -> md, objfile -> sym_private);
+ }
+
+ /* If we have a file symbol header lying around, blow it away. */
+
+ if (cur_hdr)
+ {
+ free ((PTR)cur_hdr);
+ }
+ cur_hdr = 0;
+}
+
/* Allocate zeroed memory */
-static char *
+static PTR
xzalloc(size)
+ unsigned int size;
{
- char *p = xmalloc(size);
+ PTR p = xmalloc (size);
- memset(p, 0, size);
- return p;
+ memset (p, 0, size);
+ return p;
}
/* Exported procedure: Builds a symtab from the PST partial one.
mipscoff_psymtab_to_symtab(pst)
struct partial_symtab *pst;
{
- struct symtab *ret;
- int i;
if (!pst)
return;
/* Exported procedure: Is PC in the signal trampoline code */
int
-in_sigtramp(pc, name)
+in_sigtramp(pc, ignore)
CORE_ADDR pc;
- char *name;
+ char *ignore; /* function name */
{
if (sigtramp_address == 0)
fixup_sigtramp();
\f
/* File-level interface functions */
-/* Read the symtab information from file FSYM into memory. Also,
+/* Read the symtab information from file ABFD into memory. Also,
return address just past end of our text segment in *END_OF_TEXT_SEGP. */
-static
-read_the_mips_symtab(abfd, fsym, end_of_text_segp)
- bfd *abfd;
- int fsym;
+static void
+read_the_mips_symtab(abfd, end_of_text_segp)
+ bfd *abfd;
CORE_ADDR *end_of_text_segp;
{
int stsize, st_hdrsize;
HDRR st_hdr;
/* Header for executable/object file we read symbols from */
struct coff_exec filhdr;
+ int val;
- /* We get here with DESC pointing to the symtab header. But we need
- * other info from the initial headers */
- lseek(fsym, 0L, 0);
- myread(fsym, (char *)&filhdr, sizeof filhdr);
+ /* We need some info from the initial headers */
+ val = bfd_seek(abfd, 0L, L_SET);
+ val = bfd_read((PTR)&filhdr, sizeof filhdr, 1, abfd);
if (end_of_text_segp)
*end_of_text_segp =
st_hdrsize = bfd_h_get_32 (abfd, filhdr.f.f_nsyms);
st_filptr = bfd_h_get_32 (abfd, filhdr.f.f_symptr);
if (st_filptr == 0)
- return 0;
+ return;
- lseek(fsym, st_filptr, L_SET);
+ bfd_seek (abfd, st_filptr, L_SET);
if (st_hdrsize != sizeof (hdr_ext)) { /* Profanity check */
error ("Wrong header size: %d, not %d", st_hdrsize,
sizeof (hdr_ext));
}
- if (read(fsym, &hdr_ext, st_hdrsize) != st_hdrsize)
+ if (bfd_read((PTR)&hdr_ext, st_hdrsize, 1, abfd) != st_hdrsize)
goto readerr;
ecoff_swap_hdr_in (abfd, &hdr_ext, &st_hdr);
/* Allocate space for the symbol table. Read it in. */
cur_hdr = (HDRR *) xmalloc(stsize + st_hdrsize);
- memcpy(cur_hdr, &hdr_ext, st_hdrsize);
- if (read(fsym, (char *) cur_hdr + st_hdrsize, stsize) != stsize)
+ memcpy((PTR)cur_hdr, (PTR)&hdr_ext, st_hdrsize);
+ if (bfd_read((char *)cur_hdr + st_hdrsize, stsize, 1, abfd) != stsize)
goto readerr;
/* Fixup file_pointers in it */
int f_ptr;
bfd *abfd;
{
- int f_idx, s_idx;
+ int f_idx, s_idx, i;
FDR *fh;
SYMR *sh;
PDR *pr;
EXTR *esh;
+ struct rfd_ext *rbase;
/* This function depends on the external and internal forms
of the MIPS symbol table taking identical space. Check this
assumption at compile-time. */
+#if 0 /* FIXME: Unused */
static check_hdr1[1 + sizeof (struct hdr_ext) - sizeof (HDRR)] = {0};
static check_hdr2[1 + sizeof (HDRR) - sizeof (struct hdr_ext)] = {0};
static check_fdr1[1 + sizeof (struct fdr_ext) - sizeof (FDR)] = {0};
static check_sym2[1 + sizeof (SYMR) - sizeof (struct sym_ext)] = {0};
static check_ext1[1 + sizeof (struct ext_ext) - sizeof (EXTR)] = {0};
static check_ext2[1 + sizeof (EXTR) - sizeof (struct ext_ext)] = {0};
+ static check_rfd1[1 + sizeof (struct rfd_ext) - sizeof (RFDT)] = {0};
+ static check_rfd2[1 + sizeof (RFDT) - sizeof (struct rfd_ext)] = {0};
+#endif
/* Swap in the header record. */
ecoff_swap_hdr_in (abfd, hdr, hdr);
FIX(cbExtOffset);
#undef FIX
+ /* Fix all the RFD's. */
+ rbase = (struct rfd_ext *)(hdr->cbRfdOffset);
+ for (i = 0; i < hdr->crfd; i++) {
+ ecoff_swap_rfd_in (abfd, rbase+i, (pRFDT) rbase+i);
+ }
/* Fix all string pointers inside the symtab, and
the FDR records. Also fix other miscellany. */
/* Read in and parse the symtab of the file DESC. INCREMENTAL says
- whether we are adding to the general symtab or not.
+ whether we are adding to the general symtab or not.
FIXME: INCREMENTAL is currently always zero, though it should not be. */
static void
-read_mips_symtab (objfile, desc)
+read_mips_symtab (objfile)
struct objfile *objfile;
- int desc;
{
CORE_ADDR end_of_text_seg;
- read_the_mips_symtab(objfile->obfd, desc, &end_of_text_seg);
+ read_the_mips_symtab(objfile->obfd, &end_of_text_seg);
parse_partial_symbols(end_of_text_seg, objfile);
/* Enter a new lexical context */
-static push_parse_stack()
+static void
+push_parse_stack()
{
struct parse_stack *new;
/* Exit a lexical context */
-static pop_parse_stack()
+static void
+pop_parse_stack()
{
if (!top_stack)
return;
/* Check whether we already saw symbol SH in file FH as undefined */
-static
-struct mips_pending *is_pending_symbol(fh, sh)
+static struct mips_pending *
+is_pending_symbol(fh, sh)
FDR *fh;
SYMR *sh;
{
return p;
}
-/* Check whether we already saw type T in file FH as undefined */
-
-static
-struct mips_pending *is_pending_type(fh, t)
- FDR *fh;
- struct type *t;
-{
- int f_idx = fh - (FDR *) cur_hdr->cbFdOffset;
- register struct mips_pending *p;
-
- for (p = pending_list[f_idx]; p; p = p->next)
- if (p->t == t)
- break;
- return p;
-}
-
/* Add a new undef symbol SH of type T */
-static
+static void
add_pending(fh, sh, t)
FDR *fh;
SYMR *sh;
}
/* Throw away undef entries when done with file index F_IDX */
+/* FIXME -- storage leak. This is never called!!! --gnu */
+
+#if 0
-static
+static void
free_pending(f_idx)
+ int f_idx;
{
register struct mips_pending *p, *q;
for (p = pending_list[f_idx]; p; p = q) {
q = p->next;
- free(p);
+ free((PTR)p);
}
pending_list[f_idx] = 0;
}
-/* The number of args to a procedure is not explicit in the symtab,
- this is the list of all those we know of.
- This makes parsing more reasonable and avoids extra passes */
-
-static struct numarg {
- struct numarg *next; /* link */
- unsigned adr; /* procedure's start address */
- unsigned num; /* arg count */
-} *numargs_list;
-
-/* Record that the procedure at ADR takes NUM arguments. */
-
-static
-got_numargs(adr,num)
-{
- struct numarg *n = (struct numarg *) xmalloc(sizeof(struct numarg));
-
- n->adr = adr;
- n->num = num;
- n->next = numargs_list;
- numargs_list = n;
-}
-
-/* See if we know how many arguments the procedure at ADR takes */
-
-static
-lookup_numargs(adr)
-{
- struct numarg *n = numargs_list;
-
- while (n && n->adr != adr)
- n = n->next;
- return (n) ? n->num : -1;
-}
-
-/* Release storage when done with this file */
-
-static void
-free_numargs()
-{
- struct numarg *n = numargs_list, *m;
-
- while (n) {
- m = n->next;
- free(n);
- n = m;
- }
- numargs_list = 0;
-}
+#endif
-char*
+static char *
prepend_tag_kind(tag_name, type_code)
char *tag_name;
- int type_code;
+ enum type_code type_code;
{
char *prefix;
char *result;
class = LOC_STATIC;
b = BLOCKVECTOR_BLOCK(BLOCKVECTOR(top_stack->cur_st),
GLOBAL_BLOCK);
- s = new_symbol(sh->iss);
+ s = new_symbol((char *)sh->iss);
SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value;
goto data;
case stStatic: /* static data, goes into current block. */
class = LOC_STATIC;
b = top_stack->cur_block;
- s = new_symbol(sh->iss);
+ s = new_symbol((char *)sh->iss);
SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value;
goto data;
} else
class = LOC_LOCAL;
b = top_stack->cur_block;
- s = new_symbol(sh->iss);
+ s = new_symbol((char *)sh->iss);
SYMBOL_VALUE(s) = sh->value;
data: /* Common code for symbols describing data */
name = (char*)sh->iss;
/* Special GNU C++ name. */
if (name[0] == CPLUS_MARKER && name[1] == 't' && name[2] == 0)
- name = "this";
+ name = "this"; /* FIXME, not alloc'd in obstack */
s = new_symbol(name);
SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
break;
case stLabel: /* label, goes into current block */
- s = new_symbol(sh->iss);
+ s = new_symbol((char *)sh->iss);
SYMBOL_NAMESPACE(s) = VAR_NAMESPACE; /* so that it can be used */
SYMBOL_CLASS(s) = LOC_LABEL; /* but not misused */
SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value;
case stProc: /* Procedure, usually goes into global block */
case stStaticProc: /* Static procedure, goes into current block */
- s = new_symbol(sh->iss);
+ s = new_symbol((char *)sh->iss);
SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
SYMBOL_CLASS(s) = LOC_BLOCK;
/* Type of the return value */
/* Make a type for the procedure itself */
#if 0
/* FIXME: This has not been tested yet! See dbxread.c */
- /* Generate a template for the type of this function. The
- types of the arguments will be added as we read the symbol
+ /* Generate a template for the type of this function. The
+ types of the arguments will be added as we read the symbol
table. */
bcopy(SYMBOL_TYPE(s),lookup_function_type(t),sizeof(struct type));
#else
sh->value = (long) SYMBOL_TYPE(s);
break;
+ /* Beginning of code for structure, union, and enum definitions.
+ They all share a common set of local variables, defined here. */
+ {
+ enum type_code type_code;
+ SYMR *tsym;
+ int nfields;
+ long max_value;
+ struct field *f;
-#ifndef btVoid /* btVoid was added late. */
-#define btVoid 26
-#endif
-/* These new symbol types have been recently added to SGI machines. */
-#ifndef stStruct
-#define stStruct 26
-#endif
-#ifndef stUnion
-#define stUnion 27
-#endif
-#ifndef stEnum
-#define stEnum 28
-#endif
- case stStruct:
- case stUnion:
- case stEnum:
+ case stStruct: /* Start a block defining a struct type */
+ type_code = TYPE_CODE_STRUCT;
+ goto structured_common;
+
+ case stUnion: /* Start a block defining a union type */
+ type_code = TYPE_CODE_UNION;
+ goto structured_common;
+
+ case stEnum: /* Start a block defining an enum type */
+ type_code = TYPE_CODE_ENUM;
+ goto structured_common;
case stBlock: /* Either a lexical block, or some type */
+ if (sh->sc != scInfo)
+ goto case_stBlock_code; /* Lexical block */
+
+ type_code = TYPE_CODE_UNDEF; /* We have a type. */
+
+ /* Common code for handling struct, union, enum, and/or as-yet-
+ unknown-type blocks of info about structured data. `type_code'
+ has been set to the proper TYPE_CODE, if we know it. */
+ structured_common:
push_parse_stack();
top_stack->blocktype = stBlock;
- if (sh->sc == scInfo) { /* structure/union/enum def */
- int type_code =
- sh->st == stStruct ? TYPE_CODE_STRUCT
- : sh->st == stUnion ? TYPE_CODE_UNION
- : sh->st == stEnum ? TYPE_CODE_ENUM
- : TYPE_CODE_UNDEF;
- int nfields = 0;
- SYMR *tsym;
- long max_value = 0;
- struct field *f;
-
- s = new_symbol(sh->iss);
- SYMBOL_NAMESPACE(s) = STRUCT_NAMESPACE;
- SYMBOL_CLASS(s) = LOC_TYPEDEF;
- SYMBOL_VALUE(s) = 0;
- add_symbol(s, top_stack->cur_block);
- /* First count the number of fields. */
- for (tsym = sh+1; tsym->st != stEnd; tsym++)
- if (tsym->st == stMember) {
- if (nfields == 0 && type_code == TYPE_CODE_UNDEF)
- /* If the type of the member is Nil (or Void)
- assume the tag is an enumeration. */
- if (tsym->index == indexNil)
+ s = new_symbol((char *)sh->iss);
+ SYMBOL_NAMESPACE(s) = STRUCT_NAMESPACE;
+ SYMBOL_CLASS(s) = LOC_TYPEDEF;
+ SYMBOL_VALUE(s) = 0;
+ add_symbol(s, top_stack->cur_block);
+
+ /* First count the number of fields and the highest value. */
+ nfields = 0;
+ max_value = 0;
+ for (tsym = sh+1; tsym->st != stEnd; tsym++)
+ {
+ if (tsym->st == stMember) {
+ if (nfields == 0 && type_code == TYPE_CODE_UNDEF)
+ /* If the type of the member is Nil (or Void),
+ assume the tag is an enumeration. */
+ if (tsym->index == indexNil)
+ type_code = TYPE_CODE_ENUM;
+ else {
+ ecoff_swap_tir_in (bigend,
+ &ax[tsym->index].a_ti,
+ &tir);
+ if (tir.bt == btNil || tir.bt == btVoid)
type_code = TYPE_CODE_ENUM;
- else {
- ecoff_swap_tir_in (bigend,
- &ax[tsym->index].a_ti,
- &tir);
- if (tir.bt == btNil || tir.bt == btVoid)
- type_code = TYPE_CODE_ENUM;
- }
- nfields++;
- if (tsym->value > max_value)
- max_value = tsym->value;
- }
- else if (tsym->st == stBlock
- || tsym->st == stParsed) {
- if (tsym->sc == scVariant) ; /*UNIMPLEMENTED*/
- if (tsym->index != 0)
- tsym = ((SYMR*)cur_fdr->isymBase)
- + tsym->index-1;
- }
-
- /* There is no guaranteed way to distinguish struct,
- unions, and enums at this point. This is a bug in the
- original design (that has been fixed with the
- recent addition of the stStruct, stUnion, and stEnum
- symbol types.) The way you can tell is if/when you
- see a variable or field of that type: In that case
- the variable's type (in the AUX table) says if the
- type is struct, union, or enum,
- and points back to the stBlock here.
- So you can patch the tag kind up later - but only
- if there actually is a variable or field of that type.
-
- So until we know for sure, we will guess at this point.
- The heuristic is:
- If the first member has index==indexNil or a void type,
- assume we have an enumeration.
- Otherwise, if there is more than one member, and all
- the members have offset 0, assume we have a union.
- Otherwise, assume we have a struct.
-
- The heuristic could guess wrong in the case of
- of an enumeration with no members or a union
- with one (or zero) members, or when all except the
- last field of a struct have width zero.
- These are uncommon and/or illegal situations, and
- in any case guessing wrong probably doesn't matter much.
-
- But if we later do find out we were wrong,
- we fixup the tag kind. Members of an enumeration
- must be handled differently from struct/union fields,
- and that is harder to patch up, but luckily we
- shouldn't need to. (If there are any enumeration
- members, we can tell for sure it's an enum here.) */
-
- if (type_code == TYPE_CODE_UNDEF)
- if (nfields > 1 && max_value == 0)
- type_code = TYPE_CODE_UNION;
- else
- type_code = TYPE_CODE_STRUCT;
-
- /* If this type was expected, use its partial definition */
- if (pend)
- t = is_pending_symbol(cur_fdr, sh)->t;
+ }
+ nfields++;
+ if (tsym->value > max_value)
+ max_value = tsym->value;
+ }
+ else if (tsym->st == stBlock
+ || tsym->st == stUnion
+ || tsym->st == stEnum
+ || tsym->st == stStruct
+ || tsym->st == stParsed) {
+ if (tsym->sc == scVariant) ; /*UNIMPLEMENTED*/
+ if (tsym->index != 0)
+ tsym = ((SYMR*)cur_fdr->isymBase)
+ + tsym->index-1;
+ }
+ else complain (&block_member_complaint, (char *)tsym->st);
+ }
+
+ /* In an stBlock, there is no way to distinguish structs,
+ unions, and enums at this point. This is a bug in the
+ original design (that has been fixed with the
+ recent addition of the stStruct, stUnion, and stEnum
+ symbol types.) The way you can tell is if/when you
+ see a variable or field of that type. In that case
+ the variable's type (in the AUX table) says if the
+ type is struct, union, or enum,
+ and points back to the stBlock here.
+ So you can patch the tag kind up later - but only
+ if there actually is a variable or field of that type.
+
+ So until we know for sure, we will guess at this point.
+ The heuristic is:
+ If the first member has index==indexNil or a void type,
+ assume we have an enumeration.
+ Otherwise, if there is more than one member, and all
+ the members have offset 0, assume we have a union.
+ Otherwise, assume we have a struct.
+
+ The heuristic could guess wrong in the case of
+ of an enumeration with no members or a union
+ with one (or zero) members, or when all except the
+ last field of a struct have width zero.
+ These are uncommon and/or illegal situations, and
+ in any case guessing wrong probably doesn't matter much.
+
+ But if we later do find out we were wrong,
+ we fixup the tag kind. Members of an enumeration
+ must be handled differently from struct/union fields,
+ and that is harder to patch up, but luckily we
+ shouldn't need to. (If there are any enumeration
+ members, we can tell for sure it's an enum here.) */
+
+ if (type_code == TYPE_CODE_UNDEF)
+ if (nfields > 1 && max_value == 0)
+ type_code = TYPE_CODE_UNION;
else
- t = new_type(prepend_tag_kind(sh->iss, type_code));
-
- TYPE_CODE(t) = type_code;
- TYPE_LENGTH(t) = sh->value;
- TYPE_NFIELDS(t) = nfields;
- TYPE_FIELDS(t) = f = (struct field*)
- obstack_alloc (¤t_objfile -> type_obstack,
- nfields * sizeof (struct field));
-
- if (type_code == TYPE_CODE_ENUM) {
- /* This is a non-empty enum. */
- for (tsym = sh + 1; tsym->st == stMember; tsym++) {
- struct symbol *enum_sym;
- f->bitpos = tsym->value;
- f->type = t;
- f->name = (char*)tsym->iss;
- f->bitsize = 0;
-
- enum_sym = (struct symbol *)
- obstack_alloc (¤t_objfile->symbol_obstack,
- sizeof (struct symbol));
- memset (enum_sym, 0, sizeof (struct symbol));
- SYMBOL_NAME (enum_sym) = f->name;
- SYMBOL_CLASS (enum_sym) = LOC_CONST;
- SYMBOL_TYPE (enum_sym) = t;
- SYMBOL_NAMESPACE (enum_sym) = VAR_NAMESPACE;
- SYMBOL_VALUE (enum_sym) = tsym->value;
- add_symbol(enum_sym, top_stack->cur_block);
-
- /* Skip the stMembers that we've handled. */
- count++;
- f++;
- }
+ type_code = TYPE_CODE_STRUCT;
+
+ /* If this type was expected, use its partial definition */
+ if (pend)
+ t = is_pending_symbol(cur_fdr, sh)->t;
+ else
+ t = new_type(prepend_tag_kind((char *)sh->iss,
+ type_code));
+
+ TYPE_CODE(t) = type_code;
+ TYPE_LENGTH(t) = sh->value;
+ TYPE_NFIELDS(t) = nfields;
+ TYPE_FIELDS(t) = f = (struct field*)
+ obstack_alloc (¤t_objfile -> type_obstack,
+ nfields * sizeof (struct field));
+
+ if (type_code == TYPE_CODE_ENUM) {
+ /* This is a non-empty enum. */
+ for (tsym = sh + 1; tsym->st == stMember; tsym++) {
+ struct symbol *enum_sym;
+ f->bitpos = tsym->value;
+ f->type = t;
+ f->name = (char*)tsym->iss;
+ f->bitsize = 0;
+
+ enum_sym = (struct symbol *)
+ obstack_alloc (¤t_objfile->symbol_obstack,
+ sizeof (struct symbol));
+ memset ((PTR)enum_sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (enum_sym) = f->name;
+ SYMBOL_CLASS (enum_sym) = LOC_CONST;
+ SYMBOL_TYPE (enum_sym) = t;
+ SYMBOL_NAMESPACE (enum_sym) = VAR_NAMESPACE;
+ SYMBOL_VALUE (enum_sym) = tsym->value;
+ add_symbol(enum_sym, top_stack->cur_block);
+
+ /* Skip the stMembers that we've handled. */
+ count++;
+ f++;
}
- SYMBOL_TYPE(s) = t;
- /* make this the current type */
- top_stack->cur_type = t;
- top_stack->cur_field = 0;
- /* Mark that symbol has a type, and say which one */
- sh->value = (long) t;
- } else {
- /* beginnning of (code) block. Value of symbol
- is the displacement from procedure start */
- b = new_block(top_stack->maxsyms);
- BLOCK_START(b) = sh->value + top_stack->procadr;
- BLOCK_SUPERBLOCK(b) = top_stack->cur_block;
- top_stack->cur_block = b;
- add_block(b, top_stack->cur_st);
}
+ SYMBOL_TYPE(s) = t;
+ /* make this the current type */
+ top_stack->cur_type = t;
+ top_stack->cur_field = 0;
+ /* Mark that symbol has a type, and say which one */
+ sh->value = (long) t;
+ break;
+
+ /* End of local variables shared by struct, union, enum, and
+ block (as yet unknown struct/union/enum) processing. */
+ }
+
+ case_stBlock_code:
+ /* beginnning of (code) block. Value of symbol
+ is the displacement from procedure start */
+ push_parse_stack();
+ top_stack->blocktype = stBlock;
+ b = new_block(top_stack->maxsyms);
+ BLOCK_START(b) = sh->value + top_stack->procadr;
+ BLOCK_SUPERBLOCK(b) = top_stack->cur_block;
+ top_stack->cur_block = b;
+ add_block(b, top_stack->cur_st);
break;
case stEnd: /* end (of anything) */
top_stack->blocktype == stStaticProc)) {
/* Finished with procedure */
struct blockvector *bv = BLOCKVECTOR(top_stack->cur_st);
+ struct mips_extra_func_info *e;
struct block *b;
int i;
BLOCK_END(top_stack->cur_block) += sh->value; /* size */
- got_numargs(top_stack->procadr, top_stack->numargs);
+
+ /* Make up special symbol to contain procedure specific
+ info */
+ s = new_symbol(".gdbinfo.");
+ SYMBOL_NAMESPACE(s) = LABEL_NAMESPACE;
+ SYMBOL_CLASS(s) = LOC_CONST;
+ SYMBOL_TYPE(s) = builtin_type_void;
+ e = (struct mips_extra_func_info *)
+ obstack_alloc (¤t_objfile->symbol_obstack,
+ sizeof (struct mips_extra_func_info));
+ SYMBOL_VALUE(s) = (int)e;
+ e->numargs = top_stack->numargs;
+ add_symbol(s, top_stack->cur_block);
+
/* Reallocate symbols, saving memory */
b = shrink_block(top_stack->cur_block, top_stack->cur_st);
is the displacement from the procedure`s start
address of the end of this block. */
BLOCK_END(top_stack->cur_block) = sh->value + top_stack->procadr;
- (void) shrink_block(top_stack->cur_block, top_stack->cur_st);
- }
+ shrink_block(top_stack->cur_block, top_stack->cur_st);
+ } else complain (&stEnd_complaint, (char *)sh->sc);
+
pop_parse_stack(); /* restore previous lexical context */
break;
break;
case stTypedef: /* type definition */
- s = new_symbol(sh->iss);
+ s = new_symbol((char *)sh->iss);
SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
SYMBOL_CLASS(s) = LOC_TYPEDEF;
SYMBOL_BLOCK_VALUE(s) = top_stack->cur_block;
case stConstant:
break; /* constant */
default:
- error("Unknown symbol type %x.", sh->st);
+ complain(&unknown_mips_symtype_complaint, (char *)sh->st);
+ break;
}
sh->st = stParsed;
return count;
We must byte-swap the AX entries before we use them; BIGEND says whether
they are big-endian or little-endian (from fh->fBigendian). */
-static struct type *parse_type(ax, bs, bigend)
+static struct type *
+parse_type(ax, bs, bigend)
union aux_ext *ax;
int *bs;
int bigend;
0, /* btBit */
0, /* btPicture */
&builtin_type_void, /* btVoid */
+ &builtin_type_long_long, /* btLongLong */
+ &builtin_type_unsigned_long_long,/* btULongLong */
};
TIR t[1];
struct type *tp = 0;
char *fmt;
- int i;
union aux_ext *tax;
- int type_code;
+ enum type_code type_code;
/* Use aux as a type information record, map its basic type. */
tax = ax;
ecoff_swap_tir_in (bigend, &tax->a_ti, t);
if (t->bt > (sizeof (map_bt)/sizeof (*map_bt))) {
- complain (&basic_type_complaint, t->bt);
+ complain (&basic_type_complaint, (char *)t->bt);
return builtin_type_int;
}
if (map_bt[t->bt]) {
break;
case btTypedef:
default:
- complain (&basic_type_complaint, t->bt);
+ complain (&basic_type_complaint, (char *)t->bt);
return builtin_type_int;
}
}
ax += cross_ref(ax, &tp, type_code, &pn, bigend);
/* reading .o file ? */
if (UNSAFE_DATA_ADDR(tp))
- tp = init_type(type_code, 0, 0, 0, (struct objfile *) NULL);
+ tp = init_type(type_code, 0, 0, (char *) NULL,
+ (struct objfile *) NULL);
/* SOMEONE OUGHT TO FIX DBXREAD TO DROP "STRUCT" */
sprintf(name, fmt, pn);
/* Usually, TYPE_CODE(tp) is already type_code. The main
exception is if we guessed wrong re struct/union/enum. */
if (TYPE_CODE(tp) != type_code) {
- complain (&bad_tag_guess_complaint, 0);
+ complain (&bad_tag_guess_complaint, name);
TYPE_CODE(tp) = type_code;
}
if (TYPE_NAME(tp) == NULL || strcmp(TYPE_NAME(tp), name) != 0)
/* Deal with range types */
if (t->bt == btRange) {
- struct field *f;
-
TYPE_NFIELDS (tp) = 2;
TYPE_FIELDS (tp) =
(struct field *) obstack_alloc (¤t_objfile -> type_obstack,
static int
upgrade_type(tpp, tq, ax, bigend)
struct type **tpp;
+ int tq;
union aux_ext *ax;
int bigend;
{
case tqArray:
off = 0;
- t = init_type(TYPE_CODE_ARRAY, 0, 0, 0, (struct objfile *) NULL);
+ t = init_type(TYPE_CODE_ARRAY, 0, 0, (char *) NULL,
+ (struct objfile *) NULL);
TYPE_TARGET_TYPE(t) = *tpp;
/* Determine and record the domain type (type of index) */
/* FIXME - Memory leak! */
if (TYPE_NFIELDS(t))
TYPE_FIELDS(t) = (struct field*)
- xrealloc((char *) TYPE_FIELDS(t),
+ xrealloc((PTR) TYPE_FIELDS(t),
(TYPE_NFIELDS(t)+1) * sizeof(struct field));
else
TYPE_FIELDS(t) = (struct field*)
xzalloc(sizeof(struct field));
f = &(TYPE_FIELD(t,TYPE_NFIELDS(t)));
TYPE_NFIELDS(t)++;
- memset(f, 0, sizeof(struct field));
+ memset((PTR)f, 0, sizeof(struct field));
-/* XXX */ f->type = parse_type(fh->iauxBase + id * sizeof(union aux_ext),
+/* XXX */ f->type = parse_type(id + (union aux_ext *)fh->iauxBase,
&f->bitsize, bigend);
ax++;
TYPE_LENGTH(TYPE_TARGET_TYPE(t)) = id >> 3;
}
if (id != rf)
- complain (&array_bitsize_complaint, rf);
+ complain (&array_bitsize_complaint, (char *)rf);
TYPE_LENGTH(t) = (upper < 0) ? 0 :
(upper - lower + 1) * (rf >> 3);
/* Volatile -- currently ignored */
return 0;
+ case tqConst:
+ /* Const -- currently ignored */
+ return 0;
+
default:
- complain (&unknown_type_qual_complaint, tq);
+ complain (&unknown_type_qual_complaint, (char *)tq);
return 0;
}
}
/* Parse a procedure descriptor record PR. Note that the procedure
- is parsed _after_ the local symbols, now we just make up the
- extra information we need into a special symbol that we insert
- in the procedure's main block. Note also that images that
+ is parsed _after_ the local symbols, now we just insert the extra
+ information we need into a special ".gdbinfo." symbol that has already
+ been placed in the procedure's main block. Note also that images that
have been partially stripped (ld -x) have been deprived
of local symbols, and we have to cope with them here.
The procedure's code ends at BOUND */
-static
-parse_procedure(pr, bound)
+static void
+parse_procedure (pr, bound, have_stabs)
PDR *pr;
+ int bound;
+ int have_stabs;
{
- struct symbol *s, *i;
- SYMR *sh = (SYMR*)pr->isym;
- struct block *b;
- struct mips_extra_func_info *e;
- char name[100];
- char *sh_name;
-
- /* Reuse the MIPS record */
- e = (struct mips_extra_func_info *) pr;
- e->numargs = lookup_numargs(pr->adr);
-
- /* Make up our special symbol */
- i = new_symbol(".gdbinfo.");
- SYMBOL_VALUE(i) = (int)e;
- SYMBOL_NAMESPACE(i) = LABEL_NAMESPACE;
- SYMBOL_CLASS(i) = LOC_CONST;
- SYMBOL_TYPE(i) = builtin_type_void;
-
- /* Make up a name for static procedures. Sigh. */
- if (sh == (SYMR*)-1) {
- sprintf(name,".static_procedure@%x",pr->adr);
- sh_name = savestring(name, strlen(name));
- s = NULL;
- }
- else {
- sh_name = (char*)sh->iss;
- s = mylookup_symbol(sh_name, top_stack->cur_block,
- VAR_NAMESPACE, LOC_BLOCK);
- }
- if (s != 0) {
- b = SYMBOL_BLOCK_VALUE(s);
- } else {
- s = new_symbol(sh_name);
- SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
- SYMBOL_CLASS(s) = LOC_BLOCK;
- /* Donno its type, hope int is ok */
- SYMBOL_TYPE(s) = lookup_function_type (builtin_type_int);
- add_symbol(s, top_stack->cur_block);
- /* Wont have symbols for this one */
- b = new_block(2);
- SYMBOL_BLOCK_VALUE(s) = b;
- BLOCK_FUNCTION(b) = s;
- BLOCK_START(b) = pr->adr;
- BLOCK_END(b) = bound;
- BLOCK_SUPERBLOCK(b) = top_stack->cur_block;
- add_block(b, top_stack->cur_st);
- }
- e->isym = (long)s;
- add_symbol(i,b);
+ struct symbol *s, *i;
+ SYMR *sh = (SYMR*)pr->isym;
+ struct block *b;
+ struct mips_extra_func_info *e;
+ char *sh_name;
+
+ /* Static procedure at address pr->adr. Sigh. */
+ if (sh == (SYMR*)-1) {
+ complain (&pdr_static_symbol_complaint, (char *)pr->adr);
+ return;
+ }
+ sh_name = (char*)sh->iss;
+ if (have_stabs)
+ s = lookup_symbol(sh_name, NULL, VAR_NAMESPACE, 0, NULL);
+ else
+ s = mylookup_symbol(sh_name, top_stack->cur_block,
+ VAR_NAMESPACE, LOC_BLOCK);
+
+ if (s != 0) {
+ b = SYMBOL_BLOCK_VALUE(s);
+ } else {
+ complain (&pdr_for_nonsymbol_complaint, sh_name);
+#if 1
+ return;
+#else
+/* FIXME -- delete. We can't do symbol allocation now; it's all done. */
+ s = new_symbol(sh_name);
+ SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
+ SYMBOL_CLASS(s) = LOC_BLOCK;
+ /* Donno its type, hope int is ok */
+ SYMBOL_TYPE(s) = lookup_function_type (builtin_type_int);
+ add_symbol(s, top_stack->cur_block);
+ /* Wont have symbols for this one */
+ b = new_block(2);
+ SYMBOL_BLOCK_VALUE(s) = b;
+ BLOCK_FUNCTION(b) = s;
+ BLOCK_START(b) = pr->adr;
+ BLOCK_END(b) = bound;
+ BLOCK_SUPERBLOCK(b) = top_stack->cur_block;
+ add_block(b, top_stack->cur_st);
+#endif
+ }
+
+ i = mylookup_symbol(".gdbinfo.", b, LABEL_NAMESPACE, LOC_CONST);
+
+ if (i)
+ {
+ e = (struct mips_extra_func_info *)SYMBOL_VALUE(i);
+ e->pdr = *pr;
+ e->pdr.isym = (long)s;
+ }
}
/* Parse the external symbol ES. Just call parse_symbol() after
This routine clobbers top_stack->cur_block and ->cur_st. */
-static
+static void
parse_external(es, skip_procedures, bigend)
EXTR *es;
int skip_procedures;
cur_fdr = (FDR*)(cur_hdr->cbFdOffset);
ax = 0;
}
- top_stack->cur_st = cur_stab;
- top_stack->cur_block = BLOCKVECTOR_BLOCK(BLOCKVECTOR(top_stack->cur_st),
- GLOBAL_BLOCK);
/* Reading .o files */
if (es->asym.sc == scUndefined || es->asym.sc == scNil) {
default : what = "symbol"; break;
}
n_undef_symbols++;
+ /* FIXME: Turn this into a complaint? */
if (info_verbose)
- printf_filtered("Warning: %s `%s' is undefined (in %s)\n", what,
- es->asym.iss, fdr_name(cur_fdr->rss));
+ printf_filtered("Warning: %s `%s' is undefined (in %s)\n",
+ what, es->asym.iss, fdr_name((char *)cur_fdr->rss));
return;
}
/* If we have full symbols we do not need more */
if (skip_procedures)
return;
- if (mylookup_symbol (es->asym.iss, top_stack->cur_block,
- VAR_NAMESPACE, LOC_BLOCK))
+ if (mylookup_symbol ((char *)es->asym.iss, top_stack->cur_block,
+ VAR_NAMESPACE, LOC_BLOCK))
break;
/* fall through */
case stGlobal:
numbers can go back and forth, apparently we can live
with that and do not need to reorder our linetables */
-static
+static void
parse_lines(fh, lt)
FDR *fh;
struct linetable *lt;
{
unsigned char *base = (unsigned char*)fh->cbLineOffset;
- int i, j, k;
+ int j, k;
int delta, count, lineno = 0;
PDR *pr;
return;
/* Scan by procedure descriptors */
- i = 0; j = 0, k = 0;
+ j = 0, k = 0;
for (pr = (PDR*)IPDFIRST(cur_hdr,fh); j < fh->cpd; j++, pr++) {
int l, halt;
}
}
}
-
\f
/* Master parsing procedure for first-pass reading of file symbols
into a partial_symtab.
the symtab we are reading. */
static void
-parse_partial_symbols(end_of_text_seg, objfile)
+parse_partial_symbols (end_of_text_seg, objfile)
int end_of_text_seg;
struct objfile *objfile;
{
- int f_idx, s_idx;
-/* int stat_idx, h_max;*/
+ int f_idx, s_idx;
HDRR *hdr = cur_hdr;
/* Running pointers */
- FDR *fh;
- RFDT *rh;
+ FDR *fh;
register EXTR *esh;
register SYMR *sh;
struct partial_symtab *pst;
-
+
int past_first_source_file = 0;
-
+
/* List of current psymtab's include files */
char **psymtab_include_list;
int includes_allocated;
struct partial_symtab **dependency_list;
int dependencies_used, dependencies_allocated;
struct cleanup *old_chain;
-
+
extern_tab = (EXTR**)obstack_alloc (&objfile->psymbol_obstack,
sizeof(EXTR *) * hdr->iextMax);
-
+
includes_allocated = 30;
includes_used = 0;
psymtab_include_list = (char **) alloca (includes_allocated *
sizeof (char *));
next_symbol_text_func = mips_next_symbol_text;
-
+
dependencies_allocated = 30;
dependencies_used = 0;
dependency_list =
(struct partial_symtab **) alloca (dependencies_allocated *
sizeof (struct partial_symtab *));
-
+
last_source_file = 0;
/*
- * Big plan:
+ * Big plan:
*
* Only parse the Local and External symbols, and the Relative FDR.
* Fixup enough of the loader symtab to be able to use it.
* Allocate space only for the file's portions we need to
* look at. (XXX)
*/
-
+
max_gdbinfo = 0;
max_glevel = MIN_GLEVEL;
-
+
/* Allocate the map FDR -> PST.
Minor hack: -O3 images might claim some global data belongs
to FDR -1. We`ll go along with that */
fdr_to_pst[-1].pst = pst;
FDR_IDX(pst) = -1;
}
-
+
/* Pass 1 over external syms: Presize and partition the list */
for (s_idx = 0; s_idx < hdr->iextMax; s_idx++) {
esh = (EXTR *) (hdr->cbExtOffset) + s_idx;
fdr_to_pst[esh->ifd].n_globals++;
}
-
+
/* Pass 1.5 over files: partition out global symbol space */
s_idx = 0;
for (f_idx = -1; f_idx < hdr->ifdMax; f_idx++) {
fdr_to_pst[f_idx].n_globals = 0;
}
-/* Pass 2 over external syms: fill in external symbols */
- for (s_idx = 0; s_idx < hdr->iextMax; s_idx++) {
- enum minimal_symbol_type ms_type = mst_text;
- esh = (EXTR *) (hdr->cbExtOffset) + s_idx;
+ /* Pass 2 over external syms: fill in external symbols */
+ for (s_idx = 0; s_idx < hdr->iextMax; s_idx++) {
+ enum minimal_symbol_type ms_type = mst_text;
+ esh = (EXTR *) (hdr->cbExtOffset) + s_idx;
- extern_tab[fdr_to_pst[esh->ifd].globals_offset
- + fdr_to_pst[esh->ifd].n_globals++] = esh;
+ extern_tab[fdr_to_pst[esh->ifd].globals_offset
+ + fdr_to_pst[esh->ifd].n_globals++] = esh;
- if (esh->asym.sc == scUndefined || esh->asym.sc == scNil)
- continue;
+ if (esh->asym.sc == scUndefined || esh->asym.sc == scNil)
+ continue;
- switch (esh->asym.st) {
- case stProc:
- break;
- case stGlobal:
- ms_type = mst_data;
- break;
- case stLabel:
- break;
- default:
- ms_type = mst_unknown;
- complain (&unknown_ext_complaint,
- (char *)(esh->asym.iss));
- }
- prim_record_minimal_symbol ((char *)(esh->asym.iss),
- esh->asym.value,
- ms_type);
+ switch (esh->asym.st) {
+ case stProc:
+ break;
+ case stGlobal:
+ ms_type = mst_data;
+ break;
+ case stLabel:
+ break;
+ default:
+ ms_type = mst_unknown;
+ complain (&unknown_ext_complaint, (char *)esh->asym.iss);
}
+ prim_record_minimal_symbol ((char *)esh->asym.iss,
+ esh->asym.value,
+ ms_type);
+ }
- /* Pass 3 over files, over local syms: fill in static symbols */
- for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) {
- struct partial_symtab *save_pst;
- EXTR **ext_ptr;
- cur_fdr = fh = f_idx + (FDR *)(cur_hdr->cbFdOffset);
+ /* Pass 3 over files, over local syms: fill in static symbols */
+ for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) {
+ struct partial_symtab *save_pst;
+ EXTR **ext_ptr;
+ cur_fdr = fh = f_idx + (FDR *)(cur_hdr->cbFdOffset);
- if (fh->csym == 0) {
- fdr_to_pst[f_idx].pst = NULL;
- continue;
- }
- pst = start_psymtab_common (objfile, 0, (char*)fh->rss,
- fh->cpd ? fh->adr : 0,
- objfile->global_psymbols.next,
- objfile->static_psymbols.next);
- pst->read_symtab_private = (char *)
- obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
-
- save_pst = pst;
- /* Make everything point to everything. */
- FDR_IDX(pst) = f_idx;
- fdr_to_pst[f_idx].pst = pst;
- fh->ioptBase = (int)pst;
-
- CUR_HDR(pst) = cur_hdr;
-
- /* The way to turn this into a symtab is to call... */
- pst->read_symtab = mipscoff_psymtab_to_symtab;
-
- pst->texthigh = pst->textlow;
-
+ if (fh->csym == 0) {
+ fdr_to_pst[f_idx].pst = NULL;
+ continue;
+ }
+ pst = start_psymtab_common (objfile, 0, (char*)fh->rss,
+ fh->cpd ? fh->adr : 0,
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ pst->read_symtab_private = (char *)
+ obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
+
+ save_pst = pst;
+ /* Make everything point to everything. */
+ FDR_IDX(pst) = f_idx;
+ fdr_to_pst[f_idx].pst = pst;
+ fh->ioptBase = (int)pst;
+
+ CUR_HDR(pst) = cur_hdr;
+
+ /* The way to turn this into a symtab is to call... */
+ pst->read_symtab = mipscoff_psymtab_to_symtab;
+
+ pst->texthigh = pst->textlow;
+
#if 0 /* This is done in start_psymtab_common */
- pst->globals_offset = global_psymbols.next - global_psymbols.list;
- pst->statics_offset = static_psymbols.next - static_psymbols.list;
-
- pst->n_global_syms = 0;
- pst->n_static_syms = 0;
+ pst->globals_offset = global_psymbols.next - global_psymbols.list;
+ pst->statics_offset = static_psymbols.next - static_psymbols.list;
+
+ pst->n_global_syms = 0;
+ pst->n_static_syms = 0;
#endif
-
- /* The second symbol must be @stab.
- This symbol is emitted by mips-tfile to signal
- that the current object file uses encapsulated stabs
- instead of mips ecoff for local symbols.
- (It is the second symbol because the first symbol is
- the stFile used to signal the start of a file). */
- if (fh->csym >= 2
- && strcmp((char *)(((SYMR *)fh->isymBase)[1].iss),
- stabs_symbol) == 0) {
- for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++) {
- int type_code;
- char *namestring;
- sh = cur_sdx + (SYMR *) fh->isymBase;
- type_code = MIPS_UNMARK_STAB(sh->index);
- if (!MIPS_IS_STAB(sh)) {
- if (sh->st == stProc || sh->st == stStaticProc) {
- long procaddr = sh->value;
- sh = AUX_GET_ISYM (fh->fBigendian,
- sh->index + (union aux_ext *)(fh->iauxBase))
- + (SYMR *) fh->isymBase - 1;
- if (sh->st == stEnd) {
- long high = procaddr + sh->value;
- if (high > pst->texthigh)
- pst->texthigh = high;
- }
+
+ /* The second symbol must be @stab.
+ This symbol is emitted by mips-tfile to signal
+ that the current object file uses encapsulated stabs
+ instead of mips ecoff for local symbols.
+ (It is the second symbol because the first symbol is
+ the stFile used to signal the start of a file). */
+ if (fh->csym >= 2
+ && strcmp((char *)(((SYMR *)fh->isymBase)[1].iss),
+ stabs_symbol) == 0) {
+ for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++) {
+ int type_code;
+ char *namestring;
+ sh = cur_sdx + (SYMR *) fh->isymBase;
+ type_code = MIPS_UNMARK_STAB(sh->index);
+ if (!MIPS_IS_STAB(sh)) {
+ if (sh->st == stProc || sh->st == stStaticProc) {
+ long procaddr = sh->value;
+ sh = AUX_GET_ISYM (fh->fBigendian,
+ sh->index + (union aux_ext *)(fh->iauxBase))
+ + (SYMR *) fh->isymBase - 1;
+ if (sh->st == stEnd) {
+ long high = procaddr + sh->value;
+ if (high > pst->texthigh)
+ pst->texthigh = high;
}
- continue;
}
+ continue;
+ }
#define SET_NAMESTRING() namestring = (char*)sh->iss
#define CUR_SYMBOL_TYPE type_code
#define CUR_SYMBOL_VALUE sh->value
if ((val) > save_pst->texthigh) save_pst->texthigh = (val);
#include "partial-stab.h"
#undef addr
- }
}
- else {
- register struct partial_symbol *psym;
- for (cur_sdx = 0; cur_sdx < fh->csym; ) {
- register struct partial_symbol *p;
- char *name;
- int class;
- sh = cur_sdx + (SYMR *) fh->isymBase;
-
- if (MIPS_IS_STAB(sh)) {
- cur_sdx++;
- continue;
- }
+ }
+ else {
+ for (cur_sdx = 0; cur_sdx < fh->csym; ) {
+ char *name;
+ enum address_class class;
+ sh = cur_sdx + (SYMR *) fh->isymBase;
+
+ if (MIPS_IS_STAB(sh)) {
+ cur_sdx++;
+ continue;
+ }
- if (sh->sc == scUndefined || sh->sc == scNil ||
- sh->index == 0xfffff) {
- /* FIXME, premature? */
- cur_sdx++;
+ if (sh->sc == scUndefined || sh->sc == scNil ||
+ sh->index == 0xfffff) {
+ /* FIXME, premature? */
+ cur_sdx++;
+ continue;
+ }
+
+ name = (char *)(sh->iss);
+
+ switch (sh->st) {
+ long high;
+ long procaddr;
+ int new_sdx;
+
+ case stProc: /* Asm labels apparently */
+ case stStaticProc: /* Function */
+ ADD_PSYMBOL_TO_LIST(name, strlen(name),
+ VAR_NAMESPACE, LOC_BLOCK,
+ objfile->static_psymbols, sh->value);
+ /* Skip over procedure to next one. */
+ if (sh->index >= hdr->iauxMax)
+ {
+ /* Should not happen, but does when cross-compiling
+ with the MIPS compiler. FIXME -- pull later. */
+ complain (&index_complaint, name);
+ new_sdx = cur_sdx+1; /* Don't skip at all */
+ }
+ else
+ new_sdx = AUX_GET_ISYM (fh->fBigendian,
+ sh->index + (union aux_ext *)fh->iauxBase);
+ procaddr = sh->value;
+
+ if (new_sdx <= cur_sdx)
+ {
+ /* This should not happen either... FIXME. */
+ complain (&aux_index_complaint, name);
+ new_sdx = cur_sdx + 1; /* Don't skip backward */
+ }
+
+ cur_sdx = new_sdx;
+ sh = cur_sdx + (SYMR *) fh->isymBase - 1;
+ if (sh->st != stEnd)
continue;
- }
-
- name = (char *)(sh->iss);
-
- switch (sh->st) {
- long high;
- long procaddr;
- case stProc: /* Asm labels apparently */
- case stStaticProc: /* Function */
+ high = procaddr + sh->value;
+ if (high > pst->texthigh)
+ pst->texthigh = high;
+ continue;
+
+ case stStatic: /* Variable */
+ class = LOC_STATIC;
+ break;
+
+ case stTypedef: /* Typedef */
+ class = LOC_TYPEDEF;
+ break;
+
+ case stConstant: /* Constant decl */
+ class = LOC_CONST;
+ break;
+
+ case stUnion:
+ case stStruct:
+ case stEnum:
+ case stBlock: /* { }, str, un, enum*/
+ if (sh->sc == scInfo) {
ADD_PSYMBOL_TO_LIST(name, strlen(name),
- VAR_NAMESPACE, LOC_BLOCK,
+ STRUCT_NAMESPACE, LOC_TYPEDEF,
objfile->static_psymbols, sh->value);
- /* Skip over procedure to next one. */
- cur_sdx = AUX_GET_ISYM (fh->fBigendian,
- sh->index + (union aux_ext *)fh->iauxBase);
- procaddr = sh->value;
-
- sh = cur_sdx + (SYMR *) fh->isymBase - 1;
- if (sh->st != stEnd)
- continue;
- high = procaddr + sh->value;
- if (high > pst->texthigh)
- pst->texthigh = high;
- continue;
- case stStatic: /* Variable */
- class = LOC_STATIC;
- break;
- case stTypedef: /* Typedef */
- class = LOC_TYPEDEF;
- break;
- case stConstant: /* Constant decl */
- class = LOC_CONST;
- break;
- case stBlock: /* { }, str, un, enum*/
- if (sh->sc == scInfo) {
- ADD_PSYMBOL_TO_LIST(name, strlen(name),
- STRUCT_NAMESPACE, LOC_TYPEDEF,
- objfile->static_psymbols, sh->value);
- }
- /* Skip over the block */
- cur_sdx = sh->index;
- continue;
- case stFile: /* File headers */
- case stLabel: /* Labels */
- case stEnd: /* Ends of files */
- goto skip;
- default:
- complain (&unknown_sym_complaint, SYMBOL_NAME(p));
- complain (&unknown_st_complaint, sh->st);
- cur_sdx++;
- continue;
- }
- /* Use this gdb symbol */
- ADD_PSYMBOL_TO_LIST(name, strlen(name),
- VAR_NAMESPACE, class,
- objfile->static_psymbols, sh->value);
- skip:
- cur_sdx++; /* Go to next file symbol */
- }
-
- /* Now do enter the external symbols. */
- ext_ptr = &extern_tab[fdr_to_pst[f_idx].globals_offset];
- cur_sdx = fdr_to_pst[f_idx].n_globals;
- PST_PRIVATE(save_pst)->extern_count = cur_sdx;
- PST_PRIVATE(save_pst)->extern_tab = ext_ptr;
- for (; --cur_sdx >= 0; ext_ptr++) {
- enum address_class class;
- if ((*ext_ptr)->ifd != f_idx)
- abort();
- sh = &(*ext_ptr)->asym;
- switch (sh->st) {
- case stProc:
- class = LOC_BLOCK;
- break;
- case stLabel:
- class = LOC_LABEL;
- break;
- default:
- complain (&unknown_ext_complaint, sh->iss);
- case stGlobal:
- class = LOC_STATIC;
- break;
}
- if (objfile->global_psymbols.next >=
- objfile->global_psymbols.list + objfile->global_psymbols.size)
- extend_psymbol_list (&objfile->global_psymbols, objfile);
- psym = objfile->global_psymbols.next++;
- SYMBOL_NAME (psym) = (char*)sh->iss;
- SYMBOL_NAMESPACE (psym) = VAR_NAMESPACE;
- SYMBOL_CLASS (psym) = class;
- SYMBOL_VALUE_ADDRESS (psym) = (CORE_ADDR)sh->value;
+ /* Skip over the block */
+ cur_sdx = sh->index;
+ continue;
+
+ case stFile: /* File headers */
+ case stLabel: /* Labels */
+ case stEnd: /* Ends of files */
+ goto skip;
+
+ default:
+ /* Both complaints are valid: one gives symbol name,
+ the other the offending symbol type. */
+ complain (&unknown_sym_complaint, (char *)sh->iss);
+ complain (&unknown_st_complaint, (char *)sh->st);
+ cur_sdx++;
+ continue;
}
+ /* Use this gdb symbol */
+ ADD_PSYMBOL_TO_LIST(name, strlen(name),
+ VAR_NAMESPACE, class,
+ objfile->static_psymbols, sh->value);
+ skip:
+ cur_sdx++; /* Go to next file symbol */
}
- end_psymtab (save_pst, psymtab_include_list, includes_used,
- -1, save_pst->texthigh,
- dependency_list, dependencies_used);
- if (entry_point < save_pst->texthigh
- && entry_point >= save_pst->textlow) {
- startup_file_start = save_pst->textlow;
- startup_file_end = save_pst->texthigh;
+ /* Now do enter the external symbols. */
+ ext_ptr = &extern_tab[fdr_to_pst[f_idx].globals_offset];
+ cur_sdx = fdr_to_pst[f_idx].n_globals;
+ PST_PRIVATE(save_pst)->extern_count = cur_sdx;
+ PST_PRIVATE(save_pst)->extern_tab = ext_ptr;
+ for (; --cur_sdx >= 0; ext_ptr++) {
+ register struct partial_symbol *psym;
+ enum address_class class;
+
+ if ((*ext_ptr)->ifd != f_idx)
+ abort();
+ sh = &(*ext_ptr)->asym;
+ switch (sh->st) {
+ case stProc:
+ class = LOC_BLOCK;
+ break;
+ case stLabel:
+ class = LOC_LABEL;
+ break;
+ default:
+ complain (&unknown_ext_complaint, (char *)sh->iss);
+ /* Fall through, pretend it's global. */
+ case stGlobal:
+ class = LOC_STATIC;
+ break;
+ }
+ if (objfile->global_psymbols.next >=
+ objfile->global_psymbols.list + objfile->global_psymbols.size)
+ extend_psymbol_list (&objfile->global_psymbols, objfile);
+ psym = objfile->global_psymbols.next++;
+ SYMBOL_NAME (psym) = (char*)sh->iss;
+ SYMBOL_NAMESPACE (psym) = VAR_NAMESPACE;
+ SYMBOL_CLASS (psym) = class;
+ SYMBOL_VALUE_ADDRESS (psym) = (CORE_ADDR)sh->value;
}
}
- /* Mark the last code address, and remember it for later */
- hdr->cbDnOffset = end_of_text_seg;
+ end_psymtab (save_pst, psymtab_include_list, includes_used,
+ -1, save_pst->texthigh,
+ dependency_list, dependencies_used);
+ if (objfile -> ei.entry_point >= save_pst->textlow &&
+ objfile -> ei.entry_point < save_pst->texthigh)
+ {
+ objfile -> ei.entry_file_lowpc = save_pst->textlow;
+ objfile -> ei.entry_file_highpc = save_pst->texthigh;
+ }
+ }
+
+ /* Mark the last code address, and remember it for later */
+ hdr->cbDnOffset = end_of_text_seg;
/* Now scan the FDRs for dependencies */
for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) {
for (s_idx = s_id0; s_idx < fh->crfd; s_idx++) {
RFDT *rh = (RFDT *) (fh->rfdBase) + s_idx;
if (*rh < 0 || *rh >= hdr->ifdMax)
- complain(&bad_file_number_complaint, *rh);
+ complain(&bad_file_number_complaint, (char *)*rh);
else
pst->dependencies[s_idx-s_id0] = fdr_to_pst[*rh].pst;
}
for turning the partial symtab PST into a symtab, recurring
first on all dependent psymtabs. The argument FILENAME is
only passed so we can see in debug stack traces what file
- is being read. */
+ is being read.
+
+ This function has a split personality, based on whether the
+ symbol table contains ordinary ecoff symbols, or stabs-in-ecoff.
+ The flow of control and even the memory allocation differs. FIXME. */
static void
psymtab_to_symtab_1(pst, filename)
struct partial_symtab *pst;
char *filename;
{
- int have_stabs;
- int i, f_max;
+ int i;
struct symtab *st;
FDR *fh;
- int maxlines;
struct linetable *lines;
+ int bound;
if (pst->readin)
return;
pst->readin = 1;
-
- /* How many symbols will we need */
- /* FIXME, this does not count enum values. */
- f_max = pst->n_global_syms + pst->n_static_syms;
- if (FDR_IDX(pst) == -1) {
- fh = 0;
- maxlines = 0;
- } else {
- fh = (FDR *) (cur_hdr->cbFdOffset) + FDR_IDX(pst);
- f_max += fh->csym + fh->cpd;
- maxlines = 2 * fh->cline;
- }
- /* See comment in parse_partial_symbols about the @stabs sentinel. */
- have_stabs =
- fh && fh->csym >= 2
- && strcmp((char *)(((SYMR *)fh->isymBase)[1].iss), stabs_symbol)
- == 0;
-
- if (!have_stabs) {
- if (fh)
- st = new_symtab (pst->filename, 2 * f_max, maxlines,
- pst->objfile);
- else
- st = new_symtab ("unknown", f_max, 0, pst->objfile);
- lines = LINETABLE(st);
- pending_list = (struct mips_pending **) cur_hdr->cbOptOffset;
- if (pending_list == 0) {
- pending_list = (struct mips_pending **)
- xzalloc(cur_hdr->ifdMax * sizeof(struct mips_pending *));
- cur_hdr->cbOptOffset = (int)pending_list;
- }
- }
-
/* Read in all partial symbtabs on which this one is dependent.
NOTE that we do have circular dependencies, sigh. We solved
that by setting pst->readin before this point. */
-
+
for (i = 0; i < pst->number_of_dependencies; i++)
if (!pst->dependencies[i]->readin) {
/* Inform about additional files to be read in. */
fflush (stdout);
}
/* We only pass the filename for debug purposes */
- psymtab_to_symtab_1(pst->dependencies[i],
+ psymtab_to_symtab_1(pst->dependencies[i],
pst->dependencies[i]->filename);
}
-
- cur_fdr = fh;
+
/* Now read the symbols for this symtab */
-
- current_objfile = pst -> objfile;
- if (!have_stabs) {
- cur_fd = FDR_IDX(pst);
- cur_stab = st;
+
+ current_objfile = pst->objfile;
+ cur_fd = FDR_IDX(pst);
+ fh = (cur_fd == -1) ? 0 : (FDR *) (cur_hdr->cbFdOffset) + FDR_IDX(pst);
+ cur_fdr = fh;
+
+ /* BOUND is the highest core address of this file's procedures */
+ bound = (cur_fd == cur_hdr->ifdMax - 1) ?
+ cur_hdr->cbDnOffset :
+ fh[1].adr;
+
+ /* See comment in parse_partial_symbols about the @stabs sentinel. */
+ if (fh && fh->csym >= 2
+ && strcmp((char *)(((SYMR *)fh->isymBase)[1].iss), stabs_symbol)
+ == 0) {
+
+ /*
+ * This symbol table contains stabs-in-ecoff entries.
+ */
+
+ PDR *pr;
+ /* Parse local symbols first */
+
+ if (fh->csym <= 2) /* FIXME, this blows psymtab->symtab ptr */
+ {
+ current_objfile = NULL;
+ return;
+ }
+ for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++) {
+ register SYMR *sh = cur_sdx + (SYMR *) fh->isymBase;
+ char *name = (char*)sh->iss;
+ CORE_ADDR valu = sh->value;
+ if (MIPS_IS_STAB(sh)) {
+ int type_code = MIPS_UNMARK_STAB(sh->index);
+ process_one_symbol (type_code, 0, valu, name, /*FIXME*/ 0,
+ pst->objfile);
+ if (type_code == N_FUN) {
+ /* Make up special symbol to contain
+ procedure specific info */
+ struct mips_extra_func_info *e =
+ (struct mips_extra_func_info *)
+ obstack_alloc(¤t_objfile->symbol_obstack,
+ sizeof(struct mips_extra_func_info));
+ struct symbol *s = new_symbol(".gdbinfo.");
+ SYMBOL_NAMESPACE(s) = LABEL_NAMESPACE;
+ SYMBOL_CLASS(s) = LOC_CONST;
+ SYMBOL_TYPE(s) = builtin_type_void;
+ SYMBOL_VALUE(s) = (int)e;
+ add_symbol_to_list (s, &local_symbols);
+ }
+ }
+ else if (sh->st == stLabel && sh->index != indexNil) {
+ /* Handle encoded stab line number. */
+ record_line (current_subfile, sh->index, valu);
+ }
+ else complain (&stab_unknown_complaint, (char *)sh->iss);
+ }
+ st = end_symtab (pst->texthigh, 0, 0, pst->objfile);
+
+ /* Sort the symbol table now, we are done adding symbols to it.
+ We must do this before parse_procedure calls lookup_symbol. */
+ sort_symtab_syms(st);
+
+ /* This may not be necessary for stabs symtabs. FIXME. */
+ sort_blocks (st);
+
+ /* Fill in procedure info next. We need to look-ahead to
+ find out where each procedure's code ends. */
+
+ for (i = 0; i <= fh->cpd-1; i++) {
+ pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + i;
+ parse_procedure (pr, i < fh->cpd-1 ? pr[1].adr : bound, 1);
+ }
+ } else {
+
+ /*
+ * This symbol table contains ordinary ecoff entries.
+ */
+
+ int f_max;
+ int maxlines;
+ EXTR **ext_ptr;
+
+ /* How many symbols will we need */
+ /* FIXME, this does not count enum values. */
+ f_max = pst->n_global_syms + pst->n_static_syms;
+ if (fh == 0) {
+ maxlines = 0;
+ st = new_symtab ("unknown", f_max, 0, pst->objfile);
+ } else {
+ f_max += fh->csym + fh->cpd;
+ maxlines = 2 * fh->cline;
+ st = new_symtab (pst->filename, 2 * f_max, maxlines, pst->objfile);
+ }
+
+ lines = LINETABLE(st);
+ pending_list = (struct mips_pending **) cur_hdr->cbOptOffset;
+ if (pending_list == 0) {
+ pending_list = (struct mips_pending **)
+ xzalloc(cur_hdr->ifdMax * sizeof(struct mips_pending *));
+ cur_hdr->cbOptOffset = (int)pending_list;
+ }
+
/* Get a new lexical context */
push_parse_stack();
- top_stack->cur_st = cur_stab;
- top_stack->cur_block = BLOCKVECTOR_BLOCK(BLOCKVECTOR(cur_stab),
+ top_stack->cur_st = st;
+ top_stack->cur_block = BLOCKVECTOR_BLOCK(BLOCKVECTOR(st),
STATIC_BLOCK);
BLOCK_START(top_stack->cur_block) = fh ? fh->adr : 0;
BLOCK_END(top_stack->cur_block) = 0;
top_stack->cur_type = 0;
top_stack->procadr = 0;
top_stack->numargs = 0;
- }
-
- /* Parse locals and procedures */
- if (fh) {
- SYMR *sh;
- PDR *pr;
- int f_idx = cur_fd;
- char *fh_name = (char*)fh->rss;
-
- /* Parse local symbols first */
-
-
- if (have_stabs) {
- if (fh->csym <= 2)
- {
- current_objfile = NULL;
- return;
- }
- for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++) {
- register SYMR *sh = cur_sdx + (SYMR *) fh->isymBase;
- char *name = (char*)sh->iss;
- CORE_ADDR valu = sh->value;
- if (MIPS_IS_STAB(sh)) {
- int type_code = MIPS_UNMARK_STAB(sh->index);
- process_one_symbol (type_code, 0, valu, name, /*FIXME*/ 0);
- }
- else if (sh->st == stLabel && sh->index != indexNil) {
- /* Handle encoded stab line number. */
- record_line (current_subfile, sh->index, valu);
- }
- }
- st = end_symtab (pst->texthigh, 0, 0, pst->objfile);
- }
- else {
- /* BOUND is the highest core address of this file's procedures */
- int bound = cur_fd == cur_hdr->ifdMax - 1 ? cur_hdr->cbDnOffset
- : fh[1].adr;
+
+ if (fh) {
+ SYMR *sh;
+ PDR *pr;
+
+ /* Parse local symbols first */
+
for (cur_sdx = 0; cur_sdx < fh->csym; ) {
sh = (SYMR *) (fh->isymBase) + cur_sdx;
- cur_sdx += parse_symbol(sh, fh->iauxBase, fh->fBigendian);
+ cur_sdx += parse_symbol(sh, (union aux_ent *)fh->iauxBase,
+ fh->fBigendian);
}
- /* Procedures next, note we need to look-ahead to
- find out where the procedure's code ends */
+ /* Linenumbers. At the end, check if we can save memory */
- for (i = 0; i < fh->cpd-1; i++) {
- pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + i;
- parse_procedure(pr, pr[1].adr); /* next proc up */
- }
- if (fh->cpd) {
- pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + i;
- parse_procedure(pr, bound); /* next file up */
- }
- /* Linenumbers. At the end, check if we can save memory */
parse_lines(fh, lines);
if (lines->nitems < fh->cline)
lines = shrink_linetable(lines);
+
+ /* Fill in procedure info next. We need to look-ahead to
+ find out where each procedure's code ends. */
+
+ for (i = 0; i <= fh->cpd-1; i++) {
+ pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + i;
+ parse_procedure(pr, i < fh->cpd-1 ? pr[1].adr : bound, 0);
+ }
}
- }
- if (!have_stabs) {
- EXTR **ext_ptr;
LINETABLE(st) = lines;
-
+
/* .. and our share of externals.
- XXX use the global list to speed up things here. how ?
+ XXX use the global list to speed up things here. how?
FIXME, Maybe quit once we have found the right number of ext's? */
- /* parse_external clobbers top_stack->cur_block and ->cur_st here. */
+ top_stack->cur_st = st;
+ top_stack->cur_block = BLOCKVECTOR_BLOCK(BLOCKVECTOR(top_stack->cur_st),
+ GLOBAL_BLOCK);
top_stack->blocktype = stFile;
top_stack->maxsyms =
cur_hdr->isymMax + cur_hdr->ipdMax + cur_hdr->iextMax;
ext_ptr = PST_PRIVATE(pst)->extern_tab;
for (i = PST_PRIVATE(pst)->extern_count; --i >= 0; ext_ptr++)
parse_external(*ext_ptr, 1, fh->fBigendian);
-
+
/* If there are undefined, tell the user */
if (n_undef_symbols) {
printf_filtered("File %s contains %d unresolved references:",
}
pop_parse_stack();
+
+ /* Sort the symbol table now, we are done adding symbols to it.*/
+ sort_symtab_syms(st);
+
+ sort_blocks (st);
}
-
- /* Sort the symbol table now, we are done adding symbols to it.*/
- sort_symtab_syms(st);
- sort_blocks (st);
-
/* Now link the psymtab and the symtab. */
pst->symtab = st;
cross_ref(ax, tpp, type_code, pname, bigend)
union aux_ext *ax;
struct type **tpp;
- int type_code; /* Use to alloc new type if none is found. */
+ enum type_code type_code; /* Use to alloc new type if none is found. */
char **pname;
int bigend;
{
*pname = "<undefined>";
} else {
/*
- * Find the relative file descriptor and the symbol in it
+ * Find the relative file descriptor and the symbol in it
*/
FDR *fh = get_rfd(cur_fd, rf);
SYMR *sh;
* it in a list of pending symbols, to be processed later when
* the file f will be. In any event, we collect the name for
* the type here. Which is why we made a first pass at
- * strings.
+ * strings.
*/
sh = (SYMR *) (fh->isymBase) + rn->index;
if (p)
*tpp = p->t;
else {
- *tpp = init_type(type_code, 0, 0, 0, (struct objfile *) NULL);
+ *tpp = init_type(type_code, 0, 0, (char *) NULL,
+ (struct objfile *) NULL);
add_pending(fh, sh, *tpp);
}
}
return sym;
bot++;
}
- if (block = BLOCK_SUPERBLOCK (block))
+ block = BLOCK_SUPERBLOCK (block);
+ if (block)
return mylookup_symbol (name, block, namespace, class);
return 0;
}
{
struct blockvector *bv = BLOCKVECTOR(s);
- bv = (struct blockvector *)xrealloc((char *) bv,
+ bv = (struct blockvector *)xrealloc((PTR) bv,
sizeof(struct blockvector) +
BLOCKVECTOR_NBLOCKS(bv)
* sizeof(bv->block));
lt->item[lt->nitems++].pc = adr << 2;
return lineno;
}
-
-
\f
-/* Comparison functions, used when sorting things */
-
-/* Symtabs must be ordered viz the code segments they cover */
-
-static int
-compare_symtabs( s1, s2)
- struct symtab **s1, **s2;
-{
- /* "most specific" first */
-
- register struct block *b1, *b2;
- b1 = BLOCKVECTOR_BLOCK(BLOCKVECTOR(*s1),GLOBAL_BLOCK);
- b2 = BLOCKVECTOR_BLOCK(BLOCKVECTOR(*s2),GLOBAL_BLOCK);
- if (BLOCK_END(b1) == BLOCK_END(b2))
- return BLOCK_START(b1) - BLOCK_START(b2);
- return BLOCK_END(b1) - BLOCK_END(b2);
-}
-
-
-/* Partial Symtabs, same */
-
-static int
-compare_psymtabs( s1, s2)
- struct partial_symtab **s1, **s2;
-{
- /* Perf twist: put the ones with no code at the end */
-
- register int a = (*s1)->textlow;
- register int b = (*s2)->textlow;
- if (a == 0)
- return b;
- if (b == 0)
- return -a;
- return a - b;
-}
-
+/* Sorting and reordering procedures */
/* Blocks with a smaller low bound should come first */
-static int compare_blocks(b1,b2)
- struct block **b1, **b2;
+static int
+compare_blocks(arg1, arg2)
+ const void *arg1, *arg2;
{
register int addr_diff;
+ struct block **b1 = (struct block **) arg1;
+ struct block **b2 = (struct block **) arg2;
addr_diff = (BLOCK_START((*b1))) - (BLOCK_START((*b2)));
if (addr_diff == 0)
return addr_diff;
}
-\f
-/* Sorting and reordering procedures */
-
/* Sort the blocks of a symtab S.
Reorder the blocks in the blockvector by code-address,
as required by some MI search routines */
BLOCK_START(BLOCKVECTOR_BLOCK(bv,GLOBAL_BLOCK)) =
BLOCK_START(BLOCKVECTOR_BLOCK(bv,FIRST_LOCAL_BLOCK));
- BLOCK_START(BLOCKVECTOR_BLOCK(bv,STATIC_BLOCK)) =
+ BLOCK_START(BLOCKVECTOR_BLOCK(bv,STATIC_BLOCK)) =
BLOCK_START(BLOCKVECTOR_BLOCK(bv,GLOBAL_BLOCK));
BLOCK_END (BLOCKVECTOR_BLOCK(bv,STATIC_BLOCK)) =
BLOCK_END (BLOCKVECTOR_BLOCK(bv,GLOBAL_BLOCK));
/* Allocate a new symtab for NAME. Needs an estimate of how many symbols
MAXSYMS and linenumbers MAXLINES we'll put in it */
-static
-struct symtab *
+static struct symtab *
new_symtab(name, maxsyms, maxlines, objfile)
char *name;
int maxsyms;
struct objfile *objfile;
{
struct partial_symtab *psymtab;
-
+
/* FIXME -- why (char *) -1 rather than NULL? */
psymtab = allocate_psymtab (name == (char *) -1 ? "<no name>" : name,
objfile);
-
+
/* Keep a backpointer to the file's symbols */
psymtab -> read_symtab_private = (char *)
obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
CUR_HDR(psymtab) = cur_hdr;
-
+
/* The way to turn this into a symtab is to call... */
psymtab->read_symtab = mipscoff_psymtab_to_symtab;
return (psymtab);
}
-/* Allocate a linetable array of the given SIZE */
+/* Allocate a linetable array of the given SIZE. Since the struct
+ already includes one item, we subtract one when calculating the
+ proper size to allocate. */
static struct linetable *
new_linetable(size)
+ int size;
{
struct linetable *l;
- size = size * sizeof(l->item) + sizeof(struct linetable);
+ size = (size-1) * sizeof(l->item) + sizeof(struct linetable);
l = (struct linetable *)xmalloc(size);
l->nitems = 0;
return l;
}
/* Oops, too big. Shrink it. This was important with the 2.4 linetables,
- I am not so sure about the 3.4 ones */
+ I am not so sure about the 3.4 ones.
+
+ Since the struct linetable already includes one item, we subtract one when
+ calculating the proper size to allocate. */
static struct linetable *
shrink_linetable(lt)
struct linetable * lt;
{
- struct linetable *l = new_linetable(lt->nitems);
- memcpy(l, lt, lt->nitems * sizeof(l->item) + sizeof(struct linetable));
- free (lt);
- return l;
+ return (struct linetable *) xrealloc ((PTR)lt,
+ sizeof(struct linetable)
+ + (lt->nitems - 1) * sizeof(lt->item));
}
/* Allocate and zero a new blockvector of NBLOCKS blocks. */
-static
-struct blockvector *
+static struct blockvector *
new_bvect(nblocks)
+ int nblocks;
{
struct blockvector *bv;
int size;
/* Allocate and zero a new block of MAXSYMS symbols */
-static
-struct block *
+static struct block *
new_block(maxsyms)
+ int maxsyms;
{
int size = sizeof(struct block) + (maxsyms-1) * sizeof(struct symbol *);
- struct block *b = (struct block *)xzalloc(size);
- return b;
+ return (struct block *)xzalloc (size);
}
/* Ooops, too big. Shrink block B in symtab S to its minimal size.
/* Just reallocate it and fix references to the old one */
- new = (struct block *) xrealloc ((char *)b, sizeof(struct block) +
- (BLOCK_NSYMS(b)-1) * sizeof(struct symbol *));
+ new = (struct block *) xrealloc ((PTR)b, sizeof(struct block) +
+ (BLOCK_NSYMS(b)-1) * sizeof(struct symbol *));
/* Should chase pointers to old one. Fortunately, that`s just
the block`s function and inferior blocks */
/* Create a new symbol with printname NAME */
-static
-struct symbol *
+static struct symbol *
new_symbol(name)
char *name;
{
- struct symbol *s = (struct symbol *)
+ struct symbol *s = (struct symbol *)
obstack_alloc (¤t_objfile->symbol_obstack, sizeof (struct symbol));
- memset (s, 0, sizeof (*s));
+ memset ((PTR)s, 0, sizeof (*s));
SYMBOL_NAME(s) = name;
return s;
}
/* Create a new type with printname NAME */
-static
-struct type *
+static struct type *
new_type(name)
char *name;
{
/* Most programs do not play with signals */
if (s == 0)
- return;
-
- b0 = SYMBOL_BLOCK_VALUE(s);
+ s = lookup_symbol("_sigtramp", 0, VAR_NAMESPACE, 0, NULL);
+ else
+ {
+ b0 = SYMBOL_BLOCK_VALUE(s);
- /* A label of sigvec, to be more precise */
- s = lookup_symbol("sigtramp", b0, VAR_NAMESPACE, 0, NULL);
+ /* A label of sigvec, to be more precise */
+ s = lookup_symbol("sigtramp", b0, VAR_NAMESPACE, 0, NULL);
+ }
/* But maybe this program uses its own version of sigvec */
if (s == 0)
return;
- sigtramp_address = SYMBOL_VALUE(s);
- sigtramp_end = sigtramp_address + 0x88; /* black magic */
-
/* Did we or MIPSco fix the library ? */
if (SYMBOL_CLASS(s) == LOC_BLOCK)
- return;
+ {
+ sigtramp_address = BLOCK_START(SYMBOL_BLOCK_VALUE(s));
+ sigtramp_end = BLOCK_END(SYMBOL_BLOCK_VALUE(s));
+ return;
+ }
+
+ sigtramp_address = SYMBOL_VALUE(s);
+ sigtramp_end = sigtramp_address + 0x88; /* black magic */
/* But what symtab does it live in ? */
st = find_pc_symtab(SYMBOL_VALUE(s));
*/
SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
SYMBOL_CLASS(s) = LOC_BLOCK;
- SYMBOL_TYPE(s) = init_type(TYPE_CODE_FUNC, 4, 0, 0, (struct objfile *) NULL);
+ SYMBOL_TYPE(s) = init_type(TYPE_CODE_FUNC, 4, 0, (char *) NULL,
+ (struct objfile *) NULL);
TYPE_TARGET_TYPE(SYMBOL_TYPE(s)) = builtin_type_void;
/* Need a block to allocate .gdbinfo. in */
e->numargs = 0; /* the kernel thinks otherwise */
/* align_longword(sigcontext + SIGFRAME) */
- e->framesize = 0x150;
- e->framereg = SP_REGNUM;
- e->pcreg = 31;
- e->regmask = -2;
- e->regoffset = -(41 * sizeof(int));
- e->fregmask = -1;
- e->fregoffset = -(37 * sizeof(int));
- e->isym = (long)s;
-
+ e->pdr.frameoffset = 0x150;
+ e->pdr.framereg = SP_REGNUM;
+ e->pdr.pcreg = 31;
+ e->pdr.regmask = -2;
+ e->pdr.regoffset = -(41 * sizeof(int));
+ e->pdr.fregmask = -1;
+ e->pdr.fregoffset = -(37 * sizeof(int));
+ e->pdr.isym = (long)s;
+
+ current_objfile = st->objfile; /* Keep new_symbol happy */
s = new_symbol(".gdbinfo.");
SYMBOL_VALUE(s) = (int) e;
SYMBOL_NAMESPACE(s) = LABEL_NAMESPACE;
SYMBOL_CLASS(s) = LOC_CONST;
SYMBOL_TYPE(s) = builtin_type_void;
+ current_objfile = NULL;
}
BLOCK_SYM(b,BLOCK_NSYMS(b)++) = s;
\f
/* Initialization */
-static struct sym_fns ecoff_sym_fns = {"ecoff", 5,
- mipscoff_new_init, mipscoff_symfile_init,
- mipscoff_symfile_read};
+static struct sym_fns ecoff_sym_fns =
+{
+ "ecoff", /* sym_name: name or name prefix of BFD target type */
+ 5, /* sym_namelen: number of significant sym_name chars */
+ mipscoff_new_init, /* sym_new_init: init anything gbl to entire symtab */
+ mipscoff_symfile_init,/* sym_init: read initial info, setup for sym_read() */
+ mipscoff_symfile_read,/* sym_read: read a symbol file into symtab */
+ mipscoff_symfile_finish,/* sym_finish: finished with file, cleanup */
+ NULL /* next: pointer to next struct sym_fns */
+};
+
+void
_initialize_mipsread ()
{
add_symtab_fns (&ecoff_sym_fns);
/* Missing basic types */
+
builtin_type_string =
- init_type (TYPE_CODE_PASCAL_ARRAY,
- 1, 0, "string",
- (struct objfile *) NULL);
+ init_type(TYPE_CODE_PASCAL_ARRAY,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "string",
+ (struct objfile *) NULL);
builtin_type_complex =
init_type(TYPE_CODE_FLT,
- 2 * sizeof(float), 0, "complex",
+ TARGET_COMPLEX_BIT / TARGET_CHAR_BIT,
+ 0, "complex",
(struct objfile *) NULL);
builtin_type_double_complex =
init_type(TYPE_CODE_FLT,
- 2 * sizeof(double), 0, "double_complex",
+ TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT,
+ 0, "double complex",
(struct objfile *) NULL);
builtin_type_fixed_dec =
- init_type(TYPE_CODE_INT, sizeof(int),
- 0, "fixed_decimal",
+ init_type(TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "fixed decimal",
(struct objfile *) NULL);
builtin_type_float_dec =
- init_type(TYPE_CODE_FLT, sizeof(double),
- 0, "floating_decimal",
+ init_type(TYPE_CODE_FLT,
+ TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "floating decimal",
(struct objfile *) NULL);
}