/* Read dbx symbol tables and convert to internal format, for GDB.
- Copyright (C) 1986-2017 Free Software Foundation, Inc.
+ Copyright (C) 1986-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include "cp-support.h"
#include "psympriv.h"
#include "block.h"
-
#include "aout/aout64.h"
#include "aout/stab_gnu.h" /* We always use GNU stabs, not
native, now. */
int symbol_offset;
int string_offset;
int file_string_offset;
+ enum language pst_language;
};
#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)
#define SYMBOL_OFFSET(p) (SYMLOC(p)->symbol_offset)
#define STRING_OFFSET(p) (SYMLOC(p)->string_offset)
#define FILE_STRING_OFFSET(p) (SYMLOC(p)->file_string_offset)
+#define PST_LANGUAGE(p) (SYMLOC(p)->pst_language)
\f
/* The objfile we are currently reading. */
static int symfile_relocatable = 0;
+/* When set, we are processing a .o file compiled by sun acc. This is
+ misnamed; it refers to all stabs-in-elf implementations which use
+ N_UNDF the way Sun does, including Solaris gcc. Hopefully all
+ stabs-in-elf implementations ever invented will choose to be
+ compatible. */
+
+static unsigned char processing_acc_compilation;
+
\f
/* The lowest text address we have yet encountered. This is needed
because in an a.out file, there is no header field which tells us
static void
unknown_symtype_complaint (const char *arg1)
{
- complaint (&symfile_complaints, _("unknown symbol type %s"), arg1);
+ complaint (_("unknown symbol type %s"), arg1);
}
static void
lbrac_mismatch_complaint (int arg1)
{
- complaint (&symfile_complaints,
- _("N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d"), arg1);
+ complaint (_("N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d"), arg1);
}
static void
repeated_header_complaint (const char *arg1, int arg2)
{
- complaint (&symfile_complaints,
- _("\"repeated\" header file %s not "
+ complaint (_("\"repeated\" header file %s not "
"previously seen, at symtab pos %d"),
arg1, arg2);
}
struct header_file_location
{
+ header_file_location (const char *name_, int instance_,
+ struct partial_symtab *pst_)
+ : name (name_),
+ instance (instance_),
+ pst (pst_)
+ {
+ }
+
const char *name; /* Name of header file */
int instance; /* See above */
struct partial_symtab *pst; /* Partial symtab that has the
BINCL/EINCL defs for this file. */
};
-/* The actual list and controling variables. */
-static struct header_file_location *bincl_list, *next_bincl;
-static int bincls_allocated;
+/* The list of bincls. */
+static std::vector<struct header_file_location> *bincl_list;
/* Local function prototypes. */
static void read_dbx_symtab (minimal_symbol_reader &, struct objfile *);
-static void free_bincl_list (struct objfile *);
-
static struct partial_symtab *find_corresponding_bincl_psymtab (const char *,
int);
-static void add_bincl_to_list (struct partial_symtab *, const char *, int);
-
-static void init_bincl_list (int, struct objfile *);
-
static const char *dbx_next_symbol_text (struct objfile *);
static void fill_symbuf (bfd *);
static struct partial_symtab *start_psymtab (struct objfile *, const char *,
CORE_ADDR, int,
- struct partial_symbol **,
- struct partial_symbol **);
+ std::vector<partial_symbol *> &,
+ std::vector<partial_symbol *> &);
/* Free up old header file tables. */
{
bfd *sym_bfd;
int val;
- struct cleanup *back_to;
sym_bfd = objfile->obfd;
perror_with_name (objfile_name (objfile));
/* Size the symbol table. */
- if (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0)
+ if (objfile->global_psymbols.capacity () == 0
+ && objfile->static_psymbols.capacity () == 0)
init_psymbol_list (objfile, DBX_SYMCOUNT (objfile));
symbol_size = DBX_SYMBOL_SIZE (objfile);
symbol_table_offset = DBX_SYMTAB_OFFSET (objfile);
- free_pending_blocks ();
- back_to = make_cleanup (really_free_pendings, 0);
+ scoped_free_pendings free_pending;
minimal_symbol_reader reader (objfile);
minimal symbols for this objfile. */
reader.install ();
-
- do_cleanups (back_to);
}
/* Initialize anything that needs initializing when a completely new
dbx_new_init (struct objfile *ignore)
{
stabsread_new_init ();
- buildsym_new_init ();
+ buildsym_init ();
init_header_files ();
}
return nlist.n_strx + stringtab_global + file_string_table_offset;
}
\f
-/* Initialize the list of bincls to contain none and have some
- allocated. */
-
-static void
-init_bincl_list (int number, struct objfile *objfile)
-{
- bincls_allocated = number;
- next_bincl = bincl_list = XNEWVEC (struct header_file_location,
- bincls_allocated);
-}
-
-/* Add a bincl to the list. */
-
-static void
-add_bincl_to_list (struct partial_symtab *pst, const char *name, int instance)
-{
- if (next_bincl >= bincl_list + bincls_allocated)
- {
- int offset = next_bincl - bincl_list;
-
- bincls_allocated *= 2;
- bincl_list = (struct header_file_location *)
- xrealloc ((char *) bincl_list,
- bincls_allocated * sizeof (struct header_file_location));
- next_bincl = bincl_list + offset;
- }
- next_bincl->pst = pst;
- next_bincl->instance = instance;
- next_bincl++->name = name;
-}
/* Given a name, value pair, find the corresponding
bincl in the list. Return the partial symtab associated
static struct partial_symtab *
find_corresponding_bincl_psymtab (const char *name, int instance)
{
- struct header_file_location *bincl;
-
- for (bincl = bincl_list; bincl < next_bincl; bincl++)
- if (bincl->instance == instance
- && strcmp (name, bincl->name) == 0)
- return bincl->pst;
+ for (const header_file_location &bincl : *bincl_list)
+ if (bincl.instance == instance
+ && strcmp (name, bincl.name) == 0)
+ return bincl.pst;
repeated_header_complaint (name, symnum);
return (struct partial_symtab *) 0;
}
-/* Free the storage allocated for the bincl list. */
-
-static void
-free_bincl_list (struct objfile *objfile)
-{
- xfree (bincl_list);
- bincls_allocated = 0;
-}
-
-static void
-do_free_bincl_list_cleanup (void *objfile)
-{
- free_bincl_list ((struct objfile *) objfile);
-}
-
-static struct cleanup *
-make_cleanup_free_bincl_list (struct objfile *objfile)
-{
- return make_cleanup (do_free_bincl_list_cleanup, objfile);
-}
-
/* Set namestring based on nlist. If the string table index is invalid,
give a fake name, and print a single error message per symbol file read,
rather than abort the symbol reading or flood the user with messages. */
>= DBX_STRINGTAB_SIZE (objfile)
|| nlist->n_strx + file_string_table_offset < nlist->n_strx)
{
- complaint (&symfile_complaints,
- _("bad string table offset in symbol %d"),
+ complaint (_("bad string table offset in symbol %d"),
symnum);
namestring = "<bad string table offset>";
}
static void
function_outside_compilation_unit_complaint (const char *arg1)
{
- complaint (&symfile_complaints,
- _("function `%s' appears to be defined "
+ complaint (_("function `%s' appears to be defined "
"outside of all compilation units"),
arg1);
}
int nsl;
int past_first_source_file = 0;
CORE_ADDR last_function_start = 0;
- struct cleanup *back_to;
bfd *abfd;
int textlow_not_set;
int data_sect_index;
sizeof (struct partial_symtab *));
/* Init bincl list */
- init_bincl_list (20, objfile);
- back_to = make_cleanup_free_bincl_list (objfile);
+ std::vector<struct header_file_location> bincl_storage;
+ scoped_restore restore_bincl_global
+ = make_scoped_restore (&bincl_list, &bincl_storage);
set_last_source_file (NULL);
pst = start_psymtab (objfile,
namestring, valu,
first_so_symnum * symbol_size,
- objfile->global_psymbols.next,
- objfile->static_psymbols.next);
+ objfile->global_psymbols,
+ objfile->static_psymbols);
pst->dirname = dirname_nso;
dirname_nso = NULL;
}
{
/* FIXME: we should not get here without a PST to work on.
Attempt to recover. */
- complaint (&symfile_complaints,
- _("N_BINCL %s not in entries for "
+ complaint (_("N_BINCL %s not in entries for "
"any file, at symtab pos %d"),
namestring, symnum);
continue;
}
- add_bincl_to_list (pst, namestring, nlist.n_value);
+ bincl_list->emplace_back (namestring, nlist.n_value, pst);
/* Mark down an include file in the current psymtab. */
time searching to the end of every string looking for
a backslash. */
- complaint (&symfile_complaints,
- _("unknown symbol descriptor `%c'"),
+ complaint (_("unknown symbol descriptor `%c'"),
p[1]);
/* Ignore it; perhaps it is an extension that we don't
text_end > pst->texthigh ? text_end : pst->texthigh,
dependency_list, dependencies_used, textlow_not_set);
}
-
- do_cleanups (back_to);
}
/* Allocate and partially fill a partial symtab. It will be
static struct partial_symtab *
start_psymtab (struct objfile *objfile, const char *filename, CORE_ADDR textlow,
- int ldsymoff, struct partial_symbol **global_syms,
- struct partial_symbol **static_syms)
+ int ldsymoff, std::vector<partial_symbol *> &global_psymbols,
+ std::vector<partial_symbol *> &static_psymbols)
{
struct partial_symtab *result =
start_psymtab_common (objfile, filename, textlow,
- global_syms, static_syms);
+ global_psymbols, static_psymbols);
result->read_symtab_private =
XOBNEW (&objfile->objfile_obstack, struct symloc);
/* Deduce the source language from the filename for this psymtab. */
psymtab_language = deduce_language_from_filename (filename);
+ PST_LANGUAGE (result) = psymtab_language;
return result;
}
static void
dbx_psymtab_to_symtab_1 (struct objfile *objfile, struct partial_symtab *pst)
{
- struct cleanup *old_chain;
int i;
if (pst->readin)
/* Init stuff necessary for reading in symbols */
stabsread_init ();
buildsym_init ();
- old_chain = make_cleanup (really_free_pendings, 0);
+ scoped_free_pendings free_pending;
file_string_table_offset = FILE_STRING_OFFSET (pst);
symbol_size = SYMBOL_SIZE (pst);
/* Read in this file's symbols. */
bfd_seek (objfile->obfd, SYMBOL_OFFSET (pst), SEEK_SET);
read_ofile_symtab (objfile, pst);
-
- do_cleanups (old_chain);
}
pst->readin = 1;
if (LDSYMLEN (self) || self->number_of_dependencies)
{
- struct cleanup *back_to;
-
/* Print the message now, before reading the string table,
to avoid disconcerting pauses. */
if (info_verbose)
next_symbol_text_func = dbx_next_symbol_text;
- back_to = make_cleanup (null_cleanup, NULL);
-
- if (DBX_STAB_SECTION (objfile))
- {
- stabs_data
- = symfile_relocate_debug_section (objfile,
- DBX_STAB_SECTION (objfile),
- NULL);
-
- if (stabs_data)
- make_cleanup (free_current_contents, (void *) &stabs_data);
- }
-
- dbx_psymtab_to_symtab_1 (objfile, self);
+ {
+ scoped_restore restore_stabs_data = make_scoped_restore (&stabs_data);
+ gdb::unique_xmalloc_ptr<gdb_byte> data_holder;
+ if (DBX_STAB_SECTION (objfile))
+ {
+ stabs_data
+ = symfile_relocate_debug_section (objfile,
+ DBX_STAB_SECTION (objfile),
+ NULL);
+ data_holder.reset (stabs_data);
+ }
- do_cleanups (back_to);
+ dbx_psymtab_to_symtab_1 (objfile, self);
+ }
/* Match with global symbols. This only needs to be done once,
after all of the symtabs and dependencies have been read in. */
positive offsets. */
nlist.n_value = (nlist.n_value ^ 0x80000000) - 0x80000000;
process_one_symbol (type, nlist.n_desc, nlist.n_value,
- namestring, section_offsets, objfile);
+ namestring, section_offsets, objfile,
+ PST_LANGUAGE (pst));
}
/* We skip checking for a new .o or -l file; that should never
happen in this routine. */
/* In a Solaris elf file, this variable, which comes from the
value of the N_SO symbol, will still be 0. Luckily, text_offset,
which comes from pst->textlow is correct. */
- if (last_source_start_addr == 0)
- last_source_start_addr = text_offset;
+ if (get_last_source_start_addr () == 0)
+ set_last_source_start_addr (text_offset);
/* In reordered executables last_source_start_addr may not be the
lower bound for this symtab, instead use text_offset which comes
from pst->textlow which is correct. */
- if (last_source_start_addr > text_offset)
- last_source_start_addr = text_offset;
+ if (get_last_source_start_addr () > text_offset)
+ set_last_source_start_addr (text_offset);
pst->compunit_symtab = end_symtab (text_offset + text_size,
SECT_OFF_TEXT (objfile));
the pst->section_offsets. All symbols that refer to memory
locations need to be offset by these amounts.
OBJFILE is the object file from which we are reading symbols. It
- is used in end_symtab. */
+ is used in end_symtab.
+ LANGUAGE is the language of the symtab.
+*/
void
process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
const struct section_offsets *section_offsets,
- struct objfile *objfile)
+ struct objfile *objfile, enum language language)
{
struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct context_stack *newobj;
+ struct context_stack cstk;
/* This remembers the address of the start of a function. It is
used because in Solaris 2, N_LBRAC, N_RBRAC, and N_SLINE entries
are relative to the current function's start address. On systems
the current block. */
struct block *block;
- if (context_stack_depth <= 0)
+ if (outermost_context_p ())
{
lbrac_mismatch_complaint (symnum);
break;
{
CORE_ADDR addr = last_function_start + valu;
- record_line (current_subfile, 0,
+ record_line (get_current_subfile (), 0,
gdbarch_addr_bits_remove (gdbarch, addr));
}
within_function = 0;
- newobj = pop_context ();
+ cstk = pop_context ();
/* Make a block for the local symbols within. */
- block = finish_block (newobj->name, &local_symbols,
- newobj->old_blocks, NULL,
- newobj->start_addr, newobj->start_addr + valu);
+ block = finish_block (cstk.name, &local_symbols,
+ cstk.old_blocks, NULL,
+ cstk.start_addr, cstk.start_addr + valu);
/* For C++, set the block's scope. */
- if (SYMBOL_LANGUAGE (newobj->name) == language_cplus)
- cp_set_block_scope (newobj->name, block, &objfile->objfile_obstack);
+ if (SYMBOL_LANGUAGE (cstk.name) == language_cplus)
+ cp_set_block_scope (cstk.name, block, &objfile->objfile_obstack);
/* May be switching to an assembler file which may not be using
block relative stabs, so reset the offset. */
valu += function_start_offset;
- if (context_stack_depth <= 0)
+ if (outermost_context_p ())
{
lbrac_mismatch_complaint (symnum);
break;
}
- newobj = pop_context ();
- if (desc != newobj->depth)
+ cstk = pop_context ();
+ if (desc != cstk.depth)
lbrac_mismatch_complaint (symnum);
if (local_symbols != NULL)
2000 would output N_LSYM entries after N_LBRAC
entries. As a consequence, these symbols are simply
discarded. Complain if this is the case. */
- complaint (&symfile_complaints,
- _("misplaced N_LBRAC entry; discarding local "
+ complaint (_("misplaced N_LBRAC entry; discarding local "
"symbols which have no enclosing block"));
}
- local_symbols = newobj->locals;
+ local_symbols = cstk.locals;
- if (context_stack_depth > 1)
+ if (get_context_stack_depth () > 1)
{
/* This is not the outermost LBRAC...RBRAC pair in the
function, its local symbols preceded it, and are the ones
/* Muzzle a compiler bug that makes end < start.
??? Which compilers? Is this ever harmful?. */
- if (newobj->start_addr > valu)
+ if (cstk.start_addr > valu)
{
- complaint (&symfile_complaints,
- _("block start larger than block end"));
- newobj->start_addr = valu;
+ complaint (_("block start larger than block end"));
+ cstk.start_addr = valu;
}
/* Make a block for the local symbols within. */
- finish_block (0, &local_symbols, newobj->old_blocks, NULL,
- newobj->start_addr, valu);
+ finish_block (0, &local_symbols, cstk.old_blocks, NULL,
+ cstk.start_addr, valu);
}
}
else
name. Patch things up. */
if (previous_stab_code == (unsigned char) N_SO)
{
- patch_subfile_names (current_subfile, name);
+ patch_subfile_names (get_current_subfile (), name);
break; /* Ignore repeated SOs. */
}
end_symtab (valu, SECT_OFF_TEXT (objfile));
function_start_offset = 0;
start_stabs ();
- start_symtab (objfile, name, NULL, valu);
+ start_symtab (objfile, name, NULL, valu, language);
record_debugformat ("stabs");
break;
CORE_ADDR addr = processing_gcc_compilation == 2 ?
last_function_start : valu;
- record_line (current_subfile, desc,
+ record_line (get_current_subfile (), desc,
gdbarch_addr_bits_remove (gdbarch, addr));
sline_found_in_function = 1;
}
else
- record_line (current_subfile, desc,
+ record_line (get_current_subfile (), desc,
gdbarch_addr_bits_remove (gdbarch, valu));
break;
unknown_symtype_complaint (hex_string (type));
/* FALLTHROUGH */
- /* The following symbol types don't need the address field
- relocated, since it is either unused, or is absolute. */
define_a_symbol:
+ /* These symbol types don't need the address field relocated,
+ since it is either unused, or is absolute. */
case N_GSYM: /* Global variable. */
case N_NSYMS: /* Number of symbols (Ultrix). */
case N_NOMAP: /* No map? (Ultrix). */
within_function = 1;
- if (context_stack_depth > 1)
+ if (get_context_stack_depth () > 1)
{
- complaint (&symfile_complaints,
- _("unmatched N_LBRAC before symtab pos %d"),
+ complaint (_("unmatched N_LBRAC before symtab pos %d"),
symnum);
break;
}
- if (context_stack_depth > 0)
+ if (!outermost_context_p ())
{
struct block *block;
- newobj = pop_context ();
+ cstk = pop_context ();
/* Make a block for the local symbols within. */
- block = finish_block (newobj->name, &local_symbols,
- newobj->old_blocks, NULL,
- newobj->start_addr, valu);
+ block = finish_block (cstk.name, &local_symbols,
+ cstk.old_blocks, NULL,
+ cstk.start_addr, valu);
/* For C++, set the block's scope. */
- if (SYMBOL_LANGUAGE (newobj->name) == language_cplus)
- cp_set_block_scope (newobj->name, block,
+ if (SYMBOL_LANGUAGE (cstk.name) == language_cplus)
+ cp_set_block_scope (cstk.name, block,
&objfile->objfile_obstack);
}
perror_with_name (name);
stabsread_new_init ();
- buildsym_new_init ();
+ buildsym_init ();
free_header_files ();
init_header_files ();
int val;
bfd *sym_bfd = objfile->obfd;
char *name = bfd_get_filename (sym_bfd);
- struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
/* Find the first and last text address. dbx_symfile_read seems to
want this. */
perror_with_name (name);
stabsread_new_init ();
- buildsym_new_init ();
+ buildsym_init ();
free_header_files ();
init_header_files ();
symbuf_read = 0;
symbuf_left = bfd_section_size (objfile->obfd, stabsect);
+
+ scoped_restore restore_stabs_data = make_scoped_restore (&stabs_data);
+ gdb::unique_xmalloc_ptr<gdb_byte> data_holder;
+
stabs_data = symfile_relocate_debug_section (objfile, stabsect, NULL);
if (stabs_data)
- make_cleanup (free_current_contents, (void *) &stabs_data);
+ data_holder.reset (stabs_data);
/* In an elf file, we've already installed the minimal symbols that came
from the elf (non-stab) symbol table, so always act like an
table and normal symbol entries won't be in the ".stab" section; but in
case it does, it will install them itself. */
dbx_symfile_read (objfile, 0);
-
- do_cleanups (back_to);
}
\f
/* Scan and build partial symbols for a file with special sections for stabs
perror_with_name (name);
stabsread_new_init ();
- buildsym_new_init ();
+ buildsym_init ();
free_header_files ();
init_header_files ();