Coverage Report

Created: 2026-03-10 08:46

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 ATTRIBUTE_UNUSED,
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
0
  if (info->discard_sframe)
233
0
    sec->flags |= SEC_EXCLUDE;
234
235
  /* Prior versions of assembler and ld were generating SFrame sections with
236
     section type SHT_PROGBITS.  Issue an error for lack of support for such
237
     objects now.  Even if section size is zero, a valid section type is
238
     expected.  */
239
0
  if (elf_section_type (sec) != SHT_GNU_SFRAME)
240
0
    {
241
0
      _bfd_error_handler
242
0
  (_("error in %pB(%pA); unexpected SFrame section type"),
243
0
   abfd, sec);
244
0
      return false;
245
0
    }
246
247
0
  if (sec->size == 0
248
0
      || (sec->flags & SEC_HAS_CONTENTS) == 0)
249
0
    {
250
      /* This file does not contain .sframe information.  */
251
0
      return false;
252
0
    }
253
254
  /* Check if this section was already parsed.  */
255
0
  if (sec->sec_info_type == SEC_INFO_TYPE_SFRAME)
256
0
    return true;
257
258
0
  if (bfd_is_abs_section (sec->output_section))
259
0
    {
260
      /* At least one of the sections is being discarded from the
261
   link, so we should just ignore them.  */
262
0
      return false;
263
0
    }
264
265
  /* Read the SFrame stack trace information from abfd.  */
266
0
  if (!_bfd_elf_mmap_section_contents (abfd, sec, &sfbuf))
267
0
    goto fail_no_free;
268
269
  /* Decode the buffer and keep decoded contents for later use.
270
     Relocations are performed later, but are such that the section's
271
     size is unaffected.  */
272
0
  sfd_info = bfd_zalloc (abfd, sizeof (*sfd_info));
273
0
  sf_size = sec->size;
274
275
0
  sfd_info->sfd_ctx = sframe_decode ((const char*)sfbuf, sf_size, &decerr);
276
0
  sfd_info->sfd_state = SFRAME_SEC_DECODED;
277
0
  sfd_ctx = sfd_info->sfd_ctx;
278
0
  if (!sfd_ctx)
279
    /* Free'ing up any memory held by decoder context is done by
280
       sframe_decode in case of error.  */
281
0
    goto fail_no_free;
282
283
0
  if (!sframe_decoder_init_func_bfdinfo (abfd, sec, sfd_info, cookie))
284
0
    {
285
0
      sframe_decoder_free (&sfd_info->sfd_ctx);
286
0
      goto fail_no_free;
287
0
    }
288
289
0
  sec->sec_info = sfd_info;
290
0
  sec->sec_info_type = SEC_INFO_TYPE_SFRAME;
291
292
0
  goto success;
293
294
0
fail_no_free:
295
0
  _bfd_error_handler
296
0
   (_("error in %pB(%pA); no .sframe will be created"),
297
0
    abfd, sec);
298
0
  return false;
299
0
success:
300
0
  _bfd_elf_munmap_section_contents (sec, sfbuf);
301
0
  return true;
302
0
}
303
304
/* This function is called for each input file before the .sframe section
305
   is relocated.  It marks the SFrame FDE for the discarded functions for
306
   deletion.
307
308
   The function returns TRUE iff any entries have been deleted.  */
309
310
bool
311
_bfd_elf_discard_section_sframe
312
   (asection *sec,
313
    bool (*reloc_symbol_deleted_p) (bfd_vma, void *),
314
    struct elf_reloc_cookie *cookie)
315
0
{
316
0
  bool changed;
317
0
  bool keep;
318
0
  unsigned int i;
319
0
  unsigned int func_desc_offset;
320
0
  unsigned int num_fidx;
321
0
  struct sframe_dec_info *sfd_info;
322
323
0
  changed = false;
324
  /* FIXME - if relocatable link and changed = true, how does the final
325
     .rela.sframe get updated ?.  */
326
0
  keep = false;
327
328
0
  sfd_info = sec->sec_info;
329
330
  /* Skip checking for the linker created .sframe sections
331
     (for PLT sections).  */
332
0
  if ((sec->flags & SEC_LINKER_CREATED) == 0 || cookie->rels != NULL)
333
0
    {
334
0
      num_fidx = sframe_decoder_get_num_fidx (sfd_info->sfd_ctx);
335
0
      for (i = 0; i < num_fidx; i++)
336
0
  {
337
0
    func_desc_offset = sframe_decoder_get_func_r_offset (sfd_info, i);
338
339
0
    cookie->rel = cookie->rels
340
0
      + sframe_decoder_get_func_reloc_index (sfd_info, i);
341
0
    keep = !(*reloc_symbol_deleted_p) (func_desc_offset, cookie);
342
343
0
    if (!keep)
344
0
      {
345
0
        sframe_decoder_mark_func_deleted (sfd_info, i);
346
0
        changed = true;
347
0
      }
348
0
  }
349
0
    }
350
0
  return changed;
351
0
}
352
353
/* Update the reference to the output .sframe section in the output ELF
354
   BFD ABFD.  Returns true if no error.  */
355
356
bool
357
_bfd_elf_set_section_sframe (bfd *abfd, struct bfd_link_info *info)
358
0
{
359
0
  asection *cfsec;
360
361
0
  cfsec = bfd_get_section_by_name (info->output_bfd, ".sframe");
362
0
  if (!cfsec)
363
0
    return false;
364
365
0
  elf_section_type (cfsec) = SHT_GNU_SFRAME;
366
0
  elf_sframe (abfd) = cfsec;
367
368
0
  return true;
369
0
}
370
371
/* Merge .sframe section SEC.  This is called with the relocated
372
   CONTENTS.  */
373
374
bool
375
_bfd_elf_merge_section_sframe (bfd *abfd,
376
             struct bfd_link_info *info,
377
             asection *sec,
378
             bfd_byte *contents)
379
0
{
380
0
  struct sframe_dec_info *sfd_info;
381
0
  struct sframe_enc_info *sfe_info;
382
0
  sframe_decoder_ctx *sfd_ctx;
383
0
  sframe_encoder_ctx *sfe_ctx;
384
0
  uint8_t sfd_ctx_abi_arch;
385
0
  int8_t sfd_ctx_fixed_fp_offset;
386
0
  int8_t sfd_ctx_fixed_ra_offset;
387
0
  uint8_t dctx_version;
388
0
  uint8_t ectx_version;
389
0
  uint8_t dctx_flags;
390
0
  uint8_t ectx_flags;
391
0
  int encerr = 0;
392
393
0
  struct elf_link_hash_table *htab;
394
0
  asection *cfsec;
395
396
  /* Sanity check - handle SFrame sections only.  */
397
0
  if (sec->sec_info_type != SEC_INFO_TYPE_SFRAME)
398
0
    return false;
399
400
0
  sfd_info = sec->sec_info;
401
0
  sfd_ctx = sfd_info->sfd_ctx;
402
403
0
  htab = elf_hash_table (info);
404
0
  sfe_info = &(htab->sfe_info);
405
0
  sfe_ctx = sfe_info->sfe_ctx;
406
407
  /* All input bfds are expected to have a valid SFrame section.  Even if
408
     the SFrame section is empty with only a header, there must be a valid
409
     SFrame decoder context by now.  The SFrame encoder context, however,
410
     will get set later here, if this is the first call to the function.  */
411
0
  if (sfd_ctx == NULL || sfe_info == NULL)
412
0
    return false;
413
414
0
  dctx_flags = sframe_decoder_get_flags (sfd_ctx);
415
416
0
  if (htab->sfe_info.sfe_ctx == NULL)
417
0
    {
418
0
      sfd_ctx_abi_arch = sframe_decoder_get_abi_arch (sfd_ctx);
419
0
      sfd_ctx_fixed_fp_offset = sframe_decoder_get_fixed_fp_offset (sfd_ctx);
420
0
      sfd_ctx_fixed_ra_offset = sframe_decoder_get_fixed_ra_offset (sfd_ctx);
421
422
      /* Valid values are non-zero.  */
423
0
      if (!sfd_ctx_abi_arch)
424
0
  return false;
425
426
      /* In-memory FDEs in the encoder object are unsorted during linking and
427
   will be sorted before emission.  Reset SFRAME_F_FDE_SORTED to aptly
428
   reflect that (doing so has no other functional value at this time
429
   though).  */
430
0
      uint8_t tflags = dctx_flags & ~SFRAME_F_FDE_SORTED;
431
      /* ld always generates an output section with
432
   SFRAME_F_FDE_FUNC_START_PCREL flag set.  Later using
433
   SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS, it is enforced that the provided
434
   input sections also have this flag set.  */
435
0
      tflags |= SFRAME_F_FDE_FUNC_START_PCREL;
436
0
      htab->sfe_info.sfe_ctx = sframe_encode (SFRAME_VERSION_3,
437
0
                tflags, /* SFrame flags.  */
438
0
                sfd_ctx_abi_arch,
439
0
                sfd_ctx_fixed_fp_offset,
440
0
                sfd_ctx_fixed_ra_offset,
441
0
                &encerr);
442
      /* Handle errors from sframe_encode.  */
443
0
      if (htab->sfe_info.sfe_ctx == NULL)
444
0
  return false;
445
0
    }
446
0
  sfe_ctx = sfe_info->sfe_ctx;
447
448
0
  if (sfe_info->sframe_section == NULL)
449
0
    {
450
      /* Make sure things are set for an eventual write.
451
   Size of the output section is not known until
452
   _bfd_elf_write_section_sframe is ready with the buffer
453
   to write out.  */
454
0
      cfsec = bfd_get_section_by_name (info->output_bfd, ".sframe");
455
0
      if (cfsec)
456
0
  {
457
0
    sfe_info->sframe_section = cfsec;
458
    // elf_sframe (abfd) = cfsec;
459
0
  }
460
0
      else
461
0
  return false;
462
0
    }
463
464
  /* Check that all .sframe sections being linked have the same
465
     ABI/arch.  */
466
0
  if (sframe_decoder_get_abi_arch (sfd_ctx)
467
0
      != sframe_encoder_get_abi_arch (sfe_ctx))
468
0
    {
469
0
      _bfd_error_handler
470
0
  (_("error in %pB (%pA); unexpected ABI in SFrame section"),
471
0
   sec->owner, sec);
472
0
      return false;
473
0
    }
474
475
  /* Check that all .sframe sections being linked have the same version.  */
476
0
  dctx_version = sframe_decoder_get_version (sfd_ctx);
477
0
  ectx_version = sframe_encoder_get_version (sfe_ctx);
478
0
  if (dctx_version != SFRAME_VERSION_3 || dctx_version != ectx_version)
479
0
    {
480
0
      _bfd_error_handler
481
0
  (_("error in %pB (%pA); unexpected SFrame format version %" PRIu8),
482
0
   sec->owner, sec, dctx_version);
483
0
      return false;
484
0
    }
485
486
  /* Check that all SFrame sections being linked have the 'data encoding'
487
     related flags set.  The implementation does not support updating these
488
     data encodings on the fly; confirm by checking the ectx_flags.  */
489
0
  ectx_flags = sframe_encoder_get_flags (sfe_ctx);
490
0
  if ((dctx_flags & ectx_flags & SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS)
491
0
      != SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS)
492
0
    {
493
0
      _bfd_error_handler
494
0
  (_("error in %pB (%pA); unexpected SFrame data encoding"),
495
0
   sec->owner, sec);
496
0
      return false;
497
0
    }
498
499
  /* Iterate over the function descriptor entries and the FREs of the
500
     function from the decoder context.  Add each of them to the encoder
501
     context, if suitable.  */
502
0
  uint32_t i = 0, cur_fidx = 0;
503
504
0
  uint32_t num_fidx = sframe_decoder_get_num_fidx (sfd_ctx);
505
0
  uint32_t num_enc_fidx = sframe_encoder_get_num_fidx (sfe_ctx);
506
0
  uint8_t reloc_size = 8;
507
508
0
  for (i = 0; i < num_fidx; i++)
509
0
    {
510
0
      unsigned int num_fres = 0;
511
0
      int64_t func_start_addr;
512
0
      bfd_vma address;
513
0
      uint32_t func_size = 0;
514
0
      unsigned int r_offset = 0;
515
0
      bool pltn_reloc_by_hand = false;
516
0
      unsigned int pltn_r_offset = 0;
517
518
0
      if (!sframe_decoder_get_funcdesc_v3 (sfd_ctx, i, &num_fres, &func_size,
519
0
             &func_start_addr, NULL, NULL, NULL))
520
0
  {
521
    /* If function belongs to a deleted section, skip editing the
522
       function descriptor entry.  */
523
0
    if (sframe_decoder_func_deleted_p(sfd_info, i))
524
0
      continue;
525
526
    /* Don't edit function descriptor entries for relocatable link.  */
527
0
    if (!bfd_link_relocatable (info))
528
0
      {
529
0
        if (!(sec->flags & SEC_LINKER_CREATED))
530
0
    {
531
      /* Get relocated contents by reading the value of the
532
         relocated function start address at the beginning of the
533
         function descriptor entry.  */
534
0
      r_offset = sframe_decoder_get_func_r_offset (sfd_info, i);
535
0
    }
536
0
        else
537
0
    {
538
      /* Expected to land here when SFrame stack trace info is
539
         created dynamically for the .plt* sections.  These
540
         sections are expected to have upto two SFrame FDE entries.
541
         Although the code should work for > 2,  leaving this
542
         assert here for safety.  */
543
0
      BFD_ASSERT (num_fidx <= 2);
544
      /* For the first entry, we know the offset of the SFrame FDE's
545
         sfde_func_start_address.  Side note: see how the value
546
         of PLT_SFRAME_FDE_START_OFFSET is also set to the
547
         same.  */
548
0
      r_offset = sframe_decoder_get_hdr_size (sfd_ctx);
549
      /* For any further SFrame FDEs, the generator has already put
550
         in an offset in place of sfde_func_start_address of the
551
         corresponding FDE.  We will use it by hand to relocate.  */
552
0
      if (i > 0)
553
0
        {
554
0
          pltn_r_offset
555
0
      = r_offset + (i * sizeof (sframe_func_desc_entry));
556
0
          pltn_reloc_by_hand = true;
557
0
        }
558
0
    }
559
560
        /* Get the SFrame FDE function start address after relocation.  */
561
0
        address = sframe_read_value (abfd, contents, r_offset,
562
0
             reloc_size);
563
0
        if (pltn_reloc_by_hand)
564
0
    address += sframe_read_value (abfd, contents, pltn_r_offset,
565
0
                reloc_size);
566
0
        address += (sec->output_offset + r_offset);
567
        /* SFrame FDE function start address is an offset from the
568
     sfde_func_start_address field to the start PC.  The
569
     calculation below is the distance of sfde_func_start_address
570
     field from the start of the output SFrame section.  */
571
0
        uint32_t offsetof_fde_in_sec
572
0
    = sframe_encoder_get_offsetof_fde_start_addr (sfe_ctx,
573
0
                    cur_fidx + num_enc_fidx,
574
0
                    NULL);
575
0
        address -= offsetof_fde_in_sec;
576
577
        /* FIXME For testing only. Cleanup later.  */
578
        // address += (sec->output_section->vma);
579
580
0
        func_start_addr = address;
581
0
      }
582
583
    /* Update the encoder context with FDE index entry.  */
584
0
    int err = sframe_encoder_add_funcdesc (sfe_ctx, func_start_addr,
585
0
             func_size);
586
0
    cur_fidx++;
587
0
    BFD_ASSERT (!err);
588
0
  }
589
590
0
      uint32_t fde_num_fres = 0;
591
0
      char *fres_buf = NULL;
592
0
      size_t fres_buf_size = 0;
593
594
0
      int err = sframe_decoder_get_fres_buf (sfd_ctx, i, &fres_buf,
595
0
               &fres_buf_size, &fde_num_fres);
596
0
      BFD_ASSERT (!err && fde_num_fres == num_fres);
597
0
      err = sframe_encoder_add_fres_buf (sfe_ctx, cur_fidx - 1 + num_enc_fidx,
598
0
           num_fres, fres_buf, fres_buf_size);
599
0
      BFD_ASSERT (!err);
600
0
    }
601
602
0
  sfd_info->sfd_state = SFRAME_SEC_MERGED;
603
  /* Free the SFrame decoder context.  */
604
0
  sframe_decoder_free (&sfd_info->sfd_ctx);
605
606
0
  return true;
607
0
}
608
609
/* Adjust an address in the .sframe section.  Given OFFSET within
610
   SEC, this returns the new offset in the merged .sframe section,
611
   or -1 if the address refers to an FDE which has been removed.
612
613
   PS: This function assumes that _bfd_elf_merge_section_sframe has
614
   not been called on the input section SEC yet.  Note how it uses
615
   sframe_encoder_get_num_fidx () to figure out the offset of FDE
616
   in the output section.  */
617
618
bfd_vma
619
_bfd_elf_sframe_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
620
        struct bfd_link_info *info,
621
        asection *sec,
622
        bfd_vma offset)
623
0
{
624
0
  struct sframe_dec_info *sfd_info;
625
0
  struct sframe_enc_info *sfe_info;
626
0
  sframe_decoder_ctx *sfd_ctx;
627
0
  sframe_encoder_ctx *sfe_ctx;
628
0
  struct elf_link_hash_table *htab;
629
630
0
  unsigned int sec_fde_idx, out_num_fdes;
631
0
  unsigned int sfd_num_fdes, sfe_num_fdes;
632
0
  uint32_t sfd_fde_offset;
633
0
  bfd_vma new_offset;
634
635
0
  if (sec->sec_info_type != SEC_INFO_TYPE_SFRAME)
636
0
    return offset;
637
638
0
  sfd_info = sec->sec_info;
639
0
  sfd_ctx = sfd_info->sfd_ctx;
640
0
  sfd_num_fdes = sframe_decoder_get_num_fidx (sfd_ctx);
641
642
0
  BFD_ASSERT (sfd_info->sfd_state == SFRAME_SEC_DECODED);
643
644
0
  htab = elf_hash_table (info);
645
0
  sfe_info = &(htab->sfe_info);
646
0
  sfe_ctx = sfe_info->sfe_ctx;
647
0
  sfe_num_fdes = sframe_encoder_get_num_fidx (sfe_ctx);
648
649
  /* The index of this FDE in the output section depends on number of deleted
650
     functions (between index 0 and sec_fde_idx), if any.  */
651
0
  out_num_fdes = 0;
652
0
  sec_fde_idx = 0;
653
0
  for (unsigned int i = 0; i < sfd_num_fdes; i++)
654
0
    {
655
0
      sfd_fde_offset = sframe_decoder_get_offsetof_fde_start_addr (sfd_ctx,
656
0
                   i, NULL);
657
0
      if (!sframe_decoder_func_deleted_p (sfd_info, i))
658
0
  out_num_fdes++;
659
660
0
      if (sfd_fde_offset == offset)
661
0
  {
662
    /* Found the index of the FDE (at OFFSET) in the input section.  */
663
0
    sec_fde_idx = i;
664
0
    break;
665
0
  }
666
0
    }
667
668
0
  if (sframe_decoder_func_deleted_p (sfd_info, sec_fde_idx))
669
0
    return (bfd_vma) -1;
670
671
  /* The number of FDEs in the output SFrame section.  Note that the output
672
     index of the FDE of interest will be (out_num_fdes - 1).  */
673
0
  out_num_fdes += sfe_num_fdes;
674
675
0
  new_offset = sframe_decoder_get_offsetof_fde_start_addr (sfd_ctx,
676
0
                 out_num_fdes - 1,
677
0
                 NULL);
678
  /* Recall that SFrame section merging has distinct requirements: All SFrame
679
     FDEs from input sections are clubbed together in the beginning of the
680
     output section.  So, at this point in the current function, the new_offset
681
     is the correct offset in the merged output SFrame section.  Note, however,
682
     that the default mechanism in the _elf_link_input_bfd will do the
683
     following adjustment:
684
       irela->r_offset += o->output_offset;
685
     for all section types.  However, such an adjustment in the RELA offset is
686
     _not_ needed for SFrame sections.  Perform the reverse adjustment here so
687
     that the default mechanism does not need additional SFrame specific
688
     checks.  */
689
0
  new_offset -= sec->output_offset;
690
691
0
  return new_offset;
692
0
}
693
694
/* Write out the .sframe section.  This must be called after
695
   _bfd_elf_merge_section_sframe has been called on all input
696
   .sframe sections.  */
697
698
bool
699
_bfd_elf_write_section_sframe (bfd *abfd, struct bfd_link_info *info)
700
0
{
701
0
  bool retval = true;
702
703
0
  struct elf_link_hash_table *htab;
704
0
  struct sframe_enc_info *sfe_info;
705
0
  sframe_encoder_ctx *sfe_ctx;
706
0
  asection *sec;
707
0
  void *contents;
708
0
  size_t sec_size;
709
0
  int err = 0;
710
711
0
  htab = elf_hash_table (info);
712
0
  sfe_info = &htab->sfe_info;
713
0
  sec = sfe_info->sframe_section;
714
0
  sfe_ctx = sfe_info->sfe_ctx;
715
716
0
  if (sec == NULL)
717
0
    return true;
718
719
0
  bool sort_p = !bfd_link_relocatable (info);
720
0
  contents = sframe_encoder_write (sfe_ctx, &sec_size, sort_p, &err);
721
0
  sec->size = (bfd_size_type) sec_size;
722
723
0
  if (!bfd_set_section_contents (abfd, sec->output_section, contents,
724
0
         (file_ptr) sec->output_offset,
725
0
         sec->size))
726
0
    retval = false;
727
0
  else
728
0
    {
729
0
      Elf_Internal_Shdr *hdr = &elf_section_data (sec)->this_hdr;
730
0
      hdr->sh_size = sec->size;
731
0
    }
732
733
0
  sframe_encoder_free (&sfe_info->sfe_ctx);
734
735
0
  return retval;
736
0
}