5de29b
# commit d31beafa8e4ca69faa4cf362784796ef17299341
5de29b
# Author: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
5de29b
# Date:   Wed Dec 4 06:49:15 2013 -0600
5de29b
# 
5de29b
#     PowerPC64 ELFv2 ABI 1/6: Code refactoring
5de29b
#     
5de29b
#     This is the first patch to support the new ELFv2 ABI in glibc.
5de29b
#     
5de29b
#     As preparation, this patch simply refactors some of the powerpc64 assembler
5de29b
#     code to move all code related to creating function descriptors (.opd section)
5de29b
#     or using function descriptors (function pointer call) into a central place
5de29b
#     in sysdep.h.
5de29b
#     
5de29b
#     Note that most locations creating .opd entries were already using macros
5de29b
#     in sysdep.h, this patch simply extends this to the remaining places.
5de29b
#     
5de29b
#     No relevant change in generated code expected.
5de29b
# 
12745e
diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S
12745e
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S	2014-05-29 13:56:35.000000000 -0500
12745e
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S	2014-05-29 13:56:37.000000000 -0500
5de29b
@@ -60,18 +60,8 @@
5de29b
 .LC0:
5de29b
 	.tc PREINIT_FUNCTION[TC], PREINIT_FUNCTION
5de29b
 #endif
5de29b
-	.type BODY_LABEL (_init), @function
5de29b
-	.globl _init
5de29b
-	.section ".opd", "aw"
5de29b
-	.align 3
5de29b
-_init:	OPD_ENT (_init)
5de29b
-#ifdef HAVE_ASM_GLOBAL_DOT_NAME
5de29b
-	.globl BODY_LABEL (_init)
5de29b
-	.size _init, 24
5de29b
-#else
5de29b
-	.type _init, @function
5de29b
-#endif
5de29b
 	.section ".init", "ax", @progbits
5de29b
+	ENTRY_2(_init)
5de29b
 	.align ALIGNARG (2)
5de29b
 BODY_LABEL (_init):
5de29b
 	mflr 0
5de29b
@@ -87,18 +77,8 @@
5de29b
 	nop
5de29b
 1:
5de29b
 
5de29b
-	.type BODY_LABEL (_fini), @function
5de29b
-	.globl _fini
5de29b
-	.section ".opd", "aw"
5de29b
-	.align 3
5de29b
-_fini:	OPD_ENT (_fini)
5de29b
-#ifdef HAVE_ASM_GLOBAL_DOT_NAME
5de29b
-	.globl BODY_LABEL (_fini)
5de29b
-	.size _fini, 24
5de29b
-#else
5de29b
-	.type _fini, @function
5de29b
-#endif
5de29b
 	.section ".fini", "ax", @progbits
5de29b
+	ENTRY_2(_fini)
5de29b
 	.align ALIGNARG (2)
5de29b
 BODY_LABEL (_fini):
5de29b
 	mflr 0
12745e
diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h
12745e
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h	2014-05-29 13:56:35.000000000 -0500
12745e
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h	2014-05-29 13:56:37.000000000 -0500
5de29b
@@ -122,14 +122,7 @@
5de29b
 #define RTLD_START \
5de29b
   asm (".pushsection \".text\"\n"					\
5de29b
 "	.align	2\n"							\
5de29b
-"	.type	" BODY_PREFIX "_start,@function\n"			\
5de29b
-"	.pushsection \".opd\",\"aw\"\n"					\
5de29b
-"	.align	3\n"							\
5de29b
-"	.globl	_start\n"						\
5de29b
 "	" ENTRY_2(_start) "\n"						\
5de29b
-"_start:\n"								\
5de29b
-"	" OPD_ENT(_start) "\n"						\
5de29b
-"	.popsection\n"							\
5de29b
 BODY_PREFIX "_start:\n"							\
5de29b
 /* We start with the following on the stack, from top:			\
5de29b
    argc (4 bytes);							\
5de29b
@@ -154,11 +147,6 @@
5de29b
 ".LT__start_name_end:\n"						\
5de29b
 "	.align 2\n"							\
5de29b
 "	" END_2(_start) "\n"						\
5de29b
-"	.globl	_dl_start_user\n"					\
5de29b
-"	.pushsection \".opd\",\"aw\"\n"					\
5de29b
-"_dl_start_user:\n"							\
5de29b
-"	" OPD_ENT(_dl_start_user) "\n"					\
5de29b
-"	.popsection\n"							\
5de29b
 "	.pushsection	\".toc\",\"aw\"\n"				\
5de29b
 DL_STARTING_UP_DEF							\
5de29b
 ".LC__rtld_local:\n"							\
5de29b
@@ -170,7 +158,6 @@
5de29b
 ".LC__dl_fini:\n"							\
5de29b
 "	.tc _dl_fini[TC],_dl_fini\n"					\
5de29b
 "	.popsection\n"							\
5de29b
-"	.type	" BODY_PREFIX "_dl_start_user,@function\n"		\
5de29b
 "	" ENTRY_2(_dl_start_user) "\n"					\
5de29b
 /* Now, we do our main work of calling initialisation procedures.	\
5de29b
    The ELF ABI doesn't say anything about parameters for these,		\
5de29b
@@ -228,10 +215,7 @@
5de29b
 /* Now, call the start function descriptor at r30...  */		\
5de29b
 "	.globl	._dl_main_dispatch\n"					\
5de29b
 "._dl_main_dispatch:\n"							\
5de29b
-"	ld	0,0(30)\n"						\
5de29b
-"	ld	2,8(30)\n"						\
5de29b
-"	mtctr	0\n"							\
5de29b
-"	ld	11,16(30)\n"						\
5de29b
+"	" PPC64_LOAD_FUNCPTR(30) "\n"					\
5de29b
 "	bctr\n"								\
5de29b
 ".LT__dl_start_user:\n"							\
5de29b
 "	.long 0\n"							\
12745e
diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S
12745e
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S	2014-05-29 13:56:35.000000000 -0500
12745e
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S	2014-05-29 13:56:37.000000000 -0500
5de29b
@@ -71,12 +71,8 @@
5de29b
 	ld	r5,INT_PARMS+16(r1)
5de29b
 	ld	r4,INT_PARMS+8(r1)
5de29b
 	mtcrf	0xFF,r0
5de29b
-/* Load the target address, toc and static chain reg from the function
5de29b
-   descriptor returned by fixup.  */
5de29b
-	ld	r0,0(r3)
5de29b
-	ld	r2,8(r3)
5de29b
-	mtctr	r0
5de29b
-	ld	r11,16(r3)
5de29b
+/* Prepare for calling the function returned by fixup.  */
5de29b
+	PPC64_LOAD_FUNCPTR r3
5de29b
 	ld	r3,INT_PARMS+0(r1)
5de29b
 /* Unwind the stack frame, and jump.  */
5de29b
 	addi	r1,r1,FRAME_SIZE
5de29b
@@ -322,13 +318,9 @@
5de29b
 	ld	r5,INT_PARMS+16(r1)
5de29b
 	ld	r4,INT_PARMS+8(r1)
5de29b
 	mtcrf	0xFF,r0
5de29b
-/* Load the target address, toc and static chain reg from the function
5de29b
-   descriptor returned by fixup.  */
5de29b
-	ld	r0,0(r3)
5de29b
-	ld	r2,8(r3)
5de29b
-	ld	r11,16(r3)
5de29b
+/* Prepare for calling the function returned by fixup.  */
5de29b
+	PPC64_LOAD_FUNCPTR r3
5de29b
 	ld	r3,INT_PARMS+0(r1)
5de29b
-	mtctr	r0
5de29b
 /* Load the floating point registers.  */
5de29b
 	lfd	fp1,FPR_PARMS+0(r1)
5de29b
 	lfd	fp2,FPR_PARMS+8(r1)
5de29b
@@ -386,14 +378,10 @@
5de29b
 	ld	r5,INT_PARMS+16(r1)
5de29b
 	ld	r4,INT_PARMS+8(r1)
5de29b
 	mtcrf	0xFF,r0
5de29b
-/* Load the target address, toc and static chain reg from the function
5de29b
-   descriptor returned by fixup.  */
5de29b
-	ld	r0,0(r3)
5de29b
+/* Prepare for calling the function returned by fixup.  */
5de29b
 	std	r2,40(r1)
5de29b
-	ld	r2,8(r3)
5de29b
-	ld	r11,16(r3)
5de29b
+	PPC64_LOAD_FUNCPTR r3
5de29b
 	ld	r3,INT_PARMS+0(r1)
5de29b
-	mtctr	r0
5de29b
 /* Load the floating point registers.  */
5de29b
 	lfd	fp1,FPR_PARMS+0(r1)
5de29b
 	lfd	fp2,FPR_PARMS+8(r1)
12745e
diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h
12745e
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h	2014-05-29 13:56:35.000000000 -0500
12745e
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h	2014-05-29 13:56:37.000000000 -0500
5de29b
@@ -74,6 +74,14 @@
5de29b
 #endif
5de29b
 	.endm
5de29b
 
5de29b
+/* Macro to prepare for calling via a function pointer.  */
5de29b
+	.macro PPC64_LOAD_FUNCPTR PTR
5de29b
+	ld      r12,0(\PTR)
5de29b
+	ld      r2,8(\PTR)
5de29b
+	mtctr   r12
5de29b
+	ld      r11,16(\PTR)
5de29b
+	.endm
5de29b
+
5de29b
 #ifdef USE_PPC64_OVERLAPPING_OPD
5de29b
 # define OPD_ENT(name)	.quad BODY_LABEL (name), .TOC.@tocbase
5de29b
 #else
5de29b
@@ -81,7 +89,6 @@
5de29b
 #endif
5de29b
 
5de29b
 #define ENTRY_1(name)	\
5de29b
-	.section	".text";		\
5de29b
 	.type BODY_LABEL(name),@function;	\
5de29b
 	.globl name;				\
5de29b
 	.section ".opd","aw";			\
5de29b
@@ -110,6 +117,7 @@
5de29b
 #endif
5de29b
 
5de29b
 #define ENTRY(name)	\
5de29b
+	.section	".text";		\
5de29b
 	ENTRY_2(name)				\
5de29b
 	.align ALIGNARG(2);			\
5de29b
 BODY_LABEL(name):				\
5de29b
@@ -127,6 +135,7 @@
5de29b
 /* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
5de29b
    past a 2^alignt boundary.  */
5de29b
 #define EALIGN(name, alignt, words) \
5de29b
+	.section	".text";		\
5de29b
 	ENTRY_2(name)				\
5de29b
 	.align ALIGNARG(alignt);		\
5de29b
 	EALIGN_W_##words;			\
5de29b
@@ -286,24 +295,42 @@
5de29b
 
5de29b
 #else /* !__ASSEMBLER__ */
5de29b
 
5de29b
+#define PPC64_LOAD_FUNCPTR(ptr) \
5de29b
+	"ld 	12,0(" #ptr ");\n"					\
5de29b
+	"ld	2,8(" #ptr ");\n"					\
5de29b
+	"mtctr	12;\n"							\
5de29b
+	"ld	11,16(" #ptr ");"
5de29b
+
5de29b
 #ifdef USE_PPC64_OVERLAPPING_OPD
5de29b
 # define OPD_ENT(name)	".quad " BODY_PREFIX #name ", .TOC.@tocbase;"
5de29b
 #else
5de29b
 # define OPD_ENT(name)	".quad " BODY_PREFIX #name ", .TOC.@tocbase, 0;"
5de29b
 #endif
5de29b
 
5de29b
+#define ENTRY_1(name)	\
5de29b
+	".type   " BODY_PREFIX #name ",@function;\n"			\
5de29b
+	".globl " #name ";\n"						\
5de29b
+	".pushsection \".opd\",\"aw\";\n"				\
5de29b
+	".align  3;\n"							\
5de29b
+#name ":\n"								\
5de29b
+	OPD_ENT (name) "\n"						\
5de29b
+	".popsection;"
5de29b
+
5de29b
 #ifdef HAVE_ASM_GLOBAL_DOT_NAME
5de29b
 # define DOT_PREFIX "."
5de29b
 # define BODY_PREFIX "."
5de29b
 # define ENTRY_2(name)	\
5de29b
 	".globl " BODY_PREFIX #name ";\n"				\
5de29b
+	ENTRY_1(name) "\n"						\
5de29b
 	".size  " #name ", 24;"
5de29b
 # define END_2(name)	\
5de29b
 	".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";"
5de29b
 #else
5de29b
 # define DOT_PREFIX ""
5de29b
 # define BODY_PREFIX ".LY"
5de29b
-# define ENTRY_2(name) ".type " #name ",@function;"
5de29b
+# define ENTRY_2(name)	\
5de29b
+	".type " #name ",@function;\n"					\
5de29b
+	ENTRY_1(name)
5de29b
 # define END_2(name)	\
5de29b
 	".size " #name ",.-" BODY_PREFIX #name ";\n"			\
5de29b
 	".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";"
12745e
diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
12745e
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S	2014-05-29 13:56:35.000000000 -0500
12745e
+++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S	2014-05-29 13:56:37.000000000 -0500
5de29b
@@ -104,9 +104,7 @@
5de29b
 
5de29b
 	std	r2,40(r1)
5de29b
 	/* Call procedure.  */
5de29b
-	ld	r0,0(r30)
5de29b
-	ld	r2,8(r30)
5de29b
-	mtctr	r0
5de29b
+	PPC64_LOAD_FUNCPTR r30
5de29b
 	mr	r3,r31
5de29b
 	bctrl
5de29b
 	ld	r2,40(r1)