/* Read a symbol table in MIPS' format (Third-Eye).
- Copyright (C) 1986, 1987, 1989-1991 Free Software Foundation, Inc.
+ Copyright 1986, 1987, 1989, 1990, 1991 Free Software Foundation, Inc.
This file is part of GDB.
a pointer in the psymtab to do this. */
#include <stdio.h>
-#include "param.h"
-#include "obstack.h"
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/stat.h>
#include "defs.h"
#include "symtab.h"
#include "gdbcore.h"
#include "symfile.h"
+#include "obstack.h"
+#include "buildsym.h"
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/stat.h>
#ifdef CMUCS
#include <mips/syms.h>
#else /* not CMUCS */
#include <sym.h>
#endif /* not CMUCS */
-#include "ecoff.h"
+#include "coff/mips.h"
+#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 */
struct coff_exec {
struct external_filehdr f;
struct external_aouthdr a;
};
+/* These must match the corresponding definition in mips-tfile.c. */
+
+#define CODE_MASK 0x8F300
+#define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK)
+#define MIPS_MARK_STAB(code) ((code)+CODE_MASK)
+#define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK)
+
/* Each partial symbol table entry contains a pointer to private data for the
read_symtab() function to use when expanding a partial symbol table entry
to a full symbol table entry.
For mipsread this structure contains the index of the FDR that this psymtab
represents and a pointer to the symbol table header HDRR from the symbol
- file that the psymtab was created from.
-
- Note: This code is currently untested. -fnf */
+ file that the psymtab was created from. */
#define FDR_IDX(p) (((struct symloc *)((p)->read_symtab_private))->fdr_idx)
#define CUR_HDR(p) (((struct symloc *)((p)->read_symtab_private))->cur_hdr)
static int n_undef_symbols, n_undef_labels, n_undef_vars, n_undef_procs;
+/* Pseudo symbol to use when putting stabs into the symbol table. */
+
+static char stabs_symbol[] = "@stabs";
+
/* Extra builtin types */
struct type *builtin_type_complex;
struct type *builtin_type_float_dec;
struct type *builtin_type_string;
-/* Template types */
-
-static struct type *builtin_type_ptr;
-static struct type *builtin_type_struct;
-static struct type *builtin_type_union;
-static struct type *builtin_type_enum;
-static struct type *builtin_type_range;
-static struct type *builtin_type_set;
-
/* Forward declarations */
static struct symbol *new_symbol();
static struct type *new_type();
-static struct field *new_field();
static struct block *new_block();
static struct symtab *new_symtab();
static struct linetable *new_linetable();
static struct type *make_type();
static struct symbol *mylookup_symbol();
static struct block *shrink_block();
+static void sort_blocks();
static int compare_symtabs();
static int compare_psymtabs();
static void add_block();
static void add_symbol();
static int add_line();
-static void reorder_symtabs();
-static void reorder_psymtabs();
-static void shrink_linetable();
+static struct linetable *shrink_linetable();
\f
/* Things we export to other modules */
mipscoff_symfile_init (sf)
struct sym_fns *sf;
{
- bfd *abfd = sf->sym_bfd;
sf->sym_private = NULL;
}
int mainline;
{
struct coff_symfile_info *info = (struct coff_symfile_info *)sf->sym_private;
- bfd *abfd = sf->sym_bfd;
+ bfd *abfd = sf->objfile->obfd;
char *name = bfd_get_filename (abfd);
int desc;
register int val;
int symtab_offset;
int stringtab_offset;
- /* Initialize a variable that we couldn't do at _initialize_ time. */
- builtin_type_ptr = lookup_pointer_type (builtin_type_void);
-
/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
desc = fileno ((FILE *)(abfd->iostream)); /* Raw file descriptor */
/* End of warning */
/* Now that the executable file is positioned at symbol table,
process it and define symbols accordingly. */
- read_mips_symtab(abfd, desc);
+ read_mips_symtab(sf->objfile, desc);
/* Go over the misc symbol bunches and install them in vector. */
{
char *p = xmalloc(size);
- bzero(p, size);
+ memset(p, 0, size);
return p;
}
psymtab_to_symtab_1(pst, pst->filename);
- reorder_symtabs();
+ /* Match with global symbols. This only needs to be done once,
+ after all of the symtabs and dependencies have been read in. */
+ scan_file_globals ();
if (info_verbose)
printf_filtered("done.\n");
/* Allocate space for the symbol table. Read it in. */
cur_hdr = (HDRR *) xmalloc(stsize + st_hdrsize);
- bcopy(&st_hdr, cur_hdr, st_hdrsize);
+ memcpy(cur_hdr, &st_hdr, st_hdrsize);
if (read(fsym, (char *) cur_hdr + st_hdrsize, stsize) != stsize)
goto readerr;
return;
readerr:
- error("Short read on %s", symfile);
+ error("Short read on %s", bfd_get_filename (abfd));
}
fh->issBase += hdr->cbSsOffset;
if (fh->rss != -1)
fh->rss = (long)fh->rss + fh->issBase;
+
+ /* Local symbols */
+ fh->isymBase = (int)((SYMR*)(hdr->cbSymOffset)+fh->isymBase);
+
+ /* FIXME! Probably don't want to do this here! */
for (s_idx = 0; s_idx < fh->csym; s_idx++) {
- sh = (SYMR*)(hdr->cbSymOffset) + fh->isymBase + s_idx;
+ sh = (SYMR*)fh->isymBase + s_idx;
sh->iss = (long) sh->iss + fh->issBase;
sh->reserved = 0;
}
cur_fd = f_idx;
- /* Local symbols */
- fh->isymBase = (int)((SYMR*)(hdr->cbSymOffset)+fh->isymBase);
-
/* cannot fix fh->ipdFirst because it is a short */
#define IPDFIRST(h,fh) \
((long)h->cbPdOffset + fh->ipdFirst * sizeof(PDR))
FIXME: INCREMENTAL is currently always zero, though it should not be. */
static
-read_mips_symtab (abfd, desc)
- bfd *abfd;
+read_mips_symtab (objfile, desc)
+ struct objfile *objfile;
int desc;
{
CORE_ADDR end_of_text_seg;
- read_the_mips_symtab(abfd, desc, &end_of_text_seg);
+ read_the_mips_symtab(objfile->obfd, desc, &end_of_text_seg);
- parse_partial_symbols(end_of_text_seg);
+ parse_partial_symbols(end_of_text_seg, objfile);
+#if 0
/*
* Check to make sure file was compiled with -g.
* If not, warn the user of this limitation.
*/
if (compare_glevel(max_glevel, GLEVEL_2) < 0) {
if (max_gdbinfo == 0)
- printf("\n%s not compiled with -g, debugging support is limited.", symfile);
- printf("\nYou should compile with -g2 or -g3 for best debugging support.\n");
+ printf (
+"\n%s not compiled with -g, debugging support is limited.\n",
+ objfile->name);
+ printf(
+"You should compile with -g2 or -g3 for best debugging support.\n");
fflush(stdout);
}
+#endif
}
\f
/* Local utilities */
static struct pst_map {
struct partial_symtab *pst; /* the psymtab proper */
- int n_globals; /* globals it exports */
- int n_statics; /* statics (locals) it contains */
} * fdr_to_pst;
after use. */
static struct parse_stack {
- struct parse_stack *next, *prev;
- struct symtab *cur_st; /* Current symtab */
- struct block *cur_block; /* Block in it */
- int blocktype; /* What are we parsing */
- int maxsyms; /* Max symbols in this block */
- struct type *cur_type; /* Type we parse fields for */
- int procadr; /* Start addres of this procedure */
- int numargs; /* Its argument count */
+ struct parse_stack *next, *prev;
+ struct symtab *cur_st; /* Current symtab. */
+ struct block *cur_block; /* Block in it. */
+ int blocktype; /* What are we parsing. */
+ int maxsyms; /* Max symbols in this block. */
+ struct type *cur_type; /* Type we parse fields for. */
+ int cur_field; /* Field number in cur_type. */
+ int procadr; /* Start addres of this procedure */
+ int numargs; /* Its argument count */
} *top_stack; /* Top stack ptr */
duplications we keep a quick fixup table, an array
of lists of references indexed by file descriptor */
-static struct pending {
- struct pending *next; /* link */
+static struct mips_pending {
+ struct mips_pending *next; /* link */
SYMR *s; /* the symbol */
struct type *t; /* its partial type descriptor */
} **pending_list;
/* Check whether we already saw symbol SH in file FH as undefined */
static
-struct pending *is_pending_symbol(fh, sh)
+struct mips_pending *is_pending_symbol(fh, sh)
FDR *fh;
SYMR *sh;
{
int f_idx = fh - (FDR *) cur_hdr->cbFdOffset;
- register struct pending *p;
+ register struct mips_pending *p;
/* Linear search is ok, list is typically no more than 10 deep */
for (p = pending_list[f_idx]; p; p = p->next)
/* Check whether we already saw type T in file FH as undefined */
static
-struct pending *is_pending_type(fh, t)
+struct mips_pending *is_pending_type(fh, t)
FDR *fh;
struct type *t;
{
int f_idx = fh - (FDR *) cur_hdr->cbFdOffset;
- register struct pending *p;
+ register struct mips_pending *p;
for (p = pending_list[f_idx]; p; p = p->next)
if (p->t == t)
struct type *t;
{
int f_idx = fh - (FDR *) cur_hdr->cbFdOffset;
- struct pending *p = is_pending_symbol(fh, sh);
+ struct mips_pending *p = is_pending_symbol(fh, sh);
/* Make sure we do not make duplicates */
if (!p) {
- p = (struct pending *) xmalloc(sizeof(*p));
+ p = (struct mips_pending *) xmalloc(sizeof(*p));
p->s = sh;
p->t = t;
p->next = pending_list[f_idx];
static
free_pending(f_idx)
{
- register struct pending *p, *q;
+ register struct mips_pending *p, *q;
for (p = pending_list[f_idx]; p; p = q) {
q = p->next;
/* Parse a single symbol. Mostly just make up a GDB symbol for it.
For blocks, procedures and types we open a new lexical context.
- This is basically just a big switch on the symbol's type */
+ This is basically just a big switch on the symbol's type.
+ Return count of SYMR's handled (normally one). */
-static void
+static int
parse_symbol(sh, ax)
SYMR *sh;
AUXU *ax;
{
+ char *name;
struct symbol *s;
struct block *b;
struct type *t;
struct field *f;
+ int count = 1;
/* When a symbol is cross-referenced from other files/symbols
we mark it explicitly */
int pend = (sh->reserved == 1);
case stParam: /* arg to procedure, goes into current block */
max_gdbinfo++;
top_stack->numargs++;
- s = new_symbol(sh->iss);
+
+ name = (char*)sh->iss;
+ /* Special GNU C++ name. */
+ if (name[0] == CPLUS_MARKER && name[1] == 't' && name[2] == 0)
+ name = "this";
+ s = new_symbol(name);
+
SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
if (sh->sc == scRegister) {
SYMBOL_CLASS(s) = LOC_REGPARM;
top_stack->cur_block = b;
top_stack->blocktype = sh->st;
top_stack->cur_type = SYMBOL_TYPE(s);
+ top_stack->cur_field = -1;
top_stack->procadr = sh->value;
top_stack->numargs = 0;
push_parse_stack();
top_stack->blocktype = stBlock;
if (sh->sc == scInfo) { /* structure/union/enum def */
- 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);
- /* If this type was expected, use its partial definition */
- if (pend) {
- t = is_pending_symbol(cur_fdr, sh)->t;
- } else {
- /* Uhmm, can`t decide yet. Smash later */
- t = new_type(sh->iss);
- TYPE_CODE(t) = TYPE_CODE_UNDEF;
- add_pending(cur_fdr, sh, t);
+ int type_code = TYPE_CODE_UNDEF;
+
+ 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);
+ /* If this type was expected, use its partial definition */
+ if (pend) {
+ t = is_pending_symbol(cur_fdr, sh)->t;
+ } else {
+ int nfields = 0;
+ SYMR *tsym;
+ long max_value = 0;
+ struct field *f;
+
+ /* First count the number of fields. */
+ for (tsym = sh+1; tsym->st != stEnd; tsym++)
+ if (tsym->st == stMember) {
+ if (nfields == 0)
+ if (tsym->index == indexNil
+ || ax[tsym->index].ti.bt==26)/*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;
+ }
+
+ t = new_type(sh->iss);
+
+ /* Guess the type code. */
+ if (type_code == TYPE_CODE_UNDEF)
+ if (max_value == 0) type_code = TYPE_CODE_UNION;
+ else type_code = TYPE_CODE_STRUCT;
+
+ TYPE_CODE(t) = type_code;
+ TYPE_NFIELDS(t) = nfields;
+ TYPE_FIELDS(t) = f = (struct field*)
+ obstack_alloc (symbol_obstack,
+ nfields * sizeof (struct field));
+
+ if (type_code == TYPE_CODE_ENUM) {
+ /* This is a non-empty enum. */
+ while (sh[1].st == stMember) {
+ struct symbol *enum_sym;
+ sh++;
+ f->bitpos = sh->value;
+ f->type = t;
+ f->name = (char*)sh->iss;
+ f->bitsize = 0;
+
+ enum_sym = (struct symbol *)
+ obstack_alloc (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) = sh->value;
+ add_symbol(enum_sym, top_stack->cur_block);
+
+ count++;
+ f++;
+ }
}
- SYMBOL_TYPE(s) = t;
- /* make this the current type */
- top_stack->cur_type = t;
- TYPE_LENGTH(t) = sh->value;
- /* Mark that symbol has a type, and say which one */
- sh->value = (long) t;
+ else {
+ /* Uhmm, can`t decide yet. Guess. */
+ add_pending(cur_fdr, sh, t);
+ }
+ }
+ SYMBOL_TYPE(s) = t;
+ /* make this the current type */
+ top_stack->cur_type = t;
+ top_stack->cur_field = 0;
+ TYPE_LENGTH(t) = sh->value;
+ /* 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 */
pop_parse_stack(); /* restore previous lexical context */
break;
- case stMember: /* member of struct/union/enum.. */
- f = new_field(top_stack->cur_type, sh->iss);
+ case stMember: /* member of struct or union */
+ f = &TYPE_FIELDS(top_stack->cur_type)[top_stack->cur_field++];
+ f->name = (char*)sh->iss;
f->bitpos = sh->value;
+ f->bitsize = 0;
f->type = parse_type(ax + sh->index, sh, &f->bitsize);
break;
error("Unknown symbol type %x.", sh->st);
}
sh->st = stParsed;
+ return count;
}
/* Parse the type information provided in the AX entries for
};
TIR *t;
- struct type *tp = 0, *tp1;
- char *fmt = "%s";
+ struct type *tp = 0;
+ char *fmt;
+ int i;
+ int type_code;
/* Procedures start off by one */
if (sh->st == stProc || sh->st == stStaticProc)
/* Use aux as a type information record, map its basic type */
t = &ax->ti;
- if (t->bt > 26 || t->bt == btPicture) {
+ if (t->bt > (sizeof (map_bt)/sizeof (*map_bt))) {
complain (&basic_type_complaint, t->bt);
return builtin_type_int;
}
- if (map_bt[t->bt])
+ if (map_bt[t->bt]) {
tp = *map_bt[t->bt];
- else {
- /* Cannot use builtin types, use templates */
- tp = make_type(TYPE_CODE_VOID, 0, 0, 0);
+ fmt = "%s";
+ } else {
+ tp = NULL;
+ /* Cannot use builtin types -- build our own */
switch (t->bt) {
case btAdr:
- *tp = *builtin_type_ptr;
+ tp = lookup_pointer_type (builtin_type_void);
+ fmt = "%s";
break;
case btStruct:
- *tp = *builtin_type_struct;
+ type_code = TYPE_CODE_STRUCT;
fmt = "struct %s";
break;
case btUnion:
- *tp = *builtin_type_union;
+ type_code = TYPE_CODE_UNION;
fmt = "union %s";
break;
case btEnum:
- *tp = *builtin_type_enum;
+ type_code = TYPE_CODE_ENUM;
fmt = "enum %s";
break;
case btRange:
- *tp = *builtin_type_range;
+ type_code = TYPE_CODE_RANGE;
+ fmt = "%s";
break;
case btSet:
- *tp = *builtin_type_set;
+ type_code = TYPE_CODE_SET;
fmt = "set %s";
break;
+ case btTypedef:
+ default:
+ complain (&basic_type_complaint, t->bt);
+ return builtin_type_int;
}
}
ax++;
}
- /* For bitfields all we need is the width */
if (t->fBitfield) {
*bs = ax->width;
- return tp;
+ ax++;
}
/* All these types really point to some (common) MIPS type
definition, and only the type-qualifiers fully identify
- them. We`ll make the same effort at sharing */
+ them. We'll make the same effort at sharing. */
if (t->bt == btIndirect ||
t->bt == btStruct ||
t->bt == btUnion ||
char name[256], *pn;
/* Try to cross reference this type */
- tp1 = tp;
- ax += cross_ref(ax, &tp1, &pn);
+ ax += cross_ref(ax, &tp, type_code, &pn);
+ /* reading .o file ? */
+ if (UNSAFE_DATA_ADDR(tp))
+ tp = make_type(type_code, 0, 0, 0);
/* SOMEONE OUGHT TO FIX DBXREAD TO DROP "STRUCT" */
sprintf(name, fmt, pn);
- /* reading .o file ? */
- if (UNSAFE_DATA_ADDR(tp1))
- tp1 = tp;
- if (TYPE_CODE(tp1) == TYPE_CODE_UNDEF) {
- /*
- * Type was incompletely defined, now we know.
- */
- TYPE_CODE(tp1) = TYPE_CODE(tp);
- TYPE_NAME(tp1) = obsavestring(name, strlen(name));
- if (TYPE_CODE(tp1) == TYPE_CODE_ENUM) {
- int i;
-
- for (i = 0; i < TYPE_NFIELDS(tp1); i++)
- make_enum_constant(&TYPE_FIELD(tp1,i), tp1);
- }
- }
- if (tp1 != tp) {
- /* found as cross ref, rid of our template */
- if ((TYPE_FLAGS(tp) & TYPE_FLAG_PERM) == 0)
- free(tp);
- tp = tp1;
- /* stupid idea of prepending "struct" to type names */
- if (t->bt == btStruct && !index(TYPE_NAME(tp), ' ')) {
- sprintf(name, fmt, TYPE_NAME(tp));
- TYPE_NAME(tp) = obsavestring(name, strlen(name));
- }
- } else
- TYPE_NAME(tp) = savestring(name, strlen(name));
+ /* Usually, TYPE_CODE(tp) is already type_code. The main
+ exception is if we guessed wrong re struct/union/enum. */
+ TYPE_CODE(tp) = type_code;
+ TYPE_NAME(tp) = obsavestring(pn, strlen(pn));
}
/* Deal with range types */
if (t->bt == btRange) {
struct field *f;
- f = new_field(tp, "Low");
- f->bitpos = ax->dnLow;
+ TYPE_NFIELDS (tp) = 2;
+ TYPE_FIELDS (tp) =
+ (struct field *) obstack_alloc (symbol_obstack,
+ 2 * sizeof (struct field));
+ TYPE_FIELD_NAME (tp, 0) = "Low";
+ TYPE_FIELD_BITPOS (tp, 0) = ax->dnLow;
ax++;
- f = new_field(tp, "High");
- f->bitpos = ax->dnHigh;
+ TYPE_FIELD_NAME (tp, 1) = "High";
+ TYPE_FIELD_BITPOS (tp, 1) = ax->dnHigh;
ax++;
}
off++;
}
fh = get_rfd(cur_fd, rf);
- f = new_field(t, (char *)0);
- bzero(&ss, sizeof ss);
+
+ /* Fields are kept in an array */
+ /* FIXME - Memory leak! */
+ if (TYPE_NFIELDS(t))
+ TYPE_FIELDS(t) = (struct field*)
+ xrealloc(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(&ss, 0, sizeof ss);
/* XXX */ f->type = parse_type(fh->iauxBase + id * sizeof(AUXU),
&ss, &f->bitsize);
}
}
-
-/* Parse the symbols of the file described by FH, whose index is F_IDX.
- BOUND is the highest core address of this file's procedures */
-
-static
-parse_one_file(fh, f_idx, bound)
- FDR *fh;
-{
- register int s_idx;
- SYMR *sh;
- PDR *pr;
-
- /* Parse local symbols first */
-
- for (s_idx = 0; s_idx < fh->csym; s_idx++) {
- sh = (SYMR *) (fh->isymBase) + s_idx;
- cur_sdx = s_idx;
- parse_symbol(sh, fh->iauxBase);
- }
-
- /* Procedures next, note we need to look-ahead to
- find out where the procedure's code ends */
-
- for (s_idx = 0; s_idx < fh->cpd-1; s_idx++) {
- pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + s_idx;
- parse_procedure(pr, pr[1].adr); /* next proc up */
- }
- if (fh->cpd) {
- pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + s_idx;
- parse_procedure(pr, bound); /* next file up */
- }
-
- /* Linenumbers. At the end, check if we can save memory */
- parse_lines(fh, LINETABLE(cur_stab));
- if (LINETABLE(cur_stab)->nitems < fh->cline)
- shrink_linetable(cur_stab);
-}
\f
/* Master parsing procedure for first-pass reading of file symbols
into a partial_symtab.
the symtab we are reading. */
static
-parse_partial_symbols(end_of_text_seg)
+parse_partial_symbols(end_of_text_seg, objfile)
int end_of_text_seg;
+ struct objfile *objfile;
{
- int f_idx, s_idx, h_max, stat_idx;
+ int f_idx, s_idx;
+/* int stat_idx, h_max;*/
HDRR *hdr;
/* Running pointers */
FDR *fh;
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;
+ int includes_used;
+
+ /* Index within current psymtab dependency list */
+ struct partial_symtab **dependency_list;
+ int dependencies_used, dependencies_allocated;
+
+ includes_allocated = 30;
+ includes_used = 0;
+ psymtab_include_list = (char **) alloca (includes_allocated *
+ sizeof (char *));
+
+ dependencies_allocated = 30;
+ dependencies_used = 0;
+ dependency_list =
+ (struct partial_symtab **) alloca (dependencies_allocated *
+ sizeof (struct partial_symtab *));
+
+ last_source_file = 0;
+
/*
* Big plan:
*
fdr_to_pst = (struct pst_map *)xzalloc((hdr->ifdMax+1) * sizeof *fdr_to_pst);
fdr_to_pst++;
{
- struct partial_symtab * pst = new_psymtab("");
+ struct partial_symtab * pst = new_psymtab("", objfile);
fdr_to_pst[-1].pst = pst;
FDR_IDX(pst) = -1;
}
- /* Now scan the FDRs, mostly for dependencies */
- for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++)
- (void) parse_fdr(f_idx, 1);
-
- /* Take a good guess at how many symbols we might ever need */
- h_max = hdr->iextMax;
-
- /* Parse externals: two passes because they can be ordered
- in any way, but gdb likes to have them segregated by their
- source file. */
-
- /* 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++;
- }
-
- if (global_psymbols.list) {
- int origsize = global_psymbols.next - global_psymbols.list;
-
- global_psymbols.list = (struct partial_symbol *)
- xrealloc (global_psymbols.list,
- (h_max + origsize) * sizeof(struct partial_symbol));
- global_psymbols.next = global_psymbols.list + origsize;
- global_psymbols.size = h_max + origsize;
- } else {
- global_psymbols.list = (struct partial_symbol *)
- xmalloc (h_max * sizeof(struct partial_symbol));
- global_psymbols.next = global_psymbols.list;
- global_psymbols.size = h_max;
- }
-
- /* Pass 1.5 over files: partition out global symbol space */
- s_idx = global_psymbols.next - global_psymbols.list;
- for (f_idx = -1; f_idx < hdr->ifdMax; f_idx++) {
- fdr_to_pst[f_idx].pst->globals_offset = s_idx;
- s_idx += fdr_to_pst[f_idx].n_globals;
- }
-
- /* Pass 1.6 over files: partition out static symbol space.
- Note that this loop starts at 0, not at -1. */
- stat_idx = static_psymbols.next - static_psymbols.list;
- for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) {
- fdr_to_pst[f_idx].pst->statics_offset = stat_idx;
- fh = f_idx + (FDR *)(hdr->cbFdOffset);
- stat_idx += fh->csym;
- }
-
- /* Now that we know its max size, allocate static symbol list */
- if (static_psymbols.list) {
- int origsize = static_psymbols.next - static_psymbols.list;
-
- static_psymbols.list = (struct partial_symbol *)
- xrealloc (static_psymbols.list,
- stat_idx * sizeof(struct partial_symbol));
- static_psymbols.next = static_psymbols.list + origsize;
- static_psymbols.size = stat_idx;
- } else {
- static_psymbols.list = (struct partial_symbol *)
- xmalloc (stat_idx * sizeof(struct partial_symbol));
- static_psymbols.next = static_psymbols.list;
- static_psymbols.size = stat_idx;
- }
-
/* Pass 2 over external syms: fill in external symbols */
for (s_idx = 0; s_idx < hdr->iextMax; s_idx++) {
register struct partial_symbol *p;
if (esh->asym.sc == scUndefined || esh->asym.sc == scNil)
continue;
- /* Locate the psymtab and the preallocated psymbol. */
- pst = fdr_to_pst[esh->ifd].pst;
- p = global_psymbols.list + pst->globals_offset +
- pst->n_global_syms++;
- SYMBOL_NAME(p) = (char *)(esh->asym.iss);
- SYMBOL_NAMESPACE(p) = VAR_NAMESPACE;
-
switch (esh->asym.st) {
case stProc:
- SYMBOL_CLASS(p) = LOC_BLOCK;
- SYMBOL_VALUE(p) = esh->asym.value;
break;
case stGlobal:
- SYMBOL_CLASS(p) = LOC_STATIC;
- SYMBOL_VALUE_ADDRESS(p) = (CORE_ADDR)esh->asym.value;
misc_type = mf_data;
break;
case stLabel:
- SYMBOL_CLASS(p) = LOC_LABEL;
- SYMBOL_VALUE_ADDRESS(p) = (CORE_ADDR)esh->asym.value;
break;
default:
misc_type = mf_unknown;
complain (&unknown_ext_complaint, SYMBOL_NAME(p));
}
- prim_record_misc_function (SYMBOL_NAME(p),
- SYMBOL_VALUE(p),
+ prim_record_misc_function ((char *)(esh->asym.iss),
+ esh->asym.value,
misc_type);
}
/* Pass 3 over files, over local syms: fill in static symbols */
for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) {
- fh = f_idx + (FDR *)(cur_hdr->cbFdOffset);
- pst = fdr_to_pst[f_idx].pst;
- pst->texthigh = pst->textlow;
-
- for (s_idx = 0; s_idx < fh->csym; ) {
- register struct partial_symbol *p;
-
- sh = s_idx + (SYMR *) fh->isymBase;
-
- if (sh->sc == scUndefined || sh->sc == scNil) {
- /* FIXME, premature? */
- s_idx++;
- continue;
+ struct partial_symtab *save_pst;
+
+ fh = f_idx + (FDR *)(cur_hdr->cbFdOffset);
+ if (fh->csym == 0) {
+ fdr_to_pst[f_idx].pst = NULL;
+ continue;
+ }
+ pst = start_psymtab (objfile, 0, (char*)fh->rss,
+ fh->cpd ? fh->adr : 0,
+ -1,
+ global_psymbols.next,
+ static_psymbols.next);
+ 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;
+
+ 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;
+
+
+ /* The second symbol must be @stab. */
+ if (fh->csym >= 2
+ && strcmp(((SYMR *)fh->isymBase)[1].iss, stabs_symbol) == 0) {
+ for (s_idx = 2; s_idx < fh->csym; s_idx++) {
+ int type_code;
+ char *namestring;
+ sh = s_idx + (SYMR *) fh->isymBase;
+ type_code = MIPS_UNMARK_STAB(sh->index);
+ /* TEMPORARY: */
+ if (type_code == 0x84 && s_idx == 2) continue;
+ if (!MIPS_IS_STAB(sh)) {
+ if (sh->st == stProc || sh->st == stStaticProc) {
+ long procaddr = sh->value;
+ sh = (sh->index + (AUXU *)fh->iauxBase)->isym
+ + (SYMR *) fh->isymBase - 1;
+ if (sh->st == stEnd) {
+ long high = procaddr + sh->value;
+ if (high > pst->texthigh)
+ pst->texthigh = high;
+ }
}
+ continue;
+ }
+#define SET_NAMESTRING() namestring = (char*)sh->iss
+#define CUR_SYMBOL_TYPE type_code
+#define CUR_SYMBOL_VALUE sh->value
+#define CHECK_SECOND_N_SO() \
+ if (s_idx < fh->csym \
+ && MIPS_UNMARK_STAB(((SYMR *)fh->isymBase)[s_idx+1].index) == (unsigned char)N_SO)\
+ {\
+ s_idx++;\
+ sh = s_idx + (SYMR *) fh->isymBase;\
+ SET_NAMESTRING ();\
+ valu = CUR_SYMBOL_VALUE;\
+ s_idx++;\
+ }
+#define START_PSYMTAB(ofile,addr,fname,low,symoff,global_syms,static_syms)\
+ pst = save_pst
+#define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps) (void)0
+#define addr 0
+#define HANDLE_RBRAC(val) \
+ if ((val) > save_pst->texthigh) save_pst->texthigh = (val);
+/* FIXME: Handle start_file_start and _end */
+/* FIXME: Handle enums - but must deal with next_symbol_text. */
+#include "partial-stab.h"
+#undef addr
+ }
+ }
+ else {
+ for (s_idx = 0; s_idx < fh->csym; ) {
+ register struct partial_symbol *p;
+ char *name;
+ int class;
+ sh = s_idx + (SYMR *) fh->isymBase;
+
+ if (MIPS_IS_STAB(sh)) {
+ s_idx++;
+ continue;
+ }
- /* Locate the preallocated psymbol. */
- p = static_psymbols.list + pst->statics_offset +
- pst->n_static_syms;
- SYMBOL_NAME(p) = (char *)(sh->iss);
- SYMBOL_VALUE(p) = sh->value;
- SYMBOL_NAMESPACE(p) = VAR_NAMESPACE;
-
- switch (sh->st) {
- case stProc: /* Asm labels apparently */
- case stStaticProc: /* Function */
- SYMBOL_CLASS(p) = LOC_BLOCK;
- pst->n_static_syms++; /* Use gdb symbol */
- /* Skip over procedure to next one. */
- s_idx = (sh->index + (AUXU *)fh->iauxBase)
- ->isym;
- {
- long high;
- long procaddr = sh->value;
-
- sh = s_idx + (SYMR *) fh->isymBase - 1;
- if (sh->st != stEnd)
- continue;
- high = procaddr + sh->value;
- if (high > pst->texthigh)
- pst->texthigh = high;
- }
- continue;
- case stStatic: /* Variable */
- SYMBOL_CLASS(p) = LOC_STATIC;
- SYMBOL_VALUE_ADDRESS(p) = (CORE_ADDR)sh->value;
- break;
- case stTypedef: /* Typedef */
- SYMBOL_CLASS(p) = LOC_TYPEDEF;
- break;
- case stConstant: /* Constant decl */
- SYMBOL_CLASS(p) = LOC_CONST;
- break;
- case stBlock: /* { }, str, un, enum*/
- if (sh->sc == scInfo) {
- SYMBOL_NAMESPACE(p) = STRUCT_NAMESPACE;
- SYMBOL_CLASS(p) = LOC_TYPEDEF;
- pst->n_static_syms++;
- }
- /* Skip over the block */
- s_idx = 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);
- s_idx++;
- continue;
+ if (sh->sc == scUndefined || sh->sc == scNil ||
+ sh->index == 0xfffff) {
+ /* FIXME, premature? */
+ s_idx++;
+ continue;
+ }
+
+ name = (char *)(sh->iss);
+
+ switch (sh->st) {
+ long high;
+ long procaddr;
+ case stProc: /* Asm labels apparently */
+ case stStaticProc: /* Function */
+ ADD_PSYMBOL_TO_LIST(name, strlen(name),
+ VAR_NAMESPACE, LOC_BLOCK,
+ static_psymbols, sh->value);
+ /* Skip over procedure to next one. */
+ s_idx = (sh->index + (AUXU *)fh->iauxBase)->isym;
+ procaddr = sh->value;
+
+ sh = s_idx + (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,
+ static_psymbols, sh->value);
}
- pst->n_static_syms++; /* Use this gdb symbol */
- skip:
- s_idx++; /* Go to next file symbol */
-#if 0
-/* We don't usually record static syms, but some we seem to. chk dbxread. */
-/*FIXME*/ prim_record_misc_function (SYMBOL_NAME(p),
- SYMBOL_VALUE(p),
- misc_type);
-#endif
+ /* Skip over the block */
+ s_idx = 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);
+ s_idx++;
+ continue;
+ }
+ /* Use this gdb symbol */
+ ADD_PSYMBOL_TO_LIST(name, strlen(name),
+ VAR_NAMESPACE, class,
+ static_psymbols, sh->value);
+ skip:
+ s_idx++; /* Go to next file symbol */
}
- }
-
- /* The array (of lists) of globals must be sorted. */
- reorder_psymtabs();
-
- /* Now sort the global psymbols. */
- for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) {
- struct partial_symtab *pst = fdr_to_pst[f_idx].pst;
- if (pst->n_global_syms > 1)
- qsort (global_psymbols.list + pst->globals_offset,
- pst->n_global_syms, sizeof (struct partial_symbol),
- compare_psymbols);
+ }
+ end_psymtab (save_pst, psymtab_include_list, includes_used,
+ -1, save_pst->texthigh,
+ dependency_list, dependencies_used,
+ global_psymbols.next, static_psymbols.next);
}
/* Mark the last code address, and remember it for later */
of recursion we are called (to pretty up debug traces) */
static struct partial_symtab *
-parse_fdr(f_idx, lev)
+parse_fdr(f_idx, lev, objfile)
int f_idx;
+ int lev;
+ struct objfile *objfile;
{
register FDR *fh;
register struct partial_symtab *pst;
max_glevel = fh->glevel;
/* Make a new partial_symtab */
- pst = new_psymtab(fh->rss);
+ pst = new_psymtab(fh->rss, objfile);
if (fh->cpd == 0){
pst->textlow = 0;
pst->texthigh = 0;
for (s_idx = s_id0; s_idx < fh->crfd; s_idx++) {
RFDT *rh = (RFDT *) (fh->rfdBase) + s_idx;
- pst->dependencies[s_idx-s_id0] = parse_fdr(*rh, lev+1);
+ pst->dependencies[s_idx-s_id0] = parse_fdr(*rh, lev+1, objfile);
}
return pst;
}
+#ifdef READ_MIPS_FORMAT
+static int s_idx;
+
+char*
+next_symbol_text ()
+{
+ s_idx++;
+ return (char*)((SYMR *)cur_fdr->isymBase)[s_idx].iss;
+}
+#endif
/* Ancillary function to psymtab_to_symtab(). Does all the work
for turning the partial symtab PST into a symtab, recurring
static void
psymtab_to_symtab_1(pst, filename)
- struct partial_symtab *pst;
- char *filename;
+ struct partial_symtab *pst;
+ char *filename;
{
- int i, f_max;
- struct symtab *st;
- FDR *fh;
-
- if (pst->readin)
- return;
- pst->readin = 1;
-
- pending_list = (struct pending **) cur_hdr->cbOptOffset;
+ int have_stabs;
+ int i, f_max;
+ struct symtab *st;
+ FDR *fh;
+ int maxlines;
+ struct linetable *lines;
+
+ 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;
+ }
+
+ have_stabs =
+ fh && fh->csym >= 2
+ && strcmp(((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 pending **)
- xzalloc(cur_hdr->ifdMax * sizeof(struct pending *));
- cur_hdr->cbOptOffset = (int)pending_list;
+ pending_list = (struct mips_pending **)
+ xzalloc(cur_hdr->ifdMax * sizeof(struct mips_pending *));
+ cur_hdr->cbOptOffset = (int)pending_list;
}
-
- /* 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;
- st = new_symtab( "unknown", f_max, 0);
- } else {
- fh = (FDR *) (cur_hdr->cbFdOffset) + FDR_IDX(pst);
- f_max += fh->csym + fh->cpd;
- st = new_symtab(pst->filename, 2 * f_max, 2 * fh->cline);
- }
-
- /* 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. */
- if (info_verbose)
- {
- fputs_filtered (" ", stdout);
- wrap_here ("");
- fputs_filtered ("and ", stdout);
- wrap_here ("");
- printf_filtered ("%s...",
- pst->dependencies[i]->filename);
- wrap_here (""); /* Flush output */
- fflush (stdout);
- }
- /* We only pass the filename for debug purposes */
- psymtab_to_symtab_1(pst->dependencies[i],
- pst->dependencies[i]->filename);
+ }
+
+ /* 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. */
+ if (info_verbose)
+ {
+ fputs_filtered (" ", stdout);
+ wrap_here ("");
+ fputs_filtered ("and ", stdout);
+ wrap_here ("");
+ printf_filtered ("%s...",
+ pst->dependencies[i]->filename);
+ wrap_here (""); /* Flush output */
+ fflush (stdout);
}
-
- /* Now read the symbols for this symtab */
-
+ /* We only pass the filename for debug purposes */
+ psymtab_to_symtab_1(pst->dependencies[i],
+ pst->dependencies[i]->filename);
+ }
+
+ cur_fdr = fh;
+ /* Now read the symbols for this symtab */
+
+ if (!have_stabs) {
cur_fd = FDR_IDX(pst);
- cur_fdr = fh;
cur_stab = st;
-
+
/* 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_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)
+ return;
+ for (s_idx = 2; s_idx < fh->csym; s_idx++) {
+ register SYMR *sh = s_idx + (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);
+ /* TEMPORARY: */
+ if (type_code == 0x84 && s_idx == 2) continue;
+ process_one_symbol (type_code, 0, valu, name);
+ }
+ 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;
+ for (s_idx = 0; s_idx < fh->csym; ) {
+ sh = (SYMR *) (fh->isymBase) + s_idx;
+ cur_sdx = s_idx;
+ s_idx += parse_symbol(sh, fh->iauxBase);
+ }
- /* Parse locals and procedures */
- if (fh)
- parse_one_file(fh, cur_fd, (cur_fd == (cur_hdr->ifdMax - 1)) ?
- cur_hdr->cbDnOffset : fh[1].adr);
+ /* Procedures next, note we need to look-ahead to
+ find out where the procedure's code ends */
+
+ for (s_idx = 0; s_idx < fh->cpd-1; s_idx++) {
+ pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + s_idx;
+ parse_procedure(pr, pr[1].adr); /* next proc up */
+ }
+ if (fh->cpd) {
+ pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + s_idx;
+ 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);
+ }
+ }
+ if (!have_stabs) {
+ LINETABLE(st) = lines;
+
/* .. and our share of externals.
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->blocktype = stFile;
- top_stack->maxsyms = cur_hdr->isymMax + cur_hdr->ipdMax + cur_hdr->iextMax;
+ top_stack->maxsyms =
+ cur_hdr->isymMax + cur_hdr->ipdMax + cur_hdr->iextMax;
+
for (i = 0; i < cur_hdr->iextMax; i++) {
- register EXTR *esh = (EXTR *) (cur_hdr->cbExtOffset) + i;
- if (esh->ifd == cur_fd)
- parse_external(esh, 1);
+ register EXTR *esh = (EXTR *) (cur_hdr->cbExtOffset) + i;
+ if (esh->ifd == cur_fd)
+ parse_external(esh, 1);
}
-
+
/* If there are undefined, tell the user */
if (n_undef_symbols) {
- printf_filtered("File %s contains %d unresolved references:",
- st->filename, n_undef_symbols);
- printf_filtered("\n\t%4d variables\n\t%4d procedures\n\t%4d labels\n",
- n_undef_vars, n_undef_procs, n_undef_labels);
- n_undef_symbols = n_undef_labels = n_undef_vars = n_undef_procs = 0;
- }
+ printf_filtered("File %s contains %d unresolved references:",
+ st->filename, n_undef_symbols);
+ printf_filtered("\n\t%4d variables\n\t%4d procedures\n\t%4d labels\n",
+ n_undef_vars, n_undef_procs, n_undef_labels);
+ n_undef_symbols = n_undef_labels = n_undef_vars = n_undef_procs = 0;
+ }
pop_parse_stack();
-
- /*
- * Sort the symbol table now, we are done adding symbols to it.
- */
- sort_symtab_syms(st);
-
- /* Now link the psymtab and the symtab. */
- pst->symtab = 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;
}
\f
/* Ancillary parsing procedures. */
Return value says how many aux symbols we ate */
static
-cross_ref(rn, tpp, pname)
- RNDXR *rn;
- struct type **tpp;
- char **pname;
+cross_ref(rn, tpp, type_code, pname)
+ RNDXR *rn;
+ struct type **tpp;
+ int type_code; /* Use to alloc new type if none is found. */
+ char **pname;
{
unsigned rf;
t = (struct type *) sh->value;
*tpp = t;
} else {
- struct pending *p;
-
- /* Avoid duplicates */
- p = is_pending_symbol(fh, sh);
-
- if (p)
- *tpp = p->t;
- else
- add_pending(fh, sh, *tpp);
+ /* Avoid duplicates */
+ struct mips_pending *p = is_pending_symbol(fh, sh);
+ if (p)
+ *tpp = p->t;
+ else {
+ *tpp = make_type(type_code, 0, 0, 0);
+ add_pending(fh, sh, *tpp);
+ }
}
}
}
-/* Partial symbols are compared lexicog by their print names */
-
-static int
-compare_psymbols (s1, s2)
- register struct partial_symbol *s1, *s2;
-{
- register char
- *st1 = SYMBOL_NAME(s1),
- *st2 = SYMBOL_NAME(s2);
-
- return (st1[0] - st2[0] ? st1[0] - st2[0] :
- strcmp(st1 + 1, st2 + 1));
-}
-
/* Blocks with a smaller low bound should come first */
static int compare_blocks(b1,b2)
BLOCK_END (BLOCKVECTOR_BLOCK(bv,GLOBAL_BLOCK));
}
-/* Sort the symtab list, as required by some search procedures.
- We want files ordered to make them look right to users, and for
- searching (see block_for_pc). */
-
-static void
-reorder_symtabs()
-{
- register int i;
- struct symtab *stab;
- register struct symtab **all_symtabs;
- register int symtab_count;
-
- if (!symtab_list)
- return;
-
- /* Create an array of pointers to all the symtabs. */
- for (symtab_count = 0, stab = symtab_list;
- stab;
- symtab_count++, stab = stab->next) {
- obstack_grow (psymbol_obstack, &stab, sizeof (stab));
- /* FIXME: Only sort blocks for new symtabs ??? */
- sort_blocks(stab);
- }
-
- all_symtabs = (struct symtab **)
- obstack_base (psymbol_obstack);
- qsort((char *)all_symtabs, symtab_count,
- sizeof(struct symtab *), compare_symtabs);
-
- /* Re-construct the symtab list, but now it is sorted. */
- for (i = 0; i < symtab_count-1; i++)
- all_symtabs[i]->next = all_symtabs[i+1];
- all_symtabs[i]->next = 0;
- symtab_list = all_symtabs[0];
-
- obstack_free (psymbol_obstack, all_symtabs);
-}
-
-/* Sort the partial symtab list, as required by some search procedures.
- PC lookups stop at the first psymtab such that textlow <= PC < texthigh */
-
-static void
-reorder_psymtabs()
-{
- register int i;
- register int all_psymtabs_count;
- struct partial_symtab *pstab;
- struct partial_symtab **all_psymtabs;
-
- if (!partial_symtab_list)
- return;
-
- /* Create an array of pointers to all the partial_symtabs. */
-
- for (all_psymtabs_count = 0, pstab = partial_symtab_list;
- pstab;
- all_psymtabs_count++, pstab = pstab->next)
- obstack_grow (psymbol_obstack, &pstab, sizeof (pstab));
-
- all_psymtabs = (struct partial_symtab **)
- obstack_base (psymbol_obstack);
-
- qsort((char *)all_psymtabs, all_psymtabs_count,
- sizeof(struct partial_symtab *), compare_psymtabs);
-
- /* Re-construct the partial_symtab_list, but now it is sorted. */
-
- for (i = 0; i < all_psymtabs_count-1; i++)
- all_psymtabs[i]->next = all_psymtabs[i+1];
- all_psymtabs[i]->next = 0;
- partial_symtab_list = all_psymtabs[0];
-
- obstack_free (psymbol_obstack, all_psymtabs);
-}
\f
/* Constructor/restructor/destructor procedures */
static
struct symtab *
-new_symtab(name, maxsyms, maxlines)
+new_symtab(name, maxsyms, maxlines, objfile)
char *name;
{
- struct symtab *s = allocate_symtab (name);
+ struct symtab *s = allocate_symtab (name, objfile);
LINETABLE(s) = new_linetable(maxlines);
/* Allocate a new partial_symtab NAME */
static struct partial_symtab *
-new_psymtab(name)
+new_psymtab(name, objfile)
char *name;
+ struct objfile *objfile;
{
struct partial_symtab *pst;
pst = (struct partial_symtab *)
obstack_alloc (psymbol_obstack, sizeof (*pst));
- bzero (pst, sizeof (*pst));
+ memset (pst, 0, sizeof (*pst));
if (name == (char*)-1) /* FIXME -- why not null here? */
pst->filename = "<no name>";
else
pst->filename = name;
+ /* Chain it to its object file */
+ pst->objfile = objfile;
+ pst->objfile_chain = objfile->psymtabs;
+ objfile->psymtabs = pst;
+
pst->next = partial_symtab_list;
partial_symtab_list = pst;
/* Allocate a linetable array of the given SIZE */
-static
-struct linetable *new_linetable(size)
+static struct linetable *
+new_linetable(size)
{
struct linetable *l;
/* Oops, too big. Shrink it. This was important with the 2.4 linetables,
I am not so sure about the 3.4 ones */
-static void
-shrink_linetable(s)
- struct symtab *s;
+static struct linetable *
+shrink_linetable(lt)
+ struct linetable * lt;
{
- struct linetable *l = new_linetable(LINETABLE(s)->nitems);
+ struct linetable *l = new_linetable(lt->nitems);
- bcopy(LINETABLE(s), l,
- LINETABLE(s)->nitems * sizeof(l->item) + sizeof(struct linetable));
- free (LINETABLE(s));
- LINETABLE(s) = l;
+ memcpy(l, lt, lt->nitems * sizeof(l->item) + sizeof(struct linetable));
+ free (lt);
+ return l;
}
/* Allocate and zero a new blockvector of NBLOCKS blocks. */
struct symbol *s = (struct symbol *)
obstack_alloc (symbol_obstack, sizeof (struct symbol));
- bzero (s, sizeof (*s));
+ memset (s, 0, sizeof (*s));
SYMBOL_NAME(s) = name;
return s;
}
struct type *t = (struct type *)
obstack_alloc (symbol_obstack, sizeof (struct type));
- bzero (t, sizeof (*t));
+ memset (t, 0, sizeof (*t));
TYPE_VPTR_FIELDNO (t) = -1;
TYPE_NAME(t) = name;
+ TYPE_CPLUS_SPECIFIC(t) = &cplus_struct_default;
return t;
}
int length, uns;
char *name;
{
- register struct type *type;
-
- type = (struct type *) xzalloc(sizeof(struct type));
- TYPE_CODE(type) = code;
- TYPE_LENGTH(type) = length;
- TYPE_FLAGS(type) = uns ? TYPE_FLAG_UNSIGNED : 0;
- TYPE_NAME(type) = name;
- TYPE_VPTR_FIELDNO (type) = -1;
-
- return type;
-}
-
-/* Allocate a new field named NAME to the type TYPE */
-
-static
-struct field *
-new_field(type,name)
- struct type *type;
- char *name;
-{
- struct field *f;
-
- /* Fields are kept in an array */
- if (TYPE_NFIELDS(type))
- TYPE_FIELDS(type) = (struct field*)xrealloc(TYPE_FIELDS(type),
- (TYPE_NFIELDS(type)+1) * sizeof(struct field));
- else
- TYPE_FIELDS(type) = (struct field*)xzalloc(sizeof(struct field));
- f = &(TYPE_FIELD(type,TYPE_NFIELDS(type)));
- TYPE_NFIELDS(type)++;
- bzero(f, sizeof(struct field));
- f->name = name; /* Whether or not NAME is zero, this works. */
- return f;
+ register struct type *type;
+
+ /* FIXME, I don't think this ever gets freed. */
+ type = (struct type *) xzalloc(sizeof(struct type));
+ TYPE_CODE(type) = code;
+ TYPE_LENGTH(type) = length;
+ TYPE_FLAGS(type) = uns ? TYPE_FLAG_UNSIGNED : 0;
+ TYPE_NAME(type) = name;
+ TYPE_VPTR_FIELDNO (type) = -1;
+
+ if (code != TYPE_CODE_METHOD && code != TYPE_CODE_FUNC)
+ TYPE_CPLUS_SPECIFIC(type) = &cplus_struct_default;
+ return type;
}
-
-/* Make an enum constant for a member F of an enumerated type T */
-
-static
-make_enum_constant(f,t)
- struct field *f;
- struct type *t;
-{
- struct symbol *s;
- /*
- * This is awful, but that`s the way it is supposed to be
- * (BTW, no need to free the real 'type', it's a builtin)
- */
- f->type = (struct type *) f->bitpos;
-
- s = new_symbol(f->name);
- SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
- SYMBOL_CLASS(s) = LOC_CONST;
- SYMBOL_TYPE(s) = t;
- SYMBOL_VALUE(s) = f->bitpos;
- add_symbol(s, top_stack->cur_block);
-}
-
-
\f
/* Things used for calling functions in the inferior.
These functions are exported to our companion
- mips-dep.c file and are here because they play
+ mips-tdep.c file and are here because they play
with the symbol-table explicitly. */
-#if 0
-/* Need to make a new symbol on the fly for the dummy
- frame we put on the stack. Which goes in the.. */
-
-static struct symtab *dummy_symtab;
-
-/* Make up a dummy symbol for the code we put at END_PC,
- of size SIZE, invoking a function with NARGS arguments
- and using a frame of FRAMESIZE bytes */
-
-mips_create_dummy_symbol(end_pc, size, nargs, framesize)
-{
- struct block *bl;
- struct symbol *g;
- struct mips_extra_func_info *gdbinfo;
-
- /* Allocate symtab if not done already */
- if (dummy_symtab == 0)
- dummy_symtab = new_symtab(".dummy_symtab.", 100, 0);
-
- /* Make a new block. Only needs one symbol */
- bl = new_block(1);
- BLOCK_START(bl) = end_pc - size;
- BLOCK_END(bl) = end_pc;
-
- BLOCK_SUPERBLOCK(bl) =
- BLOCKVECTOR_BLOCK(BLOCKVECTOR(dummy_symtab),GLOBAL_BLOCK);
- add_block(bl, dummy_symtab);
- sort_blocks(dummy_symtab);
-
- BLOCK_FUNCTION(bl) = new_symbol("??");
- SYMBOL_BLOCK_VALUE(BLOCK_FUNCTION(bl)) = bl;
- g = new_symbol(".gdbinfo.");
- BLOCK_SYM(bl,BLOCK_NSYMS(bl)++) = g;
-
- SYMBOL_NAMESPACE(g) = LABEL_NAMESPACE;
- SYMBOL_CLASS(g) = LOC_CONST;
- SYMBOL_TYPE(g) = builtin_type_void;
- gdbinfo = (struct mips_extra_func_info *)
- xzalloc(sizeof(struct mips_extra_func_info));
-
- SYMBOL_VALUE(g) = (long) gdbinfo;
-
- gdbinfo->numargs = nargs;
- gdbinfo->framesize = framesize;
- gdbinfo->framereg = 29;
- gdbinfo->pcreg = 31;
- gdbinfo->regmask = -2;
- gdbinfo->regoffset = -4;
- gdbinfo->fregmask = 0; /* XXX */
- gdbinfo->fregoffset = 0; /* XXX */
-}
-
-/* We just returned from the dummy code at END_PC, drop its symbol */
-
-mips_destroy_dummy_symbol(end_pc)
-{
- struct block *bl;
- struct blockvector *bv = BLOCKVECTOR(dummy_symtab);
- int i;
-
- bl = block_for_pc(end_pc);
- free(BLOCK_FUNCTION(bl));
- free(SYMBOL_VALUE(BLOCK_SYM(bl,0)));
- free(BLOCK_SYM(bl,0));
-
- for (i = FIRST_LOCAL_BLOCK; i < BLOCKVECTOR_NBLOCKS(bv); i++)
- if (BLOCKVECTOR_BLOCK(bv,i) == bl)
- break;
- for (; i < BLOCKVECTOR_NBLOCKS(bv) - 1; i++)
- BLOCKVECTOR_BLOCK(bv,i) = BLOCKVECTOR_BLOCK(bv,i+1);
- BLOCKVECTOR_NBLOCKS(bv)--;
- sort_blocks(dummy_symtab);
- free(bl);
-}
-#endif
-
/* Sigtramp: make sure we have all the necessary information
about the signal trampoline code. Since the official code
from MIPS does not do so, we make up that information ourselves.
0, "fixed_decimal");
builtin_type_float_dec = make_type(TYPE_CODE_FLT, sizeof(double),
0, "floating_decimal");
-
- /* Templates types */
- builtin_type_struct = make_type(TYPE_CODE_STRUCT, 0, 0, 0);
- builtin_type_union = make_type(TYPE_CODE_UNION, 0, 0, 0);
- builtin_type_enum = make_type(TYPE_CODE_ENUM, 0, 0, 0);
- builtin_type_range = make_type(TYPE_CODE_RANGE, 0, 0, 0);
- builtin_type_set = make_type(TYPE_CODE_SET, 0, 0, 0);
-
- /* We can't do this now because builtin_type_void may not
- be set yet. Do it at symbol reading time. */
- /* builtin_type_ptr = lookup_pointer_type (builtin_type_void); */
}