diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2017-08-26 19:22:26 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2017-08-26 19:26:21 -0700 |
commit | a5b4ee9451dc9ffb6aa29376fc03943c53c6da0d (patch) | |
tree | 74028cae4c8a9f47eab5faa25aff8a47b0c04e77 /ld | |
parent | aecbb010f9d74b574ba89a64f45cde2407e53dab (diff) | |
download | gdb-a5b4ee9451dc9ffb6aa29376fc03943c53c6da0d.zip gdb-a5b4ee9451dc9ffb6aa29376fc03943c53c6da0d.tar.gz gdb-a5b4ee9451dc9ffb6aa29376fc03943c53c6da0d.tar.bz2 |
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.
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ChangeLog | 14 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/i386.exp | 51 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr21997-1a.S | 35 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr21997-1b.c | 16 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr21997-1c.S | 51 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr21997-1a.S | 24 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr21997-1a.err | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr21997-1b.c | 13 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr21997-1b.err | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr21997-1c.c | 13 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/x86-64.exp | 69 |
11 files changed, 290 insertions, 0 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 5efcbd3..06b8c25 100644 --- a/ld/ChangeLog +++ b/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> * testsuite/ld-elf/pr21903c.d: Remove '\' before --. diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index c813a80..bd15610 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -1254,6 +1254,14 @@ if { [isnative] {} \ "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 \ @@ -1309,6 +1317,49 @@ if { [isnative] "pass.out" \ "-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] } { diff --git a/ld/testsuite/ld-i386/pr21997-1a.S b/ld/testsuite/ld-i386/pr21997-1a.S new file mode 100644 index 0000000..aea17f8 --- /dev/null +++ b/ld/testsuite/ld-i386/pr21997-1a.S @@ -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 diff --git a/ld/testsuite/ld-i386/pr21997-1b.c b/ld/testsuite/ld-i386/pr21997-1b.c new file mode 100644 index 0000000..576362e --- /dev/null +++ b/ld/testsuite/ld-i386/pr21997-1b.c @@ -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; +} diff --git a/ld/testsuite/ld-i386/pr21997-1c.S b/ld/testsuite/ld-i386/pr21997-1c.S new file mode 100644 index 0000000..8534877 --- /dev/null +++ b/ld/testsuite/ld-i386/pr21997-1c.S @@ -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 diff --git a/ld/testsuite/ld-x86-64/pr21997-1a.S b/ld/testsuite/ld-x86-64/pr21997-1a.S new file mode 100644 index 0000000..cab99a9 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr21997-1a.S @@ -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 diff --git a/ld/testsuite/ld-x86-64/pr21997-1a.err b/ld/testsuite/ld-x86-64/pr21997-1a.err new file mode 100644 index 0000000..5d663a3 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr21997-1a.err @@ -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 +#... diff --git a/ld/testsuite/ld-x86-64/pr21997-1b.c b/ld/testsuite/ld-x86-64/pr21997-1b.c new file mode 100644 index 0000000..ffed117 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr21997-1b.c @@ -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; +} diff --git a/ld/testsuite/ld-x86-64/pr21997-1b.err b/ld/testsuite/ld-x86-64/pr21997-1b.err new file mode 100644 index 0000000..365de67 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr21997-1b.err @@ -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 +#... diff --git a/ld/testsuite/ld-x86-64/pr21997-1c.c b/ld/testsuite/ld-x86-64/pr21997-1c.c new file mode 100644 index 0000000..6d7b9dc --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr21997-1c.c @@ -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; +} diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 45e93b2..0e018c5 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -1056,6 +1056,22 @@ if { [isnative] && [which $CC] != 0 } { {{error_output "pr22001-1a.err"}} \ "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"]} { @@ -1069,6 +1085,15 @@ if { [isnative] && [which $CC] != 0 } { "pass.out" \ "$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 { run_cc_link_tests [list \ @@ -1080,6 +1105,14 @@ if { [isnative] && [which $CC] != 0 } { {{error_output "pr22001-1b.err"}} \ "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" \ "-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. |