/* 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.
along with this program; if not, write to the Free Software
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
+ discards existing cached information when all symbols are being
+ discarded; and mipscoff_symfile_read, which reads a symbol table
+ from a file.
+
+ mipscoff_symfile_read only does the minimum work necessary for letting the
+ user "name" things symbolically; it does not read the entire symtab.
+ Instead, it reads the external and static symbols and puts them in partial
+ symbol tables. When more extensive information is requested of a
+ file, the corresponding partial symbol table is mutated into a full
+ fledged symbol table by going back and reading the symbols
+ for real. mipscoff_psymtab_to_symtab() is called indirectly through
+ 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 <syms.h>
+#include <symconst.h>
+#include <sym.h>
#endif /* not CMUCS */
-/* Since these things are defined differently on various systems I'll
- (re)define here what I really need in this module. I only assume the
- three standard COFF structure definitions: filehdr, aouthdr, scnhdr */
-#define MIPS /* Kludge to get MIPS version of coff */
-#undef _ETEXT /* Avoid duplicated define from <syms.h> */
-#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;
};
-#undef a_magic
-#undef a_text
-#undef a_data
-#undef a_bss
-#undef a_syms
-#undef a_entry
-#define a_magic a.magic /* magic number */
-#define a_text a.tsize /* size of text segment */
-#define a_data a.dsize /* size of initialized data */
-#define a_bss a.bsize /* size of uninitialized data */
-#define a_syms f.f_nsyms /* size of symbol table */
-#define a_entry a.entry /* entry point */
-
-#undef N_BADMAG
-#define N_BADMAG(x) \
- (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC)
+
+/* 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. */
+
+#define FDR_IDX(p) (((struct symloc *)((p)->read_symtab_private))->fdr_idx)
+#define CUR_HDR(p) (((struct symloc *)((p)->read_symtab_private))->cur_hdr)
+
+struct symloc {
+ int fdr_idx;
+ HDRR *cur_hdr;
+};
/* Things we import explicitly from other modules */
extern struct block *block_for_pc();
extern void sort_symtab_syms();
-/* Forward declarations */
+/* Various complaints about symbol reading that don't abort the process */
+
+struct complaint unknown_ext_complaint =
+ {"unknown external symbol %s", 0, 0};
-static void psymtab_to_symtab_1();
+struct complaint unknown_sym_complaint =
+ {"unknown local symbol %s", 0, 0};
-/* Macros and extra defs */
+struct complaint unknown_st_complaint =
+ {"with type %d", 0, 0};
-struct complaint unknown_ext_complaint =
- {"unknown external symbol %s", 0, 0};
+struct complaint block_overflow_complaint =
+ {"block containing %s overfilled", 0, 0};
+
+struct complaint basic_type_complaint =
+ {"cannot map MIPS basic type 0x%x", 0, 0};
+
+struct complaint unknown_type_qual_complaint =
+ {"unknown type qualifier 0x%x", 0, 0};
+
+struct complaint array_bitsize_complaint =
+ {"size of array target type not known, assuming %d bits", 0, 0};
+
+struct complaint array_parse_complaint =
+ {"array type with strange relative symbol", 0, 0};
+
+/* Macros and extra defs */
-/* Already parsed symbols are marked specially */
+/* Already-parsed symbols are marked specially */
#define stParsed stType
(((a) == GLEVEL_3) ? ((b) < GLEVEL_3) : \
((b) == GLEVEL_3) ? -1 : (int)((b) - (a)))
-/* When looking at .o files avoid tripping over bad addresses */
+/* When looking at .o files, avoid tripping over bad addresses */
#define SAFE_TEXT_ADDR 0x400000
#define SAFE_DATA_ADDR 0x10000000
static struct symtab *cur_stab;
+/* MIPS symtab header for the current file */
+
+static HDRR *cur_hdr;
+
/* Pointer to current file decriptor record, and its index */
static FDR *cur_fdr;
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 decls */
+/* 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 int compare_blocks();
static struct partial_symtab *new_psymtab();
-static struct partial_symbol *new_psymbol();
static struct partial_symtab *parse_fdr();
static int compare_psymbols();
-static void reorder_symtabs();
-static void reorder_psymtabs();
+static void psymtab_to_symtab_1();
+static void add_block();
+static void add_symbol();
+static int add_line();
+static struct linetable *shrink_linetable();
\f
/* Things we export to other modules */
-
-/* Lists of partial symbols */
-
-struct psymbol_allocation_list global_psymbols, static_psymbols;
-
/* Address bounds for the signal trampoline in inferior, if any */
+/* FIXME: Nothing really seems to use this. Why is it here? */
CORE_ADDR sigtramp_address, sigtramp_end;
-
-/* Functions that we really export */
-
-/* THIS DESCRIPTION IS OBSOLETE POST-BFD; FIXME! */
-/* Basically, this module must provide two functions: symbol_file_command()
- which loads the symbol table from a file, and add_file_command() which
- adds more symbols to the symbol table (incrementally).
-
- These two functions only do the minimum work necessary for letting the
- user "name" things symbolically, they do not read the entire symtab.
- Instead, they read in the external symbols and put them in partial
- symbol tables. When more extensive information is requested of a
- file the corresponding partial symbol table is mutated into a full
- fledged symbol table by going back and reading the relative symbols
- for real. mipscoff_psymtab_to_symtab() is the function that does this */
-
/* The entry point (starting address) of the file, if it is an executable. */
-static CORE_ADDR entry_point;
-
extern CORE_ADDR startup_file_start; /* From blockframe.c */
extern CORE_ADDR startup_file_end; /* From blockframe.c */
void
mipscoff_new_init()
{
+ /* 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;
{
- bfd *abfd = sf->sym_bfd;
sf->sym_private = NULL;
- /* Save startup file's range of PC addresses to help blockframe.c
- decide where the bottom of the stack is. */
- if (bfd_get_file_flags (abfd) & EXEC_P)
- {
- /* Executable file -- record its entry point so we'll recognize
- the startup file because it contains the entry point. */
- entry_point = bfd_get_start_address (abfd);
- }
- else
- {
- /* Examination of non-executable.o files. Short-circuit this stuff. */
- /* ~0 will not be in any file, we hope. */
- entry_point = ~0;
- /* set the startup file to be an empty range. */
- startup_file_start = 0;
- startup_file_end = 0;
- }
}
void
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 num_symbols;
int symtab_offset;
int stringtab_offset;
/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
desc = fileno ((FILE *)(abfd->iostream)); /* Raw file descriptor */
- num_symbols = bfd_get_symcount (abfd); /* How many syms */
-/* symtab_offset = obj_sym_filepos (abfd); * Symbol table file offset */
-/* stringtab_offset = symtab_offset + num_symbols * SYMESZ; * String tab */
/* End of warning */
-#ifdef TDESC
- debug_info = text_hdr.s_relptr;
- if (tdesc_handle)
- {
- dc_terminate (tdesc_handle);
- tdesc_handle = 0;
- }
-#endif
-
-#if 0
- /* Read the line number table, all at once. */
- info->min_lineno_offset = 0;
- info->max_lineno_offset = 0;
- bfd_map_over_sections (abfd, find_linenos, info);
-
- val = init_lineno (desc, info->min_lineno_offset,
- info->max_lineno_offset - info->min_lineno_offset);
- if (val < 0)
- error ("\"%s\": error reading line numbers\n", name);
-
- /* Now read the string table, all at once. */
-
- val = init_stringtab (desc, stringtab_offset);
- if (val < 0)
- {
- free_all_symtabs (); /* FIXME blows whole symtab */
- printf ("\"%s\": can't get string table", name);
- fflush (stdout);
- return;
- }
- make_cleanup (free_stringtab, 0);
-#endif
-
- /* Position to read the symbol table. Do not read it all at once. */
+ /* Position to read the symbol table. */
val = lseek (desc, (long)symtab_offset, 0);
if (val < 0)
perror_with_name (name);
/* Now that the executable file is positioned at symbol table,
process it and define symbols accordingly. */
- read_mips_symtab(abfd, desc, 0);
-
-/* patch_opaque_types ();*/
-
- /* Sort symbols alphabetically within each block. */
-
- sort_all_symtab_syms ();
+ read_mips_symtab(sf->objfile, desc);
/* Go over the misc symbol bunches and install them in vector. */
- condense_misc_bunches (0);
-
- /* Make a default for file to list. */
-
- select_source_symtab (0); /* FIXME, this might be too slow, see dbxread */
-}
-
-void
-mipscoff_symfile_discard()
-{
+ condense_misc_bunches (!mainline);
}
/* Exported procedure: Allocate zeroed memory */
-char *xzalloc(size)
+char *
+xzalloc(size)
{
char *p = xmalloc(size);
- bzero(p, size);
+ memset(p, 0, size);
return p;
}
most of the work to an ancillary procedure, and sorts
and reorders the symtab list at the end */
-/* Forward decls */
-static HDRR *cur_hdr; /* MIPS symtab header for the current file */
-
-void
+static void
mipscoff_psymtab_to_symtab(pst)
struct partial_symtab *pst;
{
fflush(stdout);
}
/* Restore the header and list of pending typedefs */
- cur_hdr = (HDRR *) pst->ldsymlen;
+ cur_hdr = CUR_HDR(pst);
- psymtab_to_symtab_1(pst);
+ 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 ();
- /* Finish up the debug error message. */
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))
/* Find a file descriptor given its index RF relative to a file CF */
-static
-FDR *get_rfd( cf, rf)
+static FDR *
+get_rfd (cf, rf)
+ int cf, rf;
{
register FDR *f;
/* Return a safer print NAME for a file descriptor */
-static
-char *fdr_name(name)
+static char *
+fdr_name(name)
char *name;
{
if (name == (char *) -1)
FIXME: INCREMENTAL is currently always zero, though it should not be. */
static
-read_mips_symtab (abfd, desc, incremental)
- bfd *abfd;
+read_mips_symtab (objfile, desc)
+ struct objfile *objfile;
int desc;
- int incremental;
{
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(cur_hdr, incremental, end_of_text_seg);
- cur_hdr = 0;
+ 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);
}
-
- /*
- * Dont allow char * to have a typename (else would get
- * caddr_t.)
- */
- TYPE_NAME(lookup_pointer_type(builtin_type_char)) = 0;
+#endif
}
-
\f
/* Local utilities */
-
/* Map of FDR indexes to partial symtabs */
static struct pst_map {
struct partial_symtab *pst; /* the psymtab proper */
- int n_globals; /* globals it exports */
} * 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;
/* Release storage when done with this file */
-static
+static void
free_numargs()
{
struct numarg *n = numargs_list, *m;
/* 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
+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 stNil:
break;
- case stGlobal: /* external symbol, goes into the primary block */
+ case stGlobal: /* external symbol, goes into global block */
class = LOC_STATIC;
b = BLOCKVECTOR_BLOCK(BLOCKVECTOR(top_stack->cur_st),
GLOBAL_BLOCK);
+ s = new_symbol(sh->iss);
+ SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value;
goto data;
- case stStatic: /* static data, goes into the current block. */
+ case stStatic: /* static data, goes into current block. */
class = LOC_STATIC;
b = top_stack->cur_block;
+ s = new_symbol(sh->iss);
+ SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value;
goto data;
- case stLocal: /* local variable, goes into the current block */
+ case stLocal: /* local variable, goes into current block */
if (sh->sc == scRegister) {
class = LOC_REGISTER;
if (sh->value > 31)
} else
class = LOC_LOCAL;
b = top_stack->cur_block;
+ s = new_symbol(sh->iss);
+ SYMBOL_VALUE(s) = sh->value;
data: /* Common code for symbols describing data */
- s = new_symbol(sh->iss);
SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
SYMBOL_CLASS(s) = class;
add_symbol(s, b);
else
SYMBOL_TYPE(s) = parse_type(ax + sh->index, sh, 0);
/* Value of a data symbol is its memory address */
- SYMBOL_VALUE(s) = sh->value;
break;
- case stParam: /* argument to procedure, goes into current block */
+ 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;
SYMBOL_VALUE(s) = sh->value;
SYMBOL_TYPE(s) = parse_type(ax + sh->index, sh, 0);
add_symbol(s, top_stack->cur_block);
+#if 0
+ /* FIXME: This has not been tested. See dbxread.c */
+ /* Add the type of this parameter to the function/procedure
+ type of this block. */
+ add_param_to_type(&top_stack->cur_block->function->type,s);
+#endif
break;
- case stLabel: /* label, we do make a symbol for it */
+ case stLabel: /* label, goes into current block */
s = new_symbol(sh->iss);
SYMBOL_NAMESPACE(s) = VAR_NAMESPACE; /* so that it can be used */
SYMBOL_CLASS(s) = LOC_LABEL; /* but not misused */
- SYMBOL_VALUE(s) = sh->value;
+ SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value;
SYMBOL_TYPE(s) = builtin_type_int;
add_symbol(s, top_stack->cur_block);
break;
- case stProc: /* Procedure */
- case stStaticProc: /* Static procedure */
+ case stProc: /* Procedure, usually goes into global block */
+ case stStaticProc: /* Static procedure, goes into current block */
s = new_symbol(sh->iss);
SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
SYMBOL_CLASS(s) = LOC_BLOCK;
t = builtin_type_int;
else
t = parse_type(ax + sh->index, sh, 0);
- add_symbol(s, top_stack->cur_block);
+ b = top_stack->cur_block;
+ if (sh->st == stProc) {
+ struct blockvector *bv = BLOCKVECTOR(top_stack->cur_st);
+ /* The next test should normally be true,
+ but provides a hook for nested functions
+ (which we don't want to make global). */
+ if (b == BLOCKVECTOR_BLOCK(bv, STATIC_BLOCK))
+ b = BLOCKVECTOR_BLOCK(bv, GLOBAL_BLOCK);
+ }
+ add_symbol(s, b);
/* 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
+ table. */
+ bcopy(SYMBOL_TYPE(s),lookup_function_type(t),sizeof(struct type));
+#else
SYMBOL_TYPE(s) = lookup_function_type (t);
+#endif
/* Create and enter a new lexical context */
b = new_block(top_stack->maxsyms);
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) {
- printf_filtered("Internal: cannot map MIPS basic type x%x\n", t->bt);
+ 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++;
}
the symbol SX we are currently analyzing.
Returns the number of aux symbols we parsed. */
-static
+static int
upgrade_type(tpp, tq, ax, sh)
struct type **tpp;
AUXU *ax;
SYMR *sh;
{
- int off = 0;
- int ret = 0;
+ int off;
struct type *t;
- if (tq == tqPtr) {
+ /* Used in array processing */
+ int rf, id;
+ FDR *fh;
+ struct field *f;
+ SYMR ss;
+ int lower, upper;
+
+ switch (tq) {
+ case tqPtr:
t = lookup_pointer_type (*tpp);
- } else if (tq == tqProc) {
+ *tpp = t;
+ return 0;
+
+ case tqProc:
t = lookup_function_type (*tpp);
- } else if (tq == tqArray) {
- int rf, id;
- FDR *fh;
- struct field *f;
- SYMR ss;
+ *tpp = t;
+ return 0;
+ case tqArray:
+ off = 0;
t = make_type(TYPE_CODE_ARRAY, 0, 0, 0);
TYPE_TARGET_TYPE(t) = *tpp;
- /* Pointer to domain type (type of index) */
+ /* Determine and record the domain type (type of index) */
id = ax->rndx.index;
- if ((rf = ax->rndx.rfd) == 0xfff)
- rf = (++ax)->isym, off++;
-
+ rf = ax->rndx.rfd;
+ if (rf == 0xfff) {
+ rf = (++ax)->isym;
+ off++;
+ }
fh = get_rfd(cur_fd, rf);
- f = new_field(t, 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);
+ if (off == 0) {
/*
* This seems to be a pointer to the end of the Block defining
* the type. Why it is here is magic for me, and I have no
* good use for it anyways.
*/
- if (off == 0) {
+ /* This used to occur because cross_ref returned
+ the wrong result (ax pointed wrong). FIXME,
+ delete this code in a while. -- gnu@cygnus jul91 */
+ complain (&array_parse_complaint, 0);
off++;
id = (++ax)->rndx.index;
if ((rf = ax->rndx.rfd) == 0xfff)
rf = (++ax)->isym, off++;
}
- f->bitpos = (++ax)->dnLow; /* ?? */
- f->bitsize = (++ax)->dnHigh; /* ?? */
- rf = (++ax)->width - 1; /* bit alignment */
+ lower = (++ax)->dnLow;
+ upper = (++ax)->dnHigh;
+ rf = (++ax)->width; /* bit size of array element */
+
+ /* Check whether supplied array element bit size matches
+ the known size of the element type. If this complaint
+ ends up not happening, we can remove this code. It's
+ here because we aren't sure we understand this *&%&$
+ symbol format. */
id = TYPE_LENGTH(TYPE_TARGET_TYPE(t)) << 3; /* bitsize */
-
if (id == 0) {
/* Most likely an undefined type */
- id = rf + 1;
+ id = rf;
TYPE_LENGTH(TYPE_TARGET_TYPE(t)) = id >> 3;
}
- TYPE_LENGTH(t) = (f->bitsize < 0) ? 0 :
- (f->bitsize - f->bitpos + 1) * (id >> 3);
- ret = 4 + off;
- } else {
- if (tq != tqVol)
- printf_filtered("Internal: unknown type qualifier %x\n", tq);
- return ret;
- }
+ if (id != rf)
+ complain (&array_bitsize_complaint, rf);
- *tpp = t;
- return ret;
+ TYPE_LENGTH(t) = (upper < 0) ? 0 :
+ (upper - lower + 1) * (rf >> 3);
+ *tpp = t;
+ return 4 + off;
+
+ case tqVol:
+ /* Volatile -- currently ignored */
+ return 0;
+
+ default:
+ complain (&unknown_type_qual_complaint, tq);
+ return 0;
+ }
}
making sure we know where the aux are for it. For procedures,
parsing of the PDRs has already provided all the needed
information, we only parse them if SKIP_PROCEDURES is false,
- and only if this causes no symbol duplication */
+ and only if this causes no symbol duplication.
+
+ This routine clobbers top_stack->cur_block and ->cur_st. */
static
parse_external(es, skip_procedures)
char *what;
switch (es->asym.st) {
case stStaticProc:
- case stProc: what = "Procedure"; n_undef_procs++; break;
- case stGlobal: what = "Variable"; n_undef_vars++; break;
- case stLabel: what = "Label"; n_undef_labels++; break;
- default : what = "Symbol"; break;
+ case stProc: what = "procedure"; n_undef_procs++; break;
+ case stGlobal: what = "variable"; n_undef_vars++; break;
+ case stLabel: what = "label"; n_undef_labels++; break;
+ default : what = "symbol"; break;
}
n_undef_symbols++;
if (info_verbose)
- printf_filtered("Warning: %s %s is undefined (in %s)\n", what,
+ printf_filtered("Warning: %s `%s' is undefined (in %s)\n", what,
es->asym.iss, fdr_name(cur_fdr->rss));
return;
}
FDR *fh;
struct linetable *lt;
{
- char *base = (char*)fh->cbLineOffset;
+ unsigned char *base = (unsigned char*)fh->cbLineOffset;
int i, j, k;
int delta, count, lineno = 0;
PDR *pr;
*/
if (pr->iline >= halt) continue;
- base = (char*)pr->cbLineOffset;
+ base = (unsigned char*)pr->cbLineOffset;
l = pr->adr >> 2; /* in words */
halt += (pr->adr >> 2) - pr->iline;
for (lineno = pr->lnLow; l < halt;) {
count = *base & 0x0f;
delta = *base++ >> 4;
+ if (delta >= 8)
+ delta -= 16;
if (delta == -8) {
- delta = (base[0] << 8) | (base[1] & 0xff);
+ delta = (base[0] << 8) | base[1];
+ if (delta >= 0x8000)
+ delta -= 0x10000;
base += 2;
}
lineno += delta;/* first delta is 0 */
}
}
+\f
+/* Master parsing procedure for first-pass reading of file symbols
+ into a partial_symtab.
-/* 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 */
+ Parses the symtab described by the global symbolic header CUR_HDR.
+ END_OF_TEXT_SEG gives the address just after the text segment for
+ the symtab we are reading. */
static
-parse_one_file(fh, f_idx, bound)
- FDR *fh;
+parse_partial_symbols(end_of_text_seg, objfile)
+ int end_of_text_seg;
+ struct objfile *objfile;
{
- register int s_idx;
- SYMR *sh;
- PDR *pr;
-
- /* Parse local symbols first */
+ int f_idx, s_idx;
+/* int stat_idx, h_max;*/
+ HDRR *hdr;
+ /* Running pointers */
+ FDR *fh;
+ RFDT *rh;
+ register EXTR *esh;
+ register SYMR *sh;
+ struct partial_symtab *pst;
- 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);
- }
+ int past_first_source_file = 0;
- /* Procedures next, note we need to look-ahead to
- find out where the procedure's code ends */
+ /* List of current psymtab's include files */
+ char **psymtab_include_list;
+ int includes_allocated;
+ int includes_used;
- 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 */
- }
+ /* Index within current psymtab dependency list */
+ struct partial_symtab **dependency_list;
+ int dependencies_used, dependencies_allocated;
- /* 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);
-}
+ 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 *));
-/* Master parsing procedure. Parses the symtab described by the
- symbolic header HDR. If INCREMENTAL is true we are called
- by add-file and must preserve the old symtabs. END_OF_TEXT_SEG
- gives the address just after the text segment for the symtab
- we are reading. */
-static
-parse_partial_symbols(hdr, incremental, end_of_text_seg)
- HDRR *hdr;
-{
- int f_idx, s_idx, h_max;
- CORE_ADDR dummy, *prevhigh;
- /* Running pointers */
- FDR *fh;
- RFDT *rh;
- register EXTR *esh;
+ last_source_file = 0;
/*
* Big plan:
*
- * Only parse the External symbols, and the Relative FDR.
+ * 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
+ * Allocate space only for the file's portions we need to
* look at. (XXX)
*/
- cur_hdr = hdr;
+ hdr = cur_hdr;
max_gdbinfo = 0;
max_glevel = MIN_GLEVEL;
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;
- pst->ldsymoff = -1;
+ 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 */
-
- /* Pass 1: 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) {
- global_psymbols.list = (struct partial_symbol *)
- xrealloc( global_psymbols.list, (h_max +
- global_psymbols.size) * sizeof(struct partial_symbol));
- global_psymbols.next = global_psymbols.list + global_psymbols.size;
- global_psymbols.size += h_max;
- } else {
- global_psymbols.list = (struct partial_symbol *)
- xmalloc( h_max * sizeof(struct partial_symbol));
- global_psymbols.size = h_max;
- global_psymbols.next = global_psymbols.list;
- }
-
- 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 2: fill in symbols */
+ /* Pass 2 over external syms: fill in external symbols */
for (s_idx = 0; s_idx < hdr->iextMax; s_idx++) {
register struct partial_symbol *p;
enum misc_function_type misc_type = mf_text;
if (esh->asym.sc == scUndefined || esh->asym.sc == scNil)
continue;
- p = new_psymbol(&global_psymbols, esh->asym.iss, esh->ifd);
- SYMBOL_VALUE(p) = esh->asym.value;
- SYMBOL_NAMESPACE(p) = VAR_NAMESPACE;
switch (esh->asym.st) {
case stProc:
- SYMBOL_CLASS(p) = LOC_BLOCK;
break;
case stGlobal:
- SYMBOL_CLASS(p) = LOC_STATIC;
misc_type = mf_data;
break;
case stLabel:
- SYMBOL_CLASS(p) = LOC_LABEL;
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);
}
-
- /* The array (of lists) of globals must be sorted.
- Take care, since we are at it, of pst->texthigh.
-
- NOTE: The way we handle textlow/high is incorrect, but good
- enough for a first approximation. The case we fail is on a
- file "foo.c" that looks like
- proc1() {...}
- #include "bar.c" -- this contains proc2()
- proc3() {...}
- where proc3() is attributed to bar.c. But since this is a
- dependent file it will cause loading of foo.c as well, so
- everything will be fine at the end. */
-
- prevhigh = &dummy;
+ /* Pass 3 over files, over local syms: fill in static symbols */
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);
- if (pst->textlow) {
- *prevhigh = pst->textlow;
- prevhigh = &pst->texthigh;
+ 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;
+ }
+
+ 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);
+ }
+ /* 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 */
}
+ }
+ 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 */
- *prevhigh = end_of_text_seg;
hdr->cbDnOffset = end_of_text_seg;
- reorder_psymtabs();
free(&fdr_to_pst[-1]);
fdr_to_pst = 0;
}
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;
pst->textlow = fh->adr;
pst->texthigh = fh->cpd; /* To be fixed later */
}
- /* Reverse mapping PST -> FDR */
- pst->ldsymoff = f_idx;
+ /* Make everything point to everything. */
+ FDR_IDX(pst) = f_idx;
fdr_to_pst[f_idx].pst = pst;
fh->ioptBase = (int)pst;
pst->number_of_dependencies = fh->crfd - s_id0;
pst->dependencies = (struct partial_symtab **)
obstack_alloc (psymbol_obstack,
- pst->number_of_dependencies * sizeof(char*));
+ pst->number_of_dependencies *
+ sizeof (struct partial_symtab *));
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
- first on all dependent psymtabs */
+ first on all dependent psymtabs. The argument FILENAME is
+ only passed so we can see in debug stack traces what file
+ is being read. */
static void
-psymtab_to_symtab_1(pst)
- struct partial_symtab *pst;
+psymtab_to_symtab_1(pst, filename)
+ struct partial_symtab *pst;
+ char *filename;
{
- int i, f_max;
- struct symtab *st;
- FDR *fh;
+ 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;
+ }
- if (pst->readin)
- return;
- pst->readin = 1;
+ have_stabs =
+ fh && fh->csym >= 2
+ && strcmp(((SYMR *)fh->isymBase)[1].iss, stabs_symbol) == 0;
- pending_list = (struct pending **) cur_hdr->cbOptOffset;
+ 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 */
- f_max = pst->n_global_syms + pst->n_static_syms;
- if (pst->ldsymoff == -1) {
- fh = 0;
- st = new_symtab( "unknown", f_max, 0);
- } else {
- fh = (FDR *) (cur_hdr->cbFdOffset) + pst->ldsymoff;
- 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.
- */
- for (i = 0; i < pst->number_of_dependencies; i++)
- if (!pst->dependencies[i]->readin) {
- /*
- * DO NOT inform about additional files that need to
- * be read in, it would only annoy the user.
- */
- psymtab_to_symtab_1(pst->dependencies[i]);
+ }
+
+ /* 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 */
-
- cur_fd = pst->ldsymoff;
- cur_fdr = fh;
+ /* 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_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),
- GLOBAL_BLOCK);
+ STATIC_BLOCK);
BLOCK_START(top_stack->cur_block) = fh ? fh->adr : 0;
BLOCK_END(top_stack->cur_block) = 0;
top_stack->blocktype = stFile;
- top_stack->maxsyms = f_max;
+ top_stack->maxsyms = 2*f_max;
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 ? */
+ 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);
+ }
+
+ /* 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);
+ }
}
}
- return (rn->rfd == 0xfff);
+
+ /* We used one auxent normally, two if we got a "next one" rf. */
+ return (rn->rfd == 0xfff? 2: 1);
}
}
-/* Add a new symbol S to a block B */
+/* Add a new symbol S to a block B.
+ Infrequently, we will need to reallocate the block to make it bigger.
+ We only detect this case when adding to top_stack->cur_block, since
+ that's the only time we know how big the block is. FIXME. */
-static
+static void
add_symbol(s,b)
struct symbol *s;
struct block *b;
{
- BLOCK_SYM(b,BLOCK_NSYMS(b)++) = s;
+ int nsyms = BLOCK_NSYMS(b)++;
+ struct block *origb;
+ struct parse_stack *stackp;
+
if (b == top_stack->cur_block &&
- BLOCK_NSYMS(b) > top_stack->maxsyms)
- printf_filtered("Internal: block at @%x overfilled (by %d)\n",
- b, BLOCK_NSYMS(b) - top_stack->maxsyms);
+ nsyms >= top_stack->maxsyms) {
+ complain (&block_overflow_complaint, s->name);
+ /* In this case shrink_block is actually grow_block, since
+ BLOCK_NSYMS(b) is larger than its current size. */
+ origb = b;
+ b = shrink_block (top_stack->cur_block, top_stack->cur_st);
+
+ /* Now run through the stack replacing pointers to the
+ original block. shrink_block has already done this
+ for the blockvector and BLOCK_FUNCTION. */
+ for (stackp = top_stack; stackp; stackp = stackp->next) {
+ if (stackp->cur_block == origb) {
+ stackp->cur_block = b;
+ stackp->maxsyms = BLOCK_NSYMS (b);
+ }
+ }
+ }
+ BLOCK_SYM(b,nsyms) = s;
}
/* Add a new block B to a symtab S */
-static
+static void
add_block(b,s)
struct block *b;
struct symtab *s;
MIPS' linenumber encoding might need more than one byte
to describe it, LAST is used to detect these continuation lines */
-static
+static int
add_line(lt, lineno, adr, last)
struct linetable *lt;
+ int lineno;
CORE_ADDR adr;
+ int last;
{
if (last == 0)
last = -2; /* make sure we record first line */
}
-/* 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)
/* Cosmetic */
if (BLOCK_END(BLOCKVECTOR_BLOCK(bv,GLOBAL_BLOCK)) == 0)
BLOCK_START(BLOCKVECTOR_BLOCK(bv,GLOBAL_BLOCK)) = 0;
+ if (BLOCK_END(BLOCKVECTOR_BLOCK(bv,STATIC_BLOCK)) == 0)
+ BLOCK_START(BLOCKVECTOR_BLOCK(bv,STATIC_BLOCK)) = 0;
return;
}
/*
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 = (struct symtab *) xzalloc(sizeof(struct symtab));
- int i;
+ struct symtab *s = allocate_symtab (name, objfile);
LINETABLE(s) = new_linetable(maxlines);
- s->filename = name;
-
/* All symtabs must have at least two blocks */
BLOCKVECTOR(s) = new_bvect(2);
BLOCKVECTOR_BLOCK(BLOCKVECTOR(s), GLOBAL_BLOCK) = new_block(maxsyms);
return s;
}
-/* Cleanup before loading a fresh image */
-
-static destroy_all_symtabs()
-{
- if (symfile)
- free(symfile);
- symfile = 0;
-
- free_all_symtabs();
- current_source_symtab = 0;
- /* psymtabs! */
-}
-
/* 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;
- /* Keep a backpointer to the file`s symbols */
- pst->ldsymlen = (int)cur_hdr;
+ /* Keep a backpointer to the file's symbols */
+ pst->read_symtab_private = (char *) obstack_alloc (psymbol_obstack,
+ sizeof (struct symloc));
+ CUR_HDR(pst) = cur_hdr;
/* The way to turn this into a symtab is to call... */
pst->read_symtab = mipscoff_psymtab_to_symtab;
}
-/* Allocate a new NAME psymbol from LIST, extending it if necessary.
- The psymbol belongs to the psymtab at index PST_IDX */
-
-static struct partial_symbol *
-new_psymbol(list, name, pst_idx)
- struct psymbol_allocation_list *list;
- char *name;
-{
- struct partial_symbol *p;
- struct partial_symtab *pst = fdr_to_pst[pst_idx].pst;
-
- /* Lists are pre-sized, we won`t overflow */
-
- p = list->list + pst->globals_offset + pst->n_global_syms++;
- SYMBOL_NAME(p) = name;
- return p;
-}
-
-
/* 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 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. */
static
-struct blockvector *new_bvect(nblocks)
+struct blockvector *
+new_bvect(nblocks)
{
struct blockvector *bv;
int size;
/* Allocate and zero a new block of MAXSYMS symbols */
static
-struct block *new_block(maxsyms)
+struct block *
+new_block(maxsyms)
{
int size = sizeof(struct block) + (maxsyms-1) * sizeof(struct symbol *);
struct block *b = (struct block *)xzalloc(size);
return b;
}
-/* Ooops, too big. Shrink block B in symtab S to its minimal size */
+/* Ooops, too big. Shrink block B in symtab S to its minimal size.
+ Shrink_block can also be used by add_symbol to grow a block. */
static struct block *
shrink_block(b, s)
struct blockvector *bv = BLOCKVECTOR(s);
int i;
- /* Just get a new one, copy, and fix references to the old one */
+ /* Just reallocate it and fix references to the old one */
- new = (struct block *)xmalloc(sizeof(struct block) +
+ new = (struct block *) xrealloc ((char *)b, sizeof(struct block) +
(BLOCK_NSYMS(b)-1) * sizeof(struct symbol *));
- bcopy(b, new, sizeof(*new) + (BLOCK_NSYMS(b) - 1) * sizeof(struct symbol*));
-
/* Should chase pointers to old one. Fortunately, that`s just
the block`s function and inferior blocks */
- if (BLOCK_FUNCTION(b) && SYMBOL_BLOCK_VALUE(BLOCK_FUNCTION(b)) == b)
- SYMBOL_BLOCK_VALUE(BLOCK_FUNCTION(b)) = new;
+ if (BLOCK_FUNCTION(new) && SYMBOL_BLOCK_VALUE(BLOCK_FUNCTION(new)) == b)
+ SYMBOL_BLOCK_VALUE(BLOCK_FUNCTION(new)) = new;
for (i = 0; i < BLOCKVECTOR_NBLOCKS(bv); i++)
if (BLOCKVECTOR_BLOCK(bv,i) == b)
BLOCKVECTOR_BLOCK(bv,i) = new;
else if (BLOCK_SUPERBLOCK(BLOCKVECTOR_BLOCK(bv,i)) == b)
BLOCK_SUPERBLOCK(BLOCKVECTOR_BLOCK(bv,i)) = new;
- free(b);
return new;
}
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;
-
- 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(2*sizeof(struct field));
- f = &(TYPE_FIELD(type,TYPE_NFIELDS(type)++));
- bzero(f, sizeof(struct field));
- if (name)
- f->name = name;
- return f;
-}
-
-/* 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);
+ 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;
}
-
-
\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.
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, mipscoff_symfile_discard};
+ mipscoff_symfile_read};
_initialize_mipsread ()
{
add_symtab_fns (&ecoff_sym_fns);
- bzero (&global_psymbols, sizeof (global_psymbols));
- bzero (&static_psymbols, sizeof (static_psymbols));
-
/* Missing basic types */
builtin_type_string = make_type(TYPE_CODE_PASCAL_ARRAY,
1, 0, "string");
0, "fixed_decimal");
builtin_type_float_dec = make_type(TYPE_CODE_FLT, sizeof(double),
0, "floating_decimal");
-
- /* Templates types */
- builtin_type_ptr = lookup_pointer_type (builtin_type_void);
- 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);
}