1/* ehopt.c--optimize gcc exception frame information.
2   Copyright 1998, 2000, 2001, 2003, 2005 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, 51 Franklin Street - Fifth Floor, Boston, MA
2002110-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
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  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
241int
242check_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  /* Select the proper section data.  */
279  if (strcmp (segment_name (now_seg), ".eh_frame") == 0)
280    d = &eh_frame_data;
281  else if (strcmp (segment_name (now_seg), ".debug_frame") == 0)
282    d = &debug_frame_data;
283  else
284    return 0;
285
286  if (d->state >= state_saw_size && S_IS_DEFINED (d->size_end_sym))
287    {
288      /* We have come to the end of the CIE or FDE.  See below where
289         we set saw_size.  We must check this first because we may now
290         be looking at the next size.  */
291      d->state = state_idle;
292    }
293
294  switch (d->state)
295    {
296    case state_idle:
297      if (*pnbytes == 4)
298	{
299	  /* This might be the size of the CIE or FDE.  We want to know
300	     the size so that we don't accidentally optimize across an FDE
301	     boundary.  We recognize the size in one of two forms: a
302	     symbol which will later be defined as a difference, or a
303	     subtraction of two symbols.  Either way, we can tell when we
304	     are at the end of the FDE because the symbol becomes defined
305	     (in the case of a subtraction, the end symbol, from which the
306	     start symbol is being subtracted).  Other ways of describing
307	     the size will not be optimized.  */
308	  if ((exp->X_op == O_symbol || exp->X_op == O_subtract)
309	      && ! S_IS_DEFINED (exp->X_add_symbol))
310	    {
311	      d->state = state_saw_size;
312	      d->size_end_sym = exp->X_add_symbol;
313	    }
314	}
315      break;
316
317    case state_saw_size:
318    case state_saw_cie_offset:
319      /* Assume whatever form it appears in, it appears atomically.  */
320      d->state += 1;
321      break;
322
323    case state_saw_pc_begin:
324      /* Decide whether we should see an augmentation.  */
325      if (! d->cie_info_ok
326	  && ! (d->cie_info_ok = get_cie_info (&d->cie_info)))
327	d->state = state_error;
328      else if (d->cie_info.z_augmentation)
329	{
330	  d->state = state_seeing_aug_size;
331	  d->aug_size = 0;
332	  d->aug_shift = 0;
333	}
334      else
335	d->state = state_wait_loc4;
336      break;
337
338    case state_seeing_aug_size:
339      /* Bytes == -1 means this comes from an leb128 directive.  */
340      if ((int)*pnbytes == -1 && exp->X_op == O_constant)
341	{
342	  d->aug_size = exp->X_add_number;
343	  d->state = state_skipping_aug;
344	}
345      else if (*pnbytes == 1 && exp->X_op == O_constant)
346	{
347	  unsigned char byte = exp->X_add_number;
348	  d->aug_size |= (byte & 0x7f) << d->aug_shift;
349	  d->aug_shift += 7;
350	  if ((byte & 0x80) == 0)
351	    d->state = state_skipping_aug;
352	}
353      else
354	d->state = state_error;
355      if (d->state == state_skipping_aug && d->aug_size == 0)
356	d->state = state_wait_loc4;
357      break;
358
359    case state_skipping_aug:
360      if ((int)*pnbytes < 0)
361	d->state = state_error;
362      else
363	{
364	  int left = (d->aug_size -= *pnbytes);
365	  if (left == 0)
366	    d->state = state_wait_loc4;
367	  else if (left < 0)
368	    d->state = state_error;
369	}
370      break;
371
372    case state_wait_loc4:
373      if (*pnbytes == 1
374	  && exp->X_op == O_constant
375	  && exp->X_add_number == DW_CFA_advance_loc4)
376	{
377	  /* This might be a DW_CFA_advance_loc4.  Record the frag and the
378	     position within the frag, so that we can change it later.  */
379	  frag_grow (1);
380	  d->state = state_saw_loc4;
381	  d->loc4_frag = frag_now;
382	  d->loc4_fix = frag_now_fix ();
383	}
384      break;
385
386    case state_saw_loc4:
387      d->state = state_wait_loc4;
388      if (*pnbytes != 4)
389	break;
390      if (exp->X_op == O_constant)
391	{
392	  /* This is a case which we can optimize.  The two symbols being
393	     subtracted were in the same frag and the expression was
394	     reduced to a constant.  We can do the optimization entirely
395	     in this function.  */
396	  if (d->cie_info.code_alignment > 0
397	      && exp->X_add_number % d->cie_info.code_alignment == 0
398	      && exp->X_add_number / d->cie_info.code_alignment < 0x40)
399	    {
400	      d->loc4_frag->fr_literal[d->loc4_fix]
401		= DW_CFA_advance_loc
402		  | (exp->X_add_number / d->cie_info.code_alignment);
403	      /* No more bytes needed.  */
404	      return 1;
405	    }
406	  else if (exp->X_add_number < 0x100)
407	    {
408	      d->loc4_frag->fr_literal[d->loc4_fix] = DW_CFA_advance_loc1;
409	      *pnbytes = 1;
410	    }
411	  else if (exp->X_add_number < 0x10000)
412	    {
413	      d->loc4_frag->fr_literal[d->loc4_fix] = DW_CFA_advance_loc2;
414	      *pnbytes = 2;
415	    }
416	}
417      else if (exp->X_op == O_subtract)
418	{
419	  /* This is a case we can optimize.  The expression was not
420	     reduced, so we can not finish the optimization until the end
421	     of the assembly.  We set up a variant frag which we handle
422	     later.  */
423	  int fr_subtype;
424
425	  if (d->cie_info.code_alignment > 0)
426	    fr_subtype = d->cie_info.code_alignment << 3;
427	  else
428	    fr_subtype = 0;
429
430	  frag_var (rs_cfa, 4, 0, fr_subtype, make_expr_symbol (exp),
431		    d->loc4_fix, (char *) d->loc4_frag);
432	  return 1;
433	}
434      break;
435
436    case state_error:
437      /* Just skipping everything.  */
438      break;
439    }
440
441  return 0;
442}
443
444/* The function estimates the size of a rs_cfa variant frag based on
445   the current values of the symbols.  It is called before the
446   relaxation loop.  We set fr_subtype{0:2} to the expected length.  */
447
448int
449eh_frame_estimate_size_before_relax (fragS *frag)
450{
451  offsetT diff;
452  int ca = frag->fr_subtype >> 3;
453  int ret;
454
455  diff = resolve_symbol_value (frag->fr_symbol);
456
457  if (ca > 0 && diff % ca == 0 && diff / ca < 0x40)
458    ret = 0;
459  else if (diff < 0x100)
460    ret = 1;
461  else if (diff < 0x10000)
462    ret = 2;
463  else
464    ret = 4;
465
466  frag->fr_subtype = (frag->fr_subtype & ~7) | ret;
467
468  return ret;
469}
470
471/* This function relaxes a rs_cfa variant frag based on the current
472   values of the symbols.  fr_subtype{0:2} is the current length of
473   the frag.  This returns the change in frag length.  */
474
475int
476eh_frame_relax_frag (fragS *frag)
477{
478  int oldsize, newsize;
479
480  oldsize = frag->fr_subtype & 7;
481  newsize = eh_frame_estimate_size_before_relax (frag);
482  return newsize - oldsize;
483}
484
485/* This function converts a rs_cfa variant frag into a normal fill
486   frag.  This is called after all relaxation has been done.
487   fr_subtype{0:2} will be the desired length of the frag.  */
488
489void
490eh_frame_convert_frag (fragS *frag)
491{
492  offsetT diff;
493  fragS *loc4_frag;
494  int loc4_fix;
495
496  loc4_frag = (fragS *) frag->fr_opcode;
497  loc4_fix = (int) frag->fr_offset;
498
499  diff = resolve_symbol_value (frag->fr_symbol);
500
501  switch (frag->fr_subtype & 7)
502    {
503    case 0:
504      {
505	int ca = frag->fr_subtype >> 3;
506	assert (ca > 0 && diff % ca == 0 && diff / ca < 0x40);
507	loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc | (diff / ca);
508      }
509      break;
510
511    case 1:
512      assert (diff < 0x100);
513      loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc1;
514      frag->fr_literal[frag->fr_fix] = diff;
515      break;
516
517    case 2:
518      assert (diff < 0x10000);
519      loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc2;
520      md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 2);
521      break;
522
523    default:
524      md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 4);
525      break;
526    }
527
528  frag->fr_fix += frag->fr_subtype & 7;
529  frag->fr_type = rs_fill;
530  frag->fr_subtype = 0;
531  frag->fr_offset = 0;
532}
533