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 { 37 if (func_idx < sfd_info->sfd_fde_count) 38 return sfd_info->sfd_func_bfdinfo[func_idx].func_deleted_p; 39 40 return false; 41 } 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 { 49 if (func_idx < sfd_info->sfd_fde_count) 50 sfd_info->sfd_func_bfdinfo[func_idx].func_deleted_p = true; 51 } 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 { 59 BFD_ASSERT (func_idx < sfd_info->sfd_fde_count); 60 unsigned int func_r_offset 61 = sfd_info->sfd_func_bfdinfo[func_idx].func_r_offset; 62 /* There must have been a reloc. */ 63 BFD_ASSERT (func_r_offset); 64 return func_r_offset; 65 } 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 { 74 if (func_idx < sfd_info->sfd_fde_count) 75 sfd_info->sfd_func_bfdinfo[func_idx].func_r_offset = r_offset; 76 } 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 { 84 BFD_ASSERT (func_idx < sfd_info->sfd_fde_count); 85 return sfd_info->sfd_func_bfdinfo[func_idx].func_reloc_index; 86 } 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 { 95 if (func_idx < sfd_info->sfd_fde_count) 96 sfd_info->sfd_func_bfdinfo[func_idx].func_reloc_index = reloc_index; 97 } 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 { 108 unsigned int fde_count; 109 unsigned int func_bfdinfo_size, i; 110 const Elf_Internal_Rela *rel; 111 112 fde_count = sframe_decoder_get_num_fidx (sfd_info->sfd_ctx); 113 sfd_info->sfd_fde_count = fde_count; 114 115 /* Allocate and clear the memory. */ 116 func_bfdinfo_size = (sizeof (struct sframe_func_bfdinfo)) * fde_count; 117 sfd_info->sfd_func_bfdinfo = bfd_zalloc (abfd, func_bfdinfo_size); 118 if (sfd_info->sfd_func_bfdinfo == NULL) 119 return false; 120 121 /* For linker generated .sframe sections, we have no relocs. Skip. */ 122 if ((sec->flags & SEC_LINKER_CREATED) && cookie->rels == NULL) 123 return true; 124 125 rel = cookie->rels; 126 unsigned int reloc_index = 0; 127 for (i = 0; i < fde_count; i++) 128 { 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 while (rel->r_info == 0) 133 { 134 reloc_index++; 135 rel++; 136 } 137 138 BFD_ASSERT (reloc_index < sec->reloc_count); 139 140 sframe_decoder_set_func_r_offset (sfd_info, i, rel->r_offset); 141 sframe_decoder_set_func_reloc_index (sfd_info, i, reloc_index); 142 143 reloc_index++; 144 rel++; 145 } 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 for (; rel < cookie->relend; rel++) 151 if (rel->r_info != 0) 152 break; 153 BFD_ASSERT (rel == cookie->relend); 154 155 return true; 156 } 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 { 164 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 BFD_ASSERT (width == 8); 168 /* FIXME endianness ?? */ 169 unsigned char *buf = contents + offset; 170 bfd_vma value = bfd_get_signed_64 (abfd, buf); 171 return value; 172 } 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 { 180 /* Find if any input file has an .sframe section. */ 181 for (bfd *pbfd = info->input_bfds; pbfd != NULL; pbfd = pbfd->link.next) 182 if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour 183 && bfd_count_sections (pbfd) != 0) 184 { 185 asection *sec = bfd_get_section_by_name (pbfd, ".sframe"); 186 if (sec != NULL) 187 return true; 188 } 189 return false; 190 } 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 { 199 asection *sframe = bfd_get_section_by_name (info->output_bfd, ".sframe"); 200 201 if (sframe == NULL) 202 return false; 203 204 /* Count only sections which have at least a single FDE. */ 205 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 if (sframe->size > sizeof (sframe_header)) 211 return true; 212 return false; 213 } 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 { 226 bfd_byte *sfbuf = NULL; 227 struct sframe_dec_info *sfd_info; 228 sframe_decoder_ctx *sfd_ctx; 229 bfd_size_type sf_size; 230 int decerr = 0; 231 232 if (info->discard_sframe) 233 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 if (elf_section_type (sec) != SHT_GNU_SFRAME) 240 { 241 _bfd_error_handler 242 (_("error in %pB(%pA); unexpected SFrame section type"), 243 abfd, sec); 244 return false; 245 } 246 247 if (sec->size == 0 248 || (sec->flags & SEC_HAS_CONTENTS) == 0) 249 { 250 /* This file does not contain .sframe information. */ 251 return false; 252 } 253 254 /* Check if this section was already parsed. */ 255 if (sec->sec_info_type == SEC_INFO_TYPE_SFRAME) 256 return true; 257 258 if (bfd_is_abs_section (sec->output_section)) 259 { 260 /* At least one of the sections is being discarded from the 261 link, so we should just ignore them. */ 262 return false; 263 } 264 265 /* Read the SFrame stack trace information from abfd. */ 266 if (!_bfd_elf_mmap_section_contents (abfd, sec, &sfbuf)) 267 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 sfd_info = bfd_zalloc (abfd, sizeof (*sfd_info)); 273 sf_size = sec->size; 274 275 sfd_info->sfd_ctx = sframe_decode ((const char*)sfbuf, sf_size, &decerr); 276 sfd_info->sfd_state = SFRAME_SEC_DECODED; 277 sfd_ctx = sfd_info->sfd_ctx; 278 if (!sfd_ctx) 279 /* Free'ing up any memory held by decoder context is done by 280 sframe_decode in case of error. */ 281 goto fail_no_free; 282 283 if (!sframe_decoder_init_func_bfdinfo (abfd, sec, sfd_info, cookie)) 284 { 285 sframe_decoder_free (&sfd_ctx); 286 goto fail_no_free; 287 } 288 289 sec->sec_info = sfd_info; 290 sec->sec_info_type = SEC_INFO_TYPE_SFRAME; 291 292 goto success; 293 294 fail_no_free: 295 _bfd_error_handler 296 (_("error in %pB(%pA); no .sframe will be created"), 297 abfd, sec); 298 return false; 299 success: 300 _bfd_elf_munmap_section_contents (sec, sfbuf); 301 return true; 302 } 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 { 316 bool changed; 317 bool keep; 318 unsigned int i; 319 unsigned int func_desc_offset; 320 unsigned int num_fidx; 321 struct sframe_dec_info *sfd_info; 322 323 changed = false; 324 /* FIXME - if relocatable link and changed = true, how does the final 325 .rela.sframe get updated ?. */ 326 keep = false; 327 328 sfd_info = sec->sec_info; 329 330 /* Skip checking for the linker created .sframe sections 331 (for PLT sections). */ 332 if ((sec->flags & SEC_LINKER_CREATED) == 0 || cookie->rels != NULL) 333 { 334 num_fidx = sframe_decoder_get_num_fidx (sfd_info->sfd_ctx); 335 for (i = 0; i < num_fidx; i++) 336 { 337 func_desc_offset = sframe_decoder_get_func_r_offset (sfd_info, i); 338 339 cookie->rel = cookie->rels 340 + sframe_decoder_get_func_reloc_index (sfd_info, i); 341 keep = !(*reloc_symbol_deleted_p) (func_desc_offset, cookie); 342 343 if (!keep) 344 { 345 sframe_decoder_mark_func_deleted (sfd_info, i); 346 changed = true; 347 } 348 } 349 } 350 return changed; 351 } 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 { 359 asection *cfsec; 360 361 cfsec = bfd_get_section_by_name (info->output_bfd, ".sframe"); 362 if (!cfsec) 363 return false; 364 365 elf_section_type (cfsec) = SHT_GNU_SFRAME; 366 elf_sframe (abfd) = cfsec; 367 368 return true; 369 } 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 { 380 struct sframe_dec_info *sfd_info; 381 struct sframe_enc_info *sfe_info; 382 sframe_decoder_ctx *sfd_ctx; 383 sframe_encoder_ctx *sfe_ctx; 384 uint8_t sfd_ctx_abi_arch; 385 int8_t sfd_ctx_fixed_fp_offset; 386 int8_t sfd_ctx_fixed_ra_offset; 387 uint8_t dctx_version; 388 uint8_t ectx_version; 389 uint8_t dctx_flags; 390 uint8_t ectx_flags; 391 int encerr = 0; 392 393 struct elf_link_hash_table *htab; 394 asection *cfsec; 395 396 /* Sanity check - handle SFrame sections only. */ 397 if (sec->sec_info_type != SEC_INFO_TYPE_SFRAME) 398 return false; 399 400 sfd_info = sec->sec_info; 401 sfd_ctx = sfd_info->sfd_ctx; 402 403 htab = elf_hash_table (info); 404 sfe_info = &(htab->sfe_info); 405 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 if (sfd_ctx == NULL || sfe_info == NULL) 412 return false; 413 414 dctx_flags = sframe_decoder_get_flags (sfd_ctx); 415 416 if (htab->sfe_info.sfe_ctx == NULL) 417 { 418 sfd_ctx_abi_arch = sframe_decoder_get_abi_arch (sfd_ctx); 419 sfd_ctx_fixed_fp_offset = sframe_decoder_get_fixed_fp_offset (sfd_ctx); 420 sfd_ctx_fixed_ra_offset = sframe_decoder_get_fixed_ra_offset (sfd_ctx); 421 422 /* Valid values are non-zero. */ 423 if (!sfd_ctx_abi_arch) 424 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 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 tflags |= SFRAME_F_FDE_FUNC_START_PCREL; 436 htab->sfe_info.sfe_ctx = sframe_encode (SFRAME_VERSION_3, 437 tflags, /* SFrame flags. */ 438 sfd_ctx_abi_arch, 439 sfd_ctx_fixed_fp_offset, 440 sfd_ctx_fixed_ra_offset, 441 &encerr); 442 /* Handle errors from sframe_encode. */ 443 if (htab->sfe_info.sfe_ctx == NULL) 444 return false; 445 } 446 sfe_ctx = sfe_info->sfe_ctx; 447 448 if (sfe_info->sframe_section == NULL) 449 { 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 cfsec = bfd_get_section_by_name (info->output_bfd, ".sframe"); 455 if (cfsec) 456 { 457 sfe_info->sframe_section = cfsec; 458 // elf_sframe (abfd) = cfsec; 459 } 460 else 461 return false; 462 } 463 464 /* Check that all .sframe sections being linked have the same 465 ABI/arch. */ 466 if (sframe_decoder_get_abi_arch (sfd_ctx) 467 != sframe_encoder_get_abi_arch (sfe_ctx)) 468 { 469 _bfd_error_handler 470 (_("error in %pB (%pA); unexpected ABI in SFrame section"), 471 sec->owner, sec); 472 return false; 473 } 474 475 /* Check that all .sframe sections being linked have the same version. */ 476 dctx_version = sframe_decoder_get_version (sfd_ctx); 477 ectx_version = sframe_encoder_get_version (sfe_ctx); 478 if (dctx_version != SFRAME_VERSION_3 || dctx_version != ectx_version) 479 { 480 _bfd_error_handler 481 (_("error in %pB (%pA); unexpected SFrame format version %" PRIu8), 482 sec->owner, sec, dctx_version); 483 return false; 484 } 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 ectx_flags = sframe_encoder_get_flags (sfe_ctx); 490 if ((dctx_flags & ectx_flags & SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS) 491 != SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS) 492 { 493 _bfd_error_handler 494 (_("error in %pB (%pA); unexpected SFrame data encoding"), 495 sec->owner, sec); 496 return false; 497 } 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 uint32_t i = 0, cur_fidx = 0; 503 504 uint32_t num_fidx = sframe_decoder_get_num_fidx (sfd_ctx); 505 uint32_t num_enc_fidx = sframe_encoder_get_num_fidx (sfe_ctx); 506 uint8_t reloc_size = 8; 507 508 for (i = 0; i < num_fidx; i++) 509 { 510 unsigned int num_fres = 0; 511 int64_t func_start_addr; 512 bfd_vma address; 513 uint32_t func_size = 0; 514 unsigned int r_offset = 0; 515 bool pltn_reloc_by_hand = false; 516 unsigned int pltn_r_offset = 0; 517 518 if (!sframe_decoder_get_funcdesc_v3 (sfd_ctx, i, &num_fres, &func_size, 519 &func_start_addr, NULL, NULL, NULL)) 520 { 521 /* If function belongs to a deleted section, skip editing the 522 function descriptor entry. */ 523 if (sframe_decoder_func_deleted_p(sfd_info, i)) 524 continue; 525 526 /* Don't edit function descriptor entries for relocatable link. */ 527 if (!bfd_link_relocatable (info)) 528 { 529 if (!(sec->flags & SEC_LINKER_CREATED)) 530 { 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 r_offset = sframe_decoder_get_func_r_offset (sfd_info, i); 535 } 536 else 537 { 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 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 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 if (i > 0) 553 { 554 pltn_r_offset 555 = r_offset + (i * sizeof (sframe_func_desc_entry)); 556 pltn_reloc_by_hand = true; 557 } 558 } 559 560 /* Get the SFrame FDE function start address after relocation. */ 561 address = sframe_read_value (abfd, contents, r_offset, 562 reloc_size); 563 if (pltn_reloc_by_hand) 564 address += sframe_read_value (abfd, contents, pltn_r_offset, 565 reloc_size); 566 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 uint32_t offsetof_fde_in_sec 572 = sframe_encoder_get_offsetof_fde_start_addr (sfe_ctx, 573 cur_fidx + num_enc_fidx, 574 NULL); 575 address -= offsetof_fde_in_sec; 576 577 /* FIXME For testing only. Cleanup later. */ 578 // address += (sec->output_section->vma); 579 580 func_start_addr = address; 581 } 582 583 /* Update the encoder context with FDE index entry. */ 584 int err = sframe_encoder_add_funcdesc (sfe_ctx, func_start_addr, 585 func_size); 586 cur_fidx++; 587 BFD_ASSERT (!err); 588 } 589 590 uint32_t fde_num_fres = 0; 591 char *fres_buf = NULL; 592 size_t fres_buf_size = 0; 593 594 int err = sframe_decoder_get_fres_buf (sfd_ctx, i, &fres_buf, 595 &fres_buf_size, &fde_num_fres); 596 BFD_ASSERT (!err && fde_num_fres == num_fres); 597 err = sframe_encoder_add_fres_buf (sfe_ctx, cur_fidx - 1 + num_enc_fidx, 598 num_fres, fres_buf, fres_buf_size); 599 BFD_ASSERT (!err); 600 } 601 602 sfd_info->sfd_state = SFRAME_SEC_MERGED; 603 /* Free the SFrame decoder context. */ 604 sframe_decoder_free (&sfd_ctx); 605 606 return true; 607 } 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 { 624 struct sframe_dec_info *sfd_info; 625 struct sframe_enc_info *sfe_info; 626 sframe_decoder_ctx *sfd_ctx; 627 sframe_encoder_ctx *sfe_ctx; 628 struct elf_link_hash_table *htab; 629 630 unsigned int sec_fde_idx, out_num_fdes; 631 unsigned int sfd_num_fdes, sfe_num_fdes; 632 uint32_t sfd_fde_offset; 633 bfd_vma new_offset; 634 635 if (sec->sec_info_type != SEC_INFO_TYPE_SFRAME) 636 return offset; 637 638 sfd_info = sec->sec_info; 639 sfd_ctx = sfd_info->sfd_ctx; 640 sfd_num_fdes = sframe_decoder_get_num_fidx (sfd_ctx); 641 642 BFD_ASSERT (sfd_info->sfd_state == SFRAME_SEC_DECODED); 643 644 htab = elf_hash_table (info); 645 sfe_info = &(htab->sfe_info); 646 sfe_ctx = sfe_info->sfe_ctx; 647 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 out_num_fdes = 0; 652 sec_fde_idx = 0; 653 for (unsigned int i = 0; i < sfd_num_fdes; i++) 654 { 655 sfd_fde_offset = sframe_decoder_get_offsetof_fde_start_addr (sfd_ctx, 656 i, NULL); 657 if (!sframe_decoder_func_deleted_p (sfd_info, i)) 658 out_num_fdes++; 659 660 if (sfd_fde_offset == offset) 661 { 662 /* Found the index of the FDE (at OFFSET) in the input section. */ 663 sec_fde_idx = i; 664 break; 665 } 666 } 667 668 if (sframe_decoder_func_deleted_p (sfd_info, sec_fde_idx)) 669 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 out_num_fdes += sfe_num_fdes; 674 675 new_offset = sframe_decoder_get_offsetof_fde_start_addr (sfd_ctx, 676 out_num_fdes - 1, 677 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 new_offset -= sec->output_offset; 690 691 return new_offset; 692 } 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 { 701 bool retval = true; 702 703 struct elf_link_hash_table *htab; 704 struct sframe_enc_info *sfe_info; 705 sframe_encoder_ctx *sfe_ctx; 706 asection *sec; 707 void *contents; 708 size_t sec_size; 709 int err = 0; 710 711 htab = elf_hash_table (info); 712 sfe_info = &htab->sfe_info; 713 sec = sfe_info->sframe_section; 714 sfe_ctx = sfe_info->sfe_ctx; 715 716 if (sec == NULL) 717 return true; 718 719 bool sort_p = !bfd_link_relocatable (info); 720 contents = sframe_encoder_write (sfe_ctx, &sec_size, sort_p, &err); 721 sec->size = (bfd_size_type) sec_size; 722 723 if (!bfd_set_section_contents (abfd, sec->output_section, contents, 724 (file_ptr) sec->output_offset, 725 sec->size)) 726 retval = false; 727 else 728 { 729 Elf_Internal_Shdr *hdr = &elf_section_data (sec)->this_hdr; 730 hdr->sh_size = sec->size; 731 } 732 733 sframe_encoder_free (&sfe_ctx); 734 735 return retval; 736 } 737