diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 4330bbd1648..abbebbe92b4 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -906,6 +906,14 @@ static const sframe_frame_row_entry elf_x86_64_sframe_pltn_fre2 = 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 = { @@ -930,7 +938,7 @@ static const struct elf_x86_sframe_plt elf_x86_64_sframe_non_lazy_plt = { &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, @@ -942,9 +950,25 @@ static const struct elf_x86_sframe_plt elf_x86_64_sframe_plt = /* 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 } }; @@ -5678,7 +5702,7 @@ elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info) { 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 diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index 0d83ce57d4f..cb90f688b6f 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -1831,7 +1831,6 @@ _bfd_x86_elf_create_sframe_plt (bfd *output_bfd, 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; @@ -1845,14 +1844,11 @@ _bfd_x86_elf_create_sframe_plt (bfd *output_bfd, 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: @@ -1860,7 +1856,10 @@ _bfd_x86_elf_create_sframe_plt (bfd *output_bfd, 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; @@ -1870,12 +1869,15 @@ _bfd_x86_elf_create_sframe_plt (bfd *output_bfd, 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: @@ -1897,7 +1899,7 @@ _bfd_x86_elf_create_sframe_plt (bfd *output_bfd, /* 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. */ @@ -1934,16 +1936,17 @@ _bfd_x86_elf_create_sframe_plt (bfd *output_bfd, 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); } } diff --git a/ld/testsuite/ld-x86-64/sframe-ibt-plt-1.d b/ld/testsuite/ld-x86-64/sframe-ibt-plt-1.d new file mode 100644 index 00000000000..26be4dfc6a0 --- /dev/null +++ b/ld/testsuite/ld-x86-64/sframe-ibt-plt-1.d @@ -0,0 +1,33 @@ +#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 + + +#... diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 2a1657da6c7..b0406efbe46 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -548,6 +548,7 @@ run_dump_test "pr32191-x32" 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*"] {