/* Read coff symbol tables and convert to internal format, for GDB.
- Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996
Free Software Foundation, Inc.
Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "symtab.h"
#include "breakpoint.h"
#include "bfd.h"
-#include <obstack.h>
+#include "obstack.h"
-#include <string.h>
+#include "gdb_string.h"
+#include <ctype.h>
#include "coff/internal.h" /* Internal format of COFF symbols in BFD */
#include "libcoff.h" /* FIXME secret internal data from BFD */
file_ptr min_lineno_offset; /* Where in file lowest line#s are */
file_ptr max_lineno_offset; /* 1+last byte of line#s in file */
- asection *stabsect; /* Section pointer for .stab section */
+ CORE_ADDR textaddr; /* Addr of .text section. */
+ unsigned int textsize; /* Size of .text section. */
+ struct stab_section_list *stabsects; /* .stab sections. */
asection *stabstrsect; /* Section pointer for .stab section */
- asection *stabindexsect; /* Section pointer for .stab.index section */
char *stabstrdata;
};
static struct symbol *opaque_type_chain[HASHSIZE];
-#if 0
-/* The type of the function we are currently reading in. This is
- used by define_symbol to record the type of arguments to a function. */
-
-struct type *in_function_type;
-#endif
-
/* Complaints about various problems in the file being read */
struct complaint ef_complaint =
{"Unmatched .ef symbol(s) ignored starting at symnum %d", 0, 0};
+struct complaint ef_stack_complaint =
+ {"`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d", 0, 0};
+
+struct complaint eb_stack_complaint =
+ {"`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d", 0, 0};
+
struct complaint bf_no_aux_complaint =
{"`.bf' symbol %d has no aux entry", 0, 0};
static char *getsymname PARAMS ((struct internal_syment *));
+static char *coff_getfilename PARAMS ((union internal_auxent *));
+
static void free_stringtab PARAMS ((void));
static int init_stringtab PARAMS ((bfd *, long));
-kingdon). */
static void
-coff_locate_sections (ignore_abfd, sectp, csip)
- bfd *ignore_abfd;
+coff_locate_sections (abfd, sectp, csip)
+ bfd *abfd;
asection *sectp;
PTR csip;
{
register struct coff_symfile_info *csi;
+ const char *name;
csi = (struct coff_symfile_info *) csip;
- if (STREQ (sectp->name, ".stab"))
+ name = bfd_get_section_name (abfd, sectp);
+ if (STREQ (name, ".text"))
+ {
+ csi->textaddr = bfd_section_vma (abfd, sectp);
+ csi->textsize += bfd_section_size (abfd, sectp);
+ }
+ else if (strncmp (name, ".text", sizeof ".text" - 1) == 0)
{
- csi->stabsect = sectp;
+ csi->textsize += bfd_section_size (abfd, sectp);
}
- else if (STREQ (sectp->name, ".stabstr"))
+ else if (STREQ (name, ".stabstr"))
{
csi->stabstrsect = sectp;
}
- else if (STREQ (sectp->name, ".stab.index"))
+ else if (strncmp (name, ".stab", sizeof ".stab" - 1) == 0)
{
- csi->stabindexsect = sectp;
+ const char *s;
+
+ /* We can have multiple .stab sections if linked with
+ --split-by-reloc. */
+ for (s = name + sizeof ".stab" - 1; *s != '\0'; s++)
+ if (! isdigit (*s))
+ break;
+ if (*s == '\0')
+ {
+ struct stab_section_list *n, **pn;
+
+ n = ((struct stab_section_list *)
+ xmalloc (sizeof (struct stab_section_list)));
+ n->section = sectp;
+ n->next = NULL;
+ for (pn = &csi->stabsects; *pn != NULL; pn = &(*pn)->next)
+ ;
+ *pn = n;
+
+ /* This will be run after coffstab_build_psymtabs is called
+ in coff_symfile_read, at which point we no longer need
+ the information. */
+ make_cleanup (free, n);
+ }
}
}
subfiles->line_vector = line_vector;
subfiles->name = last_source_file;
- /* sort_pending is needed for amdcoff, at least.
- sort_linevec is needed for the SCO compiler. */
- symtab = end_symtab (current_source_end_addr, 1, 1, objfile, 0);
+ symtab = end_symtab (current_source_end_addr, objfile, 0);
if (symtab != NULL)
free_named_symtabs (symtab->filename);
coff_symfile_init (objfile)
struct objfile *objfile;
{
- bfd *abfd = objfile->obfd;
-
/* Allocate struct to keep track of stab reading. */
objfile->sym_stab_info = (PTR)
- xmmalloc (objfile -> md, sizeof (struct dbx_symfile_info));
+ xmmalloc (objfile->md, sizeof (struct dbx_symfile_info));
memset ((PTR) objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
/* Allocate struct to keep track of the symfile */
- objfile -> sym_private = xmmalloc (objfile -> md,
- sizeof (struct coff_symfile_info));
+ objfile->sym_private = xmmalloc (objfile->md,
+ sizeof (struct coff_symfile_info));
memset (objfile->sym_private, 0, sizeof (struct coff_symfile_info));
+ /* COFF 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);
}
int symtab_offset;
int stringtab_offset;
struct cleanup *back_to;
- int stabsize, stabstrsize;
+ int stabstrsize;
info = (struct coff_symfile_info *) objfile -> sym_private;
dbxinfo = (struct dbx_symfile_info *) objfile->sym_stab_info;
bfd_map_over_sections (abfd, coff_locate_sections, (PTR) info);
- if (info->stabsect)
+ if (info->stabsects)
{
/* FIXME: dubious. Why can't we use something normal like
bfd_get_section_contents? */
bfd_seek (abfd, abfd->where, 0);
- stabsize = bfd_section_size (abfd, info->stabsect);
stabstrsize = bfd_section_size (abfd, info->stabstrsect);
coffstab_build_psymtabs (objfile,
section_offsets,
mainline,
- info->stabsect->filepos, stabsize,
+ info->textaddr, info->textsize,
+ info->stabsects,
info->stabstrsect->filepos, stabstrsize);
}
in_source_file = 1;
break;
+ /* C_LABEL is used for labels and static functions. Including
+ it here allows gdb to see static functions when no debug
+ info is available. */
+ case C_LABEL:
case C_STAT:
if (cs->c_name[0] == '.')
{
break;
}
tmpaddr = reladdr;
- sec = SECT_OFF_BSS;
+ /* The address has already been relocated; make sure that
+ objfile_relocate doesn't relocate it again. */
+ sec = -2;
+ ms_type = cs->c_sclass == C_STAT ? mst_file_bss : mst_bss;
}
else
{
tmpaddr = cs->c_value;
if (cs->c_sclass != C_STAT)
tmpaddr += ANOFFSET (section_offsets, sec);
+
+ switch (sec)
+ {
+ case SECT_OFF_TEXT:
+ case SECT_OFF_RODATA:
+ ms_type =
+ cs->c_sclass == C_STAT ? mst_file_text : mst_text;
+ break;
+ case SECT_OFF_DATA:
+ ms_type =
+ cs->c_sclass == C_STAT ? mst_file_data : mst_data;
+ break;
+ case SECT_OFF_BSS:
+ ms_type =
+ cs->c_sclass == C_STAT ? mst_file_bss : mst_bss;
+ break;
+ default:
+ ms_type = mst_unknown;
+ break;
+ }
}
- switch (sec)
+ if (cs->c_name[0] != '@' /* Skip tdesc symbols */)
+ prim_record_minimal_symbol_and_info
+ (obsavestring (cs->c_name, strlen (cs->c_name),
+ &objfile->symbol_obstack),
+ tmpaddr,
+ ms_type,
+ NULL,
+ sec,
+ objfile);
+
+ if (SDB_TYPE (cs->c_type))
{
- case SECT_OFF_TEXT:
- case SECT_OFF_RODATA:
- ms_type = cs->c_sclass == C_STAT ? mst_file_text : mst_text;
- break;
- case SECT_OFF_DATA:
- ms_type = cs->c_sclass == C_STAT ? mst_file_data : mst_data;
- break;
- case SECT_OFF_BSS:
- ms_type = cs->c_sclass == C_STAT ? mst_file_bss : mst_bss;
- break;
- default:
- ms_type = mst_unknown;
- break;
+ struct symbol *sym;
+ sym = process_coff_symbol
+ (cs, &main_aux, section_offsets, objfile);
+ SYMBOL_VALUE (sym) = tmpaddr;
+ SYMBOL_SECTION (sym) = sec;
}
-
- record_minimal_symbol (cs->c_name, tmpaddr, ms_type, objfile);
}
-
- if (SDB_TYPE (cs->c_type))
- process_coff_symbol (cs, &main_aux, section_offsets, objfile);
break;
case C_FCN:
not useful for gdb. */
/* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
contains number of lines to '}' */
+
+ if (context_stack_depth <= 0)
+ { /* We attempted to pop an empty context stack */
+ complain (&ef_stack_complaint, cs->c_symnum);
+ within_function = 0;
+ break;
+ }
+
new = pop_context ();
/* Stack must be empty now. */
if (context_stack_depth > 0 || new == NULL)
}
else if (STREQ (cs->c_name, ".eb"))
{
+ if (context_stack_depth <= 0)
+ { /* We attempted to pop an empty context stack */
+ complain (&eb_stack_complaint, cs->c_symnum);
+ break;
+ }
+
new = pop_context ();
if (depth-- != new->depth)
{
val = bfd_read ((char *)lengthbuf, sizeof lengthbuf, 1, abfd);
length = bfd_h_get_32 (symfile_bfd, lengthbuf);
-
+
/* If no string table is needed, then the file may end immediately
after the symbols. Just return with `stringtab' set to null. */
if (val != sizeof lengthbuf || length < sizeof lengthbuf)
only the last component of the name. Result is in static storage and
is only good for temporary use. */
-char *
+static char *
coff_getfilename (aux_entry)
union internal_auxent *aux_entry;
{
register char *rawptr;
struct internal_lineno lptr;
+ if (!linetab)
+ return ;
if (file_offset < linetab_offset)
{
complain (&lineno_complaint, file_offset);
if (ISFCN (cs->c_type))
{
SYMBOL_VALUE (sym) += ANOFFSET (section_offsets, SECT_OFF_TEXT);
-#if 0
- /* FIXME: This has NOT been tested. The DBX version has.. */
- /* Generate a template for the type of this function. The
- types of the arguments will be added as we read the symbol
- table. */
- struct type *new = (struct type *)
- obstack_alloc (&objfile->symbol_obstack, sizeof (struct type));
-
- memcpy (new, lookup_function_type (decode_function_type (cs, cs->c_type, aux)),
- sizeof(struct type));
- SYMBOL_TYPE (sym) = new;
- in_function_type = SYMBOL_TYPE(sym);
-#else
SYMBOL_TYPE(sym) =
lookup_function_type (decode_function_type (cs, cs->c_type, aux));
-#endif
SYMBOL_CLASS (sym) = LOC_BLOCK;
if (cs->c_sclass == C_STAT)
case C_ARG:
SYMBOL_CLASS (sym) = LOC_ARG;
-#if 0
- /* FIXME: This has not been tested. */
- /* Add parameter to function. */
- add_param_to_type(&in_function_type,sym);
-#endif
add_symbol_to_list (sym, &local_symbols);
#if !defined (BELIEVE_PCC_PROMOTION)
if (TARGET_BYTE_ORDER == BIG_ENDIAN)
case T_DOUBLE:
return lookup_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
+ case T_LNGDBL:
+ return lookup_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
+
case T_STRUCT:
if (cs->c_naux != 1)
{
return type;
}
-struct section_offsets *
-coff_symfile_offsets (objfile, addr)
- struct objfile *objfile;
- CORE_ADDR addr;
-{
- struct section_offsets *section_offsets;
- int i;
-
- objfile->num_sections = SECT_OFF_MAX;
- section_offsets = (struct section_offsets *)
- obstack_alloc (&objfile -> psymbol_obstack,
- sizeof (struct section_offsets)
- + sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
-
- for (i = 0; i < SECT_OFF_MAX; i++)
- ANOFFSET (section_offsets, i) = addr;
-
- return section_offsets;
-}
-
/* Register our ability to parse symbols for coff BFD files. */
static struct sym_fns coff_sym_fns =
coff_symfile_init, /* sym_init: read initial info, setup for sym_read() */
coff_symfile_read, /* sym_read: read a symbol file into symtab */
coff_symfile_finish, /* sym_finish: finished with file, cleanup */
- coff_symfile_offsets, /* sym_offsets: xlate external to internal form */
+ default_symfile_offsets,
+ /* sym_offsets: xlate external to internal form */
NULL /* next: pointer to next struct sym_fns */
};