📄 ieee.c
字号:
if (info->global_types != NULL)
{
info->types.alloc = info->global_types->alloc;
info->types.types = ((struct ieee_type *)
xmalloc (info->types.alloc
* sizeof (*info->types.types)));
memcpy (info->types.types, info->global_types->types,
info->types.alloc * sizeof (*info->types.types));
}
break;
case 2:
/* BB2: Global type definitions. The name is supposed to be
empty, but we don't check. */
if (! debug_set_filename (info->dhandle, "*global*"))
return false;
info->saw_filename = true;
break;
case 3:
/* BB3: High level module block begin. We don't have to do
anything here. The name is supposed to be the same as for
the BB1, but we don't check. */
break;
case 4:
/* BB4: Global function. */
{
bfd_vma stackspace, typindx, offset;
debug_type return_type;
if (! ieee_read_number (info, pp, &stackspace)
|| ! ieee_read_number (info, pp, &typindx)
|| ! ieee_read_expression (info, pp, &offset))
return false;
/* We have no way to record the stack space. FIXME. */
if (typindx < 256)
{
return_type = ieee_builtin_type (info, block_start, typindx);
if (return_type == DEBUG_TYPE_NULL)
return false;
}
else
{
typindx -= 256;
if (! ieee_alloc_type (info, typindx, true))
return false;
fnindx = typindx;
return_type = info->types.types[typindx].type;
if (debug_get_type_kind (info->dhandle, return_type)
== DEBUG_KIND_FUNCTION)
return_type = debug_get_return_type (info->dhandle,
return_type);
}
namcopy = savestring (name, namlen);
if (namcopy == NULL)
return false;
if (! debug_record_function (info->dhandle, namcopy, return_type,
true, offset))
return false;
}
break;
case 5:
/* BB5: File name for source line numbers. */
{
unsigned int i;
/* We ignore the date and time. FIXME. */
for (i = 0; i < 6; i++)
{
bfd_vma ignore;
bfd_boolean present;
if (! ieee_read_optional_number (info, pp, &ignore, &present))
return false;
if (! present)
break;
}
namcopy = savestring (name, namlen);
if (namcopy == NULL)
return false;
if (! debug_start_source (info->dhandle, namcopy))
return false;
}
break;
case 6:
/* BB6: Local function or block. */
{
bfd_vma stackspace, typindx, offset;
if (! ieee_read_number (info, pp, &stackspace)
|| ! ieee_read_number (info, pp, &typindx)
|| ! ieee_read_expression (info, pp, &offset))
return false;
/* We have no way to record the stack space. FIXME. */
if (namlen == 0)
{
if (! debug_start_block (info->dhandle, offset))
return false;
/* Change b to indicate that this is a block
rather than a function. */
b = 0x86;
}
else
{
/* The MRI C++ compiler will output a fake function named
__XRYCPP to hold C++ debugging information. We skip
that function. This is not crucial, but it makes
converting from IEEE to other debug formats work
better. */
if (strncmp (name, "__XRYCPP", namlen) == 0)
skip = true;
else
{
debug_type return_type;
if (typindx < 256)
{
return_type = ieee_builtin_type (info, block_start,
typindx);
if (return_type == NULL)
return false;
}
else
{
typindx -= 256;
if (! ieee_alloc_type (info, typindx, true))
return false;
fnindx = typindx;
return_type = info->types.types[typindx].type;
if (debug_get_type_kind (info->dhandle, return_type)
== DEBUG_KIND_FUNCTION)
return_type = debug_get_return_type (info->dhandle,
return_type);
}
namcopy = savestring (name, namlen);
if (namcopy == NULL)
return false;
if (! debug_record_function (info->dhandle, namcopy,
return_type, false, offset))
return false;
}
}
}
break;
case 10:
/* BB10: Assembler module scope. In the normal case, we
completely ignore all this information. FIXME. */
{
const char *inam, *vstr;
unsigned long inamlen, vstrlen;
bfd_vma tool_type;
bfd_boolean present;
unsigned int i;
if (! info->saw_filename)
{
namcopy = savestring (name, namlen);
if (namcopy == NULL)
return false;
if (! debug_set_filename (info->dhandle, namcopy))
return false;
info->saw_filename = true;
}
if (! ieee_read_id (info, pp, &inam, &inamlen)
|| ! ieee_read_number (info, pp, &tool_type)
|| ! ieee_read_optional_id (info, pp, &vstr, &vstrlen, &present))
return false;
for (i = 0; i < 6; i++)
{
bfd_vma ignore;
if (! ieee_read_optional_number (info, pp, &ignore, &present))
return false;
if (! present)
break;
}
}
break;
case 11:
/* BB11: Module section. We completely ignore all this
information. FIXME. */
{
bfd_vma sectype, secindx, offset, map;
bfd_boolean present;
if (! ieee_read_number (info, pp, §ype)
|| ! ieee_read_number (info, pp, &secindx)
|| ! ieee_read_expression (info, pp, &offset)
|| ! ieee_read_optional_number (info, pp, &map, &present))
return false;
}
break;
default:
ieee_error (info, block_start, _("unknown BB type"));
return false;
}
/* Push this block on the block stack. */
if (info->blockstack.bsp >= info->blockstack.stack + BLOCKSTACK_SIZE)
{
ieee_error (info, (const bfd_byte *) NULL, _("stack overflow"));
return false;
}
info->blockstack.bsp->kind = b;
if (b == 5)
info->blockstack.bsp->filename = namcopy;
info->blockstack.bsp->fnindx = fnindx;
info->blockstack.bsp->skip = skip;
++info->blockstack.bsp;
return true;
}
/* Handle an IEEE BE record. */
static bfd_boolean
parse_ieee_be (info, pp)
struct ieee_info *info;
const bfd_byte **pp;
{
bfd_vma offset;
if (info->blockstack.bsp <= info->blockstack.stack)
{
ieee_error (info, *pp, _("stack underflow"));
return false;
}
--info->blockstack.bsp;
switch (info->blockstack.bsp->kind)
{
case 2:
/* When we end the global typedefs block, we copy out the the
contents of info->vars. This is because the variable indices
may be reused in the local blocks. However, we need to
preserve them so that we can locate a function returning a
reference variable whose type is named in the global typedef
block. */
info->global_vars = ((struct ieee_vars *)
xmalloc (sizeof *info->global_vars));
info->global_vars->alloc = info->vars.alloc;
info->global_vars->vars = ((struct ieee_var *)
xmalloc (info->vars.alloc
* sizeof (*info->vars.vars)));
memcpy (info->global_vars->vars, info->vars.vars,
info->vars.alloc * sizeof (*info->vars.vars));
/* We also copy out the non builtin parts of info->types, since
the types are discarded when we start a new block. */
info->global_types = ((struct ieee_types *)
xmalloc (sizeof *info->global_types));
info->global_types->alloc = info->types.alloc;
info->global_types->types = ((struct ieee_type *)
xmalloc (info->types.alloc
* sizeof (*info->types.types)));
memcpy (info->global_types->types, info->types.types,
info->types.alloc * sizeof (*info->types.types));
memset (info->global_types->builtins, 0,
sizeof (info->global_types->builtins));
break;
case 4:
case 6:
if (! ieee_read_expression (info, pp, &offset))
return false;
if (! info->blockstack.bsp->skip)
{
if (! debug_end_function (info->dhandle, offset + 1))
return false;
}
break;
case 0x86:
/* This is BE6 when BB6 started a block rather than a local
function. */
if (! ieee_read_expression (info, pp, &offset))
return false;
if (! debug_end_block (info->dhandle, offset + 1))
return false;
break;
case 5:
/* When we end a BB5, we look up the stack for the last BB5, if
there is one, so that we can call debug_start_source. */
if (info->blockstack.bsp > info->blockstack.stack)
{
struct ieee_block *bl;
bl = info->blockstack.bsp;
do
{
--bl;
if (bl->kind == 5)
{
if (! debug_start_source (info->dhandle, bl->filename))
return false;
break;
}
}
while (bl != info->blockstack.stack);
}
break;
case 11:
if (! ieee_read_expression (info, pp, &offset))
return false;
/* We just ignore the module size. FIXME. */
break;
default:
/* Other block types do not have any trailing information. */
break;
}
return true;
}
/* Parse an NN record. */
static bfd_boolean
parse_ieee_nn (info, pp)
struct ieee_info *info;
const bfd_byte **pp;
{
const bfd_byte *nn_start;
bfd_vma varindx;
const char *name;
unsigned long namlen;
nn_start = *pp;
if (! ieee_read_number (info, pp, &varindx)
|| ! ieee_read_id (info, pp, &name, &namlen))
return false;
if (varindx < 32)
{
ieee_error (info, nn_start, _("illegal variable index"));
return false;
}
varindx -= 32;
if (varindx >= info->vars.alloc)
{
unsigned int alloc;
alloc = info->vars.alloc;
if (alloc == 0)
alloc = 4;
while (varindx >= alloc)
alloc *= 2;
info->vars.vars = ((struct ieee_var *)
xrealloc (info->vars.vars,
alloc * sizeof *info->vars.vars));
memset (info->vars.vars + info->vars.alloc, 0,
(alloc - info->vars.alloc) * sizeof *info->vars.vars);
info->vars.alloc = alloc;
}
info->vars.vars[varindx].name = name;
info->vars.vars[varindx].namlen = namlen;
return true;
}
/* Parse a TY record. */
static bfd_boolean
parse_ieee_ty (info, pp)
struct ieee_info *info;
const bfd_byte **pp;
{
const bfd_byte *ty_start, *ty_var_start, *ty_code_start;
bfd_vma typeindx, varindx, tc;
PTR dhandle;
bfd_boolean tag, typdef;
debug_type *arg_slots;
unsigned long type_bitsize;
debug_type type;
ty_start = *pp;
if (! ieee_read_number (info, pp, &typeindx))
return false;
if (typeindx < 256)
{
ieee_error (info, ty_start, _("illegal type index"));
return false;
}
typeindx -= 256;
if (! ieee_alloc_type (info, typeindx, false))
return false;
if (**pp != 0xce)
{
ieee_error (info, *pp, _("unknown TY code"));
return false;
}
++*pp;
ty_var_start = *pp;
if (! ieee_read_number (info, pp, &varindx))
return false;
if (varindx < 32)
{
ieee_error (info, ty_var_start, _("illegal variable index"));
return false;
}
varindx -= 32;
if (varindx >= info->vars.alloc || info->vars.vars[varindx].name == NULL)
{
ieee_error (info, ty_var_start, _("undefined variable in TY"));
return false;
}
ty_code_start = *pp;
if (! ieee_read_number (info, pp, &tc))
return false;
dhandle = info->dhandle;
tag = false;
typdef = false;
arg_slots = NULL;
type_bitsize = 0;
switch (tc)
{
default:
ieee_error (info, ty_code_start, _("unknown TY code"));
return false;
case '!':
/* Unknown type, with size. We treat it as int. FIXME. */
{
bfd_vma size;
if (! ieee_read_number (info, pp, &size))
return false;
type = debug_make_int_type (dhandle, size, false);
}
break;
case 'A': /* Array. */
case 'a': /* FORTRAN array in column/row order. FIXME: Not
distinguished from normal array. */
{
debug_type ele_type;
bfd_vma lower, upper;
if (! ieee_read_type_index (info, pp, &ele_type)
|| ! ieee_read_number (info, pp, &lower)
|| ! ieee_read_number (info, pp, &upper))
return false;
type = debug_make_array_type (dhandle, ele_type,
ieee_builtin_type (info, ty_code_start,
((unsigned int)
builtin_int)),
(bfd_signed_vma) lower,
(bfd_signed_vma) upper,
false);
}
break;
case 'E':
/* Simple enumeration. */
{
bfd_vma size;
unsigned int alloc;
const char **names;
unsigned int c;
bfd_signed_vma *vals;
unsigned int i;
if (! ieee_read_number (info, pp, &size))
return false;
/* FIXME: we ignore the enumeration size. */
alloc = 10;
names = (const char **) xmalloc (alloc * sizeof *names);
memset (names, 0, alloc * sizeof *names);
c = 0;
while (1)
{
const char *name;
unsigned long namlen;
bfd_boolean present;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -