This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Handle R_X86_64_RELATIVE64 and R_X86_64_64 for x32


Hi,

I try to support x86-64 assembly codes in x32 as much as I can.  To
support

	.quad	func + xxxx

x32 has a new 64-bit dynamic relocation, R_X86_64_RELATIVE64, as well
as the existing 64-bit dynamic relocation, R_X86_64_64.  This patch adds
their support with testcases.  Tested on Linux/x32 and Linux/x86-64.
OK to install?

Thanks.


H.J.
---
	* elf/elf.h (R_X86_64_RELATIVE64): New.
	(R_X86_64_NUM): Updated.
	* sysdeps/x86_64/dl-machine.h (elf_machine_rela): Handle
	R_X86_64_RELATIVE64 and R_X86_64_64 for x32.
	(elf_machine_rela_relative): Handle R_X86_64_RELATIVE64 for
	x32.
	* sysdeps/x86_64/Makefile (tests): Add tst-quad1 tst-quad2
	tst-quad1pie tst-quad2pie
	(modules-names): Add tst-quadmod1 tst-quadmod2.
	($(objpfx)tst-quad1): New dependency.
	($(objpfx)tst-quad2): Likewise.
	($(objpfx)tst-quad1pie): Likewise.
	($(objpfx)tst-quad2pie): Likewise.
	* sysdeps/x86_64/tst-quad1.c: New file.
	* sysdeps/x86_64/tst-quad1pie.c: New file.
	* sysdeps/x86_64/tst-quad2.c: Likewise.
	* sysdeps/x86_64/tst-quad2pie.c: Likewise.
	* sysdeps/x86_64/tst-quadmod1.S: Likewise.
	* sysdeps/x86_64/tst-quadmod1pie.S: Likewise.
	* sysdeps/x86_64/tst-quadmod2.S: Likewise.
	* sysdeps/x86_64/tst-quadmod2pie.S: Likewise.

diff --git a/elf/elf.h b/elf/elf.h
index 347d6d8..6522ea6 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -2703,8 +2703,9 @@ typedef Elf32_Addr Elf32_Conflict;
 					   descriptor.  */
 #define R_X86_64_TLSDESC        36	/* TLS descriptor.  */
 #define R_X86_64_IRELATIVE	37	/* Adjust indirectly by program base */
+#define R_X86_64_RELATIVE64	38	/* 64-bit adjust by program base */
 
-#define R_X86_64_NUM		38
+#define R_X86_64_NUM		39
 
 
 /* AM33 relocations.  */
diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile
index b989f6a..81c9128 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 cf49d42..1227428 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 && defined __ILP32__
+  /* 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,13 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
 
 # ifndef RTLD_BOOTSTRAP
 	case R_X86_64_64:
+#  ifdef __ILP32__
+	  /* 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;
+#  else
 	  *reloc_addr = value + reloc->r_addend;
+#  endif
 	  break;
 	case R_X86_64_32:
 	  value += reloc->r_addend;
@@ -478,6 +491,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;
+#ifdef __ILP32__
+  /* 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;
+      return;
+    }
+#endif
   assert (ELFW(R_TYPE) (reloc->r_info) == R_X86_64_RELATIVE);
   *reloc_addr = l_addr + reloc->r_addend;
 }
diff --git a/sysdeps/x86_64/tst-quad1.c b/sysdeps/x86_64/tst-quad1.c
new file mode 100644
index 0000000..a8567ea
--- /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 0000000..f5fd45f
--- /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 0000000..f5fd45f
--- /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 0000000..a15d8d3
--- /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 0000000..0e691be
--- /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 0000000..c671d0c
--- /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 0000000..38ab959
--- /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 0000000..609183f
--- /dev/null
+++ b/sysdeps/x86_64/tst-quadmod2pie.S
@@ -0,0 +1 @@
+#include "tst-quadmod2.S"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]