/* Read AIX xcoff symbol tables and convert to internal format, for GDB.
- Copyright (C) 1986-2004, 2007-2012 Free Software Foundation, Inc.
+ Copyright (C) 1986-2013 Free Software Foundation, Inc.
Derived from coffread.c, dbxread.c, and a lot of hacking.
Contributed by IBM Corporation.
static struct symbol *process_xcoff_symbol (struct coff_symbol *,
struct objfile *);
-static void read_xcoff_symtab (struct partial_symtab *);
+static void read_xcoff_symtab (struct objfile *, struct partial_symtab *);
#if 0
static void add_stab_to_list (char *, struct pending_stabs **);
in psymtab to symtab processing. */
static struct partial_symtab *this_symtab_psymtab;
+/* Objfile related to this_symtab_psymtab; set at the same time. */
+static struct objfile *this_symtab_objfile;
+
/* given the start and end addresses of a compilation unit (or a csect,
at times) process its lines and create appropriate line vectors. */
{
int offset, ii;
file_ptr max_offset
- = XCOFF_DATA (this_symtab_psymtab->objfile)->max_lineno_offset;
+ = XCOFF_DATA (this_symtab_objfile)->max_lineno_offset;
/* subfile structure for the main compilation unit. */
struct subfile main_subfile;
/* There was source with line numbers in include files. */
int linesz =
- coff_data (this_symtab_psymtab->objfile->obfd)->local_linesz;
+ coff_data (this_symtab_objfile->obfd)->local_linesz;
main_source_baseline = 0;
for (ii = 0; ii < inclIndx; ++ii)
CORE_ADDR startaddr, /* offsets to line table */
CORE_ADDR endaddr, unsigned *firstLine)
{
- struct objfile *objfile = this_symtab_psymtab->objfile;
+ struct objfile *objfile = this_symtab_objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
unsigned int curoffset;
CORE_ADDR addr;
char *retval;
/* FIXME: is this the same as the passed arg? */
- if (this_symtab_psymtab)
- objfile = this_symtab_psymtab->objfile;
+ if (this_symtab_objfile)
+ objfile = this_symtab_objfile;
bfd_coff_swap_sym_in (objfile->obfd, raw_symbol, &symbol);
if (symbol.n_zeroes)
/* Read symbols for a given partial symbol table. */
static void
-read_xcoff_symtab (struct partial_symtab *pst)
+read_xcoff_symtab (struct objfile *objfile, struct partial_symtab *pst)
{
- struct objfile *objfile = pst->objfile;
bfd *abfd = objfile->obfd;
char *raw_auxptr; /* Pointer to first raw aux entry for sym. */
struct coff_symfile_info *xcoff = XCOFF_DATA (objfile);
const char *last_csect_name; /* Last seen csect's name. */
this_symtab_psymtab = pst;
+ this_symtab_objfile = objfile;
/* Get the appropriate COFF "constants" related to the file we're
handling. */
static void
read_symbol (struct internal_syment *symbol, int symno)
{
- struct coff_symfile_info *xcoff = XCOFF_DATA (this_symtab_psymtab->objfile);
+ struct coff_symfile_info *xcoff = XCOFF_DATA (this_symtab_objfile);
int nsyms = xcoff->symtbl_num_syms;
char *stbl = xcoff->symtbl;
symbol->n_scnum = -1;
return;
}
- bfd_coff_swap_sym_in (this_symtab_psymtab->objfile->obfd,
+ bfd_coff_swap_sym_in (this_symtab_objfile->obfd,
stbl + (symno * local_symesz),
symbol);
}
static int
read_symbol_lineno (int symno)
{
- struct objfile *objfile = this_symtab_psymtab->objfile;
+ struct objfile *objfile = this_symtab_objfile;
int xcoff64 = bfd_xcoff_is_xcoff64 (objfile->obfd);
struct coff_symfile_info *info = XCOFF_DATA (objfile);
info->max_lineno_offset = maxoff;
}
\f
-static void xcoff_psymtab_to_symtab_1 (struct partial_symtab *);
-
static void
-xcoff_psymtab_to_symtab_1 (struct partial_symtab *pst)
+xcoff_psymtab_to_symtab_1 (struct objfile *objfile, struct partial_symtab *pst)
{
struct cleanup *old_chain;
int i;
wrap_here (""); /* Flush output */
gdb_flush (gdb_stdout);
}
- xcoff_psymtab_to_symtab_1 (pst->dependencies[i]);
+ xcoff_psymtab_to_symtab_1 (objfile, pst->dependencies[i]);
}
if (((struct symloc *) pst->read_symtab_private)->numsyms != 0)
buildsym_init ();
old_chain = make_cleanup (really_free_pendings, 0);
- read_xcoff_symtab (pst);
+ read_xcoff_symtab (objfile, pst);
do_cleanups (old_chain);
}
pst->readin = 1;
}
-static void xcoff_psymtab_to_symtab (struct partial_symtab *);
-
/* Read in all of the symbols for a given psymtab for real.
Be verbose about it if the user wants that. */
static void
-xcoff_psymtab_to_symtab (struct partial_symtab *pst)
+xcoff_psymtab_to_symtab (struct objfile *objfile, struct partial_symtab *pst)
{
- bfd *sym_bfd;
-
if (!pst)
return;
gdb_flush (gdb_stdout);
}
- sym_bfd = pst->objfile->obfd;
-
next_symbol_text_func = xcoff_next_symbol_text;
- xcoff_psymtab_to_symtab_1 (pst);
+ xcoff_psymtab_to_symtab_1 (objfile, pst);
/* Match with global symbols. This only needs to be done once,
after all of the symtabs and dependencies have been read in. */
- scan_file_globals (pst->objfile);
+ scan_file_globals (objfile);
/* Finish up the debug error message. */
if (info_verbose)
find this causes a significant slowdown in gdb then we could
set it in the debug symbol readers only when necessary. */
objfile->flags |= OBJF_REORDERED;
-
- init_entry_point_info (objfile);
}
/* Perform any local cleanups required when we are done with a particular
are the information for includes and dependencies. */
static struct partial_symtab *
-xcoff_end_psymtab (struct partial_symtab *pst, const char **include_list,
- int num_includes, int capping_symbol_number,
+xcoff_end_psymtab (struct objfile *objfile, struct partial_symtab *pst,
+ const char **include_list, int num_includes,
+ int capping_symbol_number,
struct partial_symtab **dependency_list,
int number_dependencies, int textlow_not_set)
{
int i;
- struct objfile *objfile = pst->objfile;
if (capping_symbol_number != -1)
((struct symloc *) pst->read_symtab_private)->numsyms =
subpst->read_symtab = pst->read_symtab;
}
- sort_pst_symbols (pst);
+ sort_pst_symbols (objfile, pst);
if (num_includes == 0
&& number_dependencies == 0
/* Empty psymtabs happen as a result of header files which don't have
any symbols in them. There can be a lot of them. */
- discard_psymtab (pst);
+ discard_psymtab (objfile, pst);
/* Indicate that psymtab was thrown away. */
pst = (struct partial_symtab *) NULL;
each program csect, because their text
sections need not be adjacent. */
xcoff_end_psymtab
- (pst, psymtab_include_list, includes_used,
- symnum_before, dependency_list,
+ (objfile, pst, psymtab_include_list,
+ includes_used, symnum_before, dependency_list,
dependencies_used, textlow_not_set);
includes_used = 0;
dependencies_used = 0;
if (pst)
{
- xcoff_end_psymtab (pst, psymtab_include_list, includes_used,
- symnum_before, dependency_list,
- dependencies_used, textlow_not_set);
+ xcoff_end_psymtab (objfile, pst, psymtab_include_list,
+ includes_used, symnum_before,
+ dependency_list, dependencies_used,
+ textlow_not_set);
includes_used = 0;
dependencies_used = 0;
}
if (pst)
{
- xcoff_end_psymtab (pst, psymtab_include_list, includes_used,
+ xcoff_end_psymtab (objfile, pst, psymtab_include_list, includes_used,
ssymnum, dependency_list,
dependencies_used, textlow_not_set);
}
&psym_functions
};
+/* Same as xcoff_get_n_import_files, but for core files. */
+
+static int
+xcoff_get_core_n_import_files (bfd *abfd)
+{
+ asection *sect = bfd_get_section_by_name (abfd, ".ldinfo");
+ gdb_byte buf[4];
+ file_ptr offset = 0;
+ int n_entries = 0;
+
+ if (sect == NULL)
+ return -1; /* Not a core file. */
+
+ for (offset = 0; offset < bfd_get_section_size (sect);)
+ {
+ int next;
+
+ n_entries++;
+
+ if (!bfd_get_section_contents (abfd, sect, buf, offset, 4))
+ return -1;
+ next = bfd_get_32 (abfd, buf);
+ if (next == 0)
+ break; /* This is the last entry. */
+ offset += next;
+ }
+
+ /* Return the number of entries, excluding the first one, which is
+ the path to the executable that produced this core file. */
+ return n_entries - 1;
+}
+
+/* Return the number of import files (shared libraries) that the given
+ BFD depends on. Return -1 if this number could not be computed. */
+
+int
+xcoff_get_n_import_files (bfd *abfd)
+{
+ asection *sect = bfd_get_section_by_name (abfd, ".loader");
+ gdb_byte buf[4];
+ int l_nimpid;
+
+ /* If the ".loader" section does not exist, the objfile is probably
+ not an executable. Might be a core file... */
+ if (sect == NULL)
+ return xcoff_get_core_n_import_files (abfd);
+
+ /* The number of entries in the Import Files Table is stored in
+ field l_nimpid. This field is always at offset 16, and is
+ always 4 bytes long. Read those 4 bytes. */
+
+ if (!bfd_get_section_contents (abfd, sect, buf, 16, 4))
+ return -1;
+ l_nimpid = bfd_get_32 (abfd, buf);
+
+ /* By convention, the first entry is the default LIBPATH value
+ to be used by the system loader, so it does not count towards
+ the number of import files. */
+ return l_nimpid - 1;
+}
+
/* Free the per-objfile xcoff data. */
static void