Coverage Report

Created: 2026-04-04 08:16

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