📄 ieee.c
字号:
{
const bfd_byte *start;
bfd_vma val;
bfd_boolean present;
ieee_record_enum_type c;
start = *pp;
if (! ieee_read_optional_number (info, pp, &val, &present))
return false;
if (present)
{
if (esp - expr_stack >= EXPR_STACK_SIZE)
{
ieee_error (info, start, _("expression stack overflow"));
return false;
}
*esp++ = val;
continue;
}
c = (ieee_record_enum_type) **pp;
if (c >= ieee_module_beginning_enum)
break;
++*pp;
if (c == ieee_comma)
break;
switch (c)
{
default:
ieee_error (info, start, _("unsupported IEEE expression operator"));
break;
case ieee_variable_R_enum:
{
bfd_vma indx;
asection *s;
if (! ieee_read_number (info, pp, &indx))
return false;
for (s = info->abfd->sections; s != NULL; s = s->next)
if ((bfd_vma) s->target_index == indx)
break;
if (s == NULL)
{
ieee_error (info, start, _("unknown section"));
return false;
}
if (esp - expr_stack >= EXPR_STACK_SIZE)
{
ieee_error (info, start, _("expression stack overflow"));
return false;
}
*esp++ = bfd_get_section_vma (info->abfd, s);
}
break;
case ieee_function_plus_enum:
case ieee_function_minus_enum:
{
bfd_vma v1, v2;
if (esp - expr_stack < 2)
{
ieee_error (info, start, _("expression stack underflow"));
return false;
}
v1 = *--esp;
v2 = *--esp;
*esp++ = v1 + v2;
}
break;
}
}
if (esp - 1 != expr_stack)
{
ieee_error (info, expr_start, _("expression stack mismatch"));
return false;
}
*pv = *--esp;
return true;
}
/* Return an IEEE builtin type. */
static debug_type
ieee_builtin_type (info, p, indx)
struct ieee_info *info;
const bfd_byte *p;
unsigned int indx;
{
PTR dhandle;
debug_type type;
const char *name;
if (indx < BUILTIN_TYPE_COUNT
&& info->types.builtins[indx] != DEBUG_TYPE_NULL)
return info->types.builtins[indx];
dhandle = info->dhandle;
if (indx >= 32 && indx < 64)
{
type = debug_make_pointer_type (dhandle,
ieee_builtin_type (info, p, indx - 32));
assert (indx < BUILTIN_TYPE_COUNT);
info->types.builtins[indx] = type;
return type;
}
switch ((enum builtin_types) indx)
{
default:
ieee_error (info, p, _("unknown builtin type"));
return NULL;
case builtin_unknown:
type = debug_make_void_type (dhandle);
name = NULL;
break;
case builtin_void:
type = debug_make_void_type (dhandle);
name = "void";
break;
case builtin_signed_char:
type = debug_make_int_type (dhandle, 1, false);
name = "signed char";
break;
case builtin_unsigned_char:
type = debug_make_int_type (dhandle, 1, true);
name = "unsigned char";
break;
case builtin_signed_short_int:
type = debug_make_int_type (dhandle, 2, false);
name = "signed short int";
break;
case builtin_unsigned_short_int:
type = debug_make_int_type (dhandle, 2, true);
name = "unsigned short int";
break;
case builtin_signed_long:
type = debug_make_int_type (dhandle, 4, false);
name = "signed long";
break;
case builtin_unsigned_long:
type = debug_make_int_type (dhandle, 4, true);
name = "unsigned long";
break;
case builtin_signed_long_long:
type = debug_make_int_type (dhandle, 8, false);
name = "signed long long";
break;
case builtin_unsigned_long_long:
type = debug_make_int_type (dhandle, 8, true);
name = "unsigned long long";
break;
case builtin_float:
type = debug_make_float_type (dhandle, 4);
name = "float";
break;
case builtin_double:
type = debug_make_float_type (dhandle, 8);
name = "double";
break;
case builtin_long_double:
/* FIXME: The size for this type should depend upon the
processor. */
type = debug_make_float_type (dhandle, 12);
name = "long double";
break;
case builtin_long_long_double:
type = debug_make_float_type (dhandle, 16);
name = "long long double";
break;
case builtin_quoted_string:
type = debug_make_array_type (dhandle,
ieee_builtin_type (info, p,
((unsigned int)
builtin_char)),
ieee_builtin_type (info, p,
((unsigned int)
builtin_int)),
0, -1, true);
name = "QUOTED STRING";
break;
case builtin_instruction_address:
/* FIXME: This should be a code address. */
type = debug_make_int_type (dhandle, 4, true);
name = "instruction address";
break;
case builtin_int:
/* FIXME: The size for this type should depend upon the
processor. */
type = debug_make_int_type (dhandle, 4, false);
name = "int";
break;
case builtin_unsigned:
/* FIXME: The size for this type should depend upon the
processor. */
type = debug_make_int_type (dhandle, 4, true);
name = "unsigned";
break;
case builtin_unsigned_int:
/* FIXME: The size for this type should depend upon the
processor. */
type = debug_make_int_type (dhandle, 4, true);
name = "unsigned int";
break;
case builtin_char:
type = debug_make_int_type (dhandle, 1, false);
name = "char";
break;
case builtin_long:
type = debug_make_int_type (dhandle, 4, false);
name = "long";
break;
case builtin_short:
type = debug_make_int_type (dhandle, 2, false);
name = "short";
break;
case builtin_unsigned_short:
type = debug_make_int_type (dhandle, 2, true);
name = "unsigned short";
break;
case builtin_short_int:
type = debug_make_int_type (dhandle, 2, false);
name = "short int";
break;
case builtin_signed_short:
type = debug_make_int_type (dhandle, 2, false);
name = "signed short";
break;
case builtin_bcd_float:
ieee_error (info, p, _("BCD float type not supported"));
return DEBUG_TYPE_NULL;
}
if (name != NULL)
type = debug_name_type (dhandle, name, type);
assert (indx < BUILTIN_TYPE_COUNT);
info->types.builtins[indx] = type;
return type;
}
/* Allocate more space in the type table. If ref is true, this is a
reference to the type; if it is not already defined, we should set
up an indirect type. */
static bfd_boolean
ieee_alloc_type (info, indx, ref)
struct ieee_info *info;
unsigned int indx;
bfd_boolean ref;
{
unsigned int nalloc;
register struct ieee_type *t;
struct ieee_type *tend;
if (indx >= info->types.alloc)
{
nalloc = info->types.alloc;
if (nalloc == 0)
nalloc = 4;
while (indx >= nalloc)
nalloc *= 2;
info->types.types = ((struct ieee_type *)
xrealloc (info->types.types,
nalloc * sizeof *info->types.types));
memset (info->types.types + info->types.alloc, 0,
(nalloc - info->types.alloc) * sizeof *info->types.types);
tend = info->types.types + nalloc;
for (t = info->types.types + info->types.alloc; t < tend; t++)
t->type = DEBUG_TYPE_NULL;
info->types.alloc = nalloc;
}
if (ref)
{
t = info->types.types + indx;
if (t->type == NULL)
{
t->pslot = (debug_type *) xmalloc (sizeof *t->pslot);
*t->pslot = DEBUG_TYPE_NULL;
t->type = debug_make_indirect_type (info->dhandle, t->pslot,
(const char *) NULL);
if (t->type == NULL)
return false;
}
}
return true;
}
/* Read a type index and return the corresponding type. */
static bfd_boolean
ieee_read_type_index (info, pp, ptype)
struct ieee_info *info;
const bfd_byte **pp;
debug_type *ptype;
{
const bfd_byte *start;
bfd_vma indx;
start = *pp;
if (! ieee_read_number (info, pp, &indx))
return false;
if (indx < 256)
{
*ptype = ieee_builtin_type (info, start, indx);
if (*ptype == NULL)
return false;
return true;
}
indx -= 256;
if (! ieee_alloc_type (info, indx, true))
return false;
*ptype = info->types.types[indx].type;
return true;
}
/* Parse IEEE debugging information for a file. This is passed the
bytes which compose the Debug Information Part of an IEEE file. */
bfd_boolean
parse_ieee (dhandle, abfd, bytes, len)
PTR dhandle;
bfd *abfd;
const bfd_byte *bytes;
bfd_size_type len;
{
struct ieee_info info;
unsigned int i;
const bfd_byte *p, *pend;
info.dhandle = dhandle;
info.abfd = abfd;
info.bytes = bytes;
info.pend = bytes + len;
info.blockstack.bsp = info.blockstack.stack;
info.saw_filename = false;
info.vars.alloc = 0;
info.vars.vars = NULL;
info.global_vars = NULL;
info.types.alloc = 0;
info.types.types = NULL;
info.global_types = NULL;
info.tags = NULL;
for (i = 0; i < BUILTIN_TYPE_COUNT; i++)
info.types.builtins[i] = DEBUG_TYPE_NULL;
p = bytes;
pend = info.pend;
while (p < pend)
{
const bfd_byte *record_start;
ieee_record_enum_type c;
record_start = p;
c = (ieee_record_enum_type) *p++;
if (c == ieee_at_record_enum)
c = (ieee_record_enum_type) (((unsigned int) c << 8) | *p++);
if (c <= ieee_number_repeat_end_enum)
{
ieee_error (&info, record_start, _("unexpected number"));
return false;
}
switch (c)
{
default:
ieee_error (&info, record_start, _("unexpected record type"));
return false;
case ieee_bb_record_enum:
if (! parse_ieee_bb (&info, &p))
return false;
break;
case ieee_be_record_enum:
if (! parse_ieee_be (&info, &p))
return false;
break;
case ieee_nn_record:
if (! parse_ieee_nn (&info, &p))
return false;
break;
case ieee_ty_record_enum:
if (! parse_ieee_ty (&info, &p))
return false;
break;
case ieee_atn_record_enum:
if (! parse_ieee_atn (&info, &p))
return false;
break;
}
}
if (info.blockstack.bsp != info.blockstack.stack)
{
ieee_error (&info, (const bfd_byte *) NULL,
_("blocks left on stack at end"));
return false;
}
return true;
}
/* Handle an IEEE BB record. */
static bfd_boolean
parse_ieee_bb (info, pp)
struct ieee_info *info;
const bfd_byte **pp;
{
const bfd_byte *block_start;
bfd_byte b;
bfd_vma size;
const char *name;
unsigned long namlen;
char *namcopy = NULL;
unsigned int fnindx;
bfd_boolean skip;
block_start = *pp;
b = **pp;
++*pp;
if (! ieee_read_number (info, pp, &size)
|| ! ieee_read_id (info, pp, &name, &namlen))
return false;
fnindx = (unsigned int) -1;
skip = false;
switch (b)
{
case 1:
/* BB1: Type definitions local to a module. */
namcopy = savestring (name, namlen);
if (namcopy == NULL)
return false;
if (! debug_set_filename (info->dhandle, namcopy))
return false;
info->saw_filename = true;
/* Discard any variables or types we may have seen before. */
if (info->vars.vars != NULL)
free (info->vars.vars);
info->vars.vars = NULL;
info->vars.alloc = 0;
if (info->types.types != NULL)
free (info->types.types);
info->types.types = NULL;
info->types.alloc = 0;
/* Initialize the types to the global types. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -