1239 lines
40 KiB
Diff
1239 lines
40 KiB
Diff
diff -rup binutils.orig/binutils/stabs.c binutils-2.30/binutils/stabs.c
|
|
--- binutils.orig/binutils/stabs.c 2024-10-29 14:00:27.334403933 +0000
|
|
+++ binutils-2.30/binutils/stabs.c 2024-10-29 14:02:25.532712776 +0000
|
|
@@ -145,42 +145,51 @@ struct stab_tag
|
|
};
|
|
|
|
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);
|
|
@@ -222,7 +231,7 @@ savestring (const char *start, int len)
|
|
/* 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;
|
|
@@ -231,6 +240,8 @@ parse_number (const char **pp, bfd_boole
|
|
*poverflow = FALSE;
|
|
|
|
orig = *pp;
|
|
+ if (orig >= p_end)
|
|
+ return (bfd_vma) 0;
|
|
|
|
/* Stop early if we are passed an empty string. */
|
|
if (*orig == 0)
|
|
@@ -409,6 +420,7 @@ bfd_boolean
|
|
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
|
|
@@ -443,6 +455,8 @@ parse_stab (void *dhandle, void *handle,
|
|
/* Now process whatever type we just got. */
|
|
}
|
|
|
|
+ string_end = string + strlen (string);
|
|
+
|
|
switch (type)
|
|
{
|
|
case N_FN:
|
|
@@ -652,7 +666,7 @@ parse_stab (void *dhandle, void *handle,
|
|
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;
|
|
@@ -680,7 +694,8 @@ parse_stab (void *dhandle, void *handle,
|
|
|
|
static bfd_boolean
|
|
parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
|
|
- int desc ATTRIBUTE_UNUSED, 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;
|
|
@@ -743,6 +758,11 @@ parse_stab_string (void *dhandle, struct
|
|
++p;
|
|
if (ISDIGIT (*p) || *p == '(' || *p == '-')
|
|
type = 'l';
|
|
+ else if (*p == 0)
|
|
+ {
|
|
+ bad_stab (string);
|
|
+ return FALSE;
|
|
+ }
|
|
else
|
|
type = *p++;
|
|
|
|
@@ -787,7 +807,7 @@ parse_stab_string (void *dhandle, struct
|
|
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 != ',')
|
|
@@ -812,7 +832,7 @@ parse_stab_string (void *dhandle, struct
|
|
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))
|
|
@@ -825,7 +845,7 @@ parse_stab_string (void *dhandle, struct
|
|
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))
|
|
@@ -839,7 +859,7 @@ parse_stab_string (void *dhandle, struct
|
|
{
|
|
++p;
|
|
if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
|
|
- (debug_type **) NULL)
|
|
+ (debug_type **) NULL, string_end)
|
|
== DEBUG_TYPE_NULL)
|
|
return FALSE;
|
|
}
|
|
@@ -853,7 +873,7 @@ parse_stab_string (void *dhandle, struct
|
|
/* 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;
|
|
if (name != NULL)
|
|
@@ -889,7 +909,7 @@ parse_stab_string (void *dhandle, struct
|
|
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,
|
|
@@ -901,7 +921,7 @@ parse_stab_string (void *dhandle, struct
|
|
/* 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
|
|
@@ -909,7 +929,7 @@ parse_stab_string (void *dhandle, struct
|
|
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;
|
|
@@ -939,7 +959,7 @@ parse_stab_string (void *dhandle, struct
|
|
{
|
|
++p;
|
|
if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
|
|
- (debug_type **) NULL)
|
|
+ (debug_type **) NULL, string_end)
|
|
== DEBUG_TYPE_NULL)
|
|
return FALSE;
|
|
}
|
|
@@ -949,7 +969,7 @@ parse_stab_string (void *dhandle, struct
|
|
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,
|
|
@@ -960,7 +980,7 @@ parse_stab_string (void *dhandle, struct
|
|
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,
|
|
@@ -974,7 +994,7 @@ parse_stab_string (void *dhandle, struct
|
|
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,
|
|
@@ -984,7 +1004,7 @@ parse_stab_string (void *dhandle, struct
|
|
|
|
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)
|
|
@@ -1017,7 +1037,7 @@ parse_stab_string (void *dhandle, struct
|
|
++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)
|
|
@@ -1068,7 +1088,7 @@ parse_stab_string (void *dhandle, struct
|
|
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. */
|
|
@@ -1080,7 +1100,7 @@ parse_stab_string (void *dhandle, struct
|
|
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,
|
|
@@ -1091,7 +1111,7 @@ parse_stab_string (void *dhandle, struct
|
|
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,
|
|
@@ -1105,7 +1125,7 @@ parse_stab_string (void *dhandle, struct
|
|
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,
|
|
@@ -1156,7 +1176,12 @@ parse_stab_string (void *dhandle, struct
|
|
store the slot used if the type is being defined. */
|
|
|
|
static debug_type
|
|
-parse_stab_type (void *dhandle, struct stab_handle *info, const char *type_name, 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];
|
|
@@ -1169,6 +1194,8 @@ parse_stab_type (void *dhandle, struct s
|
|
*slotp = NULL;
|
|
|
|
orig = *pp;
|
|
+ if (orig >= p_end)
|
|
+ return DEBUG_TYPE_NULL;
|
|
|
|
size = -1;
|
|
stringp = FALSE;
|
|
@@ -1186,7 +1213,7 @@ parse_stab_type (void *dhandle, struct s
|
|
}
|
|
else
|
|
{
|
|
- if (! parse_stab_type_number (pp, typenums))
|
|
+ if (! parse_stab_type_number (pp, typenums, p_end))
|
|
return DEBUG_TYPE_NULL;
|
|
|
|
if (**pp != '=')
|
|
@@ -1249,6 +1276,10 @@ parse_stab_type (void *dhandle, struct s
|
|
stringp = TRUE;
|
|
break;
|
|
|
|
+ case 0:
|
|
+ bad_stab (orig);
|
|
+ return DEBUG_TYPE_NULL;
|
|
+
|
|
default:
|
|
/* Ignore unrecognized type attributes, so future
|
|
compilers can invent new ones. */
|
|
@@ -1279,6 +1310,10 @@ parse_stab_type (void *dhandle, struct s
|
|
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. */
|
|
@@ -1352,7 +1387,7 @@ parse_stab_type (void *dhandle, struct s
|
|
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])
|
|
@@ -1369,7 +1404,7 @@ parse_stab_type (void *dhandle, struct s
|
|
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;
|
|
}
|
|
@@ -1388,7 +1423,8 @@ parse_stab_type (void *dhandle, struct s
|
|
parse_stab_type (dhandle, info,
|
|
(const char *) NULL,
|
|
pp,
|
|
- (debug_type **) NULL));
|
|
+ (debug_type **) NULL,
|
|
+ p_end));
|
|
break;
|
|
|
|
case '&':
|
|
@@ -1396,7 +1432,7 @@ parse_stab_type (void *dhandle, struct s
|
|
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':
|
|
@@ -1405,7 +1441,7 @@ parse_stab_type (void *dhandle, struct s
|
|
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;
|
|
|
|
@@ -1416,7 +1452,8 @@ parse_stab_type (void *dhandle, struct s
|
|
parse_stab_type (dhandle, info,
|
|
(const char *) NULL,
|
|
pp,
|
|
- (debug_type **) NULL));
|
|
+ (debug_type **) NULL,
|
|
+ p_end));
|
|
break;
|
|
|
|
case 'B':
|
|
@@ -1425,7 +1462,7 @@ parse_stab_type (void *dhandle, struct s
|
|
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 '@':
|
|
@@ -1438,7 +1475,7 @@ parse_stab_type (void *dhandle, struct s
|
|
/* 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;
|
|
|
|
@@ -1450,7 +1487,7 @@ parse_stab_type (void *dhandle, struct s
|
|
++*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;
|
|
|
|
@@ -1466,7 +1503,7 @@ parse_stab_type (void *dhandle, struct s
|
|
|
|
++*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 != ';')
|
|
@@ -1489,7 +1526,7 @@ parse_stab_type (void *dhandle, struct s
|
|
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;
|
|
|
|
@@ -1501,7 +1538,7 @@ parse_stab_type (void *dhandle, struct s
|
|
++*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;
|
|
|
|
@@ -1527,7 +1564,7 @@ parse_stab_type (void *dhandle, struct s
|
|
}
|
|
|
|
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)
|
|
/* There is a potential resource leak here, but it is not important. */
|
|
/* coverity[leaked_storage: FALSE] */
|
|
@@ -1557,30 +1594,30 @@ parse_stab_type (void *dhandle, struct s
|
|
|
|
case 'r':
|
|
/* Range type. */
|
|
- dtype = parse_stab_range_type (dhandle, info, type_name, 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, type_name, pp,
|
|
- descriptor == 's', typenums);
|
|
+ descriptor == 's', typenums, p_end);
|
|
break;
|
|
|
|
case 'a':
|
|
@@ -1592,7 +1629,7 @@ parse_stab_type (void *dhandle, struct s
|
|
}
|
|
++*pp;
|
|
|
|
- dtype = parse_stab_array_type (dhandle, info, pp, stringp);
|
|
+ dtype = parse_stab_array_type (dhandle, info, pp, stringp, p_end);
|
|
break;
|
|
|
|
case 'S':
|
|
@@ -1600,7 +1637,8 @@ parse_stab_type (void *dhandle, struct s
|
|
parse_stab_type (dhandle, info,
|
|
(const char *) NULL,
|
|
pp,
|
|
- (debug_type **) NULL),
|
|
+ (debug_type **) NULL,
|
|
+ p_end),
|
|
stringp);
|
|
break;
|
|
|
|
@@ -1633,7 +1671,7 @@ parse_stab_type (void *dhandle, struct s
|
|
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;
|
|
|
|
@@ -1642,34 +1680,39 @@ parse_stab_type_number (const char **pp,
|
|
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 *type_name, 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];
|
|
@@ -1680,12 +1723,14 @@ parse_stab_range_type (void *dhandle, st
|
|
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]
|
|
@@ -1695,7 +1740,7 @@ parse_stab_range_type (void *dhandle, st
|
|
{
|
|
*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;
|
|
}
|
|
@@ -1706,7 +1751,7 @@ parse_stab_range_type (void *dhandle, st
|
|
/* 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);
|
|
@@ -1715,7 +1760,7 @@ parse_stab_range_type (void *dhandle, st
|
|
++*pp;
|
|
|
|
s3 = *pp;
|
|
- n3 = parse_number (pp, &ov3);
|
|
+ n3 = parse_number (pp, &ov3, p_end);
|
|
if (**pp != ';')
|
|
{
|
|
bad_stab (orig);
|
|
@@ -1853,13 +1898,15 @@ parse_stab_range_type (void *dhandle, st
|
|
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)
|
|
{
|
|
@@ -1888,7 +1935,7 @@ parse_stab_sun_builtin_type (void *dhand
|
|
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);
|
|
@@ -1897,7 +1944,7 @@ parse_stab_sun_builtin_type (void *dhand
|
|
++*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);
|
|
@@ -1906,7 +1953,7 @@ parse_stab_sun_builtin_type (void *dhand
|
|
++*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
|
|
@@ -1926,17 +1973,19 @@ parse_stab_sun_builtin_type (void *dhand
|
|
/* 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);
|
|
@@ -1944,7 +1993,7 @@ parse_stab_sun_floating_type (void *dhan
|
|
}
|
|
|
|
/* 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);
|
|
@@ -1962,7 +2011,7 @@ parse_stab_sun_floating_type (void *dhan
|
|
/* 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;
|
|
@@ -1971,6 +2020,8 @@ parse_stab_enum_type (void *dhandle, con
|
|
unsigned int alloc;
|
|
|
|
orig = *pp;
|
|
+ if (orig >= p_end)
|
|
+ return DEBUG_TYPE_NULL;
|
|
|
|
/* FIXME: gdb checks os9k_stabs here. */
|
|
|
|
@@ -1978,8 +2029,14 @@ parse_stab_enum_type (void *dhandle, con
|
|
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;
|
|
}
|
|
|
|
@@ -2011,7 +2068,7 @@ parse_stab_enum_type (void *dhandle, con
|
|
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);
|
|
@@ -2053,9 +2110,13 @@ parse_stab_enum_type (void *dhandle, con
|
|
*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)
|
|
{
|
|
bfd_vma size;
|
|
debug_baseclass *baseclasses;
|
|
@@ -2066,14 +2127,14 @@ parse_stab_struct_type (void *dhandle, s
|
|
bfd_boolean ownvptr;
|
|
|
|
/* 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))
|
|
+ &ownvptr, p_end))
|
|
{
|
|
if (fields != NULL)
|
|
free (fields);
|
|
@@ -2116,8 +2177,11 @@ parse_stab_struct_type (void *dhandle, s
|
|
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;
|
|
@@ -2126,6 +2190,8 @@ parse_stab_baseclasses (void *dhandle, s
|
|
*retp = NULL;
|
|
|
|
orig = *pp;
|
|
+ if (orig >= p_end)
|
|
+ return FALSE;
|
|
|
|
if (**pp != '!')
|
|
{
|
|
@@ -2134,7 +2200,7 @@ parse_stab_baseclasses (void *dhandle, s
|
|
}
|
|
++*pp;
|
|
|
|
- c = (unsigned int) parse_number (pp, (bfd_boolean *) NULL);
|
|
+ c = (unsigned int) parse_number (pp, (bfd_boolean *) NULL, p_end);
|
|
|
|
if (**pp != ',')
|
|
{
|
|
@@ -2160,6 +2226,9 @@ parse_stab_baseclasses (void *dhandle, s
|
|
case '1':
|
|
is_virtual = TRUE;
|
|
break;
|
|
+ case 0:
|
|
+ bad_stab (orig);
|
|
+ return FALSE;
|
|
default:
|
|
warn_stab (orig, _("unknown virtual character for baseclass"));
|
|
is_virtual = FALSE;
|
|
@@ -2178,6 +2247,9 @@ parse_stab_baseclasses (void *dhandle, s
|
|
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;
|
|
@@ -2188,7 +2260,7 @@ parse_stab_baseclasses (void *dhandle, s
|
|
/* 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);
|
|
@@ -2197,7 +2269,7 @@ parse_stab_baseclasses (void *dhandle, s
|
|
++*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;
|
|
|
|
@@ -2239,9 +2311,12 @@ parse_stab_baseclasses (void *dhandle, s
|
|
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;
|
|
@@ -2253,6 +2328,8 @@ parse_stab_struct_fields (void *dhandle,
|
|
*staticsp = FALSE;
|
|
|
|
orig = *pp;
|
|
+ if (orig >= p_end)
|
|
+ return FALSE;
|
|
|
|
c = 0;
|
|
alloc = 10;
|
|
@@ -2281,7 +2358,7 @@ parse_stab_struct_fields (void *dhandle,
|
|
if ((*p == '$' || *p == '.') && p[1] != '_')
|
|
{
|
|
++*pp;
|
|
- if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c))
|
|
+ if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c, p_end))
|
|
{
|
|
free (fields);
|
|
return FALSE;
|
|
@@ -2307,7 +2384,7 @@ parse_stab_struct_fields (void *dhandle,
|
|
break;
|
|
|
|
if (! parse_stab_one_struct_field (dhandle, info, pp, p, fields + c,
|
|
- staticsp))
|
|
+ staticsp, p_end))
|
|
/* There is a potential resource leak here, but it is not important. */
|
|
/* coverity[leaked_storage: FALSE] */
|
|
return FALSE;
|
|
@@ -2325,8 +2402,11 @@ parse_stab_struct_fields (void *dhandle,
|
|
/* 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;
|
|
@@ -2339,6 +2419,8 @@ parse_stab_cpp_abbrev (void *dhandle, st
|
|
*retp = DEBUG_FIELD_NULL;
|
|
|
|
orig = *pp;
|
|
+ if (orig >= p_end)
|
|
+ return FALSE;
|
|
|
|
if (**pp != 'v')
|
|
{
|
|
@@ -2348,6 +2430,11 @@ parse_stab_cpp_abbrev (void *dhandle, st
|
|
++*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
|
|
@@ -2356,7 +2443,7 @@ parse_stab_cpp_abbrev (void *dhandle, st
|
|
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;
|
|
|
|
@@ -2392,7 +2479,7 @@ parse_stab_cpp_abbrev (void *dhandle, st
|
|
++*pp;
|
|
|
|
type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
|
|
- (debug_type **) NULL);
|
|
+ (debug_type **) NULL, p_end);
|
|
if (**pp != ',')
|
|
{
|
|
bad_stab (orig);
|
|
@@ -2402,7 +2489,7 @@ parse_stab_cpp_abbrev (void *dhandle, st
|
|
}
|
|
++*pp;
|
|
|
|
- bitpos = parse_number (pp, (bfd_boolean *) NULL);
|
|
+ bitpos = parse_number (pp, (bfd_boolean *) NULL, p_end);
|
|
if (**pp != ';')
|
|
{
|
|
bad_stab (orig);
|
|
@@ -2423,9 +2510,13 @@ parse_stab_cpp_abbrev (void *dhandle, st
|
|
/* 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;
|
|
@@ -2435,6 +2526,8 @@ parse_stab_one_struct_field (void *dhand
|
|
bfd_vma bitsize;
|
|
|
|
orig = *pp;
|
|
+ if (orig >= p_end)
|
|
+ return FALSE;
|
|
|
|
/* FIXME: gdb checks ARM_DEMANGLING here. */
|
|
|
|
@@ -2458,6 +2551,9 @@ parse_stab_one_struct_field (void *dhand
|
|
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;
|
|
@@ -2467,7 +2563,7 @@ parse_stab_one_struct_field (void *dhand
|
|
}
|
|
|
|
type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
|
|
- (debug_type **) NULL);
|
|
+ (debug_type **) NULL, p_end);
|
|
if (type == DEBUG_TYPE_NULL)
|
|
{
|
|
free (name);
|
|
@@ -2507,7 +2603,7 @@ parse_stab_one_struct_field (void *dhand
|
|
}
|
|
++*pp;
|
|
|
|
- bitpos = parse_number (pp, (bfd_boolean *) NULL);
|
|
+ bitpos = parse_number (pp, (bfd_boolean *) NULL, p_end);
|
|
if (**pp != ',')
|
|
{
|
|
bad_stab (orig);
|
|
@@ -2516,7 +2612,7 @@ parse_stab_one_struct_field (void *dhand
|
|
}
|
|
++*pp;
|
|
|
|
- bitsize = parse_number (pp, (bfd_boolean *) NULL);
|
|
+ bitsize = parse_number (pp, (bfd_boolean *) NULL, p_end);
|
|
if (**pp != ';')
|
|
{
|
|
bad_stab (orig);
|
|
@@ -2564,9 +2660,13 @@ parse_stab_one_struct_field (void *dhand
|
|
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;
|
|
@@ -2579,6 +2679,8 @@ parse_stab_members (void *dhandle, struc
|
|
*retp = NULL;
|
|
|
|
orig = *pp;
|
|
+ if (orig >= p_end)
|
|
+ return FALSE;
|
|
|
|
alloc = 0;
|
|
methods = NULL;
|
|
@@ -2648,7 +2750,7 @@ parse_stab_members (void *dhandle, struc
|
|
else
|
|
{
|
|
type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
|
|
- (debug_type **) NULL);
|
|
+ (debug_type **) NULL, p_end);
|
|
if (type == DEBUG_TYPE_NULL)
|
|
goto fail;
|
|
|
|
@@ -2683,6 +2785,9 @@ parse_stab_members (void *dhandle, struc
|
|
case '1':
|
|
visibility = DEBUG_VISIBILITY_PROTECTED;
|
|
break;
|
|
+ case 0:
|
|
+ bad_stab (orig);
|
|
+ goto fail;
|
|
default:
|
|
visibility = DEBUG_VISIBILITY_PUBLIC;
|
|
break;
|
|
@@ -2731,7 +2836,7 @@ parse_stab_members (void *dhandle, struc
|
|
bit is supposedly set to distinguish
|
|
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);
|
|
@@ -2753,7 +2858,8 @@ parse_stab_members (void *dhandle, struc
|
|
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. */
|
|
@@ -3014,9 +3120,13 @@ parse_stab_argtypes (void *dhandle, stru
|
|
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;
|
|
@@ -3026,14 +3136,15 @@ parse_stab_tilde_field (void *dhandle, s
|
|
*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 == '-')
|
|
@@ -3045,14 +3156,13 @@ parse_stab_tilde_field (void *dhandle, s
|
|
|
|
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]
|
|
@@ -3066,7 +3176,7 @@ parse_stab_tilde_field (void *dhandle, s
|
|
*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 != ';')
|
|
@@ -3086,8 +3196,11 @@ parse_stab_tilde_field (void *dhandle, s
|
|
/* 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;
|
|
@@ -3105,13 +3218,16 @@ parse_stab_array_type (void *dhandle, st
|
|
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");
|
|
@@ -3126,7 +3242,7 @@ parse_stab_array_type (void *dhandle, st
|
|
else
|
|
{
|
|
index_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
|
|
- (debug_type **) NULL);
|
|
+ (debug_type **) NULL, p_end);
|
|
}
|
|
|
|
if (**pp != ';')
|
|
@@ -3140,13 +3256,13 @@ parse_stab_array_type (void *dhandle, st
|
|
|
|
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);
|
|
@@ -3156,13 +3272,13 @@ parse_stab_array_type (void *dhandle, st
|
|
}
|
|
++*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);
|
|
@@ -3173,7 +3289,7 @@ parse_stab_array_type (void *dhandle, st
|
|
++*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)
|
|
/* There is a potential resource leak here, but it is not important. */
|
|
/* coverity[leaked_storage: FALSE] */
|
|
Only in binutils-2.30/binutils: stabs.c.orig
|
|
Only in binutils-2.30/binutils: stabs.c.rej
|