static void
enter_linenos PARAMS ((long, int, int));
+static void
+free_linetab PARAMS ((void));
+
static int
init_lineno PARAMS ((int, long, int));
/* We don't want TDESC entry points in the minimal symbol table */
if (name[0] == '@') return;
- /* mst_text isn't true, but apparently COFF doesn't tell us what it really
- is, so this guess is more useful than mst_unknown. */
- prim_record_minimal_symbol (savestring (name, strlen (name)),
- address,
- type);
+ prim_record_minimal_symbol (savestring (name, strlen (name)), address, type);
}
\f
/* coff_symfile_init ()
int num_symbols;
int symtab_offset;
int stringtab_offset;
+ struct cleanup *back_to;
info = (struct coff_symfile_info *) objfile -> sym_private;
symfile_bfd = abfd; /* Kludge for swap routines */
temp_sym = (char *) xmalloc
(cdata->local_symesz + cdata->local_auxesz);
temp_aux = temp_sym + cdata->local_symesz;
- make_cleanup (free_current_contents, &temp_sym);
+ back_to = make_cleanup (free_current_contents, &temp_sym);
/* End of warning */
/* Read the line number table, all at once. */
info->max_lineno_offset = 0;
bfd_map_over_sections (abfd, find_linenos, (PTR)info);
+ make_cleanup (free_linetab, 0);
val = init_lineno (desc, info->min_lineno_offset,
info->max_lineno_offset - info->min_lineno_offset);
if (val < 0)
/* Now read the string table, all at once. */
+ make_cleanup (free_stringtab, 0);
val = init_stringtab (desc, stringtab_offset);
if (val < 0)
error ("\"%s\": can't get string table", name);
- make_cleanup (free_stringtab, 0);
init_minimal_symbol_collection ();
make_cleanup (discard_minimal_symbols, 0);
minimal symbols for this objfile. */
install_minimal_symbols (objfile);
+
+ do_cleanups (back_to);
}
static void
int fcn_last_line = 0;
int fcn_start_addr = 0;
long fcn_line_ptr = 0;
- struct cleanup *old_chain;
int val;
stream = bfd_cache_lookup(objfile->obfd);
if (val < 0)
perror_with_name (objfile->name);
- /* This cleanup will be discarded below if we succeed. */
- old_chain = make_cleanup (free_objfile, objfile);
-
current_objfile = objfile;
nlist_stream_global = stream;
nlist_nsyms_global = nsyms;
/* Typedefs should not be treated as symbol definitions. */
if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
{
- /* record as a minimal symbol. if we get '.bf' next,
- * then we undo this step
- */
+ /* Record all functions -- external and static -- in minsyms. */
record_minimal_symbol (cs->c_name, cs->c_value, mst_text);
fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
break;
/* fall in for static symbols that don't start with '.' */
case C_EXT:
+ /* Record external symbols in minsyms if we don't have debug
+ info for them. FIXME, this is probably the wrong thing
+ to do. Why don't we record them even if we do have
+ debug symbol info? What really belongs in the minsyms
+ anyway? Fred!?? */
if (!SDB_TYPE (cs->c_type)) {
/* FIXME: This is BOGUS Will Robinson!
Coff should provide the SEC_CODE flag for executable sections,
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;
}
\f
int val;
unsigned char lengthbuf[4];
- if (stringtab)
- {
- free (stringtab);
- stringtab = NULL;
- }
+ free_stringtab ();
if (lseek (chan, offset, 0) < 0)
return -1;
/* 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 length || length < sizeof length)
+ if (val != sizeof lengthbuf || length < sizeof lengthbuf)
return 0;
stringtab = (char *) xmalloc (length);
if (length == sizeof length) /* Empty table -- just the count */
return 0;
- val = myread (chan, stringtab + sizeof length, length - sizeof length);
- if (val != length - sizeof length || stringtab[length - 1] != '\0')
+ val = myread (chan, stringtab + sizeof lengthbuf, length - sizeof lengthbuf);
+ if (val != length - sizeof lengthbuf || stringtab[length - 1] != '\0')
return -1;
return 0;
linetab_offset = offset;
linetab_size = size;
+ free_linetab();
+
if (size == 0)
return 0;
/* Allocate the desired table, plus a sentinel */
linetab = (char *) xmalloc (size + local_linesz);
+ if (linetab == NULL)
+ return -1;
+
val = myread (chan, linetab, size);
if (val != size)
return -1;
/* Terminate it with an all-zero sentinel record */
memset (linetab + size, 0, local_linesz);
- make_cleanup (free, linetab); /* Be sure it gets de-allocated. */
return 0;
}
+static void
+free_linetab ()
+{
+ if (linetab)
+ free (linetab);
+ linetab = NULL;
+}
+
#if !defined (L_LNNO32)
#define L_LNNO32(lp) ((lp)->l_lnno)
#endif
case C_ENTAG:
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
- if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
- TYPE_NAME (SYMBOL_TYPE (sym))
- = concat ("",
- (cs->c_sclass == C_ENTAG
- ? "enum "
- : (cs->c_sclass == C_STRTAG
- ? "struct " : "union ")),
- SYMBOL_NAME (sym), NULL);
+
+ /* Some compilers try to be helpful by inventing "fake"
+ names for anonymous enums, structures, and unions, like
+ "~0fake" or ".0fake". Thanks, but no thanks... */
+ if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
+ if (SYMBOL_NAME(sym) != NULL
+ && *SYMBOL_NAME(sym) != '~'
+ && *SYMBOL_NAME(sym) != '.')
+ TYPE_TAG_NAME (SYMBOL_TYPE (sym)) =
+ concat (SYMBOL_NAME (sym), NULL);
+
coff_add_symbol_to_list (sym, &coff_file_symbols);
break;
/* anonymous structure type */
type = coff_alloc_type (cs->c_symnum);
TYPE_CODE (type) = TYPE_CODE_STRUCT;
- TYPE_NAME (type) = concat ("struct ", "<opaque>", NULL);
+ TYPE_NAME (type) = NULL;
+ /* This used to set the tag to "<opaque>". But I think setting it
+ to NULL is right, and the printing code can print it as
+ "struct {...}". */
+ TYPE_TAG_NAME (type) = NULL;
INIT_CPLUS_SPECIFIC(type);
TYPE_LENGTH (type) = 0;
TYPE_FIELDS (type) = 0;
{
/* anonymous union type */
type = coff_alloc_type (cs->c_symnum);
- TYPE_NAME (type) = concat ("union ", "<opaque>", NULL);
+ TYPE_NAME (type) = NULL;
+ /* This used to set the tag to "<opaque>". But I think setting it
+ to NULL is right, and the printing code can print it as
+ "union {...}". */
+ TYPE_TAG_NAME (type) = NULL;
INIT_CPLUS_SPECIFIC(type);
TYPE_LENGTH (type) = 0;
- TYPE_LENGTH (type) = 0;
TYPE_FIELDS (type) = 0;
TYPE_NFIELDS (type) = 0;
}
return type;
case T_ENUM:
- return coff_read_enum_type (cs->c_symnum,
- aux->x_sym.x_misc.x_lnsz.x_size,
- aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+ if (cs->c_naux != 1)
+ {
+ /* anonymous enum type */
+ type = coff_alloc_type (cs->c_symnum);
+ TYPE_CODE (type) = TYPE_CODE_ENUM;
+ TYPE_NAME (type) = NULL;
+ /* This used to set the tag to "<opaque>". But I think setting it
+ to NULL is right, and the printing code can print it as
+ "enum {...}". */
+ TYPE_TAG_NAME (type) = NULL;
+ TYPE_LENGTH (type) = 0;
+ TYPE_FIELDS (type) = 0;
+ TYPE_NFIELDS(type) = 0;
+ }
+ else
+ {
+ type = coff_read_enum_type (cs->c_symnum,
+ aux->x_sym.x_misc.x_lnsz.x_size,
+ aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+ }
+ return type;
case T_MOE:
/* shouldn't show up here */
TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (syms->symbol);
TYPE_FIELD_BITSIZE (type, n) = 0;
}
+#if 0
+ /* This screws up perfectly good C programs with enums. FIXME. */
/* Is this Modula-2's BOOLEAN type? Flag it as such if so. */
if(TYPE_NFIELDS(type) == 2 &&
((STREQ(TYPE_FIELD_NAME(type,0),"TRUE") &&
(STREQ(TYPE_FIELD_NAME(type,1),"TRUE") &&
STREQ(TYPE_FIELD_NAME(type,0),"FALSE"))))
TYPE_CODE(type) = TYPE_CODE_BOOL;
+#endif
return type;
}