if (sec == NULL)
return true;
- contents = sframe_encoder_write (sfe_ctx, &sec_size, &err);
+ bool sort_p = !bfd_link_relocatable (info);
+ contents = sframe_encoder_write (sfe_ctx, &sec_size, sort_p, &err);
sec->size = (bfd_size_type) sec_size;
if (!bfd_set_section_contents (abfd, sec->output_section, contents,
BFD_ASSERT (ectx);
- void *contents = sframe_encoder_write (ectx, &sec_size, &err);
+ void *contents = sframe_encoder_write (ectx, &sec_size, false, &err);
sec->size = (bfd_size_type) sec_size;
sec->contents = (unsigned char *) bfd_zalloc (dynobj, sec->size);
BFD_ASSERT (ectx);
- void *contents = sframe_encoder_write (ectx, &sec_size, &err);
+ void *contents = sframe_encoder_write (ectx, &sec_size, false, &err);
sec->size = (bfd_size_type) sec_size;
sec->contents = (unsigned char *) bfd_zalloc (dynobj, sec->size);
uint32_t num_fres);
/* Serialize the contents of the encoder context ECTX and return the buffer.
- ENCODED_SIZE is updated to the size of the buffer.
- Sets ERRP if failure. */
+ Sort the SFrame FDEs on start PC if SORT_FDE_P is true. ENCODED_SIZE is
+ updated to the size of the buffer. Sets ERRP if failure. */
extern char *
-sframe_encoder_write (sframe_encoder_ctx *ectx,
- size_t *encoded_size, int *errp);
+sframe_encoder_write (sframe_encoder_ctx *ectx, size_t *encoded_size,
+ bool sort_fde_p, int *errp);
#ifdef __cplusplus
}
--- /dev/null
+#...
+Relocation section '.rela.sframe' at offset 0x[0-9a-f]+ contains 5 entries:
+ +Offset +Info +Type +Sym.* Value +Sym.* Name \+ Addend
+[0-9a-f ]+ R_.* +0+ .text.init \+ 0
+[0-9a-f ]+ R_.* +0+ .text \+ 0
+[0-9a-f ]+ R_.* +0+ .text.exit \+ 0
+[0-9a-f ]+ R_.* +0+ .text \+ [0-9a-f]+
+[0-9a-f ]+ R_.* +0+ .text \+ [0-9a-f]+
+#...
--- /dev/null
+#failif
+#...
+.*\(SFRAME_F_FDE_SORTED\).*
+#...
--- /dev/null
+static int a = 0;
+
+extern int bar(void);
+
+__attribute__((section((".text.init"))))
+int foo_init(void)
+{
+ return 10;
+}
+
+void foo (void)
+{
+ foo_init ();
+ a++;
+ bar ();
+}
+
+__attribute__((section((".text.exit"))))
+void foo_exit(void)
+{
+ foo ();
+}
--- /dev/null
+static int bar_var = 2;
+
+int bar(void)
+{
+ return 20;
+}
+
+void bar2(void)
+{
+ bar_var++;
+ bar ();
+}
check_pr33401
+# Run other compile and link tests.
+if { [check_compiler_available] } {
+ run_cc_link_tests [list \
+ [list \
+ "Build pr32789-1a.o pr32789-1b.o" \
+ "-r" \
+ "-Wa,--gsframe" \
+ { pr32789-1a.c pr32789-1b.c } \
+ {{readelf --sframe pr32789-1.sd}
+ {readelf -r pr32789-1.rd}} \
+ "pr32789-1.o" \
+ "c" \
+ ] \
+ ]
+}
+
if {[info exists old_lc_all]} {
set env(LC_ALL) $old_lc_all
} else {
Header :
Version: SFRAME_VERSION_2
- Flags: SFRAME_F_FDE_SORTED,
- SFRAME_F_FDE_FUNC_START_PCREL
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
CFA fixed RA offset: \-8
Num FDEs: 2
Num FREs: 8
sframe_encoder_add_fre;
sframe_encoder_add_funcdesc;
sframe_encoder_add_funcdesc_v2;
- sframe_encoder_write;
dump_sframe;
sframe_errmsg;
LIBSFRAME_2.1 {
global:
sframe_fre_get_ra_undefined_p;
+ sframe_encoder_write;
} LIBSFRAME_2.0;
}
/* Serialize the core contents of the SFrame section and write out to the
- output buffer held in the encoder context ECTX. Return SFRAME_ERR if
- failure. */
+ output buffer held in the encoder context ECTX. Sort the SFrame FDEs on
+ start PC if SORT_FDE_P is true. Return SFRAME_ERR if failure. */
static int
-sframe_encoder_write_sframe (sframe_encoder_ctx *ectx)
+sframe_encoder_write_sframe (sframe_encoder_ctx *ectx, bool sort_fde_p)
{
char *contents;
size_t buf_size;
sframe_assert ((size_t)(contents - ectx->sfe_data) == buf_size);
/* Sort the FDE table */
- sframe_sort_funcdesc (ectx);
+ if (sort_fde_p)
+ sframe_sort_funcdesc (ectx);
/* Sanity checks:
- the FDE section must have been sorted by now on the start address
- of each function. */
- if (!(sframe_encoder_get_flags (ectx) & SFRAME_F_FDE_SORTED)
+ of each function, if sorting was needed. */
+ if ((sort_fde_p != (sframe_encoder_get_flags (ectx) & SFRAME_F_FDE_SORTED))
|| (fd_info == NULL))
return sframe_set_errno (&err, SFRAME_ERR_FDE_INVAL);
}
/* Serialize the contents of the encoder context ECTX and return the buffer.
- ENCODED_SIZE is updated to the size of the buffer.
- Sets ERRP if failure. */
+ Sort the SFrame FDEs on start PC if SORT_FDE_P is true. ENCODED_SIZE is
+ updated to the size of the buffer. Sets ERRP if failure. */
char *
-sframe_encoder_write (sframe_encoder_ctx *ectx,
- size_t *encoded_size, int *errp)
+sframe_encoder_write (sframe_encoder_ctx *ectx, size_t *encoded_size,
+ bool sort_fde_p, int *errp)
{
sframe_header *ehp;
size_t hdrsize, fsz, fresz, bufsize;
foreign_endian = need_swapping (ehp->sfh_abi_arch);
/* Write out the FDE Index and the FRE table in the sfe_data. */
- if (sframe_encoder_write_sframe (ectx))
+ if (sframe_encoder_write_sframe (ectx, sort_fde_p))
return sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL);
/* Endian flip the contents if necessary. */