📄 ieee.c
字号:
if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
return false;
if (! present)
break;
if (c + 1 >= alloc)
{
alloc += 10;
names = ((const char **)
xrealloc (names, alloc * sizeof *names));
}
names[c] = savestring (name, namlen);
if (names[c] == NULL)
return false;
++c;
}
names[c] = NULL;
vals = (bfd_signed_vma *) xmalloc (c * sizeof *vals);
for (i = 0; i < c; i++)
vals[i] = i;
type = debug_make_enum_type (dhandle, names, vals);
tag = true;
}
break;
case 'G':
/* Struct with bit fields. */
{
bfd_vma size;
unsigned int alloc;
debug_field *fields;
unsigned int c;
if (! ieee_read_number (info, pp, &size))
return false;
alloc = 10;
fields = (debug_field *) xmalloc (alloc * sizeof *fields);
c = 0;
while (1)
{
const char *name;
unsigned long namlen;
bfd_boolean present;
debug_type ftype;
bfd_vma bitpos, bitsize;
if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
return false;
if (! present)
break;
if (! ieee_read_type_index (info, pp, &ftype)
|| ! ieee_read_number (info, pp, &bitpos)
|| ! ieee_read_number (info, pp, &bitsize))
return false;
if (c + 1 >= alloc)
{
alloc += 10;
fields = ((debug_field *)
xrealloc (fields, alloc * sizeof *fields));
}
fields[c] = debug_make_field (dhandle, savestring (name, namlen),
ftype, bitpos, bitsize,
DEBUG_VISIBILITY_PUBLIC);
if (fields[c] == NULL)
return false;
++c;
}
fields[c] = NULL;
type = debug_make_struct_type (dhandle, true, size, fields);
tag = true;
}
break;
case 'N':
/* Enumeration. */
{
unsigned int alloc;
const char **names;
bfd_signed_vma *vals;
unsigned int c;
alloc = 10;
names = (const char **) xmalloc (alloc * sizeof *names);
vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *names);
c = 0;
while (1)
{
const char *name;
unsigned long namlen;
bfd_boolean present;
bfd_vma val;
if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
return false;
if (! present)
break;
if (! ieee_read_number (info, pp, &val))
return false;
/* If the length of the name is zero, then the value is
actually the size of the enum. We ignore this
information. FIXME. */
if (namlen == 0)
continue;
if (c + 1 >= alloc)
{
alloc += 10;
names = ((const char **)
xrealloc (names, alloc * sizeof *names));
vals = ((bfd_signed_vma *)
xrealloc (vals, alloc * sizeof *vals));
}
names[c] = savestring (name, namlen);
if (names[c] == NULL)
return false;
vals[c] = (bfd_signed_vma) val;
++c;
}
names[c] = NULL;
type = debug_make_enum_type (dhandle, names, vals);
tag = true;
}
break;
case 'O': /* Small pointer. We don't distinguish small and large
pointers. FIXME. */
case 'P': /* Large pointer. */
{
debug_type t;
if (! ieee_read_type_index (info, pp, &t))
return false;
type = debug_make_pointer_type (dhandle, t);
}
break;
case 'R':
/* Range. */
{
bfd_vma low, high, signedp, size;
if (! ieee_read_number (info, pp, &low)
|| ! ieee_read_number (info, pp, &high)
|| ! ieee_read_number (info, pp, &signedp)
|| ! ieee_read_number (info, pp, &size))
return false;
type = debug_make_range_type (dhandle,
debug_make_int_type (dhandle, size,
! signedp),
(bfd_signed_vma) low,
(bfd_signed_vma) high);
}
break;
case 'S': /* Struct. */
case 'U': /* Union. */
{
bfd_vma size;
unsigned int alloc;
debug_field *fields;
unsigned int c;
if (! ieee_read_number (info, pp, &size))
return false;
alloc = 10;
fields = (debug_field *) xmalloc (alloc * sizeof *fields);
c = 0;
while (1)
{
const char *name;
unsigned long namlen;
bfd_boolean present;
bfd_vma tindx;
bfd_vma offset;
debug_type ftype;
bfd_vma bitsize;
if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
return false;
if (! present)
break;
if (! ieee_read_number (info, pp, &tindx)
|| ! ieee_read_number (info, pp, &offset))
return false;
if (tindx < 256)
{
ftype = ieee_builtin_type (info, ty_code_start, tindx);
bitsize = 0;
offset *= 8;
}
else
{
struct ieee_type *t;
tindx -= 256;
if (! ieee_alloc_type (info, tindx, true))
return false;
t = info->types.types + tindx;
ftype = t->type;
bitsize = t->bitsize;
if (bitsize == 0)
offset *= 8;
}
if (c + 1 >= alloc)
{
alloc += 10;
fields = ((debug_field *)
xrealloc (fields, alloc * sizeof *fields));
}
fields[c] = debug_make_field (dhandle, savestring (name, namlen),
ftype, offset, bitsize,
DEBUG_VISIBILITY_PUBLIC);
if (fields[c] == NULL)
return false;
++c;
}
fields[c] = NULL;
type = debug_make_struct_type (dhandle, tc == 'S', size, fields);
tag = true;
}
break;
case 'T':
/* Typedef. */
if (! ieee_read_type_index (info, pp, &type))
return false;
typdef = true;
break;
case 'X':
/* Procedure. FIXME: This is an extern declaration, which we
have no way of representing. */
{
bfd_vma attr;
debug_type rtype;
bfd_vma nargs;
bfd_boolean present;
struct ieee_var *pv;
/* FIXME: We ignore the attribute and the argument names. */
if (! ieee_read_number (info, pp, &attr)
|| ! ieee_read_type_index (info, pp, &rtype)
|| ! ieee_read_number (info, pp, &nargs))
return false;
do
{
const char *name;
unsigned long namlen;
if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
return false;
}
while (present);
pv = info->vars.vars + varindx;
pv->kind = IEEE_EXTERNAL;
if (pv->namlen > 0
&& debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER)
{
/* Set up the return type as an indirect type pointing to
the variable slot, so that we can change it to a
reference later if appropriate. */
pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot);
*pv->pslot = rtype;
rtype = debug_make_indirect_type (dhandle, pv->pslot,
(const char *) NULL);
}
type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL,
false);
}
break;
case 'V':
/* Void. This is not documented, but the MRI compiler emits it. */
type = debug_make_void_type (dhandle);
break;
case 'Z':
/* Array with 0 lower bound. */
{
debug_type etype;
bfd_vma high;
if (! ieee_read_type_index (info, pp, &etype)
|| ! ieee_read_number (info, pp, &high))
return false;
type = debug_make_array_type (dhandle, etype,
ieee_builtin_type (info, ty_code_start,
((unsigned int)
builtin_int)),
0, (bfd_signed_vma) high, false);
}
break;
case 'c': /* Complex. */
case 'd': /* Double complex. */
{
const char *name;
unsigned long namlen;
/* FIXME: I don't know what the name means. */
if (! ieee_read_id (info, pp, &name, &namlen))
return false;
type = debug_make_complex_type (dhandle, tc == 'c' ? 4 : 8);
}
break;
case 'f':
/* Pascal file name. FIXME. */
ieee_error (info, ty_code_start, _("Pascal file name not supported"));
return false;
case 'g':
/* Bitfield type. */
{
bfd_vma signedp, bitsize, dummy;
const bfd_byte *hold;
bfd_boolean present;
if (! ieee_read_number (info, pp, &signedp)
|| ! ieee_read_number (info, pp, &bitsize))
return false;
/* I think the documentation says that there is a type index,
but some actual files do not have one. */
hold = *pp;
if (! ieee_read_optional_number (info, pp, &dummy, &present))
return false;
if (! present)
{
/* FIXME: This is just a guess. */
type = debug_make_int_type (dhandle, 4,
signedp ? false : true);
}
else
{
*pp = hold;
if (! ieee_read_type_index (info, pp, &type))
return false;
}
type_bitsize = bitsize;
}
break;
case 'n':
/* Qualifier. */
{
bfd_vma kind;
debug_type t;
if (! ieee_read_number (info, pp, &kind)
|| ! ieee_read_type_index (info, pp, &t))
return false;
switch (kind)
{
default:
ieee_error (info, ty_start, _("unsupported qualifer"));
return false;
case 1:
type = debug_make_const_type (dhandle, t);
break;
case 2:
type = debug_make_volatile_type (dhandle, t);
break;
}
}
break;
case 's':
/* Set. */
{
bfd_vma size;
debug_type etype;
if (! ieee_read_number (info, pp, &size)
|| ! ieee_read_type_index (info, pp, &etype))
return false;
/* FIXME: We ignore the size. */
type = debug_make_set_type (dhandle, etype, false);
}
break;
case 'x':
/* Procedure with compiler dependencies. */
{
struct ieee_var *pv;
bfd_vma attr, frame_type, push_mask, nargs, level, father;
debug_type rtype;
debug_type *arg_types;
bfd_boolean varargs;
bfd_boolean present;
/* FIXME: We ignore some of this information. */
pv = info->vars.vars + varindx;
if (! ieee_read_number (info, pp, &attr)
|| ! ieee_read_number (info, pp, &frame_type)
|| ! ieee_read_number (info, pp, &push_mask)
|| ! ieee_read_type_index (info, pp, &rtype)
|| ! ieee_read_number (info, pp, &nargs))
return false;
if (nargs == (bfd_vma) -1)
{
arg_types = NULL;
varargs = false;
}
else
{
unsigned int i;
arg_types = ((debug_type *)
xmalloc ((nargs + 1) * sizeof *arg_types));
for (i = 0; i < nargs; i++)
if (! ieee_read_type_index (info, pp, arg_types + i))
return false;
/* If the last type is pointer to void, this is really a
varargs function. */
varargs = false;
if (nargs > 0)
{
debug_type last;
last = arg_types[nargs - 1];
if (debug_get_type_kind (dhandle, last) == DEBUG_KIND_POINTER
&& (debug_get_type_kind (dhandle,
debug_get_target_type (dhandle,
last))
== DEBUG_KIND_VOID))
{
--nargs;
varargs = true;
}
}
/* If there are any pointer arguments, turn them into
indirect types in case we later need to convert them to
reference types. */
for (i = 0; i < nargs; i++)
{
if (debug_get_type_kind (dhandle, arg_types[i])
== DEBUG_KIND_POINTER)
{
if (arg_slots == NULL)
{
arg_slots = ((debug_type *)
xmalloc (nargs * sizeof *arg_slots));
memset (arg_slots, 0, nargs * sizeof *arg_slots);
}
arg_slots[i] = arg_types[i];
arg_types[i] =
debug_make_indirect_type (dhandle,
arg_slots + i,
(const char *) NULL);
}
}
arg_types[nargs] = DEBUG_TYPE_NULL;
}
if (! ieee_read_number (info, pp, &level)
|| ! ieee_read_optional_number (info, pp, &father, &present))
return false;
/* We can't distinguish between a global function and a static
function. */
pv->kind = IEEE_FUNCTION;
if (pv->namlen > 0
&& debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER)
{
/* Set up the return type as an indirect type pointing to
the variable slot, so that we can change it to a
reference later if appropriate. */
pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot);
*pv->pslot = rtype;
rtype = debug_make_indirect_type (dhandle, pv->pslot,
(const char *) NULL);
}
type = debug_make_function_type (dhandle, rtype, arg_types, varargs);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -