elf: Add GNU_PROPERTY_1_NEEDED check
If GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS is set on any input relocatable files: 1. Don't generate copy relocations. 2. Turn off extern_protected_data since it implies GNU_PROPERTY_NO_COPY_ON_PROTECTED. 3. Treate reference to protected symbols with indirect external access as local. 4. Set GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS on output. 5. When generating executable, clear this bit when there are non-GOT or non-PLT relocations in input relocatable files without the bit set. 6. Add -z [no]indirect-extern-access to control indirect external access. bfd/ * elf-bfd (elf_obj_tdata): Add has_indirect_extern_access. (elf_has_indirect_extern_access): New. * elf-properties.c (_bfd_elf_parse_gnu_properties): Set elf_has_indirect_extern_access and elf_has_no_copy_on_protected when seeing GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. (elf_write_gnu_propertie): Add an argument to pass link_info. Set needed_1_p for GNU_PROPERTY_1_NEEDED in memory. (_bfd_elf_link_setup_gnu_properties): Handle GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS for -z indirect-extern-access. Set nocopyreloc to true and extern_protected_data to false for indirect external access. (_bfd_elf_convert_gnu_properties): Updated. * elf32-i386.c (elf_i386_check_relocs): Set non_got_ref_without_indirect_extern_access on legacy non-GOT or non-PLT references. * elf64-x86-64.c (elf_x86_64_check_relocs): Likewise. * elflink.c (_bfd_elf_symbol_refs_local_p): Return true for STV_PROTECTED symbols with indirect external access. * elfxx-x86.c (_bfd_x86_elf_adjust_dynamic_symbol): Clear indirect_extern_access for legacy non-GOT/non-PLT references. * elfxx-x86.h (elf_x86_link_hash_entry): Add non_got_ref_without_indirect_extern_access. include/ * bfdlink.h (bfd_link_info): Add indirect_extern_access and needed_1_p. Change nocopyreloc to int. ld/ * NEWS: Mention -z [no]indirect-extern-access * ld.texi: Document -z [no]indirect-extern-access * ldmain.c (main): Initialize link_info.indirect_extern_access to -1. * emulparams/extern_protected_data.sh: Support -z [no]indirect-extern-access. * testsuite/ld-elf/indirect-extern-access-1.rd: New file * testsuite/ld-elf/indirect-extern-access-1a.c: Likewise. * testsuite/ld-elf/indirect-extern-access-1b.c: Likewise. * testsuite/ld-elf/indirect-extern-access-2.rd: Likewise. * testsuite/ld-elf/indirect-extern-access-2a.c: Likewise. * testsuite/ld-elf/indirect-extern-access-2b.c: Likewise. * testsuite/ld-elf/indirect-extern-access-3.rd: Likewise. * testsuite/ld-elf/indirect-extern-access.S: Likewise. * testsuite/ld-elf/property-1_needed-1b.d: Likewise. * testsuite/ld-elf/property-1_needed-1c.d: Likewise. * testsuite/ld-x86-64/indirect-extern-access.rd: Likewise. * testsuite/ld-x86-64/protected-data-1.h: Likewise. * testsuite/ld-x86-64/protected-data-1a.c: Likewise. * testsuite/ld-x86-64/protected-data-1b.c: Likewise. * testsuite/ld-x86-64/protected-data-2a.S: Likewise. * testsuite/ld-x86-64/protected-data-2b.S: Likewise. * testsuite/ld-x86-64/protected-func-2a.S: Likewise. * testsuite/ld-x86-64/protected-func-2b.S: Likewise. * testsuite/ld-x86-64/protected-func-2c.c: Likewise. * testsuite/ld-elf/linux-x86.exp: Run test with GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. * testsuite/ld-x86-64/x86-64.exp: Run tests for protected function and data with indirect external access.
This commit is contained in:
parent
6320fd00dc
commit
6f365fda85
@ -2073,6 +2073,10 @@ struct elf_obj_tdata
|
||||
property. */
|
||||
unsigned int has_no_copy_on_protected : 1;
|
||||
|
||||
/* Whether if the bfd contains the
|
||||
GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS property. */
|
||||
unsigned int has_indirect_extern_access : 1;
|
||||
|
||||
/* Irix 5 often screws up the symbol table, sorting local symbols
|
||||
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
|
||||
@ -2138,6 +2142,8 @@ struct elf_obj_tdata
|
||||
#define elf_properties(bfd) (elf_tdata (bfd) -> properties)
|
||||
#define elf_has_no_copy_on_protected(bfd) \
|
||||
(elf_tdata(bfd) -> has_no_copy_on_protected)
|
||||
#define elf_has_indirect_extern_access(bfd) \
|
||||
(elf_tdata(bfd) -> has_indirect_extern_access)
|
||||
|
||||
extern void _bfd_elf_swap_verdef_in
|
||||
(bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
|
||||
|
@ -195,6 +195,18 @@ _bfd_elf_parse_gnu_properties (bfd *abfd, Elf_Internal_Note *note)
|
||||
prop = _bfd_elf_get_property (abfd, type, datasz);
|
||||
prop->u.number |= bfd_h_get_32 (abfd, ptr);
|
||||
prop->pr_kind = property_number;
|
||||
if ((abfd->flags & DYNAMIC) == 0
|
||||
&& type == GNU_PROPERTY_1_NEEDED
|
||||
&& ((prop->u.number
|
||||
& GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS)
|
||||
!= 0))
|
||||
{
|
||||
/* NB: Skip the shared library since it may not be
|
||||
the same at run-time. */
|
||||
elf_has_indirect_extern_access (abfd) = true;
|
||||
/* GNU_PROPERTY_NO_COPY_ON_PROTECTED is implied. */
|
||||
elf_has_no_copy_on_protected (abfd) = true;
|
||||
}
|
||||
goto next;
|
||||
}
|
||||
break;
|
||||
@ -525,7 +537,8 @@ elf_get_gnu_property_section_size (elf_property_list *list,
|
||||
/* Write GNU properties. */
|
||||
|
||||
static void
|
||||
elf_write_gnu_properties (bfd *abfd, bfd_byte *contents,
|
||||
elf_write_gnu_properties (struct bfd_link_info *info,
|
||||
bfd *abfd, bfd_byte *contents,
|
||||
elf_property_list *list, unsigned int size,
|
||||
unsigned int align_size)
|
||||
{
|
||||
@ -570,6 +583,11 @@ elf_write_gnu_properties (bfd *abfd, bfd_byte *contents,
|
||||
break;
|
||||
|
||||
case 4:
|
||||
/* Save the pointer to GNU_PROPERTY_1_NEEDED so that it
|
||||
can be updated later if needed. */
|
||||
if (info != NULL
|
||||
&& list->property.pr_type == GNU_PROPERTY_1_NEEDED)
|
||||
info->needed_1_p = contents + size;
|
||||
bfd_h_put_32 (abfd, list->property.u.number,
|
||||
contents + size);
|
||||
break;
|
||||
@ -598,7 +616,7 @@ elf_write_gnu_properties (bfd *abfd, bfd_byte *contents,
|
||||
bfd *
|
||||
_bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
|
||||
{
|
||||
bfd *abfd, *first_pbfd = NULL;
|
||||
bfd *abfd, *first_pbfd = NULL, *elf_bfd = NULL;
|
||||
elf_property_list *list;
|
||||
asection *sec;
|
||||
bool has_properties = false;
|
||||
@ -606,32 +624,75 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
|
||||
= get_elf_backend_data (info->output_bfd);
|
||||
unsigned int elfclass = bed->s->elfclass;
|
||||
int elf_machine_code = bed->elf_machine_code;
|
||||
elf_property *p;
|
||||
|
||||
/* Find the first relocatable ELF input with GNU properties. */
|
||||
for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
|
||||
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
|
||||
&& (abfd->flags & DYNAMIC) == 0
|
||||
&& elf_properties (abfd) != NULL)
|
||||
&& (elf_machine_code
|
||||
== get_elf_backend_data (abfd)->elf_machine_code)
|
||||
&& (elfclass == get_elf_backend_data (abfd)->s->elfclass))
|
||||
{
|
||||
has_properties = true;
|
||||
|
||||
/* Ignore GNU properties from ELF objects with different machine
|
||||
code or class. Also skip objects without a GNU_PROPERTY note
|
||||
section. */
|
||||
if ((elf_machine_code
|
||||
== get_elf_backend_data (abfd)->elf_machine_code)
|
||||
&& (elfclass
|
||||
== get_elf_backend_data (abfd)->s->elfclass)
|
||||
&& bfd_get_section_by_name (abfd,
|
||||
NOTE_GNU_PROPERTY_SECTION_NAME) != NULL
|
||||
)
|
||||
elf_bfd = abfd;
|
||||
|
||||
if (elf_properties (abfd) != NULL)
|
||||
{
|
||||
/* Keep .note.gnu.property section in FIRST_PBFD. */
|
||||
first_pbfd = abfd;
|
||||
break;
|
||||
has_properties = true;
|
||||
|
||||
if (bfd_get_section_by_name (abfd,
|
||||
NOTE_GNU_PROPERTY_SECTION_NAME)
|
||||
!= NULL)
|
||||
{
|
||||
/* Keep .note.gnu.property section in FIRST_PBFD. */
|
||||
first_pbfd = abfd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (info->indirect_extern_access > 0 && elf_bfd != NULL)
|
||||
{
|
||||
/* Support -z indirect-extern-access. */
|
||||
if (first_pbfd == NULL)
|
||||
{
|
||||
sec = bfd_make_section_with_flags (elf_bfd,
|
||||
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%P: failed to create GNU property section\n"));
|
||||
|
||||
if (!bfd_set_section_alignment (sec,
|
||||
elfclass == ELFCLASS64 ? 3 : 2))
|
||||
info->callbacks->einfo (_("%F%pA: failed to align section\n"),
|
||||
sec);
|
||||
|
||||
elf_section_type (sec) = SHT_NOTE;
|
||||
first_pbfd = elf_bfd;
|
||||
has_properties = true;
|
||||
}
|
||||
|
||||
p = _bfd_elf_get_property (first_pbfd, GNU_PROPERTY_1_NEEDED, 4);
|
||||
if (p->pr_kind == property_unknown)
|
||||
{
|
||||
/* Create GNU_PROPERTY_1_NEEDED. */
|
||||
p->u.number
|
||||
= GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS;
|
||||
p->pr_kind = property_number;
|
||||
}
|
||||
else
|
||||
p->u.number
|
||||
|= GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS;
|
||||
}
|
||||
|
||||
/* Do nothing if there is no .note.gnu.property section. */
|
||||
if (!has_properties)
|
||||
return NULL;
|
||||
@ -695,7 +756,6 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
|
||||
if N > 0. */
|
||||
if (info->stacksize > 0)
|
||||
{
|
||||
elf_property *p;
|
||||
bfd_vma stacksize = info->stacksize;
|
||||
|
||||
p = _bfd_elf_get_property (first_pbfd, GNU_PROPERTY_STACK_SIZE,
|
||||
@ -737,7 +797,30 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
|
||||
sec->size = size;
|
||||
contents = (bfd_byte *) bfd_zalloc (first_pbfd, size);
|
||||
|
||||
elf_write_gnu_properties (first_pbfd, contents, list, size,
|
||||
if (info->indirect_extern_access <= 0)
|
||||
{
|
||||
/* Get GNU_PROPERTY_1_NEEDED properties. */
|
||||
p = elf_find_and_remove_property (&elf_properties (first_pbfd),
|
||||
GNU_PROPERTY_1_NEEDED, false);
|
||||
if (p != NULL)
|
||||
{
|
||||
if (info->indirect_extern_access < 0)
|
||||
{
|
||||
/* Set indirect_extern_access to 1 to indicate that
|
||||
it is turned on by input properties. */
|
||||
if ((p->u.number
|
||||
& GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS)
|
||||
!= 0)
|
||||
info->indirect_extern_access = 1;
|
||||
}
|
||||
else
|
||||
/* Turn off indirect external access. */
|
||||
p->u.number
|
||||
&= ~GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS;
|
||||
}
|
||||
}
|
||||
|
||||
elf_write_gnu_properties (info, first_pbfd, contents, list, size,
|
||||
align_size);
|
||||
|
||||
/* Cache the section contents for elf_link_input_bfd. */
|
||||
@ -747,6 +830,15 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
|
||||
symbol is defined in the shared object. */
|
||||
if (elf_has_no_copy_on_protected (first_pbfd))
|
||||
info->extern_protected_data = false;
|
||||
|
||||
if (info->indirect_extern_access > 0)
|
||||
{
|
||||
/* For indirect external access, don't generate copy
|
||||
relocations. NB: Set to nocopyreloc to 2 to indicate
|
||||
that it is implied by indirect_extern_access. */
|
||||
info->nocopyreloc = 2;
|
||||
info->extern_protected_data = false;
|
||||
}
|
||||
}
|
||||
|
||||
return first_pbfd;
|
||||
@ -804,7 +896,8 @@ _bfd_elf_convert_gnu_properties (bfd *ibfd, asection *isec,
|
||||
*ptr_size = size;
|
||||
|
||||
/* Generate the output .note.gnu.property section. */
|
||||
elf_write_gnu_properties (ibfd, contents, list, size, 1 << align_shift);
|
||||
elf_write_gnu_properties (NULL, ibfd, contents, list, size,
|
||||
1 << align_shift);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1815,6 +1815,9 @@ elf_i386_check_relocs (bfd *abfd,
|
||||
adjust_dynamic_symbol. */
|
||||
h->non_got_ref = 1;
|
||||
|
||||
if (!elf_has_indirect_extern_access (sec->owner))
|
||||
eh->non_got_ref_without_indirect_extern_access = 1;
|
||||
|
||||
/* We may need a .plt entry if the symbol is a function
|
||||
defined in a shared lib or is a function referenced
|
||||
from the code or read-only section. */
|
||||
|
@ -1972,6 +1972,8 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
break;
|
||||
}
|
||||
|
||||
eh = (struct elf_x86_link_hash_entry *) h;
|
||||
|
||||
if (h != NULL)
|
||||
{
|
||||
/* It is referenced by a non-shared object. */
|
||||
@ -2008,7 +2010,6 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
if (h == htab->elf.hgot)
|
||||
htab->got_referenced = true;
|
||||
|
||||
eh = (struct elf_x86_link_hash_entry *) h;
|
||||
switch (r_type)
|
||||
{
|
||||
case R_X86_64_TLSLD:
|
||||
@ -2263,6 +2264,9 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
adjust_dynamic_symbol. */
|
||||
h->non_got_ref = 1;
|
||||
|
||||
if (!elf_has_indirect_extern_access (sec->owner))
|
||||
eh->non_got_ref_without_indirect_extern_access = 1;
|
||||
|
||||
/* We may need a .plt entry if the symbol is a function
|
||||
defined in a shared lib or is a function referenced
|
||||
from the code or read-only section. */
|
||||
|
@ -3353,6 +3353,10 @@ _bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *h,
|
||||
if (!is_elf_hash_table (&hash_table->root))
|
||||
return true;
|
||||
|
||||
/* STV_PROTECTED symbols with indirect external access are local. */
|
||||
if (info->indirect_extern_access > 0)
|
||||
return true;
|
||||
|
||||
bed = get_elf_backend_data (hash_table->dynobj);
|
||||
|
||||
/* If extern_protected_data is false, STV_PROTECTED non-function
|
||||
|
@ -1824,6 +1824,25 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
|
||||
|
||||
eh = (struct elf_x86_link_hash_entry *) h;
|
||||
|
||||
/* Clear GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS if it is turned
|
||||
on by an input relocatable file and there is a non-GOT/non-PLT
|
||||
reference from another relocatable file without it.
|
||||
NB: There can be non-GOT reference in data sections in input with
|
||||
GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. */
|
||||
if (eh->non_got_ref_without_indirect_extern_access
|
||||
&& info->indirect_extern_access == 1
|
||||
&& bfd_link_executable (info))
|
||||
{
|
||||
unsigned int needed_1;
|
||||
info->indirect_extern_access = 0;
|
||||
/* Turn off nocopyreloc if implied by indirect_extern_access. */
|
||||
if (info->nocopyreloc == 2)
|
||||
info->nocopyreloc = 0;
|
||||
needed_1 = bfd_h_get_32 (info->output_bfd, info->needed_1_p);
|
||||
needed_1 &= ~GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS;
|
||||
bfd_h_put_32 (info->output_bfd, needed_1, info->needed_1_p);
|
||||
}
|
||||
|
||||
/* STT_GNU_IFUNC symbol must go through PLT. */
|
||||
if (h->type == STT_GNU_IFUNC)
|
||||
{
|
||||
|
@ -279,6 +279,10 @@ struct elf_x86_link_hash_entry
|
||||
/* TRUE if symbol is defined by linker. */
|
||||
unsigned int linker_def : 1;
|
||||
|
||||
/* TRUE if symbol is referenced by a non-GOT/non-PLT relocation in a
|
||||
relocatable object file without indirect external access marker. */
|
||||
unsigned int non_got_ref_without_indirect_extern_access : 1;
|
||||
|
||||
/* TRUE if symbol is referenced by R_386_GOTOFF relocation. This is
|
||||
only used by i386. */
|
||||
unsigned int gotoff_ref : 1;
|
||||
|
@ -335,10 +335,6 @@ struct bfd_link_info
|
||||
/* TRUE if BFD should pre-bind symbols in a shared object. */
|
||||
unsigned int symbolic: 1;
|
||||
|
||||
/* TRUE if executable should not contain copy relocs.
|
||||
Setting this true may result in a non-sharable text segment. */
|
||||
unsigned int nocopyreloc: 1;
|
||||
|
||||
/* TRUE if BFD should export all symbols in the dynamic symbol table
|
||||
of an executable, rather than only those used. */
|
||||
unsigned int export_dynamic: 1;
|
||||
@ -652,6 +648,25 @@ struct bfd_link_info
|
||||
/* How many spare .dynamic DT_NULL entries should be added? */
|
||||
unsigned int spare_dynamic_tags;
|
||||
|
||||
/* GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS control:
|
||||
> 1: Turn on by -z indirect-extern-access or by backend.
|
||||
== 1: Turn on by an input.
|
||||
0: Turn off.
|
||||
< 0: Turn on if it is set on any inputs or let backend to
|
||||
decide. */
|
||||
int indirect_extern_access;
|
||||
|
||||
/* Non-zero if executable should not contain copy relocs.
|
||||
> 1: Implied by indirect_extern_access.
|
||||
== 1: Turn on by -z nocopyreloc.
|
||||
0: Turn off.
|
||||
Setting this to non-zero may result in a non-sharable text
|
||||
segment. */
|
||||
int nocopyreloc;
|
||||
|
||||
/* Pointer to the GNU_PROPERTY_1_NEEDED property in memory. */
|
||||
bfd_byte *needed_1_p;
|
||||
|
||||
/* May be used to set DT_FLAGS for ELF. */
|
||||
bfd_vma flags;
|
||||
|
||||
|
3
ld/NEWS
3
ld/NEWS
@ -1,5 +1,8 @@
|
||||
-*- text -*-
|
||||
|
||||
* Add -z indirect-extern-access/-z noindirect-extern-access to control
|
||||
canonical function pointers and copy relocation.
|
||||
|
||||
* Add --max-cache-size=SIZE to set the the maximum cache size to SIZE
|
||||
bytes.
|
||||
|
||||
|
@ -1,11 +1,21 @@
|
||||
PARSE_AND_LIST_OPTIONS_NOEXTEN_PROTECTED_DATA='
|
||||
fprintf (file, _("\
|
||||
-z noextern-protected-data Do not treat protected data symbol as external\n"));
|
||||
fprintf (file, _("\
|
||||
-z indirect-extern-access Enable indirect external access\n"));
|
||||
fprintf (file, _("\
|
||||
-z noindirect-extern-access Disable indirect external access (default)\n"));
|
||||
'
|
||||
|
||||
# Set link_info.indirect_extern_access to 2 to indicate that it is set
|
||||
# by "-z indirect-extern-access".
|
||||
PARSE_AND_LIST_ARGS_CASE_Z_NOEXTEN_PROTECTED_DATA='
|
||||
else if (strcmp (optarg, "noextern-protected-data") == 0)
|
||||
link_info.extern_protected_data = false;
|
||||
else if (strcmp (optarg, "indirect-extern-access") == 0)
|
||||
link_info.indirect_extern_access = 2;
|
||||
else if (strcmp (optarg, "noindirect-extern-access") == 0)
|
||||
link_info.indirect_extern_access = 0;
|
||||
'
|
||||
|
||||
|
||||
|
12
ld/ld.texi
12
ld/ld.texi
@ -1293,6 +1293,18 @@ Generate GNU_PROPERTY_X86_FEATURE_1_IBT in .note.gnu.property section
|
||||
to indicate compatibility with IBT. This also implies @option{ibtplt}.
|
||||
Supported for Linux/i386 and Linux/x86_64.
|
||||
|
||||
@item indirect-extern-access
|
||||
@itemx noindirect-extern-access
|
||||
Generate GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS in
|
||||
.note.gnu.property section to indicate that object file requires
|
||||
canonical function pointers and cannot be used with copy relocation.
|
||||
This option also implies @option{noextern-protected-data} and
|
||||
@option{nocopyreloc}. Supported for i386 and x86-64.
|
||||
|
||||
@option{noindirect-extern-access} removes
|
||||
GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS from .note.gnu.property
|
||||
section.
|
||||
|
||||
@item initfirst
|
||||
This option is only meaningful when building a shared object.
|
||||
It marks the object so that its runtime initialization will occur
|
||||
|
@ -347,6 +347,7 @@ main (int argc, char **argv)
|
||||
link_info.relax_pass = 1;
|
||||
link_info.extern_protected_data = -1;
|
||||
link_info.dynamic_undefined_weak = -1;
|
||||
link_info.indirect_extern_access = -1;
|
||||
link_info.pei386_auto_import = -1;
|
||||
link_info.spare_dynamic_tags = 5;
|
||||
link_info.path_separator = ':';
|
||||
|
8
ld/testsuite/ld-elf/indirect-extern-access-1.rd
Normal file
8
ld/testsuite/ld-elf/indirect-extern-access-1.rd
Normal file
@ -0,0 +1,8 @@
|
||||
#...
|
||||
[a-f0-9]+ +[0-9a-f]+ +R_.*_COPY +[a-f0-9]+ +indirect_extern_access( \+ 0|)
|
||||
#...
|
||||
Displaying notes found in: .note.gnu.property
|
||||
[ ]+Owner[ ]+Data size[ ]+Description
|
||||
GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0
|
||||
Properties: 1_needed:
|
||||
#pass
|
1
ld/testsuite/ld-elf/indirect-extern-access-1a.c
Normal file
1
ld/testsuite/ld-elf/indirect-extern-access-1a.c
Normal file
@ -0,0 +1 @@
|
||||
int indirect_extern_access = 1;
|
12
ld/testsuite/ld-elf/indirect-extern-access-1b.c
Normal file
12
ld/testsuite/ld-elf/indirect-extern-access-1b.c
Normal file
@ -0,0 +1,12 @@
|
||||
#include <stdio.h>
|
||||
|
||||
extern int indirect_extern_access;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
if (indirect_extern_access == 1)
|
||||
puts ("PASS");
|
||||
|
||||
return 0;
|
||||
}
|
8
ld/testsuite/ld-elf/indirect-extern-access-2.rd
Normal file
8
ld/testsuite/ld-elf/indirect-extern-access-2.rd
Normal file
@ -0,0 +1,8 @@
|
||||
#...
|
||||
[a-f0-9]+ +[0-9a-f]+ +R_.*_JUMP_SLO(T|) +[a-f0-9]+ +indirect_extern_access( \+ 0|)
|
||||
#...
|
||||
Displaying notes found in: .note.gnu.property
|
||||
[ ]+Owner[ ]+Data size[ ]+Description
|
||||
GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0
|
||||
Properties: 1_needed:
|
||||
#pass
|
10
ld/testsuite/ld-elf/indirect-extern-access-2a.c
Normal file
10
ld/testsuite/ld-elf/indirect-extern-access-2a.c
Normal file
@ -0,0 +1,10 @@
|
||||
void
|
||||
indirect_extern_access (void)
|
||||
{
|
||||
}
|
||||
|
||||
void *
|
||||
indirect_extern_access_p (void)
|
||||
{
|
||||
return indirect_extern_access;
|
||||
}
|
13
ld/testsuite/ld-elf/indirect-extern-access-2b.c
Normal file
13
ld/testsuite/ld-elf/indirect-extern-access-2b.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include <stdio.h>
|
||||
|
||||
extern void indirect_extern_access (void);
|
||||
extern void *indirect_extern_access_p (void);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
if (&indirect_extern_access == indirect_extern_access_p ())
|
||||
puts ("PASS");
|
||||
|
||||
return 0;
|
||||
}
|
8
ld/testsuite/ld-elf/indirect-extern-access-3.rd
Normal file
8
ld/testsuite/ld-elf/indirect-extern-access-3.rd
Normal file
@ -0,0 +1,8 @@
|
||||
#...
|
||||
[a-f0-9]+ +[0-9a-f]+ +R_.*_GLOB_DAT +[a-f0-9]+ +indirect_extern_access( \+ 0|)
|
||||
#...
|
||||
Displaying notes found in: .note.gnu.property
|
||||
[ ]+Owner[ ]+Data size[ ]+Description
|
||||
GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0
|
||||
Properties: 1_needed: indirect external access
|
||||
#pass
|
20
ld/testsuite/ld-elf/indirect-extern-access.S
Normal file
20
ld/testsuite/ld-elf/indirect-extern-access.S
Normal file
@ -0,0 +1,20 @@
|
||||
# ifdef __LP64__
|
||||
# define ALIGN 3
|
||||
# else
|
||||
# define ALIGN 2
|
||||
# endif
|
||||
.section ".note.gnu.property", "a"
|
||||
.p2align ALIGN
|
||||
.long 1f - 0f /* name length */
|
||||
.long 5f - 2f /* data length */
|
||||
.long 5 /* note type */
|
||||
0: .asciz "GNU" /* vendor name */
|
||||
1:
|
||||
.p2align ALIGN
|
||||
2: .long 0xb0008000 /* pr_type. */
|
||||
.long 4f - 3f /* pr_datasz. */
|
||||
3:
|
||||
.long 0x1
|
||||
4:
|
||||
.p2align ALIGN
|
||||
5:
|
@ -73,6 +73,103 @@ run_ld_link_tests [list \
|
||||
] \
|
||||
]
|
||||
|
||||
run_cc_link_tests [list \
|
||||
[list \
|
||||
"Build indirect-extern-access-1.so" \
|
||||
"-shared" \
|
||||
"-fPIC" \
|
||||
{ indirect-extern-access-1a.c } \
|
||||
{} \
|
||||
"indirect-extern-access-1.so" \
|
||||
] \
|
||||
[list \
|
||||
"Build indirect-extern-access-1a without PIE" \
|
||||
"$NOPIE_LDFLAGS -Wl,--no-as-needed \
|
||||
tmpdir/indirect-extern-access-1.so" \
|
||||
"$NOPIE_CFLAGS" \
|
||||
{ indirect-extern-access.S indirect-extern-access-1b.c } \
|
||||
{{readelf -rn indirect-extern-access-1.rd}} \
|
||||
"indirect-extern-access-1a" \
|
||||
] \
|
||||
[list \
|
||||
"Build indirect-extern-access-2.so" \
|
||||
"-shared" \
|
||||
"-fPIC" \
|
||||
{ indirect-extern-access-2a.c } \
|
||||
{} \
|
||||
"indirect-extern-access-2.so" \
|
||||
] \
|
||||
[list \
|
||||
"Build indirect-extern-access-2a without PIE" \
|
||||
"$NOPIE_LDFLAGS -Wl,--no-as-needed \
|
||||
tmpdir/indirect-extern-access-2.so" \
|
||||
"$NOPIE_CFLAGS" \
|
||||
{ indirect-extern-access.S indirect-extern-access-1b.c } \
|
||||
{{readelf -rn indirect-extern-access-2.rd}} \
|
||||
"indirect-extern-access-2a" \
|
||||
] \
|
||||
[list \
|
||||
"Build indirect-extern-access-2b with PIE" \
|
||||
"-pie -Wl,--no-as-needed \
|
||||
tmpdir/indirect-extern-access-2.so" \
|
||||
"-fpie" \
|
||||
{ indirect-extern-access.S indirect-extern-access-2b.c } \
|
||||
{{readelf -rn indirect-extern-access-3.rd}} \
|
||||
"indirect-extern-access-2b" \
|
||||
] \
|
||||
]
|
||||
|
||||
run_ld_link_exec_tests [list \
|
||||
[list \
|
||||
"Run indirect-extern-access-1a without PIE" \
|
||||
"$NOPIE_LDFLAGS" \
|
||||
"" \
|
||||
{ indirect-extern-access.S indirect-extern-access-1b.c } \
|
||||
"indirect-extern-access-1a" \
|
||||
"pass.out" \
|
||||
"$NOPIE_CFLAGS" \
|
||||
"" \
|
||||
"" \
|
||||
"tmpdir/indirect-extern-access-1.so" \
|
||||
] \
|
||||
[list \
|
||||
"Run indirect-extern-access-1b with PIE" \
|
||||
"-pie" \
|
||||
"" \
|
||||
{ indirect-extern-access.S indirect-extern-access-1b.c } \
|
||||
"indirect-extern-access-1b" \
|
||||
"pass.out" \
|
||||
"-fpie" \
|
||||
"" \
|
||||
"" \
|
||||
"tmpdir/indirect-extern-access-1.so" \
|
||||
] \
|
||||
[list \
|
||||
"Run indirect-extern-access-2a without PIE" \
|
||||
"$NOPIE_LDFLAGS" \
|
||||
"" \
|
||||
{ indirect-extern-access.S indirect-extern-access-2b.c } \
|
||||
"indirect-extern-access-2a" \
|
||||
"pass.out" \
|
||||
"$NOPIE_CFLAGS" \
|
||||
"" \
|
||||
"" \
|
||||
"tmpdir/indirect-extern-access-2.so" \
|
||||
] \
|
||||
[list \
|
||||
"Run indirect-extern-access-2b with PIE" \
|
||||
"-pie" \
|
||||
"" \
|
||||
{ indirect-extern-access.S indirect-extern-access-2b.c } \
|
||||
"indirect-extern-access-2b" \
|
||||
"pass.out" \
|
||||
"-fpie" \
|
||||
"" \
|
||||
"" \
|
||||
"tmpdir/indirect-extern-access-2.so" \
|
||||
] \
|
||||
]
|
||||
|
||||
proc elfedit_test { options test output } {
|
||||
global ELFEDIT
|
||||
global READELF
|
||||
|
16
ld/testsuite/ld-elf/property-1_needed-1b.d
Normal file
16
ld/testsuite/ld-elf/property-1_needed-1b.d
Normal file
@ -0,0 +1,16 @@
|
||||
#source: empty.s
|
||||
#as:
|
||||
#ld: -shared -z indirect-extern-access
|
||||
#readelf: -n
|
||||
#xfail: ![check_shared_lib_support]
|
||||
#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-*
|
||||
# Assembly source file for the HPPA assembler is renamed and modifed by
|
||||
# sed. mn10300 has relocations in .note.gnu.property section which
|
||||
# elf_parse_notes doesn't support.
|
||||
|
||||
#...
|
||||
Displaying notes found in: .note.gnu.property
|
||||
[ ]+Owner[ ]+Data size[ ]+Description
|
||||
GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0
|
||||
Properties: 1_needed: indirect external access
|
||||
#pass
|
17
ld/testsuite/ld-elf/property-1_needed-1c.d
Normal file
17
ld/testsuite/ld-elf/property-1_needed-1c.d
Normal file
@ -0,0 +1,17 @@
|
||||
#source: empty.s
|
||||
#source: property-1_needed-1.s
|
||||
#as:
|
||||
#ld: -shared -z noindirect-extern-access
|
||||
#readelf: -n
|
||||
#xfail: ![check_shared_lib_support]
|
||||
#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-*
|
||||
# Assembly source file for the HPPA assembler is renamed and modifed by
|
||||
# sed. mn10300 has relocations in .note.gnu.property section which
|
||||
# elf_parse_notes doesn't support.
|
||||
|
||||
#...
|
||||
Displaying notes found in: .note.gnu.property
|
||||
[ ]+Owner[ ]+Data size[ ]+Description
|
||||
GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0
|
||||
Properties: 1_needed: <unknown: 2>
|
||||
#pass
|
6
ld/testsuite/ld-x86-64/indirect-extern-access.rd
Normal file
6
ld/testsuite/ld-x86-64/indirect-extern-access.rd
Normal file
@ -0,0 +1,6 @@
|
||||
#...
|
||||
Displaying notes found in: .note.gnu.property
|
||||
[ ]+Owner[ ]+Data size[ ]+Description
|
||||
GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0
|
||||
Properties: 1_needed: indirect external access
|
||||
#pass
|
11
ld/testsuite/ld-x86-64/protected-data-1.h
Normal file
11
ld/testsuite/ld-x86-64/protected-data-1.h
Normal file
@ -0,0 +1,11 @@
|
||||
extern int protected_data_1a;
|
||||
extern int protected_data_1b;
|
||||
|
||||
extern int *protected_data_1a_p ();
|
||||
extern int *protected_data_1b_p ();
|
||||
|
||||
extern void set_protected_data_1a (int);
|
||||
extern void set_protected_data_1b (int);
|
||||
|
||||
extern int check_protected_data_1a (int);
|
||||
extern int check_protected_data_1b (int);
|
40
ld/testsuite/ld-x86-64/protected-data-1a.c
Normal file
40
ld/testsuite/ld-x86-64/protected-data-1a.c
Normal file
@ -0,0 +1,40 @@
|
||||
#include "protected-data-1.h"
|
||||
|
||||
int protected_data_1a __attribute__ ((visibility("protected"))) = 1;
|
||||
int protected_data_1b __attribute__ ((visibility("protected"))) = 2;
|
||||
|
||||
int *
|
||||
protected_data_1a_p (void)
|
||||
{
|
||||
return &protected_data_1a;
|
||||
}
|
||||
|
||||
int *
|
||||
protected_data_1b_p (void)
|
||||
{
|
||||
return &protected_data_1b;
|
||||
}
|
||||
|
||||
void
|
||||
set_protected_data_1a (int i)
|
||||
{
|
||||
protected_data_1a = i;
|
||||
}
|
||||
|
||||
void
|
||||
set_protected_data_1b (int i)
|
||||
{
|
||||
protected_data_1b = i;
|
||||
}
|
||||
|
||||
int
|
||||
check_protected_data_1a (int i)
|
||||
{
|
||||
return protected_data_1a == i ? 0 : 1;
|
||||
}
|
||||
|
||||
int
|
||||
check_protected_data_1b (int i)
|
||||
{
|
||||
return protected_data_1b == i ? 0 : 1;
|
||||
}
|
59
ld/testsuite/ld-x86-64/protected-data-1b.c
Normal file
59
ld/testsuite/ld-x86-64/protected-data-1b.c
Normal file
@ -0,0 +1,59 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "protected-data-1.h"
|
||||
|
||||
int protected_data_1b = 3;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
/* Check if we get the same address for the protected data symbol. */
|
||||
if (&protected_data_1a != protected_data_1a_p ())
|
||||
{
|
||||
puts ("'protected_data_1a' in main and shared library doesn't have same address");
|
||||
res = 1;
|
||||
}
|
||||
|
||||
protected_data_1a = -1;
|
||||
if (check_protected_data_1a (-1))
|
||||
{
|
||||
puts ("'protected_data_1a' in main and shared library doesn't have same value");
|
||||
res = 1;
|
||||
}
|
||||
|
||||
set_protected_data_1a (-3);
|
||||
if (protected_data_1a != -3)
|
||||
{
|
||||
puts ("'protected_data_1a' in main and shared library doesn't have same value");
|
||||
res = 1;
|
||||
}
|
||||
|
||||
/* Check if we get the different addresses for the protected data
|
||||
symbol. */
|
||||
if (&protected_data_1b == protected_data_1b_p ())
|
||||
{
|
||||
puts ("'protected_data_1b' in main and shared library has same address");
|
||||
res = 1;
|
||||
}
|
||||
|
||||
protected_data_1b = -10;
|
||||
if (check_protected_data_1b (2))
|
||||
{
|
||||
puts ("'protected_data_1b' in main and shared library has same address");
|
||||
res = 1;
|
||||
}
|
||||
|
||||
set_protected_data_1b (-30);
|
||||
if (protected_data_1b != -10)
|
||||
{
|
||||
puts ("'protected_data_1b' in main and shared library has same address");
|
||||
res = 1;
|
||||
}
|
||||
|
||||
if (!res)
|
||||
puts ("PASS");
|
||||
|
||||
return res;
|
||||
}
|
109
ld/testsuite/ld-x86-64/protected-data-2a.S
Normal file
109
ld/testsuite/ld-x86-64/protected-data-2a.S
Normal file
@ -0,0 +1,109 @@
|
||||
.text
|
||||
.p2align 4
|
||||
.protected protected_data_1a
|
||||
.globl protected_data_1a_p
|
||||
.type protected_data_1a_p, @function
|
||||
protected_data_1a_p:
|
||||
.LFB0:
|
||||
.cfi_startproc
|
||||
leaq protected_data_1a(%rip), %rax
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE0:
|
||||
.size protected_data_1a_p, .-protected_data_1a_p
|
||||
.p2align 4
|
||||
.protected protected_data_1b
|
||||
.globl protected_data_1b_p
|
||||
.type protected_data_1b_p, @function
|
||||
protected_data_1b_p:
|
||||
.LFB1:
|
||||
.cfi_startproc
|
||||
leaq protected_data_1b(%rip), %rax
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE1:
|
||||
.size protected_data_1b_p, .-protected_data_1b_p
|
||||
.p2align 4
|
||||
.globl set_protected_data_1a
|
||||
.type set_protected_data_1a, @function
|
||||
set_protected_data_1a:
|
||||
.LFB2:
|
||||
.cfi_startproc
|
||||
movl %edi, protected_data_1a(%rip)
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE2:
|
||||
.size set_protected_data_1a, .-set_protected_data_1a
|
||||
.p2align 4
|
||||
.globl set_protected_data_1b
|
||||
.type set_protected_data_1b, @function
|
||||
set_protected_data_1b:
|
||||
.LFB3:
|
||||
.cfi_startproc
|
||||
movl %edi, protected_data_1b(%rip)
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE3:
|
||||
.size set_protected_data_1b, .-set_protected_data_1b
|
||||
.p2align 4
|
||||
.globl check_protected_data_1a
|
||||
.type check_protected_data_1a, @function
|
||||
check_protected_data_1a:
|
||||
.LFB4:
|
||||
.cfi_startproc
|
||||
xorl %eax, %eax
|
||||
cmpl %edi, protected_data_1a(%rip)
|
||||
setne %al
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE4:
|
||||
.size check_protected_data_1a, .-check_protected_data_1a
|
||||
.p2align 4
|
||||
.globl check_protected_data_1b
|
||||
.type check_protected_data_1b, @function
|
||||
check_protected_data_1b:
|
||||
.LFB5:
|
||||
.cfi_startproc
|
||||
xorl %eax, %eax
|
||||
cmpl %edi, protected_data_1b(%rip)
|
||||
setne %al
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE5:
|
||||
.size check_protected_data_1b, .-check_protected_data_1b
|
||||
.globl protected_data_1b
|
||||
.data
|
||||
.align 4
|
||||
.type protected_data_1b, @object
|
||||
.size protected_data_1b, 4
|
||||
protected_data_1b:
|
||||
.long 2
|
||||
.globl protected_data_1a
|
||||
.align 4
|
||||
.type protected_data_1a, @object
|
||||
.size protected_data_1a, 4
|
||||
protected_data_1a:
|
||||
.long 1
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
#ifdef USE_GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS
|
||||
# ifdef __LP64__
|
||||
# define ALIGN 3
|
||||
# else
|
||||
# define ALIGN 2
|
||||
# endif
|
||||
.section ".note.gnu.property", "a"
|
||||
.p2align ALIGN
|
||||
.long 1f - 0f /* name length */
|
||||
.long 5f - 2f /* data length */
|
||||
.long 5 /* note type */
|
||||
0: .asciz "GNU" /* vendor name */
|
||||
1:
|
||||
.p2align ALIGN
|
||||
2: .long 0xb0008000 /* pr_type. */
|
||||
.long 4f - 3f /* pr_datasz. */
|
||||
3:
|
||||
.long 0x1
|
||||
4:
|
||||
.p2align ALIGN
|
||||
5:
|
||||
#endif
|
119
ld/testsuite/ld-x86-64/protected-data-2b.S
Normal file
119
ld/testsuite/ld-x86-64/protected-data-2b.S
Normal file
@ -0,0 +1,119 @@
|
||||
.section .rodata.str1.8,"aMS",@progbits,1
|
||||
.align 8
|
||||
.LC0:
|
||||
.string "'protected_data_1a' in main and shared library doesn't have same address"
|
||||
.align 8
|
||||
.LC1:
|
||||
.string "'protected_data_1a' in main and shared library doesn't have same value"
|
||||
.align 8
|
||||
.LC2:
|
||||
.string "'protected_data_1b' in main and shared library has same address"
|
||||
.section .rodata.str1.1,"aMS",@progbits,1
|
||||
.LC3:
|
||||
.string "PASS"
|
||||
.section .text.startup,"ax",@progbits
|
||||
.p2align 4,,15
|
||||
.globl main
|
||||
.type main, @function
|
||||
main:
|
||||
.LFB11:
|
||||
.cfi_startproc
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset 6, -16
|
||||
xorl %eax, %eax
|
||||
pushq %rbx
|
||||
.cfi_def_cfa_offset 24
|
||||
.cfi_offset 3, -24
|
||||
xorl %ebx, %ebx
|
||||
subq $8, %rsp
|
||||
.cfi_def_cfa_offset 32
|
||||
call protected_data_1a_p
|
||||
movq protected_data_1a@GOTPCREL(%rip), %rbp
|
||||
cmpq %rbp, %rax
|
||||
je .L2
|
||||
leaq .LC0(%rip), %rdi
|
||||
movb $1, %bl
|
||||
call puts
|
||||
.L2:
|
||||
movl $-1, %edi
|
||||
movl $-1, 0(%rbp)
|
||||
call check_protected_data_1a
|
||||
testl %eax, %eax
|
||||
jne .L17
|
||||
.L3:
|
||||
movl $-3, %edi
|
||||
call set_protected_data_1a
|
||||
cmpl $-3, 0(%rbp)
|
||||
je .L4
|
||||
leaq .LC1(%rip), %rdi
|
||||
movl $1, %ebx
|
||||
call puts
|
||||
.L4:
|
||||
xorl %eax, %eax
|
||||
call protected_data_1b_p
|
||||
leaq protected_data_1b(%rip), %rdx
|
||||
cmpq %rdx, %rax
|
||||
je .L18
|
||||
.L5:
|
||||
movl $2, %edi
|
||||
movl $-10, protected_data_1b(%rip)
|
||||
call check_protected_data_1b
|
||||
testl %eax, %eax
|
||||
jne .L19
|
||||
movl $-30, %edi
|
||||
call set_protected_data_1b
|
||||
cmpl $-10, protected_data_1b(%rip)
|
||||
je .L9
|
||||
.L7:
|
||||
leaq .LC2(%rip), %rdi
|
||||
movl $1, %ebx
|
||||
call puts
|
||||
.L8:
|
||||
addq $8, %rsp
|
||||
.cfi_remember_state
|
||||
.cfi_def_cfa_offset 24
|
||||
movl %ebx, %eax
|
||||
popq %rbx
|
||||
.cfi_def_cfa_offset 16
|
||||
popq %rbp
|
||||
.cfi_def_cfa_offset 8
|
||||
ret
|
||||
.L9:
|
||||
.cfi_restore_state
|
||||
testl %ebx, %ebx
|
||||
jne .L11
|
||||
leaq .LC3(%rip), %rdi
|
||||
call puts
|
||||
jmp .L8
|
||||
.L19:
|
||||
leaq .LC2(%rip), %rdi
|
||||
call puts
|
||||
movl $-30, %edi
|
||||
call set_protected_data_1b
|
||||
cmpl $-10, protected_data_1b(%rip)
|
||||
jne .L7
|
||||
.L11:
|
||||
movl $1, %ebx
|
||||
jmp .L8
|
||||
.L17:
|
||||
leaq .LC1(%rip), %rdi
|
||||
movl $1, %ebx
|
||||
call puts
|
||||
jmp .L3
|
||||
.L18:
|
||||
leaq .LC2(%rip), %rdi
|
||||
movl $1, %ebx
|
||||
call puts
|
||||
jmp .L5
|
||||
.cfi_endproc
|
||||
.LFE11:
|
||||
.size main, .-main
|
||||
.globl protected_data_1b
|
||||
.data
|
||||
.align 4
|
||||
.type protected_data_1b, @object
|
||||
.size protected_data_1b, 4
|
||||
protected_data_1b:
|
||||
.long 3
|
||||
.section .note.GNU-stack,"",@progbits
|
68
ld/testsuite/ld-x86-64/protected-func-2a.S
Normal file
68
ld/testsuite/ld-x86-64/protected-func-2a.S
Normal file
@ -0,0 +1,68 @@
|
||||
.text
|
||||
.p2align 4
|
||||
.protected protected_func_1a
|
||||
.globl protected_func_1a
|
||||
.type protected_func_1a, @function
|
||||
protected_func_1a:
|
||||
.LFB0:
|
||||
.cfi_startproc
|
||||
movl $1, %eax
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE0:
|
||||
.size protected_func_1a, .-protected_func_1a
|
||||
.p2align 4
|
||||
.protected protected_func_1b
|
||||
.globl protected_func_1b
|
||||
.type protected_func_1b, @function
|
||||
protected_func_1b:
|
||||
.LFB1:
|
||||
.cfi_startproc
|
||||
movl $2, %eax
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE1:
|
||||
.size protected_func_1b, .-protected_func_1b
|
||||
.p2align 4
|
||||
.globl protected_func_1a_p
|
||||
.type protected_func_1a_p, @function
|
||||
protected_func_1a_p:
|
||||
.LFB2:
|
||||
.cfi_startproc
|
||||
leaq protected_func_1a(%rip), %rax
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE2:
|
||||
.size protected_func_1a_p, .-protected_func_1a_p
|
||||
.p2align 4
|
||||
.globl protected_func_1b_p
|
||||
.type protected_func_1b_p, @function
|
||||
protected_func_1b_p:
|
||||
.LFB3:
|
||||
.cfi_startproc
|
||||
leaq protected_func_1b(%rip), %rax
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE3:
|
||||
.size protected_func_1b_p, .-protected_func_1b_p
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
#ifdef __LP64__
|
||||
# define ALIGN 3
|
||||
#else
|
||||
# define ALIGN 2
|
||||
#endif
|
||||
.section ".note.gnu.property", "a"
|
||||
.p2align ALIGN
|
||||
.long 1f - 0f /* name length */
|
||||
.long 5f - 2f /* data length */
|
||||
.long 5 /* note type */
|
||||
0: .asciz "GNU" /* vendor name */
|
||||
1:
|
||||
.p2align ALIGN
|
||||
2: .long 0xb0008000 /* pr_type. */
|
||||
.long 4f - 3f /* pr_datasz. */
|
||||
3:
|
||||
.long 0x1
|
||||
4:
|
||||
.p2align ALIGN
|
||||
5:
|
83
ld/testsuite/ld-x86-64/protected-func-2b.S
Normal file
83
ld/testsuite/ld-x86-64/protected-func-2b.S
Normal file
@ -0,0 +1,83 @@
|
||||
.text
|
||||
.p2align 4
|
||||
.globl protected_func_1b
|
||||
.type protected_func_1b, @function
|
||||
protected_func_1b:
|
||||
.LFB11:
|
||||
.cfi_startproc
|
||||
movl $3, %eax
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE11:
|
||||
.size protected_func_1b, .-protected_func_1b
|
||||
.section .rodata.str1.8,"aMS",@progbits,1
|
||||
.align 8
|
||||
.LC0:
|
||||
.string "'protected_func_1a' in main and shared library doesn't have same address"
|
||||
.align 8
|
||||
.LC1:
|
||||
.string "'protected_func_1a' doesn't return the correct value"
|
||||
.align 8
|
||||
.LC2:
|
||||
.string "'protected_func_1b' in main and shared library has same address"
|
||||
.section .rodata.str1.1,"aMS",@progbits,1
|
||||
.LC3:
|
||||
.string "PASS"
|
||||
.section .text.startup,"ax",@progbits
|
||||
.p2align 4
|
||||
.globl main
|
||||
.type main, @function
|
||||
main:
|
||||
.LFB12:
|
||||
.cfi_startproc
|
||||
pushq %r12
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset 12, -16
|
||||
xorl %r12d, %r12d
|
||||
call protected_func_1a_p
|
||||
cmpq protected_func_1a@GOTPCREL(%rip), %rax
|
||||
je .L4
|
||||
leaq .LC0(%rip), %rdi
|
||||
movl $1, %r12d
|
||||
call puts
|
||||
.L4:
|
||||
call protected_func_1a
|
||||
cmpl $1, %eax
|
||||
jne .L13
|
||||
call protected_func_1b_p
|
||||
leaq protected_func_1b(%rip), %rdx
|
||||
cmpq %rax, %rdx
|
||||
je .L6
|
||||
testl %r12d, %r12d
|
||||
jne .L12
|
||||
leaq .LC3(%rip), %rdi
|
||||
call puts
|
||||
movl %r12d, %eax
|
||||
popq %r12
|
||||
.cfi_remember_state
|
||||
.cfi_def_cfa_offset 8
|
||||
ret
|
||||
.L13:
|
||||
.cfi_restore_state
|
||||
leaq .LC1(%rip), %rdi
|
||||
call puts
|
||||
call protected_func_1b_p
|
||||
leaq protected_func_1b(%rip), %rdx
|
||||
cmpq %rax, %rdx
|
||||
je .L6
|
||||
.L12:
|
||||
movl $1, %r12d
|
||||
movl %r12d, %eax
|
||||
popq %r12
|
||||
.cfi_remember_state
|
||||
.cfi_def_cfa_offset 8
|
||||
ret
|
||||
.L6:
|
||||
.cfi_restore_state
|
||||
leaq .LC2(%rip), %rdi
|
||||
call puts
|
||||
jmp .L12
|
||||
.cfi_endproc
|
||||
.LFE12:
|
||||
.size main, .-main
|
||||
.section .note.GNU-stack,"",@progbits
|
29
ld/testsuite/ld-x86-64/protected-func-2c.c
Normal file
29
ld/testsuite/ld-x86-64/protected-func-2c.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include "protected-func-1.h"
|
||||
|
||||
protected_func_type protected_func_1a_ptr = protected_func_1a;
|
||||
|
||||
__attribute__ ((visibility("protected")))
|
||||
int
|
||||
protected_func_1a (void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__attribute__ ((visibility("protected")))
|
||||
int
|
||||
protected_func_1b (void)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
protected_func_type
|
||||
protected_func_1a_p (void)
|
||||
{
|
||||
return protected_func_1a;
|
||||
}
|
||||
|
||||
protected_func_type
|
||||
protected_func_1b_p (void)
|
||||
{
|
||||
return protected_func_1b;
|
||||
}
|
@ -1334,6 +1334,63 @@ if { [isnative] && [check_compiler_available] } {
|
||||
{} \
|
||||
"libprotected-func-1.so" \
|
||||
] \
|
||||
[list \
|
||||
"Build libprotected-func-2a.so" \
|
||||
"-shared" \
|
||||
"-fPIC -Wa,-mx86-used-note=yes" \
|
||||
{ protected-func-2a.S } \
|
||||
{{readelf -n indirect-extern-access.rd}} \
|
||||
"libprotected-func-2a.so" \
|
||||
] \
|
||||
[list \
|
||||
"Build libprotected-func-2b.so" \
|
||||
"-shared -z indirect-extern-access" \
|
||||
"-fPIC -Wa,-mx86-used-note=yes" \
|
||||
{ protected-func-2c.c } \
|
||||
{{readelf -n indirect-extern-access.rd}} \
|
||||
"libprotected-func-2b.so" \
|
||||
] \
|
||||
[list \
|
||||
"Build libprotected-data-1a.so" \
|
||||
"-shared -z noindirect-extern-access" \
|
||||
"-fPIC -Wa,-mx86-used-note=yes" \
|
||||
{ protected-data-1a.c } \
|
||||
{} \
|
||||
"libprotected-data-1a.so" \
|
||||
] \
|
||||
[list \
|
||||
"Build libprotected-data-1b.so" \
|
||||
"-shared -z indirect-extern-access" \
|
||||
"-fPIC -Wa,-mx86-used-note=yes" \
|
||||
{ protected-data-1a.c } \
|
||||
{} \
|
||||
"libprotected-data-1b.so" \
|
||||
] \
|
||||
[list \
|
||||
"Build protected-data-1 without PIE" \
|
||||
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1b.so" \
|
||||
"$NOPIE_CFLAGS -Wa,-mx86-used-note=yes" \
|
||||
{ protected-data-1b.c } \
|
||||
{} \
|
||||
"protected-data-1" \
|
||||
] \
|
||||
[list \
|
||||
"Build libprotected-data-2a.so" \
|
||||
"-shared" \
|
||||
"-fPIC -Wa,-mx86-used-note=yes \
|
||||
-DUSE_GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS" \
|
||||
{ protected-data-2a.S } \
|
||||
{{readelf -n indirect-extern-access.rd}} \
|
||||
"libprotected-data-2a.so" \
|
||||
] \
|
||||
[list \
|
||||
"Build libprotected-data-2b.so" \
|
||||
"-shared -z indirect-extern-access" \
|
||||
"-fPIC -Wa,-mx86-used-note=yes" \
|
||||
{ protected-data-2a.S } \
|
||||
{{readelf -n indirect-extern-access.rd}} \
|
||||
"libprotected-data-2b.so" \
|
||||
] \
|
||||
]
|
||||
|
||||
if {[istarget "x86_64-*-linux*-gnux32"]} {
|
||||
@ -1761,6 +1818,96 @@ if { [isnative] && [check_compiler_available] } {
|
||||
"pass.out" \
|
||||
"-fPIE" \
|
||||
] \
|
||||
[list \
|
||||
"Run protected-func-2a without PIE" \
|
||||
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-2a.so" \
|
||||
"-Wa,-mx86-used-note=yes" \
|
||||
{ protected-func-2b.S } \
|
||||
"protected-func-2a" \
|
||||
"pass.out" \
|
||||
"$NOPIE_CFLAGS" \
|
||||
] \
|
||||
[list \
|
||||
"Run protected-func-2b with PIE" \
|
||||
"-Wl,--no-as-needed -pie tmpdir/libprotected-func-2a.so" \
|
||||
"-Wa,-mx86-used-note=yes" \
|
||||
{ protected-func-2b.S } \
|
||||
"protected-func-2b" \
|
||||
"pass.out" \
|
||||
"-fPIE" \
|
||||
] \
|
||||
[list \
|
||||
"Run protected-func-2c without PIE" \
|
||||
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-2b.so" \
|
||||
"-Wa,-mx86-used-note=yes" \
|
||||
{ protected-func-2b.S } \
|
||||
"protected-func-2c" \
|
||||
"pass.out" \
|
||||
"$NOPIE_CFLAGS" \
|
||||
] \
|
||||
[list \
|
||||
"Run protected-func-2d with PIE" \
|
||||
"-Wl,--no-as-needed -pie tmpdir/libprotected-func-2b.so" \
|
||||
"-Wa,-mx86-used-note=yes" \
|
||||
{ protected-func-2b.S } \
|
||||
"protected-func-2d" \
|
||||
"pass.out" \
|
||||
"-fPIE" \
|
||||
] \
|
||||
[list \
|
||||
"Run protected-data-1a without PIE" \
|
||||
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
|
||||
"-Wa,-mx86-used-note=yes" \
|
||||
{ protected-data-1b.c } \
|
||||
"protected-data-1a" \
|
||||
"pass.out" \
|
||||
"$NOPIE_CFLAGS" \
|
||||
] \
|
||||
[list \
|
||||
"Run protected-data-1b with PIE" \
|
||||
"-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
|
||||
"-Wa,-mx86-used-note=yes" \
|
||||
{ protected-data-1b.c } \
|
||||
"protected-data-1b" \
|
||||
"pass.out" \
|
||||
"-fPIE" \
|
||||
] \
|
||||
[list \
|
||||
"Run protected-data-2a without PIE" \
|
||||
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
|
||||
"-Wa,-mx86-used-note=yes" \
|
||||
{ protected-data-2b.S } \
|
||||
"protected-data-2a" \
|
||||
"pass.out" \
|
||||
"$NOPIE_CFLAGS" \
|
||||
] \
|
||||
[list \
|
||||
"Run protected-data-2b with PIE" \
|
||||
"-Wl,--no-as-needed -pie tmpdir/libprotected-data-2a.so" \
|
||||
"-Wa,-mx86-used-note=yes" \
|
||||
{ protected-data-2b.S } \
|
||||
"protected-data-2b" \
|
||||
"pass.out" \
|
||||
"-fPIE" \
|
||||
] \
|
||||
[list \
|
||||
"Run protected-data-2c without PIE" \
|
||||
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2b.so" \
|
||||
"-Wa,-mx86-used-note=yes" \
|
||||
{ protected-data-2b.S } \
|
||||
"protected-data-2c" \
|
||||
"pass.out" \
|
||||
"$NOPIE_CFLAGS" \
|
||||
] \
|
||||
[list \
|
||||
"Run protected-data-2d with PIE" \
|
||||
"-Wl,--no-as-needed -pie tmpdir/libprotected-data-2b.so" \
|
||||
"-Wa,-mx86-used-note=yes" \
|
||||
{ protected-data-2b.S } \
|
||||
"protected-data-2d" \
|
||||
"pass.out" \
|
||||
"-fPIE" \
|
||||
] \
|
||||
]
|
||||
|
||||
# Run-time tests which require working ifunc attribute support.
|
||||
|
Loading…
x
Reference in New Issue
Block a user