diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2021-06-17 14:11:28 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2021-07-08 18:14:31 -0700 |
commit | 6f365fda85a2e2682b197540d14adf66c4261b19 (patch) | |
tree | f746621b46e022fabe3662b04da4d5c2a36f2e1b /ld | |
parent | 6320fd00dc374f74658c7e4b7dffbe1d71723284 (diff) | |
download | gdb-6f365fda85a2e2682b197540d14adf66c4261b19.zip gdb-6f365fda85a2e2682b197540d14adf66c4261b19.tar.gz gdb-6f365fda85a2e2682b197540d14adf66c4261b19.tar.bz2 |
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.
Diffstat (limited to 'ld')
25 files changed, 907 insertions, 0 deletions
@@ -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. diff --git a/ld/emulparams/extern_protected_data.sh b/ld/emulparams/extern_protected_data.sh index 30f3d1c..cb855a6 100644 --- a/ld/emulparams/extern_protected_data.sh +++ b/ld/emulparams/extern_protected_data.sh @@ -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; ' @@ -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 diff --git a/ld/ldmain.c b/ld/ldmain.c index e4c6774..0202923 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -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 = ':'; diff --git a/ld/testsuite/ld-elf/indirect-extern-access-1.rd b/ld/testsuite/ld-elf/indirect-extern-access-1.rd new file mode 100644 index 0000000..39dc89a --- /dev/null +++ b/ld/testsuite/ld-elf/indirect-extern-access-1.rd @@ -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 diff --git a/ld/testsuite/ld-elf/indirect-extern-access-1a.c b/ld/testsuite/ld-elf/indirect-extern-access-1a.c new file mode 100644 index 0000000..4789810 --- /dev/null +++ b/ld/testsuite/ld-elf/indirect-extern-access-1a.c @@ -0,0 +1 @@ +int indirect_extern_access = 1; diff --git a/ld/testsuite/ld-elf/indirect-extern-access-1b.c b/ld/testsuite/ld-elf/indirect-extern-access-1b.c new file mode 100644 index 0000000..68adae5 --- /dev/null +++ b/ld/testsuite/ld-elf/indirect-extern-access-1b.c @@ -0,0 +1,12 @@ +#include <stdio.h> + +extern int indirect_extern_access; + +int +main (void) +{ + if (indirect_extern_access == 1) + puts ("PASS"); + + return 0; +} diff --git a/ld/testsuite/ld-elf/indirect-extern-access-2.rd b/ld/testsuite/ld-elf/indirect-extern-access-2.rd new file mode 100644 index 0000000..9c7d72f --- /dev/null +++ b/ld/testsuite/ld-elf/indirect-extern-access-2.rd @@ -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 diff --git a/ld/testsuite/ld-elf/indirect-extern-access-2a.c b/ld/testsuite/ld-elf/indirect-extern-access-2a.c new file mode 100644 index 0000000..cb57068 --- /dev/null +++ b/ld/testsuite/ld-elf/indirect-extern-access-2a.c @@ -0,0 +1,10 @@ +void +indirect_extern_access (void) +{ +} + +void * +indirect_extern_access_p (void) +{ + return indirect_extern_access; +} diff --git a/ld/testsuite/ld-elf/indirect-extern-access-2b.c b/ld/testsuite/ld-elf/indirect-extern-access-2b.c new file mode 100644 index 0000000..dedfd9b --- /dev/null +++ b/ld/testsuite/ld-elf/indirect-extern-access-2b.c @@ -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; +} diff --git a/ld/testsuite/ld-elf/indirect-extern-access-3.rd b/ld/testsuite/ld-elf/indirect-extern-access-3.rd new file mode 100644 index 0000000..ce777a5 --- /dev/null +++ b/ld/testsuite/ld-elf/indirect-extern-access-3.rd @@ -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 diff --git a/ld/testsuite/ld-elf/indirect-extern-access.S b/ld/testsuite/ld-elf/indirect-extern-access.S new file mode 100644 index 0000000..25b88ba --- /dev/null +++ b/ld/testsuite/ld-elf/indirect-extern-access.S @@ -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: diff --git a/ld/testsuite/ld-elf/linux-x86.exp b/ld/testsuite/ld-elf/linux-x86.exp index 7e3a0b7..8192374 100644 --- a/ld/testsuite/ld-elf/linux-x86.exp +++ b/ld/testsuite/ld-elf/linux-x86.exp @@ -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 diff --git a/ld/testsuite/ld-elf/property-1_needed-1b.d b/ld/testsuite/ld-elf/property-1_needed-1b.d new file mode 100644 index 0000000..b7a9eea --- /dev/null +++ b/ld/testsuite/ld-elf/property-1_needed-1b.d @@ -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 diff --git a/ld/testsuite/ld-elf/property-1_needed-1c.d b/ld/testsuite/ld-elf/property-1_needed-1c.d new file mode 100644 index 0000000..21e1d26 --- /dev/null +++ b/ld/testsuite/ld-elf/property-1_needed-1c.d @@ -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 diff --git a/ld/testsuite/ld-x86-64/indirect-extern-access.rd b/ld/testsuite/ld-x86-64/indirect-extern-access.rd new file mode 100644 index 0000000..696b06f --- /dev/null +++ b/ld/testsuite/ld-x86-64/indirect-extern-access.rd @@ -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 diff --git a/ld/testsuite/ld-x86-64/protected-data-1.h b/ld/testsuite/ld-x86-64/protected-data-1.h new file mode 100644 index 0000000..a80c976 --- /dev/null +++ b/ld/testsuite/ld-x86-64/protected-data-1.h @@ -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); diff --git a/ld/testsuite/ld-x86-64/protected-data-1a.c b/ld/testsuite/ld-x86-64/protected-data-1a.c new file mode 100644 index 0000000..6942426 --- /dev/null +++ b/ld/testsuite/ld-x86-64/protected-data-1a.c @@ -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; +} diff --git a/ld/testsuite/ld-x86-64/protected-data-1b.c b/ld/testsuite/ld-x86-64/protected-data-1b.c new file mode 100644 index 0000000..a4756ee --- /dev/null +++ b/ld/testsuite/ld-x86-64/protected-data-1b.c @@ -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; +} diff --git a/ld/testsuite/ld-x86-64/protected-data-2a.S b/ld/testsuite/ld-x86-64/protected-data-2a.S new file mode 100644 index 0000000..865c1af --- /dev/null +++ b/ld/testsuite/ld-x86-64/protected-data-2a.S @@ -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 diff --git a/ld/testsuite/ld-x86-64/protected-data-2b.S b/ld/testsuite/ld-x86-64/protected-data-2b.S new file mode 100644 index 0000000..da89561 --- /dev/null +++ b/ld/testsuite/ld-x86-64/protected-data-2b.S @@ -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 diff --git a/ld/testsuite/ld-x86-64/protected-func-2a.S b/ld/testsuite/ld-x86-64/protected-func-2a.S new file mode 100644 index 0000000..35c9cd1 --- /dev/null +++ b/ld/testsuite/ld-x86-64/protected-func-2a.S @@ -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: diff --git a/ld/testsuite/ld-x86-64/protected-func-2b.S b/ld/testsuite/ld-x86-64/protected-func-2b.S new file mode 100644 index 0000000..8fa4cbf --- /dev/null +++ b/ld/testsuite/ld-x86-64/protected-func-2b.S @@ -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 diff --git a/ld/testsuite/ld-x86-64/protected-func-2c.c b/ld/testsuite/ld-x86-64/protected-func-2c.c new file mode 100644 index 0000000..c5ec1ec --- /dev/null +++ b/ld/testsuite/ld-x86-64/protected-func-2c.c @@ -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; +} diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 3bf6250..a80f22c 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -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. |