* stabs.c (parse_stab_argtypes): Handle g++ ABI version 3 names.
(stab_demangle_argtypes): Likewise. (stab_demangle_v3_argtypes): New static function. (stab_demangle_v3_arg): New static function.
This commit is contained in:
parent
954a7fba02
commit
041821e62e
@ -1,3 +1,10 @@
|
||||
2004-01-12 Ian Lance Taylor <ian@wasabisystems.com>
|
||||
|
||||
* stabs.c (parse_stab_argtypes): Handle g++ ABI version 3 names.
|
||||
(stab_demangle_argtypes): Likewise.
|
||||
(stab_demangle_v3_argtypes): New static function.
|
||||
(stab_demangle_v3_arg): New static function.
|
||||
|
||||
2004-01-12 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* objcopy.c (copy_object): Make the function boolean, returning
|
||||
|
304
binutils/stabs.c
304
binutils/stabs.c
@ -201,6 +201,11 @@ static debug_type stab_find_tagged_type
|
||||
(void *, struct stab_handle *, const char *, int, enum debug_type_kind);
|
||||
static debug_type *stab_demangle_argtypes
|
||||
(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. */
|
||||
|
||||
@ -2814,6 +2819,7 @@ parse_stab_argtypes (void *dhandle, struct stab_handle *info,
|
||||
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;
|
||||
@ -2833,8 +2839,9 @@ parse_stab_argtypes (void *dhandle, struct stab_handle *info,
|
||||
&& (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
|
||||
{
|
||||
@ -3697,6 +3704,10 @@ stab_demangle_argtypes (void *dhandle, struct stab_handle *info,
|
||||
{
|
||||
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;
|
||||
@ -5045,3 +5056,294 @@ stab_demangle_remember_type (struct stab_demangle_info *minfo,
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user