/* Read coff symbol tables and convert to internal format, for GDB.
- Copyright (C) 1987-2015 Free Software Foundation, Inc.
+ Copyright (C) 1987-2018 Free Software Foundation, Inc.
Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
This file is part of GDB.
#include "coff/internal.h" /* Internal format of COFF symbols in BFD */
#include "libcoff.h" /* FIXME secret internal data from BFD */
#include "objfiles.h"
-#include "buildsym.h"
+#include "buildsym-legacy.h"
#include "gdb-stabs.h"
#include "stabsread.h"
#include "complaints.h"
#include "psymtab.h"
#include "build-id.h"
-extern void _initialize_coffread (void);
-
/* Key for COFF-associated data. */
static const struct objfile_data *coff_objfile_data_key;
struct internal_syment *,
union internal_auxent *);
-static void coff_symtab_read (long, unsigned int, struct objfile *);
+static void coff_symtab_read (minimal_symbol_reader &,
+ long, unsigned int, struct objfile *);
\f
/* We are called once per section from coff_symfile_read. We
need to examine each section we are passed, check to see
static void
coff_start_symtab (struct objfile *objfile, const char *name)
{
+ within_function = 0;
start_symtab (objfile,
/* We fill in the filename later. start_symtab puts this pointer
into last_source_file and we put it in subfiles->name, which
xstrdup (name),
/* We never know the directory name for COFF. */
NULL,
- /* The start address is irrelevant, since we set
- last_source_start_addr in coff_end_symtab. */
- 0);
+ /* The start address is irrelevant, since we call
+ set_last_source_start_addr in coff_end_symtab. */
+ 0,
+ /* Let buildsym.c deduce the language for this symtab. */
+ language_unknown);
record_debugformat ("COFF");
}
static void
coff_end_symtab (struct objfile *objfile)
{
- last_source_start_addr = current_source_start_addr;
+ set_last_source_start_addr (current_source_start_addr);
end_symtab (current_source_end_addr, SECT_OFF_TEXT (objfile));
}
static struct minimal_symbol *
-record_minimal_symbol (struct coff_symbol *cs, CORE_ADDR address,
+record_minimal_symbol (minimal_symbol_reader &reader,
+ struct coff_symbol *cs, CORE_ADDR address,
enum minimal_symbol_type type, int section,
struct objfile *objfile)
{
return NULL;
}
- return prim_record_minimal_symbol_and_info (cs->c_name, address,
- type, section, objfile);
+ return reader.record_with_info (cs->c_name, address, type, section);
}
\f
/* coff_symfile_init ()
/* Read a symbol file, after initialization by coff_symfile_init. */
static void
-coff_symfile_read (struct objfile *objfile, int symfile_flags)
+coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
{
struct coff_symfile_info *info;
- struct dbx_symfile_info *dbxinfo;
bfd *abfd = objfile->obfd;
coff_data_type *cdata = coff_data (abfd);
char *name = bfd_get_filename (abfd);
unsigned int num_symbols;
int symtab_offset;
int stringtab_offset;
- struct cleanup *back_to, *cleanup_minimal_symbols;
+ struct cleanup *back_to;
int stabstrsize;
info = (struct coff_symfile_info *) objfile_data (objfile,
coff_objfile_data_key);
- dbxinfo = DBX_SYMFILE_INFO (objfile);
symfile_bfd = abfd; /* Kludge for swap routines. */
/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
if (val < 0)
error (_("\"%s\": can't get string table"), name);
- init_minimal_symbol_collection ();
- cleanup_minimal_symbols = make_cleanup_discard_minimal_symbols ();
+ minimal_symbol_reader reader (objfile);
/* 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);
+ coff_symtab_read (reader, (long) symtab_offset, num_symbols, objfile);
/* Install any minimal symbols that have been collected as the
current minimal symbols for this objfile. */
- install_minimal_symbols (objfile);
+ reader.install ();
if (pe_file)
{
}
}
- /* Free the installed minimal symbol data. */
- do_cleanups (cleanup_minimal_symbols);
-
- bfd_map_over_sections (abfd, coff_locate_sections, (void *) info);
+ if (!(objfile->flags & OBJF_READNEVER))
+ bfd_map_over_sections (abfd, coff_locate_sections, (void *) info);
if (info->stabsects)
{
/* 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_buildid (objfile);
+ std::string debugfile = find_separate_debug_file_by_buildid (objfile);
- if (debugfile == NULL)
+ if (debugfile.empty ())
debugfile = find_separate_debug_file_by_debuglink (objfile);
- make_cleanup (xfree, debugfile);
- if (debugfile)
+ if (!debugfile.empty ())
{
- bfd *abfd = symfile_bfd_open (debugfile);
+ gdb_bfd_ref_ptr abfd (symfile_bfd_open (debugfile.c_str ()));
- make_cleanup_bfd_unref (abfd);
- symbol_file_add_separate (abfd, debugfile, symfile_flags, objfile);
+ symbol_file_add_separate (abfd.get (), debugfile.c_str (),
+ symfile_flags, objfile);
}
}
{
/* Let stabs reader clean up. */
stabsread_clear_cache ();
-
- dwarf2_free_objfile (objfile);
}
\f
We read them one at a time using read_one_sym (). */
static void
-coff_symtab_read (long symtab_offset, unsigned int nsyms,
+coff_symtab_read (minimal_symbol_reader &reader,
+ long symtab_offset, unsigned int nsyms,
struct objfile *objfile)
{
struct gdbarch *gdbarch = get_objfile_arch (objfile);
CORE_ADDR tmpaddr;
struct minimal_symbol *msym;
+ scoped_free_pendings free_pending;
+
/* 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
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;
+ get_current_subfile ()->language = language_minimal;
complete_symtab ("_globals_", 0, 0);
/* Done with all files, everything from here on out is
globals. */
int section = cs_to_section (cs, objfile);
tmpaddr = cs->c_value;
- record_minimal_symbol (cs, tmpaddr, mst_text,
+ record_minimal_symbol (reader, cs, tmpaddr, mst_text,
section, objfile);
fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
case C_LINE:
case C_ALIAS:
case C_HIDDEN:
- complaint (&symfile_complaints,
- _("Bad n_sclass for symbol %s"),
+ complaint (_("Bad n_sclass for symbol %s"),
cs->c_name);
break;
backtraces, so filter them out (from phdm@macqel.be). */
if (within_function)
break;
+ /* Fall through. */
case C_STAT:
case C_THUMBLABEL:
case C_THUMBSTAT:
/* 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 '.' */
+ /* For static symbols that don't start with '.'... */
+ /* Fall through. */
case C_THUMBEXT:
case C_THUMBEXTFUNC:
case C_EXT:
ms_type = mst_unknown;
}
- msym = record_minimal_symbol (cs, tmpaddr, ms_type,
+ msym = record_minimal_symbol (reader, cs, tmpaddr, ms_type,
sec, objfile);
if (msym)
gdbarch_coff_make_msymbol_special (gdbarch,
/* main_aux.x_sym.x_misc.x_lnsz.x_lnno
contains line number of '{' }. */
if (cs->c_naux != 1)
- complaint (&symfile_complaints,
- _("`.bf' symbol %d has no aux entry"),
+ complaint (_("`.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;
/* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
contains number of lines to '}' */
- if (context_stack_depth <= 0)
+ if (outermost_context_p ())
{ /* We attempted to pop an empty context stack. */
- complaint (&symfile_complaints,
- _("`.ef' symbol without matching `.bf' "
+ complaint (_("`.ef' symbol without matching `.bf' "
"symbol ignored starting at symnum %d"),
cs->c_symnum);
within_function = 0;
break;
}
- newobj = pop_context ();
+ struct context_stack cstk = pop_context ();
/* Stack must be empty now. */
- if (context_stack_depth > 0 || newobj == NULL)
+ if (!outermost_context_p () || newobj == NULL)
{
- complaint (&symfile_complaints,
- _("Unmatched .ef symbol(s) ignored "
+ complaint (_("Unmatched .ef symbol(s) ignored "
"starting at symnum %d"),
cs->c_symnum);
within_function = 0;
}
if (cs->c_naux != 1)
{
- complaint (&symfile_complaints,
- _("`.ef' symbol %d has no aux entry"),
+ complaint (_("`.ef' symbol %d has no aux entry"),
cs->c_symnum);
fcn_last_line = 0x7FFFFFFF;
}
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,
+ record_line (get_current_subfile (), fcn_first_line,
gdbarch_addr_bits_remove (gdbarch,
fcn_first_line_addr));
else
enter_linenos (fcn_line_ptr, fcn_first_line,
fcn_last_line, objfile);
- finish_block (newobj->name, &local_symbols, newobj->old_blocks,
- NULL, newobj->start_addr,
+ finish_block (cstk.name, cstk.old_blocks,
+ NULL, cstk.start_addr,
fcn_cs_saved.c_value
+ fcn_aux_saved.x_sym.x_misc.x_fsize
+ ANOFFSET (objfile->section_offsets,
}
else if (strcmp (cs->c_name, ".eb") == 0)
{
- if (context_stack_depth <= 0)
+ if (outermost_context_p ())
{ /* We attempted to pop an empty context stack. */
- complaint (&symfile_complaints,
- _("`.eb' symbol without matching `.bb' "
+ complaint (_("`.eb' symbol without matching `.bb' "
"symbol ignored starting at symnum %d"),
cs->c_symnum);
break;
}
- newobj = pop_context ();
- if (depth-- != newobj->depth)
+ struct context_stack cstk = pop_context ();
+ if (depth-- != cstk.depth)
{
- complaint (&symfile_complaints,
- _("Mismatched .eb symbol ignored "
+ complaint (_("Mismatched .eb symbol ignored "
"starting at symnum %d"),
symnum);
break;
}
- if (local_symbols && context_stack_depth > 0)
+ if (*get_local_symbols () && !outermost_context_p ())
{
tmpaddr =
cs->c_value + ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile));
/* Make a block for the local symbols within. */
- finish_block (0, &local_symbols, newobj->old_blocks, NULL,
- newobj->start_addr, tmpaddr);
+ finish_block (0, cstk.old_blocks, NULL,
+ cstk.start_addr, tmpaddr);
}
/* Now pop locals of block just finished. */
- local_symbols = newobj->locals;
+ *get_local_symbols () = cstk.locals;
}
break;
{
/* We've got no debugging symbols, but it's a portable
executable, so try to read the export table. */
- read_pe_exported_syms (objfile);
+ read_pe_exported_syms (reader, objfile);
}
if (get_last_source_file ())
return;
if (file_offset < linetab_offset)
{
- complaint (&symfile_complaints,
- _("Line number pointer %ld lower than start of line numbers"),
+ complaint (_("Line number pointer %ld lower than start of line numbers"),
file_offset);
if (file_offset > linetab_size) /* Too big to be an offset? */
return;
CORE_ADDR addr = lptr.l_addr.l_paddr;
addr += ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile));
- record_line (current_subfile,
+ record_line (get_current_subfile (),
first_line + L_LNNO32 (&lptr),
gdbarch_addr_bits_remove (gdbarch, addr));
}
name = cs->c_name;
name = EXTERNAL_NAME (name, objfile->obfd);
- SYMBOL_SET_LANGUAGE (sym, current_subfile->language,
+ SYMBOL_SET_LANGUAGE (sym, get_current_subfile ()->language,
&objfile->objfile_obstack);
SYMBOL_SET_NAMES (sym, name, strlen (name), 1, objfile);
SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK;
if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT
|| cs->c_sclass == C_THUMBSTATFUNC)
- add_symbol_to_list (sym, &file_symbols);
+ add_symbol_to_list (sym, get_file_symbols ());
else if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT
|| cs->c_sclass == C_THUMBEXTFUNC)
- add_symbol_to_list (sym, &global_symbols);
+ add_symbol_to_list (sym, get_global_symbols ());
}
else
{
case C_AUTO:
SYMBOL_ACLASS_INDEX (sym) = LOC_LOCAL;
- add_symbol_to_list (sym, &local_symbols);
+ add_symbol_to_list (sym, get_local_symbols ());
break;
case C_THUMBEXT:
SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile));
- add_symbol_to_list (sym, &global_symbols);
+ add_symbol_to_list (sym, get_global_symbols ());
break;
case C_THUMBSTAT:
if (within_function)
{
/* Static symbol of local scope. */
- add_symbol_to_list (sym, &local_symbols);
+ add_symbol_to_list (sym, get_local_symbols ());
}
else
{
/* Static symbol at top level of file. */
- add_symbol_to_list (sym, &file_symbols);
+ add_symbol_to_list (sym, get_file_symbols ());
}
break;
case C_REG:
SYMBOL_ACLASS_INDEX (sym) = coff_register_index;
SYMBOL_VALUE (sym) = cs->c_value;
- add_symbol_to_list (sym, &local_symbols);
+ add_symbol_to_list (sym, get_local_symbols ());
break;
case C_THUMBLABEL:
case C_ARG:
SYMBOL_ACLASS_INDEX (sym) = LOC_ARG;
SYMBOL_IS_ARGUMENT (sym) = 1;
- add_symbol_to_list (sym, &local_symbols);
+ add_symbol_to_list (sym, get_local_symbols ());
break;
case C_REGPARM:
SYMBOL_ACLASS_INDEX (sym) = coff_register_index;
SYMBOL_IS_ARGUMENT (sym) = 1;
SYMBOL_VALUE (sym) = cs->c_value;
- add_symbol_to_list (sym, &local_symbols);
+ add_symbol_to_list (sym, get_local_symbols ());
break;
case C_TPDEF:
SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i];
opaque_type_chain[i] = sym;
}
- add_symbol_to_list (sym, &file_symbols);
+ add_symbol_to_list (sym, get_file_symbols ());
break;
case C_STRTAG:
/* 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 (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
if (SYMBOL_LINKAGE_NAME (sym) != NULL
&& *SYMBOL_LINKAGE_NAME (sym) != '~'
&& *SYMBOL_LINKAGE_NAME (sym) != '.')
- TYPE_TAG_NAME (SYMBOL_TYPE (sym)) =
+ TYPE_NAME (SYMBOL_TYPE (sym)) =
concat (SYMBOL_LINKAGE_NAME (sym), (char *)NULL);
- add_symbol_to_list (sym, &file_symbols);
+ add_symbol_to_list (sym, get_file_symbols ());
break;
default:
}
else
{
- complaint (&symfile_complaints,
- _("Symbol table entry for %s has bad tagndx value"),
+ complaint (_("Symbol table entry for %s has bad tagndx value"),
cs->c_name);
/* And fall through to decode_base_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 {...}". */
- TYPE_TAG_NAME (type) = NULL;
INIT_CPLUS_SPECIFIC (type);
TYPE_LENGTH (type) = 0;
TYPE_FIELDS (type) = 0;
/* 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 {...}". */
- TYPE_TAG_NAME (type) = NULL;
INIT_CPLUS_SPECIFIC (type);
TYPE_LENGTH (type) = 0;
TYPE_FIELDS (type) = 0;
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 {...}". */
- TYPE_TAG_NAME (type) = NULL;
TYPE_LENGTH (type) = 0;
TYPE_FIELDS (type) = 0;
TYPE_NFIELDS (type) = 0;
else
return objfile_type (objfile)->builtin_unsigned_long;
}
- complaint (&symfile_complaints,
- _("Unexpected type for symbol %s"), cs->c_name);
+ complaint (_("Unexpected type for symbol %s"), cs->c_name);
return objfile_type (objfile)->builtin_void;
}
\f
type = coff_alloc_type (index);
if (within_function)
- symlist = &local_symbols;
+ symlist = get_local_symbols ();
else
- symlist = &file_symbols;
+ symlist = get_file_symbols ();
osyms = *symlist;
o_nsyms = osyms ? osyms->nsyms : 0;