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