This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
extend ehopt for .debug_frame
- To: binutils at sources dot redhat dot com
- Subject: extend ehopt for .debug_frame
- From: Richard Henderson <rth at redhat dot com>
- Date: Fri, 17 Nov 2000 16:16:23 -0800
When exception handling is disabled (ie C or C++ with -fno-exceptions),
we do not emit the .eh_frame section, but rather the standard .debug_frame.
On Irix, we never elide the .debug_frame section (since their debugger
does not look at .eh_frame), so we also try to handle both sections
concurrently.
r~
* ehopt.c (eh_frame_code_alignment): New arg `in_seg', update all
callers. Don't switch segments. Expect CIE == -1 in .debug_frame.
(check_eh_frame): Handle .eh_frame and .debug_frame concurrently.
Index: ehopt.c
===================================================================
RCS file: /cvs/src/src/gas/ehopt.c,v
retrieving revision 1.2
diff -c -p -d -r1.2 ehopt.c
*** ehopt.c 2000/09/12 03:56:22 1.2
--- ehopt.c 2000/11/18 00:11:21
*************** Software Foundation, 59 Temple Place - S
*** 31,43 ****
/* Try to optimize gcc 2.8 exception frame information.
Exception frame information is emitted for every function in the
! .eh_frame section. Simple information for a function with no
! exceptions looks like this:
__FRAME_BEGIN__:
.4byte .LLCIE1 / Length of Common Information Entry
.LSCIE1:
.4byte 0x0 / CIE Identifier Tag
.byte 0x1 / CIE Version
.byte 0x0 / CIE Augmentation (none)
.byte 0x1 / ULEB128 0x1 (CIE Code Alignment Factor)
--- 31,47 ----
/* Try to optimize gcc 2.8 exception frame information.
Exception frame information is emitted for every function in the
! .eh_frame or .debug_frame sections. Simple information for a function
! with no exceptions looks like this:
__FRAME_BEGIN__:
.4byte .LLCIE1 / Length of Common Information Entry
.LSCIE1:
+ #if .eh_frame
.4byte 0x0 / CIE Identifier Tag
+ #elif .debug_frame
+ .4byte 0xffffffff / CIE Identifier Tag
+ #endif
.byte 0x1 / CIE Version
.byte 0x0 / CIE Augmentation (none)
.byte 0x1 / ULEB128 0x1 (CIE Code Alignment Factor)
*************** __FRAME_BEGIN__:
*** 84,113 ****
not know this value, it always uses four bytes. We will know the
value at the end of assembly, so we can do better. */
! static int eh_frame_code_alignment PARAMS ((void));
/* Get the code alignment factor from the CIE. */
static int
! eh_frame_code_alignment ()
{
static int code_alignment;
! segT current_seg;
! subsegT current_subseg;
fragS *f;
fixS *fix;
int offset;
char augmentation[10];
int iaug;
if (code_alignment != 0)
return code_alignment;
! /* We should find the CIE at the start of the .eh_frame section. */
! current_seg = now_seg;
! current_subseg = now_subseg;
! subseg_new (".eh_frame", 0);
#if defined (BFD_ASSEMBLER) || defined (MANY_SEGMENTS)
f = seg_info (now_seg)->frchainP->frch_root;
#else
--- 88,120 ----
not know this value, it always uses four bytes. We will know the
value at the end of assembly, so we can do better. */
! static int eh_frame_code_alignment PARAMS ((int));
/* Get the code alignment factor from the CIE. */
static int
! eh_frame_code_alignment (in_seg)
! int in_seg;
{
+ /* ??? Assume .eh_frame and .debug_frame have the same alignment. */
static int code_alignment;
!
fragS *f;
fixS *fix;
int offset;
+ char CIE_id;
char augmentation[10];
int iaug;
if (code_alignment != 0)
return code_alignment;
! /* Can't find the alignment if we've changed sections. */
! if (! in_seg)
! return -1;
! /* We should find the CIE at the start of the section. */
!
#if defined (BFD_ASSEMBLER) || defined (MANY_SEGMENTS)
f = seg_info (now_seg)->frchainP->frch_root;
#else
*************** eh_frame_code_alignment ()
*** 118,129 ****
#else
fix = *seg_fix_rootP;
#endif
- subseg_set (current_seg, current_subseg);
/* Look through the frags of the section to find the code alignment. */
! /* First make sure that the CIE Identifier Tag is 0. */
offset = 4;
while (f != NULL && offset >= f->fr_fix)
{
--- 125,140 ----
#else
fix = *seg_fix_rootP;
#endif
/* Look through the frags of the section to find the code alignment. */
! /* First make sure that the CIE Identifier Tag is 0/-1. */
+ if (strcmp (segment_name (now_seg), ".debug_frame") == 0)
+ CIE_id = (char)0xff;
+ else
+ CIE_id = 0;
+
offset = 4;
while (f != NULL && offset >= f->fr_fix)
{
*************** eh_frame_code_alignment ()
*** 132,141 ****
}
if (f == NULL
|| f->fr_fix - offset < 4
! || f->fr_literal[offset] != 0
! || f->fr_literal[offset + 1] != 0
! || f->fr_literal[offset + 2] != 0
! || f->fr_literal[offset + 3] != 0)
{
code_alignment = -1;
return -1;
--- 143,152 ----
}
if (f == NULL
|| f->fr_fix - offset < 4
! || f->fr_literal[offset] != CIE_id
! || f->fr_literal[offset + 1] != CIE_id
! || f->fr_literal[offset + 2] != CIE_id
! || f->fr_literal[offset + 3] != CIE_id)
{
code_alignment = -1;
return -1;
*************** check_eh_frame (exp, pnbytes)
*** 261,293 ****
expressionS *exp;
unsigned int *pnbytes;
{
! static int saw_size;
! static symbolS *size_end_sym;
! static int saw_advance_loc4;
! static fragS *loc4_frag;
! static int loc4_fix;
! if (saw_size
! && S_IS_DEFINED (size_end_sym))
{
/* We have come to the end of the CIE or FDE. See below where
we set saw_size. We must check this first because we may now
be looking at the next size. */
! saw_size = 0;
! saw_advance_loc4 = 0;
}
! if (flag_traditional_format)
! {
! /* Don't optimize. */
! }
! else if (strcmp (segment_name (now_seg), ".eh_frame") != 0)
! {
! saw_size = 0;
! saw_advance_loc4 = 0;
! }
! else if (! saw_size
! && *pnbytes == 4)
{
/* 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
--- 272,313 ----
expressionS *exp;
unsigned int *pnbytes;
{
! struct frame_data
! {
! symbolS *size_end_sym;
! fragS *loc4_frag;
! int saw_size;
! int saw_advance_loc4;
! int loc4_fix;
! };
!
! static struct frame_data eh_frame_data;
! static struct frame_data debug_frame_data;
! struct frame_data *d;
! /* Don't optimize. */
! if (flag_traditional_format)
! return 0;
!
! /* Select the proper section data. */
! if (strcmp (segment_name (now_seg), ".eh_frame") == 0)
! d = &eh_frame_data;
! else if (strcmp (segment_name (now_seg), ".debug_frame") == 0)
! d = &debug_frame_data;
! else
! return 0;
!
! if (d->saw_size && S_IS_DEFINED (d->size_end_sym))
{
/* We have come to the end of the CIE or FDE. See below where
we set saw_size. We must check this first because we may now
be looking at the next size. */
! d->saw_size = 0;
! d->saw_advance_loc4 = 0;
}
! if (! d->saw_size
! && *pnbytes == 4)
{
/* 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
*************** check_eh_frame (exp, pnbytes)
*** 301,323 ****
if ((exp->X_op == O_symbol || exp->X_op == O_subtract)
&& ! S_IS_DEFINED (exp->X_add_symbol))
{
! saw_size = 1;
! size_end_sym = exp->X_add_symbol;
}
}
! else if (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. */
! saw_advance_loc4 = 1;
frag_grow (1);
! loc4_frag = frag_now;
! loc4_fix = frag_now_fix ();
}
! else if (saw_advance_loc4
&& *pnbytes == 4
&& exp->X_op == O_constant)
{
--- 321,343 ----
if ((exp->X_op == O_symbol || exp->X_op == O_subtract)
&& ! S_IS_DEFINED (exp->X_add_symbol))
{
! d->saw_size = 1;
! d->size_end_sym = exp->X_add_symbol;
}
}
! 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)
{
*************** check_eh_frame (exp, pnbytes)
*** 328,336 ****
reduced to a constant. We can do the optimization entirely
in this function. */
! saw_advance_loc4 = 0;
! ca = eh_frame_code_alignment ();
if (ca < 0)
{
/* Don't optimize. */
--- 348,356 ----
reduced to a constant. We can do the optimization entirely
in this function. */
! d->saw_advance_loc4 = 0;
! ca = eh_frame_code_alignment (1);
if (ca < 0)
{
/* Don't optimize. */
*************** check_eh_frame (exp, pnbytes)
*** 338,378 ****
else if (exp->X_add_number % ca == 0
&& exp->X_add_number / ca < 0x40)
{
! loc4_frag->fr_literal[loc4_fix]
= DW_CFA_advance_loc | (exp->X_add_number / ca);
/* No more bytes needed. */
return 1;
}
else if (exp->X_add_number < 0x100)
{
! loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc1;
*pnbytes = 1;
}
else if (exp->X_add_number < 0x10000)
{
! loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc2;
*pnbytes = 2;
}
}
! else if (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. */
! saw_advance_loc4 = 0;
frag_var (rs_cfa, 4, 0, 0, make_expr_symbol (exp),
! loc4_fix, (char *) loc4_frag);
return 1;
}
else
! saw_advance_loc4 = 0;
return 0;
}
--- 358,397 ----
else if (exp->X_add_number % ca == 0
&& exp->X_add_number / ca < 0x40)
{
! d->loc4_frag->fr_literal[d->loc4_fix]
= DW_CFA_advance_loc | (exp->X_add_number / ca);
/* 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 (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. */
! d->saw_advance_loc4 = 0;
frag_var (rs_cfa, 4, 0, 0, make_expr_symbol (exp),
! d->loc4_fix, (char *) d->loc4_frag);
return 1;
}
else
! d->saw_advance_loc4 = 0;
return 0;
}
*************** eh_frame_estimate_size_before_relax (fra
*** 389,395 ****
offsetT diff;
int ret;
! ca = eh_frame_code_alignment ();
diff = resolve_symbol_value (frag->fr_symbol, 0);
if (ca < 0)
--- 408,414 ----
offsetT diff;
int ret;
! ca = eh_frame_code_alignment (0);
diff = resolve_symbol_value (frag->fr_symbol, 0);
if (ca < 0)
*************** eh_frame_convert_frag (frag)
*** 444,450 ****
{
int ca;
! ca = eh_frame_code_alignment ();
assert (ca > 0 && diff % ca == 0 && diff / ca < 0x40);
loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc | (diff / ca);
}
--- 463,469 ----
{
int ca;
! 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);
}