/* Read AIX xcoff symbol tables and convert to internal format, for GDB.
- Copyright (C) 1986-2020 Free Software Foundation, Inc.
+ Copyright (C) 1986-2021 Free Software Foundation, Inc.
Derived from coffread.c, dbxread.c, and a lot of hacking.
Contributed by IBM Corporation.
#include "expression.h"
#include "complaints.h"
#include "psympriv.h"
+#include "dwarf2/sect-names.h"
+#include "dwarf2/public.h"
#include "gdb-stabs.h"
static void xcoff_initial_scan (struct objfile *, symfile_add_flags);
static void scan_xcoff_symtab (minimal_symbol_reader &,
+ psymtab_storage *partial_symtabs,
struct objfile *);
static const char *xcoff_next_symbol_text (struct objfile *);
++function_count;
/* If the function was compiled with XLC, we may have to add an
- extra line entry later. Reserve space for that. */
+ extra line entry later. Reserve space for that. */
if (ii + 1 < oldLineTb->nitems
&& oldLineTb->item[ii].pc != oldLineTb->item[ii + 1].pc)
extra_lines++;
else if (function_count > 1)
std::sort (fentry, fentry + function_count,
[] (const linetable_entry <e1, const linetable_entry& lte2)
- { return lte1.pc < lte2.pc; });
+ { return lte1.pc < lte2.pc; });
/* Allocate a new line table. */
newLineTb = (struct linetable *)
newline = 0;
if (oldLineTb->item[0].line != 0)
for (newline = 0;
- newline < oldLineTb->nitems && oldLineTb->item[newline].line; ++newline)
+ newline < oldLineTb->nitems && oldLineTb->item[newline].line;
+ ++newline)
newLineTb->item[newline] = oldLineTb->item[newline];
/* Now copy function lines one by one. */
for (ii = 0; ii < function_count; ++ii)
{
/* If the function was compiled with XLC, we may have to add an
- extra line to cover the function prologue. */
+ extra line to cover the function prologue. */
jj = fentry[ii].line;
if (jj + 1 < oldLineTb->nitems
&& oldLineTb->item[jj].pc != oldLineTb->item[jj + 1].pc)
if (inclDepth)
{
/* In xcoff, we assume include files cannot be nested (not in .c files
- of course, but in corresponding .s files.). */
+ of course, but in corresponding .s files.). */
/* This can happen with old versions of GCC.
- GCC 2.3.3-930426 does not exhibit this on a test case which
- a user said produced the message for him. */
+ GCC 2.3.3-930426 does not exhibit this on a test case which
+ a user said produced the message for him. */
complaint (_("Nested C_BINCL symbols"));
}
++inclDepth;
if (strcmp (inclTable[ii].name, get_last_source_file ()) == 0)
{
- /* The entry in the include table refers to the main source
- file. Add the lines to the main subfile. */
+ /* The entry in the include table refers to the main source
+ file. Add the lines to the main subfile. */
main_source_baseline = inclTable[ii].funStartLine;
enter_line_range
}
/* All the include files' line have been processed at this point. Now,
- enter remaining lines of the main file, if any left. */
+ enter remaining lines of the main file, if any left. */
if (offset < max_offset + 1 - linesz)
{
enter_line_range (&main_subfile, offset, 0, start, end,
lv = main_subfile.line_vector;
/* Line numbers are not necessarily ordered. xlc compilation will
- put static function to the end. */
+ put static function to the end. */
struct subfile *current_subfile = get_current_subfile ();
lineTb = arrange_linetable (lv);
for (ii = 0; ii < inclIndx; ++ii)
{
if (inclTable[ii].subfile != ((struct subfile *) &main_subfile)
- && (inclTable[ii].subfile)->line_vector) /* Useless if!!!
+ && (inclTable[ii].subfile)->line_vector) /* Useless if!!!
FIXMEmgo */
{
struct linetable *lineTb, *lv;
/* Enter a given range of lines into the line vector.
can be called in the following two ways:
enter_line_range (subfile, beginoffset, endoffset,
- startaddr, 0, firstLine) or
+ startaddr, 0, firstLine) or
enter_line_range (subfile, beginoffset, 0,
- startaddr, endaddr, firstLine)
+ startaddr, endaddr, firstLine)
endoffset points to the last line table entry that we should pay
attention to. */
complaint (_("Unexpected symbol continuation"));
/* Return something which points to '\0' and hope the symbol reading
- code does something reasonable. */
+ code does something reasonable. */
retval = "";
}
else if (symbol.n_sclass & 0x80)
complaint (_("Unexpected symbol continuation"));
/* Return something which points to '\0' and hope the symbol reading
- code does something reasonable. */
+ code does something reasonable. */
retval = "";
}
return retval;
/* READ_ONE_SYMBOL (symbol, cs, symname_alloced); */
/* read one symbol into `cs' structure. After processing the
- whole symbol table, only string table will be kept in memory,
- symbol table and debug section of xcoff will be freed. Thus
- we can mark symbols with names in string table as
- `alloced'. */
+ whole symbol table, only string table will be kept in memory,
+ symbol table and debug section of xcoff will be freed. Thus
+ we can mark symbols with names in string table as
+ `alloced'. */
{
int ii;
to 32(0x20). So we need to read the first function auxiliary entry
which contains the size. */
if (cs->c_naux > 1 && ISFCN (cs->c_type))
- {
- /* a function entry point. */
+ {
+ /* a function entry point. */
- fcn_start_addr = cs->c_value;
+ fcn_start_addr = cs->c_value;
- /* save the function header info, which will be used
- when `.bf' is seen. */
- fcn_cs_saved = *cs;
+ /* save the function header info, which will be used
+ when `.bf' is seen. */
+ fcn_cs_saved = *cs;
- /* Convert the auxent to something we can access. */
- bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
- 0, cs->c_naux, &fcn_aux_saved);
- continue;
- }
+ /* Convert the auxent to something we can access. */
+ bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
+ 0, cs->c_naux, &fcn_aux_saved);
+ continue;
+ }
/* Read the csect auxiliary header, which is always the last by
convention. */
bfd_coff_swap_aux_in (abfd,
{
/* A program csect is seen. We have to allocate one
- symbol table for each program csect. Normally gdb
- prefers one symtab for each source file. In case
- of AIX, one source file might include more than one
- [PR] csect, and they don't have to be adjacent in
- terms of the space they occupy in memory. Thus, one
- single source file might get fragmented in the
- memory and gdb's file start and end address
- approach does not work! GCC (and I think xlc) seem
- to put all the code in the unnamed program csect. */
+ symbol table for each program csect. Normally gdb
+ prefers one symtab for each source file. In case
+ of AIX, one source file might include more than one
+ [PR] csect, and they don't have to be adjacent in
+ terms of the space they occupy in memory. Thus, one
+ single source file might get fragmented in the
+ memory and gdb's file start and end address
+ approach does not work! GCC (and I think xlc) seem
+ to put all the code in the unnamed program csect. */
if (last_csect_name)
{
}
/* If this is the very first csect seen,
- basically `__start'. */
+ basically `__start'. */
if (just_started)
{
first_object_file_end
(fcn_cs_saved.c_value + off,
fcn_stab_saved.c_name, 0, 0, objfile);
if (newobj->name != NULL)
- SYMBOL_SECTION (newobj->name) = SECT_OFF_TEXT (objfile);
+ newobj->name->set_section_index (SECT_OFF_TEXT (objfile));
}
else if (strcmp (cs->c_name, ".ef") == 0)
{
0, cs->c_naux, &main_aux);
/* The value of .ef is the address of epilogue code;
- not useful for gdb. */
+ not useful for gdb. */
/* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
- contains number of lines to '}' */
+ contains number of lines to '}' */
if (outermost_context_p ())
{ /* We attempted to pop an empty context stack. */
cur_src_end_addr = file_end_addr;
cust = end_symtab (file_end_addr, SECT_OFF_TEXT (objfile));
/* When reading symbols for the last C_FILE of the objfile, try
- to make sure that we set pst->compunit_symtab to the symtab for the
- file, not to the _globals_ symtab. I'm not sure whether this
- actually works right or when/if it comes up. */
+ to make sure that we set pst->compunit_symtab to the symtab for the
+ file, not to the _globals_ symtab. I'm not sure whether this
+ actually works right or when/if it comes up. */
if (pst->compunit_symtab == NULL)
pst->compunit_symtab = cust;
end_stabs ();
if (cs->c_secnum < 0)
{
/* The value is a register number, offset within a frame, etc.,
- and does not get relocated. */
+ and does not get relocated. */
off = 0;
sec = -1;
}
/* default assumptions */
SET_SYMBOL_VALUE_ADDRESS (sym, cs->c_value + off);
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
- SYMBOL_SECTION (sym) = secnum_to_section (cs->c_secnum, objfile);
+ sym->set_section_index (secnum_to_section (cs->c_secnum, objfile));
if (ISFCN (cs->c_type))
{
/* At this point, we don't know the type of the function. This
- will be patched with the type from its stab entry later on in
- patch_block_stabs (), unless the file was compiled without -g. */
+ will be patched with the type from its stab entry later on in
+ patch_block_stabs (), unless the file was compiled without -g. */
sym->set_linkage_name (SYMNAME_ALLOC (name, symname_alloced));
SYMBOL_TYPE (sym) = objfile_type (objfile)->nodebug_text_symbol;
sym = define_symbol (cs->c_value + off, cs->c_name, 0, 0, objfile);
if (sym != NULL)
{
- SYMBOL_SECTION (sym) = sec;
+ sym->set_section_index (sec);
}
return sym;
}
SET_SYMBOL_VALUE_ADDRESS (sym,
SYMBOL_VALUE_ADDRESS (sym)
+ static_block_base);
- SYMBOL_SECTION (sym) = static_block_section;
+ sym->set_section_index (static_block_section);
}
return sym;
self->expand_psymtab (objfile);
/* Match with global symbols. This only needs to be done once,
- after all of the symtabs and dependencies have been read in. */
+ after all of the symtabs and dependencies have been read in. */
scan_file_globals (objfile);
}
}
(normal). */
static legacy_psymtab *
-xcoff_start_psymtab (struct objfile *objfile,
+xcoff_start_psymtab (psymtab_storage *partial_symtabs,
+ struct objfile *objfile,
const char *filename, int first_symnum)
{
/* We fill in textlow later. */
- legacy_psymtab *result = new legacy_psymtab (filename, objfile, 0);
+ legacy_psymtab *result = new legacy_psymtab (filename, partial_symtabs,
+ objfile->per_bfd, 0);
result->read_symtab_private =
XOBNEW (&objfile->objfile_obstack, struct symloc);
are the information for includes and dependencies. */
static legacy_psymtab *
-xcoff_end_psymtab (struct objfile *objfile, legacy_psymtab *pst,
+xcoff_end_psymtab (struct objfile *objfile, psymtab_storage *partial_symtabs,
+ legacy_psymtab *pst,
const char **include_list, int num_includes,
int capping_symbol_number,
legacy_psymtab **dependency_list,
first_fun_line_offset;
first_fun_line_offset = 0;
- end_psymtab_common (objfile, pst);
+ pst->end ();
pst->number_of_dependencies = number_dependencies;
if (number_dependencies)
{
pst->dependencies
- = objfile->partial_symtabs->allocate_dependencies (number_dependencies);
+ = partial_symtabs->allocate_dependencies (number_dependencies);
memcpy (pst->dependencies, dependency_list,
number_dependencies * sizeof (legacy_psymtab *));
}
for (i = 0; i < num_includes; i++)
{
legacy_psymtab *subpst =
- new legacy_psymtab (include_list[i], objfile);
+ new legacy_psymtab (include_list[i], partial_symtabs, objfile->per_bfd);
subpst->read_symtab_private = XOBNEW (&objfile->objfile_obstack, symloc);
((struct symloc *) subpst->read_symtab_private)->first_symnum = 0;
((struct symloc *) subpst->read_symtab_private)->numsyms = 0;
/* We could save slight bits of space by only making one of these,
- shared by the entire set of include files. FIXME-someday. */
+ shared by the entire set of include files. FIXME-someday. */
subpst->dependencies =
- objfile->partial_symtabs->allocate_dependencies (1);
+ partial_symtabs->allocate_dependencies (1);
subpst->dependencies[0] = pst;
subpst->number_of_dependencies = 1;
if (num_includes == 0
&& number_dependencies == 0
- && pst->n_global_syms == 0
- && pst->n_static_syms == 0)
+ && pst->empty ())
{
/* Throw away this psymtab, it's empty. */
/* Empty psymtabs happen as a result of header files which don't have
- any symbols in them. There can be a lot of them. */
+ any symbols in them. There can be a lot of them. */
- objfile->partial_symtabs->discard_psymtab (pst);
+ partial_symtabs->discard_psymtab (pst);
/* Indicate that psymtab was thrown away. */
pst = NULL;
if (symbol->n_zeroes)
{
/* If it's exactly E_SYMNMLEN characters long it isn't
- '\0'-terminated. */
+ '\0'-terminated. */
if (symbol->n_name[E_SYMNMLEN - 1] != '\0')
{
/* FIXME: wastes memory for symbols which we don't end up putting
static void
scan_xcoff_symtab (minimal_symbol_reader &reader,
+ psymtab_storage *partial_symtabs,
struct objfile *objfile)
{
CORE_ADDR toc_offset = 0; /* toc offset value in data section. */
each program csect, because their text
sections need not be adjacent. */
xcoff_end_psymtab
- (objfile, pst, psymtab_include_list,
+ (objfile, partial_symtabs, pst, psymtab_include_list,
includes_used, symnum_before, dependency_list,
dependencies_used, textlow_not_set);
includes_used = 0;
/* Give all psymtabs for this source file the same
name. */
pst = xcoff_start_psymtab
- (objfile,
+ (partial_symtabs, objfile,
filestring,
symnum_before);
}
if (pst)
{
- xcoff_end_psymtab (objfile, pst, psymtab_include_list,
+ xcoff_end_psymtab (objfile, partial_symtabs,
+ pst, psymtab_include_list,
includes_used, symnum_before,
dependency_list, dependencies_used,
textlow_not_set);
else
filestring = namestring;
- pst = xcoff_start_psymtab (objfile,
+ pst = xcoff_start_psymtab (partial_symtabs, objfile,
filestring,
symnum_before);
last_csect_name = NULL;
switch (p[1])
{
case 'S':
- add_psymbol_to_list (gdb::string_view (namestring,
- p - namestring),
- true, VAR_DOMAIN, LOC_STATIC,
- SECT_OFF_DATA (objfile),
- psymbol_placement::STATIC,
- symbol.n_value,
- psymtab_language, objfile);
+ pst->add_psymbol (gdb::string_view (namestring,
+ p - namestring),
+ true, VAR_DOMAIN, LOC_STATIC,
+ SECT_OFF_DATA (objfile),
+ psymbol_placement::STATIC,
+ symbol.n_value,
+ psymtab_language,
+ partial_symtabs, objfile);
continue;
case 'G':
/* The addresses in these entries are reported to be
wrong. See the code that reads 'G's for symtabs. */
- add_psymbol_to_list (gdb::string_view (namestring,
- p - namestring),
- true, VAR_DOMAIN, LOC_STATIC,
- SECT_OFF_DATA (objfile),
- psymbol_placement::GLOBAL,
- symbol.n_value,
- psymtab_language, objfile);
+ pst->add_psymbol (gdb::string_view (namestring,
+ p - namestring),
+ true, VAR_DOMAIN, LOC_STATIC,
+ SECT_OFF_DATA (objfile),
+ psymbol_placement::GLOBAL,
+ symbol.n_value,
+ psymtab_language,
+ partial_symtabs, objfile);
continue;
case 'T':
|| (p == namestring + 1
&& namestring[0] != ' '))
{
- add_psymbol_to_list (gdb::string_view (namestring,
- p - namestring),
- true, STRUCT_DOMAIN, LOC_TYPEDEF, -1,
- psymbol_placement::STATIC,
- 0, psymtab_language, objfile);
+ pst->add_psymbol (gdb::string_view (namestring,
+ p - namestring),
+ true, STRUCT_DOMAIN, LOC_TYPEDEF, -1,
+ psymbol_placement::STATIC,
+ 0, psymtab_language,
+ partial_symtabs, objfile);
if (p[2] == 't')
{
/* Also a typedef with the same name. */
- add_psymbol_to_list (gdb::string_view (namestring,
- p - namestring),
- true, VAR_DOMAIN, LOC_TYPEDEF, -1,
- psymbol_placement::STATIC,
- 0, psymtab_language, objfile);
+ pst->add_psymbol (gdb::string_view (namestring,
+ p - namestring),
+ true, VAR_DOMAIN, LOC_TYPEDEF, -1,
+ psymbol_placement::STATIC,
+ 0, psymtab_language,
+ partial_symtabs, objfile);
p += 1;
}
}
case 't':
if (p != namestring) /* a name is there, not just :T... */
{
- add_psymbol_to_list (gdb::string_view (namestring,
- p - namestring),
- true, VAR_DOMAIN, LOC_TYPEDEF, -1,
- psymbol_placement::STATIC,
- 0, psymtab_language, objfile);
+ pst->add_psymbol (gdb::string_view (namestring,
+ p - namestring),
+ true, VAR_DOMAIN, LOC_TYPEDEF, -1,
+ psymbol_placement::STATIC,
+ 0, psymtab_language,
+ partial_symtabs, objfile);
}
check_enum:
/* If this is an enumerated type, we need to
;
/* Note that the value doesn't matter for
enum constants in psymtabs, just in symtabs. */
- add_psymbol_to_list (gdb::string_view (p, q - p), true,
- VAR_DOMAIN, LOC_CONST, -1,
- psymbol_placement::STATIC,
- 0, psymtab_language, objfile);
+ pst->add_psymbol (gdb::string_view (p, q - p), true,
+ VAR_DOMAIN, LOC_CONST, -1,
+ psymbol_placement::STATIC,
+ 0, psymtab_language,
+ partial_symtabs, objfile);
/* Point past the name. */
p = q;
/* Skip over the value. */
case 'c':
/* Constant, e.g. from "const" in Pascal. */
- add_psymbol_to_list (gdb::string_view (namestring,
- p - namestring),
- true, VAR_DOMAIN, LOC_CONST, -1,
- psymbol_placement::STATIC,
- 0, psymtab_language, objfile);
+ pst->add_psymbol (gdb::string_view (namestring,
+ p - namestring),
+ true, VAR_DOMAIN, LOC_CONST, -1,
+ psymbol_placement::STATIC,
+ 0, psymtab_language,
+ partial_symtabs, objfile);
continue;
case 'f':
function_outside_compilation_unit_complaint (name);
xfree (name);
}
- add_psymbol_to_list (gdb::string_view (namestring,
- p - namestring),
- true, VAR_DOMAIN, LOC_BLOCK,
- SECT_OFF_TEXT (objfile),
- psymbol_placement::STATIC,
- symbol.n_value,
- psymtab_language, objfile);
+ pst->add_psymbol (gdb::string_view (namestring,
+ p - namestring),
+ true, VAR_DOMAIN, LOC_BLOCK,
+ SECT_OFF_TEXT (objfile),
+ psymbol_placement::STATIC,
+ symbol.n_value,
+ psymtab_language,
+ partial_symtabs, objfile);
continue;
/* Global functions were ignored here, but now they
if (startswith (namestring, "@FIX"))
continue;
- add_psymbol_to_list (gdb::string_view (namestring,
- p - namestring),
- true, VAR_DOMAIN, LOC_BLOCK,
- SECT_OFF_TEXT (objfile),
- psymbol_placement::GLOBAL,
- symbol.n_value,
- psymtab_language, objfile);
+ pst->add_psymbol (gdb::string_view (namestring,
+ p - namestring),
+ true, VAR_DOMAIN, LOC_BLOCK,
+ SECT_OFF_TEXT (objfile),
+ psymbol_placement::GLOBAL,
+ symbol.n_value,
+ psymtab_language,
+ partial_symtabs, objfile);
continue;
/* Two things show up here (hopefully); static symbols of
if (pst)
{
- xcoff_end_psymtab (objfile, pst, psymtab_include_list, includes_used,
+ xcoff_end_psymtab (objfile, partial_symtabs,
+ pst, psymtab_include_list, includes_used,
ssymnum, dependency_list,
dependencies_used, textlow_not_set);
}
if (val != size)
perror_with_name (_("reading symbol table"));
- /* I'm not sure how how good num_symbols is; the rule of thumb in
- init_psymbol_list was developed for a.out. On the one hand,
- num_symbols includes auxents. On the other hand, it doesn't
- include N_SLINE. */
- init_psymbol_list (objfile, num_symbols);
-
scoped_free_pendings free_pending;
minimal_symbol_reader reader (objfile);
/* Now that the symbol table data of the executable file are all in core,
process them and define symbols accordingly. */
- scan_xcoff_symtab (reader, objfile);
+ psymbol_functions *psf = new psymbol_functions ();
+ psymtab_storage *partial_symtabs = psf->get_partial_symtabs ().get ();
+ objfile->qf.emplace_front (psf);
+ scan_xcoff_symtab (reader, partial_symtabs, objfile);
/* Install any minimal symbols that have been collected as the current
minimal symbols for this objfile. */
xcoff_new_init, /* init anything gbl to entire symtab */
xcoff_symfile_init, /* read initial info, setup for sym_read() */
xcoff_initial_scan, /* read a symbol file into symtab */
- NULL, /* sym_read_psymbols */
xcoff_symfile_finish, /* finished with file, cleanup */
xcoff_symfile_offsets, /* xlate offsets ext->int form */
default_symfile_segments, /* Get segment information from a file. */
aix_process_linenos,
default_symfile_relocate, /* Relocate a debug section. */
NULL, /* sym_probe_fns */
- &psym_functions
};
/* Same as xcoff_get_n_import_files, but for core files. */