OSDN Git Service

* ehopt.c (eh_frame_code_alignment): New arg `in_seg', update all
[pf3gnuchains/pf3gnuchains3x.git] / gas / ehopt.c
1 /* ehopt.c--optimize gcc exception frame information.
2    Copyright (C) 1998, 2000 Free Software Foundation, Inc.
3    Written by Ian Lance Taylor <ian@cygnus.com>.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #include "as.h"
23 #include "subsegs.h"
24
25 /* We include this ELF file, even though we may not be assembling for
26    ELF, since the exception frame information is always in a format
27    derived from DWARF.  */
28
29 #include "elf/dwarf2.h"
30
31 /* Try to optimize gcc 2.8 exception frame information.
32
33    Exception frame information is emitted for every function in the
34    .eh_frame or .debug_frame sections.  Simple information for a function
35    with no exceptions looks like this:
36
37 __FRAME_BEGIN__:
38         .4byte  .LLCIE1 / Length of Common Information Entry
39 .LSCIE1:
40 #if .eh_frame
41         .4byte  0x0     / CIE Identifier Tag
42 #elif .debug_frame
43         .4byte  0xffffffff / CIE Identifier Tag
44 #endif
45         .byte   0x1     / CIE Version
46         .byte   0x0     / CIE Augmentation (none)
47         .byte   0x1     / ULEB128 0x1 (CIE Code Alignment Factor)
48         .byte   0x7c    / SLEB128 -4 (CIE Data Alignment Factor)
49         .byte   0x8     / CIE RA Column
50         .byte   0xc     / DW_CFA_def_cfa
51         .byte   0x4     / ULEB128 0x4
52         .byte   0x4     / ULEB128 0x4
53         .byte   0x88    / DW_CFA_offset, column 0x8
54         .byte   0x1     / ULEB128 0x1
55         .align 4
56 .LECIE1:
57         .set    .LLCIE1,.LECIE1-.LSCIE1 / CIE Length Symbol
58         .4byte  .LLFDE1 / FDE Length
59 .LSFDE1:
60         .4byte  .LSFDE1-__FRAME_BEGIN__ / FDE CIE offset
61         .4byte  .LFB1   / FDE initial location
62         .4byte  .LFE1-.LFB1     / FDE address range
63         .byte   0x4     / DW_CFA_advance_loc4
64         .4byte  .LCFI0-.LFB1
65         .byte   0xe     / DW_CFA_def_cfa_offset
66         .byte   0x8     / ULEB128 0x8
67         .byte   0x85    / DW_CFA_offset, column 0x5
68         .byte   0x2     / ULEB128 0x2
69         .byte   0x4     / DW_CFA_advance_loc4
70         .4byte  .LCFI1-.LCFI0
71         .byte   0xd     / DW_CFA_def_cfa_register
72         .byte   0x5     / ULEB128 0x5
73         .byte   0x4     / DW_CFA_advance_loc4
74         .4byte  .LCFI2-.LCFI1
75         .byte   0x2e    / DW_CFA_GNU_args_size
76         .byte   0x4     / ULEB128 0x4
77         .byte   0x4     / DW_CFA_advance_loc4
78         .4byte  .LCFI3-.LCFI2
79         .byte   0x2e    / DW_CFA_GNU_args_size
80         .byte   0x0     / ULEB128 0x0
81         .align 4
82 .LEFDE1:
83         .set    .LLFDE1,.LEFDE1-.LSFDE1 / FDE Length Symbol
84
85    The immediate issue we can address in the assembler is the
86    DW_CFA_advance_loc4 followed by a four byte value.  The value is
87    the difference of two addresses in the function.  Since gcc does
88    not know this value, it always uses four bytes.  We will know the
89    value at the end of assembly, so we can do better.  */
90
91 static int eh_frame_code_alignment PARAMS ((int));
92
93 /* Get the code alignment factor from the CIE.  */
94
95 static int
96 eh_frame_code_alignment (in_seg)
97      int in_seg;
98 {
99   /* ??? Assume .eh_frame and .debug_frame have the same alignment.  */
100   static int code_alignment;
101
102   fragS *f;
103   fixS *fix;
104   int offset;
105   char CIE_id;
106   char augmentation[10];
107   int iaug;
108
109   if (code_alignment != 0)
110     return code_alignment;
111
112   /* Can't find the alignment if we've changed sections.  */
113   if (! in_seg)
114     return -1;
115
116   /* We should find the CIE at the start of the section.  */
117
118 #if defined (BFD_ASSEMBLER) || defined (MANY_SEGMENTS)
119   f = seg_info (now_seg)->frchainP->frch_root;
120 #else
121   f = frchain_now->frch_root;
122 #endif
123 #ifdef BFD_ASSEMBLER
124   fix = seg_info (now_seg)->frchainP->fix_root;
125 #else
126   fix = *seg_fix_rootP;
127 #endif
128
129   /* Look through the frags of the section to find the code alignment.  */
130
131   /* First make sure that the CIE Identifier Tag is 0/-1.  */
132
133   if (strcmp (segment_name (now_seg), ".debug_frame") == 0)
134     CIE_id = (char)0xff;
135   else
136     CIE_id = 0;
137
138   offset = 4;
139   while (f != NULL && offset >= f->fr_fix)
140     {
141       offset -= f->fr_fix;
142       f = f->fr_next;
143     }
144   if (f == NULL
145       || f->fr_fix - offset < 4
146       || f->fr_literal[offset] != CIE_id
147       || f->fr_literal[offset + 1] != CIE_id
148       || f->fr_literal[offset + 2] != CIE_id
149       || f->fr_literal[offset + 3] != CIE_id)
150     {
151       code_alignment = -1;
152       return -1;
153     }
154
155   /* Next make sure the CIE version number is 1.  */
156
157   offset += 4;
158   while (f != NULL && offset >= f->fr_fix)
159     {
160       offset -= f->fr_fix;
161       f = f->fr_next;
162     }
163   if (f == NULL
164       || f->fr_fix - offset < 1
165       || f->fr_literal[offset] != 1)
166     {
167       code_alignment = -1;
168       return -1;
169     }
170
171   /* Skip the augmentation (a null terminated string).  */
172
173   iaug = 0;
174   ++offset;
175   while (1)
176     {
177       while (f != NULL && offset >= f->fr_fix)
178         {
179           offset -= f->fr_fix;
180           f = f->fr_next;
181         }
182       if (f == NULL)
183         {
184           code_alignment = -1;
185           return -1;
186         }
187       while (offset < f->fr_fix && f->fr_literal[offset] != '\0')
188         {
189           if ((size_t) iaug < (sizeof augmentation) - 1)
190             {
191               augmentation[iaug] = f->fr_literal[offset];
192               ++iaug;
193             }
194           ++offset;
195         }
196       if (offset < f->fr_fix)
197         break;
198     }
199   ++offset;
200   while (f != NULL && offset >= f->fr_fix)
201     {
202       offset -= f->fr_fix;
203       f = f->fr_next;
204     }
205   if (f == NULL)
206     {
207       code_alignment = -1;
208       return -1;
209     }
210
211   augmentation[iaug] = '\0';
212   if (augmentation[0] == '\0')
213     {
214       /* No augmentation.  */
215     }
216   else if (strcmp (augmentation, "eh") == 0)
217     {
218       /* We have to skip a pointer.  Unfortunately, we don't know how
219          large it is.  We find out by looking for a matching fixup.  */
220       while (fix != NULL
221              && (fix->fx_frag != f || fix->fx_where != offset))
222         fix = fix->fx_next;
223       if (fix == NULL)
224         offset += 4;
225       else
226         offset += fix->fx_size;
227       while (f != NULL && offset >= f->fr_fix)
228         {
229           offset -= f->fr_fix;
230           f = f->fr_next;
231         }
232       if (f == NULL)
233         {
234           code_alignment = -1;
235           return -1;
236         }
237     }
238   else
239     {
240       code_alignment = -1;
241       return -1;
242     }
243
244   /* We're now at the code alignment factor, which is a ULEB128.  If
245      it isn't a single byte, forget it.  */
246
247   code_alignment = f->fr_literal[offset] & 0xff;
248   if ((code_alignment & 0x80) != 0 || code_alignment == 0)
249     {
250       code_alignment = -1;
251       return -1;
252     }
253
254   return code_alignment;
255 }
256
257 /* This function is called from emit_expr.  It looks for cases which
258    we can optimize.
259
260    Rather than try to parse all this information as we read it, we
261    look for a single byte DW_CFA_advance_loc4 followed by a 4 byte
262    difference.  We turn that into a rs_cfa_advance frag, and handle
263    those frags at the end of the assembly.  If the gcc output changes
264    somewhat, this optimization may stop working.
265
266    This function returns non-zero if it handled the expression and
267    emit_expr should not do anything, or zero otherwise.  It can also
268    change *EXP and *PNBYTES.  */
269
270 int
271 check_eh_frame (exp, pnbytes)
272      expressionS *exp;
273      unsigned int *pnbytes;
274 {
275   struct frame_data
276   {
277     symbolS *size_end_sym;
278     fragS *loc4_frag;
279     int saw_size;
280     int saw_advance_loc4;
281     int loc4_fix;
282   };
283   
284   static struct frame_data eh_frame_data;
285   static struct frame_data debug_frame_data;
286   struct frame_data *d;
287
288   /* Don't optimize.  */
289   if (flag_traditional_format)
290     return 0;
291
292   /* Select the proper section data.  */
293   if (strcmp (segment_name (now_seg), ".eh_frame") == 0)
294     d = &eh_frame_data;
295   else if (strcmp (segment_name (now_seg), ".debug_frame") == 0)
296     d = &debug_frame_data;
297   else
298     return 0;
299
300   if (d->saw_size && S_IS_DEFINED (d->size_end_sym))
301     {
302       /* We have come to the end of the CIE or FDE.  See below where
303          we set saw_size.  We must check this first because we may now
304          be looking at the next size.  */
305       d->saw_size = 0;
306       d->saw_advance_loc4 = 0;
307     }
308
309   if (! d->saw_size
310       && *pnbytes == 4)
311     {
312       /* This might be the size of the CIE or FDE.  We want to know
313          the size so that we don't accidentally optimize across an FDE
314          boundary.  We recognize the size in one of two forms: a
315          symbol which will later be defined as a difference, or a
316          subtraction of two symbols.  Either way, we can tell when we
317          are at the end of the FDE because the symbol becomes defined
318          (in the case of a subtraction, the end symbol, from which the
319          start symbol is being subtracted).  Other ways of describing
320          the size will not be optimized.  */
321       if ((exp->X_op == O_symbol || exp->X_op == O_subtract)
322           && ! S_IS_DEFINED (exp->X_add_symbol))
323         {
324           d->saw_size = 1;
325           d->size_end_sym = exp->X_add_symbol;
326         }
327     }
328   else if (d->saw_size
329            && *pnbytes == 1
330            && exp->X_op == O_constant
331            && exp->X_add_number == DW_CFA_advance_loc4)
332     {
333       /* This might be a DW_CFA_advance_loc4.  Record the frag and the
334          position within the frag, so that we can change it later.  */
335       d->saw_advance_loc4 = 1;
336       frag_grow (1);
337       d->loc4_frag = frag_now;
338       d->loc4_fix = frag_now_fix ();
339     }
340   else if (d->saw_advance_loc4
341            && *pnbytes == 4
342            && exp->X_op == O_constant)
343     {
344       int ca;
345
346       /* This is a case which we can optimize.  The two symbols being
347          subtracted were in the same frag and the expression was
348          reduced to a constant.  We can do the optimization entirely
349          in this function.  */
350
351       d->saw_advance_loc4 = 0;
352
353       ca = eh_frame_code_alignment (1);
354       if (ca < 0)
355         {
356           /* Don't optimize.  */
357         }
358       else if (exp->X_add_number % ca == 0
359                && exp->X_add_number / ca < 0x40)
360         {
361           d->loc4_frag->fr_literal[d->loc4_fix]
362             = DW_CFA_advance_loc | (exp->X_add_number / ca);
363           /* No more bytes needed.  */
364           return 1;
365         }
366       else if (exp->X_add_number < 0x100)
367         {
368           d->loc4_frag->fr_literal[d->loc4_fix] = DW_CFA_advance_loc1;
369           *pnbytes = 1;
370         }
371       else if (exp->X_add_number < 0x10000)
372         {
373           d->loc4_frag->fr_literal[d->loc4_fix] = DW_CFA_advance_loc2;
374           *pnbytes = 2;
375         }
376     }
377   else if (d->saw_advance_loc4
378            && *pnbytes == 4
379            && exp->X_op == O_subtract)
380     {
381       /* This is a case we can optimize.  The expression was not
382          reduced, so we can not finish the optimization until the end
383          of the assembly.  We set up a variant frag which we handle
384          later.  */
385
386       d->saw_advance_loc4 = 0;
387
388       frag_var (rs_cfa, 4, 0, 0, make_expr_symbol (exp),
389                 d->loc4_fix, (char *) d->loc4_frag);
390
391       return 1;
392     }
393   else
394     d->saw_advance_loc4 = 0;
395
396   return 0;
397 }
398
399 /* The function estimates the size of a rs_cfa variant frag based on
400    the current values of the symbols.  It is called before the
401    relaxation loop.  We set fr_subtype to the expected length.  */
402
403 int
404 eh_frame_estimate_size_before_relax (frag)
405      fragS *frag;
406 {
407   int ca;
408   offsetT diff;
409   int ret;
410
411   ca = eh_frame_code_alignment (0);
412   diff = resolve_symbol_value (frag->fr_symbol, 0);
413
414   if (ca < 0)
415     ret = 4;
416   else if (diff % ca == 0 && diff / ca < 0x40)
417     ret = 0;
418   else if (diff < 0x100)
419     ret = 1;
420   else if (diff < 0x10000)
421     ret = 2;
422   else
423     ret = 4;
424
425   frag->fr_subtype = ret;
426
427   return ret;
428 }
429
430 /* This function relaxes a rs_cfa variant frag based on the current
431    values of the symbols.  fr_subtype is the current length of the
432    frag.  This returns the change in frag length.  */
433
434 int
435 eh_frame_relax_frag (frag)
436      fragS *frag;
437 {
438   int oldsize, newsize;
439
440   oldsize = frag->fr_subtype;
441   newsize = eh_frame_estimate_size_before_relax (frag);
442   return newsize - oldsize;
443 }
444
445 /* This function converts a rs_cfa variant frag into a normal fill
446    frag.  This is called after all relaxation has been done.
447    fr_subtype will be the desired length of the frag.  */
448
449 void
450 eh_frame_convert_frag (frag)
451      fragS *frag;
452 {
453   offsetT diff;
454   fragS *loc4_frag;
455   int loc4_fix;
456
457   loc4_frag = (fragS *) frag->fr_opcode;
458   loc4_fix = (int) frag->fr_offset;
459
460   diff = resolve_symbol_value (frag->fr_symbol, 1);
461
462   if (frag->fr_subtype == 0)
463     {
464       int ca;
465
466       ca = eh_frame_code_alignment (0);
467       assert (ca > 0 && diff % ca == 0 && diff / ca < 0x40);
468       loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc | (diff / ca);
469     }
470   else if (frag->fr_subtype == 1)
471     {
472       assert (diff < 0x100);
473       loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc1;
474       frag->fr_literal[frag->fr_fix] = diff;
475     }
476   else if (frag->fr_subtype == 2)
477     {
478       assert (diff < 0x10000);
479       loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc2;
480       md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 2);
481     }
482   else
483     md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 4);
484
485   frag->fr_fix += frag->fr_subtype;
486   frag->fr_type = rs_fill;
487   frag->fr_offset = 0;
488 }