#include "breakpoint.h"
#include "bfd.h"
#include "symfile.h"
+#include "objfiles.h"
#include "buildsym.h"
#include <obstack.h>
struct pending_block *pending_blocks;
-extern CORE_ADDR startup_file_start; /* From blockframe.c */
-extern CORE_ADDR startup_file_end; /* From blockframe.c */
-
/* Complaints about various problems in the file being read */
struct complaint ef_complaint =
struct complaint bad_sclass_complaint =
{"Bad n_sclass for symbol %s", 0, 0};
+struct complaint misordered_blocks_complaint =
+ {"Blocks out of order at address %x", 0, 0};
+
+struct complaint tagndx_bad_complaint =
+ {"Symbol table entry for %s has bad tagndx value", 0, 0};
+
/* Simplified internal version of coff symbol table information */
struct coff_symbol {
process_coff_symbol PARAMS ((struct coff_symbol *, union internal_auxent *,
struct objfile *));
-static PTR
-patch_opaque_types PARAMS ((struct objfile *, struct symtab *, PTR, PTR, PTR));
+static void
+patch_opaque_types PARAMS ((struct symtab *));
static void
patch_type PARAMS ((struct type *, struct type *));
union internal_auxent *));
static void
-read_coff_symtab PARAMS ((int, int, struct objfile *));
+read_coff_symtab PARAMS ((long, int, struct objfile *));
static void
-coff_new_init PARAMS ((void));
+find_linenos PARAMS ((bfd *, sec_ptr, PTR));
static void
-coff_symfile_read PARAMS ((struct sym_fns *, CORE_ADDR, int));
+coff_symfile_init PARAMS ((struct objfile *));
static void
-find_linenos PARAMS ((bfd *, sec_ptr, PTR));
+coff_new_init PARAMS ((struct objfile *));
static void
-coff_symfile_init PARAMS ((struct sym_fns *));
+coff_symfile_read PARAMS ((struct objfile *, CORE_ADDR, int));
static void
-record_minimal_symbol PARAMS ((char *, CORE_ADDR));
+coff_symfile_finish PARAMS ((struct objfile *));
+
+static void
+record_minimal_symbol PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type));
static void
coff_end_symtab PARAMS ((struct objfile *));
type_vector = (struct type **)
xrealloc ((char *) type_vector,
type_vector_length * sizeof (struct type *));
- bzero (&type_vector[old_vector_length],
+ memset (&type_vector[old_vector_length], 0,
(type_vector_length - old_vector_length) * sizeof(struct type *));
}
return &type_vector[index];
for (next = *listhead; next; next = next1)
{
next1 = next->next;
- free (next);
+ free ((PTR)next);
}
*listhead = 0;
for (next = pending_blocks; next; next = next1)
{
next1 = next->next;
- free (next);
+ free ((PTR)next);
}
pending_blocks = 0;
/* Initialize the source file line number information for this file. */
if (line_vector) /* Unlikely, but maybe possible? */
- free (line_vector);
+ free ((PTR)line_vector);
line_vector_index = 0;
line_vector_length = 1000;
prev_line_number = -2; /* Force first line number to be explicit */
cur_src_start_addr = start_addr;
cur_src_end_addr = start_addr + size;
- if (entry_point < cur_src_end_addr
- && entry_point >= cur_src_start_addr)
+ if (current_objfile -> ei.entry_point >= cur_src_start_addr &&
+ current_objfile -> ei.entry_point < cur_src_end_addr)
{
- startup_file_start = cur_src_start_addr;
- startup_file_end = cur_src_end_addr;
+ current_objfile -> ei.entry_file_lowpc = cur_src_start_addr;
+ current_objfile -> ei.entry_file_highpc = cur_src_end_addr;
}
}
/* Make a block for the local symbols within. */
coff_finish_block (cstk->name, &coff_local_symbols, cstk->old_blocks,
cstk->start_addr, cur_src_end_addr, objfile);
- free (cstk);
+ free ((PTR)cstk);
}
/* Ignore a file that has no functions with real debugging info. */
if (pending_blocks == 0 && coff_file_symbols == 0 && coff_global_symbols == 0)
{
- free (line_vector);
+ free ((PTR)line_vector);
line_vector = 0;
line_vector_length = -1;
last_source_file = 0;
return;
}
+ /* It is unfortunate that in amdcoff, pending blocks might not be ordered
+ in this stage. Especially, blocks for static functions will show up at
+ the end. We need to sort them, so tools like `find_pc_function' and
+ `find_pc_block' can work reliably. */
+ if (pending_blocks) {
+ /* FIXME! Remove this horrid bubble sort and use qsort!!! */
+ int swapped;
+ do {
+ struct pending_block *pb, *pbnext;
+
+ pb = pending_blocks, pbnext = pb->next;
+ swapped = 0;
+
+ while ( pbnext ) {
+
+ /* swap blocks if unordered! */
+
+ if (BLOCK_START(pb->block) < BLOCK_START(pbnext->block)) {
+ struct block *tmp = pb->block;
+ complain (&misordered_blocks_complaint,
+ (char *) BLOCK_START (pb->block));
+ pb->block = pbnext->block;
+ pbnext->block = tmp;
+ swapped = 1;
+ }
+ pb = pbnext;
+ pbnext = pbnext->next;
+ }
+ } while (swapped);
+ }
+
/* Create the two top-level blocks for this file (STATIC_BLOCK and
GLOBAL_BLOCK). */
coff_finish_block (0, &coff_file_symbols, 0, cur_src_start_addr, cur_src_end_addr, objfile);
}
\f
static void
-record_minimal_symbol (name, address)
+record_minimal_symbol (name, address, type)
char *name;
CORE_ADDR address;
+ enum minimal_symbol_type type;
{
/* We don't want TDESC entry points in the minimal symbol table */
if (name[0] == '@') return;
is, so this guess is more useful than mst_unknown. */
prim_record_minimal_symbol (savestring (name, strlen (name)),
address,
- (int)mst_text);
+ type);
}
\f
/* coff_symfile_init ()
is the coff-specific initialization routine for reading symbols.
- It is passed a struct sym_fns which contains, among other things,
+ It is passed a struct objfile which contains, among other things,
the BFD for the file whose symbols are being read, and a slot for
a pointer to "private data" which we fill with cookies and other
treats for coff_symfile_read ().
static int text_bfd_scnum;
static void
-coff_symfile_init (sf)
- struct sym_fns *sf;
+coff_symfile_init (objfile)
+ struct objfile *objfile;
{
asection *section;
- bfd *abfd = sf->sym_bfd;
+ bfd *abfd = objfile->obfd;
/* Allocate struct to keep track of the symfile */
- /* FIXME memory leak */
- sf->sym_private = xmalloc (sizeof (struct coff_symfile_info));
+ objfile -> sym_private = xmmalloc (objfile -> md,
+ sizeof (struct coff_symfile_info));
- /* Save startup file's range of PC addresses to help blockframe.c
- decide where the bottom of the stack is. */
- if (bfd_get_file_flags (abfd) & EXEC_P)
- {
- /* Executable file -- record its entry point so we'll recognize
- the startup file because it contains the entry point. */
- entry_point = bfd_get_start_address (abfd);
- }
+ init_entry_point_info (objfile);
+
+ /* Save the section number for the text section */
+ section = bfd_get_section_by_name(abfd,".text");
+ if (section)
+ text_bfd_scnum = section->index;
else
- {
- /* Examination of non-executable.o files. Short-circuit this stuff. */
- /* ~0 will not be in any file, we hope. */
- entry_point = ~0;
- /* set the startup file to be an empty range. */
- startup_file_start = 0;
- startup_file_end = 0;
- }
- /* Save the section number for the text section */
- if (section = bfd_get_section_by_name(abfd,".text"))
- text_bfd_scnum = section->index;
- else
- text_bfd_scnum = -1;
+ text_bfd_scnum = -1;
}
/* This function is called for every section; it finds the outer limits
/* ARGSUSED */
static void
-coff_symfile_read (sf, addr, mainline)
- struct sym_fns *sf;
+coff_symfile_read (objfile, addr, mainline)
+ struct objfile *objfile;
CORE_ADDR addr;
int mainline;
{
- struct coff_symfile_info *info = (struct coff_symfile_info *)sf->sym_private;
- bfd *abfd = sf->objfile->obfd;
+ struct coff_symfile_info *info;
+ bfd *abfd = objfile->obfd;
coff_data_type *cdata = coff_data (abfd);
char *name = bfd_get_filename (abfd);
int desc;
int symtab_offset;
int stringtab_offset;
+ info = (struct coff_symfile_info *) objfile -> sym_private;
symfile_bfd = abfd; /* Kludge for swap routines */
/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
/* 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, info);
+ bfd_map_over_sections (abfd, find_linenos, (PTR)info);
val = init_lineno (desc, info->min_lineno_offset,
info->max_lineno_offset - info->min_lineno_offset);
error ("\"%s\": can't get string table", name);
make_cleanup (free_stringtab, 0);
- /* Position to read the symbol table. Do not read it all at once. */
- val = lseek (desc, (long)symtab_offset, 0);
- if (val < 0)
- perror_with_name (name);
-
init_minimal_symbol_collection ();
make_cleanup (discard_minimal_symbols, 0);
/* Now that the executable file is positioned at symbol table,
process it and define symbols accordingly. */
- read_coff_symtab (desc, num_symbols, sf->objfile);
-
- iterate_over_symtabs (patch_opaque_types, (PTR) NULL, (PTR) NULL,
- (PTR) NULL);
+ read_coff_symtab ((long)symtab_offset, num_symbols, objfile);
/* Sort symbols alphabetically within each block. */
/* Install any minimal symbols that have been collected as the current
minimal symbols for this objfile. */
- install_minimal_symbols (sf -> objfile);
+ install_minimal_symbols (objfile);
}
static void
-coff_new_init ()
+coff_new_init (ignore)
+ struct objfile *ignore;
{
/* Nothin' to do */
}
+
+/* Perform any local cleanups required when we are done with a particular
+ objfile. I.E, we are in the process of discarding all symbol information
+ for an objfile, freeing up all memory held for it, and unlinking the
+ objfile struct from the global list of known objfiles. */
+
+static void
+coff_symfile_finish (objfile)
+ struct objfile *objfile;
+{
+ if (objfile -> sym_private != NULL)
+ {
+ mfree (objfile -> md, objfile -> sym_private);
+ }
+}
+
\f
/* Given pointers to a symbol table in coff style exec file,
analyze them and create struct symtab's describing the symbols.
We read them one at a time using read_one_sym (). */
static void
-read_coff_symtab (desc, nsyms, objfile)
- int desc;
+read_coff_symtab (symtab_offset, nsyms, objfile)
+ long symtab_offset;
int nsyms;
struct objfile *objfile;
{
- int newfd; /* Avoid multiple closes on same desc */
FILE *stream;
register struct coff_context_stack *new;
struct coff_symbol coff_symbol;
struct coff_symbol fcn_cs_saved;
static struct internal_syment fcn_sym_saved;
static union internal_auxent fcn_aux_saved;
-
+ struct symtab *s;
+
/* A .file is open. */
int in_source_file = 0;
int num_object_files = 0;
/* Name of the current file. */
char *filestring = "";
- int depth;
- int fcn_first_line;
- int fcn_last_line;
- int fcn_start_addr;
- long fcn_line_ptr;
+ int depth = 0;
+ int fcn_first_line = 0;
+ int fcn_last_line = 0;
+ int fcn_start_addr = 0;
+ long fcn_line_ptr = 0;
struct cleanup *old_chain;
+ int val;
+ stream = fopen (objfile->name, FOPEN_RB);
+ if (!stream)
+ perror_with_name(objfile->name);
- newfd = dup (desc);
- if (newfd == -1)
- fatal ("Too many open files");
- stream = fdopen (newfd, "r");
+ /* Position to read the symbol table. */
+ val = fseek (stream, (long)symtab_offset, 0);
+ if (val < 0)
+ perror_with_name (objfile->name);
/* These cleanups will be discarded below if we succeed. */
old_chain = make_cleanup (free_objfile, objfile);
nlist_stream_global = stream;
nlist_nsyms_global = nsyms;
last_source_file = 0;
- bzero (opaque_type_chain, sizeof opaque_type_chain);
+ memset (opaque_type_chain, 0, sizeof opaque_type_chain);
if (type_vector) /* Get rid of previous one */
- free (type_vector);
+ free ((PTR)type_vector);
type_vector_length = 160;
type_vector = (struct type **)
xmalloc (type_vector_length * sizeof (struct type *));
- bzero (type_vector, type_vector_length * sizeof (struct type *));
+ memset (type_vector, 0, type_vector_length * sizeof (struct type *));
coff_start_symtab ();
/* record as a minimal symbol. if we get '.bf' next,
* then we undo this step
*/
- record_minimal_symbol (cs->c_name, cs->c_value);
+ record_minimal_symbol (cs->c_name, cs->c_value, mst_text);
fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
fcn_start_addr = cs->c_value;
record this symbol as a function in the minimal symbol table.
But why are absolute syms recorded as functions, anyway? */
if (cs->c_secnum <= text_bfd_scnum+1) {/* text or abs */
- record_minimal_symbol (cs->c_name, cs->c_value);
+ record_minimal_symbol (cs->c_name, cs->c_value,
+ mst_text);
break;
} else {
- cs->c_type = T_INT;
+ record_minimal_symbol (cs->c_name, cs->c_value,
+ mst_data);
+ break;
}
}
- (void) process_coff_symbol (cs, &main_aux, objfile);
+ process_coff_symbol (cs, &main_aux, objfile);
break;
case C_FCN:
);
coff_context_stack = 0;
within_function = 0;
- free (new);
+ free ((PTR)new);
}
break;
depth--;
coff_local_symbols = new->locals;
coff_context_stack = new->next;
- free (new);
+ free ((PTR)new);
}
break;
default:
- (void) process_coff_symbol (cs, &main_aux, objfile);
+ process_coff_symbol (cs, &main_aux, objfile);
break;
}
}
if (last_source_file)
coff_end_symtab (objfile);
fclose (stream);
+
+ /* Patch up any opaque types (references to types that are not defined
+ in the file where they are referenced, e.g. "struct foo *bar"). */
+ ALL_OBJFILE_SYMTABS (objfile, s)
+ patch_opaque_types (s);
+
discard_cleanups (old_chain);
current_objfile = NULL;
}
if (stringtab == NULL)
return -1;
- bcopy (&length, stringtab, sizeof length);
+ memcpy (stringtab, &length, sizeof length);
if (length == sizeof length) /* Empty table -- just the count */
return 0;
return -1;
/* Terminate it with an all-zero sentinel record */
- bzero (linetab + size, local_linesz);
+ memset (linetab + size, 0, local_linesz);
make_cleanup (free, linetab); /* Be sure it gets de-allocated. */
return 0;
TYPE_FIELDS (target) = (struct field *)
obstack_alloc (¤t_objfile -> type_obstack, field_size);
- bcopy (TYPE_FIELDS (real_target), TYPE_FIELDS (target), field_size);
+ memcpy (TYPE_FIELDS (target), TYPE_FIELDS (real_target), field_size);
if (TYPE_NAME (real_target))
{
}
/* Patch up all appropriate typedef symbols in the opaque_type_chains
- so that they can be used to print out opaque data structures properly.
-
- This is called via iterate_over_symtabs, and thus simply returns NULL
- for each time it is called, to indicate that the iteration should
- continue. */
+ so that they can be used to print out opaque data structures properly. */
-/* ARGSUSED */
-static PTR
-patch_opaque_types (objfile, s, arg1, arg2, arg3)
- struct objfile *objfile;
+static void
+patch_opaque_types (s)
struct symtab *s;
- PTR arg1;
- PTR arg2;
- PTR arg3;
{
register struct block *b;
register int i;
}
}
}
- return (NULL);
}
\f
static struct symbol *
#endif
struct type *temptype;
- bzero (sym, sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
name = cs->c_name;
name = (name[0] == '_' ? name + offset : name);
SYMBOL_NAME (sym) = obstack_copy0 (&objfile->symbol_obstack, name, strlen (name));
struct type *new = (struct type *)
obstack_alloc (&objfile->symbol_obstack, sizeof (struct type));
- bcopy(lookup_function_type (decode_function_type (cs, cs->c_type, aux)),
- new, 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
TYPE_NAME (SYMBOL_TYPE (sym)) = concat (SYMBOL_NAME (sym), NULL);
/* Keep track of any type which points to empty structured type,
- so it can be filled from a definition from another file */
+ so it can be filled from a definition from another file. A
+ simple forward reference (TYPE_CODE_UNDEF) is not an
+ empty structured type, though; the forward references
+ work themselves out via the magic of coff_lookup_type. */
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR &&
- TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0)
+ TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0 &&
+ TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) !=
+ TYPE_CODE_UNDEF)
{
register int i = hashname (SYMBOL_NAME (sym));
type = (struct type *)
obstack_alloc (¤t_objfile -> type_obstack,
sizeof (struct type));
- bzero (type, sizeof (struct type));
+ memset (type, 0, sizeof (struct type));
TYPE_OBJFILE (type) = current_objfile;
base_type = decode_type (cs, new_c_type, aux);
return type;
}
- /* Reference to existing type */
+ /* Reference to existing type. This only occurs with the
+ struct, union, and enum types. EPI a29k coff
+ fakes us out by producing aux entries with a nonzero
+ x_tagndx for definitions of structs, unions, and enums, so we
+ have to check the c_sclass field. */
if (cs->c_naux > 0 && aux->x_sym.x_tagndx.l != 0)
{
- type = coff_alloc_type (aux->x_sym.x_tagndx.l);
- return type;
+ if (cs->c_sclass != C_STRTAG
+ && cs->c_sclass != C_UNTAG
+ && cs->c_sclass != C_ENTAG)
+ {
+ type = coff_alloc_type (aux->x_sym.x_tagndx.l);
+ return type;
+ } else {
+ complain (&tagndx_bad_complaint, cs->c_name);
+ /* And fall through to decode_base_type... */
+ }
}
return decode_base_type (cs, BTYPE (c_type), aux);
{
case C_MOE:
sym = (struct symbol *) xmalloc (sizeof (struct symbol));
- bzero (sym, sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
SYMBOL_NAME (sym) = savestring (name, strlen (name));
SYMBOL_CLASS (sym) = LOC_CONST;
static struct sym_fns coff_sym_fns =
{
- "coff", 4,
- coff_new_init, coff_symfile_init, coff_symfile_read,
+ "coff", /* sym_name: name or name prefix of BFD target type */
+ 4, /* sym_namelen: number of significant sym_name chars */
+ coff_new_init, /* sym_new_init: init anything gbl to entire symtab */
+ 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 */
+ NULL /* next: pointer to next struct sym_fns */
};
void