OSDN Git Service

r6916@monacintosh2: monaka | 2008-11-24 19:18:29 +0900
[pf3gnuchains/pf3gnuchains3x.git] / gas / ehopt.c
1 /* ehopt.c--optimize gcc exception frame information.
2    Copyright 1998, 2000, 2001, 2003, 2005, 2007 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA
20    02110-1301, 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 struct cie_info
92 {
93   unsigned code_alignment;
94   int z_augmentation;
95 };
96
97 static int get_cie_info (struct cie_info *);
98
99 /* Extract information from the CIE.  */
100
101 static int
102 get_cie_info (struct cie_info *info)
103 {
104   fragS *f;
105   fixS *fix;
106   int offset;
107   char CIE_id;
108   char augmentation[10];
109   int iaug;
110   int code_alignment = 0;
111
112   /* We should find the CIE at the start of the section.  */
113
114   f = seg_info (now_seg)->frchainP->frch_root;
115   fix = seg_info (now_seg)->frchainP->fix_root;
116
117   /* Look through the frags of the section to find the code alignment.  */
118
119   /* First make sure that the CIE Identifier Tag is 0/-1.  */
120
121   if (strcmp (segment_name (now_seg), ".debug_frame") == 0)
122     CIE_id = (char)0xff;
123   else
124     CIE_id = 0;
125
126   offset = 4;
127   while (f != NULL && offset >= f->fr_fix)
128     {
129       offset -= f->fr_fix;
130       f = f->fr_next;
131     }
132   if (f == NULL
133       || f->fr_fix - offset < 4
134       || f->fr_literal[offset] != CIE_id
135       || f->fr_literal[offset + 1] != CIE_id
136       || f->fr_literal[offset + 2] != CIE_id
137       || f->fr_literal[offset + 3] != CIE_id)
138     return 0;
139
140   /* Next make sure the CIE version number is 1.  */
141
142   offset += 4;
143   while (f != NULL && offset >= f->fr_fix)
144     {
145       offset -= f->fr_fix;
146       f = f->fr_next;
147     }
148   if (f == NULL
149       || f->fr_fix - offset < 1
150       || f->fr_literal[offset] != 1)
151     return 0;
152
153   /* Skip the augmentation (a null terminated string).  */
154
155   iaug = 0;
156   ++offset;
157   while (1)
158     {
159       while (f != NULL && offset >= f->fr_fix)
160         {
161           offset -= f->fr_fix;
162           f = f->fr_next;
163         }
164       if (f == NULL)
165         return 0;
166
167       while (offset < f->fr_fix && f->fr_literal[offset] != '\0')
168         {
169           if ((size_t) iaug < (sizeof augmentation) - 1)
170             {
171               augmentation[iaug] = f->fr_literal[offset];
172               ++iaug;
173             }
174           ++offset;
175         }
176       if (offset < f->fr_fix)
177         break;
178     }
179   ++offset;
180   while (f != NULL && offset >= f->fr_fix)
181     {
182       offset -= f->fr_fix;
183       f = f->fr_next;
184     }
185   if (f == NULL)
186     return 0;
187
188   augmentation[iaug] = '\0';
189   if (augmentation[0] == '\0')
190     {
191       /* No augmentation.  */
192     }
193   else if (strcmp (augmentation, "eh") == 0)
194     {
195       /* We have to skip a pointer.  Unfortunately, we don't know how
196          large it is.  We find out by looking for a matching fixup.  */
197       while (fix != NULL
198              && (fix->fx_frag != f || fix->fx_where != offset))
199         fix = fix->fx_next;
200       if (fix == NULL)
201         offset += 4;
202       else
203         offset += fix->fx_size;
204       while (f != NULL && offset >= f->fr_fix)
205         {
206           offset -= f->fr_fix;
207           f = f->fr_next;
208         }
209       if (f == NULL)
210         return 0;
211     }
212   else if (augmentation[0] != 'z')
213     return 0;
214
215   /* We're now at the code alignment factor, which is a ULEB128.  If
216      it isn't a single byte, forget it.  */
217
218   code_alignment = f->fr_literal[offset] & 0xff;
219   if ((code_alignment & 0x80) != 0)
220     code_alignment = 0;
221
222   info->code_alignment = code_alignment;
223   info->z_augmentation = (augmentation[0] == 'z');
224
225   return 1;
226 }
227
228 /* This function is called from emit_expr.  It looks for cases which
229    we can optimize.
230
231    Rather than try to parse all this information as we read it, we
232    look for a single byte DW_CFA_advance_loc4 followed by a 4 byte
233    difference.  We turn that into a rs_cfa_advance frag, and handle
234    those frags at the end of the assembly.  If the gcc output changes
235    somewhat, this optimization may stop working.
236
237    This function returns non-zero if it handled the expression and
238    emit_expr should not do anything, or zero otherwise.  It can also
239    change *EXP and *PNBYTES.  */
240
241 int
242 check_eh_frame (expressionS *exp, unsigned int *pnbytes)
243 {
244   struct frame_data
245   {
246     enum frame_state
247     {
248       state_idle,
249       state_saw_size,
250       state_saw_cie_offset,
251       state_saw_pc_begin,
252       state_seeing_aug_size,
253       state_skipping_aug,
254       state_wait_loc4,
255       state_saw_loc4,
256       state_error,
257     } state;
258
259     int cie_info_ok;
260     struct cie_info cie_info;
261
262     symbolS *size_end_sym;
263     fragS *loc4_frag;
264     int loc4_fix;
265
266     int aug_size;
267     int aug_shift;
268   };
269
270   static struct frame_data eh_frame_data;
271   static struct frame_data debug_frame_data;
272   struct frame_data *d;
273
274   /* Don't optimize.  */
275   if (flag_traditional_format)
276     return 0;
277
278 #ifdef md_allow_eh_opt
279   if (! md_allow_eh_opt)
280     return 0;
281 #endif
282
283   /* Select the proper section data.  */
284   if (strcmp (segment_name (now_seg), ".eh_frame") == 0)
285     d = &eh_frame_data;
286   else if (strcmp (segment_name (now_seg), ".debug_frame") == 0)
287     d = &debug_frame_data;
288   else
289     return 0;
290
291   if (d->state >= state_saw_size && S_IS_DEFINED (d->size_end_sym))
292     {
293       /* We have come to the end of the CIE or FDE.  See below where
294          we set saw_size.  We must check this first because we may now
295          be looking at the next size.  */
296       d->state = state_idle;
297     }
298
299   switch (d->state)
300     {
301     case state_idle:
302       if (*pnbytes == 4)
303         {
304           /* This might be the size of the CIE or FDE.  We want to know
305              the size so that we don't accidentally optimize across an FDE
306              boundary.  We recognize the size in one of two forms: a
307              symbol which will later be defined as a difference, or a
308              subtraction of two symbols.  Either way, we can tell when we
309              are at the end of the FDE because the symbol becomes defined
310              (in the case of a subtraction, the end symbol, from which the
311              start symbol is being subtracted).  Other ways of describing
312              the size will not be optimized.  */
313           if ((exp->X_op == O_symbol || exp->X_op == O_subtract)
314               && ! S_IS_DEFINED (exp->X_add_symbol))
315             {
316               d->state = state_saw_size;
317               d->size_end_sym = exp->X_add_symbol;
318             }
319         }
320       break;
321
322     case state_saw_size:
323     case state_saw_cie_offset:
324       /* Assume whatever form it appears in, it appears atomically.  */
325       d->state += 1;
326       break;
327
328     case state_saw_pc_begin:
329       /* Decide whether we should see an augmentation.  */
330       if (! d->cie_info_ok
331           && ! (d->cie_info_ok = get_cie_info (&d->cie_info)))
332         d->state = state_error;
333       else if (d->cie_info.z_augmentation)
334         {
335           d->state = state_seeing_aug_size;
336           d->aug_size = 0;
337           d->aug_shift = 0;
338         }
339       else
340         d->state = state_wait_loc4;
341       break;
342
343     case state_seeing_aug_size:
344       /* Bytes == -1 means this comes from an leb128 directive.  */
345       if ((int)*pnbytes == -1 && exp->X_op == O_constant)
346         {
347           d->aug_size = exp->X_add_number;
348           d->state = state_skipping_aug;
349         }
350       else if (*pnbytes == 1 && exp->X_op == O_constant)
351         {
352           unsigned char byte = exp->X_add_number;
353           d->aug_size |= (byte & 0x7f) << d->aug_shift;
354           d->aug_shift += 7;
355           if ((byte & 0x80) == 0)
356             d->state = state_skipping_aug;
357         }
358       else
359         d->state = state_error;
360       if (d->state == state_skipping_aug && d->aug_size == 0)
361         d->state = state_wait_loc4;
362       break;
363
364     case state_skipping_aug:
365       if ((int)*pnbytes < 0)
366         d->state = state_error;
367       else
368         {
369           int left = (d->aug_size -= *pnbytes);
370           if (left == 0)
371             d->state = state_wait_loc4;
372           else if (left < 0)
373             d->state = state_error;
374         }
375       break;
376
377     case state_wait_loc4:
378       if (*pnbytes == 1
379           && exp->X_op == O_constant
380           && exp->X_add_number == DW_CFA_advance_loc4)
381         {
382           /* This might be a DW_CFA_advance_loc4.  Record the frag and the
383              position within the frag, so that we can change it later.  */
384           frag_grow (1);
385           d->state = state_saw_loc4;
386           d->loc4_frag = frag_now;
387           d->loc4_fix = frag_now_fix ();
388         }
389       break;
390
391     case state_saw_loc4:
392       d->state = state_wait_loc4;
393       if (*pnbytes != 4)
394         break;
395       if (exp->X_op == O_constant)
396         {
397           /* This is a case which we can optimize.  The two symbols being
398              subtracted were in the same frag and the expression was
399              reduced to a constant.  We can do the optimization entirely
400              in this function.  */
401           if (d->cie_info.code_alignment > 0
402               && exp->X_add_number % d->cie_info.code_alignment == 0
403               && exp->X_add_number / d->cie_info.code_alignment < 0x40)
404             {
405               d->loc4_frag->fr_literal[d->loc4_fix]
406                 = DW_CFA_advance_loc
407                   | (exp->X_add_number / d->cie_info.code_alignment);
408               /* No more bytes needed.  */
409               return 1;
410             }
411           else if (exp->X_add_number < 0x100)
412             {
413               d->loc4_frag->fr_literal[d->loc4_fix] = DW_CFA_advance_loc1;
414               *pnbytes = 1;
415             }
416           else if (exp->X_add_number < 0x10000)
417             {
418               d->loc4_frag->fr_literal[d->loc4_fix] = DW_CFA_advance_loc2;
419               *pnbytes = 2;
420             }
421         }
422       else if (exp->X_op == O_subtract)
423         {
424           /* This is a case we can optimize.  The expression was not
425              reduced, so we can not finish the optimization until the end
426              of the assembly.  We set up a variant frag which we handle
427              later.  */
428           int fr_subtype;
429
430           if (d->cie_info.code_alignment > 0)
431             fr_subtype = d->cie_info.code_alignment << 3;
432           else
433             fr_subtype = 0;
434
435           frag_var (rs_cfa, 4, 0, fr_subtype, make_expr_symbol (exp),
436                     d->loc4_fix, (char *) d->loc4_frag);
437           return 1;
438         }
439       break;
440
441     case state_error:
442       /* Just skipping everything.  */
443       break;
444     }
445
446   return 0;
447 }
448
449 /* The function estimates the size of a rs_cfa variant frag based on
450    the current values of the symbols.  It is called before the
451    relaxation loop.  We set fr_subtype{0:2} to the expected length.  */
452
453 int
454 eh_frame_estimate_size_before_relax (fragS *frag)
455 {
456   offsetT diff;
457   int ca = frag->fr_subtype >> 3;
458   int ret;
459
460   diff = resolve_symbol_value (frag->fr_symbol);
461
462   if (ca > 0 && diff % ca == 0 && diff / ca < 0x40)
463     ret = 0;
464   else if (diff < 0x100)
465     ret = 1;
466   else if (diff < 0x10000)
467     ret = 2;
468   else
469     ret = 4;
470
471   frag->fr_subtype = (frag->fr_subtype & ~7) | ret;
472
473   return ret;
474 }
475
476 /* This function relaxes a rs_cfa variant frag based on the current
477    values of the symbols.  fr_subtype{0:2} is the current length of
478    the frag.  This returns the change in frag length.  */
479
480 int
481 eh_frame_relax_frag (fragS *frag)
482 {
483   int oldsize, newsize;
484
485   oldsize = frag->fr_subtype & 7;
486   newsize = eh_frame_estimate_size_before_relax (frag);
487   return newsize - oldsize;
488 }
489
490 /* This function converts a rs_cfa variant frag into a normal fill
491    frag.  This is called after all relaxation has been done.
492    fr_subtype{0:2} will be the desired length of the frag.  */
493
494 void
495 eh_frame_convert_frag (fragS *frag)
496 {
497   offsetT diff;
498   fragS *loc4_frag;
499   int loc4_fix;
500
501   loc4_frag = (fragS *) frag->fr_opcode;
502   loc4_fix = (int) frag->fr_offset;
503
504   diff = resolve_symbol_value (frag->fr_symbol);
505
506   switch (frag->fr_subtype & 7)
507     {
508     case 0:
509       {
510         int ca = frag->fr_subtype >> 3;
511         assert (ca > 0 && diff % ca == 0 && diff / ca < 0x40);
512         loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc | (diff / ca);
513       }
514       break;
515
516     case 1:
517       assert (diff < 0x100);
518       loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc1;
519       frag->fr_literal[frag->fr_fix] = diff;
520       break;
521
522     case 2:
523       assert (diff < 0x10000);
524       loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc2;
525       md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 2);
526       break;
527
528     default:
529       md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 4);
530       break;
531     }
532
533   frag->fr_fix += frag->fr_subtype & 7;
534   frag->fr_type = rs_fill;
535   frag->fr_subtype = 0;
536   frag->fr_offset = 0;
537 }