[klibc] Fix sparc assembly when compiled as PIC

Some distributions default to PIE for their compilers, which on sparc is passed
on to the assembler. Since the behaviour of %hi/%lo changes under PIC to become
GOT offsets, the current assembly files need adapting to not try to use a GOT
offset as an absolute address.

References: https://bugs.debian.org/885852
Link: https://www.zytor.com/pipermail/klibc/2018-July/004001.html
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
diff --git a/usr/include/arch/sparc/machine/asm.h b/usr/include/arch/sparc/machine/asm.h
index 04fe9b1..fd9ef1e 100644
--- a/usr/include/arch/sparc/machine/asm.h
+++ b/usr/include/arch/sparc/machine/asm.h
@@ -61,7 +61,7 @@
 #endif
 #define	_ASM_LABEL(name)	name
 
-#ifdef PIC
+#ifdef __PIC__
 /*
  * PIC_PROLOGUE() is akin to the compiler generated function prologue for
  * PIC code. It leaves the address of the Global Offset Table in DEST,
@@ -83,12 +83,20 @@
 0: \
 	add dest,%o7,dest; \
 	mov tmp, %o7
+#define SET(var,base,dest) \
+	sethi %gdop_hix22(var), dest; \
+	xor dest, %gdop_lox10(var), dest; \
+	ldx [base + dest], dest, %gdop(var)
 #else
 #define PIC_PROLOGUE(dest,tmp) \
 	mov %o7,tmp; 3: call 4f; nop; 4: \
 	sethi %hi(_C_LABEL(_GLOBAL_OFFSET_TABLE_)-(3b-.)),dest; \
 	or dest,%lo(_C_LABEL(_GLOBAL_OFFSET_TABLE_)-(3b-.)),dest; \
 	add dest,%o7,dest; mov tmp,%o7
+#define SET(var,base,dest) \
+	sethi %gdop_hix22(var), dest; \
+	xor dest, %gdop_lox10(var), dest; \
+	ld [base + dest], dest, %gdop(var)
 #endif
 
 /*
@@ -106,7 +114,10 @@
 #endif
 #else
 #define PIC_PROLOGUE(dest,tmp)
-#define PICCY_OFFSET(var,dest,tmp)
+#define SET(var,base,dest) \
+	sethi %hi(var), dest; \
+	or dest, %lo(var), dest
+#define PICCY_SET(var,dest,tmp) SET(var,tmp,dest)
 #endif
 
 #define FTYPE(x)		.type x,@function
diff --git a/usr/include/arch/sparc64/machine/asm.h b/usr/include/arch/sparc64/machine/asm.h
new file mode 100644
index 0000000..394ba86
--- /dev/null
+++ b/usr/include/arch/sparc64/machine/asm.h
@@ -0,0 +1 @@
+#include "../../sparc/machine/asm.h"
diff --git a/usr/include/arch/sparc64/machine/frame.h b/usr/include/arch/sparc64/machine/frame.h
new file mode 100644
index 0000000..79beea6
--- /dev/null
+++ b/usr/include/arch/sparc64/machine/frame.h
@@ -0,0 +1 @@
+#include "../../sparc/machine/frame.h"
diff --git a/usr/klibc/arch/sparc/pipe.S b/usr/klibc/arch/sparc/pipe.S
index a8abf3c..e278bda 100644
--- a/usr/klibc/arch/sparc/pipe.S
+++ b/usr/klibc/arch/sparc/pipe.S
@@ -5,6 +5,7 @@
  * they return the two file descriptors in %o0 and %o1.
  */
 
+#include <machine/asm.h>
 #include <asm/unistd.h>
 
 	.globl	pipe
@@ -16,8 +17,8 @@
 	t	0x10
 	bcc	1f
 	  nop
-	sethi	%hi(errno), %g4
-	or	%g4, %lo(errno), %g4
+	PIC_PROLOGUE(%g1,%g4)
+	SET(errno,%g1,%g4)
 	st	%o0,[%g4]
 	retl
 	  mov	-1, %o0
diff --git a/usr/klibc/arch/sparc/syscall.S b/usr/klibc/arch/sparc/syscall.S
index c0273f7..52a8583 100644
--- a/usr/klibc/arch/sparc/syscall.S
+++ b/usr/klibc/arch/sparc/syscall.S
@@ -4,14 +4,16 @@
  * Common system-call stub; %g1 already set to syscall number
  */
 
+#include <machine/asm.h>
+
 	.globl	__syscall_common
 	.type	__syscall_common,#function
        	.align	4
 __syscall_common:
 	t	0x10
 	bcc	1f
-	  sethi	%hi(errno), %g4
-	or	%g4, %lo(errno), %g4
+	  PIC_PROLOGUE(%g1,%g4)
+	SET(errno,%g1,%g4)
 	st	%o0,[%g4]
 	mov	-1, %o0
 1:
diff --git a/usr/klibc/arch/sparc/sysfork.S b/usr/klibc/arch/sparc/sysfork.S
index a66c76e..3787b94 100644
--- a/usr/klibc/arch/sparc/sysfork.S
+++ b/usr/klibc/arch/sparc/sysfork.S
@@ -8,6 +8,8 @@
  * Common system-call stub; %g1 already set to syscall number
  */
 
+#include <machine/asm.h>
+
 	.globl	__syscall_forkish
 	.type	__syscall_forkish,#function
        	.align	4
@@ -16,8 +18,8 @@
 	sub	%o1, 1, %o1
 	bcc,a	1f
 	  and	%o0, %o1, %o0
-	sethi	%hi(errno), %g4
-	or	%g4, %lo(errno), %g4
+	PIC_PROLOGUE(%g1,%g4)
+	SET(errno,%g1,%g4)
 	st	%o0,[%g4]
 	mov	-1, %o0
 1:
diff --git a/usr/klibc/arch/sparc64/pipe.S b/usr/klibc/arch/sparc64/pipe.S
index c63b20f..cb5c2c7 100644
--- a/usr/klibc/arch/sparc64/pipe.S
+++ b/usr/klibc/arch/sparc64/pipe.S
@@ -5,6 +5,7 @@
  * they return the two file descriptors in %o0 and %o1.
  */
 
+#include <machine/asm.h>
 #include <asm/unistd.h>
 
 	.globl	pipe
@@ -16,8 +17,8 @@
 	t	0x6d
 	bcc	%xcc, 1f
 	  nop
-	sethi	%hi(errno), %g4
-	or	%g4, %lo(errno), %g4
+	PIC_PROLOGUE(%g1,%g4)
+	SET(errno,%g1,%g4)
 	st	%o0,[%g4]
 	retl
 	  mov	-1, %o0
diff --git a/usr/klibc/arch/sparc64/syscall.S b/usr/klibc/arch/sparc64/syscall.S
index 7ab9d95..c84c9ae 100644
--- a/usr/klibc/arch/sparc64/syscall.S
+++ b/usr/klibc/arch/sparc64/syscall.S
@@ -4,14 +4,16 @@
  * Common system-call stub; %g1 already set to syscall number
  */
 
+#include <machine/asm.h>
+
 	.globl	__syscall_common
 	.type	__syscall_common,#function
        	.align	4
 __syscall_common:
 	t	0x6d
 	bcc	%xcc, 1f
-	  sethi	%hi(errno), %g4
-	or	%g4, %lo(errno), %g4
+	  PIC_PROLOGUE(%g1,%g4)
+	SET(errno,%g1,%g4)
 	st	%o0,[%g4]
 1:
        	retl
diff --git a/usr/klibc/arch/sparc64/sysfork.S b/usr/klibc/arch/sparc64/sysfork.S
index 2eed659..a0c1334 100644
--- a/usr/klibc/arch/sparc64/sysfork.S
+++ b/usr/klibc/arch/sparc64/sysfork.S
@@ -8,6 +8,8 @@
  * Common system-call stub; %g1 already set to syscall number
  */
 
+#include <machine/asm.h>
+
 	.globl	__syscall_forkish
 	.type	__syscall_forkish,#function
        	.align	4
@@ -16,8 +18,8 @@
 	sub	%o1, 1, %o1
 	bcc,a	%xcc, 1f
 	  and	%o0, %o1, %o0
-	sethi	%hi(errno), %g4
-	or	%g4, %lo(errno), %g4
+	PIC_PROLOGUE(%g1,%g4)
+	SET(errno,%g1,%g4)
 	st	%o0, [%g4]
 	retl
 	  mov	-1, %o0