diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 0e52b9512b..2173fc9fca 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,64 @@ +2016-06-18 H.J. Lu + + PR ld/20253 + * elf-bfd.h (_bfd_elf_allocate_ifunc_dyn_relocs): Add an + bfd_boolean argument. + * elf-ifunc.c (_bfd_elf_create_ifunc_sections): Replace + "shared object" with "PIC object" in comments. + (_bfd_elf_allocate_ifunc_dyn_relocs): Updated. Replace + "shared object" with "PIC object" in comments. Avoid PLT if + requested. Generate dynamic relocations for non-GOT references. + Make room for the special first entry in PLT and allocate PLT + entry only for PLT and PC-relative references. Store dynamic + GOT relocations in .rel[a].iplt section for static executables. + If PLT isn't used, always use GOT for symbol value. Don't + allocate GOT entry if it isn't used. + * elf32-i386.c (elf_i386_check_relocs): Increment PLT reference + count only in the code section. Allocate dynamic pointer + relocation against STT_GNU_IFUNC symbol in the non-code section. + (elf_i386_adjust_dynamic_symbol): Increment PLT reference count + only for PC-relative references. + (elf_i386_allocate_dynrelocs): Pass TRUE to + _bfd_elf_allocate_ifunc_dyn_relocs. + (elf_i386_relocate_section): Allow R_386_GOT32/R_386_GOT32X + relocations against STT_GNU_IFUNC symbols without PLT. Generate + dynamic pointer relocation against STT_GNU_IFUNC symbol in + the non-code section and store it in the proper REL section. + Don't allow non-pointer relocation against STT_GNU_IFUNC symbol + without PLT. + (elf_i386_finish_dynamic_symbol): Generate dynamic + R_386_IRELATIVE and R_386_GLOB_DAT GOT relocations against + STT_GNU_IFUNC symbols without PLT. + (elf_i386_finish_dynamic_sections): Don't handle local + STT_GNU_IFUNC symbols here. + (elf_i386_output_arch_local_syms): Handle local STT_GNU_IFUNC + symbols here. + (elf_backend_output_arch_local_syms): New. + * elf32-x86-64.c (elf_i386_check_relocs): Increment PLT reference + count only in the code section. Allocate dynamic pointer + relocation against STT_GNU_IFUNC symbol in the non-code section. + (elf_x86_64_adjust_dynamic_symbol): Increment PLT reference + count only for PC-relative references. + (elf_x86_64_allocate_dynrelocs): Pass TRUE to + _bfd_elf_allocate_ifunc_dyn_relocs. + (elf_x86_64_relocate_section): Allow R_X86_64_GOTPCREL, + R_X86_64_GOTPCRELX, R_X86_64_REX_GOTPCRELX and + R_X86_64_GOTPCREL64 relocations against STT_GNU_IFUNC symbols + without PLT. Generate dynamic pointer relocation against + STT_GNU_IFUNC symbol in the non-code section and store it in + the proper RELA section. Don't allow non-pointer relocation + against STT_GNU_IFUNC symbol without PLT. + (elf_x86_64_finish_dynamic_symbol): Generate dynamic + R_X86_64_IRELATIVE and R_X86_64_GLOB_DAT GOT relocations against + STT_GNU_IFUNC symbols without PLT. + (elf_x86_64_finish_dynamic_sections): Don't handle local + STT_GNU_IFUNC symbols here. + (elf_x86_64_output_arch_local_syms): Handle local STT_GNU_IFUNC + symbols here. + (elf_backend_output_arch_local_syms): New. + * elfnn-aarch64.c (elfNN_aarch64_allocate_ifunc_dynrelocs): + Pass FALSE to _bfd_elf_allocate_ifunc_dyn_relocs. + 2016-06-17 Thomas Preud'homme Tony Wang diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 6825530dce..163ef35fad 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -2521,7 +2521,7 @@ extern bfd_boolean _bfd_elf_create_ifunc_sections extern bfd_boolean _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *, struct elf_link_hash_entry *, struct elf_dyn_relocs **, bfd_boolean *, unsigned int, - unsigned int, unsigned int); + unsigned int, unsigned int, bfd_boolean); extern long _bfd_elf_ifunc_get_synthetic_symtab (bfd *, long, asymbol **, long, asymbol **, asymbol **, asection *, bfd_vma *(*) (bfd *, asymbol **, asection *, asection *)); diff --git a/bfd/elf-ifunc.c b/bfd/elf-ifunc.c index 1377fedfd3..09cbf4a376 100644 --- a/bfd/elf-ifunc.c +++ b/bfd/elf-ifunc.c @@ -55,7 +55,7 @@ _bfd_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info) if (bfd_link_pic (info)) { - /* We need to create .rel[a].ifunc for shared objects. */ + /* We need to create .rel[a].ifunc for PIC objects. */ const char *rel_sec = (bed->rela_plts_and_copies_p ? ".rela.ifunc" : ".rel.ifunc"); @@ -113,7 +113,8 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info, bfd_boolean *readonly_dynrelocs_against_ifunc_p, unsigned int plt_entry_size, unsigned int plt_header_size, - unsigned int got_entry_size) + unsigned int got_entry_size, + bfd_boolean avoid_plt) { asection *plt, *gotplt, *relplt; struct elf_dyn_relocs *p; @@ -121,13 +122,17 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info, const struct elf_backend_data *bed; struct elf_link_hash_table *htab; bfd_boolean readonly_dynrelocs_against_ifunc; + /* If AVOID_PLT is TRUE, don't use PLT if possible. */ + bfd_boolean use_plt = !avoid_plt || h->plt.refcount > 0; + bfd_boolean need_dynreloc = !use_plt || bfd_link_pic (info); - /* When a shared library references a STT_GNU_IFUNC symbol defined - in executable, the address of the resolved function may be used. - But in non-shared executable, the address of its .plt slot may - be used. Pointer equality may not work correctly. PIE should - be used if pointer equality is required here. */ - if (!bfd_link_pic (info) + /* When a PIC object references a STT_GNU_IFUNC symbol defined + in executable or it isn't referenced via PLT, the address of + the resolved function may be used. But in non-PIC executable, + the address of its .plt slot may be used. Pointer equality may + not work correctly. PIE or non-PLT reference should be used if + pointer equality is required here. */ + if (!need_dynreloc && (h->dynindx != -1 || info->export_dynamic) && h->pointer_equality_needed) @@ -144,16 +149,30 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info, htab = elf_hash_table (info); - /* When building shared library, we need to handle the case where it is - marked with regular reference, but not non-GOT reference since the - non-GOT reference bit may not be set here. */ - if (bfd_link_pic (info) && !h->non_got_ref && h->ref_regular) - for (p = *head; p != NULL; p = p->next) - if (p->count) - { - h->non_got_ref = 1; - goto keep; - } + /* When the symbol is marked with regular reference, if PLT isn't used + or we are building a PIC object, we must keep dynamic relocation + if there is non-GOT reference and use PLT if there is PC-relative + reference. */ + if (need_dynreloc && h->ref_regular) + { + bfd_boolean keep = FALSE; + for (p = *head; p != NULL; p = p->next) + if (p->count) + { + h->non_got_ref = 1; + /* Need dynamic relocations for non-GOT reference. */ + keep = TRUE; + if (p->pc_count) + { + /* Must use PLT for PC-relative reference. */ + use_plt = TRUE; + need_dynreloc = bfd_link_pic (info); + break; + } + } + if (keep) + goto keep; + } /* Support garbage collection against STT_GNU_IFUNC symbols. */ if (h->plt.refcount <= 0 && h->got.refcount <= 0) @@ -165,7 +184,7 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info, } /* Return and discard space for dynamic relocations against it if - it is never referenced in a non-shared object. */ + it is never referenced. */ if (!h->ref_regular) { if (h->plt.refcount > 0 @@ -192,9 +211,9 @@ keep: gotplt = htab->sgotplt; relplt = htab->srelplt; - /* If this is the first .plt entry, make room for the special - first entry. */ - if (plt->size == 0) + /* If this is the first .plt entry and PLT is used, make room for + the special first entry. */ + if (plt->size == 0 && use_plt) plt->size += plt_header_size; } else @@ -204,26 +223,31 @@ keep: relplt = htab->irelplt; } - /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need - the original value for R_*_IRELATIVE. */ - h->plt.offset = plt->size; + if (use_plt) + { + /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need + the original value for R_*_IRELATIVE. */ + h->plt.offset = plt->size; - /* Make room for this entry in the .plt/.iplt section. */ - plt->size += plt_entry_size; + /* Make room for this entry in the .plt/.iplt section. */ + plt->size += plt_entry_size; - /* We also need to make an entry in the .got.plt/.got.iplt section, - which will be placed in the .got section by the linker script. */ - gotplt->size += got_entry_size; + /* We also need to make an entry in the .got.plt/.got.iplt section, + which will be placed in the .got section by the linker script. */ + gotplt->size += got_entry_size; + } /* We also need to make an entry in the .rel[a].plt/.rel[a].iplt - section. */ - relplt->size += sizeof_reloc; - relplt->reloc_count++; + section for GOTPLT relocation if PLT is used. */ + if (use_plt) + { + relplt->size += sizeof_reloc; + relplt->reloc_count++; + } /* We need dynamic relocation for STT_GNU_IFUNC symbol only when - there is a non-GOT reference in a shared object. */ - if (!bfd_link_pic (info) - || !h->non_got_ref) + there is a non-GOT reference in a PIC object or PLT isn't used. */ + if (!need_dynreloc || !h->non_got_ref) *head = NULL; readonly_dynrelocs_against_ifunc = FALSE; @@ -245,7 +269,20 @@ keep: p = p->next; } while (p != NULL); - htab->irelifunc->size += count * sizeof_reloc; + + /* Dynamic relocations are stored in + 1. .rel[a].ifunc section in PIC object. + 2. .rel[a].got section in dynamic executable. + 3. .rel[a].iplt section in static executable. */ + if (bfd_link_pic (info)) + htab->irelifunc->size += count * sizeof_reloc; + else if (htab->splt != NULL) + htab->srelgot->size += count * sizeof_reloc; + else + { + relplt->size += count * sizeof_reloc; + relplt->reloc_count += count; + } } if (readonly_dynrelocs_against_ifunc_p) @@ -254,34 +291,65 @@ keep: /* For STT_GNU_IFUNC symbol, .got.plt has the real function address and .got has the PLT entry adddress. We will load the GOT entry with the PLT entry in finish_dynamic_symbol if it is used. For - branch, it uses .got.plt. For symbol value, - 1. Use .got.plt in a shared object if it is forced local or not + branch, it uses .got.plt. For symbol value, if PLT is used, + 1. Use .got.plt in a PIC object if it is forced local or not dynamic. - 2. Use .got.plt in a non-shared object if pointer equality isn't + 2. Use .got.plt in a non-PIC object if pointer equality isn't needed. 3. Use .got.plt in PIE. 4. Use .got.plt if .got isn't used. 5. Otherwise use .got so that it can be shared among different objects at run-time. - We only need to relocate .got entry in shared object. */ - if (h->got.refcount <= 0 - || (bfd_link_pic (info) - && (h->dynindx == -1 - || h->forced_local)) - || (!bfd_link_pic (info) - && !h->pointer_equality_needed) - || bfd_link_pie (info) - || htab->sgot == NULL) + If PLT isn't used, always use .got for symbol value. + We only need to relocate .got entry in PIC object or in dynamic + executable without PLT. */ + if (use_plt + && (h->got.refcount <= 0 + || (bfd_link_pic (info) + && (h->dynindx == -1 + || h->forced_local)) + || (!bfd_link_pic (info) + && !h->pointer_equality_needed) + || bfd_link_pie (info) + || htab->sgot == NULL)) { /* Use .got.plt. */ h->got.offset = (bfd_vma) -1; } else { - h->got.offset = htab->sgot->size; - htab->sgot->size += got_entry_size; - if (bfd_link_pic (info)) - htab->srelgot->size += sizeof_reloc; + if (!use_plt) + { + /* PLT isn't used. */ + h->plt.offset = (bfd_vma) -1; + } + if (h->got.refcount <= 0) + { + /* GOT isn't need when there are only relocations for static + pointers. */ + h->got.offset = (bfd_vma) -1; + } + else + { + h->got.offset = htab->sgot->size; + htab->sgot->size += got_entry_size; + /* Need to relocate the GOT entry in a PIC object or PLT isn't + used. Otherwise, the GOT entry will be filled with the PLT + entry and dynamic GOT relocation isn't needed. */ + if (need_dynreloc) + { + /* For non-static executable, dynamic GOT relocation is in + .rel[a].got section, but for static executable, it is + in .rel[a].iplt section. */ + if (htab->splt != NULL) + htab->srelgot->size += sizeof_reloc; + else + { + relplt->size += sizeof_reloc; + relplt->reloc_count++; + } + } + } } return TRUE; diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 2b7de3397f..417957214d 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -2164,9 +2164,13 @@ do_relocation: adjust_dynamic_symbol. */ h->non_got_ref = 1; - /* We may need a .plt entry if the function this reloc - refers to is in a shared lib. */ - h->plt.refcount += 1; + /* We may need a .plt entry if the symbol is a function + defined in a shared lib or is a STT_GNU_IFUNC function + referenced from the code or read-only section. */ + if (!h->def_regular + || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0) + h->plt.refcount += 1; + if (r_type == R_386_PC32) { /* Since something like ".long foo - ." may be used @@ -2207,7 +2211,10 @@ do_size: If on the other hand, we are creating an executable, we may need to keep relocations for symbols satisfied by a dynamic library if we manage to avoid copy relocs for the - symbol. */ + symbol. + + Generate dynamic pointer relocation against STT_GNU_IFUNC + symbol in the non-code section. */ if ((bfd_link_pic (info) && (r_type != R_386_PC32 || (h != NULL @@ -2215,6 +2222,10 @@ do_size: || SYMBOLIC_BIND (info, h)) || h->root.type == bfd_link_hash_defweak || !h->def_regular)))) + || (h != NULL + && h->type == STT_GNU_IFUNC + && r_type == R_386_32 + && (sec->flags & SEC_CODE) == 0) || (ELIMINATE_COPY_RELOCS && !bfd_link_pic (info) && h != NULL @@ -2448,12 +2459,17 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info, if (pc_count || count) { - h->needs_plt = 1; h->non_got_ref = 1; - if (h->plt.refcount <= 0) - h->plt.refcount = 1; - else - h->plt.refcount += 1; + if (pc_count) + { + /* Increment PLT reference count only for PC-relative + references. */ + h->needs_plt = 1; + if (h->plt.refcount <= 0) + h->plt.refcount = 1; + else + h->plt.refcount += 1; + } } } @@ -2643,7 +2659,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs, &htab->readonly_dynrelocs_against_ifunc, plt_entry_size, - plt_entry_size, 4); + plt_entry_size, 4, TRUE); /* Don't create the PLT entry if there are only function pointer relocations which can be resolved at run-time. */ else if (htab->elf.dynamic_sections_created @@ -3898,8 +3914,6 @@ elf_i386_relocate_section (bfd *output_bfd, continue; abort (); } - else if (h->plt.offset == (bfd_vma) -1) - abort (); /* STT_GNU_IFUNC symbol must go through PLT. */ if (htab->elf.splt != NULL) @@ -3913,77 +3927,10 @@ elf_i386_relocate_section (bfd *output_bfd, gotplt = htab->elf.igotplt; } - relocation = (plt->output_section->vma - + plt->output_offset + h->plt.offset); - switch (r_type) { default: - if (h->root.root.string) - name = h->root.root.string; - else - name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, - NULL); - (*_bfd_error_handler) - (_("%B: relocation %s against STT_GNU_IFUNC " - "symbol `%s' isn't handled by %s"), input_bfd, - elf_howto_table[r_type].name, - name, __FUNCTION__); - bfd_set_error (bfd_error_bad_value); - return FALSE; - - case R_386_32: - /* Generate dynamic relcoation only when there is a - non-GOT reference in a shared object. */ - if (bfd_link_pic (info) && h->non_got_ref) - { - Elf_Internal_Rela outrel; - asection *sreloc; - bfd_vma offset; - - /* Need a dynamic relocation to get the real function - adddress. */ - offset = _bfd_elf_section_offset (output_bfd, - info, - input_section, - rel->r_offset); - if (offset == (bfd_vma) -1 - || offset == (bfd_vma) -2) - abort (); - - outrel.r_offset = (input_section->output_section->vma - + input_section->output_offset - + offset); - - if (h->dynindx == -1 - || h->forced_local - || bfd_link_executable (info)) - { - /* This symbol is resolved locally. */ - outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE); - bfd_put_32 (output_bfd, - (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset), - contents + offset); - } - else - outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); - - sreloc = htab->elf.irelifunc; - elf_append_rel (output_bfd, sreloc, &outrel); - - /* If this reloc is against an external symbol, we - do not want to fiddle with the addend. Otherwise, - we need to include the symbol value so that it - becomes an addend for the dynamic reloc. For an - internal symbol, we have updated addend. */ - continue; - } - /* FALLTHROUGH */ - case R_386_PC32: - case R_386_PLT32: - goto do_relocation; + break; case R_386_GOT32: case R_386_GOT32X: @@ -3999,6 +3946,9 @@ elf_i386_relocate_section (bfd *output_bfd, even just remember the offset, as finish_dynamic_symbol would use that as offset into .got. */ + if (h->plt.offset == (bfd_vma) -1) + abort (); + if (htab->elf.splt != NULL) { plt_index = h->plt.offset / plt_entry_size - 1; @@ -4059,6 +4009,99 @@ elf_i386_relocate_section (bfd *output_bfd, } goto do_relocation; + } + + if (h->plt.offset == (bfd_vma) -1) + { + /* Handle static pointers of STT_GNU_IFUNC symbols. */ + if (r_type == R_386_32 + && (input_section->flags & SEC_CODE) == 0) + goto do_ifunc_pointer; + goto bad_ifunc_reloc; + } + + relocation = (plt->output_section->vma + + plt->output_offset + h->plt.offset); + + switch (r_type) + { + default: +bad_ifunc_reloc: + if (h->root.root.string) + name = h->root.root.string; + else + name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, + NULL); + (*_bfd_error_handler) + (_("%B: relocation %s against STT_GNU_IFUNC " + "symbol `%s' isn't supported"), input_bfd, + howto->name, name); + bfd_set_error (bfd_error_bad_value); + return FALSE; + + case R_386_32: + /* Generate dynamic relcoation only when there is a + non-GOT reference in a shared object. */ + if ((bfd_link_pic (info) && h->non_got_ref) + || h->plt.offset == (bfd_vma) -1) + { + Elf_Internal_Rela outrel; + asection *sreloc; + bfd_vma offset; + +do_ifunc_pointer: + /* Need a dynamic relocation to get the real function + adddress. */ + offset = _bfd_elf_section_offset (output_bfd, + info, + input_section, + rel->r_offset); + if (offset == (bfd_vma) -1 + || offset == (bfd_vma) -2) + abort (); + + outrel.r_offset = (input_section->output_section->vma + + input_section->output_offset + + offset); + + if (h->dynindx == -1 + || h->forced_local + || bfd_link_executable (info)) + { + /* This symbol is resolved locally. */ + outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE); + bfd_put_32 (output_bfd, + (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset), + contents + offset); + } + else + outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); + + /* Dynamic relocations are stored in + 1. .rel.ifunc section in PIC object. + 2. .rel.got section in dynamic executable. + 3. .rel.iplt section in static executable. */ + if (bfd_link_pic (info)) + sreloc = htab->elf.irelifunc; + else if (htab->elf.splt != NULL) + sreloc = htab->elf.srelgot; + else + sreloc = htab->elf.irelplt; + elf_append_rel (output_bfd, sreloc, &outrel); + + /* If this reloc is against an external symbol, we + do not want to fiddle with the addend. Otherwise, + we need to include the symbol value so that it + becomes an addend for the dynamic reloc. For an + internal symbol, we have updated addend. */ + continue; + } + /* FALLTHROUGH */ + case R_386_PC32: + case R_386_PLT32: + goto do_relocation; case R_386_GOTOFF: relocation -= (gotplt->output_section->vma @@ -5432,6 +5475,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, && !local_undefweak) { Elf_Internal_Rela rel; + asection *relgot = htab->elf.srelgot; /* This symbol has an entry in the global offset table. Set it up. */ @@ -5451,7 +5495,28 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, if (h->def_regular && h->type == STT_GNU_IFUNC) { - if (bfd_link_pic (info)) + if (h->plt.offset == (bfd_vma) -1) + { + /* STT_GNU_IFUNC is referenced without PLT. */ + if (htab->elf.splt == NULL) + { + /* use .rel[a].iplt section to store .got relocations + in static executable. */ + relgot = htab->elf.irelplt; + } + if (SYMBOL_REFERENCES_LOCAL (info, h)) + { + bfd_put_32 (output_bfd, + (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset), + htab->elf.sgot->contents + h->got.offset); + rel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE); + } + else + goto do_glob_dat; + } + else if (bfd_link_pic (info)) { /* Generate R_386_GLOB_DAT. */ goto do_glob_dat; @@ -5489,7 +5554,7 @@ do_glob_dat: rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT); } - elf_append_rel (output_bfd, htab->elf.srelgot, &rel); + elf_append_rel (output_bfd, relgot, &rel); } if (h->needs_copy) @@ -5826,11 +5891,6 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd, if (htab->elf.sgot && htab->elf.sgot->size > 0) elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4; - /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */ - htab_traverse (htab->loc_hash_table, - elf_i386_finish_local_dynamic_symbol, - info); - /* Fill PLT entries for undefined weak symbols in PIE. */ if (bfd_link_pie (info)) bfd_hash_traverse (&info->hash->table, @@ -5840,6 +5900,33 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd, return TRUE; } +/* Fill PLT/GOT entries and allocate dynamic relocations for local + STT_GNU_IFUNC symbols, which aren't in the ELF linker hash table. + It has to be done before elf_link_sort_relocs is called so that + dynamic relocations are properly sorted. */ + +static bfd_boolean +elf_i386_output_arch_local_syms + (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info, + void *flaginfo ATTRIBUTE_UNUSED, + int (*func) (void *, const char *, + Elf_Internal_Sym *, + asection *, + struct elf_link_hash_entry *) ATTRIBUTE_UNUSED) +{ + struct elf_i386_link_hash_table *htab = elf_i386_hash_table (info); + if (htab == NULL) + return FALSE; + + /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */ + htab_traverse (htab->loc_hash_table, + elf_i386_finish_local_dynamic_symbol, + info); + + return TRUE; +} + /* Return an array of PLT entry symbol values. */ static bfd_vma * @@ -5982,6 +6069,7 @@ elf_i386_hash_symbol (struct elf_link_hash_entry *h) #define elf_backend_fake_sections elf_i386_fake_sections #define elf_backend_finish_dynamic_sections elf_i386_finish_dynamic_sections #define elf_backend_finish_dynamic_symbol elf_i386_finish_dynamic_symbol +#define elf_backend_output_arch_local_syms elf_i386_output_arch_local_syms #define elf_backend_gc_mark_hook elf_i386_gc_mark_hook #define elf_backend_grok_prstatus elf_i386_grok_prstatus #define elf_backend_grok_psinfo elf_i386_grok_psinfo diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 57a3c73b83..f9202085b3 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -2556,9 +2556,13 @@ pointer: adjust_dynamic_symbol. */ h->non_got_ref = 1; - /* We may need a .plt entry if the function this reloc - refers to is in a shared lib. */ - h->plt.refcount += 1; + /* We may need a .plt entry if the symbol is a function + defined in a shared lib or is a STT_GNU_IFUNC function + referenced from the code or read-only section. */ + if (!h->def_regular + || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0) + h->plt.refcount += 1; + if (r_type == R_X86_64_PC32) { /* Since something like ".long foo - ." may be used @@ -2605,7 +2609,10 @@ do_size: If on the other hand, we are creating an executable, we may need to keep relocations for symbols satisfied by a dynamic library if we manage to avoid copy relocs for the - symbol. */ + symbol. + + Generate dynamic pointer relocation against STT_GNU_IFUNC + symbol in the non-code section. */ if ((bfd_link_pic (info) && (! IS_X86_64_PCREL_TYPE (r_type) || (h != NULL @@ -2613,6 +2620,10 @@ do_size: || SYMBOLIC_BIND (info, h)) || h->root.type == bfd_link_hash_defweak || !h->def_regular)))) + || (h != NULL + && h->type == STT_GNU_IFUNC + && r_type == htab->pointer_r_type + && (sec->flags & SEC_CODE) == 0) || (ELIMINATE_COPY_RELOCS && !bfd_link_pic (info) && h != NULL @@ -2850,12 +2861,17 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info, if (pc_count || count) { - h->needs_plt = 1; h->non_got_ref = 1; - if (h->plt.refcount <= 0) - h->plt.refcount = 1; - else - h->plt.refcount += 1; + if (pc_count) + { + /* Increment PLT reference count only for PC-relative + references. */ + h->needs_plt = 1; + if (h->plt.refcount <= 0) + h->plt.refcount = 1; + else + h->plt.refcount += 1; + } } } @@ -3049,7 +3065,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) &htab->readonly_dynrelocs_against_ifunc, plt_entry_size, plt_entry_size, - GOT_ENTRY_SIZE)) + GOT_ENTRY_SIZE, TRUE)) { asection *s = htab->plt_bnd; if (h->plt.offset != (bfd_vma) -1 && s != NULL) @@ -4233,125 +4249,11 @@ elf_x86_64_relocate_section (bfd *output_bfd, continue; abort (); } - else if (h->plt.offset == (bfd_vma) -1) - abort (); - - /* STT_GNU_IFUNC symbol must go through PLT. */ - if (htab->elf.splt != NULL) - { - if (htab->plt_bnd != NULL) - { - resolved_plt = htab->plt_bnd; - plt_offset = eh->plt_bnd.offset; - } - else - { - resolved_plt = htab->elf.splt; - plt_offset = h->plt.offset; - } - } - else - { - resolved_plt = htab->elf.iplt; - plt_offset = h->plt.offset; - } - - relocation = (resolved_plt->output_section->vma - + resolved_plt->output_offset + plt_offset); switch (r_type) { default: - if (h->root.root.string) - name = h->root.root.string; - else - name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, - NULL); - (*_bfd_error_handler) - (_("%B: relocation %s against STT_GNU_IFUNC " - "symbol `%s' isn't handled by %s"), input_bfd, - howto->name, name, __FUNCTION__); - bfd_set_error (bfd_error_bad_value); - return FALSE; - - case R_X86_64_32S: - if (bfd_link_pic (info)) - abort (); - goto do_relocation; - - case R_X86_64_32: - if (ABI_64_P (output_bfd)) - goto do_relocation; - /* FALLTHROUGH */ - case R_X86_64_64: - if (rel->r_addend != 0) - { - if (h->root.root.string) - name = h->root.root.string; - else - name = bfd_elf_sym_name (input_bfd, symtab_hdr, - sym, NULL); - (*_bfd_error_handler) - (_("%B: relocation %s against STT_GNU_IFUNC " - "symbol `%s' has non-zero addend: %d"), - input_bfd, howto->name, name, rel->r_addend); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - /* Generate dynamic relcoation only when there is a - non-GOT reference in a shared object. */ - if (bfd_link_pic (info) && h->non_got_ref) - { - Elf_Internal_Rela outrel; - asection *sreloc; - - /* Need a dynamic relocation to get the real function - address. */ - outrel.r_offset = _bfd_elf_section_offset (output_bfd, - info, - input_section, - rel->r_offset); - if (outrel.r_offset == (bfd_vma) -1 - || outrel.r_offset == (bfd_vma) -2) - abort (); - - outrel.r_offset += (input_section->output_section->vma - + input_section->output_offset); - - if (h->dynindx == -1 - || h->forced_local - || bfd_link_executable (info)) - { - /* This symbol is resolved locally. */ - outrel.r_info = htab->r_info (0, R_X86_64_IRELATIVE); - outrel.r_addend = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - } - else - { - outrel.r_info = htab->r_info (h->dynindx, r_type); - outrel.r_addend = 0; - } - - sreloc = htab->elf.irelifunc; - elf_append_rela (output_bfd, sreloc, &outrel); - - /* If this reloc is against an external symbol, we - do not want to fiddle with the addend. Otherwise, - we need to include the symbol value so that it - becomes an addend for the dynamic reloc. For an - internal symbol, we have updated addend. */ - continue; - } - /* FALLTHROUGH */ - case R_X86_64_PC32: - case R_X86_64_PC32_BND: - case R_X86_64_PC64: - case R_X86_64_PLT32: - case R_X86_64_PLT32_BND: - goto do_relocation; + break; case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: @@ -4369,6 +4271,9 @@ elf_x86_64_relocate_section (bfd *output_bfd, even just remember the offset, as finish_dynamic_symbol would use that as offset into .got. */ + if (h->plt.offset == (bfd_vma) -1) + abort (); + if (htab->elf.splt != NULL) { plt_index = h->plt.offset / plt_entry_size - 1; @@ -4413,6 +4318,146 @@ elf_x86_64_relocate_section (bfd *output_bfd, goto do_relocation; } + + if (h->plt.offset == (bfd_vma) -1) + { + /* Handle static pointers of STT_GNU_IFUNC symbols. */ + if (r_type == htab->pointer_r_type + && (input_section->flags & SEC_CODE) == 0) + goto do_ifunc_pointer; + goto bad_ifunc_reloc; + } + + /* STT_GNU_IFUNC symbol must go through PLT. */ + if (htab->elf.splt != NULL) + { + if (htab->plt_bnd != NULL) + { + resolved_plt = htab->plt_bnd; + plt_offset = eh->plt_bnd.offset; + } + else + { + resolved_plt = htab->elf.splt; + plt_offset = h->plt.offset; + } + } + else + { + resolved_plt = htab->elf.iplt; + plt_offset = h->plt.offset; + } + + relocation = (resolved_plt->output_section->vma + + resolved_plt->output_offset + plt_offset); + + switch (r_type) + { + default: +bad_ifunc_reloc: + if (h->root.root.string) + name = h->root.root.string; + else + name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, + NULL); + (*_bfd_error_handler) + (_("%B: relocation %s against STT_GNU_IFUNC " + "symbol `%s' isn't supported"), input_bfd, + howto->name, name); + bfd_set_error (bfd_error_bad_value); + return FALSE; + + case R_X86_64_32S: + if (bfd_link_pic (info)) + abort (); + goto do_relocation; + + case R_X86_64_32: + if (ABI_64_P (output_bfd)) + goto do_relocation; + /* FALLTHROUGH */ + case R_X86_64_64: +do_ifunc_pointer: + if (rel->r_addend != 0) + { + if (h->root.root.string) + name = h->root.root.string; + else + name = bfd_elf_sym_name (input_bfd, symtab_hdr, + sym, NULL); + (*_bfd_error_handler) + (_("%B: relocation %s against STT_GNU_IFUNC " + "symbol `%s' has non-zero addend: %d"), + input_bfd, howto->name, name, rel->r_addend); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + + /* Generate dynamic relcoation only when there is a + non-GOT reference in a shared object or there is no + PLT. */ + if ((bfd_link_pic (info) && h->non_got_ref) + || h->plt.offset == (bfd_vma) -1) + { + Elf_Internal_Rela outrel; + asection *sreloc; + + /* Need a dynamic relocation to get the real function + address. */ + outrel.r_offset = _bfd_elf_section_offset (output_bfd, + info, + input_section, + rel->r_offset); + if (outrel.r_offset == (bfd_vma) -1 + || outrel.r_offset == (bfd_vma) -2) + abort (); + + outrel.r_offset += (input_section->output_section->vma + + input_section->output_offset); + + if (h->dynindx == -1 + || h->forced_local + || bfd_link_executable (info)) + { + /* This symbol is resolved locally. */ + outrel.r_info = htab->r_info (0, R_X86_64_IRELATIVE); + outrel.r_addend = (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset); + } + else + { + outrel.r_info = htab->r_info (h->dynindx, r_type); + outrel.r_addend = 0; + } + + /* Dynamic relocations are stored in + 1. .rela.ifunc section in PIC object. + 2. .rela.got section in dynamic executable. + 3. .rela.iplt section in static executable. */ + if (bfd_link_pic (info)) + sreloc = htab->elf.irelifunc; + else if (htab->elf.splt != NULL) + sreloc = htab->elf.srelgot; + else + sreloc = htab->elf.irelplt; + elf_append_rela (output_bfd, sreloc, &outrel); + + /* If this reloc is against an external symbol, we + do not want to fiddle with the addend. Otherwise, + we need to include the symbol value so that it + becomes an addend for the dynamic reloc. For an + internal symbol, we have updated addend. */ + continue; + } + /* FALLTHROUGH */ + case R_X86_64_PC32: + case R_X86_64_PC32_BND: + case R_X86_64_PC64: + case R_X86_64_PLT32: + case R_X86_64_PLT32_BND: + goto do_relocation; + } } resolved_to_zero = (eh != NULL @@ -5870,6 +5915,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, && !local_undefweak) { Elf_Internal_Rela rela; + asection *relgot = htab->elf.srelgot; /* This symbol has an entry in the global offset table. Set it up. */ @@ -5888,7 +5934,27 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, if (h->def_regular && h->type == STT_GNU_IFUNC) { - if (bfd_link_pic (info)) + if (h->plt.offset == (bfd_vma) -1) + { + /* STT_GNU_IFUNC is referenced without PLT. */ + if (htab->elf.splt == NULL) + { + /* use .rel[a].iplt section to store .got relocations + in static executable. */ + relgot = htab->elf.irelplt; + } + if (SYMBOL_REFERENCES_LOCAL (info, h)) + { + rela.r_info = htab->r_info (0, + R_X86_64_IRELATIVE); + rela.r_addend = (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset); + } + else + goto do_glob_dat; + } + else if (bfd_link_pic (info)) { /* Generate R_X86_64_GLOB_DAT. */ goto do_glob_dat; @@ -5932,7 +5998,7 @@ do_glob_dat: rela.r_addend = 0; } - elf_append_rela (output_bfd, htab->elf.srelgot, &rela); + elf_append_rela (output_bfd, relgot, &rela); } if (h->needs_copy) @@ -6265,11 +6331,6 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd, elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE; - /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */ - htab_traverse (htab->loc_hash_table, - elf_x86_64_finish_local_dynamic_symbol, - info); - /* Fill PLT entries for undefined weak symbols in PIE. */ if (bfd_link_pie (info)) bfd_hash_traverse (&info->hash->table, @@ -6279,6 +6340,33 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd, return TRUE; } +/* Fill PLT/GOT entries and allocate dynamic relocations for local + STT_GNU_IFUNC symbols, which aren't in the ELF linker hash table. + It has to be done before elf_link_sort_relocs is called so that + dynamic relocations are properly sorted. */ + +static bfd_boolean +elf_x86_64_output_arch_local_syms + (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info, + void *flaginfo ATTRIBUTE_UNUSED, + int (*func) (void *, const char *, + Elf_Internal_Sym *, + asection *, + struct elf_link_hash_entry *) ATTRIBUTE_UNUSED) +{ + struct elf_x86_64_link_hash_table *htab = elf_x86_64_hash_table (info); + if (htab == NULL) + return FALSE; + + /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */ + htab_traverse (htab->loc_hash_table, + elf_x86_64_finish_local_dynamic_symbol, + info); + + return TRUE; +} + /* Return an array of PLT entry symbol values. */ static bfd_vma * @@ -6641,6 +6729,7 @@ static const struct bfd_elf_special_section #define elf_backend_create_dynamic_sections elf_x86_64_create_dynamic_sections #define elf_backend_finish_dynamic_sections elf_x86_64_finish_dynamic_sections #define elf_backend_finish_dynamic_symbol elf_x86_64_finish_dynamic_symbol +#define elf_backend_output_arch_local_syms elf_x86_64_output_arch_local_syms #define elf_backend_gc_mark_hook elf_x86_64_gc_mark_hook #define elf_backend_grok_prstatus elf_x86_64_grok_prstatus #define elf_backend_grok_psinfo elf_x86_64_grok_psinfo diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 774364a83a..fa66b0f595 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -8238,7 +8238,8 @@ elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, NULL, htab->plt_entry_size, htab->plt_header_size, - GOT_ENTRY_SIZE); + GOT_ENTRY_SIZE, + FALSE); return TRUE; } diff --git a/ld/ChangeLog b/ld/ChangeLog index cd5f4e3915..09de0c7a01 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,94 @@ +2016-06-18 H.J. Lu + + PR ld/20253 + * testsuite/ld-i386/i386.exp: Run PR ld/20253 tests. + * testsuite/ld-i386/no-plt.exp: Likewise. + * testsuite/ld-x86-64/no-plt.exp: Likewise. + * testsuite/ld-i386/pr13302.d: Remove .rel.plt section. + * testsuite/ld-ifunc/ifunc-13-i386.d: Likewise. + * testsuite/ld-ifunc/ifunc-13-x86-64.d: Likewise. + * testsuite/ld-ifunc/ifunc-15-i386.d: Likewise. + * testsuite/ld-ifunc/ifunc-15-x86-64.d: Likewise. + * testsuite/ld-x86-64/pr13082-5a.d: Likewise. + * testsuite/ld-x86-64/pr13082-5b.d: Likewise. + * testsuite/ld-x86-64/pr13082-6a.d: Likewise. + * testsuite/ld-x86-64/pr13082-6b.d: Likewise. + * testsuite/ld-i386/pr20244-2a.d: Remove .plt section. + * testsuite/ld-ifunc/ifunc-21-i386.d: Likewise. + * testsuite/ld-ifunc/ifunc-21-x86-64.d: Likewise. + * testsuite/ld-ifunc/ifunc-22-i386.d: Likewise. + * testsuite/ld-ifunc/ifunc-22-x86-64.d: Likewise. + * testsuite/ld-i386/pr20244-2b.d: Updated. + * testsuite/ld-i386/pr20244-2c.d: Likewise. + * testsuite/ld-ifunc/ifunc-18a-i386.d: Likewise. + * testsuite/ld-ifunc/ifunc-18a-x86-64.d: Likewise. + * testsuite/ld-ifunc/ifunc-18b-i386.d: Likewise. + * testsuite/ld-ifunc/ifunc-18b-x86-64.d: Likewise. + * testsuite/ld-i386/pr20253-1a.c: New file. + * testsuite/ld-i386/pr20253-1b.S: Likewise. + * testsuite/ld-i386/pr20253-1c.S: Likewise. + * testsuite/ld-i386/pr20253-1d.S: Likewise. + * testsuite/ld-i386/pr20253-2a.c: Likewise. + * testsuite/ld-i386/pr20253-2b.S: Likewise. + * testsuite/ld-i386/pr20253-2c.S: Likewise. + * testsuite/ld-i386/pr20253-2d.S: Likewise. + * testsuite/ld-i386/pr20253-3.d: Likewise. + * testsuite/ld-i386/pr20253-3.s: Likewise. + * testsuite/ld-i386/pr20253-4.s: Likewise. + * testsuite/ld-i386/pr20253-4a.d: Likewise. + * testsuite/ld-i386/pr20253-4b.d: Likewise. + * testsuite/ld-i386/pr20253-4c.d: Likewise. + * testsuite/ld-i386/pr20253-5.d: Likewise. + * testsuite/ld-i386/pr20253-5.s: Likewise. + * testsuite/ld-ifunc/ifunc-23-x86.s: Likewise. + * testsuite/ld-ifunc/ifunc-23a-x86.d: Likewise. + * testsuite/ld-ifunc/ifunc-23b-x86.d: Likewise. + * testsuite/ld-ifunc/ifunc-23c-x86.d: Likewise. + * testsuite/ld-ifunc/ifunc-24-x86.s: Likewise. + * testsuite/ld-ifunc/ifunc-24a-x86.d: Likewise. + * testsuite/ld-ifunc/ifunc-24b-x86.d: Likewise. + * testsuite/ld-ifunc/ifunc-24c-x86.d: Likewise. + * testsuite/ld-ifunc/ifunc-25-x86.s: Likewise. + * testsuite/ld-ifunc/ifunc-25a-x86.d: Likewise. + * testsuite/ld-ifunc/ifunc-25b-x86.d: Likewise. + * testsuite/ld-ifunc/ifunc-25c-x86.d: Likewise. + * testsuite/ld-x86-64/pr20253-1.s: Likewise. + * testsuite/ld-x86-64/pr20253-1a.d: Likewise. + * testsuite/ld-x86-64/pr20253-1b.d: Likewise. + * testsuite/ld-x86-64/pr20253-1c.d: Likewise. + * testsuite/ld-x86-64/pr20253-1d.d: Likewise. + * testsuite/ld-x86-64/pr20253-1e.d: Likewise. + * testsuite/ld-x86-64/pr20253-1f.d: Likewise. + * testsuite/ld-x86-64/pr20253-1g.d: Likewise. + * testsuite/ld-x86-64/pr20253-1h.d: Likewise. + * testsuite/ld-x86-64/pr20253-1i.d: Likewise. + * testsuite/ld-x86-64/pr20253-1j.d: Likewise. + * testsuite/ld-x86-64/pr20253-1k.d: Likewise. + * testsuite/ld-x86-64/pr20253-1l.d: Likewise. + * testsuite/ld-x86-64/pr20253-2a.c: Likewise. + * testsuite/ld-x86-64/pr20253-2b.S: Likewise. + * testsuite/ld-x86-64/pr20253-2c.S: Likewise. + * testsuite/ld-x86-64/pr20253-2d.S: Likewise. + * testsuite/ld-x86-64/pr20253-3.d: Likewise. + * testsuite/ld-x86-64/pr20253-3.s: Likewise. + * testsuite/ld-x86-64/pr20253-4.s: Likewise. + * testsuite/ld-x86-64/pr20253-4a.d: Likewise. + * testsuite/ld-x86-64/pr20253-4b.d: Likewise. + * testsuite/ld-x86-64/pr20253-4c.d: Likewise. + * testsuite/ld-x86-64/pr20253-4d.d: Likewise. + * testsuite/ld-x86-64/pr20253-4e.d: Likewise. + * testsuite/ld-x86-64/pr20253-4f.d: Likewise. + * testsuite/ld-x86-64/pr20253-5.s: Likewise. + * testsuite/ld-x86-64/pr20253-5a.d: Likewise. + * testsuite/ld-x86-64/pr20253-5b.d: Likewise. + * testsuite/ld-ifunc/ifunc-18a-i386.d: Remove extra IRELATIVE + relocation. + * testsuite/ld-ifunc/ifunc-18a-x86-64.d: Likewise. + * testsuite/ld-ifunc/ifunc-18b-i386.d: Likewise. + * testsuite/ld-ifunc/ifunc-18b-x86-64.d: Likewise. + * testsuite/ld-ifunc/ifunc-18a.s: Fix a typo. + * testsuite/ld-x86-64/x86-64.exp: Run pr20253-1 tests. + 2016-06-17 Thomas Preud'homme Tony Wang diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index 98f0b1c73f..9efe406b9b 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -408,6 +408,11 @@ run_dump_test "pr20244-2a" run_dump_test "pr20244-2b" run_dump_test "pr20244-2c" run_dump_test "pr20244-2d" +run_dump_test "pr20253-3" +run_dump_test "pr20253-4a" +run_dump_test "pr20253-4b" +run_dump_test "pr20253-4c" +run_dump_test "pr20253-5" if { !([istarget "i?86-*-linux*"] || [istarget "i?86-*-gnu*"] diff --git a/ld/testsuite/ld-i386/no-plt.exp b/ld/testsuite/ld-i386/no-plt.exp index c4af0a9b69..377253ce3b 100644 --- a/ld/testsuite/ld-i386/no-plt.exp +++ b/ld/testsuite/ld-i386/no-plt.exp @@ -265,6 +265,27 @@ if { [check_ifunc_available] } { "-fPIC -O2 -g" \ { pr20244-3a.c pr20244-3b.S pr20244-3c.S pr20244-3d.S } \ ] \ + [list \ + "Build pr20253-1a.o pr20253-1b.o pr20253-1c.o pr20253-1d.o" \ + "" \ + "-fPIE -O2 -g" \ + { pr20253-1a.c pr20253-1b.S pr20253-1c.S pr20253-1d.S } \ + ] \ + [list \ + "Build libpr20253-1a.so" \ + "-shared tmpdir/pr20253-1b.o \ + tmpdir/pr20253-1c.o tmpdir/pr20253-1d.o" \ + "" \ + { dummy.s } \ + {} \ + "libpr20253-1a.so" \ + ] \ + [list \ + "Build pr20253-2a.o pr20253-2b.o pr20253-2c.o pr20253-2d.o" \ + "" \ + "-fPIE -O2 -g" \ + { pr20253-2a.c pr20253-2b.S pr20253-2c.S pr20253-2d.S } \ + ] \ ] run_ld_link_exec_tests [] [list \ @@ -286,5 +307,102 @@ if { [check_ifunc_available] } { "pr20244-3b" \ "pass.out" \ ] \ + [list \ + "Run pr20253-1a" \ + "tmpdir/pr20253-1a.o tmpdir/pr20253-1b.o \ + tmpdir/pr20253-1c.o tmpdir/pr20253-1d.o" \ + "" \ + { dummy.s } \ + "pr20253-1a" \ + "pass.out" \ + ] \ + [list \ + "Run pr20253-1b" \ + "--static tmpdir/pr20253-1a.o tmpdir/pr20253-1b.o \ + tmpdir/pr20253-1c.o tmpdir/pr20253-1d.o" \ + "" \ + { dummy.s } \ + "pr20253-1b" \ + "pass.out" \ + ] \ + [list \ + "Run pr20253-1c" \ + "-pie tmpdir/pr20253-1a.o tmpdir/pr20253-1b.o \ + tmpdir/pr20253-1c.o tmpdir/pr20253-1d.o" \ + "" \ + { dummy.s } \ + "pr20253-1c" \ + "pass.out" \ + ] \ + [list \ + "Run pr20253-1d" \ + "tmpdir/pr20253-1a.o tmpdir/libpr20253-1a.so" \ + "" \ + { dummy.s } \ + "pr20253-1d" \ + "pass.out" \ + ] \ + [list \ + "Run pr20253-1e" \ + "-pie tmpdir/pr20253-1a.o tmpdir/libpr20253-1a.so" \ + "" \ + { dummy.s } \ + "pr20253-1e" \ + "pass.out" \ + ] \ + [list \ + "Run pr20253-1f" \ + "tmpdir/pr20253-1a.o" \ + "" \ + { pr20253-1b.S pr20253-1c.S pr20253-1d.S } \ + "pr20253-1f" \ + "pass.out" \ + "-DCHECK_PLT" \ + ] \ + [list \ + "Run pr20253-1g" \ + "--static tmpdir/pr20253-1a.o" \ + "" \ + { pr20253-1b.S pr20253-1c.S pr20253-1d.S } \ + "pr20253-1g" \ + "pass.out" \ + "-DCHECK_PLT" \ + ] \ + [list \ + "Run pr20253-2a" \ + "tmpdir/pr20253-2a.o tmpdir/pr20253-2b.o \ + tmpdir/pr20253-2c.o tmpdir/pr20253-2d.o" \ + "" \ + { dummy.s } \ + "pr20253-2a" \ + "pass.out" \ + ] \ + [list \ + "Run pr20253-2b" \ + "--static tmpdir/pr20253-2a.o tmpdir/pr20253-2b.o \ + tmpdir/pr20253-2c.o tmpdir/pr20253-2d.o" \ + "" \ + { dummy.s } \ + "pr20253-2b" \ + "pass.out" \ + ] \ + [list \ + "Run pr20253-2c" \ + "tmpdir/pr20253-2a.o" \ + "" \ + { pr20253-2b.S pr20253-2c.S pr20253-2d.S } \ + "pr20253-2c" \ + "pass.out" \ + "-DCHECK_PLT" \ + ] \ + [list \ + "Run pr20253-2d" \ + "--static tmpdir/pr20253-2a.o" \ + "" \ + { pr20253-2b.S pr20253-2c.S pr20253-2d.S } \ + "pr20253-2d" \ + "pass.out" \ + "-DCHECK_PLT" \ + ] \ ] } diff --git a/ld/testsuite/ld-i386/pr13302.d b/ld/testsuite/ld-i386/pr13302.d index 35c09ae0de..9ab4fa59ae 100644 --- a/ld/testsuite/ld-i386/pr13302.d +++ b/ld/testsuite/ld-i386/pr13302.d @@ -6,7 +6,3 @@ Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 1 entries: Offset Info Type Sym. Value Symbol's Name [0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE + - -Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entries: - Offset Info Type Sym. Value Symbol's Name -[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE + diff --git a/ld/testsuite/ld-i386/pr20244-2a.d b/ld/testsuite/ld-i386/pr20244-2a.d index a04902fb0f..ec3948e5bc 100644 --- a/ld/testsuite/ld-i386/pr20244-2a.d +++ b/ld/testsuite/ld-i386/pr20244-2a.d @@ -8,36 +8,25 @@ SYMBOL TABLE: #... -0+80480b1 l i .text 00000000 bar +0+8048085 l i .text 00000000 bar #... -0+80480b2 g F .text 00000000 _start +0+8048086 g F .text 00000000 _start #... -0+80480b0 g i .text 00000000 foo +0+8048084 g i .text 00000000 foo #... - -Disassembly of section .plt: - -0+8048090 <.plt>: - +[a-f0-9]+: ff 25 e0 90 04 08 jmp \*0x80490e0 - +[a-f0-9]+: 68 00 00 00 00 push \$0x0 - +[a-f0-9]+: e9 00 00 00 00 jmp 80480a0 - +[a-f0-9]+: ff 25 e4 90 04 08 jmp \*0x80490e4 - +[a-f0-9]+: 68 00 00 00 00 push \$0x0 - +[a-f0-9]+: e9 00 00 00 00 jmp 80480b0 - Disassembly of section .text: -0+80480b0 : +0+8048084 : +[a-f0-9]+: c3 ret -0+80480b1 : +0+8048085 : +[a-f0-9]+: c3 ret -0+80480b2 <_start>: - +[a-f0-9]+: ff 15 e0 90 04 08 call \*0x80490e0 - +[a-f0-9]+: ff 25 e4 90 04 08 jmp \*0x80490e4 - +[a-f0-9]+: c7 05 e4 90 04 08 00 00 00 00 movl \$0x0,0x80490e4 - +[a-f0-9]+: 83 3d e0 90 04 08 00 cmpl \$0x0,0x80490e0 - +[a-f0-9]+: b9 10 00 00 00 mov \$0x10,%ecx +0+8048086 <_start>: + +[a-f0-9]+: ff 15 a8 90 04 08 call \*0x80490a8 + +[a-f0-9]+: ff 25 ac 90 04 08 jmp \*0x80490ac + +[a-f0-9]+: c7 05 ac 90 04 08 00 00 00 00 movl \$0x0,0x80490ac + +[a-f0-9]+: 83 3d a8 90 04 08 00 cmpl \$0x0,0x80490a8 + +[a-f0-9]+: b9 fc ff ff ff mov \$0xfffffffc,%ecx #pass diff --git a/ld/testsuite/ld-i386/pr20244-2b.d b/ld/testsuite/ld-i386/pr20244-2b.d index fc0fa17ca0..f23a406553 100644 --- a/ld/testsuite/ld-i386/pr20244-2b.d +++ b/ld/testsuite/ld-i386/pr20244-2b.d @@ -7,5 +7,4 @@ .*: +file format .* Contents of section .got.plt: - 80490d4 00000000 00000000 00000000 b0800408 ................ - 80490e4 b1800408 .... + 80490b0 00000000 00000000 00000000 ............ diff --git a/ld/testsuite/ld-i386/pr20244-2c.d b/ld/testsuite/ld-i386/pr20244-2c.d index 54eee9f9c2..acca560000 100644 --- a/ld/testsuite/ld-i386/pr20244-2c.d +++ b/ld/testsuite/ld-i386/pr20244-2c.d @@ -6,5 +6,5 @@ Relocation section '.rel.plt' at offset 0x74 contains 2 entries: Offset Info Type Sym. Value Symbol's Name -0+80490e4 0000002a R_386_IRELATIVE -0+80490e0 0000002a R_386_IRELATIVE +0+80490ac 0000002a R_386_IRELATIVE +0+80490a8 0000002a R_386_IRELATIVE diff --git a/ld/testsuite/ld-i386/pr20253-1a.c b/ld/testsuite/ld-i386/pr20253-1a.c new file mode 100644 index 0000000000..370275a076 --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-1a.c @@ -0,0 +1,8 @@ +extern void check (void); + +int +main () +{ + check (); + return 0; +} diff --git a/ld/testsuite/ld-i386/pr20253-1b.S b/ld/testsuite/ld-i386/pr20253-1b.S new file mode 100644 index 0000000000..93c6d26287 --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-1b.S @@ -0,0 +1,52 @@ + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "PASS" + .text + .globl check + .type check, @function +check: + pushl %ebx + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + subl $8, %esp + call *get_func1@GOT(%ebx) +#ifdef CHECK_PLT + cmpl $func1, %eax +#else + cmpl func1@GOT(%ebx), %eax +#endif + jne .L3 + movl func1_p@GOT(%ebx), %edx + cmpl %eax, (%edx) + jne .L3 + call *func1@GOT(%ebx) + cmpl $1, %eax + jne .L3 + call *call_func1@GOT(%ebx) + cmpl $1, %eax + jne .L3 + call *get_func2@GOT(%ebx) + movl func2_p@GOT(%ebx), %edx + cmpl %eax, (%edx) + jne .L3 + call *call_func2@GOT(%ebx) + cmpl $2, %eax + jne .L3 + leal .LC0@GOTOFF(%ebx), %eax + subl $12, %esp + pushl %eax + call *puts@GOT(%ebx) + addl $24, %esp + popl %ebx + ret +.L3: + call *abort@GOT(%ebx) + .size check, .-check + .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat + .globl __x86.get_pc_thunk.bx + .hidden __x86.get_pc_thunk.bx + .type __x86.get_pc_thunk.bx, @function +__x86.get_pc_thunk.bx: + movl (%esp), %ebx + ret + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-i386/pr20253-1c.S b/ld/testsuite/ld-i386/pr20253-1c.S new file mode 100644 index 0000000000..8a17e7c26e --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-1c.S @@ -0,0 +1,35 @@ + .text + .globl get_func1 + .type get_func1, @function +get_func1: + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl func1@GOT(%eax), %eax + ret + .size get_func1, .-get_func1 + .globl call_func1 + .type call_func1, @function +call_func1: + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + jmp *func1@GOT(%eax) + .size call_func1, .-call_func1 + .globl func1_p +#ifdef CHECK_PLT + .section .rodata,"a",@progbits +#else + .section .data.rel,"aw",@progbits +#endif + .align 4 + .type func1_p, @object + .size func1_p, 4 +func1_p: + .long func1 + .section .text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat + .globl __x86.get_pc_thunk.ax + .hidden __x86.get_pc_thunk.ax + .type __x86.get_pc_thunk.ax, @function +__x86.get_pc_thunk.ax: + movl (%esp), %eax + ret + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-i386/pr20253-1d.S b/ld/testsuite/ld-i386/pr20253-1d.S new file mode 100644 index 0000000000..2d6a1de4fc --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-1d.S @@ -0,0 +1,81 @@ + .text + .type implementation1, @function +implementation1: + movl $1, %eax + ret + .size implementation1, .-implementation1 + .type implementation2, @function +implementation2: + movl $2, %eax + ret + .size implementation2, .-implementation2 + .type resolver2, @function +resolver2: + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + leal implementation2@GOTOFF(%eax), %eax + ret + .size resolver2, .-resolver2 + .type func2, @gnu_indirect_function + .set func2,resolver2 + .type resolver1, @function +resolver1: + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + leal implementation1@GOTOFF(%eax), %eax + ret + .size resolver1, .-resolver1 + .globl func1 + .type func1, @gnu_indirect_function + .set func1,resolver1 + .globl get_func2 + .type get_func2, @function +get_func2: + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl func2@GOT(%eax), %eax + ret + .size get_func2, .-get_func2 + .globl call_func2 + .type call_func2, @function +call_func2: + pushl %ebx + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + subl $8, %esp + call *get_func2@GOT(%ebx) + cmpl func2@GOT(%ebx), %eax + jne .L10 + addl $8, %esp + movl %ebx, %eax + popl %ebx + jmp *func2@GOT(%eax) +.L10: + call *abort@GOT(%ebx) + .size call_func2, .-call_func2 + .globl func2_p +#ifdef CHECK_PLT + .section .rodata,"a",@progbits +#else + .section .data.rel,"aw",@progbits +#endif + .align 4 + .type func2_p, @object + .size func2_p, 4 +func2_p: + .long func2 + .section .text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat + .globl __x86.get_pc_thunk.ax + .hidden __x86.get_pc_thunk.ax + .type __x86.get_pc_thunk.ax, @function +__x86.get_pc_thunk.ax: + movl (%esp), %eax + ret + .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat + .globl __x86.get_pc_thunk.bx + .hidden __x86.get_pc_thunk.bx + .type __x86.get_pc_thunk.bx, @function +__x86.get_pc_thunk.bx: + movl (%esp), %ebx + ret + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-i386/pr20253-2a.c b/ld/testsuite/ld-i386/pr20253-2a.c new file mode 100644 index 0000000000..370275a076 --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-2a.c @@ -0,0 +1,8 @@ +extern void check (void); + +int +main () +{ + check (); + return 0; +} diff --git a/ld/testsuite/ld-i386/pr20253-2b.S b/ld/testsuite/ld-i386/pr20253-2b.S new file mode 100644 index 0000000000..46ab4f4e65 --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-2b.S @@ -0,0 +1,39 @@ + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "PASS" + .text + .globl check + .type check, @function +check: + subl $12, %esp + call *get_func1@GOT +#ifdef CHECK_PLT + movl $func1, %edx +#else + movl func1@GOT, %edx +#endif + cmpl %edx, %eax + jne .L3 + cmpl %edx, func1_p + jne .L3 + call *func1@GOT + cmpl $1, %eax + jne .L3 + call *call_func1@GOT + cmpl $1, %eax + jne .L3 + call *get_func2@GOT + cmpl %eax, func2_p + jne .L3 + call *call_func2@GOT + cmpl $2, %eax + jne .L3 + subl $12, %esp + pushl $.LC0 + call *puts@GOT + addl $28, %esp + ret +.L3: + call *abort@GOT + .size check, .-check + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-i386/pr20253-2c.S b/ld/testsuite/ld-i386/pr20253-2c.S new file mode 100644 index 0000000000..7e724b47e0 --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-2c.S @@ -0,0 +1,24 @@ + .text + .globl get_func1 + .type get_func1, @function +get_func1: + movl func1@GOT, %eax + ret + .size get_func1, .-get_func1 + .globl call_func1 + .type call_func1, @function +call_func1: + jmp *func1@GOT + .size call_func1, .-call_func1 + .globl func1_p +#ifdef CHECK_PLT + .section .rodata,"a",@progbits +#else + .section .data.rel,"aw",@progbits +#endif + .align 4 + .type func1_p, @object + .size func1_p, 4 +func1_p: + .long func1 + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-i386/pr20253-2d.S b/ld/testsuite/ld-i386/pr20253-2d.S new file mode 100644 index 0000000000..5c1f9ae891 --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-2d.S @@ -0,0 +1,49 @@ + .text + .type implementation1, @function +implementation1: + movl $1, %eax + ret + .size implementation1, .-implementation1 + .type implementation2, @function +implementation2: + movl $2, %eax + ret + .size implementation2, .-implementation2 + .type resolver2, @function +resolver2: + movl $implementation2, %eax + ret + .size resolver2, .-resolver2 + .type func2, @gnu_indirect_function + .set func2,resolver2 + .type resolver1, @function +resolver1: + movl $implementation1, %eax + ret + .size resolver1, .-resolver1 + .globl func1 + .type func1, @gnu_indirect_function + .set func1,resolver1 + .globl get_func2 + .type get_func2, @function +get_func2: + movl func2@GOT, %eax + ret + .size get_func2, .-get_func2 + .globl call_func2 + .type call_func2, @function +call_func2: + jmp *func2@GOT + .size call_func2, .-call_func2 + .globl func2_p +#ifdef CHECK_PLT + .section .rodata,"a",@progbits +#else + .section .data.rel,"aw",@progbits +#endif + .align 4 + .type func2_p, @object + .size func2_p, 4 +func2_p: + .long func2 + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-i386/pr20253-3.d b/ld/testsuite/ld-i386/pr20253-3.d new file mode 100644 index 0000000000..7ce0b58765 --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-3.d @@ -0,0 +1,3 @@ +#as: --32 +#ld: -melf_i386 +#error: relocation R_386_PC32 against STT_GNU_IFUNC symbol `foo' isn't supported diff --git a/ld/testsuite/ld-i386/pr20253-3.s b/ld/testsuite/ld-i386/pr20253-3.s new file mode 100644 index 0000000000..8cd25fb7a9 --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-3.s @@ -0,0 +1,11 @@ + .text + .type foo,%gnu_indirect_function +foo: + ret + .globl _start +_start: + ret + .globl __start +__start: + .data + .long foo - . diff --git a/ld/testsuite/ld-i386/pr20253-4.s b/ld/testsuite/ld-i386/pr20253-4.s new file mode 100644 index 0000000000..88f0f1b41d --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-4.s @@ -0,0 +1,11 @@ + .text + .type foo,%gnu_indirect_function +foo: + ret + .globl _start +_start: + movl __start@GOT(%eax), %eax + .globl __start +__start: + .data + .dc.a foo diff --git a/ld/testsuite/ld-i386/pr20253-4a.d b/ld/testsuite/ld-i386/pr20253-4a.d new file mode 100644 index 0000000000..cd10080df3 --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-4a.d @@ -0,0 +1,8 @@ +#source: pr20253-4.s +#as: --32 -mrelax-relocations=yes +#ld: -melf_i386 +#readelf: -r --wide + +Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE + diff --git a/ld/testsuite/ld-i386/pr20253-4b.d b/ld/testsuite/ld-i386/pr20253-4b.d new file mode 100644 index 0000000000..3b45f8f6de --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-4b.d @@ -0,0 +1,8 @@ +#source: pr20253-4.s +#as: --32 -mrelax-relocations=yes +#ld: -pie -melf_i386 +#readelf: -r --wide + +Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE + diff --git a/ld/testsuite/ld-i386/pr20253-4c.d b/ld/testsuite/ld-i386/pr20253-4c.d new file mode 100644 index 0000000000..6fa68aa46a --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-4c.d @@ -0,0 +1,9 @@ +#source: pr20253-4.s +#as: --32 -mrelax-relocations=yes +#ld: -shared -melf_i386 +#readelf: -r --wide + +Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 2 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_GLOB_DAT +[0-9a-f]+ +__start +[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE + diff --git a/ld/testsuite/ld-i386/pr20253-5.d b/ld/testsuite/ld-i386/pr20253-5.d new file mode 100644 index 0000000000..0936d98b3a --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-5.d @@ -0,0 +1,7 @@ +#as: --32 +#ld: -melf_i386 +#readelf: -r --wide + +Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE + diff --git a/ld/testsuite/ld-i386/pr20253-5.s b/ld/testsuite/ld-i386/pr20253-5.s new file mode 100644 index 0000000000..0cc18035e9 --- /dev/null +++ b/ld/testsuite/ld-i386/pr20253-5.s @@ -0,0 +1,10 @@ + .text + .globl _start + .type _start, @function +_start: + call *func1@GOT(%eax) + cmp $func1,%eax + .globl func1 + .type func1, @gnu_indirect_function +func1: + ret diff --git a/ld/testsuite/ld-ifunc/ifunc-13-i386.d b/ld/testsuite/ld-ifunc/ifunc-13-i386.d index 677fa9284c..8dd3fed890 100644 --- a/ld/testsuite/ld-ifunc/ifunc-13-i386.d +++ b/ld/testsuite/ld-ifunc/ifunc-13-i386.d @@ -8,7 +8,3 @@ Relocation section '.rel.ifunc' at offset 0x[0-9a-f]+ contains 1 entries: [ ]+Offset[ ]+Info[ ]+Type[ ]+.* [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_32[ ]+ifunc\(\)[ ]+ifunc - -Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entries: -[ ]+Offset[ ]+Info[ ]+Type[ ]+.* -[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc diff --git a/ld/testsuite/ld-ifunc/ifunc-13-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-13-x86-64.d index b01c735679..1a1d061ac8 100644 --- a/ld/testsuite/ld-ifunc/ifunc-13-x86-64.d +++ b/ld/testsuite/ld-ifunc/ifunc-13-x86-64.d @@ -8,7 +8,3 @@ Relocation section '.rela.ifunc' at offset 0x[0-9a-f]+ contains 1 entries: [ ]+Offset[ ]+Info[ ]+Type[ ]+.* [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_64[ ]+ifunc\(\)[ ]+ifunc \+ 0 - -Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries: -[ ]+Offset[ ]+Info[ ]+Type[ ]+.* -[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc \+ 0 diff --git a/ld/testsuite/ld-ifunc/ifunc-15-i386.d b/ld/testsuite/ld-ifunc/ifunc-15-i386.d index c37dd51e66..0d44ba1b3a 100644 --- a/ld/testsuite/ld-ifunc/ifunc-15-i386.d +++ b/ld/testsuite/ld-ifunc/ifunc-15-i386.d @@ -7,7 +7,3 @@ Relocation section '.rel.got' at offset 0x[0-9a-f]+ contains 1 entries: [ ]+Offset[ ]+Info[ ]+Type[ ]+.* [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_GLOB_DAT[ ]+ifunc\(\)[ ]+ifunc - -Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entries: -[ ]+Offset[ ]+Info[ ]+Type[ ]+.* -[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc diff --git a/ld/testsuite/ld-ifunc/ifunc-15-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-15-x86-64.d index a4a5cb14cf..8a28ec9cda 100644 --- a/ld/testsuite/ld-ifunc/ifunc-15-x86-64.d +++ b/ld/testsuite/ld-ifunc/ifunc-15-x86-64.d @@ -7,7 +7,3 @@ Relocation section '.rela.got' at offset 0x[0-9a-f]+ contains 1 entries: [ ]+Offset[ ]+Info[ ]+Type[ ]+.* [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_GLOB_DAT[ ]+ifunc\(\)[ ]+ifunc \+ 0 - -Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries: -[ ]+Offset[ ]+Info[ ]+Type[ ]+.* -[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc \+ 0 diff --git a/ld/testsuite/ld-ifunc/ifunc-18a-i386.d b/ld/testsuite/ld-ifunc/ifunc-18a-i386.d index 10490b112b..7c392fb881 100644 --- a/ld/testsuite/ld-ifunc/ifunc-18a-i386.d +++ b/ld/testsuite/ld-ifunc/ifunc-18a-i386.d @@ -12,4 +12,3 @@ Relocation section '.rel.ifunc' at .* Relocation section '.rel.plt' at .* [ ]+Offset[ ]+Info[ ]+Type[ ]+.* [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]* -[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]* diff --git a/ld/testsuite/ld-ifunc/ifunc-18a-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-18a-x86-64.d index 0d600eb382..e9d603176c 100644 --- a/ld/testsuite/ld-ifunc/ifunc-18a-x86-64.d +++ b/ld/testsuite/ld-ifunc/ifunc-18a-x86-64.d @@ -12,4 +12,3 @@ Relocation section '.rela.ifunc' at .* Relocation section '.rela.plt' at .* [ ]+Offset[ ]+Info[ ]+Type[ ]+.* [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]* -[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-ifunc/ifunc-18a.s b/ld/testsuite/ld-ifunc/ifunc-18a.s index c29c121c23..f68c151ac9 100644 --- a/ld/testsuite/ld-ifunc/ifunc-18a.s +++ b/ld/testsuite/ld-ifunc/ifunc-18a.s @@ -1,5 +1,5 @@ .section .data.rel,"aw",@progbits - .globl foo_ptrt + .globl foo_ptr .type foo_ptr, @object foo_ptr: .dc.a foo diff --git a/ld/testsuite/ld-ifunc/ifunc-18b-i386.d b/ld/testsuite/ld-ifunc/ifunc-18b-i386.d index a5eda9495a..4b63c57f57 100644 --- a/ld/testsuite/ld-ifunc/ifunc-18b-i386.d +++ b/ld/testsuite/ld-ifunc/ifunc-18b-i386.d @@ -12,4 +12,3 @@ Relocation section '.rel.ifunc' at .* Relocation section '.rel.plt' at .* [ ]+Offset[ ]+Info[ ]+Type[ ]+.* [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]* -[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]* diff --git a/ld/testsuite/ld-ifunc/ifunc-18b-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-18b-x86-64.d index 8dfebfb8e9..b4ff6c3c41 100644 --- a/ld/testsuite/ld-ifunc/ifunc-18b-x86-64.d +++ b/ld/testsuite/ld-ifunc/ifunc-18b-x86-64.d @@ -12,4 +12,3 @@ Relocation section '.rela.ifunc' at .* Relocation section '.rela.plt' at .* [ ]+Offset[ ]+Info[ ]+Type[ ]+.* [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]* -[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-ifunc/ifunc-21-i386.d b/ld/testsuite/ld-ifunc/ifunc-21-i386.d index e609dbe74a..d61ccd0d9a 100644 --- a/ld/testsuite/ld-ifunc/ifunc-21-i386.d +++ b/ld/testsuite/ld-ifunc/ifunc-21-i386.d @@ -5,18 +5,20 @@ .*: +file format .* -#... -0+8048090 <__start>: -[ ]*[a-f0-9]+: ff 93 0c 00 00 00 call \*0xc\(%ebx\) -[ ]*[a-f0-9]+: ff a3 0c 00 00 00 jmp \*0xc\(%ebx\) -[ ]*[a-f0-9]+: 03 83 0c 00 00 00 add 0xc\(%ebx\),%eax -[ ]*[a-f0-9]+: 8b 83 0c 00 00 00 mov 0xc\(%ebx\),%eax -[ ]*[a-f0-9]+: 85 83 0c 00 00 00 test %eax,0xc\(%ebx\) -[ ]*[a-f0-9]+: c7 c0 b5 80 04 08 mov \$0x80480b5,%eax -0+80480b4 : -[ ]*[a-f0-9]+: c3 ret +Disassembly of section .text: -0+80480b5 : -[ ]*[a-f0-9]+: c3 ret +0+804807c <__start>: + +[a-f0-9]+: ff 93 fc ff ff ff call \*-0x4\(%ebx\) + +[a-f0-9]+: ff a3 fc ff ff ff jmp \*-0x4\(%ebx\) + +[a-f0-9]+: 03 83 fc ff ff ff add -0x4\(%ebx\),%eax + +[a-f0-9]+: 8b 83 fc ff ff ff mov -0x4\(%ebx\),%eax + +[a-f0-9]+: 85 83 fc ff ff ff test %eax,-0x4\(%ebx\) + +[a-f0-9]+: c7 c0 a1 80 04 08 mov \$0x80480a1,%eax + +0+80480a0 : + +[a-f0-9]+: c3 ret + +0+80480a1 : + +[a-f0-9]+: c3 ret #pass diff --git a/ld/testsuite/ld-ifunc/ifunc-21-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-21-x86-64.d index e28734e1cf..4e3582dee9 100644 --- a/ld/testsuite/ld-ifunc/ifunc-21-x86-64.d +++ b/ld/testsuite/ld-ifunc/ifunc-21-x86-64.d @@ -5,18 +5,20 @@ .*: +file format .* -#... -0+4000e0 <__start>: -[ ]*[a-f0-9]+: ff 15 42 00 20 00 callq \*0x200042\(%rip\) # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18> -[ ]*[a-f0-9]+: ff 25 3c 00 20 00 jmpq \*0x20003c\(%rip\) # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18> -[ ]*[a-f0-9]+: 48 03 05 35 00 20 00 add 0x200035\(%rip\),%rax # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18> -[ ]*[a-f0-9]+: 48 8b 05 2e 00 20 00 mov 0x20002e\(%rip\),%rax # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18> -[ ]*[a-f0-9]+: 48 85 05 27 00 20 00 test %rax,0x200027\(%rip\) # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18> -[ ]*[a-f0-9]+: 48 c7 c0 09 01 40 00 mov \$0x400109,%rax -0+400108 : -[ ]*[a-f0-9]+: c3 retq +Disassembly of section .text: -0+400109 : -[ ]*[a-f0-9]+: c3 retq +0+4000c8 <__start>: + +[a-f0-9]+: ff 15 2a 00 20 00 callq \*0x20002a\(%rip\) # 6000f8 + +[a-f0-9]+: ff 25 24 00 20 00 jmpq \*0x200024\(%rip\) # 6000f8 + +[a-f0-9]+: 48 03 05 1d 00 20 00 add 0x20001d\(%rip\),%rax # 6000f8 + +[a-f0-9]+: 48 8b 05 16 00 20 00 mov 0x200016\(%rip\),%rax # 6000f8 + +[a-f0-9]+: 48 85 05 0f 00 20 00 test %rax,0x20000f\(%rip\) # 6000f8 + +[a-f0-9]+: 48 c7 c0 f1 00 40 00 mov \$0x4000f1,%rax + +0+4000f0 : + +[a-f0-9]+: c3 retq + +0+4000f1 : + +[a-f0-9]+: c3 retq #pass diff --git a/ld/testsuite/ld-ifunc/ifunc-22-i386.d b/ld/testsuite/ld-ifunc/ifunc-22-i386.d index e609dbe74a..d61ccd0d9a 100644 --- a/ld/testsuite/ld-ifunc/ifunc-22-i386.d +++ b/ld/testsuite/ld-ifunc/ifunc-22-i386.d @@ -5,18 +5,20 @@ .*: +file format .* -#... -0+8048090 <__start>: -[ ]*[a-f0-9]+: ff 93 0c 00 00 00 call \*0xc\(%ebx\) -[ ]*[a-f0-9]+: ff a3 0c 00 00 00 jmp \*0xc\(%ebx\) -[ ]*[a-f0-9]+: 03 83 0c 00 00 00 add 0xc\(%ebx\),%eax -[ ]*[a-f0-9]+: 8b 83 0c 00 00 00 mov 0xc\(%ebx\),%eax -[ ]*[a-f0-9]+: 85 83 0c 00 00 00 test %eax,0xc\(%ebx\) -[ ]*[a-f0-9]+: c7 c0 b5 80 04 08 mov \$0x80480b5,%eax -0+80480b4 : -[ ]*[a-f0-9]+: c3 ret +Disassembly of section .text: -0+80480b5 : -[ ]*[a-f0-9]+: c3 ret +0+804807c <__start>: + +[a-f0-9]+: ff 93 fc ff ff ff call \*-0x4\(%ebx\) + +[a-f0-9]+: ff a3 fc ff ff ff jmp \*-0x4\(%ebx\) + +[a-f0-9]+: 03 83 fc ff ff ff add -0x4\(%ebx\),%eax + +[a-f0-9]+: 8b 83 fc ff ff ff mov -0x4\(%ebx\),%eax + +[a-f0-9]+: 85 83 fc ff ff ff test %eax,-0x4\(%ebx\) + +[a-f0-9]+: c7 c0 a1 80 04 08 mov \$0x80480a1,%eax + +0+80480a0 : + +[a-f0-9]+: c3 ret + +0+80480a1 : + +[a-f0-9]+: c3 ret #pass diff --git a/ld/testsuite/ld-ifunc/ifunc-22-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-22-x86-64.d index e28734e1cf..4e3582dee9 100644 --- a/ld/testsuite/ld-ifunc/ifunc-22-x86-64.d +++ b/ld/testsuite/ld-ifunc/ifunc-22-x86-64.d @@ -5,18 +5,20 @@ .*: +file format .* -#... -0+4000e0 <__start>: -[ ]*[a-f0-9]+: ff 15 42 00 20 00 callq \*0x200042\(%rip\) # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18> -[ ]*[a-f0-9]+: ff 25 3c 00 20 00 jmpq \*0x20003c\(%rip\) # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18> -[ ]*[a-f0-9]+: 48 03 05 35 00 20 00 add 0x200035\(%rip\),%rax # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18> -[ ]*[a-f0-9]+: 48 8b 05 2e 00 20 00 mov 0x20002e\(%rip\),%rax # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18> -[ ]*[a-f0-9]+: 48 85 05 27 00 20 00 test %rax,0x200027\(%rip\) # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18> -[ ]*[a-f0-9]+: 48 c7 c0 09 01 40 00 mov \$0x400109,%rax -0+400108 : -[ ]*[a-f0-9]+: c3 retq +Disassembly of section .text: -0+400109 : -[ ]*[a-f0-9]+: c3 retq +0+4000c8 <__start>: + +[a-f0-9]+: ff 15 2a 00 20 00 callq \*0x20002a\(%rip\) # 6000f8 + +[a-f0-9]+: ff 25 24 00 20 00 jmpq \*0x200024\(%rip\) # 6000f8 + +[a-f0-9]+: 48 03 05 1d 00 20 00 add 0x20001d\(%rip\),%rax # 6000f8 + +[a-f0-9]+: 48 8b 05 16 00 20 00 mov 0x200016\(%rip\),%rax # 6000f8 + +[a-f0-9]+: 48 85 05 0f 00 20 00 test %rax,0x20000f\(%rip\) # 6000f8 + +[a-f0-9]+: 48 c7 c0 f1 00 40 00 mov \$0x4000f1,%rax + +0+4000f0 : + +[a-f0-9]+: c3 retq + +0+4000f1 : + +[a-f0-9]+: c3 retq #pass diff --git a/ld/testsuite/ld-ifunc/ifunc-23-x86.s b/ld/testsuite/ld-ifunc/ifunc-23-x86.s new file mode 100644 index 0000000000..69c227909b --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-23-x86.s @@ -0,0 +1,10 @@ + .type foo,%gnu_indirect_function +foo: + ret + .globl _start +_start: + ret + .globl __start +__start: + .data + .dc.a foo diff --git a/ld/testsuite/ld-ifunc/ifunc-23a-x86.d b/ld/testsuite/ld-ifunc/ifunc-23a-x86.d new file mode 100644 index 0000000000..47ec5d1c09 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-23a-x86.d @@ -0,0 +1,8 @@ +#source: ifunc-23-x86.s +#ld: +#readelf: -r --wide +#target: x86_64-*-* i?86-*-* + +Relocation section '.rel(a|).plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]* diff --git a/ld/testsuite/ld-ifunc/ifunc-23b-x86.d b/ld/testsuite/ld-ifunc/ifunc-23b-x86.d new file mode 100644 index 0000000000..dbe2ec170c --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-23b-x86.d @@ -0,0 +1,8 @@ +#source: ifunc-23-x86.s +#ld: -pie +#readelf: -r --wide +#target: x86_64-*-* i?86-*-* + +Relocation section '.rel(a|).dyn' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]* diff --git a/ld/testsuite/ld-ifunc/ifunc-23c-x86.d b/ld/testsuite/ld-ifunc/ifunc-23c-x86.d new file mode 100644 index 0000000000..dc7e5c18f7 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-23c-x86.d @@ -0,0 +1,8 @@ +#source: ifunc-23-x86.s +#ld: -shared +#readelf: -r --wide +#target: x86_64-*-* i?86-*-* + +Relocation section '.rel(a|).dyn' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]* diff --git a/ld/testsuite/ld-ifunc/ifunc-24-x86.s b/ld/testsuite/ld-ifunc/ifunc-24-x86.s new file mode 100644 index 0000000000..967cdf6fc9 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-24-x86.s @@ -0,0 +1,11 @@ + .text + .type foo,%gnu_indirect_function +foo: + ret + .globl _start +_start: + call foo@PLT + .globl __start +__start: + .data + .dc.a foo diff --git a/ld/testsuite/ld-ifunc/ifunc-24a-x86.d b/ld/testsuite/ld-ifunc/ifunc-24a-x86.d new file mode 100644 index 0000000000..78bd4e2beb --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-24a-x86.d @@ -0,0 +1,8 @@ +#source: ifunc-24-x86.s +#ld: +#readelf: -r --wide +#target: x86_64-*-* i?86-*-* + +Relocation section '.rel(a|).plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]* diff --git a/ld/testsuite/ld-ifunc/ifunc-24b-x86.d b/ld/testsuite/ld-ifunc/ifunc-24b-x86.d new file mode 100644 index 0000000000..c73b019e7a --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-24b-x86.d @@ -0,0 +1,12 @@ +#source: ifunc-24-x86.s +#ld: -pie +#readelf: -r --wide +#target: x86_64-*-* i?86-*-* + +Relocation section '.rel(a|).dyn' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]* + +Relocation section '.rel(a|).plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]* diff --git a/ld/testsuite/ld-ifunc/ifunc-24c-x86.d b/ld/testsuite/ld-ifunc/ifunc-24c-x86.d new file mode 100644 index 0000000000..db167546d0 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-24c-x86.d @@ -0,0 +1,12 @@ +#source: ifunc-24-x86.s +#ld: -shared +#readelf: -r --wide +#target: x86_64-*-* i?86-*-* + +Relocation section '.rel(a|).dyn' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]* + +Relocation section '.rel(a|).plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]* diff --git a/ld/testsuite/ld-ifunc/ifunc-25-x86.s b/ld/testsuite/ld-ifunc/ifunc-25-x86.s new file mode 100644 index 0000000000..0549cbfa94 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-25-x86.s @@ -0,0 +1,12 @@ + .text + .globl foo + .type foo,%gnu_indirect_function +foo: + ret + .globl _start +_start: + call foo@PLT + .globl __start +__start: + .data + .dc.a foo diff --git a/ld/testsuite/ld-ifunc/ifunc-25a-x86.d b/ld/testsuite/ld-ifunc/ifunc-25a-x86.d new file mode 100644 index 0000000000..0f37f52c16 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-25a-x86.d @@ -0,0 +1,8 @@ +#source: ifunc-25-x86.s +#ld: +#readelf: -r --wide +#target: x86_64-*-* i?86-*-* + +Relocation section '.rel(a|).plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]* diff --git a/ld/testsuite/ld-ifunc/ifunc-25b-x86.d b/ld/testsuite/ld-ifunc/ifunc-25b-x86.d new file mode 100644 index 0000000000..96b0ed5efa --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-25b-x86.d @@ -0,0 +1,12 @@ +#source: ifunc-25-x86.s +#ld: -pie +#readelf: -r --wide +#target: x86_64-*-* i?86-*-* + +Relocation section '.rel(a|).dyn' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]* + +Relocation section '.rel(a|).plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]* diff --git a/ld/testsuite/ld-ifunc/ifunc-25c-x86.d b/ld/testsuite/ld-ifunc/ifunc-25c-x86.d new file mode 100644 index 0000000000..f9c08dc7a6 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-25c-x86.d @@ -0,0 +1,12 @@ +#source: ifunc-25-x86.s +#ld: -shared +#readelf: -r --wide +#target: x86_64-*-* i?86-*-* + +Relocation section '.rel(a|).dyn' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)_(32|64) +foo\(\) +foo( \+ 0|) + +Relocation section '.rel(a|).plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)_JUMP_SLOT +foo\(\) +foo( \+ 0|) diff --git a/ld/testsuite/ld-x86-64/no-plt.exp b/ld/testsuite/ld-x86-64/no-plt.exp index d57ccb51ce..bdf1843d52 100644 --- a/ld/testsuite/ld-x86-64/no-plt.exp +++ b/ld/testsuite/ld-x86-64/no-plt.exp @@ -199,3 +199,88 @@ run_ld_link_exec_tests [] [list \ "pass.out" \ ] \ ] + +# Run-time tests which require working IFUNC support. +if { [check_ifunc_available] } { + run_cc_link_tests [list \ + [list \ + "Build pr20253-2a.o pr20253-2b.o pr20253-2c.o pr20253-2d.o" \ + "" \ + "-fPIE -O2 -g" \ + { pr20253-2a.c pr20253-2b.S pr20253-2c.S pr20253-2d.S } \ + ] \ + [list \ + "Build libpr20253-2a.so" \ + "-shared tmpdir/pr20253-2b.o \ + tmpdir/pr20253-2c.o tmpdir/pr20253-2d.o" \ + "" \ + { dummy.s } \ + {} \ + "libpr20253-2a.so" \ + ] \ + ] + + run_ld_link_exec_tests [] [list \ + [list \ + "Run pr20253-2a" \ + "tmpdir/pr20253-2a.o tmpdir/pr20253-2b.o \ + tmpdir/pr20253-2c.o tmpdir/pr20253-2d.o" \ + "" \ + { dummy.s } \ + "pr20253-2a" \ + "pass.out" \ + ] \ + [list \ + "Run pr20253-2b" \ + "--static tmpdir/pr20253-2a.o tmpdir/pr20253-2b.o \ + tmpdir/pr20253-2c.o tmpdir/pr20253-2d.o" \ + "" \ + { dummy.s } \ + "pr20253-2b" \ + "pass.out" \ + ] \ + [list \ + "Run pr20253-2c" \ + "-pie tmpdir/pr20253-2a.o tmpdir/pr20253-2b.o \ + tmpdir/pr20253-2c.o tmpdir/pr20253-2d.o" \ + "" \ + { dummy.s } \ + "pr20253-2c" \ + "pass.out" \ + ] \ + [list \ + "Run pr20253-2d" \ + "tmpdir/pr20253-2a.o tmpdir/libpr20253-2a.so" \ + "" \ + { dummy.s } \ + "pr20253-2d" \ + "pass.out" \ + ] \ + [list \ + "Run pr20253-2e" \ + "-pie tmpdir/pr20253-2a.o tmpdir/libpr20253-2a.so" \ + "" \ + { dummy.s } \ + "pr20253-2e" \ + "pass.out" \ + ] \ + [list \ + "Run pr20253-2f" \ + "tmpdir/pr20253-2a.o" \ + "" \ + { pr20253-2b.S pr20253-2c.S pr20253-2d.S } \ + "pr20253-2f" \ + "pass.out" \ + "-DCHECK_PLT" \ + ] \ + [list \ + "Run pr20253-2g" \ + "--static tmpdir/pr20253-2a.o" \ + "" \ + { pr20253-2b.S pr20253-2c.S pr20253-2d.S } \ + "pr20253-2g" \ + "pass.out" \ + "-DCHECK_PLT" \ + ] \ + ] +} diff --git a/ld/testsuite/ld-x86-64/pr13082-5a.d b/ld/testsuite/ld-x86-64/pr13082-5a.d index 191c29e9af..d1b100d3b9 100644 --- a/ld/testsuite/ld-x86-64/pr13082-5a.d +++ b/ld/testsuite/ld-x86-64/pr13082-5a.d @@ -7,7 +7,3 @@ Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries: Offset Info Type Sym. Value Symbol's Name \+ Addend [0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +ifunc\(\)+ +ifunc \+ 0 - -Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries: - Offset Info Type Sym. Value Symbol's Name \+ Addend -[0-9a-f]+ +[0-9a-f]+ +R_X86_64_JUMP_SLOT +ifunc\(\)+ +ifunc \+ 0 diff --git a/ld/testsuite/ld-x86-64/pr13082-5b.d b/ld/testsuite/ld-x86-64/pr13082-5b.d index 1c5a5e79b5..01e403bbf5 100644 --- a/ld/testsuite/ld-x86-64/pr13082-5b.d +++ b/ld/testsuite/ld-x86-64/pr13082-5b.d @@ -7,7 +7,3 @@ Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries: Offset Info Type Sym. Value Symbol's Name \+ Addend [0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ - -Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries: - Offset Info Type Sym. Value Symbol's Name \+ Addend -[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr13082-6a.d b/ld/testsuite/ld-x86-64/pr13082-6a.d index 9a1a655185..5914f3d50e 100644 --- a/ld/testsuite/ld-x86-64/pr13082-6a.d +++ b/ld/testsuite/ld-x86-64/pr13082-6a.d @@ -7,7 +7,3 @@ Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries: Offset Info Type Sym. Value Symbol's Name \+ Addend [0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ - -Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries: - Offset Info Type Sym. Value Symbol's Name \+ Addend -[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr13082-6b.d b/ld/testsuite/ld-x86-64/pr13082-6b.d index 792c3483eb..6ff23ffcc5 100644 --- a/ld/testsuite/ld-x86-64/pr13082-6b.d +++ b/ld/testsuite/ld-x86-64/pr13082-6b.d @@ -7,7 +7,3 @@ Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries: Offset Info Type Sym. Value Symbol's Name \+ Addend [0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ - -Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries: - Offset Info Type Sym. Value Symbol's Name \+ Addend -[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr20253-1.s b/ld/testsuite/ld-x86-64/pr20253-1.s new file mode 100644 index 0000000000..4b9b7a426a --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-1.s @@ -0,0 +1,18 @@ + .text + .globl foo + .type foo, @gnu_indirect_function +foo: + ret + .text + .type bar, @gnu_indirect_function +bar: + ret + .globl _start + .type _start, @function +_start: + call *foo@GOTPCREL(%rip) + jmp *bar@GOTPCREL(%rip) + movq $0, bar@GOTPCREL(%rip) + cmpq $0, foo@GOTPCREL(%rip) + cmpq foo@GOTPCREL(%rip), %rcx + cmpq bar@GOTPCREL(%rip), %rcx diff --git a/ld/testsuite/ld-x86-64/pr20253-1a.d b/ld/testsuite/ld-x86-64/pr20253-1a.d new file mode 100644 index 0000000000..94c7c1d47d --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-1a.d @@ -0,0 +1,9 @@ +#source: pr20253-1.s +#as: --64 +#ld: -melf_x86_64 +#readelf: -r --wide + +Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 2 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr20253-1b.d b/ld/testsuite/ld-x86-64/pr20253-1b.d new file mode 100644 index 0000000000..247e042235 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-1b.d @@ -0,0 +1,25 @@ +#source: pr20253-1.s +#as: --64 +#ld: -melf_x86_64 +#objdump: -dw +#notarget: x86_64-*-nacl* + +.*: +file format .* + + +Disassembly of section .text: + +0+4000e0 : + +[a-f0-9]+: c3 retq + +0+4000e1 : + +[a-f0-9]+: c3 retq + +0+4000e2 <_start>: + +[a-f0-9]+: ff 15 28 00 20 00 callq \*0x200028\(%rip\) # 600110 <_start\+0x20002e> + +[a-f0-9]+: ff 25 2a 00 20 00 jmpq \*0x20002a\(%rip\) # 600118 <_start\+0x200036> + +[a-f0-9]+: 48 c7 05 1f 00 20 00 00 00 00 00 movq \$0x0,0x20001f\(%rip\) # 600118 <_start\+0x200036> + +[a-f0-9]+: 48 83 3d 0f 00 20 00 00 cmpq \$0x0,0x20000f\(%rip\) # 600110 <_start\+0x20002e> + +[a-f0-9]+: 48 3b 0d 08 00 20 00 cmp 0x200008\(%rip\),%rcx # 600110 <_start\+0x20002e> + +[a-f0-9]+: 48 3b 0d 09 00 20 00 cmp 0x200009\(%rip\),%rcx # 600118 <_start\+0x200036> +#pass diff --git a/ld/testsuite/ld-x86-64/pr20253-1c.d b/ld/testsuite/ld-x86-64/pr20253-1c.d new file mode 100644 index 0000000000..02c4542434 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-1c.d @@ -0,0 +1,9 @@ +#source: pr20253-1.s +#as: --64 +#ld: -pie -melf_x86_64 +#readelf: -r --wide + +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr20253-1d.d b/ld/testsuite/ld-x86-64/pr20253-1d.d new file mode 100644 index 0000000000..35c04f8e56 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-1d.d @@ -0,0 +1,25 @@ +#source: pr20253-1.s +#as: --64 +#ld: -pie -melf_x86_64 +#objdump: -dw +#notarget: x86_64-*-nacl* + +.*: +file format .* + + +Disassembly of section .text: + +0+1c8 : + +[a-f0-9]+: c3 retq + +0+1c9 : + +[a-f0-9]+: c3 retq + +0+1ca <_start>: + +[a-f0-9]+: ff 15 28 01 20 00 callq \*0x200128\(%rip\) # 2002f8 <_DYNAMIC\+0x100> + +[a-f0-9]+: ff 25 2a 01 20 00 jmpq \*0x20012a\(%rip\) # 200300 <_DYNAMIC\+0x108> + +[a-f0-9]+: 48 c7 05 1f 01 20 00 00 00 00 00 movq \$0x0,0x20011f\(%rip\) # 200300 <_DYNAMIC\+0x108> + +[a-f0-9]+: 48 83 3d 0f 01 20 00 00 cmpq \$0x0,0x20010f\(%rip\) # 2002f8 <_DYNAMIC\+0x100> + +[a-f0-9]+: 48 3b 0d 08 01 20 00 cmp 0x200108\(%rip\),%rcx # 2002f8 <_DYNAMIC\+0x100> + +[a-f0-9]+: 48 3b 0d 09 01 20 00 cmp 0x200109\(%rip\),%rcx # 200300 <_DYNAMIC\+0x108> +#pass diff --git a/ld/testsuite/ld-x86-64/pr20253-1e.d b/ld/testsuite/ld-x86-64/pr20253-1e.d new file mode 100644 index 0000000000..722fdf70fb --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-1e.d @@ -0,0 +1,9 @@ +#source: pr20253-1.s +#as: --64 +#ld: -shared -melf_x86_64 +#readelf: -r --wide + +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +foo\(\)+ +foo \+ 0 +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr20253-1f.d b/ld/testsuite/ld-x86-64/pr20253-1f.d new file mode 100644 index 0000000000..d84b60ec32 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-1f.d @@ -0,0 +1,25 @@ +#source: pr20253-1.s +#as: --64 +#ld: -shared -melf_x86_64 +#objdump: -dw +#notarget: x86_64-*-nacl* + +.*: +file format .* + + +Disassembly of section .text: + +0+1f8 : + +[a-f0-9]+: c3 retq + +0+1f9 : + +[a-f0-9]+: c3 retq + +0+1fa <_start>: + +[a-f0-9]+: ff 15 08 01 20 00 callq \*0x200108\(%rip\) # 200308 <_DYNAMIC\+0xe0> + +[a-f0-9]+: ff 25 0a 01 20 00 jmpq \*0x20010a\(%rip\) # 200310 <_DYNAMIC\+0xe8> + +[a-f0-9]+: 48 c7 05 ff 00 20 00 00 00 00 00 movq \$0x0,0x2000ff\(%rip\) # 200310 <_DYNAMIC\+0xe8> + +[a-f0-9]+: 48 83 3d ef 00 20 00 00 cmpq \$0x0,0x2000ef\(%rip\) # 200308 <_DYNAMIC\+0xe0> + +[a-f0-9]+: 48 3b 0d e8 00 20 00 cmp 0x2000e8\(%rip\),%rcx # 200308 <_DYNAMIC\+0xe0> + +[a-f0-9]+: 48 3b 0d e9 00 20 00 cmp 0x2000e9\(%rip\),%rcx # 200310 <_DYNAMIC\+0xe8> +#pass diff --git a/ld/testsuite/ld-x86-64/pr20253-1g.d b/ld/testsuite/ld-x86-64/pr20253-1g.d new file mode 100644 index 0000000000..671a980622 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-1g.d @@ -0,0 +1,9 @@ +#source: pr20253-1.s +#as: --x32 +#ld: -melf32_x86_64 +#readelf: -r --wide + +Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 2 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr20253-1h.d b/ld/testsuite/ld-x86-64/pr20253-1h.d new file mode 100644 index 0000000000..77ff100085 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-1h.d @@ -0,0 +1,25 @@ +#source: pr20253-1.s +#as: --x32 +#ld: -melf32_x86_64 +#objdump: -dw +#notarget: x86_64-*-nacl* + +.*: +file format .* + + +Disassembly of section .text: + +0+40008c : + +[a-f0-9]+: c3 retq + +0+40008d : + +[a-f0-9]+: c3 retq + +0+40008e <_start>: + +[a-f0-9]+: ff 15 28 00 20 00 callq \*0x200028\(%rip\) # 6000bc <_start\+0x20002e> + +[a-f0-9]+: ff 25 2a 00 20 00 jmpq \*0x20002a\(%rip\) # 6000c4 <_start\+0x200036> + +[a-f0-9]+: 48 c7 05 1f 00 20 00 00 00 00 00 movq \$0x0,0x20001f\(%rip\) # 6000c4 <_start\+0x200036> + +[a-f0-9]+: 48 83 3d 0f 00 20 00 00 cmpq \$0x0,0x20000f\(%rip\) # 6000bc <_start\+0x20002e> + +[a-f0-9]+: 48 3b 0d 08 00 20 00 cmp 0x200008\(%rip\),%rcx # 6000bc <_start\+0x20002e> + +[a-f0-9]+: 48 3b 0d 09 00 20 00 cmp 0x200009\(%rip\),%rcx # 6000c4 <_start\+0x200036> +#pass diff --git a/ld/testsuite/ld-x86-64/pr20253-1i.d b/ld/testsuite/ld-x86-64/pr20253-1i.d new file mode 100644 index 0000000000..bf42ed1c36 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-1i.d @@ -0,0 +1,9 @@ +#source: pr20253-1.s +#as: --x32 +#ld: -pie -melf32_x86_64 +#readelf: -r --wide + +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr20253-1j.d b/ld/testsuite/ld-x86-64/pr20253-1j.d new file mode 100644 index 0000000000..6f5d666f24 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-1j.d @@ -0,0 +1,25 @@ +#source: pr20253-1.s +#as: --x32 +#ld: -pie -melf32_x86_64 +#objdump: -dw +#notarget: x86_64-*-nacl* + +.*: +file format .* + + +Disassembly of section .text: + +0+120 : + +[a-f0-9]+: c3 retq + +0+121 : + +[a-f0-9]+: c3 retq + +0+122 <_start>: + +[a-f0-9]+: ff 15 a8 00 20 00 callq \*0x2000a8\(%rip\) # 2001d0 <_DYNAMIC\+0x80> + +[a-f0-9]+: ff 25 aa 00 20 00 jmpq \*0x2000aa\(%rip\) # 2001d8 <_DYNAMIC\+0x88> + +[a-f0-9]+: 48 c7 05 9f 00 20 00 00 00 00 00 movq \$0x0,0x20009f\(%rip\) # 2001d8 <_DYNAMIC\+0x88> + +[a-f0-9]+: 48 83 3d 8f 00 20 00 00 cmpq \$0x0,0x20008f\(%rip\) # 2001d0 <_DYNAMIC\+0x80> + +[a-f0-9]+: 48 3b 0d 88 00 20 00 cmp 0x200088\(%rip\),%rcx # 2001d0 <_DYNAMIC\+0x80> + +[a-f0-9]+: 48 3b 0d 89 00 20 00 cmp 0x200089\(%rip\),%rcx # 2001d8 <_DYNAMIC\+0x88> +#pass diff --git a/ld/testsuite/ld-x86-64/pr20253-1k.d b/ld/testsuite/ld-x86-64/pr20253-1k.d new file mode 100644 index 0000000000..1d557701f2 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-1k.d @@ -0,0 +1,9 @@ +#source: pr20253-1.s +#as: --x32 +#ld: -shared -melf32_x86_64 +#readelf: -r --wide + +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +foo\(\)+ +foo \+ 0 +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr20253-1l.d b/ld/testsuite/ld-x86-64/pr20253-1l.d new file mode 100644 index 0000000000..0276558360 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-1l.d @@ -0,0 +1,25 @@ +#source: pr20253-1.s +#as: --x32 +#ld: -shared -melf32_x86_64 +#objdump: -dw +#notarget: x86_64-*-nacl* + +.*: +file format .* + + +Disassembly of section .text: + +0+158 : + +[a-f0-9]+: c3 retq + +0+159 : + +[a-f0-9]+: c3 retq + +0+15a <_start>: + +[a-f0-9]+: ff 15 98 00 20 00 callq \*0x200098\(%rip\) # 2001f8 <_DYNAMIC\+0x70> + +[a-f0-9]+: ff 25 9a 00 20 00 jmpq \*0x20009a\(%rip\) # 200200 <_DYNAMIC\+0x78> + +[a-f0-9]+: 48 c7 05 8f 00 20 00 00 00 00 00 movq \$0x0,0x20008f\(%rip\) # 200200 <_DYNAMIC\+0x78> + +[a-f0-9]+: 48 83 3d 7f 00 20 00 00 cmpq \$0x0,0x20007f\(%rip\) # 2001f8 <_DYNAMIC\+0x70> + +[a-f0-9]+: 48 3b 0d 78 00 20 00 cmp 0x200078\(%rip\),%rcx # 2001f8 <_DYNAMIC\+0x70> + +[a-f0-9]+: 48 3b 0d 79 00 20 00 cmp 0x200079\(%rip\),%rcx # 200200 <_DYNAMIC\+0x78> +#pass diff --git a/ld/testsuite/ld-x86-64/pr20253-2a.c b/ld/testsuite/ld-x86-64/pr20253-2a.c new file mode 100644 index 0000000000..370275a076 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-2a.c @@ -0,0 +1,8 @@ +extern void check (void); + +int +main () +{ + check (); + return 0; +} diff --git a/ld/testsuite/ld-x86-64/pr20253-2b.S b/ld/testsuite/ld-x86-64/pr20253-2b.S new file mode 100644 index 0000000000..9bfab0cb47 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-2b.S @@ -0,0 +1,46 @@ + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "PASS" + .text + .globl check + .type check, @function +check: + subq $8, %rsp + call *get_func1@GOTPCREL(%rip) +#ifdef CHECK_PLT + cmpl $func1, %eax +#else + cmpq func1@GOTPCREL(%rip), %rax +#endif + jne .L3 + movq func1_p@GOTPCREL(%rip), %rdx +#ifdef __LP64__ + cmpq %rax, (%rdx) +#else + cmpl %eax, (%rdx) +#endif + jne .L3 + call *func1@GOTPCREL(%rip) + cmpl $1, %eax + jne .L3 + call *call_func1@GOTPCREL(%rip) + cmpl $1, %eax + jne .L3 + call *get_func2@GOTPCREL(%rip) + movq func2_p@GOTPCREL(%rip), %rdx +#ifdef __LP64__ + cmpq %rax, (%rdx) +#else + cmpl %eax, (%rdx) +#endif + jne .L3 + call *call_func2@GOTPCREL(%rip) + cmpl $2, %eax + jne .L3 + leaq .LC0(%rip), %rdi + addq $8, %rsp + jmp *puts@GOTPCREL(%rip) +.L3: + call *abort@GOTPCREL(%rip) + .size check, .-check + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-x86-64/pr20253-2c.S b/ld/testsuite/ld-x86-64/pr20253-2c.S new file mode 100644 index 0000000000..5ec7e764b4 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-2c.S @@ -0,0 +1,29 @@ + .text + .globl get_func1 + .type get_func1, @function +get_func1: + movq func1@GOTPCREL(%rip), %rax + ret + .size get_func1, .-get_func1 + .globl call_func1 + .type call_func1, @function +call_func1: + jmp *func1@GOTPCREL(%rip) + .size call_func1, .-call_func1 + .globl func1_p +#ifdef CHECK_PLT + .section .rodata,"a",@progbits +#else + .section .data.rel,"aw",@progbits +#endif +#ifdef __LP64__ + .align 8 + .size func1_p, 8 +#else + .align 4 + .size func1_p, 4 +#endif + .type func1_p, @object +func1_p: + .dc.a func1 + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-x86-64/pr20253-2d.S b/ld/testsuite/ld-x86-64/pr20253-2d.S new file mode 100644 index 0000000000..bc4c32e1b0 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-2d.S @@ -0,0 +1,61 @@ + .text + .type implementation1, @function +implementation1: + movl $1, %eax + ret + .size implementation1, .-implementation1 + .type implementation2, @function +implementation2: + movl $2, %eax + ret + .size implementation2, .-implementation2 + .type resolver2, @function +resolver2: + leaq implementation2(%rip), %rax + ret + .size resolver2, .-resolver2 + .type func2, @gnu_indirect_function + .set func2,resolver2 + .type resolver1, @function +resolver1: + leaq implementation1(%rip), %rax + ret + .size resolver1, .-resolver1 + .globl func1 + .type func1, @gnu_indirect_function + .set func1,resolver1 + .globl get_func2 + .type get_func2, @function +get_func2: + movq func2@GOTPCREL(%rip), %rax + ret + .size get_func2, .-get_func2 + .globl call_func2 + .type call_func2, @function +call_func2: + subq $8, %rsp + call *get_func2@GOTPCREL(%rip) + cmpq func2@GOTPCREL(%rip), %rax + jne .L10 + addq $8, %rsp + jmp *func2@GOTPCREL(%rip) +.L10: + call *abort@GOTPCREL(%rip) + .size call_func2, .-call_func2 + .globl func2_p +#ifdef CHECK_PLT + .section .rodata,"a",@progbits +#else + .section .data.rel,"aw",@progbits +#endif +#ifdef __LP64__ + .align 8 + .size func2_p, 8 +#else + .align 4 + .size func2_p, 4 +#endif + .type func2_p, @object +func2_p: + .dc.a func2 + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-x86-64/pr20253-3.d b/ld/testsuite/ld-x86-64/pr20253-3.d new file mode 100644 index 0000000000..30db29c64e --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-3.d @@ -0,0 +1,3 @@ +#as: --64 +#ld: -melf_x86_64 +#error: relocation R_X86_64_PC32 against STT_GNU_IFUNC symbol `foo' isn't supported diff --git a/ld/testsuite/ld-x86-64/pr20253-3.s b/ld/testsuite/ld-x86-64/pr20253-3.s new file mode 100644 index 0000000000..8cd25fb7a9 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-3.s @@ -0,0 +1,11 @@ + .text + .type foo,%gnu_indirect_function +foo: + ret + .globl _start +_start: + ret + .globl __start +__start: + .data + .long foo - . diff --git a/ld/testsuite/ld-x86-64/pr20253-4.s b/ld/testsuite/ld-x86-64/pr20253-4.s new file mode 100644 index 0000000000..7dc9aa36f5 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-4.s @@ -0,0 +1,11 @@ + .text + .type foo,%gnu_indirect_function +foo: + ret + .globl _start +_start: + movq __start@GOTPCREL(%rip), %rax + .globl __start +__start: + .data + .dc.a foo diff --git a/ld/testsuite/ld-x86-64/pr20253-4a.d b/ld/testsuite/ld-x86-64/pr20253-4a.d new file mode 100644 index 0000000000..041c1642ea --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-4a.d @@ -0,0 +1,8 @@ +#source: pr20253-4.s +#as: --64 +#ld: -melf_x86_64 +#readelf: -r --wide + +Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr20253-4b.d b/ld/testsuite/ld-x86-64/pr20253-4b.d new file mode 100644 index 0000000000..6dc95b5dfe --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-4b.d @@ -0,0 +1,8 @@ +#source: pr20253-4.s +#as: --64 +#ld: -pie -melf_x86_64 +#readelf: -r --wide + +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr20253-4c.d b/ld/testsuite/ld-x86-64/pr20253-4c.d new file mode 100644 index 0000000000..26fa0df789 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-4c.d @@ -0,0 +1,9 @@ +#source: pr20253-4.s +#as: --64 +#ld: -shared -melf_x86_64 +#readelf: -r --wide + +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +[0-9a-f]+ +__start \+ 0 +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr20253-4d.d b/ld/testsuite/ld-x86-64/pr20253-4d.d new file mode 100644 index 0000000000..52dd8779f5 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-4d.d @@ -0,0 +1,8 @@ +#source: pr20253-4.s +#as: --x32 +#ld: -melf32_x86_64 +#readelf: -r --wide + +Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr20253-4e.d b/ld/testsuite/ld-x86-64/pr20253-4e.d new file mode 100644 index 0000000000..d9f2fa4c42 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-4e.d @@ -0,0 +1,8 @@ +#source: pr20253-4.s +#as: --x32 +#ld: -pie -melf32_x86_64 +#readelf: -r --wide + +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr20253-4f.d b/ld/testsuite/ld-x86-64/pr20253-4f.d new file mode 100644 index 0000000000..fb3d6f8e67 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-4f.d @@ -0,0 +1,9 @@ +#source: pr20253-4.s +#as: --x32 +#ld: -shared -melf32_x86_64 +#readelf: -r --wide + +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +[0-9a-f]+ +__start \+ 0 +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr20253-5.s b/ld/testsuite/ld-x86-64/pr20253-5.s new file mode 100644 index 0000000000..ade0e8befc --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-5.s @@ -0,0 +1,10 @@ + .text + .globl _start + .type _start, @function +_start: + call *func1@GOTPCREL(%rip) + cmp $func1,%eax + .globl func1 + .type func1, @gnu_indirect_function +func1: + ret diff --git a/ld/testsuite/ld-x86-64/pr20253-5a.d b/ld/testsuite/ld-x86-64/pr20253-5a.d new file mode 100644 index 0000000000..1eceda4375 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-5a.d @@ -0,0 +1,8 @@ +#source: pr20253-5.s +#as: --64 +#ld: -melf_x86_64 +#readelf: -r --wide + +Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr20253-5b.d b/ld/testsuite/ld-x86-64/pr20253-5b.d new file mode 100644 index 0000000000..c1cb335de7 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr20253-5b.d @@ -0,0 +1,8 @@ +#source: pr20253-5.s +#as: --x32 +#ld: -melf32_x86_64 +#readelf: -r --wide + +Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 7fd953b8b7..f6f89e2aad 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -503,6 +503,27 @@ run_dump_test "pr19609-7d" run_dump_test "pr19939a" run_dump_test "pr19939b" run_dump_test "pr19719" +run_dump_test "pr20253-1a" +run_dump_test "pr20253-1b" +run_dump_test "pr20253-1c" +run_dump_test "pr20253-1d" +run_dump_test "pr20253-1e" +run_dump_test "pr20253-1f" +run_dump_test "pr20253-1g" +run_dump_test "pr20253-1h" +run_dump_test "pr20253-1i" +run_dump_test "pr20253-1j" +run_dump_test "pr20253-1k" +run_dump_test "pr20253-1l" +run_dump_test "pr20253-3" +run_dump_test "pr20253-4a" +run_dump_test "pr20253-4b" +run_dump_test "pr20253-4c" +run_dump_test "pr20253-4d" +run_dump_test "pr20253-4e" +run_dump_test "pr20253-4f" +run_dump_test "pr20253-5a" +run_dump_test "pr20253-5b" proc undefined_weak {cflags ldflags} { set testname "Undefined weak symbol"