SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */
};
+/* .sframe FRE covering the .plt section entry for IBT. */
+static const sframe_frame_row_entry elf_x86_64_sframe_ibt_pltn_fre2 =
+{
+ 9, /* SFrame FRE start address. */
+ {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
+ SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */
+};
+
/* .sframe FRE covering the second .plt section entry. */
static const sframe_frame_row_entry elf_x86_64_sframe_sec_pltn_fre1 =
{
{ &elf_x86_64_sframe_null_fre }
};
-/* SFrame helper object for lazy PLT. Also used for IBT enabled PLT. */
+/* SFrame helper object for lazy PLT. */
static const struct elf_x86_sframe_plt elf_x86_64_sframe_plt =
{
LAZY_PLT_ENTRY_SIZE,
/* Array of SFrame FREs for plt. */
{ &elf_x86_64_sframe_pltn_fre1, &elf_x86_64_sframe_pltn_fre2 },
NON_LAZY_PLT_ENTRY_SIZE,
- 1, /* Number of FREs for PLTn for second PLT. */
- /* FREs for second plt (stack trace info for .plt.got is
- identical). Used when IBT or non-lazy PLT is in effect. */
+ 1, /* Number of FREs for second PLT. */
+ /* Array of SFrame FREs for second PLT. */
+ { &elf_x86_64_sframe_sec_pltn_fre1 }
+};
+
+/* SFrame helper object for lazy PLT with IBT. */
+static const struct elf_x86_sframe_plt elf_x86_64_sframe_ibt_plt =
+{
+ LAZY_PLT_ENTRY_SIZE,
+ 2, /* Number of FREs for PLT0. */
+ /* Array of SFrame FREs for plt0. */
+ { &elf_x86_64_sframe_plt0_fre1, &elf_x86_64_sframe_plt0_fre2 },
+ LAZY_PLT_ENTRY_SIZE,
+ 2, /* Number of FREs for PLTn. */
+ /* Array of SFrame FREs for plt. */
+ { &elf_x86_64_sframe_pltn_fre1, &elf_x86_64_sframe_ibt_pltn_fre2 },
+ LAZY_PLT_ENTRY_SIZE,
+ 1, /* Number of FREs for second PLT. */
+ /* Array of SFrame FREs for second plt. */
{ &elf_x86_64_sframe_sec_pltn_fre1 }
};
{
init_table.sframe_lazy_plt = &elf_x86_64_sframe_plt;
init_table.sframe_non_lazy_plt = &elf_x86_64_sframe_non_lazy_plt;
- init_table.sframe_lazy_ibt_plt = &elf_x86_64_sframe_plt;
+ init_table.sframe_lazy_ibt_plt = &elf_x86_64_sframe_ibt_plt;
init_table.sframe_non_lazy_ibt_plt = &elf_x86_64_sframe_non_lazy_plt;
}
else
struct elf_x86_link_hash_table *htab;
const struct elf_backend_data *bed;
- bool plt0_generated_p;
unsigned int plt0_entry_size;
unsigned char func_info;
uint32_t fre_type;
unsigned plt_entry_size = 0;
unsigned int num_pltn_fres = 0;
unsigned int num_pltn_entries = 0;
+ const sframe_frame_row_entry * const *pltn_fres;
bed = get_elf_backend_data (output_bfd);
htab = elf_x86_hash_table (info, bed->target_id);
/* Whether SFrame stack trace info for plt0 is to be generated. */
- plt0_generated_p = htab->plt.has_plt0;
- plt0_entry_size
- = (plt0_generated_p) ? htab->sframe_plt->plt0_entry_size : 0;
-
switch (plt_sec_type)
{
case SFRAME_PLT:
ectx = &htab->plt_cfe_ctx;
dpltsec = htab->elf.splt;
- plt_entry_size = htab->plt.plt_entry_size;
+ plt0_entry_size
+ = htab->plt.has_plt0 ? htab->sframe_plt->plt0_entry_size : 0;
+ plt_entry_size = htab->sframe_plt->pltn_entry_size;
+ pltn_fres = htab->sframe_plt->pltn_fres;
num_pltn_fres = htab->sframe_plt->pltn_num_fres;
num_pltn_entries
= (dpltsec->size - plt0_entry_size) / plt_entry_size;
case SFRAME_PLT_SEC:
{
ectx = &htab->plt_second_cfe_ctx;
- /* FIXME - this or htab->plt_second_sframe ? */
- dpltsec = htab->plt_second_eh_frame;
+ dpltsec = htab->plt_second;
+
+ plt0_entry_size = 0;
plt_entry_size = htab->sframe_plt->sec_pltn_entry_size;
+ pltn_fres = htab->sframe_plt->sec_pltn_fres;
num_pltn_fres = htab->sframe_plt->sec_pltn_num_fres;
num_pltn_entries = dpltsec->size / plt_entry_size;
+
break;
}
default:
/* Add SFrame FDE and the associated FREs for plt0 if plt0 has been
generated. */
- if (plt0_generated_p)
+ if (plt0_entry_size)
{
/* Add SFrame FDE for plt0, the function start address is updated later
at _bfd_elf_merge_section_sframe time. */
plt0_entry_size, /* func start addr. */
dpltsec->size - plt0_entry_size,
func_info,
- 16,
+ plt_entry_size,
0 /* Num FREs. */);
sframe_frame_row_entry pltn_fre;
- /* Now add the FREs for pltn. Simply adding the two FREs suffices due
+ /* Now add the FREs for pltn. Simply adding the FREs suffices due
to the usage of SFRAME_FDE_TYPE_PCMASK above. */
for (unsigned int j = 0; j < num_pltn_fres; j++)
{
- pltn_fre = *(htab->sframe_plt->pltn_fres[j]);
- sframe_encoder_add_fre (*ectx, 1, &pltn_fre);
+ unsigned int func_idx = plt0_entry_size ? 1 : 0;
+ pltn_fre = *(pltn_fres[j]);
+ sframe_encoder_add_fre (*ectx, func_idx, &pltn_fre);
}
}
--- /dev/null
+#as: --gsframe
+#source: ibt-plt-3.s
+#objdump: --sframe=.sframe
+#ld: -shared -z ibtplt --no-rosegment
+#name: SFrame for IBT PLT .plt.sec
+
+.*: +file format .*
+
+Contents of the SFrame section .sframe:
+ Header :
+
+ Version: SFRAME_VERSION_2
+ Flags: SFRAME_F_FDE_SORTED
+ CFA fixed RA offset: \-8
+#...
+
+ Function Index :
+
+ func idx \[0\]: pc = 0x1000, size = 16 bytes
+ STARTPC +CFA +FP +RA +
+ 0+1000 +sp\+16 +u +f +
+ 0+1006 +sp\+24 +u +f +
+
+ func idx \[1\]: pc = 0x1010, size = 32 bytes
+ STARTPC\[m\] +CFA +FP +RA +
+ 0+0000 +sp\+8 +u +f +
+ 0+0009 +sp\+16 +u +f +
+
+ func idx \[2\]: pc = 0x1030, size = 32 bytes
+ STARTPC\[m\] +CFA +FP +RA +
+ 0+0000 +sp\+8 +u +f +
+
+#...
if { ![skip_sframe_tests] } {
run_dump_test "sframe-simple-1"
run_dump_test "sframe-plt-1"
+ run_dump_test "sframe-ibt-plt-1"
}
if ![istarget "x86_64-*-linux*"] {