1/* ehopt.c--optimize gcc exception frame information.
2   Copyright (C) 1998-2022 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 "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  unsigned 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 (startswith (segment_name (now_seg), ".debug_frame"))
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
228enum frame_state
229{
230  state_idle,
231  state_saw_size,
232  state_saw_cie_offset,
233  state_saw_pc_begin,
234  state_seeing_aug_size,
235  state_skipping_aug,
236  state_wait_loc4,
237  state_saw_loc4,
238  state_error,
239};
240
241/* This function is called from emit_expr.  It looks for cases which
242   we can optimize.
243
244   Rather than try to parse all this information as we read it, we
245   look for a single byte DW_CFA_advance_loc4 followed by a 4 byte
246   difference.  We turn that into a rs_cfa_advance frag, and handle
247   those frags at the end of the assembly.  If the gcc output changes
248   somewhat, this optimization may stop working.
249
250   This function returns non-zero if it handled the expression and
251   emit_expr should not do anything, or zero otherwise.  It can also
252   change *EXP and *PNBYTES.  */
253
254int
255check_eh_frame (expressionS *exp, unsigned int *pnbytes)
256{
257  struct frame_data
258  {
259    enum frame_state state;
260
261    int cie_info_ok;
262    struct cie_info cie_info;
263
264    symbolS *size_end_sym;
265    fragS *loc4_frag;
266    int loc4_fix;
267
268    int aug_size;
269    int aug_shift;
270  };
271
272  static struct frame_data eh_frame_data;
273  static struct frame_data debug_frame_data;
274  struct frame_data *d;
275
276  /* Don't optimize.  */
277  if (flag_traditional_format)
278    return 0;
279
280#ifdef md_allow_eh_opt
281  if (! md_allow_eh_opt)
282    return 0;
283#endif
284
285  /* Select the proper section data.  */
286  if (startswith (segment_name (now_seg), ".eh_frame")
287      && segment_name (now_seg)[9] != '_')
288    d = &eh_frame_data;
289  else if (startswith (segment_name (now_seg), ".debug_frame"))
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 = (enum frame_state) (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 (exp->X_add_number < 0x40)
405	    {
406	      d->loc4_frag->fr_literal[d->loc4_fix]
407		= DW_CFA_advance_loc | exp->X_add_number;
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 && d->cie_info.code_alignment == 1)
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	  frag_var (rs_cfa, 4, 0, 1 << 3, make_expr_symbol (exp),
429		    d->loc4_fix, (char *) d->loc4_frag);
430	  return 1;
431	}
432      else if ((exp->X_op == O_divide
433		|| exp->X_op == O_right_shift)
434	       && d->cie_info.code_alignment > 1)
435	{
436	  if (symbol_symbolS (exp->X_add_symbol)
437	      && symbol_constant_p (exp->X_op_symbol)
438	      && S_GET_SEGMENT (exp->X_op_symbol) == absolute_section
439	      && ((exp->X_op == O_divide
440		   ? *symbol_X_add_number (exp->X_op_symbol)
441		   : (offsetT) 1 << *symbol_X_add_number (exp->X_op_symbol))
442		  == (offsetT) d->cie_info.code_alignment))
443	    {
444	      expressionS *symval;
445
446	      symval = symbol_get_value_expression (exp->X_add_symbol);
447	      if (symval->X_op == O_subtract)
448		{
449		  /* This is a case we can optimize as well.  The
450		     expression was not reduced, so we can not finish
451		     the optimization until the end of the assembly.
452		     We set up a variant frag which we handle later.  */
453		  frag_var (rs_cfa, 4, 0, d->cie_info.code_alignment << 3,
454			    make_expr_symbol (symval),
455			    d->loc4_fix, (char *) d->loc4_frag);
456		  return 1;
457		}
458	    }
459	}
460      break;
461
462    case state_error:
463      /* Just skipping everything.  */
464      break;
465    }
466
467  return 0;
468}
469
470/* The function estimates the size of a rs_cfa variant frag based on
471   the current values of the symbols.  It is called before the
472   relaxation loop.  We set fr_subtype{0:2} to the expected length.  */
473
474int
475eh_frame_estimate_size_before_relax (fragS *frag)
476{
477  offsetT diff;
478  int ca = frag->fr_subtype >> 3;
479  int ret;
480
481  diff = resolve_symbol_value (frag->fr_symbol);
482
483  gas_assert (ca > 0);
484  diff /= ca;
485  if (diff == 0)
486    ret = -1;
487  else if (diff < 0x40)
488    ret = 0;
489  else if (diff < 0x100)
490    ret = 1;
491  else if (diff < 0x10000)
492    ret = 2;
493  else
494    ret = 4;
495
496  frag->fr_subtype = (frag->fr_subtype & ~7) | (ret & 7);
497
498  return ret;
499}
500
501/* This function relaxes a rs_cfa variant frag based on the current
502   values of the symbols.  fr_subtype{0:2} is the current length of
503   the frag.  This returns the change in frag length.  */
504
505int
506eh_frame_relax_frag (fragS *frag)
507{
508  int oldsize, newsize;
509
510  oldsize = frag->fr_subtype & 7;
511  if (oldsize == 7)
512    oldsize = -1;
513  newsize = eh_frame_estimate_size_before_relax (frag);
514  return newsize - oldsize;
515}
516
517/* This function converts a rs_cfa variant frag into a normal fill
518   frag.  This is called after all relaxation has been done.
519   fr_subtype{0:2} will be the desired length of the frag.  */
520
521void
522eh_frame_convert_frag (fragS *frag)
523{
524  offsetT diff;
525  fragS *loc4_frag;
526  int loc4_fix, ca;
527
528  loc4_frag = (fragS *) frag->fr_opcode;
529  loc4_fix = (int) frag->fr_offset;
530
531  diff = resolve_symbol_value (frag->fr_symbol);
532
533  ca = frag->fr_subtype >> 3;
534  gas_assert (ca > 0);
535  diff /= ca;
536  switch (frag->fr_subtype & 7)
537    {
538    case 0:
539      gas_assert (diff < 0x40);
540      loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc | diff;
541      break;
542
543    case 1:
544      gas_assert (diff < 0x100);
545      loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc1;
546      frag->fr_literal[frag->fr_fix] = diff;
547      break;
548
549    case 2:
550      gas_assert (diff < 0x10000);
551      loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc2;
552      md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 2);
553      break;
554
555    case 4:
556      md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 4);
557      break;
558
559    case 7:
560      gas_assert (diff == 0);
561      frag->fr_fix -= 8;
562      break;
563
564    default:
565      abort ();
566    }
567
568  frag->fr_fix += frag->fr_subtype & 7;
569  frag->fr_type = rs_fill;
570  frag->fr_subtype = 0;
571  frag->fr_offset = 0;
572}
573