Index: gdb/xcoffread.c |
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c |
index af93a4345b67f13584f3a14a7a63fe8a2a2e72f9..2fba510acf836be768bba11320aa5f45b7c8d272 100644 |
--- a/gdb/xcoffread.c |
+++ b/gdb/xcoffread.c |
@@ -1,5 +1,5 @@ |
/* 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. |
@@ -24,13 +24,12 @@ |
#include <sys/types.h> |
#include <fcntl.h> |
#include <ctype.h> |
-#include "gdb_string.h" |
+#include <string.h> |
-#include <sys/param.h> |
#ifdef HAVE_SYS_FILE_H |
#include <sys/file.h> |
#endif |
-#include "gdb_stat.h" |
+#include <sys/stat.h> |
#include "coff/internal.h" |
#include "libcoff.h" /* FIXME, internal data from BFD */ |
@@ -56,6 +55,10 @@ |
#include "aout/stab_gnu.h" |
+/* Key for XCOFF-associated data. */ |
+ |
+static const struct objfile_data *xcoff_objfile_data_key; |
+ |
/* We put a pointer to this structure in the read_symtab_private field |
of the psymtab. */ |
@@ -91,7 +94,7 @@ struct coff_symbol |
char *c_name; |
int c_symnum; /* Symbol number of this entry. */ |
int c_naux; /* 0 if syment only, 1 if syment + auxent. */ |
- long c_value; |
+ CORE_ADDR c_value; |
unsigned char c_sclass; |
int c_secnum; |
unsigned int c_type; |
@@ -150,6 +153,12 @@ struct coff_symfile_info |
CORE_ADDR toc_offset; |
}; |
+/* Convenience macro to access the per-objfile XCOFF data. */ |
+ |
+#define XCOFF_DATA(objfile) \ |
+ ((struct coff_symfile_info *) objfile_data ((objfile), \ |
+ xcoff_objfile_data_key)) |
+ |
/* XCOFF names for dwarf sections. There is no compressed sections. */ |
static const struct dwarf2_debug_sections dwarf2_xcoff_names = { |
@@ -210,9 +219,6 @@ static void xcoff_new_init (struct objfile *); |
static void xcoff_symfile_finish (struct objfile *); |
-static void xcoff_symfile_offsets (struct objfile *, |
- struct section_addr_info *addrs); |
- |
static char *coff_getfilename (union internal_auxent *, struct objfile *); |
static void read_symbol (struct internal_syment *, int); |
@@ -224,7 +230,7 @@ static CORE_ADDR read_symbol_nvalue (int); |
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 **); |
@@ -268,7 +274,7 @@ find_targ_sec (bfd *abfd, asection *sect, void *obj) |
else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD) |
*args->resultp = SECT_OFF_DATA (objfile); |
else |
- *args->resultp = sect->index; |
+ *args->resultp = gdb_bfd_section_index (abfd, sect); |
*args->bfd_sect = sect; |
} |
} |
@@ -431,6 +437,7 @@ arrange_linetable (struct linetable *oldLineTb) |
struct linetable_entry *fentry; /* function entry vector */ |
int fentry_size; /* # of function entries */ |
struct linetable *newLineTb; /* new line table */ |
+ int extra_lines = 0; |
#define NUM_OF_FUNCTIONS 20 |
@@ -452,6 +459,12 @@ arrange_linetable (struct linetable *oldLineTb) |
fentry[function_count].line = ii; |
fentry[function_count].pc = oldLineTb->item[ii].pc; |
++function_count; |
+ |
+ /* If the function was compiled with XLC, we may have to add an |
+ extra line entry later. Reserve space for that. */ |
+ if (ii + 1 < oldLineTb->nitems |
+ && oldLineTb->item[ii].pc != oldLineTb->item[ii + 1].pc) |
+ extra_lines++; |
} |
} |
@@ -468,7 +481,7 @@ arrange_linetable (struct linetable *oldLineTb) |
newLineTb = (struct linetable *) |
xmalloc |
(sizeof (struct linetable) + |
- (oldLineTb->nitems - function_count) * sizeof (struct linetable_entry)); |
+ (oldLineTb->nitems - function_count + extra_lines) * sizeof (struct linetable_entry)); |
/* If line table does not start with a function beginning, copy up until |
a function begin. */ |
@@ -483,13 +496,26 @@ arrange_linetable (struct linetable *oldLineTb) |
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. */ |
+ jj = fentry[ii].line; |
+ if (jj + 1 < oldLineTb->nitems |
+ && oldLineTb->item[jj].pc != oldLineTb->item[jj + 1].pc) |
+ { |
+ newLineTb->item[newline] = oldLineTb->item[jj]; |
+ newLineTb->item[newline].line = oldLineTb->item[jj + 1].line; |
+ newline++; |
+ } |
+ |
for (jj = fentry[ii].line + 1; |
jj < oldLineTb->nitems && oldLineTb->item[jj].line != 0; |
++jj, ++newline) |
newLineTb->item[newline] = oldLineTb->item[jj]; |
} |
xfree (fentry); |
- newLineTb->nitems = oldLineTb->nitems - function_count; |
+ /* The number of items in the line table must include these |
+ extra lines which were added in case of XLC compiled functions. */ |
+ newLineTb->nitems = oldLineTb->nitems - function_count + extra_lines; |
return newLineTb; |
} |
@@ -586,6 +612,9 @@ allocate_include_entry (void) |
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. */ |
@@ -593,9 +622,8 @@ static void |
process_linenos (CORE_ADDR start, CORE_ADDR end) |
{ |
int offset, ii; |
- file_ptr max_offset = |
- ((struct coff_symfile_info *) this_symtab_psymtab->objfile |
- ->deprecated_sym_private)->max_lineno_offset; |
+ file_ptr max_offset |
+ = XCOFF_DATA (this_symtab_objfile)->max_lineno_offset; |
/* subfile structure for the main compilation unit. */ |
struct subfile main_subfile; |
@@ -628,7 +656,7 @@ process_linenos (CORE_ADDR start, CORE_ADDR end) |
/* 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) |
@@ -643,7 +671,7 @@ process_linenos (CORE_ADDR start, CORE_ADDR end) |
start, 0, &main_source_baseline); |
} |
- if (strcmp (inclTable[ii].name, last_source_file) == 0) |
+ 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. */ |
@@ -789,7 +817,7 @@ return_after_cleanup: |
} |
static void |
-aix_process_linenos (void) |
+aix_process_linenos (struct objfile *objfile) |
{ |
/* There is no linenos to read if there are only dwarf info. */ |
if (this_symtab_psymtab == NULL) |
@@ -816,7 +844,7 @@ enter_line_range (struct subfile *subfile, unsigned beginoffset, |
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; |
@@ -829,9 +857,7 @@ enter_line_range (struct subfile *subfile, unsigned beginoffset, |
if (endoffset == 0 && startaddr == 0 && endaddr == 0) |
return; |
curoffset = beginoffset; |
- limit_offset = |
- ((struct coff_symfile_info *) objfile->deprecated_sym_private) |
- ->max_lineno_offset; |
+ limit_offset = XCOFF_DATA (objfile)->max_lineno_offset; |
if (endoffset != 0) |
{ |
@@ -884,7 +910,7 @@ enter_line_range (struct subfile *subfile, unsigned beginoffset, |
text address for the file, and SIZE is the number of bytes of text. */ |
#define complete_symtab(name, start_addr) { \ |
- last_source_file = xstrdup (name); \ |
+ set_last_source_file (name); \ |
last_source_start_addr = start_addr; \ |
} |
@@ -897,11 +923,16 @@ enter_line_range (struct subfile *subfile, unsigned beginoffset, |
/* Create a new minimal symbol (using prim_record_minimal_symbol_and_info). |
+ Creation of all new minimal symbols should go through this function |
+ rather than calling the various prim_record_[...] functions in order |
+ to make sure that all symbol addresses get properly relocated. |
+ |
Arguments are: |
NAME - the symbol's name (but if NAME starts with a period, that |
leading period is discarded). |
- ADDRESS - the symbol's address. |
+ ADDRESS - the symbol's address, prior to relocation. This function |
+ relocates the address before recording the minimal symbol. |
MS_TYPE - the symbol's type. |
N_SCNUM - the symbol's XCOFF section number. |
OBJFILE - the objfile associated with the minimal symbol. */ |
@@ -912,15 +943,15 @@ record_minimal_symbol (const char *name, CORE_ADDR address, |
int n_scnum, |
struct objfile *objfile) |
{ |
- int secnum; |
- asection *bfd_sect; |
+ int section = secnum_to_section (n_scnum, objfile); |
if (name[0] == '.') |
++name; |
- xcoff_secnum_to_sections (n_scnum, objfile, &bfd_sect, &secnum); |
+ address += ANOFFSET (objfile->section_offsets, section); |
prim_record_minimal_symbol_and_info (name, address, ms_type, |
- secnum, bfd_sect, objfile); |
+ secnum_to_section (n_scnum, objfile), |
+ objfile); |
} |
/* xcoff has static blocks marked in `.bs', `.es' pairs. They cannot be |
@@ -951,8 +982,8 @@ xcoff_next_symbol_text (struct objfile *objfile) |
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) |
@@ -965,9 +996,7 @@ xcoff_next_symbol_text (struct objfile *objfile) |
} |
else if (symbol.n_sclass & 0x80) |
{ |
- retval = ((struct coff_symfile_info *) |
- objfile->deprecated_sym_private)->debugsec |
- + symbol.n_offset; |
+ retval = XCOFF_DATA (objfile)->debugsec + symbol.n_offset; |
raw_symbol += coff_data (objfile->obfd)->local_symesz; |
++symnum; |
} |
@@ -985,15 +1014,13 @@ xcoff_next_symbol_text (struct objfile *objfile) |
/* 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. */ |
- char *strtbl = |
- ((struct coff_symfile_info *) objfile->deprecated_sym_private)->strtbl; |
- char *debugsec = |
- ((struct coff_symfile_info *) objfile->deprecated_sym_private)->debugsec; |
+ struct coff_symfile_info *xcoff = XCOFF_DATA (objfile); |
+ char *strtbl = xcoff->strtbl; |
+ char *debugsec = xcoff->debugsec; |
const char *debugfmt = bfd_xcoff_is_xcoff64 (abfd) ? "XCOFF64" : "XCOFF"; |
struct internal_syment symbol[1]; |
@@ -1006,7 +1033,7 @@ read_xcoff_symtab (struct partial_symtab *pst) |
unsigned int max_symnum; |
int just_started = 1; |
int depth = 0; |
- int fcn_start_addr = 0; |
+ CORE_ADDR fcn_start_addr = 0; |
struct coff_symbol fcn_stab_saved = { 0 }; |
@@ -1019,12 +1046,13 @@ read_xcoff_symtab (struct partial_symtab *pst) |
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. */ |
local_symesz = coff_data (abfd)->local_symesz; |
- last_source_file = NULL; |
+ set_last_source_file (NULL); |
last_csect_name = 0; |
start_stabs (); |
@@ -1035,9 +1063,7 @@ read_xcoff_symtab (struct partial_symtab *pst) |
symnum + ((struct symloc *) pst->read_symtab_private)->numsyms; |
first_object_file_end = 0; |
- raw_symbol = |
- ((struct coff_symfile_info *) objfile->deprecated_sym_private)->symtbl |
- + symnum * local_symesz; |
+ raw_symbol = xcoff->symtbl + symnum * local_symesz; |
while (symnum < max_symnum) |
{ |
@@ -1114,7 +1140,7 @@ read_xcoff_symtab (struct partial_symtab *pst) |
if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE) |
{ |
- if (last_source_file) |
+ if (get_last_source_file ()) |
{ |
pst->symtab = end_symtab (cur_src_end_addr, objfile, |
SECT_OFF_TEXT (objfile)); |
@@ -1483,7 +1509,7 @@ read_xcoff_symtab (struct partial_symtab *pst) |
} |
} |
- if (last_source_file) |
+ if (get_last_source_file ()) |
{ |
struct symtab *s; |
@@ -1507,8 +1533,8 @@ read_xcoff_symtab (struct partial_symtab *pst) |
#define SYMNAME_ALLOC(NAME, ALLOCED) \ |
- ((ALLOCED) ? (NAME) : obsavestring ((NAME), strlen (NAME), \ |
- &objfile->objfile_obstack)) |
+ ((ALLOCED) ? (NAME) : obstack_copy0 (&objfile->objfile_obstack, \ |
+ (NAME), strlen (NAME))) |
/* process one xcoff symbol. */ |
@@ -1541,7 +1567,7 @@ process_xcoff_symbol (struct coff_symbol *cs, struct objfile *objfile) |
if (name[0] == '.') |
++name; |
- memset (sym, '\0', sizeof (struct symbol)); |
+ initialize_symbol (sym); |
/* default assumptions */ |
SYMBOL_VALUE_ADDRESS (sym) = cs->c_value + off; |
@@ -1557,7 +1583,7 @@ process_xcoff_symbol (struct coff_symbol *cs, struct objfile *objfile) |
SYMBOL_SET_LINKAGE_NAME (sym, SYMNAME_ALLOC (name, symname_alloced)); |
SYMBOL_TYPE (sym) = objfile_type (objfile)->nodebug_text_symbol; |
- SYMBOL_CLASS (sym) = LOC_BLOCK; |
+ SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK; |
SYMBOL_DUP (sym, sym2); |
if (cs->c_sclass == C_EXT) |
@@ -1661,9 +1687,8 @@ coff_getfilename (union internal_auxent *aux_entry, struct objfile *objfile) |
static char buffer[BUFSIZ]; |
if (aux_entry->x_file.x_n.x_zeroes == 0) |
- strcpy (buffer, ((struct coff_symfile_info *) |
- objfile->deprecated_sym_private)->strtbl |
- + aux_entry->x_file.x_n.x_offset); |
+ strcpy (buffer, (XCOFF_DATA (objfile)->strtbl |
+ + aux_entry->x_file.x_n.x_offset)); |
else |
{ |
strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN); |
@@ -1676,11 +1701,9 @@ coff_getfilename (union internal_auxent *aux_entry, struct objfile *objfile) |
static void |
read_symbol (struct internal_syment *symbol, int symno) |
{ |
- int nsyms |
- = ((struct coff_symfile_info *) |
- this_symtab_psymtab->objfile->deprecated_sym_private)->symtbl_num_syms; |
- char *stbl = ((struct coff_symfile_info *) |
- this_symtab_psymtab->objfile->deprecated_sym_private)->symtbl; |
+ struct coff_symfile_info *xcoff = XCOFF_DATA (this_symtab_objfile); |
+ int nsyms = xcoff->symtbl_num_syms; |
+ char *stbl = xcoff->symtbl; |
if (symno < 0 || symno >= nsyms) |
{ |
@@ -1689,7 +1712,7 @@ read_symbol (struct internal_syment *symbol, int symno) |
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); |
} |
@@ -1712,11 +1735,10 @@ read_symbol_nvalue (int symno) |
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 = |
- (struct coff_symfile_info *)objfile->deprecated_sym_private; |
+ struct coff_symfile_info *info = XCOFF_DATA (objfile); |
int nsyms = info->symtbl_num_syms; |
char *stbl = info->symtbl; |
char *strtbl = info->strtbl; |
@@ -1803,10 +1825,8 @@ find_linenos (struct bfd *abfd, struct bfd_section *asect, void *vpinfo) |
info->max_lineno_offset = maxoff; |
} |
-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; |
@@ -1837,7 +1857,7 @@ xcoff_psymtab_to_symtab_1 (struct partial_symtab *pst) |
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) |
@@ -1847,7 +1867,7 @@ xcoff_psymtab_to_symtab_1 (struct partial_symtab *pst) |
buildsym_init (); |
old_chain = make_cleanup (really_free_pendings, 0); |
- read_xcoff_symtab (pst); |
+ read_xcoff_symtab (objfile, pst); |
do_cleanups (old_chain); |
} |
@@ -1855,47 +1875,38 @@ xcoff_psymtab_to_symtab_1 (struct partial_symtab *pst) |
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. */ |
+ Be verbose about it if the user wants that. SELF is not NULL. */ |
static void |
-xcoff_psymtab_to_symtab (struct partial_symtab *pst) |
+xcoff_read_symtab (struct partial_symtab *self, struct objfile *objfile) |
{ |
- bfd *sym_bfd; |
- |
- if (!pst) |
- return; |
- |
- if (pst->readin) |
+ if (self->readin) |
{ |
fprintf_unfiltered |
(gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n", |
- pst->filename); |
+ self->filename); |
return; |
} |
- if (((struct symloc *) pst->read_symtab_private)->numsyms != 0 |
- || pst->number_of_dependencies) |
+ if (((struct symloc *) self->read_symtab_private)->numsyms != 0 |
+ || self->number_of_dependencies) |
{ |
/* Print the message now, before reading the string table, |
to avoid disconcerting pauses. */ |
if (info_verbose) |
{ |
- printf_filtered ("Reading in symbols for %s...", pst->filename); |
+ printf_filtered ("Reading in symbols for %s...", self->filename); |
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, self); |
/* 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) |
@@ -1919,16 +1930,16 @@ xcoff_new_init (struct objfile *objfile) |
static void |
xcoff_symfile_init (struct objfile *objfile) |
{ |
+ struct coff_symfile_info *xcoff; |
+ |
/* Allocate struct to keep track of the symfile. */ |
- objfile->deprecated_sym_private |
- = xmalloc (sizeof (struct coff_symfile_info)); |
+ xcoff = XNEW (struct coff_symfile_info); |
+ set_objfile_data (objfile, xcoff_objfile_data_key, xcoff); |
/* XCOFF objects may be reordered, so set OBJF_REORDERED. If we |
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 |
@@ -1939,11 +1950,6 @@ xcoff_symfile_init (struct objfile *objfile) |
static void |
xcoff_symfile_finish (struct objfile *objfile) |
{ |
- if (objfile->deprecated_sym_private != NULL) |
- { |
- xfree (objfile->deprecated_sym_private); |
- } |
- |
/* Start with a fresh include table for the next objfile. */ |
if (inclTable) |
{ |
@@ -1963,9 +1969,9 @@ init_stringtab (bfd *abfd, file_ptr offset, struct objfile *objfile) |
int val; |
unsigned char lengthbuf[4]; |
char *strtbl; |
+ struct coff_symfile_info *xcoff = XCOFF_DATA (objfile); |
- ((struct coff_symfile_info *) objfile->deprecated_sym_private)->strtbl |
- = NULL; |
+ xcoff->strtbl = NULL; |
if (bfd_seek (abfd, offset, SEEK_SET) < 0) |
error (_("cannot seek to string table in %s: %s"), |
@@ -1984,8 +1990,7 @@ init_stringtab (bfd *abfd, file_ptr offset, struct objfile *objfile) |
as long as we have its symbol table around. */ |
strtbl = (char *) obstack_alloc (&objfile->objfile_obstack, length); |
- ((struct coff_symfile_info *) objfile->deprecated_sym_private)->strtbl |
- = strtbl; |
+ xcoff->strtbl = strtbl; |
/* Copy length buffer, the first byte is usually zero and is |
used for stabs with a name length of zero. */ |
@@ -2033,7 +2038,7 @@ xcoff_start_psymtab (struct objfile *objfile, |
result->read_symtab_private = obstack_alloc (&objfile->objfile_obstack, |
sizeof (struct symloc)); |
((struct symloc *) result->read_symtab_private)->first_symnum = first_symnum; |
- result->read_symtab = xcoff_psymtab_to_symtab; |
+ result->read_symtab = xcoff_read_symtab; |
/* Deduce the source language from the filename for this psymtab. */ |
psymtab_language = deduce_language_from_filename (filename); |
@@ -2050,13 +2055,13 @@ xcoff_start_psymtab (struct objfile *objfile, |
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 = |
@@ -2113,7 +2118,7 @@ xcoff_end_psymtab (struct partial_symtab *pst, const char **include_list, |
subpst->read_symtab = pst->read_symtab; |
} |
- sort_pst_symbols (pst); |
+ sort_pst_symbols (objfile, pst); |
if (num_includes == 0 |
&& number_dependencies == 0 |
@@ -2125,7 +2130,7 @@ xcoff_end_psymtab (struct partial_symtab *pst, const char **include_list, |
/* 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; |
@@ -2165,13 +2170,11 @@ swap_sym (struct internal_syment *symbol, union internal_auxent *aux, |
} |
else if (symbol->n_sclass & 0x80) |
{ |
- *name = ((struct coff_symfile_info *) |
- objfile->deprecated_sym_private)->debugsec + symbol->n_offset; |
+ *name = XCOFF_DATA (objfile)->debugsec + symbol->n_offset; |
} |
else |
{ |
- *name = ((struct coff_symfile_info *) |
- objfile->deprecated_sym_private)->strtbl + symbol->n_offset; |
+ *name = XCOFF_DATA (objfile)->strtbl + symbol->n_offset; |
} |
++*symnump; |
*raw += coff_data (objfile->obfd)->local_symesz; |
@@ -2243,15 +2246,13 @@ scan_xcoff_symtab (struct objfile *objfile) |
(struct partial_symtab **) alloca (dependencies_allocated * |
sizeof (struct partial_symtab *)); |
- last_source_file = NULL; |
+ set_last_source_file (NULL); |
abfd = objfile->obfd; |
next_symbol_text_func = xcoff_next_symbol_text; |
- sraw_symbol = ((struct coff_symfile_info *) |
- objfile->deprecated_sym_private)->symtbl; |
- nsyms = ((struct coff_symfile_info *) |
- objfile->deprecated_sym_private)->symtbl_num_syms; |
+ sraw_symbol = XCOFF_DATA (objfile)->symtbl; |
+ nsyms = XCOFF_DATA (objfile)->symtbl_num_syms; |
ssymnum = 0; |
while (ssymnum < nsyms) |
{ |
@@ -2319,8 +2320,8 @@ scan_xcoff_symtab (struct objfile *objfile) |
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; |
@@ -2362,12 +2363,10 @@ scan_xcoff_symtab (struct objfile *objfile) |
/* Data variables are recorded in the minimal symbol |
table, except for section symbols. */ |
if (*namestring != '.') |
- prim_record_minimal_symbol_and_info |
+ record_minimal_symbol |
(namestring, symbol.n_value, |
sclass == C_HIDEXT ? mst_file_data : mst_data, |
- secnum_to_section (symbol.n_scnum, objfile), |
- secnum_to_bfd_section (symbol.n_scnum, objfile), |
- objfile); |
+ symbol.n_scnum, objfile); |
break; |
case XMC_TC0: |
@@ -2440,12 +2439,10 @@ scan_xcoff_symtab (struct objfile *objfile) |
typically be XMC_RW; I suspect XMC_RO and |
XMC_BS might be possible too. */ |
if (*namestring != '.') |
- prim_record_minimal_symbol_and_info |
+ record_minimal_symbol |
(namestring, symbol.n_value, |
sclass == C_HIDEXT ? mst_file_data : mst_data, |
- secnum_to_section (symbol.n_scnum, objfile), |
- secnum_to_bfd_section (symbol.n_scnum, objfile), |
- objfile); |
+ symbol.n_scnum, objfile); |
break; |
} |
break; |
@@ -2458,12 +2455,10 @@ scan_xcoff_symtab (struct objfile *objfile) |
/* Common variables are recorded in the minimal symbol |
table, except for section symbols. */ |
if (*namestring != '.') |
- prim_record_minimal_symbol_and_info |
+ record_minimal_symbol |
(namestring, symbol.n_value, |
sclass == C_HIDEXT ? mst_file_bss : mst_bss, |
- secnum_to_section (symbol.n_scnum, objfile), |
- secnum_to_bfd_section (symbol.n_scnum, objfile), |
- objfile); |
+ symbol.n_scnum, objfile); |
break; |
} |
break; |
@@ -2496,9 +2491,10 @@ scan_xcoff_symtab (struct objfile *objfile) |
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; |
} |
@@ -2920,7 +2916,7 @@ scan_xcoff_symtab (struct objfile *objfile) |
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); |
} |
@@ -2930,8 +2926,7 @@ scan_xcoff_symtab (struct objfile *objfile) |
Another place to obtain this information would be file auxiliary |
header. */ |
- ((struct coff_symfile_info *) objfile->deprecated_sym_private)->toc_offset |
- = toc_offset; |
+ XCOFF_DATA (objfile)->toc_offset = toc_offset; |
} |
/* Return the toc offset value for a given objfile. */ |
@@ -2940,8 +2935,7 @@ CORE_ADDR |
xcoff_get_toc_offset (struct objfile *objfile) |
{ |
if (objfile) |
- return ((struct coff_symfile_info *) |
- objfile->deprecated_sym_private)->toc_offset; |
+ return XCOFF_DATA (objfile)->toc_offset; |
return 0; |
} |
@@ -2964,12 +2958,12 @@ xcoff_initial_scan (struct objfile *objfile, int symfile_flags) |
file_ptr symtab_offset; /* symbol table and */ |
file_ptr stringtab_offset; /* string table file offsets */ |
struct coff_symfile_info *info; |
- char *name; |
+ const char *name; |
unsigned int size; |
- info = (struct coff_symfile_info *) objfile->deprecated_sym_private; |
+ info = XCOFF_DATA (objfile); |
symfile_bfd = abfd = objfile->obfd; |
- name = objfile->name; |
+ name = objfile_name (objfile); |
num_symbols = bfd_get_symcount (abfd); /* # of symbols */ |
symtab_offset = obj_sym_filepos (abfd); /* symbol table file offset */ |
@@ -2989,7 +2983,7 @@ xcoff_initial_scan (struct objfile *objfile, int symfile_flags) |
{ |
struct bfd_section *secp; |
bfd_size_type length; |
- char *debugsec = NULL; |
+ bfd_byte *debugsec = NULL; |
secp = bfd_get_section_by_name (abfd, ".debug"); |
if (secp) |
@@ -2997,20 +2991,16 @@ xcoff_initial_scan (struct objfile *objfile, int symfile_flags) |
length = bfd_section_size (abfd, secp); |
if (length) |
{ |
- debugsec = |
- (char *) obstack_alloc (&objfile->objfile_obstack, length); |
+ debugsec = obstack_alloc (&objfile->objfile_obstack, length); |
- if (!bfd_get_section_contents (abfd, secp, debugsec, |
- (file_ptr) 0, length)) |
+ if (!bfd_get_full_section_contents (abfd, secp, &debugsec)) |
{ |
error (_("Error reading .debug section of `%s': %s"), |
name, bfd_errmsg (bfd_get_error ())); |
} |
} |
} |
- ((struct coff_symfile_info *) |
- objfile->deprecated_sym_private)->debugsec |
- = debugsec; |
+ info->debugsec = (char *) debugsec; |
} |
} |
@@ -3021,15 +3011,10 @@ xcoff_initial_scan (struct objfile *objfile, int symfile_flags) |
error (_("Error reading symbols from %s: %s"), |
name, bfd_errmsg (bfd_get_error ())); |
size = coff_data (abfd)->local_symesz * num_symbols; |
- ((struct coff_symfile_info *) objfile->deprecated_sym_private)->symtbl = |
- obstack_alloc (&objfile->objfile_obstack, size); |
- ((struct coff_symfile_info *) |
- objfile->deprecated_sym_private)->symtbl_num_syms |
- = num_symbols; |
- |
- val = bfd_bread (((struct coff_symfile_info *) |
- objfile->deprecated_sym_private)->symtbl, |
- size, abfd); |
+ info->symtbl = obstack_alloc (&objfile->objfile_obstack, size); |
+ info->symtbl_num_syms = num_symbols; |
+ |
+ val = bfd_bread (info->symtbl, size, abfd); |
if (val != size) |
perror_with_name (_("reading symbol table")); |
@@ -3069,46 +3054,40 @@ xcoff_initial_scan (struct objfile *objfile, int symfile_flags) |
static void |
xcoff_symfile_offsets (struct objfile *objfile, |
- struct section_addr_info *addrs) |
+ const struct section_addr_info *addrs) |
{ |
- asection *sect = NULL; |
- int i; |
+ const char *first_section_name; |
- objfile->num_sections = bfd_count_sections (objfile->obfd); |
- objfile->section_offsets = (struct section_offsets *) |
- obstack_alloc (&objfile->objfile_obstack, |
- SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); |
+ default_symfile_offsets (objfile, addrs); |
- /* Initialize the section indexes for future use. */ |
- sect = bfd_get_section_by_name (objfile->obfd, ".text"); |
- if (sect) |
- objfile->sect_index_text = sect->index; |
+ /* Oneof the weird side-effects of default_symfile_offsets is that |
+ it sometimes sets some section indices to zero for sections that, |
+ in fact do not exist. See the body of default_symfile_offsets |
+ for more info on when that happens. Undo that, as this then allows |
+ us to test whether the associated section exists or not, and then |
+ access it quickly (without searching it again). */ |
- sect = bfd_get_section_by_name (objfile->obfd, ".data"); |
- if (sect) |
- objfile->sect_index_data = sect->index; |
+ if (objfile->num_sections == 0) |
+ return; /* Is that even possible? Better safe than sorry. */ |
- sect = bfd_get_section_by_name (objfile->obfd, ".bss"); |
- if (sect) |
- objfile->sect_index_bss = sect->index; |
+ first_section_name |
+ = bfd_section_name (objfile->obfd, objfile->sections[0].the_bfd_section); |
- sect = bfd_get_section_by_name (objfile->obfd, ".rodata"); |
- if (sect) |
- objfile->sect_index_rodata = sect->index; |
+ if (objfile->sect_index_text == 0 |
+ && strcmp (first_section_name, ".text") != 0) |
+ objfile->sect_index_text = -1; |
- for (i = 0; i < objfile->num_sections; ++i) |
- { |
- /* syms_from_objfile kindly subtracts from addr the |
- bfd_section_vma of the .text section. This strikes me as |
- wrong--whether the offset to be applied to symbol reading is |
- relative to the start address of the section depends on the |
- symbol format. In any event, this whole "addr" concept is |
- pretty broken (it doesn't handle any section but .text |
- sensibly), so just ignore the addr parameter and use 0. |
- rs6000-nat.c will set the correct section offsets via |
- objfile_relocate. */ |
- (objfile->section_offsets)->offsets[i] = 0; |
- } |
+ if (objfile->sect_index_data == 0 |
+ && strcmp (first_section_name, ".data") != 0) |
+ objfile->sect_index_data = -1; |
+ |
+ if (objfile->sect_index_bss == 0 |
+ && strcmp (first_section_name, ".bss") != 0) |
+ objfile->sect_index_bss = -1; |
+ |
+ if (objfile->sect_index_rodata == 0 |
+ && strcmp (first_section_name, ".rodata") != 0) |
+ objfile->sect_index_rodata = -1; |
} |
/* Register our ability to parse symbols for xcoff BFD files. */ |
@@ -3125,8 +3104,6 @@ static const struct sym_fns xcoff_sym_fns = |
xcoffread.c reads all the symbols and does in fact randomly access them |
(in C_BSTAT and line number processing). */ |
- bfd_target_xcoff_flavour, |
- |
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 */ |
@@ -3140,11 +3117,83 @@ static const struct sym_fns xcoff_sym_fns = |
&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 |
+xcoff_free_info (struct objfile *objfile, void *arg) |
+{ |
+ xfree (arg); |
+} |
+ |
/* Provide a prototype to silence -Wmissing-prototypes. */ |
extern initialize_file_ftype _initialize_xcoffread; |
void |
_initialize_xcoffread (void) |
{ |
- add_symtab_fns (&xcoff_sym_fns); |
+ add_symtab_fns (bfd_target_xcoff_flavour, &xcoff_sym_fns); |
+ |
+ xcoff_objfile_data_key = register_objfile_data_with_cleanup (NULL, |
+ xcoff_free_info); |
} |