/* Read coff symbol tables and convert to internal format, for GDB.
Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
- Free Software Foundation, Inc.
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009,
+ 2010, 2011 Free Software Foundation, Inc.
Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "symtab.h"
#include "coff-pe-read.h"
+#include "psymtab.h"
+
extern void _initialize_coffread (void);
+/* The objfile we are currently reading. */
+
+static struct objfile *coffread_objfile;
+
struct coff_symfile_info
{
- file_ptr min_lineno_offset; /* Where in file lowest line#s are */
- file_ptr max_lineno_offset; /* 1+last byte of line#s in file */
+ file_ptr min_lineno_offset; /* Where in file lowest line#s are. */
+ file_ptr max_lineno_offset; /* 1+last byte of line#s in file. */
- CORE_ADDR textaddr; /* Addr of .text section. */
- unsigned int textsize; /* Size of .text section. */
+ CORE_ADDR textaddr; /* Addr of .text section. */
+ unsigned int textsize; /* Size of .text section. */
struct stab_section_list *stabsects; /* .stab sections. */
- asection *stabstrsect; /* Section pointer for .stab section */
+ asection *stabstrsect; /* Section pointer for .stab section. */
char *stabstrdata;
};
/* Translate an external name string into a user-visible name. */
#define EXTERNAL_NAME(string, abfd) \
- (string[0] == bfd_get_symbol_leading_char(abfd)? string+1: string)
+ (string[0] == bfd_get_symbol_leading_char (abfd) \
+ ? string + 1 : string)
/* To be an sdb debug type, type must have at least a basic or primary
derived type. Using this rather than checking against T_NULL is
static int nlist_nsyms_global;
-/* Pointers to scratch storage, used for reading raw symbols and auxents. */
+/* Pointers to scratch storage, used for reading raw symbols and
+ auxents. */
static char *temp_sym;
static char *temp_aux;
#define N_TMASK local_n_tmask
#define N_TSHIFT local_n_tshift
-/* Local variables that hold the sizes in the file of various COFF structures.
- (We only need to know this to read them from the file -- BFD will then
- translate the data in them, into `internal_xxx' structs in the right
- byte order, alignment, etc.) */
+/* Local variables that hold the sizes in the file of various COFF
+ structures. (We only need to know this to read them from the file
+ -- BFD will then translate the data in them, into `internal_xxx'
+ structs in the right byte order, alignment, etc.) */
static unsigned local_linesz;
static unsigned local_symesz;
static struct symbol *opaque_type_chain[HASHSIZE];
-/* Simplified internal version of coff symbol table information */
+/* Simplified internal version of coff symbol table information. */
struct coff_symbol
{
char *c_name;
- int c_symnum; /* symbol number of this entry */
- int c_naux; /* 0 if syment only, 1 if syment + auxent, etc */
- long c_value;
+ int c_symnum; /* Symbol number of this entry. */
+ int c_naux; /* 0 if syment only, 1 if syment +
+ auxent, etc. */
+ CORE_ADDR c_value;
int c_sclass;
int c_secnum;
unsigned int c_type;
extern void stabsread_clear_cache (void);
-static struct type *coff_read_struct_type (int, int, int);
+static struct type *coff_read_struct_type (int, int, int,
+ struct objfile *);
static struct type *decode_base_type (struct coff_symbol *,
- unsigned int, union internal_auxent *);
+ unsigned int,
+ union internal_auxent *,
+ struct objfile *);
static struct type *decode_type (struct coff_symbol *, unsigned int,
- union internal_auxent *);
+ union internal_auxent *,
+ struct objfile *);
static struct type *decode_function_type (struct coff_symbol *,
unsigned int,
- union internal_auxent *);
+ union internal_auxent *,
+ struct objfile *);
-static struct type *coff_read_enum_type (int, int, int);
+static struct type *coff_read_enum_type (int, int, int,
+ struct objfile *);
static struct symbol *process_coff_symbol (struct coff_symbol *,
union internal_auxent *,
static char *getsymname (struct internal_syment *);
-static char *coff_getfilename (union internal_auxent *);
+static const char *coff_getfilename (union internal_auxent *);
static void free_stringtab (void);
static int init_stringtab (bfd *, long);
static void read_one_sym (struct coff_symbol *,
- struct internal_syment *, union internal_auxent *);
+ struct internal_syment *,
+ union internal_auxent *);
static void coff_symtab_read (long, unsigned int, struct objfile *);
\f
csi = (struct coff_symfile_info *) csip;
name = bfd_get_section_name (abfd, sectp);
- if (DEPRECATED_STREQ (name, ".text"))
+ if (strcmp (name, ".text") == 0)
{
csi->textaddr = bfd_section_vma (abfd, sectp);
csi->textsize += bfd_section_size (abfd, sectp);
{
csi->textsize += bfd_section_size (abfd, sectp);
}
- else if (DEPRECATED_STREQ (name, ".stabstr"))
+ else if (strcmp (name, ".stabstr") == 0)
{
csi->stabstrsect = sectp;
}
find_targ_sec (bfd *abfd, asection *sect, void *obj)
{
struct find_targ_sec_arg *args = (struct find_targ_sec_arg *) obj;
+
if (sect->target_index == args->targ_index)
*args->resultp = sect;
}
cs_to_section (struct coff_symbol *cs, struct objfile *objfile)
{
asection *sect = cs_to_bfd_section (cs, objfile);
+
if (sect == NULL)
return SECT_OFF_TEXT (objfile);
return sect->index;
We will fill it in later if we find out how. */
if (type == NULL)
{
- type = alloc_type (current_objfile);
+ type = alloc_type (coffread_objfile);
*type_addr = type;
}
return type;
it indicates the start of data for one original source file. */
static void
-coff_start_symtab (char *name)
+coff_start_symtab (const char *name)
{
start_symtab (
- /* We fill in the filename later. start_symtab puts
- this pointer into last_source_file and we put it in
- subfiles->name, which end_symtab frees; that's why
- it must be malloc'd. */
- savestring (name, strlen (name)),
+ /* We fill in the filename later. start_symtab puts this pointer
+ into last_source_file and we put it in subfiles->name, which
+ end_symtab frees; that's why it must be malloc'd. */
+ xstrdup (name),
/* We never know the directory name for COFF. */
NULL,
/* The start address is irrelevant, since we set
/* Save the vital information from when starting to read a file,
for use when closing off the current file.
- NAME is the file name the symbols came from, START_ADDR is the first
- text address for the file, and SIZE is the number of bytes of text. */
+ NAME is the file name the symbols came from, START_ADDR is the
+ first text address for the file, and SIZE is the number of bytes of
+ text. */
static void
-complete_symtab (char *name, CORE_ADDR start_addr, unsigned int size)
+complete_symtab (const char *name, CORE_ADDR start_addr, unsigned int size)
{
if (last_source_file != NULL)
xfree (last_source_file);
- last_source_file = savestring (name, strlen (name));
+ last_source_file = xstrdup (name);
current_source_start_addr = start_addr;
current_source_end_addr = start_addr + size;
}
-/* Finish the symbol definitions for one main source file,
- close off all the lexical contexts for that file
- (creating struct block's for them), then make the
- struct symtab for that file and put it in the list of all such. */
+/* Finish the symbol definitions for one main source file, close off
+ all the lexical contexts for that file (creating struct block's for
+ them), then make the struct symtab for that file and put it in the
+ list of all such. */
static void
coff_end_symtab (struct objfile *objfile)
{
- struct symtab *symtab;
-
last_source_start_addr = current_source_start_addr;
- symtab = end_symtab (current_source_end_addr, objfile, SECT_OFF_TEXT (objfile));
-
- if (symtab != NULL)
- free_named_symtabs (symtab->filename);
+ end_symtab (current_source_end_addr, objfile,
+ SECT_OFF_TEXT (objfile));
- /* Reinitialize for beginning of new file. */
+ /* Reinitialize for beginning of new file. */
last_source_file = NULL;
}
\f
struct objfile *objfile)
{
struct bfd_section *bfd_section;
- /* We don't want TDESC entry points in the minimal symbol table */
+
+ /* We don't want TDESC entry points in the minimal symbol table. */
if (cs->c_name[0] == '@')
return NULL;
bfd_section = cs_to_bfd_section (cs, objfile);
- return prim_record_minimal_symbol_and_info (cs->c_name, address, type,
- NULL, section, bfd_section, objfile);
+ return prim_record_minimal_symbol_and_info (cs->c_name, address,
+ type, section,
+ bfd_section, objfile);
}
\f
/* coff_symfile_init ()
a pointer to "private data" which we fill with cookies and other
treats for coff_symfile_read ().
- We will only be called if this is a COFF or COFF-like file.
- BFD handles figuring out the format of the file, and code in symtab.c
+ We will only be called if this is a COFF or COFF-like file. BFD
+ handles figuring out the format of the file, and code in symtab.c
uses BFD's determination to vector to us.
- The ultimate result is a new symtab (or, FIXME, eventually a psymtab). */
+ The ultimate result is a new symtab (or, FIXME, eventually a
+ psymtab). */
static void
coff_symfile_init (struct objfile *objfile)
{
- /* Allocate struct to keep track of stab reading. */
+ /* Allocate struct to keep track of stab reading. */
objfile->deprecated_sym_stab_info = (struct dbx_symfile_info *)
xmalloc (sizeof (struct dbx_symfile_info));
memset (objfile->deprecated_sym_stab_info, 0,
sizeof (struct dbx_symfile_info));
- /* Allocate struct to keep track of the symfile */
- objfile->deprecated_sym_private = xmalloc (sizeof (struct coff_symfile_info));
+ /* Allocate struct to keep track of the symfile. */
+ objfile->deprecated_sym_private
+ = xmalloc (sizeof (struct coff_symfile_info));
- memset (objfile->deprecated_sym_private, 0, sizeof (struct coff_symfile_info));
+ memset (objfile->deprecated_sym_private, 0,
+ sizeof (struct coff_symfile_info));
/* COFF objects may be reordered, so set OBJF_REORDERED. If we
find this causes a significant slowdown in gdb then we could
init_entry_point_info (objfile);
}
-/* This function is called for every section; it finds the outer limits
- of the line table (minimum and maximum file offset) so that the
- mainline code can read the whole thing for efficiency. */
+/* This function is called for every section; it finds the outer
+ limits of the line table (minimum and maximum file offset) so that
+ the mainline code can read the whole thing for efficiency. */
static void
find_linenos (bfd *abfd, struct bfd_section *asect, void *vpinfo)
int size, count;
file_ptr offset, maxoff;
-/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
+ /* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
count = asect->lineno_count;
-/* End of warning */
+ /* End of warning. */
if (count == 0)
return;
size = count * local_linesz;
info = (struct coff_symfile_info *) vpinfo;
-/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
+ /* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
offset = asect->line_filepos;
-/* End of warning */
+ /* End of warning. */
if (offset < info->min_lineno_offset || info->min_lineno_offset == 0)
info->min_lineno_offset = offset;
/* Read a symbol file, after initialization by coff_symfile_init. */
static void
-coff_symfile_read (struct objfile *objfile, int mainline)
+coff_symfile_read (struct objfile *objfile, int symfile_flags)
{
struct coff_symfile_info *info;
struct dbx_symfile_info *dbxinfo;
int stringtab_offset;
struct cleanup *back_to, *cleanup_minimal_symbols;
int stabstrsize;
- int len;
- char * target;
info = (struct coff_symfile_info *) objfile->deprecated_sym_private;
dbxinfo = objfile->deprecated_sym_stab_info;
- symfile_bfd = abfd; /* Kludge for swap routines */
+ symfile_bfd = abfd; /* Kludge for swap routines. */
/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
num_symbols = bfd_get_symcount (abfd); /* How many syms */
strncmp (bfd_get_target (objfile->obfd), "pe", 2) == 0
|| strncmp (bfd_get_target (objfile->obfd), "epoc-pe", 7) == 0;
-/* End of warning */
+ /* End of warning. */
info->min_lineno_offset = 0;
info->max_lineno_offset = 0;
coff_symtab_read ((long) symtab_offset, num_symbols, objfile);
- /* Install any minimal symbols that have been collected as the current
- minimal symbols for this objfile. */
+ /* 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);
- /* If we are reinitializing, or if we have not loaded syms yet,
- empty the psymtab. "mainline" is cleared so the *_read_psymtab
- functions do not all re-initialize it. */
- if (mainline)
- {
- init_psymbol_list (objfile, 0);
- mainline = 0;
- }
-
bfd_map_over_sections (abfd, coff_locate_sections, (void *) info);
if (info->stabsects)
{
if (!info->stabstrsect)
{
- error (_("The debugging information in `%s' is corrupted.\n"
- "The file has a `.stabs' section, but no `.stabstr' section."),
+ error (_("The debugging information in `%s' is corrupted.\nThe "
+ "file has a `.stabs' section, but no `.stabstr' section."),
name);
}
stabstrsize = bfd_section_size (abfd, info->stabstrsect);
coffstab_build_psymtabs (objfile,
- mainline,
info->textaddr, info->textsize,
info->stabsects,
info->stabstrsect->filepos, stabstrsize);
}
- if (dwarf2_has_info (objfile))
+ if (dwarf2_has_info (objfile, NULL))
{
/* DWARF2 sections. */
- dwarf2_build_psymtabs (objfile, mainline);
+ dwarf2_build_psymtabs (objfile);
}
dwarf2_build_frame_info (objfile);
+ /* Try to add separate debug file if no symbols table found. */
+ if (!objfile_has_partial_symbols (objfile))
+ {
+ char *debugfile;
+
+ debugfile = find_separate_debug_file_by_debuglink (objfile);
+
+ if (debugfile)
+ {
+ bfd *abfd = symfile_bfd_open (debugfile);
+
+ symbol_file_add_separate (abfd, symfile_flags, objfile);
+ xfree (debugfile);
+ }
+ }
+
do_cleanups (back_to);
}
{
}
-/* Perform any local cleanups required when we are done with a particular
- objfile. I.E, we are in the process of discarding all symbol information
- for an objfile, freeing up all memory held for it, and unlinking the
- objfile struct from the global list of known objfiles. */
+/* Perform any local cleanups required when we are done with a
+ particular objfile. I.E, we are in the process of discarding all
+ symbol information for an objfile, freeing up all memory held for
+ it, and unlinking the objfile struct from the global list of known
+ objfiles. */
static void
coff_symfile_finish (struct objfile *objfile)
xfree (objfile->deprecated_sym_private);
}
- /* Let stabs reader clean up */
+ /* Let stabs reader clean up. */
stabsread_clear_cache ();
+
+ dwarf2_free_objfile (objfile);
}
\f
coff_symtab_read (long symtab_offset, unsigned int nsyms,
struct objfile *objfile)
{
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct context_stack *new;
struct coff_symbol coff_symbol;
struct coff_symbol *cs = &coff_symbol;
int in_source_file = 0;
int next_file_symnum = -1;
/* Name of the current file. */
- char *filestring = "";
+ const char *filestring = "";
int depth = 0;
int fcn_first_line = 0;
CORE_ADDR fcn_first_line_addr = 0;
struct minimal_symbol *msym;
/* Work around a stdio bug in SunOS4.1.1 (this makes me nervous....
- it's hard to know I've really worked around it. The fix should be
- harmless, anyway). The symptom of the bug is that the first
+ it's hard to know I've really worked around it. The fix should
+ be harmless, anyway). The symptom of the bug is that the first
fread (in read_one_sym), will (in my example) actually get data
from file offset 268, when the fseek was to 264 (and ftell shows
264). This causes all hell to break loose. I was unable to
bfd_seek (objfile->obfd, 0, 0);
- /* Position to read the symbol table. */
+ /* Position to read the symbol table. */
val = bfd_seek (objfile->obfd, (long) symtab_offset, 0);
if (val < 0)
perror_with_name (objfile->name);
- current_objfile = objfile;
+ coffread_objfile = objfile;
nlist_bfd_global = objfile->obfd;
nlist_nsyms_global = nsyms;
last_source_file = NULL;
memset (opaque_type_chain, 0, sizeof opaque_type_chain);
- if (type_vector) /* Get rid of previous one */
+ if (type_vector) /* Get rid of previous one. */
xfree (type_vector);
type_vector_length = 160;
type_vector = (struct type **)
coff_end_symtab (objfile);
coff_start_symtab ("_globals_");
+ /* coff_start_symtab will set the language of this symtab to
+ language_unknown, since such a ``file name'' is not
+ recognized. Override that with the minimal language to
+ allow printing values in this symtab. */
+ current_subfile->language = language_minimal;
complete_symtab ("_globals_", 0, 0);
- /* done with all files, everything from here on out is globals */
+ /* Done with all files, everything from here on out is
+ globals. */
}
- /* Special case for file with type declarations only, no text. */
+ /* Special case for file with type declarations only, no
+ text. */
if (!last_source_file && SDB_TYPE (cs->c_type)
&& cs->c_secnum == N_DEBUG)
complete_symtab (filestring, 0, 0);
/* Typedefs should not be treated as symbol definitions. */
if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
{
- /* Record all functions -- external and static -- in minsyms. */
+ /* Record all functions -- external and static -- in
+ minsyms. */
int section = cs_to_section (cs, objfile);
- tmpaddr = cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- record_minimal_symbol (cs, tmpaddr, mst_text, section, objfile);
+
+ tmpaddr = cs->c_value + ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
+ record_minimal_symbol (cs, tmpaddr, mst_text,
+ section, objfile);
fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
fcn_start_addr = tmpaddr;
case C_LINE:
case C_ALIAS:
case C_HIDDEN:
- complaint (&symfile_complaints, _("Bad n_sclass for symbol %s"),
+ complaint (&symfile_complaints,
+ _("Bad n_sclass for symbol %s"),
cs->c_name);
break;
case C_FILE:
- /* c_value field contains symnum of next .file entry in table
- or symnum of first global after last .file. */
+ /* c_value field contains symnum of next .file entry in
+ table or symnum of first global after last .file. */
next_file_symnum = cs->c_value;
if (cs->c_naux > 0)
filestring = coff_getfilename (&main_aux);
in_source_file = 1;
break;
- /* C_LABEL is used for labels and static functions. Including
- it here allows gdb to see static functions when no debug
- info is available. */
+ /* C_LABEL is used for labels and static functions.
+ Including it here allows gdb to see static functions when
+ no debug info is available. */
case C_LABEL:
- /* However, labels within a function can make weird backtraces,
- so filter them out (from phdm@macqel.be). */
+ /* However, labels within a function can make weird
+ backtraces, so filter them out (from phdm@macqel.be). */
if (within_function)
break;
case C_STAT:
case C_THUMBSTATFUNC:
if (cs->c_name[0] == '.')
{
- if (DEPRECATED_STREQ (cs->c_name, ".text"))
+ if (strcmp (cs->c_name, ".text") == 0)
{
- /* FIXME: don't wire in ".text" as section name
- or symbol name! */
- /* Check for in_source_file deals with case of
- a file with debugging symbols
- followed by a later file with no symbols. */
+ /* FIXME: don't wire in ".text" as section name or
+ symbol name! */
+ /* Check for in_source_file deals with case of a
+ file with debugging symbols followed by a later
+ file with no symbols. */
if (in_source_file)
complete_symtab (filestring,
- cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
+ cs->c_value + ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile)),
main_aux.x_scn.x_scnlen);
in_source_file = 0;
}
- /* flush rest of '.' symbols */
+ /* Flush rest of '.' symbols. */
break;
}
else if (!SDB_TYPE (cs->c_type)
/* At least on a 3b1, gcc generates swbeg and string labels
that look like this. Ignore them. */
break;
- /* fall in for static symbols that don't start with '.' */
+ /* Fall in for static symbols that don't start with '.' */
case C_THUMBEXT:
case C_THUMBEXTFUNC:
case C_EXT:
if (cs->c_secnum == N_UNDEF)
{
- /* This is a common symbol. See if the target
- environment knows where it has been relocated to. */
- CORE_ADDR reladdr;
- if (target_lookup_symbol (cs->c_name, &reladdr))
- {
- /* Error in lookup; ignore symbol. */
- break;
- }
- tmpaddr = reladdr;
- /* The address has already been relocated; make sure that
- objfile_relocate doesn't relocate it again. */
- sec = -2;
- ms_type = cs->c_sclass == C_EXT
- || cs->c_sclass == C_THUMBEXT ?
- mst_bss : mst_file_bss;
+ /* This is a common symbol. We used to rely on
+ the target to tell us whether it knows where
+ the symbol has been relocated to, but none of
+ the target implementations actually provided
+ that operation. So we just ignore the symbol,
+ the same way we would do if we had a target-side
+ symbol lookup which returned no match. */
+ break;
}
else if (cs->c_secnum == N_ABS)
{
/* Use the correct minimal symbol type (and don't
- relocate) for absolute values. */
+ relocate) for absolute values. */
ms_type = mst_abs;
sec = cs_to_section (cs, objfile);
tmpaddr = cs->c_value;
else
{
asection *bfd_section = cs_to_bfd_section (cs, objfile);
+
sec = cs_to_section (cs, objfile);
tmpaddr = cs->c_value;
- /* Statics in a PE file also get relocated */
+ /* Statics in a PE file also get relocated. */
if (cs->c_sclass == C_EXT
|| cs->c_sclass == C_THUMBEXTFUNC
|| cs->c_sclass == C_THUMBEXT
cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
|| cs->c_sclass == C_THUMBEXT ?
mst_text : mst_file_text;
- tmpaddr = gdbarch_smash_text_address
- (current_gdbarch, tmpaddr);
+ tmpaddr = gdbarch_smash_text_address (gdbarch, tmpaddr);
}
else if (bfd_section->flags & SEC_ALLOC
&& bfd_section->flags & SEC_LOAD)
{
ms_type =
- cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
- mst_data : mst_file_data;
+ cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT
+ ? mst_data : mst_file_data;
}
else if (bfd_section->flags & SEC_ALLOC)
{
ms_type =
- cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
- mst_bss : mst_file_bss;
+ cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT
+ ? mst_bss : mst_file_bss;
}
else
ms_type = mst_unknown;
}
- msym = record_minimal_symbol (cs, tmpaddr, ms_type, sec, objfile);
+ msym = record_minimal_symbol (cs, tmpaddr, ms_type,
+ sec, objfile);
if (msym)
- gdbarch_coff_make_msymbol_special
- (current_gdbarch, cs->c_sclass, msym);
+ gdbarch_coff_make_msymbol_special (gdbarch,
+ cs->c_sclass, msym);
if (SDB_TYPE (cs->c_type))
{
struct symbol *sym;
+
sym = process_coff_symbol
(cs, &main_aux, objfile);
SYMBOL_VALUE (sym) = tmpaddr;
break;
case C_FCN:
- if (DEPRECATED_STREQ (cs->c_name, ".bf"))
+ if (strcmp (cs->c_name, ".bf") == 0)
{
within_function = 1;
- /* value contains address of first non-init type code */
+ /* Value contains address of first non-init type
+ code. */
/* main_aux.x_sym.x_misc.x_lnsz.x_lnno
- contains line number of '{' } */
+ contains line number of '{' }. */
if (cs->c_naux != 1)
complaint (&symfile_complaints,
- _("`.bf' symbol %d has no aux entry"), cs->c_symnum);
+ _("`.bf' symbol %d has no aux entry"),
+ cs->c_symnum);
fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
fcn_first_line_addr = cs->c_value;
new = push_context (depth, fcn_start_addr);
fcn_cs_saved.c_name = getsymname (&fcn_sym_saved);
new->name =
- process_coff_symbol (&fcn_cs_saved, &fcn_aux_saved, objfile);
+ process_coff_symbol (&fcn_cs_saved,
+ &fcn_aux_saved, objfile);
}
- else if (DEPRECATED_STREQ (cs->c_name, ".ef"))
+ else if (strcmp (cs->c_name, ".ef") == 0)
{
if (!within_function)
error (_("Bad coff function information."));
- /* the value of .ef is the address of epilogue code;
+ /* The value of .ef is the address of epilogue code;
not useful for gdb. */
/* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
contains number of lines to '}' */
if (context_stack_depth <= 0)
- { /* We attempted to pop an empty context stack */
+ { /* We attempted to pop an empty context stack. */
complaint (&symfile_complaints,
- _("`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d"),
+ _("`.ef' symbol without matching `.bf' "
+ "symbol ignored starting at symnum %d"),
cs->c_symnum);
within_function = 0;
break;
if (context_stack_depth > 0 || new == NULL)
{
complaint (&symfile_complaints,
- _("Unmatched .ef symbol(s) ignored starting at symnum %d"),
+ _("Unmatched .ef symbol(s) ignored "
+ "starting at symnum %d"),
cs->c_symnum);
within_function = 0;
break;
if (cs->c_naux != 1)
{
complaint (&symfile_complaints,
- _("`.ef' symbol %d has no aux entry"), cs->c_symnum);
+ _("`.ef' symbol %d has no aux entry"),
+ cs->c_symnum);
fcn_last_line = 0x7FFFFFFF;
}
else
}
/* fcn_first_line is the line number of the opening '{'.
Do not record it - because it would affect gdb's idea
- of the line number of the first statement of the function -
- except for one-line functions, for which it is also the line
- number of all the statements and of the closing '}', and
- for which we do not have any other statement-line-number. */
+ of the line number of the first statement of the
+ function - except for one-line functions, for which
+ it is also the line number of all the statements and
+ of the closing '}', and for which we do not have any
+ other statement-line-number. */
if (fcn_last_line == 1)
record_line (current_subfile, fcn_first_line,
- fcn_first_line_addr);
+ gdbarch_addr_bits_remove (gdbarch,
+ fcn_first_line_addr));
else
- enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line,
- objfile);
-
- finish_block (new->name, &local_symbols, new->old_blocks,
- new->start_addr,
-#if defined (FUNCTION_EPILOGUE_SIZE)
- /* This macro should be defined only on
- machines where the
- fcn_aux_saved.x_sym.x_misc.x_fsize
- field is always zero.
- So use the .bf record information that
- points to the epilogue and add the size
- of the epilogue. */
- cs->c_value
- + FUNCTION_EPILOGUE_SIZE
- + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
-#else
+ enter_linenos (fcn_line_ptr, fcn_first_line,
+ fcn_last_line, objfile);
+
+ finish_block (new->name, &local_symbols,
+ new->old_blocks, new->start_addr,
fcn_cs_saved.c_value
+ fcn_aux_saved.x_sym.x_misc.x_fsize
- + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
-#endif
+ + ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile)),
objfile
);
within_function = 0;
break;
case C_BLOCK:
- if (DEPRECATED_STREQ (cs->c_name, ".bb"))
+ if (strcmp (cs->c_name, ".bb") == 0)
{
tmpaddr = cs->c_value;
- tmpaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ tmpaddr += ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
push_context (++depth, tmpaddr);
}
- else if (DEPRECATED_STREQ (cs->c_name, ".eb"))
+ else if (strcmp (cs->c_name, ".eb") == 0)
{
if (context_stack_depth <= 0)
- { /* We attempted to pop an empty context stack */
+ { /* We attempted to pop an empty context stack. */
complaint (&symfile_complaints,
- _("`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d"),
+ _("`.eb' symbol without matching `.bb' "
+ "symbol ignored starting at symnum %d"),
cs->c_symnum);
break;
}
if (depth-- != new->depth)
{
complaint (&symfile_complaints,
- _("Mismatched .eb symbol ignored starting at symnum %d"),
+ _("Mismatched .eb symbol ignored "
+ "starting at symnum %d"),
symnum);
break;
}
if (local_symbols && context_stack_depth > 0)
{
tmpaddr =
- cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ cs->c_value + ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
/* Make a block for the local symbols within. */
finish_block (0, &local_symbols, new->old_blocks,
new->start_addr, tmpaddr, objfile);
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 */
+ /* We've got no debugging symbols, but it's a portable
+ executable, so try to read the export table. */
read_pe_exported_syms (objfile);
}
ALL_OBJFILE_SYMTABS (objfile, s)
patch_opaque_types (s);
- current_objfile = NULL;
+ coffread_objfile = NULL;
}
\f
/* Routines for reading headers and symbols from executable. */
-/* Read the next symbol, swap it, and return it in both internal_syment
- form, and coff_symbol form. Also return its first auxent, if any,
- in internal_auxent form, and skip any other auxents. */
+/* Read the next symbol, swap it, and return it in both
+ internal_syment form, and coff_symbol form. Also return its first
+ auxent, if any, in internal_auxent form, and skip any other
+ auxents. */
static void
read_one_sym (struct coff_symbol *cs,
union internal_auxent *aux)
{
int i;
+ bfd_size_type bytes;
cs->c_symnum = symnum;
- bfd_bread (temp_sym, local_symesz, nlist_bfd_global);
+ bytes = bfd_bread (temp_sym, local_symesz, nlist_bfd_global);
+ if (bytes != local_symesz)
+ error (_("%s: error reading symbols"), coffread_objfile->name);
bfd_coff_swap_sym_in (symfile_bfd, temp_sym, (char *) sym);
cs->c_naux = sym->n_numaux & 0xff;
if (cs->c_naux >= 1)
{
- bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
- bfd_coff_swap_aux_in (symfile_bfd, temp_aux, sym->n_type, sym->n_sclass,
+ bytes = bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
+ if (bytes != local_auxesz)
+ error (_("%s: error reading symbols"), coffread_objfile->name);
+ bfd_coff_swap_aux_in (symfile_bfd, temp_aux,
+ sym->n_type, sym->n_sclass,
0, cs->c_naux, (char *) aux);
/* If more than one aux entry, read past it (only the first aux
- is important). */
+ is important). */
for (i = 1; i < cs->c_naux; i++)
- bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
+ {
+ bytes = bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
+ if (bytes != local_auxesz)
+ error (_("%s: error reading symbols"), coffread_objfile->name);
+ }
}
cs->c_name = getsymname (sym);
cs->c_value = sym->n_value;
}
}
\f
-/* Support for string table handling */
+/* Support for string table handling. */
static char *stringtab = NULL;
free_stringtab ();
/* If the file is stripped, the offset might be zero, indicating no
- string table. Just return with `stringtab' set to null. */
+ string table. Just return with `stringtab' set to null. */
if (offset == 0)
return 0;
length = bfd_h_get_32 (symfile_bfd, lengthbuf);
/* If no string table is needed, then the file may end immediately
- after the symbols. Just return with `stringtab' set to null. */
+ after the symbols. Just return with `stringtab' set to null. */
if (val != sizeof lengthbuf || length < sizeof lengthbuf)
return 0;
stringtab = (char *) xmalloc (length);
- /* This is in target format (probably not very useful, and not currently
- used), not host format. */
+ /* This is in target format (probably not very useful, and not
+ currently used), not host format. */
memcpy (stringtab, lengthbuf, sizeof lengthbuf);
- if (length == sizeof length) /* Empty table -- just the count */
+ if (length == sizeof length) /* Empty table -- just the count. */
return 0;
- val = bfd_bread (stringtab + sizeof lengthbuf, length - sizeof lengthbuf,
- abfd);
+ val = bfd_bread (stringtab + sizeof lengthbuf,
+ length - sizeof lengthbuf, abfd);
if (val != length - sizeof lengthbuf || stringtab[length - 1] != '\0')
return -1;
return result;
}
-/* Extract the file name from the aux entry of a C_FILE symbol. Return
- only the last component of the name. Result is in static storage and
- is only good for temporary use. */
+/* Extract the file name from the aux entry of a C_FILE symbol.
+ Return only the last component of the name. Result is in static
+ storage and is only good for temporary use. */
-static char *
+static const char *
coff_getfilename (union internal_auxent *aux_entry)
{
static char buffer[BUFSIZ];
char *temp;
- char *result;
+ const char *result;
if (aux_entry->x_file.x_n.x_zeroes == 0)
- strcpy (buffer, stringtab + aux_entry->x_file.x_n.x_offset);
+ {
+ if (strlen (stringtab + aux_entry->x_file.x_n.x_offset) >= BUFSIZ)
+ internal_error (__FILE__, __LINE__, _("coff file name too long"));
+ strcpy (buffer, stringtab + aux_entry->x_file.x_n.x_offset);
+ }
else
{
strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN);
/* FIXME: We should not be throwing away the information about what
directory. It should go into dirname of the symtab, or some such
place. */
- if ((temp = strrchr (result, '/')) != NULL)
- result = temp + 1;
+ result = lbasename (result);
return (result);
}
\f
if (bfd_seek (abfd, offset, 0) < 0)
return -1;
- /* Allocate the desired table, plus a sentinel */
+ /* Allocate the desired table, plus a sentinel. */
linetab = (char *) xmalloc (size + local_linesz);
val = bfd_bread (linetab, size, abfd);
if (val != size)
return -1;
- /* Terminate it with an all-zero sentinel record */
+ /* Terminate it with an all-zero sentinel record. */
memset (linetab + size, 0, local_linesz);
return 0;
enter_linenos (long file_offset, int first_line,
int last_line, struct objfile *objfile)
{
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
char *rawptr;
struct internal_lineno lptr;
complaint (&symfile_complaints,
_("Line number pointer %ld lower than start of line numbers"),
file_offset);
- if (file_offset > linetab_size) /* Too big to be an offset? */
+ if (file_offset > linetab_size) /* Too big to be an offset? */
return;
- file_offset += linetab_offset; /* Try reading at that linetab offset */
+ file_offset += linetab_offset; /* Try reading at that linetab
+ offset. */
}
rawptr = &linetab[file_offset - linetab_offset];
- /* skip first line entry for each function */
+ /* Skip first line entry for each function. */
rawptr += local_linesz;
- /* line numbers start at one for the first line of the function */
+ /* Line numbers start at one for the first line of the function. */
first_line--;
/* If the line number table is full (e.g. 64K lines in COFF debug
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. */
+ 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
- + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)));
+ {
+ CORE_ADDR addr = lptr.l_addr.l_paddr;
+ addr += ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
+ record_line (current_subfile,
+ first_line + L_LNNO32 (&lptr),
+ gdbarch_addr_bits_remove (gdbarch, addr));
+ }
else
break;
}
TYPE_LENGTH (target) = TYPE_LENGTH (real_target);
TYPE_NFIELDS (target) = TYPE_NFIELDS (real_target);
- TYPE_FIELDS (target) = (struct field *) TYPE_ALLOC (target, field_size);
+ TYPE_FIELDS (target) = (struct field *) TYPE_ALLOC (target,
+ field_size);
- memcpy (TYPE_FIELDS (target), TYPE_FIELDS (real_target), field_size);
+ memcpy (TYPE_FIELDS (target),
+ TYPE_FIELDS (real_target),
+ field_size);
if (TYPE_NAME (real_target))
{
if (TYPE_NAME (target))
xfree (TYPE_NAME (target));
- TYPE_NAME (target) = concat (TYPE_NAME (real_target), (char *)NULL);
+ TYPE_NAME (target) = concat (TYPE_NAME (real_target),
+ (char *) NULL);
}
}
/* Patch up all appropriate typedef symbols in the opaque_type_chains
- so that they can be used to print out opaque data structures properly. */
+ so that they can be used to print out opaque data structures
+ properly. */
static void
patch_opaque_types (struct symtab *s)
struct dict_iterator iter;
struct symbol *real_sym;
- /* Go through the per-file symbols only */
+ /* Go through the per-file symbols only. */
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
ALL_BLOCK_SYMBOLS (b, iter, real_sym)
{
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_DOMAIN (real_sym) == VAR_DOMAIN &&
- TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&
- TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)
+ if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF
+ && 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)
{
- char *name = DEPRECATED_SYMBOL_NAME (real_sym);
+ char *name = SYMBOL_LINKAGE_NAME (real_sym);
int hash = hashname (name);
struct symbol *sym, *prev;
prev = 0;
for (sym = opaque_type_chain[hash]; sym;)
{
- if (name[0] == DEPRECATED_SYMBOL_NAME (sym)[0] &&
- strcmp (name + 1, DEPRECATED_SYMBOL_NAME (sym) + 1) == 0)
+ if (name[0] == SYMBOL_LINKAGE_NAME (sym)[0]
+ && strcmp (name + 1, SYMBOL_LINKAGE_NAME (sym) + 1) == 0)
{
if (prev)
{
}
}
\f
+static int
+coff_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
+{
+ return gdbarch_sdb_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym));
+}
+
+static const struct symbol_register_ops coff_register_funcs = {
+ coff_reg_to_regnum
+};
+
static struct symbol *
process_coff_symbol (struct coff_symbol *cs,
union internal_auxent *aux,
struct objfile *objfile)
{
struct symbol *sym
- = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
- sizeof (struct symbol));
+ = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
+ sizeof (struct symbol));
char *name;
memset (sym, 0, sizeof (struct symbol));
name = cs->c_name;
name = EXTERNAL_NAME (name, objfile->obfd);
- SYMBOL_LANGUAGE (sym) = language_auto;
- SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
+ SYMBOL_SET_LANGUAGE (sym, current_subfile->language);
+ SYMBOL_SET_NAMES (sym, name, strlen (name), 1, objfile);
/* default assumptions */
SYMBOL_VALUE (sym) = cs->c_value;
if (ISFCN (cs->c_type))
{
- SYMBOL_VALUE (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ SYMBOL_VALUE (sym) += ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
SYMBOL_TYPE (sym) =
- lookup_function_type (decode_function_type (cs, cs->c_type, aux));
+ lookup_function_type (decode_function_type (cs, cs->c_type,
+ aux, objfile));
SYMBOL_CLASS (sym) = LOC_BLOCK;
if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT
}
else
{
- SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux);
+ SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux, objfile);
switch (cs->c_sclass)
{
case C_NULL:
case C_EXT:
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
- SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
add_symbol_to_list (sym, &global_symbols);
break;
case C_STAT:
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
- SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
if (within_function)
{
- /* Static symbol of local scope */
+ /* Static symbol of local scope. */
add_symbol_to_list (sym, &local_symbols);
}
else
{
- /* Static symbol at top level of file */
+ /* Static symbol at top level of file. */
add_symbol_to_list (sym, &file_symbols);
}
break;
#endif
case C_REG:
SYMBOL_CLASS (sym) = LOC_REGISTER;
- SYMBOL_VALUE (sym) = gdbarch_sdb_reg_to_regnum
- (current_gdbarch, cs->c_value);
+ SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs;
+ SYMBOL_VALUE (sym) = cs->c_value;
add_symbol_to_list (sym, &local_symbols);
break;
case C_ARG:
SYMBOL_CLASS (sym) = LOC_ARG;
+ SYMBOL_IS_ARGUMENT (sym) = 1;
add_symbol_to_list (sym, &local_symbols);
-#if !defined (BELIEVE_PCC_PROMOTION)
- if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
- {
- /* If PCC says a parameter is a short or a char,
- aligned on an int boundary, realign it to the
- "little end" of the int. */
- struct type *temptype;
- temptype = lookup_fundamental_type (current_objfile,
- FT_INTEGER);
- if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
- && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT
- && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (temptype))
- {
- SYMBOL_VALUE (sym) +=
- TYPE_LENGTH (temptype)
- - TYPE_LENGTH (SYMBOL_TYPE (sym));
- }
- }
-#endif
break;
case C_REGPARM:
- SYMBOL_CLASS (sym) = LOC_REGPARM;
- SYMBOL_VALUE (sym) = gdbarch_sdb_reg_to_regnum
- (current_gdbarch, cs->c_value);
+ SYMBOL_CLASS (sym) = LOC_REGISTER;
+ SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs;
+ SYMBOL_IS_ARGUMENT (sym) = 1;
+ SYMBOL_VALUE (sym) = cs->c_value;
add_symbol_to_list (sym, &local_symbols);
-#if !defined (BELIEVE_PCC_PROMOTION)
- /* FIXME: This should retain the current type, since it's just
- a register value. gnu@adobe, 26Feb93 */
- {
- /* If PCC says a parameter is a short or a char,
- it is really an int. */
- struct type *temptype;
- temptype =
- lookup_fundamental_type (current_objfile, FT_INTEGER);
- if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
- && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)
- {
- SYMBOL_TYPE (sym) =
- (TYPE_UNSIGNED (SYMBOL_TYPE (sym))
- ? lookup_fundamental_type (current_objfile,
- FT_UNSIGNED_INTEGER)
- : temptype);
- }
- }
-#endif
break;
case C_TPDEF:
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
- /* If type has no name, give it one */
+ /* If type has no name, give it one. */
if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
{
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
|| TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC)
{
- /* If we are giving a name to a type such as "pointer to
- foo" or "function returning foo", we better not set
- the TYPE_NAME. If the program contains "typedef char
- *caddr_t;", we don't want all variables of type char
- * to print as caddr_t. This is not just a
- consequence of GDB's type management; CC and GCC (at
- least through version 2.4) both output variables of
- either type char * or caddr_t with the type
- refering to the C_TPDEF symbol for caddr_t. If a future
- compiler cleans this up it GDB is not ready for it
- yet, but if it becomes ready we somehow need to
- disable this check (without breaking the PCC/GCC2.4
- case).
+ /* If we are giving a name to a type such as
+ "pointer to foo" or "function returning foo", we
+ better not set the TYPE_NAME. If the program
+ contains "typedef char *caddr_t;", we don't want
+ all variables of type char * to print as caddr_t.
+ This is not just a consequence of GDB's type
+ management; CC and GCC (at least through version
+ 2.4) both output variables of either type char *
+ or caddr_t with the type refering to the C_TPDEF
+ symbol for caddr_t. If a future compiler cleans
+ this up it GDB is not ready for it yet, but if it
+ becomes ready we somehow need to disable this
+ check (without breaking the PCC/GCC2.4 case).
Sigh.
}
else
TYPE_NAME (SYMBOL_TYPE (sym)) =
- concat (DEPRECATED_SYMBOL_NAME (sym), (char *)NULL);
+ concat (SYMBOL_LINKAGE_NAME (sym), (char *) NULL);
}
- /* Keep track of any type which points to empty structured type,
- so it can be filled from a definition from another file. A
- simple forward reference (TYPE_CODE_UNDEF) is not an
- empty structured type, though; the forward references
- work themselves out via the magic of coff_lookup_type. */
- if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR &&
- TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0 &&
- TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) !=
- TYPE_CODE_UNDEF)
+ /* Keep track of any type which points to empty structured
+ type, so it can be filled from a definition from another
+ file. A simple forward reference (TYPE_CODE_UNDEF) is
+ not an empty structured type, though; the forward
+ references work themselves out via the magic of
+ coff_lookup_type. */
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
+ && TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0
+ && TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym)))
+ != TYPE_CODE_UNDEF)
{
- int i = hashname (DEPRECATED_SYMBOL_NAME (sym));
+ int i = hashname (SYMBOL_LINKAGE_NAME (sym));
SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i];
opaque_type_chain[i] = sym;
/* Some compilers try to be helpful by inventing "fake"
names for anonymous enums, structures, and unions, like
- "~0fake" or ".0fake". Thanks, but no thanks... */
+ "~0fake" or ".0fake". Thanks, but no thanks... */
if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
- if (DEPRECATED_SYMBOL_NAME (sym) != NULL
- && *DEPRECATED_SYMBOL_NAME (sym) != '~'
- && *DEPRECATED_SYMBOL_NAME (sym) != '.')
+ if (SYMBOL_LINKAGE_NAME (sym) != NULL
+ && *SYMBOL_LINKAGE_NAME (sym) != '~'
+ && *SYMBOL_LINKAGE_NAME (sym) != '.')
TYPE_TAG_NAME (SYMBOL_TYPE (sym)) =
- concat (DEPRECATED_SYMBOL_NAME (sym), (char *)NULL);
+ concat (SYMBOL_LINKAGE_NAME (sym), (char *)NULL);
add_symbol_to_list (sym, &file_symbols);
break;
static struct type *
decode_type (struct coff_symbol *cs, unsigned int c_type,
- union internal_auxent *aux)
+ union internal_auxent *aux, struct objfile *objfile)
{
struct type *type = 0;
unsigned int new_c_type;
new_c_type = DECREF (c_type);
if (ISPTR (c_type))
{
- type = decode_type (cs, new_c_type, aux);
+ type = decode_type (cs, new_c_type, aux, objfile);
type = lookup_pointer_type (type);
}
else if (ISFCN (c_type))
{
- type = decode_type (cs, new_c_type, aux);
+ type = decode_type (cs, new_c_type, aux, objfile);
type = lookup_function_type (type);
}
else if (ISARY (c_type))
struct type *base_type, *index_type, *range_type;
/* Define an array type. */
- /* auxent refers to array, not base type */
+ /* auxent refers to array, not base type. */
if (aux->x_sym.x_tagndx.l == 0)
cs->c_naux = 0;
- /* shift the indices down */
+ /* Shift the indices down. */
dim = &aux->x_sym.x_fcnary.x_ary.x_dimen[0];
i = 1;
n = dim[0];
*dim = *(dim + 1);
*dim = 0;
- base_type = decode_type (cs, new_c_type, aux);
- index_type = lookup_fundamental_type (current_objfile, FT_INTEGER);
+ base_type = decode_type (cs, new_c_type, aux, objfile);
+ index_type = objfile_type (objfile)->builtin_int;
range_type =
- create_range_type ((struct type *) NULL, index_type, 0, n - 1);
+ create_range_type ((struct type *) NULL,
+ index_type, 0, n - 1);
type =
- create_array_type ((struct type *) NULL, base_type, range_type);
+ create_array_type ((struct type *) NULL,
+ base_type, range_type);
}
return type;
}
- /* Reference to existing type. This only occurs with the
- struct, union, and enum types. EPI a29k coff
- fakes us out by producing aux entries with a nonzero
- x_tagndx for definitions of structs, unions, and enums, so we
- have to check the c_sclass field. SCO 3.2v4 cc gets confused
- with pointers to pointers to defined structs, and generates
- negative x_tagndx fields. */
+ /* Reference to existing type. This only occurs with the struct,
+ union, and enum types. EPI a29k coff fakes us out by producing
+ aux entries with a nonzero x_tagndx for definitions of structs,
+ unions, and enums, so we have to check the c_sclass field. SCO
+ 3.2v4 cc gets confused with pointers to pointers to defined
+ structs, and generates negative x_tagndx fields. */
if (cs->c_naux > 0 && aux->x_sym.x_tagndx.l != 0)
{
if (cs->c_sclass != C_STRTAG
complaint (&symfile_complaints,
_("Symbol table entry for %s has bad tagndx value"),
cs->c_name);
- /* And fall through to decode_base_type... */
+ /* And fall through to decode_base_type... */
}
}
- return decode_base_type (cs, BTYPE (c_type), aux);
+ return decode_base_type (cs, BTYPE (c_type), aux, objfile);
}
/* Decode a coff type specifier for function definition;
return the type that the function returns. */
static struct type *
-decode_function_type (struct coff_symbol *cs, unsigned int c_type,
- union internal_auxent *aux)
+decode_function_type (struct coff_symbol *cs,
+ unsigned int c_type,
+ union internal_auxent *aux,
+ struct objfile *objfile)
{
if (aux->x_sym.x_tagndx.l == 0)
- cs->c_naux = 0; /* auxent refers to function, not base type */
+ cs->c_naux = 0; /* auxent refers to function, not base
+ type. */
- return decode_type (cs, DECREF (c_type), aux);
+ return decode_type (cs, DECREF (c_type), aux, objfile);
}
\f
-/* basic C types */
+/* Basic C types. */
static struct type *
-decode_base_type (struct coff_symbol *cs, unsigned int c_type,
- union internal_auxent *aux)
+decode_base_type (struct coff_symbol *cs,
+ unsigned int c_type,
+ union internal_auxent *aux,
+ struct objfile *objfile)
{
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct type *type;
switch (c_type)
{
case T_NULL:
- /* shows up with "void (*foo)();" structure members */
- return lookup_fundamental_type (current_objfile, FT_VOID);
+ /* Shows up with "void (*foo)();" structure members. */
+ return objfile_type (objfile)->builtin_void;
#ifdef T_VOID
case T_VOID:
/* Intel 960 COFF has this symbol and meaning. */
- return lookup_fundamental_type (current_objfile, FT_VOID);
+ return objfile_type (objfile)->builtin_void;
#endif
case T_CHAR:
- return lookup_fundamental_type (current_objfile, FT_CHAR);
+ return objfile_type (objfile)->builtin_char;
case T_SHORT:
- return lookup_fundamental_type (current_objfile, FT_SHORT);
+ return objfile_type (objfile)->builtin_short;
case T_INT:
- return lookup_fundamental_type (current_objfile, FT_INTEGER);
+ return objfile_type (objfile)->builtin_int;
case T_LONG:
if (cs->c_sclass == C_FIELD
&& aux->x_sym.x_misc.x_lnsz.x_size
- > gdbarch_long_bit (current_gdbarch))
- return lookup_fundamental_type (current_objfile, FT_LONG_LONG);
+ > gdbarch_long_bit (gdbarch))
+ return objfile_type (objfile)->builtin_long_long;
else
- return lookup_fundamental_type (current_objfile, FT_LONG);
+ return objfile_type (objfile)->builtin_long;
case T_FLOAT:
- return lookup_fundamental_type (current_objfile, FT_FLOAT);
+ return objfile_type (objfile)->builtin_float;
case T_DOUBLE:
- return lookup_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
+ return objfile_type (objfile)->builtin_double;
case T_LNGDBL:
- return lookup_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
+ return objfile_type (objfile)->builtin_long_double;
case T_STRUCT:
if (cs->c_naux != 1)
{
- /* anonymous structure type */
+ /* Anonymous structure type. */
type = coff_alloc_type (cs->c_symnum);
TYPE_CODE (type) = TYPE_CODE_STRUCT;
TYPE_NAME (type) = NULL;
- /* This used to set the tag to "<opaque>". But I think setting it
- to NULL is right, and the printing code can print it as
- "struct {...}". */
+ /* This used to set the tag to "<opaque>". But I think
+ setting it to NULL is right, and the printing code can
+ print it as "struct {...}". */
TYPE_TAG_NAME (type) = NULL;
INIT_CPLUS_SPECIFIC (type);
TYPE_LENGTH (type) = 0;
{
type = coff_read_struct_type (cs->c_symnum,
aux->x_sym.x_misc.x_lnsz.x_size,
- aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+ aux->x_sym.x_fcnary.x_fcn.x_endndx.l,
+ objfile);
}
return type;
case T_UNION:
if (cs->c_naux != 1)
{
- /* anonymous union type */
+ /* Anonymous union type. */
type = coff_alloc_type (cs->c_symnum);
TYPE_NAME (type) = NULL;
- /* This used to set the tag to "<opaque>". But I think setting it
- to NULL is right, and the printing code can print it as
- "union {...}". */
+ /* This used to set the tag to "<opaque>". But I think
+ setting it to NULL is right, and the printing code can
+ print it as "union {...}". */
TYPE_TAG_NAME (type) = NULL;
INIT_CPLUS_SPECIFIC (type);
TYPE_LENGTH (type) = 0;
{
type = coff_read_struct_type (cs->c_symnum,
aux->x_sym.x_misc.x_lnsz.x_size,
- aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+ aux->x_sym.x_fcnary.x_fcn.x_endndx.l,
+ objfile);
}
TYPE_CODE (type) = TYPE_CODE_UNION;
return type;
case T_ENUM:
if (cs->c_naux != 1)
{
- /* anonymous enum type */
+ /* Anonymous enum type. */
type = coff_alloc_type (cs->c_symnum);
TYPE_CODE (type) = TYPE_CODE_ENUM;
TYPE_NAME (type) = NULL;
- /* This used to set the tag to "<opaque>". But I think setting it
- to NULL is right, and the printing code can print it as
- "enum {...}". */
+ /* This used to set the tag to "<opaque>". But I think
+ setting it to NULL is right, and the printing code can
+ print it as "enum {...}". */
TYPE_TAG_NAME (type) = NULL;
TYPE_LENGTH (type) = 0;
TYPE_FIELDS (type) = 0;
{
type = coff_read_enum_type (cs->c_symnum,
aux->x_sym.x_misc.x_lnsz.x_size,
- aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+ aux->x_sym.x_fcnary.x_fcn.x_endndx.l,
+ objfile);
}
return type;
case T_MOE:
- /* shouldn't show up here */
+ /* Shouldn't show up here. */
break;
case T_UCHAR:
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
+ return objfile_type (objfile)->builtin_unsigned_char;
case T_USHORT:
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);
+ return objfile_type (objfile)->builtin_unsigned_short;
case T_UINT:
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
+ return objfile_type (objfile)->builtin_unsigned_int;
case T_ULONG:
if (cs->c_sclass == C_FIELD
&& aux->x_sym.x_misc.x_lnsz.x_size
- > gdbarch_long_bit (current_gdbarch))
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG);
+ > gdbarch_long_bit (gdbarch))
+ return objfile_type (objfile)->builtin_unsigned_long_long;
else
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
+ return objfile_type (objfile)->builtin_unsigned_long;
}
- complaint (&symfile_complaints, _("Unexpected type for symbol %s"), cs->c_name);
- return lookup_fundamental_type (current_objfile, FT_VOID);
+ complaint (&symfile_complaints,
+ _("Unexpected type for symbol %s"), cs->c_name);
+ return objfile_type (objfile)->builtin_void;
}
\f
/* This page contains subroutines of read_type. */
object describing the type. */
static struct type *
-coff_read_struct_type (int index, int length, int lastsym)
+coff_read_struct_type (int index, int length, int lastsym,
+ struct objfile *objfile)
{
struct nextfield
{
{
read_one_sym (ms, &sub_sym, &sub_aux);
name = ms->c_name;
- name = EXTERNAL_NAME (name, current_objfile->obfd);
+ name = EXTERNAL_NAME (name, objfile->obfd);
switch (ms->c_sclass)
{
list = new;
/* Save the data. */
- list->field.name =
- obsavestring (name,
- strlen (name),
- ¤t_objfile->objfile_obstack);
- FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
- FIELD_BITPOS (list->field) = 8 * ms->c_value;
+ list->field.name = obsavestring (name, strlen (name),
+ &objfile->objfile_obstack);
+ FIELD_TYPE (list->field) = decode_type (ms, ms->c_type,
+ &sub_aux, objfile);
+ SET_FIELD_BITPOS (list->field, 8 * ms->c_value);
FIELD_BITSIZE (list->field) = 0;
- FIELD_STATIC_KIND (list->field) = 0;
nfields++;
break;
list = new;
/* Save the data. */
- list->field.name =
- obsavestring (name,
- strlen (name),
- ¤t_objfile->objfile_obstack);
- FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
- FIELD_BITPOS (list->field) = ms->c_value;
+ list->field.name = obsavestring (name, strlen (name),
+ &objfile->objfile_obstack);
+ FIELD_TYPE (list->field) = decode_type (ms, ms->c_type,
+ &sub_aux, objfile);
+ SET_FIELD_BITPOS (list->field, ms->c_value);
FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size;
- FIELD_STATIC_KIND (list->field) = 0;
nfields++;
break;
Also defines the symbols that represent the values of the type. */
static struct type *
-coff_read_enum_type (int index, int length, int lastsym)
+coff_read_enum_type (int index, int length, int lastsym,
+ struct objfile *objfile)
{
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct symbol *sym;
struct type *type;
int nsyms = 0;
{
read_one_sym (ms, &sub_sym, &sub_aux);
name = ms->c_name;
- name = EXTERNAL_NAME (name, current_objfile->obfd);
+ name = EXTERNAL_NAME (name, objfile->obfd);
switch (ms->c_sclass)
{
case C_MOE:
sym = (struct symbol *) obstack_alloc
- (¤t_objfile->objfile_obstack,
- sizeof (struct symbol));
+ (&objfile->objfile_obstack, sizeof (struct symbol));
memset (sym, 0, sizeof (struct symbol));
- DEPRECATED_SYMBOL_NAME (sym) =
- obsavestring (name, strlen (name),
- ¤t_objfile->objfile_obstack);
+ SYMBOL_SET_LINKAGE_NAME (sym,
+ obsavestring (name, strlen (name),
+ &objfile->objfile_obstack));
SYMBOL_CLASS (sym) = LOC_CONST;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
SYMBOL_VALUE (sym) = ms->c_value;
if (length > 0)
TYPE_LENGTH (type) = length;
else /* Assume ints. */
- TYPE_LENGTH (type) = gdbarch_int_bit (current_gdbarch) / TARGET_CHAR_BIT;
+ TYPE_LENGTH (type) = gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT;
TYPE_CODE (type) = TYPE_CODE_ENUM;
TYPE_NFIELDS (type) = nsyms;
TYPE_FIELDS (type) = (struct field *)
for (; j < syms->nsyms; j++, n++)
{
struct symbol *xsym = syms->symbol[j];
+
SYMBOL_TYPE (xsym) = type;
- TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym);
- TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
+ TYPE_FIELD_NAME (type, n) = SYMBOL_LINKAGE_NAME (xsym);
+ SET_FIELD_BITPOS (TYPE_FIELD (type, n), SYMBOL_VALUE (xsym));
if (SYMBOL_VALUE (xsym) < 0)
unsigned_enum = 0;
TYPE_FIELD_BITSIZE (type, n) = 0;
- TYPE_FIELD_STATIC_KIND (type, n) = 0;
}
if (syms == osyms)
break;
}
if (unsigned_enum)
- TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+ TYPE_UNSIGNED (type) = 1;
return type;
}
-/* Register our ability to parse symbols for coff BFD files. */
+/* Register our ability to parse symbols for coff BFD files. */
-static struct sym_fns coff_sym_fns =
+static const struct sym_fns coff_sym_fns =
{
bfd_target_coff_flavour,
- coff_new_init, /* sym_new_init: init anything gbl to entire symtab */
- coff_symfile_init, /* sym_init: read initial info, setup for sym_read() */
- coff_symfile_read, /* sym_read: read a symbol file into symtab */
- coff_symfile_finish, /* sym_finish: finished with file, cleanup */
- default_symfile_offsets, /* sym_offsets: xlate external to internal form */
- NULL /* next: pointer to next struct sym_fns */
+ coff_new_init, /* sym_new_init: init anything gbl to
+ entire symtab */
+ coff_symfile_init, /* sym_init: read initial info, setup
+ for sym_read() */
+ coff_symfile_read, /* sym_read: read a symbol file into
+ symtab */
+ NULL, /* sym_read_psymbols */
+ coff_symfile_finish, /* sym_finish: finished with file,
+ cleanup */
+ default_symfile_offsets, /* sym_offsets: xlate external to
+ internal form */
+ default_symfile_segments, /* sym_segments: Get segment
+ information from a file */
+ NULL, /* sym_read_linetable */
+
+ default_symfile_relocate, /* sym_relocate: Relocate a debug
+ section. */
+ &psym_functions
};
void