/* Read coff symbol tables and convert to internal format, for GDB.
- Copyright 1987, 88, 89, 90, 91, 92, 93, 94, 96, 97, 1998
+ Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
#include "breakpoint.h"
#include "bfd.h"
-#include "obstack.h"
+#include "gdb_obstack.h"
#include "gdb_string.h"
#include <ctype.h>
#include "stabsread.h"
#include "complaints.h"
#include "target.h"
+#include "gdb_assert.h"
extern void _initialize_coffread (void);
#define SDB_TYPE(type) (BTYPE(type) | (type & N_TMASK))
-/* Convert from an sdb register number to an internal gdb register number.
- This should be defined in tm.h, if REGISTER_NAMES is not set up
- to map one to one onto the sdb register numbers. */
-
-#ifndef SDB_REG_TO_REGNUM
-#define SDB_REG_TO_REGNUM(value) (value)
-#endif
-
/* Core address of start and end of text of current source file.
This comes from a ".text" symbol where x_nlinno > 0. */
static void patch_opaque_types (struct symtab *);
-static void patch_type (struct type *, struct type *);
-
static void enter_linenos (long, int, int, struct objfile *);
static void free_linetab (void);
struct internal_syment *, union internal_auxent *);
static void coff_symtab_read (long, unsigned int, struct objfile *);
-
-static void find_linenos (bfd *, sec_ptr, PTR);
-
-static void coff_symfile_init (struct objfile *);
-
-static void coff_new_init (struct objfile *);
-
-static void coff_symfile_read (struct objfile *, int);
-
-static void coff_symfile_finish (struct objfile *);
-
-static void record_minimal_symbol (char *, CORE_ADDR,
- enum minimal_symbol_type,
- struct objfile *);
-
-static void coff_end_symtab (struct objfile *);
-
-static void complete_symtab (char *, CORE_ADDR, unsigned int);
-
-static void coff_start_symtab (char *);
-
-static struct type *coff_alloc_type (int);
-
-static struct type **coff_lookup_type (int);
-
-static void coff_locate_sections (bfd *, asection *, PTR);
\f
/* We are called once per section from coff_symfile_read. We
need to examine each section we are passed, check to see
-kingdon). */
static void
-coff_locate_sections (bfd *abfd, asection *sectp, PTR csip)
+coff_locate_sections (bfd *abfd, asection *sectp, void *csip)
{
register struct coff_symfile_info *csi;
const char *name;
/* 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);
+ make_cleanup (xfree, n);
}
}
}
asection **resultp;
};
-static void find_targ_sec (bfd *, asection *, void *);
-
static void
-find_targ_sec (bfd *abfd, asection *sect, PTR obj)
+find_targ_sec (bfd *abfd, asection *sect, void *obj)
{
struct find_targ_sec_arg *args = (struct find_targ_sec_arg *) obj;
if (sect->target_index == args->targ_index)
else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
off = SECT_OFF_DATA (objfile);
else
- off = SECT_OFF_BSS (objfile);
+ /* Just return the bfd section index. */
+ off = sect->index;
}
return off;
}
complete_symtab (char *name, CORE_ADDR start_addr, unsigned int size)
{
if (last_source_file != NULL)
- free (last_source_file);
+ xfree (last_source_file);
last_source_file = savestring (name, strlen (name));
current_source_start_addr = start_addr;
current_source_end_addr = start_addr + size;
last_source_start_addr = current_source_start_addr;
- symtab = end_symtab (current_source_end_addr, objfile, 0);
+ symtab = end_symtab (current_source_end_addr, objfile, SECT_OFF_TEXT (objfile));
if (symtab != NULL)
free_named_symtabs (symtab->filename);
objfile->sym_stab_info = (struct dbx_symfile_info *)
xmmalloc (objfile->md, sizeof (struct dbx_symfile_info));
- memset ((PTR) objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
+ memset (objfile->sym_stab_info, 0,
+ sizeof (struct dbx_symfile_info));
/* Allocate struct to keep track of the symfile */
objfile->sym_private = xmmalloc (objfile->md,
/* ARGSUSED */
static void
-find_linenos (bfd *abfd, sec_ptr asect, PTR vpinfo)
+find_linenos (bfd *abfd, sec_ptr asect, void *vpinfo)
{
struct coff_symfile_info *info;
int size, count;
/* End of warning */
- /* Read the line number table, all at once. */
info->min_lineno_offset = 0;
info->max_lineno_offset = 0;
- bfd_map_over_sections (abfd, find_linenos, (PTR) info);
- make_cleanup (free_linetab_cleanup, 0 /*ignore*/);
- val = init_lineno (abfd, info->min_lineno_offset,
- info->max_lineno_offset - info->min_lineno_offset);
- if (val < 0)
- error ("\"%s\": error reading line numbers\n", name);
+ /* Only read line number information if we have symbols.
+
+ On Windows NT, some of the system's DLL's have sections with
+ PointerToLinenumbers fields that are non-zero, but point at
+ random places within the image file. (In the case I found,
+ KERNEL32.DLL's .text section has a line number info pointer that
+ points into the middle of the string `lib\\i386\kernel32.dll'.)
+
+ However, these DLL's also have no symbols. The line number
+ tables are meaningless without symbols. And in fact, GDB never
+ uses the line number information unless there are symbols. So we
+ can avoid spurious error messages (and maybe run a little
+ faster!) by not even reading the line number table unless we have
+ symbols. */
+ if (num_symbols > 0)
+ {
+ /* Read the line number table, all at once. */
+ bfd_map_over_sections (abfd, find_linenos, (void *) info);
+
+ make_cleanup (free_linetab_cleanup, 0 /*ignore*/);
+ val = init_lineno (abfd, info->min_lineno_offset,
+ info->max_lineno_offset - info->min_lineno_offset);
+ if (val < 0)
+ error ("\"%s\": error reading line numbers\n", name);
+ }
/* Now read the string table, all at once. */
install_minimal_symbols (objfile);
- bfd_map_over_sections (abfd, coff_locate_sections, (PTR) info);
+ bfd_map_over_sections (abfd, coff_locate_sections, (void *) info);
if (info->stabsects)
{
if (!info->stabstrsect)
{
- error_begin ();
- fprintf_filtered
- (gdb_stderr,
- ("The debugging information in `%s' is corrupted.\n"
- "The file has a `.stabs' section, but no `.stabstr' section.\n"),
- name);
- return_to_top_level (RETURN_ERROR);
+ error (("The debugging information in `%s' is corrupted.\n"
+ "The file has a `.stabs' section, but no `.stabstr' "
+ "section."),
+ name);
}
/* FIXME: dubious. Why can't we use something normal like
info->stabsects,
info->stabstrsect->filepos, stabstrsize);
}
+ if (dwarf2_has_info (abfd))
+ {
+ /* DWARF2 sections. */
+ dwarf2_build_psymtabs (objfile, mainline);
+ }
do_cleanups (back_to);
}
{
if (objfile->sym_private != NULL)
{
- mfree (objfile->md, objfile->sym_private);
+ xmfree (objfile->md, objfile->sym_private);
}
/* Let stabs reader clean up */
char *filestring = "";
int depth = 0;
int fcn_first_line = 0;
- CORE_ADDR fcn_first_line_addr;
+ CORE_ADDR fcn_first_line_addr = 0;
int fcn_last_line = 0;
int fcn_start_addr = 0;
long fcn_line_ptr = 0;
memset (opaque_type_chain, 0, sizeof opaque_type_chain);
if (type_vector) /* Get rid of previous one */
- free ((PTR) type_vector);
+ xfree (type_vector);
type_vector_length = 160;
type_vector = (struct type **)
xmalloc (type_vector_length * sizeof (struct type *));
cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
|| cs->c_sclass == C_THUMBEXT ?
mst_text : mst_file_text;
-#ifdef SMASH_TEXT_ADDRESS
- if (tmpaddr & 1) /* FIXME: delete this line */
- SMASH_TEXT_ADDRESS (tmpaddr);
-#endif
+ tmpaddr = SMASH_TEXT_ADDRESS (tmpaddr);
}
else if (sec == SECT_OFF_DATA (objfile))
{
{
struct minimal_symbol *msym;
+ /* FIXME: cagney/2001-02-01: The nasty (int) -> (long)
+ -> (void*) cast is to ensure that that the value of
+ cs->c_sclass can be correctly stored in a void
+ pointer in MSYMBOL_INFO. Better solutions
+ welcome. */
+ gdb_assert (sizeof (void *) >= sizeof (cs->c_sclass));
msym = prim_record_minimal_symbol_and_info
- (cs->c_name, tmpaddr, ms_type, (char *) cs->c_sclass, sec,
- NULL, objfile);
-#ifdef COFF_MAKE_MSYMBOL_SPECIAL
+ (cs->c_name, tmpaddr, ms_type, (void *) (long) cs->c_sclass,
+ sec, NULL, objfile);
if (msym)
COFF_MAKE_MSYMBOL_SPECIAL (cs->c_sclass, msym);
-#endif
}
if (SDB_TYPE (cs->c_type))
{
}
else if (STREQ (cs->c_name, ".ef"))
{
+ if (!within_function)
+ error ("Bad coff function information\n");
/* the value of .ef is the address of epilogue code;
not useful for gdb. */
/* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
int i;
cs->c_symnum = symnum;
- bfd_read (temp_sym, local_symesz, 1, nlist_bfd_global);
+ bfd_bread (temp_sym, local_symesz, nlist_bfd_global);
bfd_coff_swap_sym_in (symfile_bfd, temp_sym, (char *) sym);
cs->c_naux = sym->n_numaux & 0xff;
if (cs->c_naux >= 1)
{
- bfd_read (temp_aux, local_auxesz, 1, nlist_bfd_global);
+ bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
bfd_coff_swap_aux_in (symfile_bfd, temp_aux, sym->n_type, sym->n_sclass,
0, cs->c_naux, (char *) aux);
/* If more than one aux entry, read past it (only the first aux
is important). */
for (i = 1; i < cs->c_naux; i++)
- bfd_read (temp_aux, local_auxesz, 1, nlist_bfd_global);
+ bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
}
cs->c_name = getsymname (sym);
cs->c_value = sym->n_value;
if (bfd_seek (abfd, offset, 0) < 0)
return -1;
- val = bfd_read ((char *) lengthbuf, sizeof lengthbuf, 1, abfd);
+ val = bfd_bread ((char *) lengthbuf, sizeof lengthbuf, abfd);
length = bfd_h_get_32 (symfile_bfd, lengthbuf);
/* If no string table is needed, then the file may end immediately
if (length == sizeof length) /* Empty table -- just the count */
return 0;
- val = bfd_read (stringtab + sizeof lengthbuf, length - sizeof lengthbuf, 1, abfd);
+ val = bfd_bread (stringtab + sizeof lengthbuf, length - sizeof lengthbuf,
+ abfd);
if (val != length - sizeof lengthbuf || stringtab[length - 1] != '\0')
return -1;
free_stringtab (void)
{
if (stringtab)
- free (stringtab);
+ xfree (stringtab);
stringtab = NULL;
}
/* Allocate the desired table, plus a sentinel */
linetab = (char *) xmalloc (size + local_linesz);
- val = bfd_read (linetab, size, 1, abfd);
+ val = bfd_bread (linetab, size, abfd);
if (val != size)
return -1;
free_linetab (void)
{
if (linetab)
- free (linetab);
+ xfree (linetab);
linetab = NULL;
}
if (TYPE_NAME (real_target))
{
if (TYPE_NAME (target))
- free (TYPE_NAME (target));
+ xfree (TYPE_NAME (target));
TYPE_NAME (target) = concat (TYPE_NAME (real_target), NULL);
}
}
/* Go through the per-file symbols only */
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
- for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--)
+ ALL_BLOCK_SYMBOLS (b, i, real_sym)
{
/* Find completed typedefs to use to fix opaque ones.
Remove syms from the chain when their types are stored,
but search the whole chain, as there may be several syms
from different files with the same name. */
- real_sym = BLOCK_SYM (b, i);
if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF &&
SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE &&
TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&
SYMBOL_CLASS (sym) = LOC_ARG;
add_symbol_to_list (sym, &local_symbols);
#if !defined (BELIEVE_PCC_PROMOTION)
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
{
/* If PCC says a parameter is a short or a char,
aligned on an int boundary, realign it to the