#include "libbfd.h" /* FIXME Secret Internal BFD stuff (bfd_read) */
#include "elf/dwarf.h"
#include "buildsym.h"
+#include "demangle.h"
#ifdef MAINTENANCE /* Define to 1 to compile in some maintenance stuff */
#define SQUAWK(stuff) dwarfwarn stuff
#define GCC_PRODUCER "GNU C "
#endif
+#ifndef GPLUS_PRODUCER
+#define GPLUS_PRODUCER "GNU C++ "
+#endif
+
+#ifndef LCC_PRODUCER
+#define LCC_PRODUCER "NCR C/C++ "
+#endif
+
+#ifndef CFRONT_PRODUCER
+#define CFRONT_PRODUCER "CFRONT " /* A wild a** guess... */
+#endif
+
#define STREQ(a,b) (strcmp(a,b)==0)
#define STREQN(a,b,n) (strncmp(a,b,n)==0)
static int isreg; /* Kludge to identify register variables */
static int offreg; /* Kludge to identify basereg references */
+/* This value is added to each symbol value. FIXME: Generalize to
+ the section_offsets structure used by dbxread. */
static CORE_ADDR baseaddr; /* Add to each symbol value */
+/* The section offsets used in the current psymtab or symtab. FIXME,
+ only used to pass one value (baseaddr) at the moment. */
+static struct section_offsets *base_section_offsets;
+
/* Each partial symbol table entry contains a pointer to private data for the
read_symtab() function to use when expanding a partial symbol table entry
to a full symbol table entry. For DWARF debugging info, this data is
static void
add_enum_psymbol PARAMS ((struct dieinfo *, struct objfile *));
+static void
+handle_producer PARAMS ((char *));
+
static void
read_file_scope PARAMS ((struct dieinfo *, char *, char *, struct objfile *));
decode_mod_u_d_type PARAMS ((char *));
static struct type *
-decode_modified_type PARAMS ((unsigned char *, unsigned int, int));
+decode_modified_type PARAMS ((char *, unsigned int, int));
static struct type *
decode_fund_type PARAMS ((unsigned int));
SYNOPSIS
- void dwarf_build_psymtabs (int desc, char *filename, CORE_ADDR addr,
+ void dwarf_build_psymtabs (int desc, char *filename,
+ struct section_offsets *section_offsets,
int mainline, unsigned int dbfoff, unsigned int dbsize,
unsigned int lnoffset, unsigned int lnsize,
struct objfile *objfile)
*/
void
-dwarf_build_psymtabs (desc, filename, addr, mainline, dbfoff, dbsize,
+dwarf_build_psymtabs (desc, filename, section_offsets, mainline, dbfoff, dbsize,
lnoffset, lnsize, objfile)
int desc;
char *filename;
- CORE_ADDR addr;
+ struct section_offsets *section_offsets;
int mainline;
unsigned int dbfoff;
unsigned int dbsize;
/* Save the relocation factor where everybody can see it. */
- baseaddr = addr;
+ base_section_offsets = section_offsets;
+ baseaddr = ANOFFSET (section_offsets, 0);
/* Follow the compilation unit sibling chain, building a partial symbol
table entry for each one. Save enough information about each compilation
{
register struct context_stack *new;
- (void) push_context (0, dip -> at_low_pc);
+ push_context (0, dip -> at_low_pc);
process_dies (thisdie + dip -> die_length, enddie, objfile);
new = pop_context ();
if (local_symbols != NULL)
{
if (utypep == NULL)
{
- utypep = (struct type *)
- obstack_alloc (¤t_objfile -> type_obstack,
- sizeof (struct type));
- (void) memset (utypep, 0, sizeof (struct type));
- TYPE_OBJFILE (utypep) = current_objfile;
+ utypep = alloc_type (current_objfile);
}
*typep = utypep;
}
new -> next = list;
list = new;
/* Save the data. */
- list -> field.name = savestring (mbr.at_name, strlen (mbr.at_name));
+ list -> field.name =
+ obsavestring (mbr.at_name, strlen (mbr.at_name),
+ &objfile -> type_obstack);
list -> field.type = decode_die_type (&mbr);
list -> field.bitpos = 8 * locval (mbr.at_location);
/* Handle bit fields. */
nexttype = decode_subscr_data (scan, end);
if (nexttype != NULL)
{
- typep = (struct type *)
- obstack_alloc (¤t_objfile -> type_obstack,
- sizeof (struct type));
- (void) memset (typep, 0, sizeof (struct type));
- TYPE_OBJFILE (typep) = current_objfile;
+ typep = alloc_type (current_objfile);
TYPE_CODE (typep) = TYPE_CODE_ARRAY;
TYPE_LENGTH (typep) = TYPE_LENGTH (nexttype);
TYPE_LENGTH (typep) *= (highbound - lowbound) + 1;
{
if ((utype = lookup_utype (dip -> die_ref)) == NULL)
{
- (void) alloc_utype (dip -> die_ref, type);
+ alloc_utype (dip -> die_ref, type);
}
else
{
if ((utype = lookup_utype (dip -> die_ref)) == NULL)
{
utype = lookup_pointer_type (type);
- (void) alloc_utype (dip -> die_ref, utype);
+ alloc_utype (dip -> die_ref, utype);
}
else
{
/* This is the first reference to one of these types. Make
a new one and place it in the user defined types. */
ftype = lookup_function_type (type);
- (void) alloc_utype (dip -> die_ref, ftype);
+ alloc_utype (dip -> die_ref, ftype);
}
else
{
target_to_host (scan, TARGET_FT_LONG_SIZE (objfile), GET_SIGNED,
objfile);
scan += TARGET_FT_LONG_SIZE (objfile);
- list -> field.name = savestring (scan, strlen (scan));
+ list -> field.name = obsavestring (scan, strlen (scan),
+ &objfile -> type_obstack);
scan += strlen (scan) + 1;
nfields++;
/* Handcraft a new symbol for this enum member. */
sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
sizeof (struct symbol));
- (void) memset (sym, 0, sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
SYMBOL_NAME (sym) = create_name (list -> field.name,
&objfile->symbol_obstack);
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
add_symbol_to_list (sym, list_in_scope);
}
/* Now create the vector of fields, and record how big it is. This is
- where we reverse the order, by pulling the members of the list in
+ where we reverse the order, by pulling the members off the list in
reverse order from how they were inserted. If we have no fields
(this is apparently possible in C++) then skip building a field
vector. */
list_in_scope = &file_symbols;
}
+
+/*
+
+LOCAL FUNCTION
+
+ handle_producer -- process the AT_producer attribute
+
+DESCRIPTION
+
+ Perform any operations that depend on finding a particular
+ AT_producer attribute.
+
+ */
+
+static void
+handle_producer (producer)
+ char *producer;
+{
+
+ /* If this compilation unit was compiled with g++ or gcc, then set the
+ processing_gcc_compilation flag. */
+
+ processing_gcc_compilation =
+ STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER))
+ || STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER));
+
+ /* Select a demangling style if we can identify the producer and if
+ the current style is auto. We leave the current style alone if it
+ is not auto. We also leave the demangling style alone if we find a
+ gcc (cc1) producer, as opposed to a g++ (cc1plus) producer. */
+
+#if 1 /* Works, but is experimental. -fnf */
+ if (current_demangling_style == auto_demangling)
+ {
+ if (STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER)))
+ {
+ set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
+ }
+ else if (STREQN (producer, LCC_PRODUCER, strlen (LCC_PRODUCER)))
+ {
+ set_demangling_style (LUCID_DEMANGLING_STYLE_STRING);
+ }
+ else if (STREQN (producer, CFRONT_PRODUCER, strlen (CFRONT_PRODUCER)))
+ {
+ set_demangling_style (CFRONT_DEMANGLING_STYLE_STRING);
+ }
+ }
+#endif
+}
+
+
/*
LOCAL FUNCTION
}
if (dip -> at_producer != NULL)
{
- processing_gcc_compilation =
- STREQN (dip -> at_producer, GCC_PRODUCER, strlen (GCC_PRODUCER));
+ handle_producer (dip -> at_producer);
}
numutypes = (enddie - thisdie) / 4;
utypes = (struct type **) xmalloc (numutypes * sizeof (struct type *));
back_to = make_cleanup (free, utypes);
- (void) memset (utypes, 0, numutypes * sizeof (struct type *));
- start_symtab (dip -> at_name, NULL, dip -> at_low_pc);
+ memset (utypes, 0, numutypes * sizeof (struct type *));
+ start_symtab (dip -> at_name, dip -> at_comp_dir, dip -> at_low_pc);
decode_line_numbers (lnbase);
process_dies (thisdie + dip -> die_length, enddie, objfile);
symtab = end_symtab (dip -> at_high_pc, 0, 0, objfile);
read_tag_pointer_type (&di);
break;
default:
- (void) new_symbol (&di, objfile);
+ new_symbol (&di, objfile);
break;
}
}
dbbase = xmalloc (DBLENGTH(pst));
dbroff = DBROFF(pst);
foffset = DBFOFF(pst) + dbroff;
- baseaddr = pst -> addr;
+ base_section_offsets = pst->section_offsets;
+ baseaddr = ANOFFSET (pst->section_offsets, 0);
if (bfd_seek (abfd, foffset, 0) ||
(bfd_read (dbbase, DBLENGTH(pst), 1, abfd) != DBLENGTH(pst)))
{
struct partial_symtab *pst;
{
int i;
+ struct cleanup *old_chain;
if (pst != NULL)
{
}
if (DBLENGTH (pst)) /* Otherwise it's a dummy */
{
+ buildsym_init ();
+ old_chain = make_cleanup (really_free_pendings, 0);
pst -> symtab = read_ofile_symtab (pst);
if (info_verbose)
{
fflush (stdout);
}
sort_symtab_syms (pst -> symtab);
+ do_cleanups (old_chain);
}
pst -> readin = 1;
}
/* First allocate a new partial symbol table structure */
- pst = start_psymtab_common (objfile, baseaddr, di.at_name,
+ pst = start_psymtab_common (objfile, base_section_offsets, di.at_name,
di.at_low_pc,
objfile -> global_psymbols.next,
objfile -> static_psymbols.next);
{
sym = (struct symbol *) obstack_alloc (&objfile -> symbol_obstack,
sizeof (struct symbol));
- (void) memset (sym, 0, sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
SYMBOL_NAME (sym) = create_name (dip -> at_name, &objfile->symbol_obstack);
/* default assumptions */
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
SYNOPSIS
- static struct type *decode_modified_type (unsigned char *modifiers,
+ static struct type *decode_modified_type (char *modifiers,
unsigned short modcount, int mtype)
DESCRIPTION
static struct type *
decode_modified_type (modifiers, modcount, mtype)
- unsigned char *modifiers;
+ char *modifiers;
unsigned int modcount;
int mtype;
{
struct type *typep = NULL;
unsigned short fundtype;
DIE_REF die_ref;
- unsigned char modifier;
+ char modifier;
int nbytes;
if (modcount == 0)
SQUAWK (("type modifier 'volatile' ignored")); /* FIXME */
break;
default:
- if (!(MOD_lo_user <= modifier && modifier <= MOD_hi_user))
+ if (!(MOD_lo_user <= (unsigned char) modifier
+ && (unsigned char) modifier <= MOD_hi_user))
{
- SQUAWK (("unknown type modifier %u", modifier));
+ SQUAWK (("unknown type modifier %u",
+ (unsigned char) modifier));
}
break;
}
length = strlen (name) + 1;
newname = (char *) obstack_alloc (obstackp, length);
- (void) strcpy (newname, name);
+ strcpy (newname, name);
return (newname);
}
struct objfile *objfile;
{
curdie = dip;
- (void) memset (dip, 0, sizeof (struct dieinfo));
+ memset (dip, 0, sizeof (struct dieinfo));
dip -> die = diep;
dip -> die_ref = dbroff + (diep - dbbase);
dip -> die_length = target_to_host (diep, SIZEOF_DIE_LENGTH, GET_UNSIGNED,
dip -> at_name = diep;
break;
case AT_comp_dir:
- dip -> at_comp_dir = diep;
+ /* For now, ignore any "hostname:" portion, since gdb doesn't
+ know how to deal with it. (FIXME). */
+ dip -> at_comp_dir = strrchr (diep, ':');
+ if (dip -> at_comp_dir != NULL)
+ {
+ dip -> at_comp_dir++;
+ }
+ else
+ {
+ dip -> at_comp_dir = diep;
+ }
break;
case AT_producer:
dip -> at_producer = diep;