/* Read AIX xcoff symbol tables and convert to internal format, for GDB.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994
Free Software Foundation, Inc.
Derived from coffread.c, dbxread.c, and a lot of hacking.
Contributed by IBM Corporation.
#include <sys/stat.h>
#include <sys/debug.h>
+#include "coff/internal.h" /* FIXME, internal data from BFD */
+#include "libcoff.h" /* FIXME, internal data from BFD */
+#include "coff/rs6000.h" /* FIXME, raw file-format guts of xcoff */
+
#include "symtab.h"
#include "gdbtypes.h"
#include "symfile.h"
#include "stabsread.h"
#include "complaints.h"
-#include "coff/internal.h" /* FIXME, internal data from BFD */
-#include "libcoff.h" /* FIXME, internal data from BFD */
-#include "coff/rs6000.h" /* FIXME, raw file-format guts of xcoff */
-
/* For interface with stabsread.c. */
#include "aout/stab_gnu.h"
static void
xcoff_new_init PARAMS ((struct objfile *));
-#ifdef __STDC__
-struct section_offset;
-#endif
-
static void
-xcoff_symfile_read PARAMS ((struct objfile *, struct section_offset *, int));
+xcoff_symfile_read PARAMS ((struct objfile *, struct section_offsets *, int));
static void
xcoff_symfile_finish PARAMS ((struct objfile *));
static int inclLength; /* table length */
static int inclDepth; /* nested include depth */
+static void allocate_include_entry PARAMS ((void));
static void
record_include_begin (cs)
}
++inclDepth;
- /* allocate an include file, or make room for the new entry */
- if (inclLength == 0) {
- inclTable = (InclTable*)
- xmalloc (sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH);
- memset (inclTable, '\0', sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH);
- inclLength = INITIAL_INCLUDE_TABLE_LENGTH;
- inclIndx = 0;
- }
- else if (inclIndx >= inclLength) {
- inclLength += INITIAL_INCLUDE_TABLE_LENGTH;
- inclTable = (InclTable*)
- xrealloc (inclTable, sizeof (InclTable) * inclLength);
- memset (inclTable+inclLength-INITIAL_INCLUDE_TABLE_LENGTH,
- '\0', sizeof (InclTable)*INITIAL_INCLUDE_TABLE_LENGTH);
- }
+ allocate_include_entry ();
inclTable [inclIndx].name = cs->c_name;
inclTable [inclIndx].begin = cs->c_value;
}
-
static void
record_include_end (cs)
struct coff_symbol *cs;
complain (&msg);
}
+ allocate_include_entry ();
+
pTbl = &inclTable [inclIndx];
pTbl->end = cs->c_value;
++inclIndx;
}
+static void
+allocate_include_entry ()
+{
+ if (inclTable == NULL)
+ {
+ inclTable = (InclTable *)
+ xmalloc (sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH);
+ memset (inclTable,
+ '\0', sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH);
+ inclLength = INITIAL_INCLUDE_TABLE_LENGTH;
+ inclIndx = 0;
+ }
+ else if (inclIndx >= inclLength)
+ {
+ inclLength += INITIAL_INCLUDE_TABLE_LENGTH;
+ inclTable = (InclTable *)
+ xrealloc (inclTable, sizeof (InclTable) * inclLength);
+ memset (inclTable + inclLength - INITIAL_INCLUDE_TABLE_LENGTH,
+ '\0', sizeof (InclTable)*INITIAL_INCLUDE_TABLE_LENGTH);
+ }
+}
-/* given the start and end addresses of a compilation unit (or a csect, at times)
- process its lines and create appropriate line vectors. */
+/* given the start and end addresses of a compilation unit (or a csect,
+ at times) process its lines and create appropriate line vectors. */
static void
process_linenos (start, end)
static int symname_alloced = 0;
+/* Next symbol to read. Pointer into raw seething symbol table. */
+
+static char *raw_symbol;
+
+/* This is the function which stabsread.c calls to get symbol
+ continuations. */
+static char *
+xcoff_next_symbol_text ()
+{
+ struct internal_syment symbol;
+ static struct complaint msg =
+ {"Unexpected symbol continuation", 0, 0};
+ char *retval;
+
+ bfd_coff_swap_sym_in (current_objfile->obfd, raw_symbol, &symbol);
+ if (symbol.n_zeroes)
+ {
+ complain (&msg);
+
+ /* Return something which points to '\0' and hope the symbol reading
+ code does something reasonable. */
+ retval = "";
+ }
+ else if (symbol.n_sclass & 0x80)
+ {
+ retval = debugsec + symbol.n_offset;
+ raw_symbol += coff_data (current_objfile->obfd)->local_symesz;
+ ++symnum;
+ }
+ else
+ {
+ complain (&msg);
+
+ /* Return something which points to '\0' and hope the symbol reading
+ code does something reasonable. */
+ retval = "";
+ }
+ return retval;
+}
+
/* read the whole symbol table of a given bfd. */
static void
int nsyms; /* # of symbols */
{
bfd *abfd = objfile->obfd;
- char *raw_symbol; /* Pointer into raw seething symbol table */
char *raw_auxptr; /* Pointer to first raw aux entry for sym */
sec_ptr textsec; /* Pointer to text section */
TracebackInfo *ptb; /* Pointer to traceback table */
struct internal_syment symbol[1];
- union internal_auxent main_aux[1];
+ union internal_auxent main_aux;
struct coff_symbol cs[1];
CORE_ADDR file_start_addr = 0;
CORE_ADDR file_end_addr = 0;
printf_unfiltered ("Unable to locate text section!\n");
}
+ next_symbol_text_func = xcoff_next_symbol_text;
+
while (symnum < nsyms) {
QUIT; /* make this command interruptable. */
/* if explicitly specified as a function, treat is as one. */
if (ISFCN(cs->c_type) && cs->c_sclass != C_TPDEF) {
bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
- main_aux);
+ 0, cs->c_naux, &main_aux);
goto function_entry_point;
}
/* dealing with a symbol with a csect entry. */
# define CSECT(PP) ((PP)->x_csect)
-# define CSECT_LEN(PP) (CSECT(PP).x_scnlen)
+# define CSECT_LEN(PP) (CSECT(PP).x_scnlen.l)
# define CSECT_ALIGN(PP) (SMTYP_ALIGN(CSECT(PP).x_smtyp))
# define CSECT_SMTYP(PP) (SMTYP_SMTYP(CSECT(PP).x_smtyp))
# define CSECT_SCLAS(PP) (CSECT(PP).x_smclas)
/* Convert the auxent to something we can access. */
bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
- main_aux);
+ 0, cs->c_naux, &main_aux);
- switch (CSECT_SMTYP (main_aux)) {
+ switch (CSECT_SMTYP (&main_aux)) {
case XTY_ER :
continue; /* ignore all external references. */
case XTY_SD : /* a section description. */
{
- switch (CSECT_SCLAS (main_aux)) {
+ switch (CSECT_SCLAS (&main_aux)) {
case XMC_PR : /* a `.text' csect. */
{
/* If this is the very first csect seen, basically `__start'. */
if (just_started) {
- first_object_file_end = cs->c_value + CSECT_LEN (main_aux);
+ first_object_file_end = cs->c_value + CSECT_LEN (&main_aux);
just_started = 0;
}
file_start_addr = cs->c_value;
- file_end_addr = cs->c_value + CSECT_LEN (main_aux);
+ file_end_addr = cs->c_value + CSECT_LEN (&main_aux);
if (cs->c_name && cs->c_name[0] == '.') {
last_csect_name = cs->c_name;
break; /* switch CSECT_SCLAS() */
case XTY_LD :
-
- /* a function entry point. */
- if (CSECT_SCLAS (main_aux) == XMC_PR) {
-function_entry_point:
+ switch (CSECT_SCLAS (&main_aux))
+ {
+ case XMC_PR:
+ /* a function entry point. */
+ function_entry_point:
RECORD_MINIMAL_SYMBOL (cs->c_name, cs->c_value, mst_text,
symname_alloced, cs->c_secnum, objfile);
- fcn_line_offset = main_aux->x_sym.x_fcnary.x_fcn.x_lnnoptr;
+ fcn_line_offset = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
fcn_start_addr = cs->c_value;
/* save the function header info, which will be used
when `.bf' is seen. */
fcn_cs_saved = *cs;
- fcn_aux_saved = *main_aux;
+ fcn_aux_saved = main_aux;
ptb = NULL;
cs->c_value + ptb->fsize, objfile);
}
continue;
- }
- /* shared library function trampoline code entry point. */
- else if (CSECT_SCLAS (main_aux) == XMC_GL) {
- /* record trampoline code entries as mst_unknown symbol. When we
- lookup mst symbols, we will choose mst_text over mst_unknown. */
+ case XMC_GL:
+ /* shared library function trampoline code entry point. */
-#if 1
- /* After the implementation of incremental loading of shared
- libraries, we don't want to access trampoline entries. This
- approach has a consequence of the necessity to bring the whole
- shared library at first, in order do anything with it (putting
- breakpoints, using malloc, etc). On the other side, this is
- consistient with gdb's behaviour on a SUN platform. */
-
- /* Trying to prefer *real* function entry over its trampoline,
- by assigning `mst_unknown' type to trampoline entries fails.
- Gdb treats those entries as chars. FIXME. */
-
- /* Recording this entry is necessary. Single stepping relies on
- this vector to get an idea about function address boundaries. */
-
- prim_record_minimal_symbol_and_info
- ("<trampoline>", cs->c_value, mst_unknown,
- (char *)NULL, cs->c_secnum, objfile);
-#else
-
- /* record trampoline code entries as mst_unknown symbol. When we
- lookup mst symbols, we will choose mst_text over mst_unknown. */
+ /* record trampoline code entries as mst_solib_trampoline symbol.
+ When we lookup mst symbols, we will choose mst_text over
+ mst_solib_trampoline. */
+ RECORD_MINIMAL_SYMBOL (cs->c_name, cs->c_value,
+ mst_solib_trampoline,
+ symname_alloced, cs->c_secnum, objfile);
+ continue;
- RECORD_MINIMAL_SYMBOL (cs->c_name, cs->c_value, mst_unknown,
- symname_alloced, objfile);
-#endif
+ case XMC_DS:
+ /* The symbols often have the same names as debug symbols for
+ functions, and confuse lookup_symbol. */
continue;
+
+ default:
+ /* xlc puts each variable in a separate csect, so we get
+ an XTY_SD for each variable. But gcc puts several
+ variables in a csect, so that each variable only gets
+ an XTY_LD. We still need to record them. This will
+ typically be XMC_RW; I suspect XMC_RO and XMC_BS might
+ be possible too. */
+ break;
}
- break;
default : /* all other XTY_XXXs */
break;
/* XCOFF, according to the AIX 3.2 documentation, puts the filename
in cs->c_name. But xlc 1.3.0.2 has decided to do things the
standard COFF way and put it in the auxent. We use the auxent if
- there is one, otherwise use the name. Simple enough. */
- if (cs->c_naux > 0)
- filestring = coff_getfilename (&main_aux);
+ the symbol is ".file" and an auxent exists, otherwise use the symbol
+ itself. Simple enough. */
+ if (!strcmp (cs->c_name, ".file") && cs->c_naux > 0)
+ {
+ bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
+ 0, cs->c_naux, &main_aux);
+ filestring = coff_getfilename (&main_aux);
+ }
else
filestring = cs->c_name;
if (STREQ (cs->c_name, ".bf")) {
bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
- main_aux);
+ 0, cs->c_naux, &main_aux);
within_function = 1;
else if (STREQ (cs->c_name, ".ef")) {
bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
- main_aux);
+ 0, cs->c_naux, &main_aux);
/* the value of .ef is the address of epilogue code;
not useful for gdb */
/* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
contains number of lines to '}' */
- fcn_last_line = main_aux->x_sym.x_misc.x_lnsz.x_lnno;
+ fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
new = pop_context ();
if (context_stack_depth != 0)
error ("invalid symbol data; .bf/.ef/.bb/.eb symbol mismatch, at symbol %d.",
/* take aux entry and return its lineno */
symno++;
bfd_coff_swap_aux_in (symfile_bfd, symtbl+(symno*local_symesz),
- symbol->n_type, symbol->n_sclass, main_aux);
+ symbol->n_type, symbol->n_sclass,
+ 0, symbol->n_numaux, main_aux);
return main_aux->x_sym.x_misc.x_lnsz.x_lnno;
}
linetab = NULL;
}
\f
-/* dbx allows the text of a symbol name to be continued into the
- next symbol name! When such a continuation is encountered
- (a \ at the end of the text of a name)
- call this function to get the continuation. */
-/* So far, I haven't seen this happenning xlc output. I doubt we'll need this
- for xcoff. */
-
-#undef next_symbol_text
-#define next_symbol_text() \
- printf_unfiltered ("Gdb Error: symbol names on multiple lines not implemented.\n")
-
-
static void
xcoff_new_init (objfile)
struct objfile *objfile;
static void
xcoff_symfile_read (objfile, section_offset, mainline)
struct objfile *objfile;
- struct section_offset *section_offset;
+ struct section_offsets *section_offset;
int mainline;
{
int num_symbols; /* # of symbols */