/* stabs.c -- Parse stabs debugging information
- Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
- Free Software Foundation, Inc.
+ Copyright (C) 1995-2020 Free Software Foundation, Inc.
Written by Ian Lance Taylor <ian@cygnus.com>.
This file is part of GNU Binutils.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
/* This file contains code which parses stabs debugging information.
The organization of this code is based on the gdb stabs reading
code. The job it does is somewhat different, because it is not
trying to identify the correct address for anything. */
-#include <stdio.h>
-
+#include "sysdep.h"
#include "bfd.h"
-#include "bucomm.h"
#include "libiberty.h"
#include "safe-ctype.h"
#include "demangle.h"
};
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
- (void *, struct stab_handle *, int, int, bfd_vma, const char *);
+ (void *, struct stab_handle *, int, int, bfd_vma,
+ const char *, const char *);
static debug_type parse_stab_type
- (void *, struct stab_handle *, const char *, const char **, debug_type **);
-static bfd_boolean parse_stab_type_number (const char **, int *);
+ (void *, struct stab_handle *, const char *, const char **,
+ debug_type **, const char *);
+static bfd_boolean parse_stab_type_number
+ (const char **, int *, const char *);
static debug_type parse_stab_range_type
- (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 **);
+ (void *, struct stab_handle *, const char *, const char **,
+ const int *, const char *);
+static debug_type parse_stab_sun_builtin_type
+ (void *, const char **, const char *);
+static debug_type parse_stab_sun_floating_type
+ (void *, const char **, const char *);
+static debug_type parse_stab_enum_type
+ (void *, const char **, const char *);
static debug_type parse_stab_struct_type
(void *, struct stab_handle *, const char *, const char **,
- bfd_boolean, const int *);
+ bfd_boolean, const int *, const char *);
static bfd_boolean parse_stab_baseclasses
- (void *, struct stab_handle *, const char **, debug_baseclass **);
+ (void *, struct stab_handle *, const char **, debug_baseclass **,
+ const char *);
static bfd_boolean parse_stab_struct_fields
- (void *, struct stab_handle *, const char **, debug_field **, bfd_boolean *);
+ (void *, struct stab_handle *, const char **, debug_field **,
+ bfd_boolean *, const char *);
static bfd_boolean parse_stab_cpp_abbrev
- (void *, struct stab_handle *, const char **, debug_field *);
+ (void *, struct stab_handle *, const char **, debug_field *, const char *);
static bfd_boolean parse_stab_one_struct_field
(void *, struct stab_handle *, const char **, const char *,
- debug_field *, bfd_boolean *);
+ debug_field *, bfd_boolean *, const char *);
static bfd_boolean parse_stab_members
(void *, struct stab_handle *, const char *, const char **, const int *,
- debug_method **);
+ debug_method **, const char *);
static debug_type parse_stab_argtypes
(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
(void *, struct stab_handle *, const char **, const int *, debug_type *,
- bfd_boolean *);
+ bfd_boolean *, const char *);
static debug_type parse_stab_array_type
- (void *, struct stab_handle *, const char **, bfd_boolean);
+ (void *, struct stab_handle *, const char **, bfd_boolean, const char *);
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);
(void *, struct stab_handle *, struct demangle_component *, debug_type,
bfd_boolean *);
+static int demangle_flags = DMGL_ANSI;
+
/* Save a string in memory. */
static char *
/* Read a number from a string. */
static bfd_vma
-parse_number (const char **pp, bfd_boolean *poverflow)
+parse_number (const char **pp, bfd_boolean *poverflow, const char *p_end)
{
unsigned long ul;
const char *orig;
*poverflow = FALSE;
orig = *pp;
+ if (orig >= p_end)
+ return (bfd_vma) 0;
+
+ /* Stop early if we are passed an empty string. */
+ if (*orig == 0)
+ return (bfd_vma) 0;
errno = 0;
ul = strtoul (*pp, (char **) pp, 0);
parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value,
const char *string)
{
+ const char * string_end;
struct stab_handle *info = (struct stab_handle *) handle;
/* gcc will emit two N_SO strings per compilation unit, one for the
info->file_types = ((struct stab_types **)
xmalloc (sizeof *info->file_types));
info->file_types[0] = NULL;
-
info->so_string = NULL;
/* Now process whatever type we just got. */
}
+ string_end = string + strlen (string);
+
switch (type)
{
case N_FN:
info->within_function = TRUE;
}
- if (! parse_stab_string (dhandle, info, type, desc, value, string))
+ if (! parse_stab_string (dhandle, info, type, desc, value, string, string_end))
return FALSE;
}
break;
static bfd_boolean
parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
- int desc, bfd_vma value, const char *string)
+ int desc ATTRIBUTE_UNUSED, bfd_vma value,
+ const char *string, const char * string_end)
{
const char *p;
char *name;
debug_type dtype;
bfd_boolean synonym;
bfd_boolean self_crossref;
- unsigned int lineno;
debug_type *slot;
p = strchr (string, ':');
}
}
- /* GCC 2.x puts the line number in desc. SunOS apparently puts in
- the number of bytes occupied by a type or object, which we
- ignore. */
- if (info->gcc_compiled >= 2)
- lineno = desc;
- else
- lineno = 0;
-
/* FIXME: Sometimes the special C++ names start with '.'. */
name = NULL;
if (string[0] == '$')
++p;
if (ISDIGIT (*p) || *p == '(' || *p == '-')
type = 'l';
+ else if (*p == 0)
+ {
+ bad_stab (string);
+ return FALSE;
+ }
else
type = *p++;
e.g. "b:c=e6,0" for "const b = blob1"
(where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
dtype = parse_stab_type (dhandle, info, (const char *) NULL,
- &p, (debug_type **) NULL);
+ &p, (debug_type **) NULL, string_end);
if (dtype == DEBUG_TYPE_NULL)
return FALSE;
if (*p != ',')
case 'C':
/* The name of a caught exception. */
dtype = parse_stab_type (dhandle, info, (const char *) NULL,
- &p, (debug_type **) NULL);
+ &p, (debug_type **) NULL, string_end);
if (dtype == DEBUG_TYPE_NULL)
return FALSE;
if (! debug_record_label (dhandle, name, dtype, value))
case 'F':
/* A function definition. */
dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
+ (debug_type **) NULL, string_end);
if (dtype == DEBUG_TYPE_NULL)
return FALSE;
if (! debug_record_function (dhandle, name, dtype, type == 'F', value))
{
++p;
if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL)
+ (debug_type **) NULL, string_end)
== DEBUG_TYPE_NULL)
return FALSE;
}
case 'G':
{
- char leading;
- long c;
asymbol **ps;
/* A global symbol. The value must be extracted from the
symbol table. */
dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
+ (debug_type **) NULL, string_end);
if (dtype == DEBUG_TYPE_NULL)
return FALSE;
- leading = bfd_get_symbol_leading_char (info->abfd);
- for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
+ if (name != NULL)
{
- const char *n;
+ char leading;
+ long c;
- n = bfd_asymbol_name (*ps);
- if (leading != '\0' && *n == leading)
- ++n;
- if (*n == *name && strcmp (n, name) == 0)
- break;
+ leading = bfd_get_symbol_leading_char (info->abfd);
+ for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
+ {
+ const char *n;
+
+ n = bfd_asymbol_name (*ps);
+ if (leading != '\0' && *n == leading)
+ ++n;
+ if (*n == *name && strcmp (n, name) == 0)
+ break;
+ }
+
+ if (c > 0)
+ value = bfd_asymbol_value (*ps);
}
- if (c > 0)
- value = bfd_asymbol_value (*ps);
+
if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_GLOBAL,
value))
return FALSE;
case 'l':
case 's':
dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
+ (debug_type **) NULL, string_end);
if (dtype == DEBUG_TYPE_NULL)
return FALSE;
if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
/* A function parameter. */
if (*p != 'F')
dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
+ (debug_type **) NULL, string_end);
else
{
/* pF is a two-letter code that means a function parameter in
value. Translate it into a pointer-to-function type. */
++p;
dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
+ (debug_type **) NULL, string_end);
if (dtype != DEBUG_TYPE_NULL)
{
debug_type ftype;
{
++p;
if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL)
+ (debug_type **) NULL, string_end)
== DEBUG_TYPE_NULL)
return FALSE;
}
case 'R':
/* Parameter which is in a register. */
dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
+ (debug_type **) NULL, string_end);
if (dtype == DEBUG_TYPE_NULL)
return FALSE;
if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REG,
case 'r':
/* Register variable (either global or local). */
dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
+ (debug_type **) NULL, string_end);
if (dtype == DEBUG_TYPE_NULL)
return FALSE;
if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_REGISTER,
case 'S':
/* Static symbol at top level of file. */
dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
+ (debug_type **) NULL, string_end);
if (dtype == DEBUG_TYPE_NULL)
return FALSE;
if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_STATIC,
case 't':
/* A typedef. */
- dtype = parse_stab_type (dhandle, info, name, &p, &slot);
+ dtype = parse_stab_type (dhandle, info, name, &p, &slot, string_end);
if (dtype == DEBUG_TYPE_NULL)
return FALSE;
if (name == NULL)
break;
case 'T':
- /* Struct, union, or enum tag. For GNU C++, this can be be followed
+ /* Struct, union, or enum tag. For GNU C++, this can be followed
by 't' which means we are typedef'ing it as well. */
if (*p != 't')
{
++p;
}
- dtype = parse_stab_type (dhandle, info, name, &p, &slot);
+ dtype = parse_stab_type (dhandle, info, name, &p, &slot, string_end);
if (dtype == DEBUG_TYPE_NULL)
return FALSE;
if (name == NULL)
case 'V':
/* Static symbol of local scope */
dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
+ (debug_type **) NULL, string_end);
if (dtype == DEBUG_TYPE_NULL)
return FALSE;
/* FIXME: gdb checks os9k_stabs here. */
case 'v':
/* Reference parameter. */
dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
+ (debug_type **) NULL, string_end);
if (dtype == DEBUG_TYPE_NULL)
return FALSE;
if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REFERENCE,
case 'a':
/* Reference parameter which is in a register. */
dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
+ (debug_type **) NULL, string_end);
if (dtype == DEBUG_TYPE_NULL)
return FALSE;
if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REF_REG,
that Pascal uses it too, but when I tried it Pascal used
"x:3" (local symbol) instead. */
dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
+ (debug_type **) NULL, string_end);
if (dtype == DEBUG_TYPE_NULL)
return FALSE;
if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
return FALSE;
break;
+ case 'Y':
+ /* SUNPro C++ Namespace =Yn0. */
+ /* Skip the namespace mapping, as it is not used now. */
+ if (*(++p) == 'n' && *(++p) == '0')
+ {
+ /* =Yn0name; */
+ while (*p != ';')
+ ++p;
+ ++p;
+ return TRUE;
+ }
+ /* TODO SUNPro C++ support:
+ Support default arguments after F,P parameters
+ Ya = Anonymous unions
+ YM,YD = Pointers to class members
+ YT,YI = Templates
+ YR = Run-time type information (RTTI) */
+
+ /* Fall through. */
+
default:
bad_stab (string);
return FALSE;
store the slot used if the type is being defined. */
static debug_type
-parse_stab_type (void *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 * type_name,
+ const char ** pp,
+ debug_type ** slotp,
+ const char * p_end)
{
const char *orig;
int typenums[2];
*slotp = NULL;
orig = *pp;
+ if (orig >= p_end)
+ return DEBUG_TYPE_NULL;
size = -1;
stringp = FALSE;
}
else
{
- if (! parse_stab_type_number (pp, typenums))
+ if (! parse_stab_type_number (pp, typenums, p_end))
return DEBUG_TYPE_NULL;
if (**pp != '=')
stringp = TRUE;
break;
+ case 0:
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+
default:
/* Ignore unrecognized type attributes, so future
compilers can invent new ones. */
case 'e':
code = DEBUG_KIND_ENUM;
break;
+ case 0:
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+
default:
/* Complain and keep going, so compilers can invent new
cross-reference types. */
fleep:T20=xsfleep:
which define structures in terms of themselves. We need to
tell the caller to avoid building a circular structure. */
- if (typename != NULL
- && strncmp (typename, *pp, p - *pp) == 0
- && typename[p - *pp] == '\0')
+ if (type_name != NULL
+ && strncmp (type_name, *pp, p - *pp) == 0
+ && type_name[p - *pp] == '\0')
info->self_crossref = TRUE;
dtype = stab_find_tagged_type (dhandle, info, *pp, p - *pp, code);
hold = *pp;
/* Peek ahead at the number to detect void. */
- if (! parse_stab_type_number (pp, xtypenums))
+ if (! parse_stab_type_number (pp, xtypenums, p_end))
return DEBUG_TYPE_NULL;
if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1])
This means that we can deal with something like
t(1,2)=(3,4)=... which the Lucid compiler uses. */
dtype = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
+ pp, (debug_type **) NULL, p_end);
if (dtype == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
}
parse_stab_type (dhandle, info,
(const char *) NULL,
pp,
- (debug_type **) NULL));
+ (debug_type **) NULL,
+ p_end));
break;
case '&':
dtype = (debug_make_reference_type
(dhandle,
parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL)));
+ (debug_type **) NULL, p_end)));
break;
case 'f':
dtype = (debug_make_function_type
(dhandle,
parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL),
+ (debug_type **) NULL, p_end),
(debug_type *) NULL, FALSE));
break;
parse_stab_type (dhandle, info,
(const char *) NULL,
pp,
- (debug_type **) NULL));
+ (debug_type **) NULL,
+ p_end));
break;
case 'B':
dtype = (debug_make_volatile_type
(dhandle,
parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL)));
+ (debug_type **) NULL, p_end)));
break;
case '@':
/* Member type. */
domain = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
+ (debug_type **) NULL, p_end);
if (domain == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
++*pp;
memtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
+ (debug_type **) NULL, p_end);
if (memtype == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
++*pp;
return_type = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
+ pp, (debug_type **) NULL, p_end);
if (return_type == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
if (**pp != ';')
bfd_boolean varargs;
domain = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
+ pp, (debug_type **) NULL, p_end);
if (domain == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
++*pp;
return_type = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
+ pp, (debug_type **) NULL, p_end);
if (return_type == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
}
args[n] = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
+ pp, (debug_type **) NULL, p_end);
if (args[n] == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
++n;
case 'r':
/* Range type. */
- dtype = parse_stab_range_type (dhandle, info, typename, pp, typenums);
+ dtype = parse_stab_range_type (dhandle, info, type_name, pp, typenums, p_end);
break;
case 'b':
/* FIXME: gdb checks os9k_stabs here. */
/* Sun ACC builtin int type. */
- dtype = parse_stab_sun_builtin_type (dhandle, pp);
+ dtype = parse_stab_sun_builtin_type (dhandle, pp, p_end);
break;
case 'R':
/* Sun ACC builtin float type. */
- dtype = parse_stab_sun_floating_type (dhandle, pp);
+ dtype = parse_stab_sun_floating_type (dhandle, pp, p_end);
break;
case 'e':
/* Enumeration type. */
- dtype = parse_stab_enum_type (dhandle, pp);
+ dtype = parse_stab_enum_type (dhandle, pp, p_end);
break;
case 's':
case 'u':
/* Struct or union type. */
- dtype = parse_stab_struct_type (dhandle, info, typename, pp,
- descriptor == 's', typenums);
+ dtype = parse_stab_struct_type (dhandle, info, type_name, pp,
+ descriptor == 's', typenums, p_end);
break;
case 'a':
}
++*pp;
- dtype = parse_stab_array_type (dhandle, info, pp, stringp);
+ dtype = parse_stab_array_type (dhandle, info, pp, stringp, p_end);
break;
case 'S':
parse_stab_type (dhandle, info,
(const char *) NULL,
pp,
- (debug_type **) NULL),
+ (debug_type **) NULL,
+ p_end),
stringp);
break;
storing them in the vector TYPENUMS. */
static bfd_boolean
-parse_stab_type_number (const char **pp, int *typenums)
+parse_stab_type_number (const char **pp, int *typenums, const char *p_end)
{
const char *orig;
if (**pp != '(')
{
typenums[0] = 0;
- typenums[1] = (int) parse_number (pp, (bfd_boolean *) NULL);
+ typenums[1] = (int) parse_number (pp, (bfd_boolean *) NULL, p_end);
+ return TRUE;
}
- else
+
+ ++*pp;
+ typenums[0] = (int) parse_number (pp, (bfd_boolean *) NULL, p_end);
+ if (**pp != ',')
{
- ++*pp;
- typenums[0] = (int) parse_number (pp, (bfd_boolean *) NULL);
- if (**pp != ',')
- {
- bad_stab (orig);
- return FALSE;
- }
- ++*pp;
- typenums[1] = (int) parse_number (pp, (bfd_boolean *) NULL);
- if (**pp != ')')
- {
- bad_stab (orig);
- return FALSE;
- }
- ++*pp;
+ bad_stab (orig);
+ return FALSE;
}
+ ++*pp;
+ typenums[1] = (int) parse_number (pp, (bfd_boolean *) NULL, p_end);
+ if (**pp != ')')
+ {
+ bad_stab (orig);
+ return FALSE;
+ }
+
+ ++*pp;
return TRUE;
}
/* Parse a range type. */
static debug_type
-parse_stab_range_type (void *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 * type_name,
+ const char ** pp,
+ const int * typenums,
+ const char * p_end)
{
const char *orig;
int rangenums[2];
bfd_boolean ov2, ov3;
orig = *pp;
+ if (orig >= p_end)
+ return DEBUG_TYPE_NULL;
index_type = DEBUG_TYPE_NULL;
/* First comes a type we are a subrange of.
In C it is usually 0, 1 or the type being defined. */
- if (! parse_stab_type_number (pp, rangenums))
+ if (! parse_stab_type_number (pp, rangenums, p_end))
return DEBUG_TYPE_NULL;
self_subrange = (rangenums[0] == typenums[0]
{
*pp = orig;
index_type = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
+ pp, (debug_type **) NULL, p_end);
if (index_type == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
}
/* The remaining two operands are usually lower and upper bounds of
the range. But in some special cases they mean something else. */
s2 = *pp;
- n2 = parse_number (pp, &ov2);
+ n2 = parse_number (pp, &ov2, p_end);
if (**pp != ';')
{
bad_stab (orig);
++*pp;
s3 = *pp;
- n3 = parse_number (pp, &ov3);
+ n3 = parse_number (pp, &ov3, p_end);
if (**pp != ';')
{
bad_stab (orig);
#define ULLHIGH "01777777777777777777777;"
if (index_type == DEBUG_TYPE_NULL)
{
- if (strncmp (s2, LLLOW, sizeof LLLOW - 1) == 0
- && strncmp (s3, LLHIGH, sizeof LLHIGH - 1) == 0)
+ if (CONST_STRNEQ (s2, LLLOW)
+ && CONST_STRNEQ (s3, LLHIGH))
return debug_make_int_type (dhandle, 8, FALSE);
if (! ov2
&& n2 == 0
- && strncmp (s3, ULLHIGH, sizeof ULLHIGH - 1) == 0)
+ && CONST_STRNEQ (s3, ULLHIGH))
return debug_make_int_type (dhandle, 8, TRUE);
}
long long int:t6=r1;0;-1;
long long unsigned int:t7=r1;0;-1;
We hack here to handle this reasonably. */
- if (typename != NULL)
+ if (type_name != NULL)
{
- if (strcmp (typename, "long long int") == 0)
+ if (strcmp (type_name, "long long int") == 0)
return debug_make_int_type (dhandle, 8, FALSE);
- else if (strcmp (typename, "long long unsigned int") == 0)
+ else if (strcmp (type_name, "long long unsigned int") == 0)
return debug_make_int_type (dhandle, 8, TRUE);
}
/* FIXME: The size here really depends upon the target. */
else if (n3 == (bfd_signed_vma) 0xffffffff)
return debug_make_int_type (dhandle, 4, TRUE);
#ifdef BFD64
- else if (n3 == ((((bfd_signed_vma) 0xffffffff) << 32) | 0xffffffff))
+ else if (n3 == (bfd_signed_vma) 0xffffffffffffffffLL)
return debug_make_int_type (dhandle, 8, TRUE);
#endif
}
FIXME. */
static debug_type
-parse_stab_sun_builtin_type (void *dhandle, const char **pp)
+parse_stab_sun_builtin_type (void *dhandle, const char **pp, const char * p_end)
{
const char *orig;
bfd_boolean unsignedp;
bfd_vma bits;
orig = *pp;
+ if (orig >= p_end)
+ return DEBUG_TYPE_NULL;
switch (**pp)
{
}
++*pp;
- /* For some odd reason, all forms of char put a c here. This is strange
- because no other type has this honor. We can safely ignore this because
- we actually determine 'char'acterness by the number of bits specified in
- the descriptor. */
- if (**pp == 'c')
+ /* OpenSolaris source code indicates that one of "cbv" characters
+ can come next and specify the intrinsic 'iformat' encoding.
+ 'c' is character encoding, 'b' is boolean encoding, and 'v' is
+ varargs encoding. This field can be safely ignored because
+ the type of the field is determined from the bitwidth extracted
+ below. */
+ if (**pp == 'c' || **pp == 'b' || **pp == 'v')
++*pp;
/* The first number appears to be the number of bytes occupied
by this type, except that unsigned short is 4 instead of 2.
Since this information is redundant with the third number,
we will ignore it. */
- (void) parse_number (pp, (bfd_boolean *) NULL);
+ (void) parse_number (pp, (bfd_boolean *) NULL, p_end);
if (**pp != ';')
{
bad_stab (orig);
++*pp;
/* The second number is always 0, so ignore it too. */
- (void) parse_number (pp, (bfd_boolean *) NULL);
+ (void) parse_number (pp, (bfd_boolean *) NULL, p_end);
if (**pp != ';')
{
bad_stab (orig);
++*pp;
/* The third number is the number of bits for this type. */
- bits = parse_number (pp, (bfd_boolean *) NULL);
+ bits = parse_number (pp, (bfd_boolean *) NULL, p_end);
/* The type *should* end with a semicolon. If it are embedded
in a larger type the semicolon may be the only way to know where
/* Parse a builtin floating type generated by the Sun compiler. */
static debug_type
-parse_stab_sun_floating_type (void *dhandle, const char **pp)
+parse_stab_sun_floating_type (void *dhandle, const char **pp, const char *p_end)
{
const char *orig;
bfd_vma details;
bfd_vma bytes;
orig = *pp;
+ if (orig >= p_end)
+ return DEBUG_TYPE_NULL;
/* The first number has more details about the type, for example
FN_COMPLEX. */
- details = parse_number (pp, (bfd_boolean *) NULL);
+ details = parse_number (pp, (bfd_boolean *) NULL, p_end);
if (**pp != ';')
{
bad_stab (orig);
}
/* The second number is the number of bytes occupied by this type */
- bytes = parse_number (pp, (bfd_boolean *) NULL);
+ bytes = parse_number (pp, (bfd_boolean *) NULL, p_end);
if (**pp != ';')
{
bad_stab (orig);
/* Handle an enum type. */
static debug_type
-parse_stab_enum_type (void *dhandle, const char **pp)
+parse_stab_enum_type (void *dhandle, const char **pp, const char * p_end)
{
const char *orig;
const char **names;
unsigned int alloc;
orig = *pp;
+ if (orig >= p_end)
+ return DEBUG_TYPE_NULL;
/* FIXME: gdb checks os9k_stabs here. */
my guess is it's a type of some sort. Just ignore it. */
if (**pp == '-')
{
- while (**pp != ':')
+ while (**pp != ':' && **pp != 0)
++*pp;
+
+ if (**pp == 0)
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
++*pp;
}
bfd_signed_vma val;
p = *pp;
- while (*p != ':')
+ while (*p != ':' && *p != 0)
++p;
+ if (*p == 0)
+ {
+ bad_stab (orig);
+ free (names);
+ free (values);
+ return DEBUG_TYPE_NULL;
+ }
+
name = savestring (*pp, p - *pp);
*pp = p + 1;
- val = (bfd_signed_vma) parse_number (pp, (bfd_boolean *) NULL);
+ val = (bfd_signed_vma) parse_number (pp, (bfd_boolean *) NULL, p_end);
if (**pp != ',')
{
bad_stab (orig);
+ free (name);
+ free (names);
+ free (values);
return DEBUG_TYPE_NULL;
}
++*pp;
*PP will point to "4a:1,0,32;;". */
static debug_type
-parse_stab_struct_type (void *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 * p_end)
{
- const char *orig;
bfd_vma size;
debug_baseclass *baseclasses;
- debug_field *fields;
+ debug_field *fields = NULL;
bfd_boolean statics;
debug_method *methods;
debug_type vptrbase;
bfd_boolean ownvptr;
- orig = *pp;
-
/* Get the size. */
- size = parse_number (pp, (bfd_boolean *) NULL);
+ size = parse_number (pp, (bfd_boolean *) NULL, p_end);
/* Get the other information. */
- if (! parse_stab_baseclasses (dhandle, info, pp, &baseclasses)
- || ! parse_stab_struct_fields (dhandle, info, pp, &fields, &statics)
- || ! parse_stab_members (dhandle, info, tagname, pp, typenums, &methods)
+ if (! parse_stab_baseclasses (dhandle, info, pp, &baseclasses, p_end)
+ || ! parse_stab_struct_fields (dhandle, info, pp, &fields, &statics, p_end)
+ || ! parse_stab_members (dhandle, info, tagname, pp, typenums, &methods, p_end)
|| ! parse_stab_tilde_field (dhandle, info, pp, typenums, &vptrbase,
- &ownvptr))
- return DEBUG_TYPE_NULL;
+ &ownvptr, p_end))
+ {
+ if (fields != NULL)
+ free (fields);
+ return DEBUG_TYPE_NULL;
+ }
if (! statics
&& baseclasses == NULL
Return TRUE for success, FALSE for failure. */
static bfd_boolean
-parse_stab_baseclasses (void *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 * p_end)
{
const char *orig;
unsigned int c, i;
*retp = NULL;
orig = *pp;
+ if (orig >= p_end)
+ return FALSE;
if (**pp != '!')
{
}
++*pp;
- c = (unsigned int) parse_number (pp, (bfd_boolean *) NULL);
+ c = (unsigned int) parse_number (pp, (bfd_boolean *) NULL, p_end);
if (**pp != ',')
{
for (i = 0; i < c; i++)
{
- bfd_boolean virtual;
+ bfd_boolean is_virtual;
enum debug_visibility visibility;
bfd_vma bitpos;
debug_type type;
switch (**pp)
{
case '0':
- virtual = FALSE;
+ is_virtual = FALSE;
break;
case '1':
- virtual = TRUE;
+ is_virtual = TRUE;
break;
+ case 0:
+ bad_stab (orig);
+ return FALSE;
default:
warn_stab (orig, _("unknown virtual character for baseclass"));
- virtual = FALSE;
+ is_virtual = FALSE;
break;
}
++*pp;
case '2':
visibility = DEBUG_VISIBILITY_PUBLIC;
break;
+ case 0:
+ bad_stab (orig);
+ return FALSE;
default:
warn_stab (orig, _("unknown visibility character for baseclass"));
visibility = DEBUG_VISIBILITY_PUBLIC;
/* The remaining value is the bit offset of the portion of the
object corresponding to this baseclass. Always zero in the
absence of multiple inheritance. */
- bitpos = parse_number (pp, (bfd_boolean *) NULL);
+ bitpos = parse_number (pp, (bfd_boolean *) NULL, p_end);
if (**pp != ',')
{
bad_stab (orig);
++*pp;
type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
+ (debug_type **) NULL, p_end);
if (type == DEBUG_TYPE_NULL)
return FALSE;
- classes[i] = debug_make_baseclass (dhandle, type, bitpos, virtual,
+ classes[i] = debug_make_baseclass (dhandle, type, bitpos, is_virtual,
visibility);
if (classes[i] == DEBUG_BASECLASS_NULL)
return FALSE;
Returns 1 for success, 0 for failure. */
static bfd_boolean
-parse_stab_struct_fields (void *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 * p_end)
{
const char *orig;
const char *p;
*staticsp = FALSE;
orig = *pp;
+ if (orig >= p_end)
+ return FALSE;
c = 0;
alloc = 10;
if ((*p == '$' || *p == '.') && p[1] != '_')
{
++*pp;
- if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c))
- return FALSE;
+ if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c, p_end))
+ {
+ free (fields);
+ return FALSE;
+ }
++c;
continue;
}
if (p == NULL)
{
bad_stab (orig);
+ free (fields);
return FALSE;
}
break;
if (! parse_stab_one_struct_field (dhandle, info, pp, p, fields + c,
- staticsp))
+ staticsp, p_end))
return FALSE;
++c;
/* Special GNU C++ name. */
static bfd_boolean
-parse_stab_cpp_abbrev (void *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 * p_end)
{
const char *orig;
int cpp_abbrev;
debug_type context;
const char *name;
- const char *typename;
+ const char *type_name;
debug_type type;
bfd_vma bitpos;
*retp = DEBUG_FIELD_NULL;
orig = *pp;
+ if (orig >= p_end)
+ return FALSE;
if (**pp != 'v')
{
++*pp;
cpp_abbrev = **pp;
+ if (cpp_abbrev == 0)
+ {
+ bad_stab (orig);
+ return FALSE;
+ }
++*pp;
/* At this point, *pp points to something like "22:23=*22...", where
name, and construct the field name. */
context = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
+ (debug_type **) NULL, p_end);
if (context == DEBUG_TYPE_NULL)
return FALSE;
break;
case 'b':
/* $vb -- a virtual bsomethingorother */
- typename = debug_get_type_name (dhandle, context);
- if (typename == NULL)
+ type_name = debug_get_type_name (dhandle, context);
+ if (type_name == NULL)
{
warn_stab (orig, _("unnamed $vb type"));
- typename = "FOO";
+ type_name = "FOO";
}
- name = concat ("_vb$", typename, (const char *) NULL);
+ name = concat ("_vb$", type_name, (const char *) NULL);
break;
default:
warn_stab (orig, _("unrecognized C++ abbreviation"));
++*pp;
type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
+ (debug_type **) NULL, p_end);
if (**pp != ',')
{
bad_stab (orig);
}
++*pp;
- bitpos = parse_number (pp, (bfd_boolean *) NULL);
+ bitpos = parse_number (pp, (bfd_boolean *) NULL, p_end);
if (**pp != ';')
{
bad_stab (orig);
/* Parse a single field in a struct or union. */
static bfd_boolean
-parse_stab_one_struct_field (void *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 * p_end)
{
const char *orig;
char *name;
bfd_vma bitsize;
orig = *pp;
+ if (orig >= p_end)
+ return FALSE;
/* FIXME: gdb checks ARM_DEMANGLING here. */
case '2':
visibility = DEBUG_VISIBILITY_PUBLIC;
break;
+ case 0:
+ bad_stab (orig);
+ return FALSE;
default:
warn_stab (orig, _("unknown visibility character for field"));
visibility = DEBUG_VISIBILITY_PUBLIC;
}
type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
+ (debug_type **) NULL, p_end);
if (type == DEBUG_TYPE_NULL)
- return FALSE;
+ {
+ free (name);
+ return FALSE;
+ }
if (**pp == ':')
{
if (p == NULL)
{
bad_stab (orig);
+ free (name);
return FALSE;
}
if (**pp != ',')
{
bad_stab (orig);
+ free (name);
return FALSE;
}
++*pp;
- bitpos = parse_number (pp, (bfd_boolean *) NULL);
+ bitpos = parse_number (pp, (bfd_boolean *) NULL, p_end);
if (**pp != ',')
{
bad_stab (orig);
+ free (name);
return FALSE;
}
++*pp;
- bitsize = parse_number (pp, (bfd_boolean *) NULL);
+ bitsize = parse_number (pp, (bfd_boolean *) NULL, p_end);
if (**pp != ';')
{
bad_stab (orig);
+ free (name);
return FALSE;
}
++*pp;
name (such as `+=') and `.' marks the end of the operator name. */
static bfd_boolean
-parse_stab_members (void *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 * p_end)
{
const char *orig;
debug_method *methods;
unsigned int c;
unsigned int alloc;
+ char *name = NULL;
+ debug_method_variant *variants = NULL;
+ char *argtypes = NULL;
*retp = NULL;
orig = *pp;
+ if (orig >= p_end)
+ return FALSE;
alloc = 0;
methods = NULL;
while (**pp != ';')
{
const char *p;
- char *name;
- debug_method_variant *variants;
unsigned int cvars;
unsigned int allocvars;
debug_type look_ahead_type;
if (*p != '.')
{
bad_stab (orig);
- return FALSE;
+ goto fail;
}
name = savestring (*pp, p - *pp);
*pp = p + 1;
{
debug_type type;
bfd_boolean stub;
- char *argtypes;
enum debug_visibility visibility;
bfd_boolean constp, volatilep, staticp;
bfd_vma voffset;
else
{
type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
+ (debug_type **) NULL, p_end);
if (type == DEBUG_TYPE_NULL)
- return FALSE;
+ goto fail;
+
if (**pp != ':')
{
bad_stab (orig);
- return FALSE;
+ goto fail;
}
}
if (p == NULL)
{
bad_stab (orig);
- return FALSE;
+ goto fail;
}
stub = FALSE;
case '1':
visibility = DEBUG_VISIBILITY_PROTECTED;
break;
+ case 0:
+ bad_stab (orig);
+ goto fail;
default:
visibility = DEBUG_VISIBILITY_PUBLIC;
break;
case '*':
/* virtual member function, followed by index. The sign
bit is supposedly set to distinguish
- pointers-to-methods from virtual function indicies. */
+ pointers-to-methods from virtual function indices. */
++*pp;
- voffset = parse_number (pp, (bfd_boolean *) NULL);
+ voffset = parse_number (pp, (bfd_boolean *) NULL, p_end);
if (**pp != ';')
{
bad_stab (orig);
- return FALSE;
+ goto fail;
}
++*pp;
voffset &= 0x7fffffff;
- if (**pp == ';' || *pp == '\0')
+ if (**pp == ';' || **pp == '\0')
{
/* Must be g++ version 1. */
context = DEBUG_TYPE_NULL;
look_ahead_type = parse_stab_type (dhandle, info,
(const char *) NULL,
pp,
- (debug_type **) NULL);
+ (debug_type **) NULL,
+ p_end);
if (**pp == ':')
{
/* g++ version 1 overloaded methods. */
if (**pp != ';')
{
bad_stab (orig);
- return FALSE;
+ goto fail;
}
++*pp;
}
argtypes string is the mangled form of the argument
types, and the full type and the physical name must be
extracted from them. */
- if (! stub)
- physname = argtypes;
- else
+ physname = argtypes;
+ if (stub)
{
debug_type class_type, return_type;
class_type = stab_find_type (dhandle, info, typenums);
if (class_type == DEBUG_TYPE_NULL)
- return FALSE;
+ goto fail;
return_type = debug_get_return_type (dhandle, type);
if (return_type == DEBUG_TYPE_NULL)
{
bad_stab (orig);
- return FALSE;
+ goto fail;
}
type = parse_stab_argtypes (dhandle, info, class_type, name,
tagname, return_type, argtypes,
constp, volatilep, &physname);
if (type == DEBUG_TYPE_NULL)
- return FALSE;
+ goto fail;
}
if (cvars + 1 >= allocvars)
constp,
volatilep);
if (variants[cvars] == DEBUG_METHOD_VARIANT_NULL)
- return FALSE;
+ goto fail;
++cvars;
}
*retp = methods;
return TRUE;
+
+ fail:
+ if (name != NULL)
+ free (name);
+ if (variants != NULL)
+ free (variants);
+ if (argtypes != NULL)
+ free (argtypes);
+ return FALSE;
}
/* Parse a string representing argument types for a method. Stabs
&& (ISDIGIT (argtypes[2])
|| argtypes[2] == 'Q'
|| argtypes[2] == 't'))
- || strncmp (argtypes, "__ct", 4) == 0);
+ || CONST_STRNEQ (argtypes, "__ct"));
is_constructor = (is_full_physname_constructor
|| (tagname != NULL
is_destructor = ((argtypes[0] == '_'
&& (argtypes[1] == '$' || argtypes[1] == '.')
&& argtypes[2] == '_')
- || strncmp (argtypes, "__dt", 4) == 0);
+ || CONST_STRNEQ (argtypes, "__dt"));
is_v3 = argtypes[0] == '_' && argtypes[1] == 'Z';
- if (is_destructor || is_full_physname_constructor || is_v3)
- *pphysname = argtypes;
- else
+ if (!(is_destructor || is_full_physname_constructor || is_v3))
{
unsigned int len;
const char *const_prefix;
&& fieldname[1] == 'p'
&& (fieldname[2] == '$' || fieldname[2] == '.'))
{
- const char *opname;
-
- opname = cplus_mangle_opname (fieldname + 3, 0);
- if (opname == NULL)
- {
- fprintf (stderr, _("No mangling for \"%s\"\n"), fieldname);
- return DEBUG_TYPE_NULL;
- }
- mangled_name_len += strlen (opname);
- physname = (char *) xmalloc (mangled_name_len);
- strncpy (physname, fieldname, 3);
- strcpy (physname + 3, opname);
+ /* Opname selection is no longer supported by libiberty's demangler. */
+ return DEBUG_TYPE_NULL;
}
+
+ physname = (char *) xmalloc (mangled_name_len);
+ if (is_constructor)
+ physname[0] = '\0';
else
- {
- physname = (char *) xmalloc (mangled_name_len);
- if (is_constructor)
- physname[0] = '\0';
- else
- strcpy (physname, fieldname);
- }
+ strcpy (physname, fieldname);
physname_len = strlen (physname);
strcat (physname, buf);
so we can look for the vptr base class info. */
static bfd_boolean
-parse_stab_tilde_field (void *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 * p_end)
{
const char *orig;
const char *hold;
*retownvptr = FALSE;
orig = *pp;
-
+ if (orig >= p_end)
+ return FALSE;
+
/* If we are positioned at a ';', then skip it. */
if (**pp == ';')
++*pp;
if (**pp != '~')
return TRUE;
-
++*pp;
if (**pp == '=' || **pp == '+' || **pp == '-')
if (**pp != '%')
return TRUE;
-
++*pp;
hold = *pp;
/* The next number is the type number of the base class (possibly
our own class) which supplies the vtable for this class. */
- if (! parse_stab_type_number (pp, vtypenums))
+ if (! parse_stab_type_number (pp, vtypenums, p_end))
return FALSE;
if (vtypenums[0] == typenums[0]
*pp = hold;
vtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
+ (debug_type **) NULL, p_end);
for (p = *pp; *p != ';' && *p != '\0'; p++)
;
if (*p != ';')
/* Read a definition of an array type. */
static debug_type
-parse_stab_array_type (void *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 * p_end)
{
const char *orig;
const char *p;
for these, produce a type like float[][]. */
orig = *pp;
+ if (orig >= p_end)
+ return DEBUG_TYPE_NULL;
/* FIXME: gdb checks os9k_stabs here. */
/* If the index type is type 0, we take it as int. */
p = *pp;
- if (! parse_stab_type_number (&p, typenums))
+ if (! parse_stab_type_number (&p, typenums, p_end))
return DEBUG_TYPE_NULL;
+
if (typenums[0] == 0 && typenums[1] == 0 && **pp != '=')
{
index_type = debug_find_named_type (dhandle, "int");
else
{
index_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
+ (debug_type **) NULL, p_end);
}
if (**pp != ';')
adjustable = FALSE;
- if (! ISDIGIT (**pp) && **pp != '-')
+ if (! ISDIGIT (**pp) && **pp != '-' && **pp != 0)
{
++*pp;
adjustable = TRUE;
}
- lower = (bfd_signed_vma) parse_number (pp, (bfd_boolean *) NULL);
+ lower = (bfd_signed_vma) parse_number (pp, (bfd_boolean *) NULL, p_end);
if (**pp != ';')
{
bad_stab (orig);
}
++*pp;
- if (! ISDIGIT (**pp) && **pp != '-')
+ if (! ISDIGIT (**pp) && **pp != '-' && **pp != 0)
{
++*pp;
adjustable = TRUE;
}
- upper = (bfd_signed_vma) parse_number (pp, (bfd_boolean *) NULL);
+ upper = (bfd_signed_vma) parse_number (pp, (bfd_boolean *) NULL, p_end);
if (**pp != ';')
{
bad_stab (orig);
++*pp;
element_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
+ (debug_type **) NULL, p_end);
if (element_type == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
return info->main_filename;
info->bincl_stack = o->next_stack;
+ if (o->file >= info->files)
+ return info->main_filename;
+
o->file_types = info->file_types[o->file];
if (info->bincl_stack == NULL)
stab_find_slot (struct stab_handle *info, const int *typenums)
{
int filenum;
- int index;
+ int tindex;
struct stab_types **ps;
filenum = typenums[0];
- index = typenums[1];
+ tindex = typenums[1];
if (filenum < 0 || (unsigned int) filenum >= info->files)
{
fprintf (stderr, _("Type file number %d out of range\n"), filenum);
return NULL;
}
- if (index < 0)
+ if (tindex < 0)
{
- fprintf (stderr, _("Type index number %d out of range\n"), index);
+ fprintf (stderr, _("Type index number %d out of range\n"), tindex);
return NULL;
}
ps = info->file_types + filenum;
- while (index >= STAB_TYPES_SLOTS)
+ while (tindex >= STAB_TYPES_SLOTS)
{
if (*ps == NULL)
{
memset (*ps, 0, sizeof **ps);
}
ps = &(*ps)->next;
- index -= STAB_TYPES_SLOTS;
+ tindex -= STAB_TYPES_SLOTS;
}
if (*ps == NULL)
{
memset (*ps, 0, sizeof **ps);
}
- return (*ps)->types + index;
+ return (*ps)->types + tindex;
}
/* Find a type given a type number. If the type has not been
case 9:
name = "unsigned";
rettype = debug_make_int_type (dhandle, 4, TRUE);
+ break;
case 10:
name = "unsigned long";
rettype = debug_make_int_type (dhandle, 4, TRUE);
*pp = scan + 2;
if (*pp - name >= 5
- && strncmp (name, "type", 4) == 0
+ && CONST_STRNEQ (name, "type")
&& (name[4] == '$' || name[4] == '.'))
{
const char *tem;
ft = debug_get_field_type (minfo->dhandle, *fields);
if (ft == NULL)
- return FALSE;
+ {
+ free (name);
+ return FALSE;
+ }
dn = debug_get_type_name (minfo->dhandle, ft);
if (dn != NULL && strcmp (dn, name) == 0)
{
{
unsigned int len;
- if (! stab_demangle_get_count (pp, &len))
+ len = stab_demangle_count (pp);
+ if (len == 0)
{
stab_bad_demangle (orig);
return FALSE;
free (s1);
- s3 = cplus_demangle (s2, DMGL_ANSI);
+ s3 = cplus_demangle (s2, demangle_flags);
free (s2);
case 'M':
case 'O':
{
- bfd_boolean memberp, constp, volatilep;
+ bfd_boolean memberp;
debug_type class_type = DEBUG_TYPE_NULL;
debug_type *args;
bfd_boolean varargs;
const char *name;
memberp = **pp == 'M';
- constp = FALSE;
- volatilep = FALSE;
args = NULL;
varargs = FALSE;
{
if (**pp == 'C')
{
- constp = TRUE;
++*pp;
}
else if (**pp == 'V')
{
- volatilep = TRUE;
++*pp;
}
if (**pp != 'F')
case 'Q':
{
- const char *hold;
-
- hold = *pp;
if (! stab_demangle_qualified (minfo, pp, ptype))
return FALSE;
}
void *mem;
debug_type *pargs;
- dc = cplus_demangle_v3_components (physname, DMGL_PARAMS | DMGL_ANSI, &mem);
+ dc = cplus_demangle_v3_components (physname, DMGL_PARAMS | demangle_flags, &mem);
if (dc == NULL)
{
stab_bad_demangle (physname);
return NULL;
}
+ /* PR 13925: Cope if the demangler returns an empty
+ context for a function with no arguments. */
+ if (dc->u.s_binary.left == NULL)
+ break;
+
arg = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left,
NULL, &varargs);
if (arg == NULL)
/* 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);
+ p = cplus_demangle_print (DMGL_PARAMS | demangle_flags, dc, 20, &alc);
if (p == NULL)
{
fprintf (stderr, _("Failed to print demangled template\n"));
/* 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);
+ p = cplus_demangle_print (DMGL_PARAMS | demangle_flags, dc, 20, &alc);
if (p == NULL)
{
fprintf (stderr, _("Couldn't get demangled builtin type\n"));