struct ieee_defined_enum *next;
/* Type index. */
unsigned int indx;
+ /* Whether this enum has been defined. */
+ boolean defined;
/* Tag. */
const char *tag;
/* Names. */
/* Prepend the global typedef information to the other data. */
if (! ieee_buffer_emptyp (&info.global_types))
{
+ /* The HP debugger seems to have a bug in which it ignores the
+ last entry in the global types, so we add a dummy entry. */
if (! ieee_change_buffer (&info, &info.global_types)
+ || ! ieee_write_byte (&info, (int) ieee_nn_record)
+ || ! ieee_write_number (&info, info.name_indx)
+ || ! ieee_write_id (&info, "")
+ || ! ieee_write_byte (&info, (int) ieee_ty_record_enum)
+ || ! ieee_write_number (&info, info.type_indx)
+ || ! ieee_write_byte (&info, 0xce)
+ || ! ieee_write_number (&info, info.name_indx)
+ || ! ieee_write_number (&info, 'P')
+ || ! ieee_write_number (&info, (int) builtin_void + 32)
|| ! ieee_write_byte (&info, (int) ieee_be_record_enum))
return false;
/* Coalesce ranges if it seems reasonable. */
while (r->next != NULL
- && high + 64 >= r->next->low
+ && high + 0x1000 >= r->next->low
&& (r->next->high
<= (bfd_get_section_vma (info->abfd, s)
+ bfd_section_size (info->abfd, s))))
return;
}
- if (low < r->low)
+ if (low < r->low
+ && r->low - low > 0x100)
{
if (! ieee_add_bb11 (info, sec, low, r->low))
{
struct ieee_handle *info = (struct ieee_handle *) p;
struct ieee_defined_enum *e;
boolean localp, simple;
+ unsigned int indx;
int i;
localp = false;
+ indx = (unsigned int) -1;
for (e = info->enums; e != NULL; e = e->next)
{
if (tag == NULL)
continue;
}
+ if (! e->defined)
+ {
+ /* This enum tag has been seen but not defined. */
+ indx = e->indx;
+ break;
+ }
+
if (names != NULL && e->names != NULL)
{
for (i = 0; names[i] != NULL && e->names[i] != NULL; i++)
}
}
- if (! ieee_define_named_type (info, tag, (unsigned int) -1, 0,
- true, localp, (struct ieee_buflist *) NULL)
+ if (! ieee_define_named_type (info, tag, indx, 0, true, localp,
+ (struct ieee_buflist *) NULL)
|| ! ieee_write_number (info, simple ? 'E' : 'N'))
return false;
if (simple)
if (! localp)
{
- e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
- memset (e, 0, sizeof *e);
+ if (indx == (unsigned int) -1)
+ {
+ e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
+ memset (e, 0, sizeof *e);
+ e->indx = info->type_stack->type.indx;
+ e->tag = tag;
+
+ e->next = info->enums;
+ info->enums = e;
+ }
- e->indx = info->type_stack->type.indx;
- e->tag = tag;
e->names = names;
e->vals = vals;
-
- e->next = info->enums;
- info->enums = e;
+ e->defined = true;
}
return true;
struct ieee_handle *info = (struct ieee_handle *) p;
unsigned int eleindx;
boolean localp;
+ unsigned int size;
struct ieee_modified_type *m = NULL;
struct ieee_modified_array_type *a;
/* IEEE does not store the range, so we just ignore it. */
ieee_pop_unused_type (info);
localp = info->type_stack->type.localp;
+ size = info->type_stack->type.size;
eleindx = ieee_pop_type (info);
+ /* If we don't know the range, treat the size as exactly one
+ element. */
+ if (low < high)
+ size *= (high - low) + 1;
+
if (! localp)
{
m = ieee_get_modified_info (info, eleindx);
for (a = m->arrays; a != NULL; a = a->next)
{
if (a->low == low && a->high == high)
- return ieee_push_type (info, a->indx, 0, false, false);
+ return ieee_push_type (info, a->indx, size, false, false);
}
}
- if (! ieee_define_type (info, 0, false, localp)
+ if (! ieee_define_type (info, size, false, localp)
|| ! ieee_write_number (info, low == 0 ? 'Z' : 'C')
|| ! ieee_write_number (info, eleindx))
return false;
for (e = info->enums; e != NULL; e = e->next)
if (e->tag != NULL && strcmp (e->tag, name) == 0)
return ieee_push_type (info, e->indx, 0, true, false);
- abort ();
+
+ e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
+ memset (e, 0, sizeof *e);
+
+ e->indx = info->type_indx;
+ ++info->type_indx;
+ e->tag = name;
+ e->defined = false;
+
+ e->next = info->enums;
+ info->enums = e;
+
+ return ieee_push_type (info, e->indx, 0, true, false);
}
localp = false;
return false;
}
- info->pending_lineno_filename = filename;
- info->pending_lineno = lineno;
- info->pending_lineno_addr = addr;
+ if (addr < info->highaddr)
+ {
+ info->pending_lineno_filename = filename;
+ info->pending_lineno = lineno;
+ info->pending_lineno_addr = addr;
+ }
return true;
}