diff options
Diffstat (limited to 'sysdeps/x86_64')
-rw-r--r-- | sysdeps/x86_64/Makefile | 13 | ||||
-rw-r--r-- | sysdeps/x86_64/dl-machine.h | 22 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-quad1.c | 25 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-quad1pie.c | 1 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-quad2.c | 1 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-quad2pie.c | 1 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-quadmod1.S | 44 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-quadmod1pie.S | 2 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-quadmod2.S | 43 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-quadmod2pie.S | 1 |
10 files changed, 150 insertions, 3 deletions
diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile index b989f6a976..81c9128a95 100644 --- a/sysdeps/x86_64/Makefile +++ b/sysdeps/x86_64/Makefile @@ -21,6 +21,19 @@ sysdep-dl-routines += tlsdesc dl-tlsdesc sysdep_routines += tlsdesc dl-tlsdesc sysdep-rtld-routines += tlsdesc dl-tlsdesc +tests += tst-quad1 tst-quad2 +modules-names += tst-quadmod1 tst-quadmod2 + +$(objpfx)tst-quad1: $(objpfx)tst-quadmod1.so +$(objpfx)tst-quad2: $(objpfx)tst-quadmod2.so + +quad-pie-test += tst-quad1pie tst-quad2pie +tests += $(quad-pie-test) +tests-pie += $(quad-pie-test) + +$(objpfx)tst-quad1pie: $(objpfx)tst-quadmod1pie.o +$(objpfx)tst-quad2pie: $(objpfx)tst-quadmod2pie.o + tests: $(objpfx)tst-xmmymm.out $(objpfx)tst-xmmymm.out: ../sysdeps/x86_64/tst-xmmymm.sh $(objpfx)ld.so @echo "Checking ld.so for SSE register use. This will take a few seconds..." diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h index 934e0b0d6f..e3bab5f22d 100644 --- a/sysdeps/x86_64/dl-machine.h +++ b/sysdeps/x86_64/dl-machine.h @@ -283,6 +283,13 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, } else # endif +# if !defined RTLD_BOOTSTRAP + /* l_addr + r_addend may be > 0xffffffff and R_X86_64_RELATIVE64 + relocation updates the whole 64-bit entry. */ + if (__builtin_expect (r_type == R_X86_64_RELATIVE64, 0)) + *(Elf64_Addr *) reloc_addr = (Elf64_Addr) map->l_addr + reloc->r_addend; + else +# endif if (__builtin_expect (r_type == R_X86_64_NONE, 0)) return; else @@ -407,7 +414,9 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, # ifndef RTLD_BOOTSTRAP case R_X86_64_64: - *reloc_addr = value + reloc->r_addend; + /* value + r_addend may be > 0xffffffff and R_X86_64_64 + relocation updates the whole 64-bit entry. */ + *(Elf64_Addr *) reloc_addr = (Elf64_Addr) value + reloc->r_addend; break; case R_X86_64_32: value += reloc->r_addend; @@ -478,8 +487,15 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, void *const reloc_addr_arg) { ElfW(Addr) *const reloc_addr = reloc_addr_arg; - assert (ELFW(R_TYPE) (reloc->r_info) == R_X86_64_RELATIVE); - *reloc_addr = l_addr + reloc->r_addend; + /* l_addr + r_addend may be > 0xffffffff and R_X86_64_RELATIVE64 + relocation updates the whole 64-bit entry. */ + if (__builtin_expect (ELFW(R_TYPE) (reloc->r_info) == R_X86_64_RELATIVE64, 0)) + *(Elf64_Addr *) reloc_addr = (Elf64_Addr) l_addr + reloc->r_addend; + else + { + assert (ELFW(R_TYPE) (reloc->r_info) == R_X86_64_RELATIVE); + *reloc_addr = l_addr + reloc->r_addend; + } } auto inline void diff --git a/sysdeps/x86_64/tst-quad1.c b/sysdeps/x86_64/tst-quad1.c new file mode 100644 index 0000000000..a8567ea8a2 --- /dev/null +++ b/sysdeps/x86_64/tst-quad1.c @@ -0,0 +1,25 @@ +/* Copyright (C) 2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +extern void foo (void); + +int +main (void) +{ + foo (); + return 0; +} diff --git a/sysdeps/x86_64/tst-quad1pie.c b/sysdeps/x86_64/tst-quad1pie.c new file mode 100644 index 0000000000..f5fd45f9b0 --- /dev/null +++ b/sysdeps/x86_64/tst-quad1pie.c @@ -0,0 +1 @@ +#include "tst-quad1.c" diff --git a/sysdeps/x86_64/tst-quad2.c b/sysdeps/x86_64/tst-quad2.c new file mode 100644 index 0000000000..f5fd45f9b0 --- /dev/null +++ b/sysdeps/x86_64/tst-quad2.c @@ -0,0 +1 @@ +#include "tst-quad1.c" diff --git a/sysdeps/x86_64/tst-quad2pie.c b/sysdeps/x86_64/tst-quad2pie.c new file mode 100644 index 0000000000..a15d8d36ac --- /dev/null +++ b/sysdeps/x86_64/tst-quad2pie.c @@ -0,0 +1 @@ +#include "tst-quad2.c" diff --git a/sysdeps/x86_64/tst-quadmod1.S b/sysdeps/x86_64/tst-quadmod1.S new file mode 100644 index 0000000000..0e691be803 --- /dev/null +++ b/sysdeps/x86_64/tst-quadmod1.S @@ -0,0 +1,44 @@ +/* Copyright (C) 2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef BIAS +# define BIAS 0x7fffffff +#endif + + .section .data.rel,"aw",@progbits + .align 8 +.Ljmp: + .quad func + BIAS + .text + .globl func + .type func, @function +func: + .cfi_startproc + xorl %edi, %edi + jmp exit@PLT + .cfi_endproc + .size func, .-func + .globl foo + .type foo, @function +foo: + .cfi_startproc + .cfi_def_cfa_register 6 + movq .Ljmp(%rip), %rax + subq $BIAS, %rax + jmp *%rax + .cfi_endproc + .size foo, .-foo diff --git a/sysdeps/x86_64/tst-quadmod1pie.S b/sysdeps/x86_64/tst-quadmod1pie.S new file mode 100644 index 0000000000..c671d0cda9 --- /dev/null +++ b/sysdeps/x86_64/tst-quadmod1pie.S @@ -0,0 +1,2 @@ +#define BIAS 0x7fff0000 +#include "tst-quadmod1.S" diff --git a/sysdeps/x86_64/tst-quadmod2.S b/sysdeps/x86_64/tst-quadmod2.S new file mode 100644 index 0000000000..38ab9598bf --- /dev/null +++ b/sysdeps/x86_64/tst-quadmod2.S @@ -0,0 +1,43 @@ +/* Copyright (C) 2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef BIAS +# define BIAS 0x7fff0000 +#endif + + .section .data.rel.local,"aw",@progbits + .align 8 +.Ljmp: + .quad func + BIAS + .text + .type func, @function +func: + .cfi_startproc + xorl %edi, %edi + jmp exit@PLT + .cfi_endproc + .size func, .-func + .globl foo + .type foo, @function +foo: + .cfi_startproc + .cfi_def_cfa_register 6 + movq .Ljmp(%rip), %rax + subq $BIAS, %rax + jmp *%rax + .cfi_endproc + .size foo, .-foo diff --git a/sysdeps/x86_64/tst-quadmod2pie.S b/sysdeps/x86_64/tst-quadmod2pie.S new file mode 100644 index 0000000000..609183fe58 --- /dev/null +++ b/sysdeps/x86_64/tst-quadmod2pie.S @@ -0,0 +1 @@ +#include "tst-quadmod2.S" |