/* Read a symbol table in ECOFF format (Third-Eye).
- Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994
+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995
Free Software Foundation, Inc.
Original version contributed by Alessandro Forin (af@cs.cmu.edu) at
CMU. Major work by Per Bothner, John Gilmore and Ian Lance Taylor
#ifndef ECOFF_REG_TO_REGNUM
#define ECOFF_REG_TO_REGNUM(num) (num)
#endif
-
-/* 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 mdebugread this structure contains the index of the FDR that this
- psymtab represents and a pointer to the BFD that the psymtab was
- created from. */
-
-#define PST_PRIVATE(p) ((struct symloc *)(p)->read_symtab_private)
-#define FDR_IDX(p) (PST_PRIVATE(p)->fdr_idx)
-#define CUR_BFD(p) (PST_PRIVATE(p)->cur_bfd)
-#define DEBUG_SWAP(p) (PST_PRIVATE(p)->debug_swap)
-#define DEBUG_INFO(p) (PST_PRIVATE(p)->debug_info)
-#define PENDING_LIST(p) (PST_PRIVATE(p)->pending_list)
+\f
+/* We put a pointer to this structure in the read_symtab_private field
+ of the psymtab. */
struct symloc
{
+ /* Index of the FDR that this psymtab represents. */
int fdr_idx;
+ /* The BFD that the psymtab was created from. */
bfd *cur_bfd;
const struct ecoff_debug_swap *debug_swap;
struct ecoff_debug_info *debug_info;
struct mdebug_pending **pending_list;
- EXTR *extern_tab; /* Pointer to external symbols for this file. */
- int extern_count; /* Size of extern_tab. */
+ /* Pointer to external symbols for this file. */
+ EXTR *extern_tab;
+ /* Size of extern_tab. */
+ int extern_count;
enum language pst_language;
};
+#define PST_PRIVATE(p) ((struct symloc *)(p)->read_symtab_private)
+#define FDR_IDX(p) (PST_PRIVATE(p)->fdr_idx)
+#define CUR_BFD(p) (PST_PRIVATE(p)->cur_bfd)
+#define DEBUG_SWAP(p) (PST_PRIVATE(p)->debug_swap)
+#define DEBUG_INFO(p) (PST_PRIVATE(p)->debug_info)
+#define PENDING_LIST(p) (PST_PRIVATE(p)->pending_list)
+\f
/* Things we import explicitly from other modules */
extern int info_verbose;
be using our own types thoughout this file, instead of sometimes using
builtin_type_*. */
-static struct type *mdebug_type_complex;
-static struct type *mdebug_type_double_complex;
static struct type *mdebug_type_fixed_dec;
static struct type *mdebug_type_float_dec;
static struct type *mdebug_type_string;
+/* Types for symbols from files compiled without debugging info. */
+
+static struct type *nodebug_func_symbol_type;
+static struct type *nodebug_var_symbol_type;
+
+/* Nonzero if we have seen ecoff debugging info for a file. */
+
+static int found_ecoff_debugging_info;
+
/* Forward declarations */
static int
switch (sh->sc)
{
case scText:
- /* The value of a stEnd symbol is the displacement from the
- corresponding start symbol value, do not relocate it. */
- if (sh->st != stEnd)
+ /* Do not relocate relative values.
+ The value of a stEnd symbol is the displacement from the
+ corresponding start symbol value.
+ The value of a stBlock symbol is the displacement from the
+ procedure address. */
+ if (sh->st != stEnd && sh->st != stBlock)
sh->value += ANOFFSET (section_offsets, SECT_OFF_TEXT);
break;
case scData:
class = LOC_STATIC;
b = top_stack->cur_block;
s = new_symbol (name);
- if (sh->sc == scCommon)
+ if (sh->sc == scCommon || sh->sc == scSCommon)
{
/* It is a FORTRAN common block. At least for SGI Fortran the
address is not in the symbol; we need to fix it later in
SYMBOL_CLASS (s) = class;
add_symbol (s, b);
- /* Type could be missing in a number of cases */
- if (sh->sc == scUndefined || sh->sc == scNil)
- SYMBOL_TYPE (s) = builtin_type_int; /* undefined? */
+ /* Type could be missing if file is compiled without debugging info. */
+ if (sh->sc == scUndefined || sh->sc == scNil || sh->index == indexNil)
+ SYMBOL_TYPE (s) = nodebug_var_symbol_type;
else
SYMBOL_TYPE (s) = parse_type (cur_fd, ax, sh->index, 0, bigend, name);
/* Value of a data symbol is its memory address */
case stParam: /* arg to procedure, goes into current block */
max_gdbinfo++;
+ found_ecoff_debugging_info = 1;
top_stack->numargs++;
/* Special GNU C++ name. */
SYMBOL_VALUE (s) = svalue;
SYMBOL_TYPE (s) = parse_type (cur_fd, ax, sh->index, 0, bigend, name);
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, goes into current 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. */
- memcpy (lookup_function_type (t), SYMBOL_TYPE (s), 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);
goto structured_common;
case stBlock: /* Either a lexical block, or some type */
- if (sh->sc != scInfo && sh->sc != scCommon)
+ if (sh->sc != scInfo && sh->sc != scCommon && sh->sc != scSCommon)
goto case_stBlock_code; /* Lexical block */
type_code = TYPE_CODE_UNDEF; /* We have a type. */
unknown-type blocks of info about structured data. `type_code'
has been set to the proper TYPE_CODE, if we know it. */
structured_common:
+ found_ecoff_debugging_info = 1;
push_parse_stack ();
top_stack->blocktype = stBlock;
}
case_stBlock_code:
+ found_ecoff_debugging_info = 1;
/* beginnning of (code) block. Value of symbol
is the displacement from procedure start */
push_parse_stack ();
break;
case stEnd: /* end (of anything) */
- if (sh->sc == scInfo || sh->sc == scCommon)
+ if (sh->sc == scInfo || sh->sc == scCommon || sh->sc == scSCommon)
{
/* Finished with type */
top_stack->cur_type = 0;
struct blockvector *bv = BLOCKVECTOR (top_stack->cur_st);
struct mips_extra_func_info *e;
struct block *b;
+ struct type *ftype = top_stack->cur_type;
int i;
BLOCK_END (top_stack->cur_block) += sh->value; /* size */
e = ((struct mips_extra_func_info *)
obstack_alloc (¤t_objfile->symbol_obstack,
sizeof (struct mips_extra_func_info)));
+ memset ((PTR) e, 0, sizeof (struct mips_extra_func_info));
SYMBOL_VALUE (s) = (long) e;
e->numargs = top_stack->numargs;
+ e->pdr.framereg = -1;
add_symbol (s, top_stack->cur_block);
/* Reallocate symbols, saving memory */
BLOCK_END (b_bad) = BLOCK_END (b);
}
}
+
+ if (TYPE_NFIELDS (ftype) <= 0)
+ {
+ /* No parameter type information is recorded with the function's
+ type. Set that from the type of the parameter symbols. */
+ int nparams = top_stack->numargs;
+ int iparams;
+ struct symbol *sym;
+
+ if (nparams > 0)
+ {
+ TYPE_NFIELDS (ftype) = nparams;
+ TYPE_FIELDS (ftype) = (struct field *)
+ TYPE_ALLOC (ftype, nparams * sizeof (struct field));
+
+ for (i = iparams = 0; iparams < nparams; i++)
+ {
+ sym = BLOCK_SYM (b, i);
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym);
+ iparams++;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
}
else if (sh->sc == scText && top_stack->blocktype == stBlock)
{
break;
case stTypedef: /* type definition */
+ found_ecoff_debugging_info = 1;
+
/* Typedefs for forward declarations and opaque structs from alpha cc
are handled by cross_ref, skip them. */
if (sh->iss == 0)
0, /* btTypedef */
0, /* btRange */
0, /* btSet */
- &mdebug_type_complex, /* btComplex */
- &mdebug_type_double_complex, /* btDComplex */
+ &builtin_type_complex, /* btComplex */
+ &builtin_type_double_complex,/* btDComplex */
0, /* btIndirect */
&mdebug_type_fixed_dec, /* btFixedDec */
&mdebug_type_float_dec, /* btFloatDec */
e->pdr.regoffset = -4;
}
}
+
+ /* It would be reasonable that functions that have been compiled
+ without debugging info have a btNil type for their return value,
+ and functions that are void and are compiled with debugging info
+ have btVoid.
+ gcc and DEC f77 put out btNil types for both cases, so btNil is mapped
+ to TYPE_CODE_VOID in parse_type to get the `compiled with debugging info'
+ case right.
+ The glevel field in cur_fdr could be used to determine the presence
+ of debugging info, but GCC doesn't always pass the -g switch settings
+ to the assembler and GAS doesn't set the glevel field from the -g switch
+ settings.
+ To work around these problems, the return value type of a TYPE_CODE_VOID
+ function is adjusted accordingly if no debugging info was found in the
+ compilation unit. */
+
+ if (processing_gcc_compilation == 0
+ && found_ecoff_debugging_info == 0
+ && TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (s))) == TYPE_CODE_VOID)
+ SYMBOL_TYPE (s) = nodebug_func_symbol_type;
}
/* Relocate the extra function info pointed to by the symbol table. */
break;
case stGlobal:
case stLabel:
+ /* Global common symbols are resolved by the runtime loader,
+ ignore them. */
+ if (es->asym.sc == scCommon || es->asym.sc == scSCommon)
+ break;
+
/* Note that the case of a symbol with indexNil must be handled
anyways by parse_symbol(). */
parse_symbol (&es->asym, ax, (char *) NULL, bigend, section_offsets);
svalue += ANOFFSET (section_offsets, SECT_OFF_TEXT);
break;
case stGlobal:
- if (ext_in->asym.sc == scCommon)
+ if (ext_in->asym.sc == scCommon || ext_in->asym.sc == scSCommon)
{
/* The value of a common symbol is its size, not its address.
Ignore it. */
case stBlock: /* { }, str, un, enum*/
/* Do not create a partial symbol for cc unnamed aggregates
and gcc empty aggregates. */
- if ((sh.sc == scInfo || sh.sc == scCommon)
+ if ((sh.sc == scInfo
+ || sh.sc == scCommon || sh.sc == scSCommon)
&& sh.iss != 0
&& sh.index != cur_sdx + 2)
{
debug_info->ssext + psh->iss);
/* Fall through, pretend it's global. */
case stGlobal:
+ /* Global common symbols are resolved by the runtime loader,
+ ignore them. */
+ if (psh->sc == scCommon || psh->sc == scSCommon)
+ continue;
+
class = LOC_STATIC;
break;
}
objfile->ei.entry_file_lowpc = save_pst->textlow;
objfile->ei.entry_file_highpc = save_pst->texthigh;
}
+
+ /* The objfile has its functions reordered if this partial symbol
+ table overlaps any other partial symbol table.
+ We cannot assume a reordered objfile if a partial symbol table
+ is contained within another partial symbol table, as partial symbol
+ tables for include files with executable code are contained
+ within the partial symbol table for the including source file,
+ and we do not want to flag the objfile reordered for these cases.
+
+ This strategy works well for Irix-5.2 shared libraries, but we
+ might have to use a more elaborate (and slower) algorithm for
+ other cases. */
+ save_pst = fdr_to_pst[f_idx].pst;
+ if (save_pst != NULL
+ && save_pst->textlow != 0
+ && !(objfile->flags & OBJF_REORDERED))
+ {
+ ALL_OBJFILE_PSYMTABS (objfile, pst)
+ {
+ if (save_pst != pst
+ && save_pst->textlow >= pst->textlow
+ && save_pst->textlow < pst->texthigh
+ && save_pst->texthigh > pst->texthigh)
+ {
+ objfile->flags |= OBJF_REORDERED;
+ break;
+ }
+ }
+ }
}
/* Now scan the FDRs for dependencies */
obstack_alloc (¤t_objfile->symbol_obstack,
sizeof (struct mips_extra_func_info)));
struct symbol *s = new_symbol (MIPS_EFI_SYMBOL_NAME);
+
+ memset ((PTR) e, 0, sizeof (struct mips_extra_func_info));
SYMBOL_NAMESPACE (s) = LABEL_NAMESPACE;
SYMBOL_CLASS (s) = LOC_CONST;
SYMBOL_TYPE (s) = builtin_type_void;
SYMBOL_VALUE (s) = (long) e;
+ e->pdr.framereg = -1;
add_symbol_to_list (s, &local_symbols);
}
}
{
/* This symbol table contains ordinary ecoff entries. */
- /* FIXME: doesn't use pst->section_offsets. */
-
int f_max;
int maxlines;
EXTR *ext_ptr;
top_stack->cur_type = 0;
top_stack->procadr = 0;
top_stack->numargs = 0;
+ found_ecoff_debugging_info = 0;
if (fh)
{
|| (sh.st != stBlock && sh.st != stTypedef && sh.st != stIndirect
&& sh.st != stStruct && sh.st != stUnion
&& sh.st != stEnum))
- && (sh.sc != scCommon || sh.st != stBlock))
+ && (sh.st != stBlock || (sh.sc != scCommon && sh.sc != scSCommon)))
{
/* File indirect entry is corrupt. */
*pname = "<illegal>";
0, "string",
(struct objfile *) NULL);
- mdebug_type_complex =
- init_type (TYPE_CODE_ERROR,
- TARGET_COMPLEX_BIT / TARGET_CHAR_BIT,
- 0, "complex",
- (struct objfile *) NULL);
- mdebug_type_double_complex =
- init_type (TYPE_CODE_ERROR,
- TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT,
- 0, "double complex",
- (struct objfile *) NULL);
-
/* We use TYPE_CODE_INT to print these as integers. Does this do any
good? Would we be better off with TYPE_CODE_ERROR? Should
TYPE_CODE_ERROR print things in hex if it knows the size? */
TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
0, "floating decimal",
(struct objfile *) NULL);
+
+ nodebug_func_symbol_type = init_type (TYPE_CODE_FUNC, 1, 0,
+ "<function, no debug info>", NULL);
+ TYPE_TARGET_TYPE (nodebug_func_symbol_type) = builtin_type_int;
+ nodebug_var_symbol_type =
+ init_type (TYPE_CODE_INT, TARGET_INT_BIT / HOST_CHAR_BIT, 0,
+ "<variable, no debug info>", NULL);
}