unsigned int func_reloc_index;
};
+/* Link state information of the SFrame section. */
+enum sframe_sec_state
+{
+ SFRAME_SEC_DECODED = 1,
+ SFRAME_SEC_MERGED,
+};
+
/* SFrame decoder info.
Contains all information for a decoded .sframe section. */
struct sframe_dec_info
{
/* Decoder context. */
struct sframe_decoder_ctx *sfd_ctx;
+ /* SFrame section state as it progresses through the link process. */
+ enum sframe_sec_state sfd_state;
/* Number of function descriptor entries in this .sframe. */
unsigned int sfd_fde_count;
/* Additional information for linking. */
(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 *);
/* Decode the buffer and keep decoded contents for later use.
Relocations are performed later, but are such that the section's
size is unaffected. */
- sfd_info = bfd_alloc (abfd, sizeof (*sfd_info));
+ sfd_info = bfd_zalloc (abfd, sizeof (*sfd_info));
sf_size = sec->size;
sfd_info->sfd_ctx = sframe_decode ((const char*)sfbuf, sf_size, &decerr);
+ sfd_info->sfd_state = SFRAME_SEC_DECODED;
sfd_ctx = sfd_info->sfd_ctx;
if (!sfd_ctx)
/* Free'ing up any memory held by decoder context is done by
}
}
}
+ sfd_info->sfd_state = SFRAME_SEC_MERGED;
/* Free the SFrame decoder context. */
sframe_decoder_free (&sfd_ctx);
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. Note how it uses
+ sframe_encoder_get_num_fidx () to figure out the offset of FDE
+ in the output section. */
+
+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;
+ 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;
+
+ BFD_ASSERT (sfd_info->sfd_state == SFRAME_SEC_DECODED);
+
+ /* 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));
+
+ if (sframe_decoder_func_deleted_p (sfd_info, sec_fde_idx))
+ return (bfd_vma) -1;
+
+ 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);
+
+ /* The index of this FDE in the output section depends on number of deleted
+ functions (between index 0 and sec_fde_idx), if any. */
+ out_fde_idx = 0;
+ 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. */
--- /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 +