/* Read coff symbol tables and convert to internal format, for GDB.
Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
#include "coff/internal.h" /* Internal format of COFF symbols in BFD */
#include "libcoff.h" /* FIXME secret internal data from BFD */
-
-#include "symfile.h"
#include "objfiles.h"
#include "buildsym.h"
#include "gdb-stabs.h"
#include "target.h"
#include "gdb_assert.h"
#include "block.h"
+#include "dictionary.h"
+
+#include "coff-pe-read.h"
extern void _initialize_coffread (void);
static void
coff_locate_sections (bfd *abfd, asection *sectp, void *csip)
{
- register struct coff_symfile_info *csi;
+ struct coff_symfile_info *csi;
const char *name;
csi = (struct coff_symfile_info *) csip;
name = bfd_get_section_name (abfd, sectp);
- if (STREQ (name, ".text"))
+ if (DEPRECATED_STREQ (name, ".text"))
{
csi->textaddr = bfd_section_vma (abfd, sectp);
csi->textsize += bfd_section_size (abfd, sectp);
{
csi->textsize += bfd_section_size (abfd, sectp);
}
- else if (STREQ (name, ".stabstr"))
+ else if (DEPRECATED_STREQ (name, ".stabstr"))
{
csi->stabstrsect = sectp;
}
or for associating a new type with the index. */
static struct type **
-coff_lookup_type (register int index)
+coff_lookup_type (int index)
{
if (index >= type_vector_length)
{
static struct type *
coff_alloc_type (int index)
{
- register struct type **type_addr = coff_lookup_type (index);
- register struct type *type = *type_addr;
+ struct type **type_addr = coff_lookup_type (index);
+ struct type *type = *type_addr;
/* If we are referring to a type not known at all yet,
allocate an empty type for it.
last_source_file = savestring (name, strlen (name));
current_source_start_addr = start_addr;
current_source_end_addr = start_addr + size;
-
- if (current_objfile->ei.entry_point >= current_source_start_addr &&
- current_objfile->ei.entry_point < current_source_end_addr)
- {
- current_objfile->ei.entry_file_lowpc = current_source_start_addr;
- current_objfile->ei.entry_file_highpc = current_source_end_addr;
- }
}
/* Finish the symbol definitions for one main source file,
of the line table (minimum and maximum file offset) so that the
mainline code can read the whole thing for efficiency. */
-/* ARGSUSED */
static void
-find_linenos (bfd *abfd, sec_ptr asect, void *vpinfo)
+find_linenos (bfd *abfd, struct bfd_section *asect, void *vpinfo)
{
struct coff_symfile_info *info;
int size, count;
/* Read a symbol file, after initialization by coff_symfile_init. */
-/* ARGSUSED */
static void
coff_symfile_read (struct objfile *objfile, int mainline)
{
bfd *abfd = objfile->obfd;
coff_data_type *cdata = coff_data (abfd);
char *name = bfd_get_filename (abfd);
- register int val;
+ int val;
unsigned int num_symbols;
int symtab_offset;
int stringtab_offset;
- struct cleanup *back_to;
+ struct cleanup *back_to, *cleanup_minimal_symbols;
int stabstrsize;
int len;
char * target;
error ("\"%s\": can't get string table", name);
init_minimal_symbol_collection ();
- make_cleanup_discard_minimal_symbols ();
+ cleanup_minimal_symbols = make_cleanup_discard_minimal_symbols ();
/* Now that the executable file is positioned at symbol table,
process it and define symbols accordingly. */
coff_symtab_read ((long) symtab_offset, num_symbols, objfile);
- /* Sort symbols alphabetically within each block. */
-
- {
- struct symtab *s;
-
- for (s = objfile->symtabs; s != NULL; s = s->next)
- sort_symtab_syms (s);
- }
-
/* Install any minimal symbols that have been collected as the current
minimal symbols for this objfile. */
install_minimal_symbols (objfile);
+ /* Free the installed minimal symbol data. */
+ do_cleanups (cleanup_minimal_symbols);
+
bfd_map_over_sections (abfd, coff_locate_sections, (void *) info);
if (info->stabsects)
info->stabsects,
info->stabstrsect->filepos, stabstrsize);
}
- if (dwarf2_has_info (abfd))
+ if (dwarf2_has_info (objfile))
{
/* DWARF2 sections. */
dwarf2_build_psymtabs (objfile, mainline);
coff_symtab_read (long symtab_offset, unsigned int nsyms,
struct objfile *objfile)
{
- register struct context_stack *new;
+ struct context_stack *new;
struct coff_symbol coff_symbol;
- register struct coff_symbol *cs = &coff_symbol;
+ struct coff_symbol *cs = &coff_symbol;
static struct internal_syment main_sym;
static union internal_auxent main_aux;
struct coff_symbol fcn_cs_saved;
case C_THUMBSTATFUNC:
if (cs->c_name[0] == '.')
{
- if (STREQ (cs->c_name, ".text"))
+ if (DEPRECATED_STREQ (cs->c_name, ".text"))
{
/* FIXME: don't wire in ".text" as section name
or symbol name! */
print_address_symbolic work right without the (now
gone) "set fast-symbolic-addr off" kludge. */
- /* FIXME: should use mst_abs, and not relocate, if absolute. */
enum minimal_symbol_type ms_type;
int sec;
|| cs->c_sclass == C_THUMBEXT ?
mst_bss : mst_file_bss;
}
+ else if (cs->c_secnum == N_ABS)
+ {
+ /* Use the correct minimal symbol type (and don't
+ relocate) for absolute values. */
+ ms_type = mst_abs;
+ sec = cs_to_section (cs, objfile);
+ tmpaddr = cs->c_value;
+ }
else
{
sec = cs_to_section (cs, objfile);
tmpaddr = cs->c_value;
- if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
- || cs->c_sclass == C_THUMBEXT)
+ /* Statics in a PE file also get relocated */
+ if (cs->c_sclass == C_EXT
+ || cs->c_sclass == C_THUMBEXTFUNC
+ || cs->c_sclass == C_THUMBEXT
+ || (pe_file && (cs->c_sclass == C_STAT)))
tmpaddr += ANOFFSET (objfile->section_offsets, sec);
if (sec == SECT_OFF_TEXT (objfile))
if (cs->c_name[0] != '@' /* Skip tdesc symbols */ )
{
struct minimal_symbol *msym;
-
- /* FIXME: cagney/2001-02-01: The nasty (int) -> (long)
- -> (void*) cast is to ensure that that the value of
- cs->c_sclass can be correctly stored in a void
- pointer in MSYMBOL_INFO. Better solutions
- welcome. */
- gdb_assert (sizeof (void *) >= sizeof (cs->c_sclass));
msym = prim_record_minimal_symbol_and_info
- (cs->c_name, tmpaddr, ms_type, (void *) (long) cs->c_sclass,
+ (cs->c_name, tmpaddr, ms_type, NULL,
sec, NULL, objfile);
if (msym)
COFF_MAKE_MSYMBOL_SPECIAL (cs->c_sclass, msym);
break;
case C_FCN:
- if (STREQ (cs->c_name, ".bf"))
+ if (DEPRECATED_STREQ (cs->c_name, ".bf"))
{
within_function = 1;
new->name =
process_coff_symbol (&fcn_cs_saved, &fcn_aux_saved, objfile);
}
- else if (STREQ (cs->c_name, ".ef"))
+ else if (DEPRECATED_STREQ (cs->c_name, ".ef"))
{
if (!within_function)
error ("Bad coff function information\n");
break;
case C_BLOCK:
- if (STREQ (cs->c_name, ".bb"))
+ if (DEPRECATED_STREQ (cs->c_name, ".bb"))
{
tmpaddr = cs->c_value;
tmpaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
push_context (++depth, tmpaddr);
}
- else if (STREQ (cs->c_name, ".eb"))
+ else if (DEPRECATED_STREQ (cs->c_name, ".eb"))
{
if (context_stack_depth <= 0)
{ /* We attempted to pop an empty context stack */
}
}
+ if ((nsyms == 0) && (pe_file))
+ {
+ /* We've got no debugging symbols, but it's is a portable
+ executable, so try to read the export table */
+ read_pe_exported_syms (objfile);
+ }
+
if (last_source_file)
coff_end_symtab (objfile);
in internal_auxent form, and skip any other auxents. */
static void
-read_one_sym (register struct coff_symbol *cs,
- register struct internal_syment *sym,
- register union internal_auxent *aux)
+read_one_sym (struct coff_symbol *cs,
+ struct internal_syment *sym,
+ union internal_auxent *aux)
{
int i;
coff_getfilename (union internal_auxent *aux_entry)
{
static char buffer[BUFSIZ];
- register char *temp;
+ char *temp;
char *result;
if (aux_entry->x_file.x_n.x_zeroes == 0)
#endif
static void
-enter_linenos (long file_offset, register int first_line,
- register int last_line, struct objfile *objfile)
+enter_linenos (long file_offset, int first_line,
+ int last_line, struct objfile *objfile)
{
- register char *rawptr;
+ char *rawptr;
struct internal_lineno lptr;
if (!linetab)
/* line numbers start at one for the first line of the function */
first_line--;
- for (;;)
+ /* If the line number table is full (e.g. 64K lines in COFF debug
+ info), the next function's L_LNNO32 might not be zero, so don't
+ overstep the table's end in any case. */
+ while (rawptr <= &linetab[0] + linetab_size)
{
bfd_coff_swap_lineno_in (symfile_bfd, rawptr, &lptr);
rawptr += local_linesz;
- /* The next function, or the sentinel, will have L_LNNO32 zero; we exit. */
+ /* The next function, or the sentinel, will have L_LNNO32 zero;
+ we exit. */
if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)
record_line (current_subfile, first_line + L_LNNO32 (&lptr),
lptr.l_addr.l_paddr
static void
patch_type (struct type *type, struct type *real_type)
{
- register struct type *target = TYPE_TARGET_TYPE (type);
- register struct type *real_target = TYPE_TARGET_TYPE (real_type);
+ struct type *target = TYPE_TARGET_TYPE (type);
+ struct type *real_target = TYPE_TARGET_TYPE (real_type);
int field_size = TYPE_NFIELDS (real_target) * sizeof (struct field);
TYPE_LENGTH (target) = TYPE_LENGTH (real_target);
static void
patch_opaque_types (struct symtab *s)
{
- register struct block *b;
- register int i;
- register struct symbol *real_sym;
+ struct block *b;
+ struct dict_iterator iter;
+ struct symbol *real_sym;
/* Go through the per-file symbols only */
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
- ALL_BLOCK_SYMBOLS (b, i, real_sym)
+ ALL_BLOCK_SYMBOLS (b, iter, real_sym)
{
/* Find completed typedefs to use to fix opaque ones.
Remove syms from the chain when their types are stored,
but search the whole chain, as there may be several syms
from different files with the same name. */
if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF &&
- SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE &&
+ SYMBOL_DOMAIN (real_sym) == VAR_DOMAIN &&
TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&
TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)
{
- register char *name = SYMBOL_NAME (real_sym);
- register int hash = hashname (name);
- register struct symbol *sym, *prev;
+ char *name = DEPRECATED_SYMBOL_NAME (real_sym);
+ int hash = hashname (name);
+ struct symbol *sym, *prev;
prev = 0;
for (sym = opaque_type_chain[hash]; sym;)
{
- if (name[0] == SYMBOL_NAME (sym)[0] &&
- STREQ (name + 1, SYMBOL_NAME (sym) + 1))
+ if (name[0] == DEPRECATED_SYMBOL_NAME (sym)[0] &&
+ strcmp (name + 1, DEPRECATED_SYMBOL_NAME (sym) + 1) == 0)
{
if (prev)
{
}
\f
static struct symbol *
-process_coff_symbol (register struct coff_symbol *cs,
- register union internal_auxent *aux,
+process_coff_symbol (struct coff_symbol *cs,
+ union internal_auxent *aux,
struct objfile *objfile)
{
- register struct symbol *sym
- = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ struct symbol *sym
+ = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
sizeof (struct symbol));
char *name;
/* default assumptions */
SYMBOL_VALUE (sym) = cs->c_value;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
SYMBOL_SECTION (sym) = cs_to_section (cs, objfile);
if (ISFCN (cs->c_type))
case C_TPDEF:
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
/* If type has no name, give it one */
if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
}
else
TYPE_NAME (SYMBOL_TYPE (sym)) =
- concat (SYMBOL_NAME (sym), NULL);
+ concat (DEPRECATED_SYMBOL_NAME (sym), NULL);
}
-#ifdef CXUX_TARGET
- /* Ignore vendor section for Harris CX/UX targets. */
- else if (cs->c_name[0] == '$')
- break;
-#endif /* CXUX_TARGET */
/* Keep track of any type which points to empty structured type,
so it can be filled from a definition from another file. A
TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) !=
TYPE_CODE_UNDEF)
{
- register int i = hashname (SYMBOL_NAME (sym));
+ int i = hashname (DEPRECATED_SYMBOL_NAME (sym));
SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i];
opaque_type_chain[i] = sym;
case C_UNTAG:
case C_ENTAG:
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
- SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+ SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
/* Some compilers try to be helpful by inventing "fake"
names for anonymous enums, structures, and unions, like
"~0fake" or ".0fake". Thanks, but no thanks... */
if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
- if (SYMBOL_NAME (sym) != NULL
- && *SYMBOL_NAME (sym) != '~'
- && *SYMBOL_NAME (sym) != '.')
+ if (DEPRECATED_SYMBOL_NAME (sym) != NULL
+ && *DEPRECATED_SYMBOL_NAME (sym) != '~'
+ && *DEPRECATED_SYMBOL_NAME (sym) != '.')
TYPE_TAG_NAME (SYMBOL_TYPE (sym)) =
- concat (SYMBOL_NAME (sym), NULL);
+ concat (DEPRECATED_SYMBOL_NAME (sym), NULL);
add_symbol_to_list (sym, &file_symbols);
break;
/* Decode a coff type specifier; return the type that is meant. */
static struct type *
-decode_type (register struct coff_symbol *cs, unsigned int c_type,
- register union internal_auxent *aux)
+decode_type (struct coff_symbol *cs, unsigned int c_type,
+ union internal_auxent *aux)
{
- register struct type *type = 0;
+ struct type *type = 0;
unsigned int new_c_type;
if (c_type & ~N_BTMASK)
else if (ISARY (c_type))
{
int i, n;
- register unsigned short *dim;
+ unsigned short *dim;
struct type *base_type, *index_type, *range_type;
/* Define an array type. */
return the type that the function returns. */
static struct type *
-decode_function_type (register struct coff_symbol *cs, unsigned int c_type,
- register union internal_auxent *aux)
+decode_function_type (struct coff_symbol *cs, unsigned int c_type,
+ union internal_auxent *aux)
{
if (aux->x_sym.x_tagndx.l == 0)
cs->c_naux = 0; /* auxent refers to function, not base type */
/* basic C types */
static struct type *
-decode_base_type (register struct coff_symbol *cs, unsigned int c_type,
- register union internal_auxent *aux)
+decode_base_type (struct coff_symbol *cs, unsigned int c_type,
+ union internal_auxent *aux)
{
struct type *type;
/* shows up with "void (*foo)();" structure members */
return lookup_fundamental_type (current_objfile, FT_VOID);
-#if 0
-/* DGUX actually defines both T_ARG and T_VOID to the same value. */
-#ifdef T_ARG
- case T_ARG:
- /* Shows up in DGUX, I think. Not sure where. */
- return lookup_fundamental_type (current_objfile, FT_VOID); /* shouldn't show up here */
-#endif
-#endif /* 0 */
-
#ifdef T_VOID
case T_VOID:
/* Intel 960 COFF has this symbol and meaning. */
struct field field;
};
- register struct type *type;
- register struct nextfield *list = 0;
+ struct type *type;
+ struct nextfield *list = 0;
struct nextfield *new;
int nfields = 0;
- register int n;
+ int n;
char *name;
struct coff_symbol member_sym;
- register struct coff_symbol *ms = &member_sym;
+ struct coff_symbol *ms = &member_sym;
struct internal_syment sub_sym;
union internal_auxent sub_aux;
int done = 0;
list->field.name =
obsavestring (name,
strlen (name),
- ¤t_objfile->symbol_obstack);
+ ¤t_objfile->objfile_obstack);
FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
FIELD_BITPOS (list->field) = 8 * ms->c_value;
FIELD_BITSIZE (list->field) = 0;
list->field.name =
obsavestring (name,
strlen (name),
- ¤t_objfile->symbol_obstack);
+ ¤t_objfile->objfile_obstack);
FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
FIELD_BITPOS (list->field) = ms->c_value;
FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size;
and create and return a suitable type object.
Also defines the symbols that represent the values of the type. */
-/* ARGSUSED */
static struct type *
coff_read_enum_type (int index, int length, int lastsym)
{
- register struct symbol *sym;
- register struct type *type;
+ struct symbol *sym;
+ struct type *type;
int nsyms = 0;
int done = 0;
struct pending **symlist;
struct coff_symbol member_sym;
- register struct coff_symbol *ms = &member_sym;
+ struct coff_symbol *ms = &member_sym;
struct internal_syment sub_sym;
union internal_auxent sub_aux;
struct pending *osyms, *syms;
int o_nsyms;
- register int n;
+ int n;
char *name;
int unsigned_enum = 1;
{
case C_MOE:
sym = (struct symbol *) obstack_alloc
- (¤t_objfile->symbol_obstack,
+ (¤t_objfile->objfile_obstack,
sizeof (struct symbol));
memset (sym, 0, sizeof (struct symbol));
- SYMBOL_NAME (sym) =
+ DEPRECATED_SYMBOL_NAME (sym) =
obsavestring (name, strlen (name),
- ¤t_objfile->symbol_obstack);
+ ¤t_objfile->objfile_obstack);
SYMBOL_CLASS (sym) = LOC_CONST;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
SYMBOL_VALUE (sym) = ms->c_value;
add_symbol_to_list (sym, symlist);
nsyms++;
{
struct symbol *xsym = syms->symbol[j];
SYMBOL_TYPE (xsym) = type;
- TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+ TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym);
TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
if (SYMBOL_VALUE (xsym) < 0)
unsigned_enum = 0;