Deleted Added
full compact
2c2
< Copyright (C) 1998, 2000 Free Software Foundation, Inc.
---
> Copyright 1998, 2000, 2001 Free Software Foundation, Inc.
91c91,95
< static int eh_frame_code_alignment PARAMS ((int));
---
> struct cie_info
> {
> unsigned code_alignment;
> int z_augmentation;
> };
93c97
< /* Get the code alignment factor from the CIE. */
---
> static int get_cie_info PARAMS ((struct cie_info *));
94a99,100
> /* Extract information from the CIE. */
>
96,97c102,103
< eh_frame_code_alignment (in_seg)
< int in_seg;
---
> get_cie_info (info)
> struct cie_info *info;
99,101d104
< /* ??? Assume .eh_frame and .debug_frame have the same alignment. */
< static int code_alignment;
<
107a111
> int code_alignment = 0;
109,115d112
< if (code_alignment != 0)
< return code_alignment;
<
< /* Can't find the alignment if we've changed sections. */
< if (! in_seg)
< return -1;
<
150,153c147
< {
< code_alignment = -1;
< return -1;
< }
---
> return 0;
166,169c160
< {
< code_alignment = -1;
< return -1;
< }
---
> return 0;
183,186c174,175
< {
< code_alignment = -1;
< return -1;
< }
---
> return 0;
>
206,209c195
< {
< code_alignment = -1;
< return -1;
< }
---
> return 0;
233,236c219
< {
< code_alignment = -1;
< return -1;
< }
---
> return 0;
238,242c221,222
< else
< {
< code_alignment = -1;
< return -1;
< }
---
> else if (augmentation[0] != 'z')
> return 0;
248,252c228,229
< if ((code_alignment & 0x80) != 0 || code_alignment == 0)
< {
< code_alignment = -1;
< return -1;
< }
---
> if ((code_alignment & 0x80) != 0)
> code_alignment = 0;
254c231,234
< return code_alignment;
---
> info->code_alignment = code_alignment;
> info->z_augmentation = (augmentation[0] == 'z');
>
> return 1;
276a257,272
> enum frame_state
> {
> state_idle,
> state_saw_size,
> state_saw_cie_offset,
> state_saw_pc_begin,
> state_seeing_aug_size,
> state_skipping_aug,
> state_wait_loc4,
> state_saw_loc4,
> state_error,
> } state;
>
> int cie_info_ok;
> struct cie_info cie_info;
>
279,280d274
< int saw_size;
< int saw_advance_loc4;
281a276,278
>
> int aug_size;
> int aug_shift;
300c297
< if (d->saw_size && S_IS_DEFINED (d->size_end_sym))
---
> if (d->state >= state_saw_size && S_IS_DEFINED (d->size_end_sym))
305,306c302
< d->saw_size = 0;
< d->saw_advance_loc4 = 0;
---
> d->state = state_idle;
309,310c305
< if (! d->saw_size
< && *pnbytes == 4)
---
> switch (d->state)
312,322c307,308
< /* This might be the size of the CIE or FDE. We want to know
< the size so that we don't accidentally optimize across an FDE
< boundary. We recognize the size in one of two forms: a
< symbol which will later be defined as a difference, or a
< subtraction of two symbols. Either way, we can tell when we
< are at the end of the FDE because the symbol becomes defined
< (in the case of a subtraction, the end symbol, from which the
< start symbol is being subtracted). Other ways of describing
< the size will not be optimized. */
< if ((exp->X_op == O_symbol || exp->X_op == O_subtract)
< && ! S_IS_DEFINED (exp->X_add_symbol))
---
> case state_idle:
> if (*pnbytes == 4)
324,325c310,324
< d->saw_size = 1;
< d->size_end_sym = exp->X_add_symbol;
---
> /* This might be the size of the CIE or FDE. We want to know
> the size so that we don't accidentally optimize across an FDE
> boundary. We recognize the size in one of two forms: a
> symbol which will later be defined as a difference, or a
> subtraction of two symbols. Either way, we can tell when we
> are at the end of the FDE because the symbol becomes defined
> (in the case of a subtraction, the end symbol, from which the
> start symbol is being subtracted). Other ways of describing
> the size will not be optimized. */
> if ((exp->X_op == O_symbol || exp->X_op == O_subtract)
> && ! S_IS_DEFINED (exp->X_add_symbol))
> {
> d->state = state_saw_size;
> d->size_end_sym = exp->X_add_symbol;
> }
327,344c326
< }
< else if (d->saw_size
< && *pnbytes == 1
< && exp->X_op == O_constant
< && exp->X_add_number == DW_CFA_advance_loc4)
< {
< /* This might be a DW_CFA_advance_loc4. Record the frag and the
< position within the frag, so that we can change it later. */
< d->saw_advance_loc4 = 1;
< frag_grow (1);
< d->loc4_frag = frag_now;
< d->loc4_fix = frag_now_fix ();
< }
< else if (d->saw_advance_loc4
< && *pnbytes == 4
< && exp->X_op == O_constant)
< {
< int ca;
---
> break;
346,349c328,332
< /* This is a case which we can optimize. The two symbols being
< subtracted were in the same frag and the expression was
< reduced to a constant. We can do the optimization entirely
< in this function. */
---
> case state_saw_size:
> case state_saw_cie_offset:
> /* Assume whatever form it appears in, it appears atomically. */
> d->state += 1;
> break;
351c334,347
< d->saw_advance_loc4 = 0;
---
> 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)))
> d->state = state_error;
> else if (d->cie_info.z_augmentation)
> {
> d->state = state_seeing_aug_size;
> d->aug_size = 0;
> d->aug_shift = 0;
> }
> else
> d->state = state_wait_loc4;
> break;
353,354c349,351
< ca = eh_frame_code_alignment (1);
< if (ca < 0)
---
> case state_seeing_aug_size:
> /* Bytes == -1 means this comes from an leb128 directive. */
> if ((int)*pnbytes == -1 && exp->X_op == O_constant)
356c353,354
< /* Don't optimize. */
---
> d->aug_size = exp->X_add_number;
> d->state = state_skipping_aug;
358,359c356
< else if (exp->X_add_number % ca == 0
< && exp->X_add_number / ca < 0x40)
---
> else if (*pnbytes == 1 && exp->X_op == O_constant)
361,364c358,362
< d->loc4_frag->fr_literal[d->loc4_fix]
< = DW_CFA_advance_loc | (exp->X_add_number / ca);
< /* No more bytes needed. */
< return 1;
---
> unsigned char byte = exp->X_add_number;
> d->aug_size |= (byte & 0x7f) << d->aug_shift;
> d->aug_shift += 7;
> if ((byte & 0x80) == 0)
> d->state = state_skipping_aug;
366c364,371
< else if (exp->X_add_number < 0x100)
---
> else
> d->state = state_error;
> break;
>
> case state_skipping_aug:
> if ((int)*pnbytes < 0)
> d->state = state_error;
> else
368,369c373,377
< d->loc4_frag->fr_literal[d->loc4_fix] = DW_CFA_advance_loc1;
< *pnbytes = 1;
---
> int left = (d->aug_size -= *pnbytes);
> if (left == 0)
> d->state = state_wait_loc4;
> else if (left < 0)
> d->state = state_error;
371c379,384
< else if (exp->X_add_number < 0x10000)
---
> break;
>
> case state_wait_loc4:
> if (*pnbytes == 1
> && exp->X_op == O_constant
> && exp->X_add_number == DW_CFA_advance_loc4)
373,374c386,391
< d->loc4_frag->fr_literal[d->loc4_fix] = DW_CFA_advance_loc2;
< *pnbytes = 2;
---
> /* This might be a DW_CFA_advance_loc4. Record the frag and the
> position within the frag, so that we can change it later. */
> frag_grow (1);
> d->state = state_saw_loc4;
> d->loc4_frag = frag_now;
> d->loc4_fix = frag_now_fix ();
376,384c393
< }
< else if (d->saw_advance_loc4
< && *pnbytes == 4
< && exp->X_op == O_subtract)
< {
< /* This is a case we can optimize. The expression was not
< reduced, so we can not finish the optimization until the end
< of the assembly. We set up a variant frag which we handle
< later. */
---
> break;
386c395,432
< d->saw_advance_loc4 = 0;
---
> case state_saw_loc4:
> d->state = state_wait_loc4;
> if (*pnbytes != 4)
> break;
> if (exp->X_op == O_constant)
> {
> /* This is a case which we can optimize. The two symbols being
> subtracted were in the same frag and the expression was
> reduced to a constant. We can do the optimization entirely
> in this function. */
> if (d->cie_info.code_alignment > 0
> && exp->X_add_number % d->cie_info.code_alignment == 0
> && exp->X_add_number / d->cie_info.code_alignment < 0x40)
> {
> d->loc4_frag->fr_literal[d->loc4_fix]
> = DW_CFA_advance_loc
> | (exp->X_add_number / d->cie_info.code_alignment);
> /* No more bytes needed. */
> return 1;
> }
> else if (exp->X_add_number < 0x100)
> {
> d->loc4_frag->fr_literal[d->loc4_fix] = DW_CFA_advance_loc1;
> *pnbytes = 1;
> }
> else if (exp->X_add_number < 0x10000)
> {
> d->loc4_frag->fr_literal[d->loc4_fix] = DW_CFA_advance_loc2;
> *pnbytes = 2;
> }
> }
> else if (exp->X_op == O_subtract)
> {
> /* This is a case we can optimize. The expression was not
> reduced, so we can not finish the optimization until the end
> of the assembly. We set up a variant frag which we handle
> later. */
> int fr_subtype;
388,389c434,437
< frag_var (rs_cfa, 4, 0, 0, make_expr_symbol (exp),
< d->loc4_fix, (char *) d->loc4_frag);
---
> if (d->cie_info.code_alignment > 0)
> fr_subtype = d->cie_info.code_alignment << 3;
> else
> fr_subtype = 0;
391c439,447
< return 1;
---
> frag_var (rs_cfa, 4, 0, fr_subtype, make_expr_symbol (exp),
> d->loc4_fix, (char *) d->loc4_frag);
> return 1;
> }
> break;
>
> case state_error:
> /* Just skipping everything. */
> break;
393,394d448
< else
< d->saw_advance_loc4 = 0;
401c455
< relaxation loop. We set fr_subtype to the expected length. */
---
> relaxation loop. We set fr_subtype{0:2} to the expected length. */
407d460
< int ca;
408a462
> int ca = frag->fr_subtype >> 3;
411d464
< ca = eh_frame_code_alignment (0);
414,416c467
< if (ca < 0)
< ret = 4;
< else if (diff % ca == 0 && diff / ca < 0x40)
---
> if (ca > 0 && diff % ca == 0 && diff / ca < 0x40)
425c476
< frag->fr_subtype = ret;
---
> frag->fr_subtype = (frag->fr_subtype & ~7) | ret;
431,432c482,483
< values of the symbols. fr_subtype is the current length of the
< frag. This returns the change in frag length. */
---
> values of the symbols. fr_subtype{0:2} is the current length of
> the frag. This returns the change in frag length. */
440c491
< oldsize = frag->fr_subtype;
---
> oldsize = frag->fr_subtype & 7;
447c498
< fr_subtype will be the desired length of the frag. */
---
> fr_subtype{0:2} will be the desired length of the frag. */
462c513
< if (frag->fr_subtype == 0)
---
> switch (frag->fr_subtype & 7)
464c515,521
< int ca;
---
> case 0:
> {
> int ca = frag->fr_subtype >> 3;
> assert (ca > 0 && diff % ca == 0 && diff / ca < 0x40);
> loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc | (diff / ca);
> }
> break;
466,471c523
< ca = eh_frame_code_alignment (0);
< assert (ca > 0 && diff % ca == 0 && diff / ca < 0x40);
< loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc | (diff / ca);
< }
< else if (frag->fr_subtype == 1)
< {
---
> case 1:
475,477c527,529
< }
< else if (frag->fr_subtype == 2)
< {
---
> break;
>
> case 2:
480a533,537
> break;
>
> default:
> md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 4);
> break;
482,483d538
< else
< md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 4);
485c540
< frag->fr_fix += frag->fr_subtype;
---
> frag->fr_fix += frag->fr_subtype & 7;
486a542
> frag->fr_subtype = 0;