(asection *, bool (*) (bfd_vma, void *), struct elf_reloc_cookie *);
extern bool _bfd_elf_merge_section_sframe
(bfd *, struct bfd_link_info *, asection *, bfd_byte *);
+extern bfd_vma _bfd_elf_sframe_section_offset
+ (bfd *, struct bfd_link_info *, asection *, bfd_vma);
extern bool _bfd_elf_write_section_sframe
(bfd *, struct bfd_link_info *);
extern bool _bfd_elf_set_section_sframe (bfd *, struct bfd_link_info *);
return true;
}
+/* Adjust an address in the .sframe section. Given OFFSET within
+ SEC, this returns the new offset in the merged .sframe section,
+ or -1 if the address refers to an FDE which has been removed.
+
+ PS: This function assumes that _bfd_elf_merge_section_sframe has not been
+ called on the input section SEC yet. */
+
+bfd_vma
+_bfd_elf_sframe_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info,
+ asection *sec,
+ bfd_vma offset)
+{
+ struct sframe_dec_info *sfd_info;
+ struct sframe_enc_info *sfe_info;
+ sframe_decoder_ctx *sfd_ctx;
+ sframe_encoder_ctx *sfe_ctx;
+ struct elf_link_hash_table *htab;
+
+ unsigned int sec_fde_idx, out_fde_idx = 0;
+ unsigned int i, sfe_num_fdes;
+
+ if (sec->sec_info_type != SEC_INFO_TYPE_SFRAME)
+ return offset;
+
+ sfd_info = (struct sframe_dec_info *) elf_section_data (sec)->sec_info;
+ sfd_ctx = sfd_info->sfd_ctx;
+
+ htab = elf_hash_table (info);
+ sfe_info = &(htab->sfe_info);
+ sfe_ctx = sfe_info->sfe_ctx;
+
+ sfe_num_fdes = sframe_encoder_get_num_fidx (sfe_ctx);
+ /* Identify the index of the FDE (at OFFSET) in the input section. */
+ sec_fde_idx = ((offset - sframe_decoder_get_hdr_size (sfd_ctx))
+ / sizeof (sframe_func_desc_entry));
+ /* The index of this FDE in the output section depends on number of deleted
+ functions, if any. */
+ for (i = 0; i < sec_fde_idx; i++)
+ {
+ if (!sframe_decoder_func_deleted_p (sfd_info, i))
+ out_fde_idx++;
+ }
+ /* The actual index of the FDE in the output SFrame section. */
+ out_fde_idx += sfe_num_fdes;
+
+ return (sframe_decoder_get_hdr_size (sfd_ctx)
+ + out_fde_idx * sizeof (sframe_func_desc_entry));
+}
+
/* Write out the .sframe section. This must be called after
_bfd_elf_merge_section_sframe has been called on all input
.sframe sections. */
case SEC_INFO_TYPE_EH_FRAME:
return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset);
+ case SEC_INFO_TYPE_SFRAME:
+ return _bfd_elf_sframe_section_offset (abfd, info, sec, offset);
+
default:
if ((sec->flags & SEC_ELF_REVERSE_COPY) != 0)
{
continue;
}
- irela->r_offset += o->output_offset;
+ if (o->sec_info_type != SEC_INFO_TYPE_SFRAME)
+ irela->r_offset += o->output_offset;
/* Relocs in an executable have to be virtual addresses. */
if (!bfd_link_relocatable (flinfo->info))
--- /dev/null
+#as: --gsframe
+#source: sframe-foo.s
+#source: sframe-bar.s
+#objdump: --sframe=.sframe
+#ld: -r --no-rosegment
+#name: SFrame simple link - relocatable
+
+.*: +file format .*
+
+Contents of the SFrame section .sframe:
+ Header :
+
+ Version: SFRAME_VERSION_2
+ Flags: SFRAME_F_FDE_SORTED
+ CFA fixed RA offset: \-8
+ Num FDEs: 2
+ Num FREs: 8
+
+ Function Index :
+
+
+ func idx \[0\]: pc = 0x0, size = 53 bytes
+ STARTPC +CFA +FP +RA +
+ 0+0000 +sp\+8 +u +f +
+ 0+0001 +sp\+16 +c-16 +f +
+ 0+0004 +fp\+16 +c-16 +f +
+ 0+0034 +sp\+8 +c-16 +f +
+
+ func idx \[1\]: pc = 0x35, size = 37 bytes
+ STARTPC +CFA +FP +RA +
+ 0+0035 +sp\+8 +u +f +
+ 0+0036 +sp\+16 +c-16 +f +
+ 0+0039 +fp\+16 +c-16 +f +
+ 0+0059 +sp\+8 +c-16 +f +
if { ![skip_sframe_tests] } {
run_dump_test "sframe-simple-1"
+ run_dump_test "sframe-reloc-1"
run_dump_test "sframe-plt-1"
run_dump_test "sframe-ibt-plt-1"
run_dump_test "sframe-pltgot-1"