/* Read dbx symbol tables and convert to internal format, for GDB.
- Copyright (C) 1986-2022 Free Software Foundation, Inc.
+ Copyright (C) 1986-2023 Free Software Foundation, Inc.
This file is part of GDB.
#include "symtab.h"
#include "breakpoint.h"
#include "target.h"
-#include "gdbcore.h" /* for bfd stuff */
-#include "libaout.h" /* FIXME Secret internal BFD stuff for a.out */
+#include "gdbcore.h"
+#include "libaout.h"
#include "filenames.h"
#include "objfiles.h"
#include "buildsym-legacy.h"
#include "complaints.h"
#include "cp-abi.h"
#include "cp-support.h"
-#include "psympriv.h"
+#include "c-lang.h"
+#include "psymtab.h"
#include "block.h"
#include "aout/aout64.h"
-#include "aout/stab_gnu.h" /* We always use GNU stabs, not
- native, now. */
+#include "aout/stab_gnu.h"
\f
/* Key for dbx-associated data. */
need to make guesses based on the symbols (which *are* relocated to
reflect the address it will be loaded at). */
-static CORE_ADDR lowest_text_address;
+static unrelocated_addr lowest_text_address;
/* Non-zero if there is any line number info in the objfile. Prevents
dbx_end_psymtab from discarding an otherwise empty psymtab. */
static void dbx_symfile_finish (struct objfile *);
static void record_minimal_symbol (minimal_symbol_reader &,
- const char *, CORE_ADDR, int,
+ const char *, unrelocated_addr, int,
struct objfile *);
static void add_new_header_file (const char *, int);
static void add_this_object_header_file (int);
static legacy_psymtab *start_psymtab (psymtab_storage *, struct objfile *,
- const char *, CORE_ADDR, int);
+ const char *, unrelocated_addr, int);
/* Free up old header file tables. */
\f
static void
record_minimal_symbol (minimal_symbol_reader &reader,
- const char *name, CORE_ADDR address, int type,
+ const char *name, unrelocated_addr address, int type,
struct objfile *objfile)
{
enum minimal_symbol_type ms_type;
Record it as global even if it's local, not global, so
lookup_minimal_symbol can find it. We don't check symbol_leading_char
because for SunOS4 it always is '_'. */
- if (name[8] == 'C' && strcmp ("__DYNAMIC", name) == 0)
+ if (strcmp ("__DYNAMIC", name) == 0)
ms_type = mst_data;
/* Same with virtual function tables, both global and static. */
{
const char *tempstring = name;
- if (tempstring[0] == bfd_get_symbol_leading_char (objfile->obfd.get ()))
+ if (*tempstring != '\0'
+ && *tempstring == bfd_get_symbol_leading_char (objfile->obfd.get ()))
++tempstring;
if (is_vtable_name (tempstring))
ms_type = mst_data;
perror_with_name (name);
memset (size_temp, 0, sizeof (size_temp));
- val = bfd_bread (size_temp, sizeof (size_temp), sym_bfd);
+ val = bfd_read (size_temp, sizeof (size_temp), sym_bfd);
if (val < 0)
{
perror_with_name (name);
val = bfd_seek (sym_bfd, STRING_TABLE_OFFSET, SEEK_SET);
if (val < 0)
perror_with_name (name);
- val = bfd_bread (DBX_STRINGTAB (objfile),
- DBX_STRINGTAB_SIZE (objfile),
- sym_bfd);
+ val = bfd_read (DBX_STRINGTAB (objfile),
+ DBX_STRINGTAB_SIZE (objfile),
+ sym_bfd);
if (val != DBX_STRINGTAB_SIZE (objfile))
perror_with_name (name);
}
else if (symbuf_sections == NULL)
{
count = sizeof (symbuf);
- nbytes = bfd_bread (symbuf, count, sym_bfd);
+ nbytes = bfd_read (symbuf, count, sym_bfd);
}
else
{
count = symbuf_left;
if (count > sizeof (symbuf))
count = sizeof (symbuf);
- nbytes = bfd_bread (symbuf, count, sym_bfd);
+ nbytes = bfd_read (symbuf, count, sym_bfd);
}
if (nbytes < 0)
symbuf_left -= sym_offset;
}
else
- bfd_seek (symfile_bfd, sym_offset, SEEK_CUR);
+ if (bfd_seek (symfile_bfd, sym_offset, SEEK_CUR) != 0)
+ perror_with_name (bfd_get_filename (symfile_bfd));
}
#define INTERNALIZE_SYMBOL(intern, extern, abfd) \
set_last_source_file (NULL);
- lowest_text_address = (CORE_ADDR) -1;
+ lowest_text_address = (unrelocated_addr) -1;
symfile_bfd = objfile->obfd.get (); /* For next_text_symbol. */
abfd = objfile->obfd.get ();
*) The call to strchr.
*) The addition of a partial symbol the two partial
symbol lists. This last is a large section of code, so
- I've imbedded it in the following macro. */
+ I've embedded it in the following macro. */
switch (nlist.n_type)
{
record_it:
namestring = set_namestring (objfile, &nlist);
- record_minimal_symbol (reader, namestring, nlist.n_value,
+ record_minimal_symbol (reader, namestring,
+ unrelocated_addr (nlist.n_value),
nlist.n_type, objfile); /* Always */
continue;
|| (namestring[(nsl = strlen (namestring)) - 1] == 'o'
&& namestring[nsl - 2] == '.'))
{
+ unrelocated_addr unrel_val = unrelocated_addr (nlist.n_value);
+
if (past_first_source_file && pst
/* The gould NP1 uses low values for .o and -l symbols
which are not the address. */
- && nlist.n_value >= pst->raw_text_low ())
+ && unrel_val >= pst->unrelocated_text_low ())
{
dbx_end_psymtab (objfile, partial_symtabs,
pst, psymtab_include_list,
includes_used, symnum * symbol_size,
- nlist.n_value > pst->raw_text_high ()
- ? nlist.n_value : pst->raw_text_high (),
+ unrel_val > pst->unrelocated_text_high ()
+ ? unrel_val : pst->unrelocated_text_high (),
dependency_list, dependencies_used,
textlow_not_set);
pst = (legacy_psymtab *) 0;
if (pst)
{
+ unrelocated_addr unrel_value = unrelocated_addr (valu);
dbx_end_psymtab (objfile, partial_symtabs,
pst, psymtab_include_list,
includes_used, symnum * symbol_size,
- (valu > pst->raw_text_high ()
- ? valu : pst->raw_text_high ()),
+ unrel_value > pst->unrelocated_text_high ()
+ ? unrel_value
+ : pst->unrelocated_text_high (),
dependency_list, dependencies_used,
prev_textlow_not_set);
pst = (legacy_psymtab *) 0;
if (!pst)
{
pst = start_psymtab (partial_symtabs, objfile,
- namestring, valu,
+ namestring,
+ unrelocated_addr (valu),
first_so_symnum * symbol_size);
pst->dirname = dirname_nso;
dirname_nso = NULL;
/* See if this is an end of function stab. */
if (pst && nlist.n_type == N_FUN && *namestring == '\000')
{
- CORE_ADDR valu;
+ unrelocated_addr valu;
/* It's value is the size (in bytes) of the function for
function relative stabs, or the address of the function's
end for old style stabs. */
- valu = nlist.n_value + last_function_start;
- if (pst->raw_text_high () == 0 || valu > pst->raw_text_high ())
+ valu = unrelocated_addr (nlist.n_value + last_function_start);
+ if (pst->unrelocated_text_high () == unrelocated_addr (0)
+ || valu > pst->unrelocated_text_high ())
pst->set_text_high (valu);
break;
}
new_name.get ());
}
}
+ else if (psymtab_language == language_c)
+ {
+ std::string name (namestring, p - namestring);
+ gdb::unique_xmalloc_ptr<char> new_name
+ = c_canonicalize_name (name.c_str ());
+ if (new_name != nullptr)
+ {
+ sym_len = strlen (new_name.get ());
+ sym_name = obstack_strdup (&objfile->objfile_obstack,
+ new_name.get ());
+ }
+ }
if (sym_len == 0)
{
{
case 'S':
if (pst != nullptr)
- pst->add_psymbol (gdb::string_view (sym_name, sym_len), true,
+ pst->add_psymbol (std::string_view (sym_name, sym_len), true,
VAR_DOMAIN, LOC_STATIC,
data_sect_index,
psymbol_placement::STATIC,
- nlist.n_value, psymtab_language,
+ unrelocated_addr (nlist.n_value),
+ psymtab_language,
partial_symtabs, objfile);
else
complaint (_("static `%*s' appears to be defined "
/* The addresses in these entries are reported to be
wrong. See the code that reads 'G's for symtabs. */
if (pst != nullptr)
- pst->add_psymbol (gdb::string_view (sym_name, sym_len), true,
+ pst->add_psymbol (std::string_view (sym_name, sym_len), true,
VAR_DOMAIN, LOC_STATIC,
data_sect_index,
psymbol_placement::GLOBAL,
- nlist.n_value, psymtab_language,
+ unrelocated_addr (nlist.n_value),
+ psymtab_language,
partial_symtabs, objfile);
else
complaint (_("global `%*s' appears to be defined "
&& namestring[0] != ' '))
{
if (pst != nullptr)
- pst->add_psymbol (gdb::string_view (sym_name, sym_len),
+ pst->add_psymbol (std::string_view (sym_name, sym_len),
true, STRUCT_DOMAIN, LOC_TYPEDEF, -1,
psymbol_placement::STATIC,
- 0, psymtab_language,
+ unrelocated_addr (0),
+ psymtab_language,
partial_symtabs, objfile);
else
complaint (_("enum, struct, or union `%*s' appears "
{
/* Also a typedef with the same name. */
if (pst != nullptr)
- pst->add_psymbol (gdb::string_view (sym_name, sym_len),
+ pst->add_psymbol (std::string_view (sym_name, sym_len),
true, VAR_DOMAIN, LOC_TYPEDEF, -1,
psymbol_placement::STATIC,
- 0, psymtab_language,
+ unrelocated_addr (0),
+ psymtab_language,
partial_symtabs, objfile);
else
complaint (_("typedef `%*s' appears to be defined "
if (p != namestring) /* a name is there, not just :T... */
{
if (pst != nullptr)
- pst->add_psymbol (gdb::string_view (sym_name, sym_len),
+ pst->add_psymbol (std::string_view (sym_name, sym_len),
true, VAR_DOMAIN, LOC_TYPEDEF, -1,
psymbol_placement::STATIC,
- 0, psymtab_language,
+ unrelocated_addr (0),
+ psymtab_language,
partial_symtabs, objfile);
else
complaint (_("typename `%*s' appears to be defined "
/* Note that the value doesn't matter for
enum constants in psymtabs, just in symtabs. */
if (pst != nullptr)
- pst->add_psymbol (gdb::string_view (p, q - p), true,
+ pst->add_psymbol (std::string_view (p, q - p), true,
VAR_DOMAIN, LOC_CONST, -1,
- psymbol_placement::STATIC, 0,
+ psymbol_placement::STATIC,
+ unrelocated_addr (0),
psymtab_language,
partial_symtabs, objfile);
else
case 'c':
/* Constant, e.g. from "const" in Pascal. */
if (pst != nullptr)
- pst->add_psymbol (gdb::string_view (sym_name, sym_len), true,
+ pst->add_psymbol (std::string_view (sym_name, sym_len), true,
VAR_DOMAIN, LOC_CONST, -1,
- psymbol_placement::STATIC, 0,
+ psymbol_placement::STATIC,
+ unrelocated_addr (0),
psymtab_language,
partial_symtabs, objfile);
else
pst ? pst->filename : NULL,
objfile);
if (minsym.minsym != NULL)
- nlist.n_value = minsym.minsym->value_raw_address ();
+ nlist.n_value
+ = CORE_ADDR (minsym.minsym->unrelocated_address ());
}
if (pst && textlow_not_set
&& gdbarch_sofun_address_maybe_missing (gdbarch))
{
- pst->set_text_low (nlist.n_value);
+ pst->set_text_low (unrelocated_addr (nlist.n_value));
textlow_not_set = 0;
}
/* End kludge. */
the partial symbol table. */
if (pst
&& (textlow_not_set
- || (nlist.n_value < pst->raw_text_low ()
+ || (unrelocated_addr (nlist.n_value)
+ < pst->unrelocated_text_low ()
&& (nlist.n_value != 0))))
{
- pst->set_text_low (nlist.n_value);
+ pst->set_text_low (unrelocated_addr (nlist.n_value));
textlow_not_set = 0;
}
if (pst != nullptr)
- pst->add_psymbol (gdb::string_view (sym_name, sym_len), true,
+ pst->add_psymbol (std::string_view (sym_name, sym_len), true,
VAR_DOMAIN, LOC_BLOCK,
SECT_OFF_TEXT (objfile),
psymbol_placement::STATIC,
- nlist.n_value, psymtab_language,
+ unrelocated_addr (nlist.n_value),
+ psymtab_language,
partial_symtabs, objfile);
continue;
pst ? pst->filename : NULL,
objfile);
if (minsym.minsym != NULL)
- nlist.n_value = minsym.minsym->value_raw_address ();
+ nlist.n_value
+ = CORE_ADDR (minsym.minsym->unrelocated_address ());
}
if (pst && textlow_not_set
&& gdbarch_sofun_address_maybe_missing (gdbarch))
{
- pst->set_text_low (nlist.n_value);
+ pst->set_text_low (unrelocated_addr (nlist.n_value));
textlow_not_set = 0;
}
/* End kludge. */
the partial symbol table. */
if (pst
&& (textlow_not_set
- || (nlist.n_value < pst->raw_text_low ()
+ || (unrelocated_addr (nlist.n_value)
+ < pst->unrelocated_text_low ()
&& (nlist.n_value != 0))))
{
- pst->set_text_low (nlist.n_value);
+ pst->set_text_low (unrelocated_addr (nlist.n_value));
textlow_not_set = 0;
}
if (pst != nullptr)
- pst->add_psymbol (gdb::string_view (sym_name, sym_len), true,
+ pst->add_psymbol (std::string_view (sym_name, sym_len), true,
VAR_DOMAIN, LOC_BLOCK,
SECT_OFF_TEXT (objfile),
psymbol_placement::GLOBAL,
- nlist.n_value, psymtab_language,
+ unrelocated_addr (nlist.n_value),
+ psymtab_language,
partial_symtabs, objfile);
continue;
dbx_end_psymtab (objfile, partial_symtabs, pst,
psymtab_include_list, includes_used,
symnum * symbol_size,
- (CORE_ADDR) 0, dependency_list,
+ (unrelocated_addr) 0, dependency_list,
dependencies_used, textlow_not_set);
pst = (legacy_psymtab *) 0;
includes_used = 0;
{
/* Don't set high text address of PST lower than it already
is. */
- CORE_ADDR text_end =
- (lowest_text_address == (CORE_ADDR) -1
- ? text_addr
- : lowest_text_address)
- + text_size;
+ unrelocated_addr text_end
+ = (unrelocated_addr
+ ((lowest_text_address == (unrelocated_addr) -1
+ ? text_addr
+ : CORE_ADDR (lowest_text_address))
+ + text_size));
dbx_end_psymtab (objfile, partial_symtabs,
pst, psymtab_include_list, includes_used,
symnum * symbol_size,
- (text_end > pst->raw_text_high ()
- ? text_end : pst->raw_text_high ()),
+ (text_end > pst->unrelocated_text_high ()
+ ? text_end : pst->unrelocated_text_high ()),
dependency_list, dependencies_used, textlow_not_set);
}
}
static legacy_psymtab *
start_psymtab (psymtab_storage *partial_symtabs, struct objfile *objfile,
- const char *filename, CORE_ADDR textlow, int ldsymoff)
+ const char *filename, unrelocated_addr textlow, int ldsymoff)
{
legacy_psymtab *result = new legacy_psymtab (filename, partial_symtabs,
objfile->per_bfd, textlow);
dbx_end_psymtab (struct objfile *objfile, psymtab_storage *partial_symtabs,
legacy_psymtab *pst,
const char **include_list, int num_includes,
- int capping_symbol_offset, CORE_ADDR capping_text,
+ int capping_symbol_offset, unrelocated_addr capping_text,
legacy_psymtab **dependency_list,
int number_dependencies,
int textlow_not_set)
}
if (minsym.minsym)
- pst->set_text_high (minsym.minsym->value_raw_address ()
- + minsym.minsym->size ());
+ pst->set_text_high
+ (unrelocated_addr (CORE_ADDR (minsym.minsym->unrelocated_address ())
+ + minsym.minsym->size ()));
last_function_name = NULL;
}
;
/* This test will be true if the last .o file is only data. */
else if (textlow_not_set)
- pst->set_text_low (pst->raw_text_high ());
+ pst->set_text_low (pst->unrelocated_text_high ());
else
{
/* If we know our own starting text address, then walk through all other
for (partial_symtab *p1 : partial_symtabs->range ())
if (!p1->text_high_valid && p1->text_low_valid && p1 != pst)
- p1->set_text_high (pst->raw_text_low ());
+ p1->set_text_high (pst->unrelocated_text_low ());
}
/* End of kludge for patching Solaris textlow and texthigh. */
symbol_size = SYMBOL_SIZE (pst);
/* Read in this file's symbols. */
- bfd_seek (objfile->obfd.get (), SYMBOL_OFFSET (pst), SEEK_SET);
- read_ofile_symtab (objfile, pst);
+ if (bfd_seek (objfile->obfd.get (), SYMBOL_OFFSET (pst), SEEK_SET) == 0)
+ read_ofile_symtab (objfile, pst);
}
pst->readin = true;
processing_gcc_compilation = 1;
else if (strcmp (namestring, GCC2_COMPILED_FLAG_SYMBOL) == 0)
processing_gcc_compilation = 2;
- if (tempstring[0] == bfd_get_symbol_leading_char (symfile_bfd))
+ if (*tempstring != '\0'
+ && *tempstring == bfd_get_symbol_leading_char (symfile_bfd))
++tempstring;
if (startswith (tempstring, "__gnu_compiled"))
processing_gcc_compilation = 2;
if (get_last_source_start_addr () > text_offset)
set_last_source_start_addr (text_offset);
- pst->compunit_symtab = end_compunit_symtab (text_offset + text_size,
- SECT_OFF_TEXT (objfile));
+ pst->compunit_symtab = end_compunit_symtab (text_offset + text_size);
end_stabs ();
const char *name = symbol->demangled_name ();
unsigned int prefix_len = cp_entire_prefix_len (name);
- block_set_scope (block, obstack_strndup (obstack, name, prefix_len),
- obstack);
+ block->set_scope (obstack_strndup (obstack, name, prefix_len),
+ obstack);
}
}
source file. Used to detect the SunPRO solaris compiler. */
static int n_opt_found;
+ /* The section index for this symbol. */
+ int section_index = -1;
+
/* Something is wrong if we see real data before seeing a source
file name. */
{
CORE_ADDR addr = last_function_start + valu;
- record_line (get_current_subfile (), 0,
- gdbarch_addr_bits_remove (gdbarch, addr));
+ record_line
+ (get_current_subfile (), 0,
+ unrelocated_addr (gdbarch_addr_bits_remove (gdbarch, addr)
+ - objfile->text_section_offset ()));
}
within_function = 0;
sline_found_in_function = 0;
/* Relocate for dynamic loading. */
+ section_index = SECT_OFF_TEXT (objfile);
valu += section_offsets[SECT_OFF_TEXT (objfile)];
valu = gdbarch_addr_bits_remove (gdbarch, valu);
last_function_start = valu;
case N_FN_SEQ:
/* This kind of symbol indicates the start of an object file.
Relocate for dynamic loading. */
+ section_index = SECT_OFF_TEXT (objfile);
valu += section_offsets[SECT_OFF_TEXT (objfile)];
break;
source file. Finish the symbol table of the previous source
file (if any) and start accumulating a new symbol table.
Relocate for dynamic loading. */
+ section_index = SECT_OFF_TEXT (objfile);
valu += section_offsets[SECT_OFF_TEXT (objfile)];
n_opt_found = 0;
patch_subfile_names (get_current_subfile (), name);
break; /* Ignore repeated SOs. */
}
- end_compunit_symtab (valu, SECT_OFF_TEXT (objfile));
+ end_compunit_symtab (valu);
end_stabs ();
}
sub-source-file, one whose contents were copied or included
in the compilation of the main source file (whose name was
given in the N_SO symbol). Relocate for dynamic loading. */
+ section_index = SECT_OFF_TEXT (objfile);
valu += section_offsets[SECT_OFF_TEXT (objfile)];
start_subfile (name);
break;
CORE_ADDR addr = processing_gcc_compilation == 2 ?
last_function_start : valu;
- record_line (get_current_subfile (), desc,
- gdbarch_addr_bits_remove (gdbarch, addr));
+ record_line
+ (get_current_subfile (), desc,
+ unrelocated_addr (gdbarch_addr_bits_remove (gdbarch, addr)
+ - objfile->text_section_offset ()));
sline_found_in_function = 1;
}
else
- record_line (get_current_subfile (), desc,
- gdbarch_addr_bits_remove (gdbarch, valu));
+ record_line
+ (get_current_subfile (), desc,
+ unrelocated_addr (gdbarch_addr_bits_remove (gdbarch, valu)
+ - objfile->text_section_offset ()));
break;
case N_BCOMM:
symbol_file_add as addr (this is known to affect
SunOS 4, and I suspect ELF too). Since there is no
Ttext.text symbol, we can get addr from the text offset. */
+ section_index = SECT_OFF_TEXT (objfile);
valu += section_offsets[SECT_OFF_TEXT (objfile)];
goto define_a_symbol;
}
case N_ROSYM:
goto case_N_ROSYM;
default:
- internal_error (__FILE__, __LINE__,
- _("failed internal consistency check"));
+ internal_error (_("failed internal consistency check"));
}
}
case_N_STSYM: /* Static symbol in data segment. */
case N_DSLINE: /* Source line number, data segment. */
+ section_index = SECT_OFF_DATA (objfile);
valu += section_offsets[SECT_OFF_DATA (objfile)];
goto define_a_symbol;
case_N_LCSYM: /* Static symbol in BSS segment. */
case N_BSLINE: /* Source line number, BSS segment. */
/* N_BROWS: overlaps with N_BSLINE. */
+ section_index = SECT_OFF_BSS (objfile);
valu += section_offsets[SECT_OFF_BSS (objfile)];
goto define_a_symbol;
case_N_ROSYM: /* Static symbol in read-only data segment. */
+ section_index = SECT_OFF_RODATA (objfile);
valu += section_offsets[SECT_OFF_RODATA (objfile)];
goto define_a_symbol;
case N_ENTRY: /* Alternate entry point. */
/* Relocate for dynamic loading. */
+ section_index = SECT_OFF_TEXT (objfile);
valu += section_offsets[SECT_OFF_TEXT (objfile)];
goto define_a_symbol;
case N_NBSTS:
case N_NBLCS:
unknown_symtype_complaint (hex_string (type));
- /* FALLTHROUGH */
define_a_symbol:
+ [[fallthrough]];
/* These symbol types don't need the address field relocated,
since it is either unused, or is absolute. */
case N_GSYM: /* Global variable. */
newobj = push_context (0, valu);
newobj->name = define_symbol (valu, name, desc, type, objfile);
+ if (newobj->name != nullptr)
+ newobj->name->set_section_index (section_index);
break;
default:
- define_symbol (valu, name, desc, type, objfile);
+ {
+ struct symbol *sym = define_symbol (valu, name, desc, type,
+ objfile);
+ if (sym != nullptr)
+ sym->set_section_index (section_index);
+ }
break;
}
}
val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
if (val < 0)
perror_with_name (name);
- val = bfd_bread (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
+ val = bfd_read (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
if (val != stabstrsize)
perror_with_name (name);
val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
if (val < 0)
perror_with_name (name);
- val = bfd_bread (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
+ val = bfd_read (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
if (val != stabstrsize)
perror_with_name (name);