Disallow copy relocation against protected data symbol
We shpouldn't generate copy relocation to resolve reference to protected data symbol defined in shared object with the NO_COPY_ON_PROTECTED property. This patch adds a bit to elf_obj_tdata as well as elf_i386_link_hash_entry and elf_x86_64_link_hash_entry to track the bfd with the NO_COPY_ON_PROTECTED property as well as protected symbol defined in shared object. extern_protected_data is set to FALSE if any input relocatable file contains the NO_COPY_ON_PROTECTED property. bfd/ PR ld/21997 * elf-bfd.h (elf_obj_tdata): Use ENUM_BITFIELD on object_id, dyn_lib_class and has_gnu_symbols. Change bad_symtab to bitfield. Add a has_no_copy_on_protected bitfield. (elf_has_no_copy_on_protected): New. * elf-properties.c (_bfd_elf_parse_gnu_properties): Set elf_has_no_copy_on_protected for GNU_PROPERTY_NO_COPY_ON_PROTECTED. (elf_merge_gnu_property_list): Likewise. (_bfd_elf_link_setup_gnu_properties): Set extern_protected_data to FALSE for elf_has_no_copy_on_protected. * elf32-i386.c (SYMBOL_NO_COPYRELOC): New. (elf_i386_link_hash_entry): Add def_protected. (elf_i386_adjust_dynamic_symbol): Also check SYMBOL_NO_COPYRELOC when checking info->nocopyreloc. (elf_i386_link_setup_gnu_properties): Don't set extern_protected_data here. (elf_i386_merge_symbol_attribute): New function. (elf_backend_merge_symbol_attribute): New. * elf64-x86-64.c (SYMBOL_NO_COPYRELOC): New. (elf_x86_64_link_hash_entry): Add def_protected. (elf_x86_64_need_pic): Report protected symbol for def_protected. (elf_x86_64_adjust_dynamic_symbol): Also check SYMBOL_NO_COPYRELOC when checking info->nocopyreloc. (elf_x86_64_relocate_section): Also check for R_X86_64_PC32 relocation run-time overflow and unresolvable R_X86_64_32S relocation against protected data symbol defined in shared object with GNU_PROPERTY_NO_COPY_ON_PROTECTED. (elf_x86_64_link_setup_gnu_properties): Don't set extern_protected_data here. (elf_x86_64_merge_symbol_attribute): New function. (elf_backend_merge_symbol_attribute): New. ld/ PR ld/21997 * testsuite/ld-i386/i386.exp: Run PR ld/21997 tests. * testsuite/ld-x86-64/x86-64.exp: Likewise. * testsuite/ld-i386/pr21997-1a.S: New file. * testsuite/ld-i386/pr21997-1b.c: Likewise. * testsuite/ld-i386/pr21997-1c.S: Likewise. * testsuite/ld-x86-64/pr21997-1a.S: Likewise. * testsuite/ld-x86-64/pr21997-1a.err: Likewise. * testsuite/ld-x86-64/pr21997-1b.c: Likewise. * testsuite/ld-x86-64/pr21997-1b.err: Likewise. * testsuite/ld-x86-64/pr21997-1c.c: Likewise.
This commit is contained in:
parent
aecbb010f9
commit
a5b4ee9451
|
@ -1,3 +1,37 @@
|
||||||
|
2017-08-26 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
PR ld/21997
|
||||||
|
* elf-bfd.h (elf_obj_tdata): Use ENUM_BITFIELD on object_id,
|
||||||
|
dyn_lib_class and has_gnu_symbols. Change bad_symtab to bitfield.
|
||||||
|
Add a has_no_copy_on_protected bitfield.
|
||||||
|
(elf_has_no_copy_on_protected): New.
|
||||||
|
* elf-properties.c (_bfd_elf_parse_gnu_properties): Set
|
||||||
|
elf_has_no_copy_on_protected for GNU_PROPERTY_NO_COPY_ON_PROTECTED.
|
||||||
|
(elf_merge_gnu_property_list): Likewise.
|
||||||
|
(_bfd_elf_link_setup_gnu_properties): Set extern_protected_data
|
||||||
|
to FALSE for elf_has_no_copy_on_protected.
|
||||||
|
* elf32-i386.c (SYMBOL_NO_COPYRELOC): New.
|
||||||
|
(elf_i386_link_hash_entry): Add def_protected.
|
||||||
|
(elf_i386_adjust_dynamic_symbol): Also check SYMBOL_NO_COPYRELOC
|
||||||
|
when checking info->nocopyreloc.
|
||||||
|
(elf_i386_link_setup_gnu_properties): Don't set
|
||||||
|
extern_protected_data here.
|
||||||
|
(elf_i386_merge_symbol_attribute): New function.
|
||||||
|
(elf_backend_merge_symbol_attribute): New.
|
||||||
|
* elf64-x86-64.c (SYMBOL_NO_COPYRELOC): New.
|
||||||
|
(elf_x86_64_link_hash_entry): Add def_protected.
|
||||||
|
(elf_x86_64_need_pic): Report protected symbol for def_protected.
|
||||||
|
(elf_x86_64_adjust_dynamic_symbol): Also check SYMBOL_NO_COPYRELOC
|
||||||
|
when checking info->nocopyreloc.
|
||||||
|
(elf_x86_64_relocate_section): Also check for R_X86_64_PC32
|
||||||
|
relocation run-time overflow and unresolvable R_X86_64_32S
|
||||||
|
relocation against protected data symbol defined in shared object
|
||||||
|
with GNU_PROPERTY_NO_COPY_ON_PROTECTED.
|
||||||
|
(elf_x86_64_link_setup_gnu_properties): Don't set
|
||||||
|
extern_protected_data here.
|
||||||
|
(elf_x86_64_merge_symbol_attribute): New function.
|
||||||
|
(elf_backend_merge_symbol_attribute): New.
|
||||||
|
|
||||||
2017-08-26 Alan Modra <amodra@gmail.com>
|
2017-08-26 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* elf32-ppc.c (must_be_dyn_reloc): Use bfd_link_dll. Comment.
|
* elf32-ppc.c (must_be_dyn_reloc): Use bfd_link_dll. Comment.
|
||||||
|
|
|
@ -1887,21 +1887,27 @@ struct elf_obj_tdata
|
||||||
|
|
||||||
/* An identifier used to distinguish different target
|
/* An identifier used to distinguish different target
|
||||||
specific extensions to this structure. */
|
specific extensions to this structure. */
|
||||||
enum elf_target_id object_id;
|
ENUM_BITFIELD (elf_target_id) object_id : 6;
|
||||||
|
|
||||||
/* Whether a dyanmic object was specified normally on the linker
|
/* Whether a dyanmic object was specified normally on the linker
|
||||||
command line, or was specified when --as-needed was in effect,
|
command line, or was specified when --as-needed was in effect,
|
||||||
or was found via a DT_NEEDED entry. */
|
or was found via a DT_NEEDED entry. */
|
||||||
enum dynamic_lib_link_class dyn_lib_class;
|
ENUM_BITFIELD (dynamic_lib_link_class) dyn_lib_class : 4;
|
||||||
|
|
||||||
|
/* Whether if the bfd contains symbols that have the STT_GNU_IFUNC
|
||||||
|
symbol type or STB_GNU_UNIQUE binding. */
|
||||||
|
ENUM_BITFIELD (elf_gnu_symbols) has_gnu_symbols : 3;
|
||||||
|
|
||||||
|
/* Whether if the bfd contains the GNU_PROPERTY_NO_COPY_ON_PROTECTED
|
||||||
|
property. */
|
||||||
|
unsigned int has_no_copy_on_protected : 1;
|
||||||
|
|
||||||
/* Irix 5 often screws up the symbol table, sorting local symbols
|
/* Irix 5 often screws up the symbol table, sorting local symbols
|
||||||
after global symbols. This flag is set if the symbol table in
|
after global symbols. This flag is set if the symbol table in
|
||||||
this BFD appears to be screwed up. If it is, we ignore the
|
this BFD appears to be screwed up. If it is, we ignore the
|
||||||
sh_info field in the symbol table header, and always read all the
|
sh_info field in the symbol table header, and always read all the
|
||||||
symbols. */
|
symbols. */
|
||||||
bfd_boolean bad_symtab;
|
unsigned int bad_symtab : 1;
|
||||||
|
|
||||||
enum elf_gnu_symbols has_gnu_symbols;
|
|
||||||
|
|
||||||
/* Information grabbed from an elf core file. */
|
/* Information grabbed from an elf core file. */
|
||||||
struct core_elf_obj_tdata *core;
|
struct core_elf_obj_tdata *core;
|
||||||
|
@ -1956,6 +1962,8 @@ struct elf_obj_tdata
|
||||||
#define elf_other_obj_attributes_proc(bfd) \
|
#define elf_other_obj_attributes_proc(bfd) \
|
||||||
(elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
|
(elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
|
||||||
#define elf_properties(bfd) (elf_tdata (bfd) -> properties)
|
#define elf_properties(bfd) (elf_tdata (bfd) -> properties)
|
||||||
|
#define elf_has_no_copy_on_protected(bfd) \
|
||||||
|
(elf_tdata(bfd) -> has_no_copy_on_protected)
|
||||||
|
|
||||||
extern void _bfd_elf_swap_verdef_in
|
extern void _bfd_elf_swap_verdef_in
|
||||||
(bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
|
(bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
|
||||||
|
|
|
@ -168,6 +168,7 @@ bad_size:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
prop = _bfd_elf_get_property (abfd, type, datasz);
|
prop = _bfd_elf_get_property (abfd, type, datasz);
|
||||||
|
elf_has_no_copy_on_protected (abfd) = TRUE;
|
||||||
prop->pr_kind = property_number;
|
prop->pr_kind = property_number;
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
|
@ -290,6 +291,9 @@ elf_merge_gnu_property_list (struct bfd_link_info *info, bfd *abfd,
|
||||||
for (p = *listp; p != NULL; p = p->next)
|
for (p = *listp; p != NULL; p = p->next)
|
||||||
if (elf_merge_gnu_properties (info, abfd, NULL, &p->property))
|
if (elf_merge_gnu_properties (info, abfd, NULL, &p->property))
|
||||||
{
|
{
|
||||||
|
if (p->property.pr_type == GNU_PROPERTY_NO_COPY_ON_PROTECTED)
|
||||||
|
elf_has_no_copy_on_protected (abfd) = TRUE;
|
||||||
|
|
||||||
pr = _bfd_elf_get_property (abfd, p->property.pr_type,
|
pr = _bfd_elf_get_property (abfd, p->property.pr_type,
|
||||||
p->property.pr_datasz);
|
p->property.pr_datasz);
|
||||||
/* It must be a new property. */
|
/* It must be a new property. */
|
||||||
|
@ -489,6 +493,11 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
|
||||||
|
|
||||||
/* Cache the section contents for elf_link_input_bfd. */
|
/* Cache the section contents for elf_link_input_bfd. */
|
||||||
elf_section_data (sec)->this_hdr.contents = contents;
|
elf_section_data (sec)->this_hdr.contents = contents;
|
||||||
|
|
||||||
|
/* If GNU_PROPERTY_NO_COPY_ON_PROTECTED is set, protected data
|
||||||
|
symbol is defined in the shared object. */
|
||||||
|
if (elf_has_no_copy_on_protected (first_pbfd))
|
||||||
|
info->extern_protected_data = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return first_pbfd;
|
return first_pbfd;
|
||||||
|
|
121
bfd/elf32-i386.c
121
bfd/elf32-i386.c
|
@ -956,6 +956,18 @@ static const struct elf_i386_backend_data elf_i386_arch_bed =
|
||||||
|| (EH)->has_non_got_reloc \
|
|| (EH)->has_non_got_reloc \
|
||||||
|| !(INFO)->dynamic_undefined_weak))))
|
|| !(INFO)->dynamic_undefined_weak))))
|
||||||
|
|
||||||
|
/* Should copy relocation be generated for a symbol. Don't generate
|
||||||
|
copy relocation against a protected symbol defined in a shared
|
||||||
|
object with GNU_PROPERTY_NO_COPY_ON_PROTECTED. */
|
||||||
|
#define SYMBOL_NO_COPYRELOC(INFO, EH) \
|
||||||
|
((EH)->def_protected \
|
||||||
|
&& ((EH)->elf.root.type == bfd_link_hash_defined \
|
||||||
|
|| (EH)->elf.root.type == bfd_link_hash_defweak) \
|
||||||
|
&& elf_has_no_copy_on_protected ((EH)->elf.root.u.def.section->owner) \
|
||||||
|
&& ((EH)->elf.root.u.def.section->owner->flags & DYNAMIC) != 0 \
|
||||||
|
&& ((EH)->elf.root.u.def.section->flags & SEC_CODE) == 0)
|
||||||
|
|
||||||
|
|
||||||
/* i386 ELF linker hash entry. */
|
/* i386 ELF linker hash entry. */
|
||||||
|
|
||||||
struct elf_i386_link_hash_entry
|
struct elf_i386_link_hash_entry
|
||||||
|
@ -998,6 +1010,9 @@ struct elf_i386_link_hash_entry
|
||||||
/* TRUE if symbol is __tls_get_addr. */
|
/* TRUE if symbol is __tls_get_addr. */
|
||||||
unsigned int tls_get_addr : 1;
|
unsigned int tls_get_addr : 1;
|
||||||
|
|
||||||
|
/* TRUE if symbol is defined as a protected symbol. */
|
||||||
|
unsigned int def_protected : 1;
|
||||||
|
|
||||||
/* Reference count of C/C++ function pointer relocations in read-write
|
/* Reference count of C/C++ function pointer relocations in read-write
|
||||||
section which can be resolved at run-time. */
|
section which can be resolved at run-time. */
|
||||||
bfd_signed_vma func_pointer_refcount;
|
bfd_signed_vma func_pointer_refcount;
|
||||||
|
@ -2590,6 +2605,8 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
|
||||||
the link may change h->type. So fix it now. */
|
the link may change h->type. So fix it now. */
|
||||||
h->plt.offset = (bfd_vma) -1;
|
h->plt.offset = (bfd_vma) -1;
|
||||||
|
|
||||||
|
eh = (struct elf_i386_link_hash_entry *) h;
|
||||||
|
|
||||||
/* If this is a weak symbol, and there is a real definition, the
|
/* If this is a weak symbol, and there is a real definition, the
|
||||||
processor independent code will have arranged for us to see the
|
processor independent code will have arranged for us to see the
|
||||||
real definition first, and we can just use the same value. */
|
real definition first, and we can just use the same value. */
|
||||||
|
@ -2599,7 +2616,9 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
|
||||||
|| h->u.weakdef->root.type == bfd_link_hash_defweak);
|
|| h->u.weakdef->root.type == bfd_link_hash_defweak);
|
||||||
h->root.u.def.section = h->u.weakdef->root.u.def.section;
|
h->root.u.def.section = h->u.weakdef->root.u.def.section;
|
||||||
h->root.u.def.value = h->u.weakdef->root.u.def.value;
|
h->root.u.def.value = h->u.weakdef->root.u.def.value;
|
||||||
if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
|
if (ELIMINATE_COPY_RELOCS
|
||||||
|
|| info->nocopyreloc
|
||||||
|
|| SYMBOL_NO_COPYRELOC (info, eh))
|
||||||
h->non_got_ref = h->u.weakdef->non_got_ref;
|
h->non_got_ref = h->u.weakdef->non_got_ref;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -2617,12 +2636,11 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
|
||||||
/* If there are no references to this symbol that do not use the
|
/* If there are no references to this symbol that do not use the
|
||||||
GOT nor R_386_GOTOFF relocation, we don't need to generate a copy
|
GOT nor R_386_GOTOFF relocation, we don't need to generate a copy
|
||||||
reloc. */
|
reloc. */
|
||||||
eh = (struct elf_i386_link_hash_entry *) h;
|
|
||||||
if (!h->non_got_ref && !eh->gotoff_ref)
|
if (!h->non_got_ref && !eh->gotoff_ref)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* If -z nocopyreloc was given, we won't generate them either. */
|
/* If -z nocopyreloc was given, we won't generate them either. */
|
||||||
if (info->nocopyreloc)
|
if (info->nocopyreloc || SYMBOL_NO_COPYRELOC (info, eh))
|
||||||
{
|
{
|
||||||
h->non_got_ref = 0;
|
h->non_got_ref = 0;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -6802,68 +6820,39 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ebfd != NULL)
|
if (ebfd != NULL && features)
|
||||||
{
|
{
|
||||||
if (features)
|
/* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT and
|
||||||
|
GNU_PROPERTY_X86_FEATURE_1_SHSTK. */
|
||||||
|
prop = _bfd_elf_get_property (ebfd,
|
||||||
|
GNU_PROPERTY_X86_FEATURE_1_AND,
|
||||||
|
4);
|
||||||
|
prop->u.number |= features;
|
||||||
|
prop->pr_kind = property_number;
|
||||||
|
|
||||||
|
/* Create the GNU property note section if needed. */
|
||||||
|
if (pbfd == NULL)
|
||||||
{
|
{
|
||||||
/* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT and
|
sec = bfd_make_section_with_flags (ebfd,
|
||||||
GNU_PROPERTY_X86_FEATURE_1_SHSTK. */
|
NOTE_GNU_PROPERTY_SECTION_NAME,
|
||||||
prop = _bfd_elf_get_property (ebfd,
|
(SEC_ALLOC
|
||||||
GNU_PROPERTY_X86_FEATURE_1_AND,
|
| SEC_LOAD
|
||||||
4);
|
| SEC_IN_MEMORY
|
||||||
prop->u.number |= features;
|
| SEC_READONLY
|
||||||
prop->pr_kind = property_number;
|
| SEC_HAS_CONTENTS
|
||||||
|
| SEC_DATA));
|
||||||
|
if (sec == NULL)
|
||||||
|
info->callbacks->einfo (_("%F: failed to create GNU property section\n"));
|
||||||
|
|
||||||
/* Create the GNU property note section if needed. */
|
if (!bfd_set_section_alignment (ebfd, sec, 2))
|
||||||
if (pbfd == NULL)
|
|
||||||
{
|
{
|
||||||
sec = bfd_make_section_with_flags (ebfd,
|
|
||||||
NOTE_GNU_PROPERTY_SECTION_NAME,
|
|
||||||
(SEC_ALLOC
|
|
||||||
| SEC_LOAD
|
|
||||||
| SEC_IN_MEMORY
|
|
||||||
| SEC_READONLY
|
|
||||||
| SEC_HAS_CONTENTS
|
|
||||||
| SEC_DATA));
|
|
||||||
if (sec == NULL)
|
|
||||||
info->callbacks->einfo (_("%F: failed to create GNU property section\n"));
|
|
||||||
|
|
||||||
if (!bfd_set_section_alignment (ebfd, sec, 2))
|
|
||||||
{
|
|
||||||
error_alignment:
|
error_alignment:
|
||||||
info->callbacks->einfo (_("%F%A: failed to align section\n"),
|
info->callbacks->einfo (_("%F%A: failed to align section\n"),
|
||||||
sec);
|
sec);
|
||||||
}
|
|
||||||
|
|
||||||
elf_section_type (sec) = SHT_NOTE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elf_section_type (sec) = SHT_NOTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check GNU_PROPERTY_NO_COPY_ON_PROTECTED. */
|
|
||||||
for (; pbfd != NULL; pbfd = pbfd->link.next)
|
|
||||||
if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
|
|
||||||
&& (pbfd->flags
|
|
||||||
& (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0)
|
|
||||||
{
|
|
||||||
elf_property_list *p;
|
|
||||||
|
|
||||||
/* The property list is sorted in order of type. */
|
|
||||||
for (p = elf_properties (pbfd); p != NULL; p = p->next)
|
|
||||||
{
|
|
||||||
if (GNU_PROPERTY_NO_COPY_ON_PROTECTED
|
|
||||||
== p->property.pr_type)
|
|
||||||
{
|
|
||||||
/* Clear extern_protected_data if
|
|
||||||
GNU_PROPERTY_NO_COPY_ON_PROTECTED is
|
|
||||||
set on any input relocatable file. */
|
|
||||||
info->extern_protected_data = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (GNU_PROPERTY_NO_COPY_ON_PROTECTED
|
|
||||||
< p->property.pr_type)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pbfd = _bfd_elf_link_setup_gnu_properties (info);
|
pbfd = _bfd_elf_link_setup_gnu_properties (info);
|
||||||
|
@ -7163,6 +7152,21 @@ elf_i386_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
|
||||||
return _bfd_elf_link_check_relocs (abfd, info);
|
return _bfd_elf_link_check_relocs (abfd, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
elf_i386_merge_symbol_attribute (struct elf_link_hash_entry *h,
|
||||||
|
const Elf_Internal_Sym *isym,
|
||||||
|
bfd_boolean definition,
|
||||||
|
bfd_boolean dynamic ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
if (definition)
|
||||||
|
{
|
||||||
|
struct elf_i386_link_hash_entry *eh
|
||||||
|
= (struct elf_i386_link_hash_entry *) h;
|
||||||
|
eh->def_protected = (ELF_ST_VISIBILITY (isym->st_other)
|
||||||
|
== STV_PROTECTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define TARGET_LITTLE_SYM i386_elf32_vec
|
#define TARGET_LITTLE_SYM i386_elf32_vec
|
||||||
#define TARGET_LITTLE_NAME "elf32-i386"
|
#define TARGET_LITTLE_NAME "elf32-i386"
|
||||||
#define ELF_ARCH bfd_arch_i386
|
#define ELF_ARCH bfd_arch_i386
|
||||||
|
@ -7218,6 +7222,7 @@ elf_i386_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
|
||||||
#define elf_backend_parse_gnu_properties elf_i386_parse_gnu_properties
|
#define elf_backend_parse_gnu_properties elf_i386_parse_gnu_properties
|
||||||
#define elf_backend_merge_gnu_properties elf_i386_merge_gnu_properties
|
#define elf_backend_merge_gnu_properties elf_i386_merge_gnu_properties
|
||||||
#define elf_backend_setup_gnu_properties elf_i386_link_setup_gnu_properties
|
#define elf_backend_setup_gnu_properties elf_i386_link_setup_gnu_properties
|
||||||
|
#define elf_backend_merge_symbol_attribute elf_i386_merge_symbol_attribute
|
||||||
|
|
||||||
#include "elf32-target.h"
|
#include "elf32-target.h"
|
||||||
|
|
||||||
|
|
|
@ -1061,6 +1061,17 @@ static const struct elf_x86_64_backend_data elf_x86_64_arch_bed =
|
||||||
|| (EH)->has_non_got_reloc \
|
|| (EH)->has_non_got_reloc \
|
||||||
|| !(INFO)->dynamic_undefined_weak))))
|
|| !(INFO)->dynamic_undefined_weak))))
|
||||||
|
|
||||||
|
/* Should copy relocation be generated for a symbol. Don't generate
|
||||||
|
copy relocation against a protected symbol defined in a shared
|
||||||
|
object with GNU_PROPERTY_NO_COPY_ON_PROTECTED. */
|
||||||
|
#define SYMBOL_NO_COPYRELOC(INFO, EH) \
|
||||||
|
((EH)->def_protected \
|
||||||
|
&& ((EH)->elf.root.type == bfd_link_hash_defined \
|
||||||
|
|| (EH)->elf.root.type == bfd_link_hash_defweak) \
|
||||||
|
&& elf_has_no_copy_on_protected ((EH)->elf.root.u.def.section->owner) \
|
||||||
|
&& ((EH)->elf.root.u.def.section->owner->flags & DYNAMIC) != 0 \
|
||||||
|
&& ((EH)->elf.root.u.def.section->flags & SEC_CODE) == 0)
|
||||||
|
|
||||||
/* x86-64 ELF linker hash entry. */
|
/* x86-64 ELF linker hash entry. */
|
||||||
|
|
||||||
struct elf_x86_64_link_hash_entry
|
struct elf_x86_64_link_hash_entry
|
||||||
|
@ -1104,6 +1115,9 @@ struct elf_x86_64_link_hash_entry
|
||||||
/* TRUE if symbol is __tls_get_addr. */
|
/* TRUE if symbol is __tls_get_addr. */
|
||||||
unsigned int tls_get_addr : 1;
|
unsigned int tls_get_addr : 1;
|
||||||
|
|
||||||
|
/* TRUE if symbol is defined as a protected symbol. */
|
||||||
|
unsigned int def_protected : 1;
|
||||||
|
|
||||||
/* Reference count of C/C++ function pointer relocations in read-write
|
/* Reference count of C/C++ function pointer relocations in read-write
|
||||||
section which can be resolved at run-time. */
|
section which can be resolved at run-time. */
|
||||||
bfd_signed_vma func_pointer_refcount;
|
bfd_signed_vma func_pointer_refcount;
|
||||||
|
@ -1908,7 +1922,10 @@ elf_x86_64_need_pic (struct bfd_link_info *info,
|
||||||
v = _("protected symbol ");
|
v = _("protected symbol ");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
v = _("symbol ");
|
if (((struct elf_x86_64_link_hash_entry *) h)->def_protected)
|
||||||
|
v = _("protected symbol ");
|
||||||
|
else
|
||||||
|
v = _("symbol ");
|
||||||
pic = _("; recompile with -fPIC");
|
pic = _("; recompile with -fPIC");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3043,6 +3060,8 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
|
||||||
the link may change h->type. So fix it now. */
|
the link may change h->type. So fix it now. */
|
||||||
h->plt.offset = (bfd_vma) -1;
|
h->plt.offset = (bfd_vma) -1;
|
||||||
|
|
||||||
|
eh = (struct elf_x86_64_link_hash_entry *) h;
|
||||||
|
|
||||||
/* If this is a weak symbol, and there is a real definition, the
|
/* If this is a weak symbol, and there is a real definition, the
|
||||||
processor independent code will have arranged for us to see the
|
processor independent code will have arranged for us to see the
|
||||||
real definition first, and we can just use the same value. */
|
real definition first, and we can just use the same value. */
|
||||||
|
@ -3052,9 +3071,10 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
|
||||||
|| h->u.weakdef->root.type == bfd_link_hash_defweak);
|
|| h->u.weakdef->root.type == bfd_link_hash_defweak);
|
||||||
h->root.u.def.section = h->u.weakdef->root.u.def.section;
|
h->root.u.def.section = h->u.weakdef->root.u.def.section;
|
||||||
h->root.u.def.value = h->u.weakdef->root.u.def.value;
|
h->root.u.def.value = h->u.weakdef->root.u.def.value;
|
||||||
if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
|
if (ELIMINATE_COPY_RELOCS
|
||||||
|
|| info->nocopyreloc
|
||||||
|
|| SYMBOL_NO_COPYRELOC (info, eh))
|
||||||
{
|
{
|
||||||
eh = (struct elf_x86_64_link_hash_entry *) h;
|
|
||||||
h->non_got_ref = h->u.weakdef->non_got_ref;
|
h->non_got_ref = h->u.weakdef->non_got_ref;
|
||||||
eh->needs_copy = h->u.weakdef->needs_copy;
|
eh->needs_copy = h->u.weakdef->needs_copy;
|
||||||
}
|
}
|
||||||
|
@ -3077,7 +3097,7 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* If -z nocopyreloc was given, we won't generate them either. */
|
/* If -z nocopyreloc was given, we won't generate them either. */
|
||||||
if (info->nocopyreloc)
|
if (info->nocopyreloc || SYMBOL_NO_COPYRELOC (info, eh))
|
||||||
{
|
{
|
||||||
h->non_got_ref = 0;
|
h->non_got_ref = 0;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -4950,7 +4970,9 @@ do_ifunc_pointer:
|
||||||
&& ((bfd_link_executable (info)
|
&& ((bfd_link_executable (info)
|
||||||
&& ((h->root.type == bfd_link_hash_undefweak
|
&& ((h->root.type == bfd_link_hash_undefweak
|
||||||
&& !resolved_to_zero)
|
&& !resolved_to_zero)
|
||||||
|| (info->nocopyreloc
|
|| ((info->nocopyreloc
|
||||||
|
|| (eh->def_protected
|
||||||
|
&& elf_has_no_copy_on_protected (h->root.u.def.section->owner)))
|
||||||
&& h->def_dynamic
|
&& h->def_dynamic
|
||||||
&& !(h->root.u.def.section->flags & SEC_CODE))))
|
&& !(h->root.u.def.section->flags & SEC_CODE))))
|
||||||
|| bfd_link_dll (info)))
|
|| bfd_link_dll (info)))
|
||||||
|
@ -5724,7 +5746,10 @@ direct:
|
||||||
switch (r_type)
|
switch (r_type)
|
||||||
{
|
{
|
||||||
case R_X86_64_32S:
|
case R_X86_64_32S:
|
||||||
if (info->nocopyreloc
|
sec = h->root.u.def.section;
|
||||||
|
if ((info->nocopyreloc
|
||||||
|
|| (eh->def_protected
|
||||||
|
&& elf_has_no_copy_on_protected (h->root.u.def.section->owner)))
|
||||||
&& !(h->root.u.def.section->flags & SEC_CODE))
|
&& !(h->root.u.def.section->flags & SEC_CODE))
|
||||||
return elf_x86_64_need_pic (info, input_bfd, input_section,
|
return elf_x86_64_need_pic (info, input_bfd, input_section,
|
||||||
h, NULL, NULL, howto);
|
h, NULL, NULL, howto);
|
||||||
|
@ -7137,6 +7162,21 @@ elf_x86_64_merge_symbol (struct elf_link_hash_entry *h,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
elf_x86_64_merge_symbol_attribute (struct elf_link_hash_entry *h,
|
||||||
|
const Elf_Internal_Sym *isym,
|
||||||
|
bfd_boolean definition,
|
||||||
|
bfd_boolean dynamic ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
if (definition)
|
||||||
|
{
|
||||||
|
struct elf_x86_64_link_hash_entry *eh
|
||||||
|
= (struct elf_x86_64_link_hash_entry *) h;
|
||||||
|
eh->def_protected = (ELF_ST_VISIBILITY (isym->st_other)
|
||||||
|
== STV_PROTECTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
elf_x86_64_additional_program_headers (bfd *abfd,
|
elf_x86_64_additional_program_headers (bfd *abfd,
|
||||||
struct bfd_link_info *info ATTRIBUTE_UNUSED)
|
struct bfd_link_info *info ATTRIBUTE_UNUSED)
|
||||||
|
@ -7349,69 +7389,40 @@ elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ebfd != NULL)
|
if (ebfd != NULL && features)
|
||||||
{
|
{
|
||||||
if (features)
|
/* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT and
|
||||||
|
GNU_PROPERTY_X86_FEATURE_1_SHSTK. */
|
||||||
|
prop = _bfd_elf_get_property (ebfd,
|
||||||
|
GNU_PROPERTY_X86_FEATURE_1_AND,
|
||||||
|
4);
|
||||||
|
prop->u.number |= features;
|
||||||
|
prop->pr_kind = property_number;
|
||||||
|
|
||||||
|
/* Create the GNU property note section if needed. */
|
||||||
|
if (pbfd == NULL)
|
||||||
{
|
{
|
||||||
/* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT and
|
sec = bfd_make_section_with_flags (ebfd,
|
||||||
GNU_PROPERTY_X86_FEATURE_1_SHSTK. */
|
NOTE_GNU_PROPERTY_SECTION_NAME,
|
||||||
prop = _bfd_elf_get_property (ebfd,
|
(SEC_ALLOC
|
||||||
GNU_PROPERTY_X86_FEATURE_1_AND,
|
| SEC_LOAD
|
||||||
4);
|
| SEC_IN_MEMORY
|
||||||
prop->u.number |= features;
|
| SEC_READONLY
|
||||||
prop->pr_kind = property_number;
|
| SEC_HAS_CONTENTS
|
||||||
|
| SEC_DATA));
|
||||||
|
if (sec == NULL)
|
||||||
|
info->callbacks->einfo (_("%F: failed to create GNU property section\n"));
|
||||||
|
|
||||||
/* Create the GNU property note section if needed. */
|
if (!bfd_set_section_alignment (ebfd, sec,
|
||||||
if (pbfd == NULL)
|
ABI_64_P (ebfd) ? 3 : 2))
|
||||||
{
|
{
|
||||||
sec = bfd_make_section_with_flags (ebfd,
|
|
||||||
NOTE_GNU_PROPERTY_SECTION_NAME,
|
|
||||||
(SEC_ALLOC
|
|
||||||
| SEC_LOAD
|
|
||||||
| SEC_IN_MEMORY
|
|
||||||
| SEC_READONLY
|
|
||||||
| SEC_HAS_CONTENTS
|
|
||||||
| SEC_DATA));
|
|
||||||
if (sec == NULL)
|
|
||||||
info->callbacks->einfo (_("%F: failed to create GNU property section\n"));
|
|
||||||
|
|
||||||
if (!bfd_set_section_alignment (ebfd, sec,
|
|
||||||
ABI_64_P (ebfd) ? 3 : 2))
|
|
||||||
{
|
|
||||||
error_alignment:
|
error_alignment:
|
||||||
info->callbacks->einfo (_("%F%A: failed to align section\n"),
|
info->callbacks->einfo (_("%F%A: failed to align section\n"),
|
||||||
sec);
|
sec);
|
||||||
}
|
|
||||||
|
|
||||||
elf_section_type (sec) = SHT_NOTE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elf_section_type (sec) = SHT_NOTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check GNU_PROPERTY_NO_COPY_ON_PROTECTED. */
|
|
||||||
for (; pbfd != NULL; pbfd = pbfd->link.next)
|
|
||||||
if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
|
|
||||||
&& (pbfd->flags
|
|
||||||
& (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0)
|
|
||||||
{
|
|
||||||
elf_property_list *p;
|
|
||||||
|
|
||||||
/* The property list is sorted in order of type. */
|
|
||||||
for (p = elf_properties (pbfd); p != NULL; p = p->next)
|
|
||||||
{
|
|
||||||
if (GNU_PROPERTY_NO_COPY_ON_PROTECTED
|
|
||||||
== p->property.pr_type)
|
|
||||||
{
|
|
||||||
/* Clear extern_protected_data if
|
|
||||||
GNU_PROPERTY_NO_COPY_ON_PROTECTED is
|
|
||||||
set on any input relocatable file. */
|
|
||||||
info->extern_protected_data = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (GNU_PROPERTY_NO_COPY_ON_PROTECTED
|
|
||||||
< p->property.pr_type)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pbfd = _bfd_elf_link_setup_gnu_properties (info);
|
pbfd = _bfd_elf_link_setup_gnu_properties (info);
|
||||||
|
@ -7830,6 +7841,8 @@ elf_x86_64_special_sections[]=
|
||||||
elf_x86_64_common_definition
|
elf_x86_64_common_definition
|
||||||
#define elf_backend_merge_symbol \
|
#define elf_backend_merge_symbol \
|
||||||
elf_x86_64_merge_symbol
|
elf_x86_64_merge_symbol
|
||||||
|
#define elf_backend_merge_symbol_attribute \
|
||||||
|
elf_x86_64_merge_symbol_attribute
|
||||||
#define elf_backend_special_sections \
|
#define elf_backend_special_sections \
|
||||||
elf_x86_64_special_sections
|
elf_x86_64_special_sections
|
||||||
#define elf_backend_additional_program_headers \
|
#define elf_backend_additional_program_headers \
|
||||||
|
|
14
ld/ChangeLog
14
ld/ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
2017-08-26 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
PR ld/21997
|
||||||
|
* testsuite/ld-i386/i386.exp: Run PR ld/21997 tests.
|
||||||
|
* testsuite/ld-x86-64/x86-64.exp: Likewise.
|
||||||
|
* testsuite/ld-i386/pr21997-1a.S: New file.
|
||||||
|
* testsuite/ld-i386/pr21997-1b.c: Likewise.
|
||||||
|
* testsuite/ld-i386/pr21997-1c.S: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr21997-1a.S: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr21997-1a.err: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr21997-1b.c: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr21997-1b.err: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr21997-1c.c: Likewise.
|
||||||
|
|
||||||
2017-08-24 H.J. Lu <hongjiu.lu@intel.com>
|
2017-08-24 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
* testsuite/ld-elf/pr21903c.d: Remove '\' before --.
|
* testsuite/ld-elf/pr21903c.d: Remove '\' before --.
|
||||||
|
|
|
@ -1254,6 +1254,14 @@ if { [isnative]
|
||||||
{} \
|
{} \
|
||||||
"pr22001-1.so" \
|
"pr22001-1.so" \
|
||||||
] \
|
] \
|
||||||
|
[list \
|
||||||
|
"Build pr21997-1.so" \
|
||||||
|
"-shared" \
|
||||||
|
"" \
|
||||||
|
{ property-stack.S property-no-copy.S pr21997-1a.S } \
|
||||||
|
{} \
|
||||||
|
"pr21997-1.so" \
|
||||||
|
] \
|
||||||
]
|
]
|
||||||
|
|
||||||
run_ld_link_exec_tests [list \
|
run_ld_link_exec_tests [list \
|
||||||
|
@ -1309,6 +1317,49 @@ if { [isnative]
|
||||||
"pass.out" \
|
"pass.out" \
|
||||||
"-fPIC" \
|
"-fPIC" \
|
||||||
] \
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr21997-1" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/pr21997-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr21997-1b.c } \
|
||||||
|
"pr21997-1" \
|
||||||
|
"pass.out" \
|
||||||
|
"$NOPIE_CFLAGS" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr21997-1 (PIC 1)" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/pr21997-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr21997-1b.c } \
|
||||||
|
"pr21997-1-pic-1" \
|
||||||
|
"pass.out" \
|
||||||
|
"-fPIC" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr21997-1 (PIC 2)" \
|
||||||
|
"-pie -Wl,--no-as-needed tmpdir/pr21997-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr21997-1b.c } \
|
||||||
|
"pr21997-1-pic-2" \
|
||||||
|
"pass.out" \
|
||||||
|
"-fPIC" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr21997-1 (PIE 1)" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/pr21997-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr21997-1c.S } \
|
||||||
|
"pr21997-1-pie-1" \
|
||||||
|
"pass.out" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr21997-1 (PIE 2)" \
|
||||||
|
"-pie -Wl,--no-as-needed tmpdir/pr21997-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr21997-1c.S } \
|
||||||
|
"pr21997-1-pie-2" \
|
||||||
|
"pass.out" \
|
||||||
|
] \
|
||||||
]
|
]
|
||||||
|
|
||||||
if { [at_least_gcc_version 5 0] } {
|
if { [at_least_gcc_version 5 0] } {
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
.text
|
||||||
|
.p2align 4,,15
|
||||||
|
.globl get_protected
|
||||||
|
.type get_protected, @function
|
||||||
|
get_protected:
|
||||||
|
call __x86.get_pc_thunk.ax
|
||||||
|
addl $_GLOBAL_OFFSET_TABLE_, %eax
|
||||||
|
movl protected@GOTOFF(%eax), %eax
|
||||||
|
ret
|
||||||
|
.size get_protected, .-get_protected
|
||||||
|
.p2align 4,,15
|
||||||
|
.globl get_protected_p
|
||||||
|
.type get_protected_p, @function
|
||||||
|
get_protected_p:
|
||||||
|
call __x86.get_pc_thunk.ax
|
||||||
|
addl $_GLOBAL_OFFSET_TABLE_, %eax
|
||||||
|
leal protected@GOTOFF(%eax), %eax
|
||||||
|
ret
|
||||||
|
.size get_protected_p, .-get_protected_p
|
||||||
|
.protected protected
|
||||||
|
.globl protected
|
||||||
|
.data
|
||||||
|
.align 4
|
||||||
|
.type protected, @object
|
||||||
|
.size protected, 4
|
||||||
|
protected:
|
||||||
|
.long 1
|
||||||
|
.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
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
extern int protected;
|
||||||
|
extern int get_protected (void);
|
||||||
|
extern int* get_protected_p (void);
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (protected == get_protected ()
|
||||||
|
&& &protected == get_protected_p ())
|
||||||
|
printf ("PASS\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
.section .rodata.str1.1,"aMS",@progbits,1
|
||||||
|
.LC0:
|
||||||
|
.string "PASS"
|
||||||
|
.section .text.startup,"ax",@progbits
|
||||||
|
.p2align 4,,15
|
||||||
|
.globl main
|
||||||
|
.type main, @function
|
||||||
|
main:
|
||||||
|
leal 4(%esp), %ecx
|
||||||
|
andl $-16, %esp
|
||||||
|
pushl -4(%ecx)
|
||||||
|
pushl %ebp
|
||||||
|
movl %esp, %ebp
|
||||||
|
pushl %esi
|
||||||
|
pushl %ebx
|
||||||
|
pushl %ecx
|
||||||
|
call __x86.get_pc_thunk.bx
|
||||||
|
addl $_GLOBAL_OFFSET_TABLE_, %ebx
|
||||||
|
subl $12, %esp
|
||||||
|
call get_protected@PLT
|
||||||
|
movl protected@GOT(%ebx), %esi
|
||||||
|
cmpl (%esi), %eax
|
||||||
|
je .L7
|
||||||
|
.L3:
|
||||||
|
leal -12(%ebp), %esp
|
||||||
|
xorl %eax, %eax
|
||||||
|
popl %ecx
|
||||||
|
popl %ebx
|
||||||
|
popl %esi
|
||||||
|
popl %ebp
|
||||||
|
leal -4(%ecx), %esp
|
||||||
|
ret
|
||||||
|
.L7:
|
||||||
|
call get_protected_p@PLT
|
||||||
|
cmpl %esi, %eax
|
||||||
|
jne .L3
|
||||||
|
leal .LC0@GOTOFF(%ebx), %eax
|
||||||
|
subl $12, %esp
|
||||||
|
pushl %eax
|
||||||
|
call puts@PLT
|
||||||
|
addl $16, %esp
|
||||||
|
jmp .L3
|
||||||
|
.size main, .-main
|
||||||
|
.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
|
|
@ -0,0 +1,24 @@
|
||||||
|
.text
|
||||||
|
.p2align 4,,15
|
||||||
|
.globl get_protected
|
||||||
|
.type get_protected, @function
|
||||||
|
get_protected:
|
||||||
|
movl protected(%rip), %eax
|
||||||
|
ret
|
||||||
|
.size get_protected, .-get_protected
|
||||||
|
.p2align 4,,15
|
||||||
|
.globl get_protected_p
|
||||||
|
.type get_protected_p, @function
|
||||||
|
get_protected_p:
|
||||||
|
leaq protected(%rip), %rax
|
||||||
|
ret
|
||||||
|
.size get_protected_p, .-get_protected_p
|
||||||
|
.protected protected
|
||||||
|
.globl protected
|
||||||
|
.data
|
||||||
|
.align 4
|
||||||
|
.type protected, @object
|
||||||
|
.size protected, 4
|
||||||
|
protected:
|
||||||
|
.long 1
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
|
@ -0,0 +1,2 @@
|
||||||
|
.*relocation R_X86_64_PC32 against protected symbol `protected' can not be used when making a P(D|I)E object; recompile with -fPIC
|
||||||
|
#...
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
extern int protected;
|
||||||
|
extern int get_protected (void);
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
if (protected == get_protected ())
|
||||||
|
printf ("PASS\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
.*relocation R_X86_64_32S against protected symbol `protected' can not be used when making a P(D|I)E object; recompile with -fPIC
|
||||||
|
#...
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
extern int protected;
|
||||||
|
extern int* get_protected_p (void);
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
if (&protected == get_protected_p ())
|
||||||
|
printf ("PASS\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1056,6 +1056,22 @@ if { [isnative] && [which $CC] != 0 } {
|
||||||
{{error_output "pr22001-1a.err"}} \
|
{{error_output "pr22001-1a.err"}} \
|
||||||
"pr22001-1a" \
|
"pr22001-1a" \
|
||||||
] \
|
] \
|
||||||
|
[list \
|
||||||
|
"Build pr21997-1.so" \
|
||||||
|
"-shared" \
|
||||||
|
"" \
|
||||||
|
{ property-stack.S property-no-copy.S pr21997-1a.S } \
|
||||||
|
{} \
|
||||||
|
"pr21997-1.so" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Build pr21997-1a" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/pr21997-1.so" \
|
||||||
|
"$NOPIE_CFLAGS" \
|
||||||
|
{ pr21997-1b.c } \
|
||||||
|
{{error_output "pr21997-1a.err"}} \
|
||||||
|
"pr21997-1a" \
|
||||||
|
] \
|
||||||
]
|
]
|
||||||
|
|
||||||
if {[istarget "x86_64-*-linux*-gnux32"]} {
|
if {[istarget "x86_64-*-linux*-gnux32"]} {
|
||||||
|
@ -1069,6 +1085,15 @@ if { [isnative] && [which $CC] != 0 } {
|
||||||
"pass.out" \
|
"pass.out" \
|
||||||
"$NOPIE_CFLAGS" \
|
"$NOPIE_CFLAGS" \
|
||||||
] \
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr21997-1b" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/pr21997-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr21997-1c.c } \
|
||||||
|
"pr21997-1b" \
|
||||||
|
"pass.out" \
|
||||||
|
"$NOPIE_CFLAGS" \
|
||||||
|
] \
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
run_cc_link_tests [list \
|
run_cc_link_tests [list \
|
||||||
|
@ -1080,6 +1105,14 @@ if { [isnative] && [which $CC] != 0 } {
|
||||||
{{error_output "pr22001-1b.err"}} \
|
{{error_output "pr22001-1b.err"}} \
|
||||||
"pr22001-1b" \
|
"pr22001-1b" \
|
||||||
] \
|
] \
|
||||||
|
[list \
|
||||||
|
"Build pr21997-1b" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/pr21997-1.so" \
|
||||||
|
"$NOPIE_CFLAGS" \
|
||||||
|
{ pr21997-1c.c } \
|
||||||
|
{{error_output "pr21997-1b.err"}} \
|
||||||
|
"pr21997-1b" \
|
||||||
|
] \
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1293,6 +1326,42 @@ if { [isnative] && [which $CC] != 0 } {
|
||||||
"pass.out" \
|
"pass.out" \
|
||||||
"-fPIC" \
|
"-fPIC" \
|
||||||
] \
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr21997-1a (PIC 1)" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/pr21997-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr21997-1b.c } \
|
||||||
|
"pr21997-1a-pic-1" \
|
||||||
|
"pass.out" \
|
||||||
|
"-fPIC" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr21997-1a (PIC 2)" \
|
||||||
|
"-pie -Wl,--no-as-needed tmpdir/pr21997-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr21997-1b.c } \
|
||||||
|
"pr21997-1a-pic-2" \
|
||||||
|
"pass.out" \
|
||||||
|
"-fPIC" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr21997-1b (PIC 1)" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/pr21997-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr21997-1c.c } \
|
||||||
|
"pr21997-1b-pic-1" \
|
||||||
|
"pass.out" \
|
||||||
|
"-fPIC" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr21997-1b (PIC 2)" \
|
||||||
|
"-pie -Wl,--no-as-needed tmpdir/pr21997-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr21997-1c.c } \
|
||||||
|
"pr21997-1b-pic-2" \
|
||||||
|
"pass.out" \
|
||||||
|
"-fPIC" \
|
||||||
|
] \
|
||||||
]
|
]
|
||||||
|
|
||||||
# Run-time tests which require working ifunc attribute support.
|
# Run-time tests which require working ifunc attribute support.
|
||||||
|
|
Loading…
Reference in New Issue