xref: /dragonfly/contrib/binutils-2.34/gas/ehopt.c (revision e6d22e9b)
1 /* ehopt.c--optimize gcc exception frame information.
2    Copyright (C) 1998-2020 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 
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   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 (strncmp (segment_name (now_seg), ".debug_frame", 12) == 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 enum 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 
254 int
255 check_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 (strncmp (segment_name (now_seg), ".eh_frame", 9) == 0
287       && segment_name (now_seg)[9] != '_')
288     d = &eh_frame_data;
289   else if (strncmp (segment_name (now_seg), ".debug_frame", 12) == 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 = (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 
474 int
475 eh_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 
505 int
506 eh_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 
521 void
522 eh_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