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