X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fstabs.c;h=aebde7afe97214d0d4fce7ad351c4dc22ee6c3ea;hb=ad43e107eb233dcef8e76da6328aa4e4d74afd84;hp=879a3e2c7a7065906d44dc65d1d8d2667fd58743;hpb=01f0fe5e0450edf168c1f612feb93cf588e4e7ea;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/stabs.c b/binutils/stabs.c index 879a3e2c7a..aebde7afe9 100644 --- a/binutils/stabs.c +++ b/binutils/stabs.c @@ -1,13 +1,12 @@ /* stabs.c -- Parse stabs debugging information - Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 - Free Software Foundation, Inc. + Copyright (C) 1995-2016 Free Software Foundation, Inc. Written by Ian Lance Taylor . 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, @@ -25,10 +24,8 @@ code. The job it does is somewhat different, because it is not trying to identify the correct address for anything. */ -#include - +#include "sysdep.h" #include "bfd.h" -#include "bucomm.h" #include "libiberty.h" #include "safe-ctype.h" #include "demangle.h" @@ -679,7 +676,7 @@ parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value, 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 *p; char *name; @@ -687,7 +684,6 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype, debug_type dtype; bfd_boolean synonym; bfd_boolean self_crossref; - unsigned int lineno; debug_type *slot; p = strchr (string, ':'); @@ -705,14 +701,6 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype, } } - /* 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] == '$') @@ -848,8 +836,6 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype, case 'G': { - char leading; - long c; asymbol **ps; /* A global symbol. The value must be extracted from the @@ -858,19 +844,27 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype, (debug_type **) NULL); 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; @@ -1107,6 +1101,26 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype, 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; @@ -1124,7 +1138,7 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype, 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 *orig; int typenums[2]; @@ -1288,9 +1302,9 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename, 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); @@ -1521,7 +1535,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename, 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); break; case 'b': @@ -1543,7 +1557,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename, case 's': case 'u': /* Struct or union type. */ - dtype = parse_stab_struct_type (dhandle, info, typename, pp, + dtype = parse_stab_struct_type (dhandle, info, type_name, pp, descriptor == 's', typenums); break; @@ -1633,7 +1647,7 @@ parse_stab_type_number (const char **pp, int *typenums) /* 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 *orig; int rangenums[2]; @@ -1696,12 +1710,12 @@ parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *type #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); } @@ -1732,11 +1746,11 @@ parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *type 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. */ @@ -1760,7 +1774,7 @@ parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *type 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 } @@ -1839,11 +1853,13 @@ parse_stab_sun_builtin_type (void *dhandle, const char **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 @@ -1969,6 +1985,9 @@ parse_stab_enum_type (void *dhandle, const char **pp) if (**pp != ',') { bad_stab (orig); + free (name); + free (names); + free (values); return DEBUG_TYPE_NULL; } ++*pp; @@ -2008,17 +2027,14 @@ parse_stab_struct_type (void *dhandle, struct stab_handle *info, const char *tagname, const char **pp, bfd_boolean structp, const int *typenums) { - const char *orig; bfd_vma size; 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); @@ -2028,7 +2044,11 @@ parse_stab_struct_type (void *dhandle, struct stab_handle *info, || ! parse_stab_members (dhandle, info, tagname, pp, typenums, &methods) || ! parse_stab_tilde_field (dhandle, info, pp, typenums, &vptrbase, &ownvptr)) - return DEBUG_TYPE_NULL; + { + if (fields != NULL) + free (fields); + return DEBUG_TYPE_NULL; + } if (! statics && baseclasses == NULL @@ -2097,7 +2117,7 @@ parse_stab_baseclasses (void *dhandle, struct stab_handle *info, for (i = 0; i < c; i++) { - bfd_boolean virtual; + bfd_boolean is_virtual; enum debug_visibility visibility; bfd_vma bitpos; debug_type type; @@ -2105,14 +2125,14 @@ parse_stab_baseclasses (void *dhandle, struct stab_handle *info, switch (**pp) { case '0': - virtual = FALSE; + is_virtual = FALSE; break; case '1': - virtual = TRUE; + is_virtual = TRUE; break; default: warn_stab (orig, _("unknown virtual character for baseclass")); - virtual = FALSE; + is_virtual = FALSE; break; } ++*pp; @@ -2151,7 +2171,7 @@ parse_stab_baseclasses (void *dhandle, struct stab_handle *info, 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; @@ -2232,7 +2252,10 @@ parse_stab_struct_fields (void *dhandle, struct stab_handle *info, { ++*pp; if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c)) - return FALSE; + { + free (fields); + return FALSE; + } ++c; continue; } @@ -2246,6 +2269,7 @@ parse_stab_struct_fields (void *dhandle, struct stab_handle *info, if (p == NULL) { bad_stab (orig); + free (fields); return FALSE; } @@ -2276,7 +2300,7 @@ parse_stab_cpp_abbrev (void *dhandle, struct stab_handle *info, int cpp_abbrev; debug_type context; const char *name; - const char *typename; + const char *type_name; debug_type type; bfd_vma bitpos; @@ -2312,13 +2336,13 @@ parse_stab_cpp_abbrev (void *dhandle, struct stab_handle *info, 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")); @@ -2407,7 +2431,10 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info, type = parse_stab_type (dhandle, info, (const char *) NULL, pp, (debug_type **) NULL); if (type == DEBUG_TYPE_NULL) - return FALSE; + { + free (name); + return FALSE; + } if (**pp == ':') { @@ -2419,6 +2446,7 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info, if (p == NULL) { bad_stab (orig); + free (name); return FALSE; } @@ -2436,6 +2464,7 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info, if (**pp != ',') { bad_stab (orig); + free (name); return FALSE; } ++*pp; @@ -2444,6 +2473,7 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info, if (**pp != ',') { bad_stab (orig); + free (name); return FALSE; } ++*pp; @@ -2452,6 +2482,7 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info, if (**pp != ';') { bad_stab (orig); + free (name); return FALSE; } ++*pp; @@ -2503,6 +2534,9 @@ parse_stab_members (void *dhandle, struct stab_handle *info, debug_method *methods; unsigned int c; unsigned int alloc; + char *name = NULL; + debug_method_variant *variants = NULL; + char *argtypes = NULL; *retp = NULL; @@ -2515,8 +2549,6 @@ parse_stab_members (void *dhandle, struct stab_handle *info, while (**pp != ';') { const char *p; - char *name; - debug_method_variant *variants; unsigned int cvars; unsigned int allocvars; debug_type look_ahead_type; @@ -2545,7 +2577,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info, if (*p != '.') { bad_stab (orig); - return FALSE; + goto fail; } name = savestring (*pp, p - *pp); *pp = p + 1; @@ -2562,7 +2594,6 @@ parse_stab_members (void *dhandle, struct stab_handle *info, { debug_type type; bfd_boolean stub; - char *argtypes; enum debug_visibility visibility; bfd_boolean constp, volatilep, staticp; bfd_vma voffset; @@ -2581,11 +2612,12 @@ parse_stab_members (void *dhandle, struct stab_handle *info, type = parse_stab_type (dhandle, info, (const char *) NULL, pp, (debug_type **) NULL); if (type == DEBUG_TYPE_NULL) - return FALSE; + goto fail; + if (**pp != ':') { bad_stab (orig); - return FALSE; + goto fail; } } @@ -2594,7 +2626,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info, if (p == NULL) { bad_stab (orig); - return FALSE; + goto fail; } stub = FALSE; @@ -2665,7 +2697,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info, if (**pp != ';') { bad_stab (orig); - return FALSE; + goto fail; } ++*pp; voffset &= 0x7fffffff; @@ -2696,7 +2728,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info, if (**pp != ';') { bad_stab (orig); - return FALSE; + goto fail; } ++*pp; } @@ -2731,26 +2763,25 @@ parse_stab_members (void *dhandle, struct stab_handle *info, 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) @@ -2774,7 +2805,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info, constp, volatilep); if (variants[cvars] == DEBUG_METHOD_VARIANT_NULL) - return FALSE; + goto fail; ++cvars; } @@ -2803,6 +2834,15 @@ parse_stab_members (void *dhandle, struct stab_handle *info, *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 @@ -2832,7 +2872,7 @@ parse_stab_argtypes (void *dhandle, struct stab_handle *info, && (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 @@ -2840,12 +2880,10 @@ parse_stab_argtypes (void *dhandle, struct stab_handle *info, 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; @@ -3257,26 +3295,26 @@ static debug_type * 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) { @@ -3284,7 +3322,7 @@ stab_find_slot (struct stab_handle *info, const int *typenums) memset (*ps, 0, sizeof **ps); } ps = &(*ps)->next; - index -= STAB_TYPES_SLOTS; + tindex -= STAB_TYPES_SLOTS; } if (*ps == NULL) { @@ -3292,7 +3330,7 @@ stab_find_slot (struct stab_handle *info, const int *typenums) 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 @@ -3841,7 +3879,7 @@ stab_demangle_function_name (struct stab_demangle_info *minfo, *pp = scan + 2; if (*pp - name >= 5 - && strncmp (name, "type", 4) == 0 + && CONST_STRNEQ (name, "type") && (name[4] == '$' || name[4] == '.')) { const char *tem; @@ -4100,7 +4138,10 @@ stab_demangle_qualified (struct stab_demangle_info *minfo, const char **pp, 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) { @@ -4647,7 +4688,7 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp, 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; @@ -4655,8 +4696,6 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp, const char *name; memberp = **pp == 'M'; - constp = FALSE; - volatilep = FALSE; args = NULL; varargs = FALSE; @@ -4700,12 +4739,10 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp, { if (**pp == 'C') { - constp = TRUE; ++*pp; } else if (**pp == 'V') { - volatilep = TRUE; ++*pp; } if (**pp != 'F') @@ -4766,9 +4803,6 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp, case 'Q': { - const char *hold; - - hold = *pp; if (! stab_demangle_qualified (minfo, pp, ptype)) return FALSE; } @@ -5137,6 +5171,11 @@ stab_demangle_v3_arglist (void *dhandle, struct stab_handle *info, 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)