Home | History | Annotate | Line # | Download | only in bfd
elf-sframe.c revision 1.1.1.2
      1 /* .sframe section processing.
      2    Copyright (C) 2022-2025 Free Software Foundation, Inc.
      3 
      4    This file is part of BFD, the Binary File Descriptor library.
      5 
      6    This program is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3 of the License, or
      9    (at your option) any later version.
     10 
     11    This program is distributed in the hope that it will be useful,
     12    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program; if not, write to the Free Software
     18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19    MA 02110-1301, USA.  */
     20 
     21 #include "sysdep.h"
     22 #include "bfd.h"
     23 #include "libbfd.h"
     24 #include "elf-bfd.h"
     25 #include "sframe-api.h"
     26 #include "sframe-internal.h"
     27 
     28 /* Return TRUE if the function has been marked for deletion during the linking
     29    process.  */
     30 
     31 static bool
     32 sframe_decoder_func_deleted_p (struct sframe_dec_info *sfd_info,
     33 			       unsigned int func_idx)
     34 {
     35   if (func_idx < sfd_info->sfd_fde_count)
     36     return sfd_info->sfd_func_bfdinfo[func_idx].func_deleted_p;
     37 
     38   return false;
     39 }
     40 
     41 /* Mark the function in the decoder info for deletion.  */
     42 
     43 static void
     44 sframe_decoder_mark_func_deleted (struct sframe_dec_info *sfd_info,
     45 				  unsigned int func_idx)
     46 {
     47   if (func_idx < sfd_info->sfd_fde_count)
     48     sfd_info->sfd_func_bfdinfo[func_idx].func_deleted_p = true;
     49 }
     50 
     51 /* Get the relocation offset from the decoder info for the given function.  */
     52 
     53 static unsigned int
     54 sframe_decoder_get_func_r_offset (struct sframe_dec_info *sfd_info,
     55 				  unsigned int func_idx)
     56 {
     57   BFD_ASSERT (func_idx < sfd_info->sfd_fde_count);
     58   unsigned int func_r_offset
     59     = sfd_info->sfd_func_bfdinfo[func_idx].func_r_offset;
     60   /* There must have been a reloc.  */
     61   BFD_ASSERT (func_r_offset);
     62   return func_r_offset;
     63 }
     64 
     65 /* Bookkeep the function relocation offset in the decoder info.  */
     66 
     67 static void
     68 sframe_decoder_set_func_r_offset (struct sframe_dec_info *sfd_info,
     69 				  unsigned int func_idx,
     70 				  unsigned int r_offset)
     71 {
     72   if (func_idx < sfd_info->sfd_fde_count)
     73     sfd_info->sfd_func_bfdinfo[func_idx].func_r_offset = r_offset;
     74 }
     75 
     76 /* Get the relocation index in the elf_reloc_cookie for the function.  */
     77 
     78 static unsigned int
     79 sframe_decoder_get_func_reloc_index (struct sframe_dec_info *sfd_info,
     80 				     unsigned int func_idx)
     81 {
     82   BFD_ASSERT (func_idx < sfd_info->sfd_fde_count);
     83   return sfd_info->sfd_func_bfdinfo[func_idx].func_reloc_index;
     84 }
     85 
     86 /* Bookkeep the relocation index in the elf_reloc_cookie for the function.  */
     87 
     88 static void
     89 sframe_decoder_set_func_reloc_index (struct sframe_dec_info *sfd_info,
     90 				     unsigned int func_idx,
     91 				     unsigned int reloc_index)
     92 {
     93   if (func_idx < sfd_info->sfd_fde_count)
     94     sfd_info->sfd_func_bfdinfo[func_idx].func_reloc_index = reloc_index;
     95 }
     96 
     97 /* Initialize the set of additional information in CFD_INFO,
     98    needed for linking SEC.  Returns TRUE if setup is done successfully.  */
     99 
    100 static bool
    101 sframe_decoder_init_func_bfdinfo (bfd *abfd,
    102 				  const asection *sec,
    103 				  struct sframe_dec_info *sfd_info,
    104 				  const struct elf_reloc_cookie *cookie)
    105 {
    106   unsigned int fde_count;
    107   unsigned int func_bfdinfo_size, i;
    108   const Elf_Internal_Rela *rel;
    109 
    110   fde_count = sframe_decoder_get_num_fidx (sfd_info->sfd_ctx);
    111   sfd_info->sfd_fde_count = fde_count;
    112 
    113   /* Allocate and clear the memory.  */
    114   func_bfdinfo_size = (sizeof (struct sframe_func_bfdinfo)) * fde_count;
    115   sfd_info->sfd_func_bfdinfo = bfd_zalloc (abfd, func_bfdinfo_size);
    116   if (sfd_info->sfd_func_bfdinfo == NULL)
    117     return false;
    118 
    119   /* For linker generated .sframe sections, we have no relocs.  Skip.  */
    120   if ((sec->flags & SEC_LINKER_CREATED) && cookie->rels == NULL)
    121     return true;
    122 
    123   rel = cookie->rels;
    124   for (i = 0; i < fde_count; i++)
    125     {
    126       /* Bookkeep the relocation offset and relocation index of each function
    127 	 for later use.  */
    128       sframe_decoder_set_func_r_offset (sfd_info, i, rel->r_offset);
    129       sframe_decoder_set_func_reloc_index (sfd_info, i, i);
    130 
    131       rel++;
    132     }
    133 
    134   /* If there are more relocation entries, they must be R_*_NONE which
    135      may be generated from relocations against discarded sections by
    136      ld -r.  */
    137   for (; rel < cookie->relend; rel++)
    138    if (rel->r_info != 0)
    139      break;
    140   BFD_ASSERT (rel == cookie->relend);
    141 
    142   return true;
    143 }
    144 
    145 /* Read the value from CONTENTS at the specified OFFSET for the given ABFD.  */
    146 
    147 static bfd_vma
    148 sframe_read_value (bfd *abfd, bfd_byte *contents, unsigned int offset,
    149 		   unsigned int width)
    150 {
    151   BFD_ASSERT (contents && offset);
    152   /* Supporting the usecase of reading only the 4-byte relocated
    153      value (signed offset for func start addr) for now.  */
    154   BFD_ASSERT (width == 4);
    155   /* FIXME endianness ?? */
    156   unsigned char *buf = contents + offset;
    157   bfd_vma value = bfd_get_signed_32 (abfd, buf);
    158   return value;
    159 }
    160 
    161 /* Return true if there is at least one non-empty .sframe section in
    162    input files.  Can only be called after ld has mapped input to
    163    output sections, and before sections are stripped.  */
    164 
    165 bool
    166 _bfd_elf_sframe_present (struct bfd_link_info *info)
    167 {
    168   asection *sframe = bfd_get_section_by_name (info->output_bfd, ".sframe");
    169 
    170   if (sframe == NULL)
    171     return false;
    172 
    173   /* Count only sections which have at least a single FDE.  */
    174   for (sframe = sframe->map_head.s; sframe != NULL; sframe = sframe->map_head.s)
    175     /* Note that this may become an approximate check in the future when
    176        some ABI/arch begin to use the sfh_auxhdr_len.  When sfh_auxhdr_len has
    177        non-zero value, it will need to be accounted for in the calculation of
    178        the SFrame header size.  */
    179     if (sframe->size > sizeof (sframe_header))
    180       return true;
    181   return false;
    182 }
    183 
    184 /* Try to parse .sframe section SEC, which belongs to ABFD.  Store the
    185    information in the section's sec_info field on success.  COOKIE
    186    describes the relocations in SEC.
    187 
    188    Returns TRUE if success, FALSE if any error or failure.  */
    189 
    190 bool
    191 _bfd_elf_parse_sframe (bfd *abfd,
    192 		       struct bfd_link_info *info ATTRIBUTE_UNUSED,
    193 		       asection *sec, struct elf_reloc_cookie *cookie)
    194 {
    195   bfd_byte *sfbuf = NULL;
    196   struct sframe_dec_info *sfd_info;
    197   sframe_decoder_ctx *sfd_ctx;
    198   bfd_size_type sf_size;
    199   int decerr = 0;
    200 
    201   /* Prior versions of assembler and ld were generating SFrame sections with
    202      section type SHT_PROGBITS.  Issue an error for lack of support for such
    203      objects now.  Even if section size is zero, a valid section type is
    204      expected.  */
    205   if (elf_section_type (sec) != SHT_GNU_SFRAME)
    206     {
    207       _bfd_error_handler
    208 	(_("error in %pB(%pA); unexpected SFrame section type"),
    209 	 abfd, sec);
    210       return false;
    211     }
    212 
    213   if (sec->size == 0
    214       || (sec->flags & SEC_HAS_CONTENTS) == 0
    215       || sec->sec_info_type != SEC_INFO_TYPE_NONE)
    216     {
    217       /* This file does not contain .sframe information.  */
    218       return false;
    219     }
    220 
    221   if (bfd_is_abs_section (sec->output_section))
    222     {
    223       /* At least one of the sections is being discarded from the
    224 	 link, so we should just ignore them.  */
    225       return false;
    226     }
    227 
    228   /* Read the SFrame stack trace information from abfd.  */
    229   if (!_bfd_elf_mmap_section_contents (abfd, sec, &sfbuf))
    230     goto fail_no_free;
    231 
    232   /* Decode the buffer and keep decoded contents for later use.
    233      Relocations are performed later, but are such that the section's
    234      size is unaffected.  */
    235   sfd_info = bfd_zalloc (abfd, sizeof (*sfd_info));
    236   sf_size = sec->size;
    237 
    238   sfd_info->sfd_ctx = sframe_decode ((const char*)sfbuf, sf_size, &decerr);
    239   sfd_info->sfd_state = SFRAME_SEC_DECODED;
    240   sfd_ctx = sfd_info->sfd_ctx;
    241   if (!sfd_ctx)
    242     /* Free'ing up any memory held by decoder context is done by
    243        sframe_decode in case of error.  */
    244     goto fail_no_free;
    245 
    246   if (!sframe_decoder_init_func_bfdinfo (abfd, sec, sfd_info, cookie))
    247     {
    248       sframe_decoder_free (&sfd_ctx);
    249       goto fail_no_free;
    250     }
    251 
    252   elf_section_data (sec)->sec_info = sfd_info;
    253   sec->sec_info_type = SEC_INFO_TYPE_SFRAME;
    254 
    255   goto success;
    256 
    257 fail_no_free:
    258   _bfd_error_handler
    259    (_("error in %pB(%pA); no .sframe will be created"),
    260     abfd, sec);
    261   return false;
    262 success:
    263   _bfd_elf_munmap_section_contents (sec, sfbuf);
    264   return true;
    265 }
    266 
    267 /* This function is called for each input file before the .sframe section
    268    is relocated.  It marks the SFrame FDE for the discarded functions for
    269    deletion.
    270 
    271    The function returns TRUE iff any entries have been deleted.  */
    272 
    273 bool
    274 _bfd_elf_discard_section_sframe
    275    (asection *sec,
    276     bool (*reloc_symbol_deleted_p) (bfd_vma, void *),
    277     struct elf_reloc_cookie *cookie)
    278 {
    279   bool changed;
    280   bool keep;
    281   unsigned int i;
    282   unsigned int func_desc_offset;
    283   unsigned int num_fidx;
    284   struct sframe_dec_info *sfd_info;
    285 
    286   changed = false;
    287   /* FIXME - if relocatable link and changed = true, how does the final
    288      .rela.sframe get updated ?.  */
    289   keep = false;
    290 
    291   sfd_info = (struct sframe_dec_info *) elf_section_data (sec)->sec_info;
    292 
    293   /* Skip checking for the linker created .sframe sections
    294      (for PLT sections).  */
    295   if ((sec->flags & SEC_LINKER_CREATED) == 0 || cookie->rels != NULL)
    296     {
    297       num_fidx = sframe_decoder_get_num_fidx (sfd_info->sfd_ctx);
    298       for (i = 0; i < num_fidx; i++)
    299 	{
    300 	  func_desc_offset = sframe_decoder_get_func_r_offset (sfd_info, i);
    301 
    302 	  cookie->rel = cookie->rels
    303 	    + sframe_decoder_get_func_reloc_index (sfd_info, i);
    304 	  keep = !(*reloc_symbol_deleted_p) (func_desc_offset, cookie);
    305 
    306 	  if (!keep)
    307 	    {
    308 	      sframe_decoder_mark_func_deleted (sfd_info, i);
    309 	      changed = true;
    310 	    }
    311 	}
    312     }
    313   return changed;
    314 }
    315 
    316 /* Update the reference to the output .sframe section in the output ELF
    317    BFD ABFD.  Returns true if no error.  */
    318 
    319 bool
    320 _bfd_elf_set_section_sframe (bfd *abfd, struct bfd_link_info *info)
    321 {
    322   asection *cfsec;
    323 
    324   cfsec = bfd_get_section_by_name (info->output_bfd, ".sframe");
    325   if (!cfsec)
    326     return false;
    327 
    328   elf_section_type (cfsec) = SHT_GNU_SFRAME;
    329   elf_sframe (abfd) = cfsec;
    330 
    331   return true;
    332 }
    333 
    334 /* Merge .sframe section SEC.  This is called with the relocated
    335    CONTENTS.  */
    336 
    337 bool
    338 _bfd_elf_merge_section_sframe (bfd *abfd,
    339 			       struct bfd_link_info *info,
    340 			       asection *sec,
    341 			       bfd_byte *contents)
    342 {
    343   struct sframe_dec_info *sfd_info;
    344   struct sframe_enc_info *sfe_info;
    345   sframe_decoder_ctx *sfd_ctx;
    346   sframe_encoder_ctx *sfe_ctx;
    347   uint8_t sfd_ctx_abi_arch;
    348   int8_t sfd_ctx_fixed_fp_offset;
    349   int8_t sfd_ctx_fixed_ra_offset;
    350   uint8_t dctx_version;
    351   uint8_t ectx_version;
    352   uint8_t dctx_flags;
    353   uint8_t ectx_flags;
    354   int encerr = 0;
    355 
    356   struct elf_link_hash_table *htab;
    357   asection *cfsec;
    358 
    359   /* Sanity check - handle SFrame sections only.  */
    360   if (sec->sec_info_type != SEC_INFO_TYPE_SFRAME)
    361     return false;
    362 
    363   sfd_info = (struct sframe_dec_info *) elf_section_data (sec)->sec_info;
    364   sfd_ctx = sfd_info->sfd_ctx;
    365 
    366   htab = elf_hash_table (info);
    367   sfe_info = &(htab->sfe_info);
    368   sfe_ctx = sfe_info->sfe_ctx;
    369 
    370   /* All input bfds are expected to have a valid SFrame section.  Even if
    371      the SFrame section is empty with only a header, there must be a valid
    372      SFrame decoder context by now.  The SFrame encoder context, however,
    373      will get set later here, if this is the first call to the function.  */
    374   if (sfd_ctx == NULL || sfe_info == NULL)
    375     return false;
    376 
    377   dctx_flags = sframe_decoder_get_flags (sfd_ctx);
    378 
    379   if (htab->sfe_info.sfe_ctx == NULL)
    380     {
    381       sfd_ctx_abi_arch = sframe_decoder_get_abi_arch (sfd_ctx);
    382       sfd_ctx_fixed_fp_offset = sframe_decoder_get_fixed_fp_offset (sfd_ctx);
    383       sfd_ctx_fixed_ra_offset = sframe_decoder_get_fixed_ra_offset (sfd_ctx);
    384 
    385       /* Valid values are non-zero.  */
    386       if (!sfd_ctx_abi_arch)
    387 	return false;
    388 
    389       /* In-memory FDEs in the encoder object are unsorted during linking and
    390 	 will be sorted before emission.  Reset SFRAME_F_FDE_SORTED to aptly
    391 	 reflect that (doing so has no other functional value at this time
    392 	 though).  */
    393       uint8_t tflags = dctx_flags & ~SFRAME_F_FDE_SORTED;
    394       /* ld always generates an output section with
    395 	 SFRAME_F_FDE_FUNC_START_PCREL flag set.  Later using
    396 	 SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS, it is enforced that the provided
    397 	 input sections also have this flag set.  */
    398       tflags |= SFRAME_F_FDE_FUNC_START_PCREL;
    399       htab->sfe_info.sfe_ctx = sframe_encode (SFRAME_VERSION_2,
    400 					      tflags, /* SFrame flags.  */
    401 					      sfd_ctx_abi_arch,
    402 					      sfd_ctx_fixed_fp_offset,
    403 					      sfd_ctx_fixed_ra_offset,
    404 					      &encerr);
    405       /* Handle errors from sframe_encode.  */
    406       if (htab->sfe_info.sfe_ctx == NULL)
    407 	return false;
    408     }
    409   sfe_ctx = sfe_info->sfe_ctx;
    410 
    411   if (sfe_info->sframe_section == NULL)
    412     {
    413       /* Make sure things are set for an eventual write.
    414 	 Size of the output section is not known until
    415 	 _bfd_elf_write_section_sframe is ready with the buffer
    416 	 to write out.  */
    417       cfsec = bfd_get_section_by_name (info->output_bfd, ".sframe");
    418       if (cfsec)
    419 	{
    420 	  sfe_info->sframe_section = cfsec;
    421 	  // elf_sframe (abfd) = cfsec;
    422 	}
    423       else
    424 	return false;
    425     }
    426 
    427   /* Check that all .sframe sections being linked have the same
    428      ABI/arch.  */
    429   if (sframe_decoder_get_abi_arch (sfd_ctx)
    430       != sframe_encoder_get_abi_arch (sfe_ctx))
    431     {
    432       _bfd_error_handler
    433 	(_("input SFrame sections with different abi prevent .sframe"
    434 	  " generation"));
    435       return false;
    436     }
    437 
    438   /* Check that all .sframe sections being linked have the same version.  */
    439   dctx_version = sframe_decoder_get_version (sfd_ctx);
    440   ectx_version = sframe_encoder_get_version (sfe_ctx);
    441   if (dctx_version != SFRAME_VERSION_2 || dctx_version != ectx_version)
    442     {
    443       _bfd_error_handler
    444 	(_("input SFrame sections with different format versions prevent"
    445 	  " .sframe generation"));
    446       return false;
    447     }
    448 
    449   /* Check that all SFrame sections being linked have the 'data encoding'
    450      related flags set.  The implementation does not support updating these
    451      data encodings on the fly; confirm by checking the ectx_flags.  */
    452   ectx_flags = sframe_encoder_get_flags (sfe_ctx);
    453   if ((dctx_flags & ectx_flags & SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS)
    454       != SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS)
    455     {
    456       _bfd_error_handler
    457 	(_("SFrame sections with unexpected data encoding prevent"
    458 	  " .sframe generation"));
    459       return false;
    460     }
    461 
    462   /* Iterate over the function descriptor entries and the FREs of the
    463      function from the decoder context.  Add each of them to the encoder
    464      context, if suitable.  */
    465   uint32_t i = 0, j = 0, cur_fidx = 0;
    466 
    467   uint32_t num_fidx = sframe_decoder_get_num_fidx (sfd_ctx);
    468   uint32_t num_enc_fidx = sframe_encoder_get_num_fidx (sfe_ctx);
    469 
    470   for (i = 0; i < num_fidx; i++)
    471     {
    472       unsigned int num_fres = 0;
    473       int32_t func_start_addr;
    474       bfd_vma address;
    475       uint32_t func_size = 0;
    476       unsigned char func_info = 0;
    477       unsigned int r_offset = 0;
    478       bool pltn_reloc_by_hand = false;
    479       unsigned int pltn_r_offset = 0;
    480       uint8_t rep_block_size = 0;
    481 
    482       if (!sframe_decoder_get_funcdesc_v2 (sfd_ctx, i, &num_fres, &func_size,
    483 					   &func_start_addr, &func_info,
    484 					   &rep_block_size))
    485 	{
    486 	  /* If function belongs to a deleted section, skip editing the
    487 	     function descriptor entry.  */
    488 	  if (sframe_decoder_func_deleted_p(sfd_info, i))
    489 	    continue;
    490 
    491 	  /* Don't edit function descriptor entries for relocatable link.  */
    492 	  if (!bfd_link_relocatable (info))
    493 	    {
    494 	      if (!(sec->flags & SEC_LINKER_CREATED))
    495 		{
    496 		  /* Get relocated contents by reading the value of the
    497 		     relocated function start address at the beginning of the
    498 		     function descriptor entry.  */
    499 		  r_offset = sframe_decoder_get_func_r_offset (sfd_info, i);
    500 		}
    501 	      else
    502 		{
    503 		  /* Expected to land here when SFrame stack trace info is
    504 		     created dynamically for the .plt* sections.  These
    505 		     sections are expected to have upto two SFrame FDE entries.
    506 		     Although the code should work for > 2,  leaving this
    507 		     assert here for safety.  */
    508 		  BFD_ASSERT (num_fidx <= 2);
    509 		  /* For the first entry, we know the offset of the SFrame FDE's
    510 		     sfde_func_start_address.  Side note: see how the value
    511 		     of PLT_SFRAME_FDE_START_OFFSET is also set to the
    512 		     same.  */
    513 		  r_offset = sframe_decoder_get_hdr_size (sfd_ctx);
    514 		  /* For any further SFrame FDEs, the generator has already put
    515 		     in an offset in place of sfde_func_start_address of the
    516 		     corresponding FDE.  We will use it by hand to relocate.  */
    517 		  if (i > 0)
    518 		    {
    519 		      pltn_r_offset
    520 			= r_offset + (i * sizeof (sframe_func_desc_entry));
    521 		      pltn_reloc_by_hand = true;
    522 		    }
    523 		}
    524 
    525 	      /* Get the SFrame FDE function start address after relocation.  */
    526 	      address = sframe_read_value (abfd, contents, r_offset, 4);
    527 	      if (pltn_reloc_by_hand)
    528 		address += sframe_read_value (abfd, contents,
    529 					      pltn_r_offset, 4);
    530 	      address += (sec->output_offset + r_offset);
    531 	      /* SFrame FDE function start address is an offset from the
    532 		 sfde_func_start_address field to the start PC.  The
    533 		 calculation below is the distance of sfde_func_start_address
    534 		 field from the start of the output SFrame section.  */
    535 	      uint32_t offsetof_fde_in_sec
    536 		= sframe_encoder_get_offsetof_fde_start_addr (sfe_ctx,
    537 							      cur_fidx + num_enc_fidx,
    538 							      NULL);
    539 	      address -= offsetof_fde_in_sec;
    540 
    541 	      /* FIXME For testing only. Cleanup later.  */
    542 	      // address += (sec->output_section->vma);
    543 
    544 	      func_start_addr = address;
    545 	    }
    546 
    547 	  /* Update the encoder context with updated content.  */
    548 	  int err = sframe_encoder_add_funcdesc_v2 (sfe_ctx, func_start_addr,
    549 						    func_size, func_info,
    550 						    rep_block_size, num_fres);
    551 	  cur_fidx++;
    552 	  BFD_ASSERT (!err);
    553 	}
    554 
    555       for (j = 0; j < num_fres; j++)
    556 	{
    557 	  sframe_frame_row_entry fre;
    558 	  if (!sframe_decoder_get_fre (sfd_ctx, i, j, &fre))
    559 	    {
    560 	      int err = sframe_encoder_add_fre (sfe_ctx,
    561 						cur_fidx-1+num_enc_fidx,
    562 						&fre);
    563 	      BFD_ASSERT (!err);
    564 	    }
    565 	}
    566     }
    567   sfd_info->sfd_state = SFRAME_SEC_MERGED;
    568   /* Free the SFrame decoder context.  */
    569   sframe_decoder_free (&sfd_ctx);
    570 
    571   return true;
    572 }
    573 
    574 /* Adjust an address in the .sframe section.  Given OFFSET within
    575    SEC, this returns the new offset in the merged .sframe section,
    576    or -1 if the address refers to an FDE which has been removed.
    577 
    578    PS: This function assumes that _bfd_elf_merge_section_sframe has
    579    not been called on the input section SEC yet.  Note how it uses
    580    sframe_encoder_get_num_fidx () to figure out the offset of FDE
    581    in the output section.  */
    582 
    583 bfd_vma
    584 _bfd_elf_sframe_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
    585 				struct bfd_link_info *info,
    586 				asection *sec,
    587 				bfd_vma offset)
    588 {
    589   struct sframe_dec_info *sfd_info;
    590   struct sframe_enc_info *sfe_info;
    591   sframe_decoder_ctx *sfd_ctx;
    592   sframe_encoder_ctx *sfe_ctx;
    593   struct elf_link_hash_table *htab;
    594 
    595   unsigned int sec_fde_idx, out_num_fdes;
    596   unsigned int sfd_num_fdes, sfe_num_fdes;
    597   uint32_t sfd_fde_offset;
    598   bfd_vma new_offset;
    599 
    600   if (sec->sec_info_type != SEC_INFO_TYPE_SFRAME)
    601     return offset;
    602 
    603   sfd_info = elf_section_data (sec)->sec_info;
    604   sfd_ctx = sfd_info->sfd_ctx;
    605   sfd_num_fdes = sframe_decoder_get_num_fidx (sfd_ctx);
    606 
    607   BFD_ASSERT (sfd_info->sfd_state == SFRAME_SEC_DECODED);
    608 
    609   htab = elf_hash_table (info);
    610   sfe_info = &(htab->sfe_info);
    611   sfe_ctx = sfe_info->sfe_ctx;
    612   sfe_num_fdes = sframe_encoder_get_num_fidx (sfe_ctx);
    613 
    614   /* The index of this FDE in the output section depends on number of deleted
    615      functions (between index 0 and sec_fde_idx), if any.  */
    616   out_num_fdes = 0;
    617   sec_fde_idx = 0;
    618   for (unsigned int i = 0; i < sfd_num_fdes; i++)
    619     {
    620       sfd_fde_offset = sframe_decoder_get_offsetof_fde_start_addr (sfd_ctx,
    621 								   i, NULL);
    622       if (!sframe_decoder_func_deleted_p (sfd_info, i))
    623 	out_num_fdes++;
    624 
    625       if (sfd_fde_offset == offset)
    626 	{
    627 	  /* Found the index of the FDE (at OFFSET) in the input section.  */
    628 	  sec_fde_idx = i;
    629 	  break;
    630 	}
    631     }
    632 
    633   if (sframe_decoder_func_deleted_p (sfd_info, sec_fde_idx))
    634     return (bfd_vma) -1;
    635 
    636   /* The number of FDEs in the output SFrame section.  Note that the output
    637      index of the FDE of interest will be (out_num_fdes - 1).  */
    638   out_num_fdes += sfe_num_fdes;
    639 
    640   new_offset = sframe_decoder_get_offsetof_fde_start_addr (sfd_ctx,
    641 							   out_num_fdes - 1,
    642 							   NULL);
    643   /* Recall that SFrame section merging has distinct requirements: All SFrame
    644      FDEs from input sections are clubbed together in the beginning of the
    645      output section.  So, at this point in the current function, the new_offset
    646      is the correct offset in the merged output SFrame section.  Note, however,
    647      that the default mechanism in the _elf_link_input_bfd will do the
    648      following adjustment:
    649        irela->r_offset += o->output_offset;
    650      for all section types.  However, such an adjustment in the RELA offset is
    651      _not_ needed for SFrame sections.  Perform the reverse adjustment here so
    652      that the default mechanism does not need additional SFrame specific
    653      checks.  */
    654   new_offset -= sec->output_offset;
    655 
    656   return new_offset;
    657 }
    658 
    659 /* Write out the .sframe section.  This must be called after
    660    _bfd_elf_merge_section_sframe has been called on all input
    661    .sframe sections.  */
    662 
    663 bool
    664 _bfd_elf_write_section_sframe (bfd *abfd, struct bfd_link_info *info)
    665 {
    666   bool retval = true;
    667 
    668   struct elf_link_hash_table *htab;
    669   struct sframe_enc_info *sfe_info;
    670   sframe_encoder_ctx *sfe_ctx;
    671   asection *sec;
    672   void *contents;
    673   size_t sec_size;
    674   int err = 0;
    675 
    676   htab = elf_hash_table (info);
    677   sfe_info = &htab->sfe_info;
    678   sec = sfe_info->sframe_section;
    679   sfe_ctx = sfe_info->sfe_ctx;
    680 
    681   if (sec == NULL)
    682     return true;
    683 
    684   contents = sframe_encoder_write (sfe_ctx, &sec_size, &err);
    685   sec->size = (bfd_size_type) sec_size;
    686 
    687   if (!bfd_set_section_contents (abfd, sec->output_section, contents,
    688 				 (file_ptr) sec->output_offset,
    689 				 sec->size))
    690     retval = false;
    691   else
    692     {
    693       Elf_Internal_Shdr *hdr = &elf_section_data (sec)->this_hdr;
    694       hdr->sh_size = sec->size;
    695     }
    696 
    697   sframe_encoder_free (&sfe_ctx);
    698 
    699   return retval;
    700 }
    701