📄 stabs.c
字号:
parse_stab_type (dhandle, info,
(const char *) NULL,
pp,
(debug_type **) NULL));
break;
case 'B':
/* Volatile qual on some type (Sun). */
/* FIXME: gdb accepts 'i' here if os9k_stabs. */
dtype = (debug_make_volatile_type
(dhandle,
parse_stab_type (dhandle, info, (const char *) NULL, pp,
(debug_type **) NULL)));
break;
case '@':
/* Offset (class & variable) type. This is used for a pointer
relative to an object. */
{
debug_type domain;
debug_type memtype;
/* Member type. */
domain = parse_stab_type (dhandle, info, (const char *) NULL, pp,
(debug_type **) NULL);
if (domain == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
if (**pp != ',')
{
bad_stab (orig);
return DEBUG_TYPE_NULL;
}
++*pp;
memtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
(debug_type **) NULL);
if (memtype == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
dtype = debug_make_offset_type (dhandle, domain, memtype);
}
break;
case '#':
/* Method (class & fn) type. */
if (**pp == '#')
{
debug_type return_type;
++*pp;
return_type = parse_stab_type (dhandle, info, (const char *) NULL,
pp, (debug_type **) NULL);
if (return_type == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
if (**pp != ';')
{
bad_stab (orig);
return DEBUG_TYPE_NULL;
}
++*pp;
dtype = debug_make_method_type (dhandle, return_type,
DEBUG_TYPE_NULL,
(debug_type *) NULL, false);
}
else
{
debug_type domain;
debug_type return_type;
debug_type *args;
unsigned int n;
unsigned int alloc;
bfd_boolean varargs;
domain = parse_stab_type (dhandle, info, (const char *) NULL,
pp, (debug_type **) NULL);
if (domain == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
if (**pp != ',')
{
bad_stab (orig);
return DEBUG_TYPE_NULL;
}
++*pp;
return_type = parse_stab_type (dhandle, info, (const char *) NULL,
pp, (debug_type **) NULL);
if (return_type == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
alloc = 10;
args = (debug_type *) xmalloc (alloc * sizeof *args);
n = 0;
while (**pp != ';')
{
if (**pp != ',')
{
bad_stab (orig);
return DEBUG_TYPE_NULL;
}
++*pp;
if (n + 1 >= alloc)
{
alloc += 10;
args = ((debug_type *)
xrealloc ((PTR) args, alloc * sizeof *args));
}
args[n] = parse_stab_type (dhandle, info, (const char *) NULL,
pp, (debug_type **) NULL);
if (args[n] == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
++n;
}
++*pp;
/* If the last type is not void, then this function takes a
variable number of arguments. Otherwise, we must strip
the void type. */
if (n == 0
|| debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID)
varargs = true;
else
{
--n;
varargs = false;
}
args[n] = DEBUG_TYPE_NULL;
dtype = debug_make_method_type (dhandle, return_type, domain, args,
varargs);
}
break;
case 'r':
/* Range type. */
dtype = parse_stab_range_type (dhandle, info, typename, pp, typenums);
break;
case 'b':
/* FIXME: gdb checks os9k_stabs here. */
/* Sun ACC builtin int type. */
dtype = parse_stab_sun_builtin_type (dhandle, pp);
break;
case 'R':
/* Sun ACC builtin float type. */
dtype = parse_stab_sun_floating_type (dhandle, pp);
break;
case 'e':
/* Enumeration type. */
dtype = parse_stab_enum_type (dhandle, pp);
break;
case 's':
case 'u':
/* Struct or union type. */
dtype = parse_stab_struct_type (dhandle, info, typename, pp,
descriptor == 's', typenums);
break;
case 'a':
/* Array type. */
if (**pp != 'r')
{
bad_stab (orig);
return DEBUG_TYPE_NULL;
}
++*pp;
dtype = parse_stab_array_type (dhandle, info, pp, stringp);
break;
case 'S':
dtype = debug_make_set_type (dhandle,
parse_stab_type (dhandle, info,
(const char *) NULL,
pp,
(debug_type **) NULL),
stringp);
break;
default:
bad_stab (orig);
return DEBUG_TYPE_NULL;
}
if (dtype == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
if (typenums[0] != -1)
{
if (! stab_record_type (dhandle, info, typenums, dtype))
return DEBUG_TYPE_NULL;
}
if (size != -1)
{
if (! debug_record_type_size (dhandle, dtype, (unsigned int) size))
return DEBUG_TYPE_NULL;
}
return dtype;
}
/* Read a number by which a type is referred to in dbx data, or
perhaps read a pair (FILENUM, TYPENUM) in parentheses. Just a
single number N is equivalent to (0,N). Return the two numbers by
storing them in the vector TYPENUMS. */
static bfd_boolean
parse_stab_type_number (pp, typenums)
const char **pp;
int *typenums;
{
const char *orig;
orig = *pp;
if (**pp != '(')
{
typenums[0] = 0;
typenums[1] = (int) parse_number (pp, (bfd_boolean *) NULL);
}
else
{
++*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;
}
return true;
}
/* Parse a range type. */
static debug_type
parse_stab_range_type (dhandle, info, typename, pp, typenums)
PTR dhandle;
struct stab_handle *info;
const char *typename;
const char **pp;
const int *typenums;
{
const char *orig;
int rangenums[2];
bfd_boolean self_subrange;
debug_type index_type;
const char *s2, *s3;
bfd_signed_vma n2, n3;
bfd_boolean ov2, ov3;
orig = *pp;
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))
return DEBUG_TYPE_NULL;
self_subrange = (rangenums[0] == typenums[0]
&& rangenums[1] == typenums[1]);
if (**pp == '=')
{
*pp = orig;
index_type = parse_stab_type (dhandle, info, (const char *) NULL,
pp, (debug_type **) NULL);
if (index_type == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
}
if (**pp == ';')
++*pp;
/* 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);
if (**pp != ';')
{
bad_stab (orig);
return DEBUG_TYPE_NULL;
}
++*pp;
s3 = *pp;
n3 = parse_number (pp, &ov3);
if (**pp != ';')
{
bad_stab (orig);
return DEBUG_TYPE_NULL;
}
++*pp;
if (ov2 || ov3)
{
/* gcc will emit range stabs for long long types. Handle this
as a special case. FIXME: This needs to be more general. */
#define LLLOW "01000000000000000000000;"
#define LLHIGH "0777777777777777777777;"
#define ULLHIGH "01777777777777777777777;"
if (index_type == DEBUG_TYPE_NULL)
{
if (strncmp (s2, LLLOW, sizeof LLLOW - 1) == 0
&& strncmp (s3, LLHIGH, sizeof LLHIGH - 1) == 0)
return debug_make_int_type (dhandle, 8, false);
if (! ov2
&& n2 == 0
&& strncmp (s3, ULLHIGH, sizeof ULLHIGH - 1) == 0)
return debug_make_int_type (dhandle, 8, true);
}
warn_stab (orig, _("numeric overflow"));
}
if (index_type == DEBUG_TYPE_NULL)
{
/* A type defined as a subrange of itself, with both bounds 0,
is void. */
if (self_subrange && n2 == 0 && n3 == 0)
return debug_make_void_type (dhandle);
/* A type defined as a subrange of itself, with n2 positive and
n3 zero, is a complex type, and n2 is the number of bytes. */
if (self_subrange && n3 == 0 && n2 > 0)
return debug_make_complex_type (dhandle, n2);
/* If n3 is zero and n2 is positive, this is a floating point
type, and n2 is the number of bytes. */
if (n3 == 0 && n2 > 0)
return debug_make_float_type (dhandle, n2);
/* If the upper bound is -1, this is an unsigned int. */
if (n2 == 0 && n3 == -1)
{
/* When gcc is used with -gstabs, but not -gstabs+, it will emit
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 (strcmp (typename, "long long int") == 0)
return debug_make_int_type (dhandle, 8, false);
else if (strcmp (typename, "long long unsigned int") == 0)
return debug_make_int_type (dhandle, 8, true);
}
/* FIXME: The size here really depends upon the target. */
return debug_make_int_type (dhandle, 4, true);
}
/* A range of 0 to 127 is char. */
if (self_subrange && n2 == 0 && n3 == 127)
return debug_make_int_type (dhandle, 1, false);
/* FIXME: gdb checks for the language CHILL here. */
if (n2 == 0)
{
if (n3 < 0)
return debug_make_int_type (dhandle, - n3, true);
else if (n3 == 0xff)
return debug_make_int_type (dhandle, 1, true);
else if (n3 == 0xffff)
return debug_make_int_type (dhandle, 2, true);
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))
return debug_make_int_type (dhandle, 8, true);
#endif
}
else if (n3 == 0
&& n2 < 0
&& (self_subrange || n2 == -8))
return debug_make_int_type (dhandle, - n2, true);
else if (n2 == - n3 - 1 || n2 == n3 + 1)
{
if (n3 == 0x7f)
return debug_make_int_type (dhandle, 1, false);
else if (n3 == 0x7fff)
return debug_make_int_type (dhandle, 2, false);
else if (n3 == 0x7fffffff)
return debug_make_int_type (dhandle, 4, false);
#ifdef BFD64
else if (n3 == ((((bfd_vma) 0x7fffffff) << 32) | 0xffffffff))
return debug_make_int_type (dhandle, 8, false);
#endif
}
}
/* At this point I don't have the faintest idea how to deal with a
self_subrange type; I'm going to assume that this is used as an
idiom, and that all of them are special cases. So . . . */
if (self_subrange)
{
bad_stab (orig);
return DEBUG_TYPE_NULL;
}
index_type = stab_find_type (dhandle, info, rangenums);
if (index_type == DEBUG_TYPE_NULL)
{
/* Does this actually ever happen? Is that why we are worrying
about dealing with it rather than just calling error_type? */
warn_stab (orig, _("missing index type"));
index_type = debug_make_int_type (dhandle, 4, false);
}
return debug_make_range_type (dhandle, index_type, n2, n3);
}
/* Sun's ACC uses a somewhat saner method for specifying the builtin
typedefs in every file (for int, long, etc):
type = b <signed> <width>; <offset>; <nbits>
signed = u or s. Possible c in addition to u or s (for char?).
offset = offset from high order bit to start bit of type.
width is # bytes in object of this type, nbits is # bits in type.
The width/offset stuff appears to be for small objects stored in
larger ones (e.g. `shorts' in `int' registers). We ignore it for now,
FIXME. */
static debug_type
parse_stab_sun_builtin_type (dhandle, pp)
PTR dhandle;
const char **pp;
{
const char *orig;
bfd_boolean unsignedp;
bfd_vma bits;
orig = *pp;
switch (**pp)
{
case 's':
unsignedp = false;
break;
case 'u':
unsignedp = true;
break;
default:
bad_stab (orig);
return DEBUG_TYPE_NULL;
}
++*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')
++*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);
if (**pp != ';')
{
bad_stab (orig);
return DEBUG_TYPE_NULL;
}
++*pp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -