From fff53daefb7838b5718422c87946330e4a8288ce Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 10 Jan 2017 13:31:59 -0800 Subject: [PATCH] i386/x86-64: Add unwind info for .plt.got section When there are both PLT and GOT references to the same function symbol, linker combines GOTPLT and GOT slots into a single GOT slot and create an entry in .plt.got section for PLT access via the GOT slot. This patch adds unwind info for .plt.got section. bfd/ PR ld/20830 * elf32-i386.c (elf_i386_eh_frame_plt_got): New. (PLT_GOT_FDE_LENGTH): Likewise. (elf_i386_plt_layout): Add eh_frame_plt_got and eh_frame_plt_got_size. (elf_i386_plt): Updated. (elf_i386_link_hash_table): Add plt_got_eh_frame. (elf_i386_check_relocs): Create .eh_frame section for .plt.got. (elf_i386_size_dynamic_sections): Allocate and initialize .eh_frame section for .plt.got. (elf_i386_finish_dynamic_sections): Adjust .eh_frame section for .plt.got. (elf_i386_nacl_plt): Add FIXME for eh_frame_plt_got and eh_frame_plt_got_size. * elf64-x86-64.c (elf_x86_64_eh_frame_plt_got): New. (PLT_GOT_FDE_LENGTH): Likewise. (elf_x86_64_backend_data): Add eh_frame_plt_got and eh_frame_plt_got_size. (elf_x86_64_arch_bed): Updated. (elf_x86_64_bnd_arch_bed): Add FIXME for eh_frame_plt_got and eh_frame_plt_got_size. (elf_x86_64_nacl_arch_bed): Likewise. (elf_x86_64_link_hash_table): Add plt_got_eh_frame. (elf_x86_64_check_relocs): Create .eh_frame section for .plt.got. (elf_x86_64_size_dynamic_sections): Allocate and initialize .eh_frame section for .plt.got. (elf_x86_64_finish_dynamic_sections): Adjust .eh_frame section for .plt.got. ld/ PR ld/20830 * testsuite/ld-i386/i386.exp: Run pr20830. * testsuite/ld-x86-64/x86-64.exp: Likewise. * testsuite/ld-i386/pr20830.d: New file. * testsuite/ld-i386/pr20830.s: Likewise. * testsuite/ld-x86-64/pr20830.d: Likewise. * testsuite/ld-x86-64/pr20830.s: Likewise. --- bfd/ChangeLog | 31 ++++++++ bfd/elf32-i386.c | 116 +++++++++++++++++++++++++-- bfd/elf64-x86-64.c | 128 ++++++++++++++++++++++++++++-- ld/ChangeLog | 10 +++ ld/testsuite/ld-i386/i386.exp | 1 + ld/testsuite/ld-i386/pr20830.d | 60 ++++++++++++++ ld/testsuite/ld-i386/pr20830.s | 8 ++ ld/testsuite/ld-x86-64/pr20830.d | 71 +++++++++++++++++ ld/testsuite/ld-x86-64/pr20830.s | 8 ++ ld/testsuite/ld-x86-64/x86-64.exp | 1 + 10 files changed, 418 insertions(+), 16 deletions(-) create mode 100644 ld/testsuite/ld-i386/pr20830.d create mode 100644 ld/testsuite/ld-i386/pr20830.s create mode 100644 ld/testsuite/ld-x86-64/pr20830.d create mode 100644 ld/testsuite/ld-x86-64/pr20830.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 09121d2fceb..d6d340c7eb8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,34 @@ +2017-01-10 H.J. Lu + + PR ld/20830 + * elf32-i386.c (elf_i386_eh_frame_plt_got): New. + (PLT_GOT_FDE_LENGTH): Likewise. + (elf_i386_plt_layout): Add eh_frame_plt_got and + eh_frame_plt_got_size. + (elf_i386_plt): Updated. + (elf_i386_link_hash_table): Add plt_got_eh_frame. + (elf_i386_check_relocs): Create .eh_frame section for .plt.got. + (elf_i386_size_dynamic_sections): Allocate and initialize + .eh_frame section for .plt.got. + (elf_i386_finish_dynamic_sections): Adjust .eh_frame section for + .plt.got. + (elf_i386_nacl_plt): Add FIXME for eh_frame_plt_got and + eh_frame_plt_got_size. + * elf64-x86-64.c (elf_x86_64_eh_frame_plt_got): New. + (PLT_GOT_FDE_LENGTH): Likewise. + (elf_x86_64_backend_data): Add eh_frame_plt_got and + eh_frame_plt_got_size. + (elf_x86_64_arch_bed): Updated. + (elf_x86_64_bnd_arch_bed): Add FIXME for eh_frame_plt_got and + eh_frame_plt_got_size. + (elf_x86_64_nacl_arch_bed): Likewise. + (elf_x86_64_link_hash_table): Add plt_got_eh_frame. + (elf_x86_64_check_relocs): Create .eh_frame section for .plt.got. + (elf_x86_64_size_dynamic_sections): Allocate and initialize + .eh_frame section for .plt.got. + (elf_x86_64_finish_dynamic_sections): Adjust .eh_frame section + for .plt.got. + 2017-01-10 H.J. Lu * elf32-i386.c (elf_i386_size_dynamic_sections): Set diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index a2da987850f..982bae6ce11 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -648,6 +648,32 @@ static const bfd_byte elf_i386_eh_frame_plt[] = DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop }; +/* .eh_frame covering the .plt.got section. */ + +static const bfd_byte elf_i386_eh_frame_plt_got[] = +{ +#define PLT_GOT_FDE_LENGTH 16 + PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */ + 0, 0, 0, 0, /* CIE ID */ + 1, /* CIE version */ + 'z', 'R', 0, /* Augmentation string */ + 1, /* Code alignment factor */ + 0x7c, /* Data alignment factor */ + 8, /* Return address column */ + 1, /* Augmentation size */ + DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */ + DW_CFA_def_cfa, 4, 4, /* DW_CFA_def_cfa: r4 (esp) ofs 4 */ + DW_CFA_offset + 8, 1, /* DW_CFA_offset: r8 (eip) at cfa-4 */ + DW_CFA_nop, DW_CFA_nop, + + PLT_GOT_FDE_LENGTH, 0, 0, 0, /* FDE length */ + PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */ + 0, 0, 0, 0, /* the start of .plt.got goes here */ + 0, 0, 0, 0, /* .plt.got size goes here */ + 0, /* Augmentation size */ + DW_CFA_nop, DW_CFA_nop, DW_CFA_nop +}; + struct elf_i386_plt_layout { /* The first entry in an absolute procedure linkage table looks like this. */ @@ -679,6 +705,10 @@ struct elf_i386_plt_layout /* .eh_frame covering the .plt section. */ const bfd_byte *eh_frame_plt; unsigned int eh_frame_plt_size; + + /* .eh_frame covering the .plt.got section. */ + const bfd_byte *eh_frame_plt_got; + unsigned int eh_frame_plt_got_size; }; #define GET_PLT_ENTRY_SIZE(abfd) \ @@ -701,6 +731,8 @@ static const struct elf_i386_plt_layout elf_i386_plt = elf_i386_pic_plt_entry, /* pic_plt_entry */ elf_i386_eh_frame_plt, /* eh_frame_plt */ sizeof (elf_i386_eh_frame_plt), /* eh_frame_plt_size */ + elf_i386_eh_frame_plt_got, /* eh_frame_plt_got */ + sizeof (elf_i386_eh_frame_plt_got), /* eh_frame_plt_got_size */ }; @@ -850,6 +882,7 @@ struct elf_i386_link_hash_table asection *interp; asection *plt_eh_frame; asection *plt_got; + asection *plt_got_eh_frame; union { @@ -2347,6 +2380,24 @@ do_size: htab->plt_got, plt_got_align)) goto error_return; + + if (!info->no_ld_generated_unwind_info + && htab->plt_got_eh_frame == NULL + && get_elf_i386_backend_data (abfd)->plt->eh_frame_plt_got != NULL) + { + flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY + | SEC_HAS_CONTENTS | SEC_IN_MEMORY + | SEC_LINKER_CREATED); + htab->plt_got_eh_frame + = bfd_make_section_anyway_with_flags (htab->elf.dynobj, + ".eh_frame", + flags); + if (htab->plt_got_eh_frame == NULL + || !bfd_set_section_alignment (htab->elf.dynobj, + htab->plt_got_eh_frame, + 3)) + goto error_return; + } } if (r_type == R_386_GOT32X @@ -3379,14 +3430,22 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) htab->elf.sgotplt->size = 0; } - - if (htab->plt_eh_frame != NULL - && htab->elf.splt != NULL - && htab->elf.splt->size != 0 - && !bfd_is_abs_section (htab->elf.splt->output_section) - && _bfd_elf_eh_frame_present (info)) - htab->plt_eh_frame->size - = get_elf_i386_backend_data (output_bfd)->plt->eh_frame_plt_size; + if (_bfd_elf_eh_frame_present (info)) + { + if (htab->plt_eh_frame != NULL + && htab->elf.splt != NULL + && htab->elf.splt->size != 0 + && !bfd_is_abs_section (htab->elf.splt->output_section)) + htab->plt_eh_frame->size + = get_elf_i386_backend_data (output_bfd)->plt->eh_frame_plt_size; + + if (htab->plt_got_eh_frame != NULL + && htab->plt_got != NULL + && htab->plt_got->size != 0 + && !bfd_is_abs_section (htab->plt_got->output_section)) + htab->plt_got_eh_frame->size + = get_elf_i386_backend_data (output_bfd)->plt->eh_frame_plt_got_size; + } /* We now have determined the sizes of the various dynamic sections. Allocate memory for them. */ @@ -3415,6 +3474,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) || s == htab->elf.igotplt || s == htab->plt_got || s == htab->plt_eh_frame + || s == htab->plt_got_eh_frame || s == htab->elf.sdynbss || s == htab->elf.sdynrelro) { @@ -3476,6 +3536,17 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET); } + if (htab->plt_got_eh_frame != NULL + && htab->plt_got_eh_frame->contents != NULL) + { + memcpy (htab->plt_got_eh_frame->contents, + get_elf_i386_backend_data (output_bfd)->plt->eh_frame_plt_got, + htab->plt_got_eh_frame->size); + bfd_put_32 (dynobj, htab->plt_got->size, + (htab->plt_got_eh_frame->contents + + PLT_FDE_LEN_OFFSET)); + } + if (htab->elf.dynamic_sections_created) { /* Add some entries to the .dynamic section. We fill in the @@ -5885,6 +5956,33 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd, } } + /* Adjust .eh_frame for .plt.got section. */ + if (htab->plt_got_eh_frame != NULL + && htab->plt_got_eh_frame->contents != NULL) + { + if (htab->plt_got != NULL + && htab->plt_got->size != 0 + && (htab->plt_got->flags & SEC_EXCLUDE) == 0 + && htab->plt_got->output_section != NULL + && htab->plt_got_eh_frame->output_section != NULL) + { + bfd_vma plt_start = htab->plt_got->output_section->vma; + bfd_vma eh_frame_start = htab->plt_got_eh_frame->output_section->vma + + htab->plt_got_eh_frame->output_offset + + PLT_FDE_START_OFFSET; + bfd_put_signed_32 (dynobj, plt_start - eh_frame_start, + htab->plt_got_eh_frame->contents + + PLT_FDE_START_OFFSET); + } + if (htab->plt_got_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME) + { + if (! _bfd_elf_write_section_eh_frame (output_bfd, info, + htab->plt_got_eh_frame, + htab->plt_got_eh_frame->contents)) + return FALSE; + } + } + if (htab->elf.sgot && htab->elf.sgot->size > 0) elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4; @@ -6428,6 +6526,8 @@ static const struct elf_i386_plt_layout elf_i386_nacl_plt = elf_i386_nacl_pic_plt_entry, /* pic_plt_entry */ elf_i386_nacl_eh_frame_plt, /* eh_frame_plt */ sizeof (elf_i386_nacl_eh_frame_plt),/* eh_frame_plt_size */ + NULL, /* eh_frame_plt_got */ + 0, /* eh_frame_plt_got_size */ }; static const struct elf_i386_backend_data elf_i386_nacl_arch_bed = diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 36630f88cc1..b5a949a9cd8 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -659,6 +659,33 @@ static const bfd_byte elf_x86_64_eh_frame_plt[] = DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop }; +/* .eh_frame covering the .plt.got section. */ + +static const bfd_byte elf_x86_64_eh_frame_plt_got[] = +{ +#define PLT_GOT_FDE_LENGTH 20 + PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */ + 0, 0, 0, 0, /* CIE ID */ + 1, /* CIE version */ + 'z', 'R', 0, /* Augmentation string */ + 1, /* Code alignment factor */ + 0x78, /* Data alignment factor */ + 16, /* Return address column */ + 1, /* Augmentation size */ + DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */ + DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */ + DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */ + DW_CFA_nop, DW_CFA_nop, + + PLT_GOT_FDE_LENGTH, 0, 0, 0, /* FDE length */ + PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */ + 0, 0, 0, 0, /* the start of .plt.got goes here */ + 0, 0, 0, 0, /* .plt.got size goes here */ + 0, /* Augmentation size */ + DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, + DW_CFA_nop, DW_CFA_nop, DW_CFA_nop +}; + /* Architecture-specific backend data for x86-64. */ struct elf_x86_64_backend_data @@ -693,6 +720,10 @@ struct elf_x86_64_backend_data /* .eh_frame covering the .plt section. */ const bfd_byte *eh_frame_plt; unsigned int eh_frame_plt_size; + + /* .eh_frame covering the .plt.got section. */ + const bfd_byte *eh_frame_plt_got; + unsigned int eh_frame_plt_got_size; }; #define get_elf_x86_64_arch_data(bed) \ @@ -721,6 +752,8 @@ static const struct elf_x86_64_backend_data elf_x86_64_arch_bed = 6, /* plt_lazy_offset */ elf_x86_64_eh_frame_plt, /* eh_frame_plt */ sizeof (elf_x86_64_eh_frame_plt), /* eh_frame_plt_size */ + elf_x86_64_eh_frame_plt_got, /* eh_frame_plt_got */ + sizeof (elf_x86_64_eh_frame_plt_got), /* eh_frame_plt_got_size */ }; static const struct elf_x86_64_backend_data elf_x86_64_bnd_arch_bed = @@ -739,6 +772,9 @@ static const struct elf_x86_64_backend_data elf_x86_64_bnd_arch_bed = 0, /* plt_lazy_offset */ elf_x86_64_eh_frame_plt, /* eh_frame_plt */ sizeof (elf_x86_64_eh_frame_plt), /* eh_frame_plt_size */ + /* FIXME: Needs .eh_frame coverage. */ + NULL, /* eh_frame_plt_got */ + 0, /* eh_frame_plt_got_size */ }; #define elf_backend_arch_data &elf_x86_64_arch_bed @@ -865,6 +901,7 @@ struct elf_x86_64_link_hash_table asection *plt_eh_frame; asection *plt_bnd; asection *plt_got; + asection *plt_got_eh_frame; union { @@ -2744,6 +2781,24 @@ do_size: htab->plt_got, plt_got_align)) goto error_return; + + if (!info->no_ld_generated_unwind_info + && htab->plt_got_eh_frame == NULL + && get_elf_x86_64_backend_data (abfd)->eh_frame_plt_got != NULL) + { + flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY + | SEC_HAS_CONTENTS | SEC_IN_MEMORY + | SEC_LINKER_CREATED); + htab->plt_got_eh_frame + = bfd_make_section_anyway_with_flags (htab->elf.dynobj, + ".eh_frame", + flags); + if (htab->plt_got_eh_frame == NULL + || !bfd_set_section_alignment (htab->elf.dynobj, + htab->plt_got_eh_frame, + 3)) + goto error_return; + } } if ((r_type == R_X86_64_GOTPCREL @@ -3788,15 +3843,28 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd, htab->elf.sgotplt->size = 0; } - if (htab->plt_eh_frame != NULL - && htab->elf.splt != NULL - && htab->elf.splt->size != 0 - && !bfd_is_abs_section (htab->elf.splt->output_section) - && _bfd_elf_eh_frame_present (info)) + if (_bfd_elf_eh_frame_present (info)) { - const struct elf_x86_64_backend_data *arch_data - = get_elf_x86_64_arch_data (bed); - htab->plt_eh_frame->size = arch_data->eh_frame_plt_size; + if (htab->plt_eh_frame != NULL + && htab->elf.splt != NULL + && htab->elf.splt->size != 0 + && !bfd_is_abs_section (htab->elf.splt->output_section)) + { + const struct elf_x86_64_backend_data *arch_data + = get_elf_x86_64_arch_data (bed); + htab->plt_eh_frame->size = arch_data->eh_frame_plt_size; + } + + if (htab->plt_got_eh_frame != NULL + && htab->plt_got != NULL + && htab->plt_got->size != 0 + && !bfd_is_abs_section (htab->plt_got->output_section)) + { + const struct elf_x86_64_backend_data *arch_data + = get_elf_x86_64_arch_data (bed); + htab->plt_got_eh_frame->size + = arch_data->eh_frame_plt_got_size; + } } /* We now have determined the sizes of the various dynamic sections. @@ -3815,6 +3883,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd, || s == htab->plt_bnd || s == htab->plt_got || s == htab->plt_eh_frame + || s == htab->plt_got_eh_frame || s == htab->elf.sdynbss || s == htab->elf.sdynrelro) { @@ -3878,6 +3947,20 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd, htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET); } + if (htab->plt_got_eh_frame != NULL + && htab->plt_got_eh_frame->contents != NULL) + { + const struct elf_x86_64_backend_data *arch_data + = get_elf_x86_64_arch_data (bed); + + memcpy (htab->plt_got_eh_frame->contents, + arch_data->eh_frame_plt_got, + htab->plt_got_eh_frame->size); + bfd_put_32 (dynobj, htab->plt_got->size, + (htab->plt_got_eh_frame->contents + + PLT_FDE_LEN_OFFSET)); + } + if (htab->elf.dynamic_sections_created) { /* Add some entries to the .dynamic section. We fill in the @@ -6343,6 +6426,33 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd, } } + /* Adjust .eh_frame for .plt.got section. */ + if (htab->plt_got_eh_frame != NULL + && htab->plt_got_eh_frame->contents != NULL) + { + if (htab->plt_got != NULL + && htab->plt_got->size != 0 + && (htab->plt_got->flags & SEC_EXCLUDE) == 0 + && htab->plt_got->output_section != NULL + && htab->plt_got_eh_frame->output_section != NULL) + { + bfd_vma plt_start = htab->plt_got->output_section->vma; + bfd_vma eh_frame_start = htab->plt_got_eh_frame->output_section->vma + + htab->plt_got_eh_frame->output_offset + + PLT_FDE_START_OFFSET; + bfd_put_signed_32 (dynobj, plt_start - eh_frame_start, + htab->plt_got_eh_frame->contents + + PLT_FDE_START_OFFSET); + } + if (htab->plt_got_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME) + { + if (! _bfd_elf_write_section_eh_frame (output_bfd, info, + htab->plt_got_eh_frame, + htab->plt_got_eh_frame->contents)) + return FALSE; + } + } + if (htab->elf.sgot && htab->elf.sgot->size > 0) elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE; @@ -7007,6 +7117,8 @@ static const struct elf_x86_64_backend_data elf_x86_64_nacl_arch_bed = 32, /* plt_lazy_offset */ elf_x86_64_nacl_eh_frame_plt, /* eh_frame_plt */ sizeof (elf_x86_64_nacl_eh_frame_plt), /* eh_frame_plt_size */ + NULL, /* eh_frame_plt_got */ + 0, /* eh_frame_plt_got_size */ }; #undef elf_backend_arch_data diff --git a/ld/ChangeLog b/ld/ChangeLog index ef2c466e150..57d73873c6d 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,13 @@ +2017-01-10 H.J. Lu + + PR ld/20830 + * testsuite/ld-i386/i386.exp: Run pr20830. + * testsuite/ld-x86-64/x86-64.exp: Likewise. + * testsuite/ld-i386/pr20830.d: New file. + * testsuite/ld-i386/pr20830.s: Likewise. + * testsuite/ld-x86-64/pr20830.d: Likewise. + * testsuite/ld-x86-64/pr20830.s: Likewise. + 2017-01-10 H.J. Lu * testsuite/ld-i386/i386.exp: Pass -Wl,-R,tmpdir and diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index 973a1106517..43cb3c56fb4 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -864,3 +864,4 @@ if { !([istarget "i?86-*-linux*"] # Linux only tests run_dump_test "pltgot-1" run_dump_test "pltgot-2" +run_dump_test "pr20830" diff --git a/ld/testsuite/ld-i386/pr20830.d b/ld/testsuite/ld-i386/pr20830.d new file mode 100644 index 00000000000..caaadd77a49 --- /dev/null +++ b/ld/testsuite/ld-i386/pr20830.d @@ -0,0 +1,60 @@ +#name: PR ld/20830 (.plt.got) +#as: --32 +#ld: -melf_i386 -shared -z relro --ld-generated-unwind-info +#objdump: -dw -Wf + +.*: +file format .* + +Contents of the .eh_frame section: + +0+ 00000014 00000000 CIE + Version: 1 + Augmentation: "zR" + Code alignment factor: 1 + Data alignment factor: -4 + Return address column: 8 + Augmentation data: 1b + + DW_CFA_def_cfa: r4 \(esp\) ofs 4 + DW_CFA_offset: r8 \(eip\) at cfa-4 + DW_CFA_nop + DW_CFA_nop + +0+18 00000010 0000001c FDE cie=00000000 pc=00000188..00000193 + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + +0+2c 00000020 00000030 FDE cie=00000000 pc=00000170..00000180 + DW_CFA_def_cfa_offset: 8 + DW_CFA_advance_loc: 6 to 00000176 + DW_CFA_def_cfa_offset: 12 + DW_CFA_advance_loc: 10 to 00000180 + DW_CFA_def_cfa_expression \(DW_OP_breg4 \(esp\): 4; DW_OP_breg8 \(eip\): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit11; DW_OP_ge; DW_OP_lit2; DW_OP_shl; DW_OP_plus\) + +0+50 00000010 00000054 FDE cie=00000000 pc=00000180..00000188 + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + + +Disassembly of section .plt: + +0+170 <.plt>: + +[a-f0-9]+: ff b3 04 00 00 00 pushl 0x4\(%ebx\) + +[a-f0-9]+: ff a3 08 00 00 00 jmp \*0x8\(%ebx\) + +[a-f0-9]+: 00 00 add %al,\(%eax\) + ... + +Disassembly of section .plt.got: + +0+180 <.plt.got>: + +[a-f0-9]+: ff a3 fc ff ff ff jmp \*-0x4\(%ebx\) + +[a-f0-9]+: 66 90 xchg %ax,%ax + +Disassembly of section .text: + +0+188 : + +[a-f0-9]+: e8 f3 ff ff ff call 180 <.plt.got> + +[a-f0-9]+: 8b 83 fc ff ff ff mov -0x4\(%ebx\),%eax +#pass diff --git a/ld/testsuite/ld-i386/pr20830.s b/ld/testsuite/ld-i386/pr20830.s new file mode 100644 index 00000000000..344a1370768 --- /dev/null +++ b/ld/testsuite/ld-i386/pr20830.s @@ -0,0 +1,8 @@ + .text + .globl foo + .type foo, @function +foo: + .cfi_startproc + call func@plt + movl func@GOT(%ebx), %eax + .cfi_endproc diff --git a/ld/testsuite/ld-x86-64/pr20830.d b/ld/testsuite/ld-x86-64/pr20830.d new file mode 100644 index 00000000000..2dc0f30348e --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20830.d @@ -0,0 +1,71 @@ +#name: PR ld/20830 (.plt.got) +#as: --64 +#ld: -melf_x86_64 -shared -z relro --ld-generated-unwind-info +#objdump: -dw -Wf + +.*: +file format .* + +Contents of the .eh_frame section: + +0+ 0000000000000014 00000000 CIE + Version: 1 + Augmentation: "zR" + Code alignment factor: 1 + Data alignment factor: -8 + Return address column: 16 + Augmentation data: 1b + + DW_CFA_def_cfa: r7 \(rsp\) ofs 8 + DW_CFA_offset: r16 \(rip\) at cfa-8 + DW_CFA_nop + DW_CFA_nop + +0+18 0000000000000014 0000001c FDE cie=00000000 pc=0000000000000238..0000000000000244 + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + +0+30 0000000000000024 00000034 FDE cie=00000000 pc=0000000000000220..0000000000000230 + DW_CFA_def_cfa_offset: 16 + DW_CFA_advance_loc: 6 to 0000000000000226 + DW_CFA_def_cfa_offset: 24 + DW_CFA_advance_loc: 10 to 0000000000000230 + DW_CFA_def_cfa_expression \(DW_OP_breg7 \(rsp\): 8; DW_OP_breg16 \(rip\): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit11; DW_OP_ge; DW_OP_lit3; DW_OP_shl; DW_OP_plus\) + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + +0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238 + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + + +Disassembly of section .plt: + +0+220 <.plt>: + +[a-f0-9]+: ff 35 e2 0d 20 00 pushq 0x200de2\(%rip\) # 201008 <_GLOBAL_OFFSET_TABLE_\+0x8> + +[a-f0-9]+: ff 25 e4 0d 20 00 jmpq \*0x200de4\(%rip\) # 201010 <_GLOBAL_OFFSET_TABLE_\+0x10> + +[a-f0-9]+: 0f 1f 40 00 nopl 0x0\(%rax\) + +Disassembly of section .plt.got: + +0+230 <.plt.got>: + +[a-f0-9]+: ff 25 c2 0d 20 00 jmpq \*0x200dc2\(%rip\) # 200ff8 + +[a-f0-9]+: 66 90 xchg %ax,%ax + +Disassembly of section .text: + +0+238 : + +[a-f0-9]+: e8 f3 ff ff ff callq 230 <.plt.got> + +[a-f0-9]+: 48 8b 05 b4 0d 20 00 mov 0x200db4\(%rip\),%rax # 200ff8 +#pass diff --git a/ld/testsuite/ld-x86-64/pr20830.s b/ld/testsuite/ld-x86-64/pr20830.s new file mode 100644 index 00000000000..d9a1b4c7f22 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20830.s @@ -0,0 +1,8 @@ + .text + .globl foo + .type foo, @function +foo: + .cfi_startproc + call func@plt + movq func@GOTPCREL(%rip), %rax + .cfi_endproc diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 26d739e3350..878e28e878e 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -1019,3 +1019,4 @@ if { ![istarget "x86_64-*-linux*"]} { run_dump_test "pr17618" run_dump_test "pltgot-1" run_dump_test "pltgot-2" +run_dump_test "pr20830" -- 2.30.2