struct cie_info
{
+ fragS *f;
unsigned code_alignment;
int z_augmentation;
};
/* Extract information from the CIE. */
-static int
+static bool
get_cie_info (struct cie_info *info)
{
fragS *f;
- fixS *fix;
unsigned int offset;
char CIE_id;
char augmentation[10];
/* We should find the CIE at the start of the section. */
f = seg_info (now_seg)->frchainP->frch_root;
- fix = seg_info (now_seg)->frchainP->fix_root;
-
- /* Look through the frags of the section to find the code alignment. */
+ while (f != NULL && f->fr_fix == 0)
+ f = f->fr_next;
+ if (f != info->f)
+ return false;
/* First make sure that the CIE Identifier Tag is 0/-1. */
|| f->fr_literal[offset + 1] != CIE_id
|| f->fr_literal[offset + 2] != CIE_id
|| f->fr_literal[offset + 3] != CIE_id)
- return 0;
+ return false;
/* Next make sure the CIE version number is 1. */
if (f == NULL
|| f->fr_fix - offset < 1
|| f->fr_literal[offset] != 1)
- return 0;
+ return false;
/* Skip the augmentation (a null terminated string). */
f = f->fr_next;
}
if (f == NULL)
- return 0;
+ return false;
while (offset < f->fr_fix && f->fr_literal[offset] != '\0')
{
f = f->fr_next;
}
if (f == NULL)
- return 0;
+ return false;
augmentation[iaug] = '\0';
if (augmentation[0] == '\0')
{
/* We have to skip a pointer. Unfortunately, we don't know how
large it is. We find out by looking for a matching fixup. */
+ fixS *fix = seg_info (now_seg)->frchainP->fix_root;
while (fix != NULL
&& (fix->fx_frag != f || fix->fx_where != offset))
fix = fix->fx_next;
f = f->fr_next;
}
if (f == NULL)
- return 0;
+ return false;
}
else if (augmentation[0] != 'z')
- return 0;
+ return false;
/* We're now at the code alignment factor, which is a ULEB128. If
it isn't a single byte, forget it. */
info->code_alignment = code_alignment;
info->z_augmentation = (augmentation[0] == 'z');
- return 1;
+ return true;
}
enum frame_state
{
enum frame_state state;
- int cie_info_ok;
+ bool cie_info_ok;
struct cie_info cie_info;
symbolS *size_end_sym;
{
d->state = state_saw_size;
d->size_end_sym = exp->X_add_symbol;
+ if (!d->cie_info.f)
+ d->cie_info.f = frag_now;
}
}
break;
case state_saw_size:
case state_saw_cie_offset:
- /* Assume whatever form it appears in, it appears atomically. */
- d->state = (enum frame_state) (d->state + 1);
+ if (!(*pnbytes == 4 || *pnbytes == 8))
+ /* Stop scanning if we don't see the expected FDE fields. */
+ d->state = state_error;
+ else
+ d->state = (enum frame_state) (d->state + 1);
break;
case state_saw_pc_begin:
/* Decide whether we should see an augmentation. */
- if (! d->cie_info_ok
- && ! (d->cie_info_ok = get_cie_info (&d->cie_info)))
+ if (!(*pnbytes == 4 || *pnbytes == 8))
+ d->state = state_error;
+ else if (!d->cie_info_ok
+ && !(d->cie_info_ok = get_cie_info (&d->cie_info)))
d->state = state_error;
else if (d->cie_info.z_augmentation)
{
case state_seeing_aug_size:
/* Bytes == -1 means this comes from an leb128 directive. */
- if ((int)*pnbytes == -1 && exp->X_op == O_constant)
+ if ((int) *pnbytes == -1 && exp->X_op == O_constant)
{
d->aug_size = exp->X_add_number;
d->state = state_skipping_aug;
break;
case state_skipping_aug:
- if ((int)*pnbytes < 0)
+ if ((int) *pnbytes < 0)
d->state = state_error;
else
{