/* stabs.c -- Parse stabs debugging information
- Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Ian Lance Taylor <ian@cygnus.com>.
#include "debug.h"
#include "budbg.h"
#include "filenames.h"
-
-/* Meaningless definition needs by aout64.h. FIXME. */
-#define BYTES_IN_WORD 4
-
#include "aout/aout64.h"
#include "aout/stab_gnu.h"
debug_type type;
};
-static char *savestring
- PARAMS ((const char *, int));
-static bfd_vma parse_number
- PARAMS ((const char **, bfd_boolean *));
-static void bad_stab
- PARAMS ((const char *));
-static void warn_stab
- PARAMS ((const char *, const char *));
+static char *savestring (const char *, int);
+static bfd_vma parse_number (const char **, bfd_boolean *);
+static void bad_stab (const char *);
+static void warn_stab (const char *, const char *);
static bfd_boolean parse_stab_string
- PARAMS ((PTR, struct stab_handle *, int, int, bfd_vma, const char *));
+ (void *, struct stab_handle *, int, int, bfd_vma, const char *);
static debug_type parse_stab_type
- PARAMS ((PTR, struct stab_handle *, const char *, const char **,
- debug_type **));
-static bfd_boolean parse_stab_type_number
- PARAMS ((const char **, int *));
+ (void *, struct stab_handle *, const char *, const char **, debug_type **);
+static bfd_boolean parse_stab_type_number (const char **, int *);
static debug_type parse_stab_range_type
- PARAMS ((PTR, struct stab_handle *, const char *, const char **,
- const int *));
-static debug_type parse_stab_sun_builtin_type
- PARAMS ((PTR, const char **));
-static debug_type parse_stab_sun_floating_type
- PARAMS ((PTR, const char **));
-static debug_type parse_stab_enum_type
- PARAMS ((PTR, const char **));
+ (void *, struct stab_handle *, const char *, const char **, const int *);
+static debug_type parse_stab_sun_builtin_type (void *, const char **);
+static debug_type parse_stab_sun_floating_type (void *, const char **);
+static debug_type parse_stab_enum_type (void *, const char **);
static debug_type parse_stab_struct_type
- PARAMS ((PTR, struct stab_handle *, const char *, const char **,
- bfd_boolean, const int *));
+ (void *, struct stab_handle *, const char *, const char **,
+ bfd_boolean, const int *);
static bfd_boolean parse_stab_baseclasses
- PARAMS ((PTR, struct stab_handle *, const char **, debug_baseclass **));
+ (void *, struct stab_handle *, const char **, debug_baseclass **);
static bfd_boolean parse_stab_struct_fields
- PARAMS ((PTR, struct stab_handle *, const char **, debug_field **,
- bfd_boolean *));
+ (void *, struct stab_handle *, const char **, debug_field **, bfd_boolean *);
static bfd_boolean parse_stab_cpp_abbrev
- PARAMS ((PTR, struct stab_handle *, const char **, debug_field *));
+ (void *, struct stab_handle *, const char **, debug_field *);
static bfd_boolean parse_stab_one_struct_field
- PARAMS ((PTR, struct stab_handle *, const char **, const char *,
- debug_field *, bfd_boolean *));
+ (void *, struct stab_handle *, const char **, const char *,
+ debug_field *, bfd_boolean *);
static bfd_boolean parse_stab_members
- PARAMS ((PTR, struct stab_handle *, const char *, const char **,
- const int *, debug_method **));
+ (void *, struct stab_handle *, const char *, const char **, const int *,
+ debug_method **);
static debug_type parse_stab_argtypes
- PARAMS ((PTR, struct stab_handle *, debug_type, const char *, const char *,
- debug_type, const char *, bfd_boolean, bfd_boolean, const char **));
+ (void *, struct stab_handle *, debug_type, const char *, const char *,
+ debug_type, const char *, bfd_boolean, bfd_boolean, const char **);
static bfd_boolean parse_stab_tilde_field
- PARAMS ((PTR, struct stab_handle *, const char **, const int *,
- debug_type *, bfd_boolean *));
+ (void *, struct stab_handle *, const char **, const int *, debug_type *,
+ bfd_boolean *);
static debug_type parse_stab_array_type
- PARAMS ((PTR, struct stab_handle *, const char **, bfd_boolean));
-static void push_bincl
- PARAMS ((struct stab_handle *, const char *, bfd_vma));
-static const char *pop_bincl
- PARAMS ((struct stab_handle *));
-static bfd_boolean find_excl
- PARAMS ((struct stab_handle *, const char *, bfd_vma));
+ (void *, struct stab_handle *, const char **, bfd_boolean);
+static void push_bincl (struct stab_handle *, const char *, bfd_vma);
+static const char *pop_bincl (struct stab_handle *);
+static bfd_boolean find_excl (struct stab_handle *, const char *, bfd_vma);
static bfd_boolean stab_record_variable
- PARAMS ((PTR, struct stab_handle *, const char *, debug_type,
- enum debug_var_kind, bfd_vma));
-static bfd_boolean stab_emit_pending_vars
- PARAMS ((PTR, struct stab_handle *));
-static debug_type *stab_find_slot
- PARAMS ((struct stab_handle *, const int *));
-static debug_type stab_find_type
- PARAMS ((PTR, struct stab_handle *, const int *));
+ (void *, struct stab_handle *, const char *, debug_type,
+ enum debug_var_kind, bfd_vma);
+static bfd_boolean stab_emit_pending_vars (void *, struct stab_handle *);
+static debug_type *stab_find_slot (struct stab_handle *, const int *);
+static debug_type stab_find_type (void *, struct stab_handle *, const int *);
static bfd_boolean stab_record_type
- PARAMS ((PTR, struct stab_handle *, const int *, debug_type));
+ (void *, struct stab_handle *, const int *, debug_type);
static debug_type stab_xcoff_builtin_type
- PARAMS ((PTR, struct stab_handle *, int));
+ (void *, struct stab_handle *, int);
static debug_type stab_find_tagged_type
- PARAMS ((PTR, struct stab_handle *, const char *, int,
- enum debug_type_kind));
+ (void *, struct stab_handle *, const char *, int, enum debug_type_kind);
static debug_type *stab_demangle_argtypes
- PARAMS ((PTR, struct stab_handle *, const char *, bfd_boolean *,
- unsigned int));
+ (void *, struct stab_handle *, const char *, bfd_boolean *, unsigned int);
+static debug_type *stab_demangle_v3_argtypes
+ (void *, struct stab_handle *, const char *, bfd_boolean *);
+static debug_type stab_demangle_v3_arg
+ (void *, struct stab_handle *, struct demangle_component *, debug_type,
+ bfd_boolean *);
/* Save a string in memory. */
static char *
-savestring (start, len)
- const char *start;
- int len;
+savestring (const char *start, int len)
{
char *ret;
/* Read a number from a string. */
static bfd_vma
-parse_number (pp, poverflow)
- const char **pp;
- bfd_boolean *poverflow;
+parse_number (const char **pp, bfd_boolean *poverflow)
{
unsigned long ul;
const char *orig;
/* Note that even though strtoul overflowed, it should have set *pp
to the end of the number, which is where we want it. */
-
if (sizeof (bfd_vma) > sizeof (unsigned long))
{
const char *p;
bfd_vma v;
/* Our own version of strtoul, for a bfd_vma. */
-
p = orig;
neg = FALSE;
/* If we get here, the number is too large to represent in a
bfd_vma. */
-
if (poverflow != NULL)
*poverflow = TRUE;
else
/* Give an error for a bad stab string. */
static void
-bad_stab (p)
- const char *p;
+bad_stab (const char *p)
{
fprintf (stderr, _("Bad stab: %s\n"), p);
}
/* Warn about something in a stab string. */
static void
-warn_stab (p, err)
- const char *p;
- const char *err;
+warn_stab (const char *p, const char *err)
{
fprintf (stderr, _("Warning: %s: %s\n"), err, p);
}
/* Create a handle to parse stabs symbols with. */
-PTR
-start_stab (dhandle, abfd, sections, syms, symcount)
- PTR dhandle ATTRIBUTE_UNUSED;
- bfd *abfd;
- bfd_boolean sections;
- asymbol **syms;
- long symcount;
+void *
+start_stab (void *dhandle ATTRIBUTE_UNUSED, bfd *abfd, bfd_boolean sections,
+ asymbol **syms, long symcount)
{
struct stab_handle *ret;
ret->file_types = (struct stab_types **) xmalloc (sizeof *ret->file_types);
ret->file_types[0] = NULL;
ret->function_end = (bfd_vma) -1;
- return (PTR) ret;
+ return (void *) ret;
}
/* When we have processed all the stabs information, we need to go
through and fill in all the undefined tags. */
bfd_boolean
-finish_stab (dhandle, handle)
- PTR dhandle;
- PTR handle;
+finish_stab (void *dhandle, void *handle)
{
struct stab_handle *info = (struct stab_handle *) handle;
struct stab_tag *st;
/* Handle a single stabs symbol. */
bfd_boolean
-parse_stab (dhandle, handle, type, desc, value, string)
- PTR dhandle;
- PTR handle;
- int type;
- int desc;
- bfd_vma value;
- const char *string;
+parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value,
+ const char *string)
{
struct stab_handle *info = (struct stab_handle *) handle;
/* Parse the stabs string. */
static bfd_boolean
-parse_stab_string (dhandle, info, stabtype, desc, value, string)
- PTR dhandle;
- struct stab_handle *info;
- int stabtype;
- int desc;
- bfd_vma value;
- const char *string;
+parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
+ int desc, bfd_vma value, const char *string)
{
const char *p;
char *name;
address on a big endian machine if it is smaller than an int.
We have no way to do that, since we don't really know much
about the target. */
-
break;
case 'P':
/* FIXME: At this point gdb checks to combine pairs of 'p' and
'r' stabs into a single 'P' stab. */
-
break;
case 'S':
- /* Static symbol at top level of file */
+ /* Static symbol at top level of file. */
dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
(debug_type **) NULL);
if (dtype == DEBUG_TYPE_NULL)
store the slot used if the type is being defined. */
static debug_type
-parse_stab_type (dhandle, info, typename, pp, slotp)
- PTR dhandle;
- struct stab_handle *info;
- const char *typename;
- const char **pp;
- debug_type **slotp;
+parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename, const char **pp, debug_type **slotp)
{
const char *orig;
int typenums[2];
return DEBUG_TYPE_NULL;
if (**pp != '=')
- {
- /* Type is not being defined here. Either it already
- exists, or this is a forward reference to it. */
- return stab_find_type (dhandle, info, typenums);
- }
+ /* Type is not being defined here. Either it already
+ exists, or this is a forward reference to it. */
+ return stab_find_type (dhandle, info, typenums);
/* Only set the slot if the type is being defined. This means
that the mapping from type numbers to types will only record
const char *attr;
if (ISDIGIT (*p) || *p == '(' || *p == '-')
- {
- /* Member type. */
- break;
- }
+ /* Member type. */
+ break;
/* Type attributes. */
attr = p;
const char *q1, *q2, *p;
/* A cross reference to another type. */
-
switch (**pp)
{
case 's':
int xtypenums[2];
/* This type is defined as another type. */
-
(*pp)--;
hold = *pp;
{
alloc += 10;
args = ((debug_type *)
- xrealloc ((PTR) args, alloc * sizeof *args));
+ xrealloc (args, alloc * sizeof *args));
}
args[n] = parse_stab_type (dhandle, info, (const char *) NULL,
storing them in the vector TYPENUMS. */
static bfd_boolean
-parse_stab_type_number (pp, typenums)
- const char **pp;
- int *typenums;
+parse_stab_type_number (const char **pp, int *typenums)
{
const char *orig;
/* Parse a range type. */
static debug_type
-parse_stab_range_type (dhandle, info, typename, pp, typenums)
- PTR dhandle;
- struct stab_handle *info;
- const char *typename;
- const char **pp;
- const int *typenums;
+parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *typename, const char **pp, const int *typenums)
{
const char *orig;
int rangenums[2];
{
/* gcc will emit range stabs for long long types. Handle this
as a special case. FIXME: This needs to be more general. */
-#define LLLOW "01000000000000000000000;"
-#define LLHIGH "0777777777777777777777;"
+#define LLLOW "01000000000000000000000;"
+#define LLHIGH "0777777777777777777777;"
#define ULLHIGH "01777777777777777777777;"
if (index_type == DEBUG_TYPE_NULL)
{
FIXME. */
static debug_type
-parse_stab_sun_builtin_type (dhandle, pp)
- PTR dhandle;
- const char **pp;
+parse_stab_sun_builtin_type (void *dhandle, const char **pp)
{
const char *orig;
bfd_boolean unsignedp;
/* Parse a builtin floating type generated by the Sun compiler. */
static debug_type
-parse_stab_sun_floating_type (dhandle, pp)
- PTR dhandle;
- const char **pp;
+parse_stab_sun_floating_type (void *dhandle, const char **pp)
{
const char *orig;
bfd_vma details;
/* Handle an enum type. */
static debug_type
-parse_stab_enum_type (dhandle, pp)
- PTR dhandle;
- const char **pp;
+parse_stab_enum_type (void *dhandle, const char **pp)
{
const char *orig;
const char **names;
{
alloc += 10;
names = ((const char **)
- xrealloc ((PTR) names, alloc * sizeof *names));
+ xrealloc (names, alloc * sizeof *names));
values = ((bfd_signed_vma *)
- xrealloc ((PTR) values, alloc * sizeof *values));
+ xrealloc (values, alloc * sizeof *values));
}
names[n] = name;
describing the type.
PP points to a character pointer that points to the next unconsumed token
- in the the stabs string. For example, given stabs "A:T4=s4a:1,0,32;;",
+ in the stabs string. For example, given stabs "A:T4=s4a:1,0,32;;",
*PP will point to "4a:1,0,32;;". */
static debug_type
-parse_stab_struct_type (dhandle, info, tagname, pp, structp, typenums)
- PTR dhandle;
- struct stab_handle *info;
- const char *tagname;
- const char **pp;
- bfd_boolean structp;
- const int *typenums;
+parse_stab_struct_type (void *dhandle, struct stab_handle *info,
+ const char *tagname, const char **pp,
+ bfd_boolean structp, const int *typenums)
{
const char *orig;
bfd_vma size;
the type for the base class, and a terminating semicolon.
A typical example, with two base classes, would be "!2,020,19;0264,21;".
- ^^ ^ ^ ^ ^ ^ ^
+ ^^ ^ ^ ^ ^ ^ ^
Baseclass information marker __________________|| | | | | | |
Number of baseclasses __________________________| | | | | | |
Visibility specifiers (2) ________________________| | | | | |
Return TRUE for success, FALSE for failure. */
static bfd_boolean
-parse_stab_baseclasses (dhandle, info, pp, retp)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- debug_baseclass **retp;
+parse_stab_baseclasses (void *dhandle, struct stab_handle *info,
+ const char **pp, debug_baseclass **retp)
{
const char *orig;
unsigned int c, i;
/* Read struct or class data fields. They have the form:
- NAME : [VISIBILITY] TYPENUM , BITPOS , BITSIZE ;
+ NAME : [VISIBILITY] TYPENUM , BITPOS , BITSIZE ;
At the end, we see a semicolon instead of a field.
The optional VISIBILITY is one of:
- '/0' (VISIBILITY_PRIVATE)
+ '/0' (VISIBILITY_PRIVATE)
'/1' (VISIBILITY_PROTECTED)
'/2' (VISIBILITY_PUBLIC)
'/9' (VISIBILITY_IGNORE)
Returns 1 for success, 0 for failure. */
static bfd_boolean
-parse_stab_struct_fields (dhandle, info, pp, retp, staticsp)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- debug_field **retp;
- bfd_boolean *staticsp;
+parse_stab_struct_fields (void *dhandle, struct stab_handle *info,
+ const char **pp, debug_field **retp,
+ bfd_boolean *staticsp)
{
const char *orig;
const char *p;
{
alloc += 10;
fields = ((debug_field *)
- xrealloc ((PTR) fields, alloc * sizeof *fields));
+ xrealloc (fields, alloc * sizeof *fields));
}
/* If it starts with CPLUS_MARKER it is a special abbreviation,
/* Special GNU C++ name. */
static bfd_boolean
-parse_stab_cpp_abbrev (dhandle, info, pp, retp)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- debug_field *retp;
+parse_stab_cpp_abbrev (void *dhandle, struct stab_handle *info,
+ const char **pp, debug_field *retp)
{
const char *orig;
int cpp_abbrev;
/* Parse a single field in a struct or union. */
static bfd_boolean
-parse_stab_one_struct_field (dhandle, info, pp, p, retp, staticsp)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- const char *p;
- debug_field *retp;
- bfd_boolean *staticsp;
+parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
+ const char **pp, const char *p,
+ debug_field *retp, bfd_boolean *staticsp)
{
const char *orig;
char *name;
name (such as `+=') and `.' marks the end of the operator name. */
static bfd_boolean
-parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
- PTR dhandle;
- struct stab_handle *info;
- const char *tagname;
- const char **pp;
- const int *typenums;
- debug_method **retp;
+parse_stab_members (void *dhandle, struct stab_handle *info,
+ const char *tagname, const char **pp,
+ const int *typenums, debug_method **retp)
{
const char *orig;
debug_method *methods;
}
else
{
- /* This is a completely wierd case. In order to stuff in the
+ /* This is a completely weird case. In order to stuff in the
names that might contain colons (the usual name delimiter),
Mike Tiemann defined a different name format which is
signalled if the identifier is "op$". In that case, the
{
allocvars += 10;
variants = ((debug_method_variant *)
- xrealloc ((PTR) variants,
+ xrealloc (variants,
allocvars * sizeof *variants));
}
{
alloc += 10;
methods = ((debug_method *)
- xrealloc ((PTR) methods, alloc * sizeof *methods));
+ xrealloc (methods, alloc * sizeof *methods));
}
methods[c] = debug_make_method (dhandle, name, variants);
the tag name. */
static debug_type
-parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname,
- return_type, argtypes, constp, volatilep, pphysname)
- PTR dhandle;
- struct stab_handle *info;
- debug_type class_type;
- const char *fieldname;
- const char *tagname;
- debug_type return_type;
- const char *argtypes;
- bfd_boolean constp;
- bfd_boolean volatilep;
- const char **pphysname;
+parse_stab_argtypes (void *dhandle, struct stab_handle *info,
+ debug_type class_type, const char *fieldname,
+ const char *tagname, debug_type return_type,
+ const char *argtypes, bfd_boolean constp,
+ bfd_boolean volatilep, const char **pphysname)
{
bfd_boolean is_full_physname_constructor;
bfd_boolean is_constructor;
bfd_boolean is_destructor;
+ bfd_boolean is_v3;
debug_type *args;
bfd_boolean varargs;
unsigned int physname_len = 0;
&& (argtypes[1] == '$' || argtypes[1] == '.')
&& argtypes[2] == '_')
|| strncmp (argtypes, "__dt", 4) == 0);
+ is_v3 = argtypes[0] == '_' && argtypes[1] == 'Z';
- if (is_destructor || is_full_physname_constructor)
+ if (is_destructor || is_full_physname_constructor || is_v3)
*pphysname = argtypes;
else
{
so we can look for the vptr base class info. */
static bfd_boolean
-parse_stab_tilde_field (dhandle, info, pp, typenums, retvptrbase, retownvptr)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- const int *typenums;
- debug_type *retvptrbase;
- bfd_boolean *retownvptr;
+parse_stab_tilde_field (void *dhandle, struct stab_handle *info,
+ const char **pp, const int *typenums,
+ debug_type *retvptrbase, bfd_boolean *retownvptr)
{
const char *orig;
const char *hold;
/* Read a definition of an array type. */
static debug_type
-parse_stab_array_type (dhandle, info, pp, stringp)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- bfd_boolean stringp;
+parse_stab_array_type (void *dhandle, struct stab_handle *info,
+ const char **pp, bfd_boolean stringp)
{
const char *orig;
const char *p;
/* Start a new N_BINCL file, pushing it onto the stack. */
static void
-push_bincl (info, name, hash)
- struct stab_handle *info;
- const char *name;
- bfd_vma hash;
+push_bincl (struct stab_handle *info, const char *name, bfd_vma hash)
{
struct bincl_file *n;
++info->files;
info->file_types = ((struct stab_types **)
- xrealloc ((PTR) info->file_types,
+ xrealloc (info->file_types,
(info->files
* sizeof *info->file_types)));
info->file_types[n->file] = NULL;
stack. */
static const char *
-pop_bincl (info)
- struct stab_handle *info;
+pop_bincl (struct stab_handle *info)
{
struct bincl_file *o;
/* Handle an N_EXCL: get the types from the corresponding N_BINCL. */
static bfd_boolean
-find_excl (info, name, hash)
- struct stab_handle *info;
- const char *name;
- bfd_vma hash;
+find_excl (struct stab_handle *info, const char *name, bfd_vma hash)
{
struct bincl_file *l;
++info->files;
info->file_types = ((struct stab_types **)
- xrealloc ((PTR) info->file_types,
+ xrealloc (info->file_types,
(info->files
* sizeof *info->file_types)));
N_LBRAC, so we can call debug_record_variable immediately. */
static bfd_boolean
-stab_record_variable (dhandle, info, name, type, kind, val)
- PTR dhandle;
- struct stab_handle *info;
- const char *name;
- debug_type type;
- enum debug_var_kind kind;
- bfd_vma val;
+stab_record_variable (void *dhandle, struct stab_handle *info,
+ const char *name, debug_type type,
+ enum debug_var_kind kind, bfd_vma val)
{
struct stab_pending_var *v;
N_LBRAC that starts the block. */
static bfd_boolean
-stab_emit_pending_vars (dhandle, info)
- PTR dhandle;
- struct stab_handle *info;
+stab_emit_pending_vars (void *dhandle, struct stab_handle *info)
{
struct stab_pending_var *v;
/* Find the slot for a type in the database. */
static debug_type *
-stab_find_slot (info, typenums)
- struct stab_handle *info;
- const int *typenums;
+stab_find_slot (struct stab_handle *info, const int *typenums)
{
int filenum;
int index;
allocated yet, create an indirect type. */
static debug_type
-stab_find_type (dhandle, info, typenums)
- PTR dhandle;
- struct stab_handle *info;
- const int *typenums;
+stab_find_type (void *dhandle, struct stab_handle *info, const int *typenums)
{
debug_type *slot;
/* Record that a given type number refers to a given type. */
static bfd_boolean
-stab_record_type (dhandle, info, typenums, type)
- PTR dhandle ATTRIBUTE_UNUSED;
- struct stab_handle *info;
- const int *typenums;
- debug_type type;
+stab_record_type (void *dhandle ATTRIBUTE_UNUSED, struct stab_handle *info,
+ const int *typenums, debug_type type)
{
debug_type *slot;
/* Return an XCOFF builtin type. */
static debug_type
-stab_xcoff_builtin_type (dhandle, info, typenum)
- PTR dhandle;
- struct stab_handle *info;
- int typenum;
+stab_xcoff_builtin_type (void *dhandle, struct stab_handle *info,
+ int typenum)
{
debug_type rettype;
const char *name;
/* Find or create a tagged type. */
static debug_type
-stab_find_tagged_type (dhandle, info, p, len, kind)
- PTR dhandle;
- struct stab_handle *info;
- const char *p;
- int len;
- enum debug_type_kind kind;
+stab_find_tagged_type (void *dhandle, struct stab_handle *info,
+ const char *p, int len, enum debug_type_kind kind)
{
char *name;
debug_type dtype;
struct stab_demangle_info
{
/* The debugging information handle. */
- PTR dhandle;
+ void *dhandle;
/* The stab information handle. */
struct stab_handle *info;
/* The array of arguments we are building. */
unsigned int typestring_alloc;
};
-static void stab_bad_demangle
- PARAMS ((const char *));
-static unsigned int stab_demangle_count
- PARAMS ((const char **));
-static bfd_boolean stab_demangle_get_count
- PARAMS ((const char **, unsigned int *));
+static void stab_bad_demangle (const char *);
+static unsigned int stab_demangle_count (const char **);
+static bfd_boolean stab_demangle_get_count (const char **, unsigned int *);
static bfd_boolean stab_demangle_prefix
- PARAMS ((struct stab_demangle_info *, const char **, unsigned int));
+ (struct stab_demangle_info *, const char **, unsigned int);
static bfd_boolean stab_demangle_function_name
- PARAMS ((struct stab_demangle_info *, const char **, const char *));
+ (struct stab_demangle_info *, const char **, const char *);
static bfd_boolean stab_demangle_signature
- PARAMS ((struct stab_demangle_info *, const char **));
+ (struct stab_demangle_info *, const char **);
static bfd_boolean stab_demangle_qualified
- PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
+ (struct stab_demangle_info *, const char **, debug_type *);
static bfd_boolean stab_demangle_template
- PARAMS ((struct stab_demangle_info *, const char **, char **));
+ (struct stab_demangle_info *, const char **, char **);
static bfd_boolean stab_demangle_class
- PARAMS ((struct stab_demangle_info *, const char **, const char **));
+ (struct stab_demangle_info *, const char **, const char **);
static bfd_boolean stab_demangle_args
- PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
- bfd_boolean *));
+ (struct stab_demangle_info *, const char **, debug_type **, bfd_boolean *);
static bfd_boolean stab_demangle_arg
- PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
- unsigned int *, unsigned int *));
+ (struct stab_demangle_info *, const char **, debug_type **,
+ unsigned int *, unsigned int *);
static bfd_boolean stab_demangle_type
- PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
+ (struct stab_demangle_info *, const char **, debug_type *);
static bfd_boolean stab_demangle_fund_type
- PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
+ (struct stab_demangle_info *, const char **, debug_type *);
static bfd_boolean stab_demangle_remember_type
- PARAMS ((struct stab_demangle_info *, const char *, int));
+ (struct stab_demangle_info *, const char *, int);
/* Warn about a bad demangling. */
static void
-stab_bad_demangle (s)
- const char *s;
+stab_bad_demangle (const char *s)
{
fprintf (stderr, _("bad mangled name `%s'\n"), s);
}
/* Get a count from a stab string. */
static unsigned int
-stab_demangle_count (pp)
- const char **pp;
+stab_demangle_count (const char **pp)
{
unsigned int count;
which case it must end in an underscore. */
static bfd_boolean
-stab_demangle_get_count (pp, pi)
- const char **pp;
- unsigned int *pi;
+stab_demangle_get_count (const char **pp, unsigned int *pi)
{
if (! ISDIGIT (**pp))
return FALSE;
terminated array of argument types. */
static debug_type *
-stab_demangle_argtypes (dhandle, info, physname, pvarargs, physname_len)
- PTR dhandle;
- struct stab_handle *info;
- const char *physname;
- bfd_boolean *pvarargs;
- unsigned int physname_len;
+stab_demangle_argtypes (void *dhandle, struct stab_handle *info,
+ const char *physname, bfd_boolean *pvarargs,
+ unsigned int physname_len)
{
struct stab_demangle_info minfo;
+ /* Check for the g++ V3 ABI. */
+ if (physname[0] == '_' && physname[1] == 'Z')
+ return stab_demangle_v3_argtypes (dhandle, info, physname, pvarargs);
+
minfo.dhandle = dhandle;
minfo.info = info;
minfo.args = NULL;
/* Demangle the prefix of the mangled name. */
static bfd_boolean
-stab_demangle_prefix (minfo, pp, physname_len)
- struct stab_demangle_info *minfo;
- const char **pp;
- unsigned int physname_len;
+stab_demangle_prefix (struct stab_demangle_info *minfo, const char **pp,
+ unsigned int physname_len)
{
const char *scan;
unsigned int i;
signature. */
static bfd_boolean
-stab_demangle_function_name (minfo, pp, scan)
- struct stab_demangle_info *minfo;
- const char **pp;
- const char *scan;
+stab_demangle_function_name (struct stab_demangle_info *minfo,
+ const char **pp, const char *scan)
{
const char *name;
found. */
static bfd_boolean
-stab_demangle_signature (minfo, pp)
- struct stab_demangle_info *minfo;
- const char **pp;
+stab_demangle_signature (struct stab_demangle_info *minfo, const char **pp)
{
const char *orig;
bfd_boolean expect_func, func_done;
mangled form of "Outer::Inner". */
static bfd_boolean
-stab_demangle_qualified (minfo, pp, ptype)
- struct stab_demangle_info *minfo;
- const char **pp;
- debug_type *ptype;
+stab_demangle_qualified (struct stab_demangle_info *minfo, const char **pp,
+ debug_type *ptype)
{
const char *orig;
const char *p;
string representation of the template. */
static bfd_boolean
-stab_demangle_template (minfo, pp, pname)
- struct stab_demangle_info *minfo;
- const char **pp;
- char **pname;
+stab_demangle_template (struct stab_demangle_info *minfo, const char **pp,
+ char **pname)
{
const char *orig;
unsigned int r, i;
/* Demangle a class name. */
static bfd_boolean
-stab_demangle_class (minfo, pp, pstart)
- struct stab_demangle_info *minfo ATTRIBUTE_UNUSED;
- const char **pp;
- const char **pstart;
+stab_demangle_class (struct stab_demangle_info *minfo ATTRIBUTE_UNUSED,
+ const char **pp, const char **pstart)
{
const char *orig;
unsigned int n;
is set to a NULL terminated array holding the arguments. */
static bfd_boolean
-stab_demangle_args (minfo, pp, pargs, pvarargs)
- struct stab_demangle_info *minfo;
- const char **pp;
- debug_type **pargs;
- bfd_boolean *pvarargs;
+stab_demangle_args (struct stab_demangle_info *minfo, const char **pp,
+ debug_type **pargs, bfd_boolean *pvarargs)
{
const char *orig;
unsigned int alloc, count;
/* Demangle a single argument. */
static bfd_boolean
-stab_demangle_arg (minfo, pp, pargs, pcount, palloc)
- struct stab_demangle_info *minfo;
- const char **pp;
- debug_type **pargs;
- unsigned int *pcount;
- unsigned int *palloc;
+stab_demangle_arg (struct stab_demangle_info *minfo, const char **pp,
+ debug_type **pargs, unsigned int *pcount,
+ unsigned int *palloc)
{
const char *start;
debug_type type;
to the newly allocated type. */
static bfd_boolean
-stab_demangle_type (minfo, pp, ptype)
- struct stab_demangle_info *minfo;
- const char **pp;
- debug_type *ptype;
+stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
+ debug_type *ptype)
{
const char *orig;
*ptype is set to the newly allocated type. */
static bfd_boolean
-stab_demangle_fund_type (minfo, pp, ptype)
- struct stab_demangle_info *minfo;
- const char **pp;
- debug_type *ptype;
+stab_demangle_fund_type (struct stab_demangle_info *minfo, const char **pp,
+ debug_type *ptype)
{
const char *orig;
bfd_boolean constp, volatilep, unsignedp, signedp;
/* Remember a type string in a demangled string. */
static bfd_boolean
-stab_demangle_remember_type (minfo, p, len)
- struct stab_demangle_info *minfo;
- const char *p;
- int len;
+stab_demangle_remember_type (struct stab_demangle_info *minfo,
+ const char *p, int len)
{
if (minfo->typestring_count >= minfo->typestring_alloc)
{
return TRUE;
}
+\f
+/* Demangle names encoded using the g++ V3 ABI. The newer versions of
+ g++ which use this ABI do not encode ordinary method argument types
+ in a mangled name; they simply output the argument types. However,
+ for a static method, g++ simply outputs the return type and the
+ physical name. So in that case we need to demangle the name here.
+ Here PHYSNAME is the physical name of the function, and we set the
+ variable pointed at by PVARARGS to indicate whether this function
+ is varargs. This returns NULL, or a NULL terminated array of
+ argument types. */
+
+static debug_type *
+stab_demangle_v3_argtypes (void *dhandle, struct stab_handle *info,
+ const char *physname, bfd_boolean *pvarargs)
+{
+ struct demangle_component *dc;
+ void *mem;
+ unsigned int alloc, count;
+ debug_type *pargs;
+
+ dc = cplus_demangle_v3_components (physname, DMGL_PARAMS | DMGL_ANSI, &mem);
+ if (dc == NULL)
+ {
+ stab_bad_demangle (physname);
+ return NULL;
+ }
+
+ /* We expect to see TYPED_NAME, and the right subtree describes the
+ function type. */
+ if (dc->type != DEMANGLE_COMPONENT_TYPED_NAME
+ || dc->u.s_binary.right->type != DEMANGLE_COMPONENT_FUNCTION_TYPE)
+ {
+ fprintf (stderr, _("Demangled name is not a function\n"));
+ free (mem);
+ return NULL;
+ }
+
+ alloc = 10;
+ pargs = (debug_type *) xmalloc (alloc * sizeof *pargs);
+ *pvarargs = FALSE;
+
+ count = 0;
+
+ for (dc = dc->u.s_binary.right->u.s_binary.right;
+ dc != NULL;
+ dc = dc->u.s_binary.right)
+ {
+ debug_type arg;
+ bfd_boolean varargs;
+
+ if (dc->type != DEMANGLE_COMPONENT_ARGLIST)
+ {
+ fprintf (stderr, _("Unexpected type in demangle tree\n"));
+ free (mem);
+ return NULL;
+ }
+
+ arg = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left,
+ NULL, &varargs);
+ if (arg == NULL)
+ {
+ if (varargs)
+ {
+ *pvarargs = TRUE;
+ continue;
+ }
+ free (mem);
+ return NULL;
+ }
+
+ if (count + 1 >= alloc)
+ {
+ alloc += 10;
+ pargs = (debug_type *) xrealloc (pargs, alloc * sizeof *pargs);
+ }
+
+ pargs[count] = arg;
+ ++count;
+ }
+
+ pargs[count] = DEBUG_TYPE_NULL;
+
+ free (mem);
+
+ return pargs;
+}
+
+/* Convert a struct demangle_component tree describing an argument
+ type into a debug_type. */
+
+static debug_type
+stab_demangle_v3_arg (void *dhandle, struct stab_handle *info,
+ struct demangle_component *dc, debug_type context,
+ bfd_boolean *pvarargs)
+{
+ debug_type dt;
+
+ if (pvarargs != NULL)
+ *pvarargs = FALSE;
+
+ switch (dc->type)
+ {
+ /* FIXME: These are demangle component types which we probably
+ need to handle one way or another. */
+ case DEMANGLE_COMPONENT_LOCAL_NAME:
+ case DEMANGLE_COMPONENT_TYPED_NAME:
+ case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
+ case DEMANGLE_COMPONENT_CTOR:
+ case DEMANGLE_COMPONENT_DTOR:
+ case DEMANGLE_COMPONENT_JAVA_CLASS:
+ case DEMANGLE_COMPONENT_RESTRICT_THIS:
+ case DEMANGLE_COMPONENT_VOLATILE_THIS:
+ case DEMANGLE_COMPONENT_CONST_THIS:
+ case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
+ case DEMANGLE_COMPONENT_COMPLEX:
+ case DEMANGLE_COMPONENT_IMAGINARY:
+ case DEMANGLE_COMPONENT_VENDOR_TYPE:
+ case DEMANGLE_COMPONENT_FUNCTION_TYPE:
+ case DEMANGLE_COMPONENT_ARRAY_TYPE:
+ case DEMANGLE_COMPONENT_PTRMEM_TYPE:
+ case DEMANGLE_COMPONENT_ARGLIST:
+ default:
+ fprintf (stderr, _("Unrecognized demangle component\n"));
+ return NULL;
+
+ case DEMANGLE_COMPONENT_NAME:
+ if (context != NULL)
+ {
+ const debug_field *fields;
+
+ fields = debug_get_fields (dhandle, context);
+ if (fields != NULL)
+ {
+ /* Try to find this type by looking through the context
+ class. */
+ for (; *fields != DEBUG_FIELD_NULL; fields++)
+ {
+ debug_type ft;
+ const char *dn;
+
+ ft = debug_get_field_type (dhandle, *fields);
+ if (ft == NULL)
+ return NULL;
+ dn = debug_get_type_name (dhandle, ft);
+ if (dn != NULL
+ && (int) strlen (dn) == dc->u.s_name.len
+ && strncmp (dn, dc->u.s_name.s, dc->u.s_name.len) == 0)
+ return ft;
+ }
+ }
+ }
+ return stab_find_tagged_type (dhandle, info, dc->u.s_name.s,
+ dc->u.s_name.len, DEBUG_KIND_ILLEGAL);
+
+ case DEMANGLE_COMPONENT_QUAL_NAME:
+ context = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left,
+ context, NULL);
+ if (context == NULL)
+ return NULL;
+ return stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.right,
+ context, NULL);
+
+ case DEMANGLE_COMPONENT_TEMPLATE:
+ {
+ char *p;
+ size_t alc;
+
+ /* We print this component to get a class name which we can
+ use. FIXME: This probably won't work if the template uses
+ template parameters which refer to an outer template. */
+ p = cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, dc, 20, &alc);
+ if (p == NULL)
+ {
+ fprintf (stderr, _("Failed to print demangled template\n"));
+ return NULL;
+ }
+ dt = stab_find_tagged_type (dhandle, info, p, strlen (p),
+ DEBUG_KIND_CLASS);
+ free (p);
+ return dt;
+ }
+
+ case DEMANGLE_COMPONENT_SUB_STD:
+ return stab_find_tagged_type (dhandle, info, dc->u.s_string.string,
+ dc->u.s_string.len, DEBUG_KIND_ILLEGAL);
+
+ case DEMANGLE_COMPONENT_RESTRICT:
+ case DEMANGLE_COMPONENT_VOLATILE:
+ case DEMANGLE_COMPONENT_CONST:
+ case DEMANGLE_COMPONENT_POINTER:
+ case DEMANGLE_COMPONENT_REFERENCE:
+ dt = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left, NULL,
+ NULL);
+ if (dt == NULL)
+ return NULL;
+
+ switch (dc->type)
+ {
+ default:
+ abort ();
+ case DEMANGLE_COMPONENT_RESTRICT:
+ /* FIXME: We have no way to represent restrict. */
+ return dt;
+ case DEMANGLE_COMPONENT_VOLATILE:
+ return debug_make_volatile_type (dhandle, dt);
+ case DEMANGLE_COMPONENT_CONST:
+ return debug_make_const_type (dhandle, dt);
+ case DEMANGLE_COMPONENT_POINTER:
+ return debug_make_pointer_type (dhandle, dt);
+ case DEMANGLE_COMPONENT_REFERENCE:
+ return debug_make_reference_type (dhandle, dt);
+ }
+
+ case DEMANGLE_COMPONENT_BUILTIN_TYPE:
+ {
+ char *p;
+ size_t alc;
+ debug_type ret;
+
+ /* We print this component in order to find out the type name.
+ FIXME: Should we instead expose the
+ demangle_builtin_type_info structure? */
+ p = cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, dc, 20, &alc);
+ if (p == NULL)
+ {
+ fprintf (stderr, _("Couldn't get demangled builtin type\n"));
+ return NULL;
+ }
+
+ /* The mangling is based on the type, but does not itself
+ indicate what the sizes are. So we have to guess. */
+ if (strcmp (p, "signed char") == 0)
+ ret = debug_make_int_type (dhandle, 1, FALSE);
+ else if (strcmp (p, "bool") == 0)
+ ret = debug_make_bool_type (dhandle, 1);
+ else if (strcmp (p, "char") == 0)
+ ret = debug_make_int_type (dhandle, 1, FALSE);
+ else if (strcmp (p, "double") == 0)
+ ret = debug_make_float_type (dhandle, 8);
+ else if (strcmp (p, "long double") == 0)
+ ret = debug_make_float_type (dhandle, 8);
+ else if (strcmp (p, "float") == 0)
+ ret = debug_make_float_type (dhandle, 4);
+ else if (strcmp (p, "__float128") == 0)
+ ret = debug_make_float_type (dhandle, 16);
+ else if (strcmp (p, "unsigned char") == 0)
+ ret = debug_make_int_type (dhandle, 1, TRUE);
+ else if (strcmp (p, "int") == 0)
+ ret = debug_make_int_type (dhandle, 4, FALSE);
+ else if (strcmp (p, "unsigned int") == 0)
+ ret = debug_make_int_type (dhandle, 4, TRUE);
+ else if (strcmp (p, "long") == 0)
+ ret = debug_make_int_type (dhandle, 4, FALSE);
+ else if (strcmp (p, "unsigned long") == 0)
+ ret = debug_make_int_type (dhandle, 4, TRUE);
+ else if (strcmp (p, "__int128") == 0)
+ ret = debug_make_int_type (dhandle, 16, FALSE);
+ else if (strcmp (p, "unsigned __int128") == 0)
+ ret = debug_make_int_type (dhandle, 16, TRUE);
+ else if (strcmp (p, "short") == 0)
+ ret = debug_make_int_type (dhandle, 2, FALSE);
+ else if (strcmp (p, "unsigned short") == 0)
+ ret = debug_make_int_type (dhandle, 2, TRUE);
+ else if (strcmp (p, "void") == 0)
+ ret = debug_make_void_type (dhandle);
+ else if (strcmp (p, "wchar_t") == 0)
+ ret = debug_make_int_type (dhandle, 4, TRUE);
+ else if (strcmp (p, "long long") == 0)
+ ret = debug_make_int_type (dhandle, 8, FALSE);
+ else if (strcmp (p, "unsigned long long") == 0)
+ ret = debug_make_int_type (dhandle, 8, TRUE);
+ else if (strcmp (p, "...") == 0)
+ {
+ if (pvarargs == NULL)
+ fprintf (stderr, _("Unexpected demangled varargs\n"));
+ else
+ *pvarargs = TRUE;
+ ret = NULL;
+ }
+ else
+ {
+ fprintf (stderr, _("Unrecognized demangled builtin type\n"));
+ ret = NULL;
+ }
+
+ free (p);
+
+ return ret;
+ }
+ }
+}