aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/elf.h9
-rw-r--r--elf/tls-macros.h51
2 files changed, 57 insertions, 3 deletions
diff --git a/elf/elf.h b/elf/elf.h
index 5ae696da6c..a09d279dbf 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -1979,10 +1979,19 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
+/* GNU relocs used in PIC code sequences. */
+#define R_PPC_REL16 249 /* word32 (sym-.) */
+#define R_PPC_REL16_LO 250 /* half16 (sym-.)@l */
+#define R_PPC_REL16_HI 251 /* half16 (sym-.)@h */
+#define R_PPC_REL16_HA 252 /* half16 (sym-.)@ha */
+
/* This is a phony reloc to handle any old fashioned TOC16 references
that may still be in object files. */
#define R_PPC_TOC16 255
+/* PowerPC specific values for the Dyn d_tag field. */
+#define DT_PPC_GOT (DT_LOPROC + 0)
+#define DT_PPC_NUM 1
/* PowerPC64 relocations defined by the ABIs */
#define R_PPC64_NONE R_PPC_NONE
diff --git a/elf/tls-macros.h b/elf/tls-macros.h
index 0ae9e65dc0..37cbe7514f 100644
--- a/elf/tls-macros.h
+++ b/elf/tls-macros.h
@@ -703,6 +703,8 @@ register void *__gp __asm__("$29");
#elif defined __powerpc__ && !defined __powerpc64__
+#include "config.h"
+
# define __TLS_CALL_CLOBBERS \
"0", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", \
"lr", "ctr", "cr0", "cr1", "cr5", "cr6", "cr7"
@@ -715,7 +717,20 @@ register void *__gp __asm__("$29");
__result; })
/* PowerPC32 Initial Exec TLS access. */
-# define TLS_IE(x) \
+# ifdef HAVE_ASM_PPC_REL16
+# define TLS_IE(x) \
+ ({ int *__result; \
+ asm ("bcl 20,31,1f\n1:\t" \
+ "mflr %0\n\t" \
+ "addis %0,%0,_GLOBAL_OFFSET_TABLE_-1b@ha\n\t" \
+ "addi %0,%0,_GLOBAL_OFFSET_TABLE_-1b@l\n\t" \
+ "lwz %0," #x "@got@tprel(%0)\n\t" \
+ "add %0,%0," #x "@tls" \
+ : "=b" (__result) : \
+ : "lr"); \
+ __result; })
+# else
+# define TLS_IE(x) \
({ int *__result; \
asm ("bl _GLOBAL_OFFSET_TABLE_@local-4\n\t" \
"mflr %0\n\t" \
@@ -724,9 +739,24 @@ register void *__gp __asm__("$29");
: "=b" (__result) : \
: "lr"); \
__result; })
+# endif
/* PowerPC32 Local Dynamic TLS access. */
-# define TLS_LD(x) \
+# ifdef HAVE_ASM_PPC_REL16
+# define TLS_LD(x) \
+ ({ int *__result; \
+ asm ("bcl 20,31,1f\n1:\t" \
+ "mflr 3\n\t" \
+ "addis 3,3,_GLOBAL_OFFSET_TABLE_-1b@ha\n\t" \
+ "addi 3,3,_GLOBAL_OFFSET_TABLE_-1b@l\n\t" \
+ "addi 3,3," #x "@got@tlsld\n\t" \
+ "bl __tls_get_addr@plt\n\t" \
+ "addi %0,3," #x "@dtprel" \
+ : "=r" (__result) : \
+ : __TLS_CALL_CLOBBERS); \
+ __result; })
+# else
+# define TLS_LD(x) \
({ int *__result; \
asm ("bl _GLOBAL_OFFSET_TABLE_@local-4\n\t" \
"mflr 3\n\t" \
@@ -736,9 +766,23 @@ register void *__gp __asm__("$29");
: "=r" (__result) : \
: __TLS_CALL_CLOBBERS); \
__result; })
+# endif
/* PowerPC32 General Dynamic TLS access. */
-# define TLS_GD(x) \
+# ifdef HAVE_ASM_PPC_REL16
+# define TLS_GD(x) \
+ ({ register int *__result __asm__ ("r3"); \
+ asm ("bcl 20,31,1f\n1:\t" \
+ "mflr 3\n\t" \
+ "addis 3,3,_GLOBAL_OFFSET_TABLE_-1b@ha\n\t" \
+ "addi 3,3,_GLOBAL_OFFSET_TABLE_-1b@l\n\t" \
+ "addi 3,3," #x "@got@tlsgd\n\t" \
+ "bl __tls_get_addr@plt" \
+ : : \
+ : __TLS_CALL_CLOBBERS); \
+ __result; })
+# else
+# define TLS_GD(x) \
({ register int *__result __asm__ ("r3"); \
asm ("bl _GLOBAL_OFFSET_TABLE_@local-4\n\t" \
"mflr 3\n\t" \
@@ -747,6 +791,7 @@ register void *__gp __asm__("$29");
: : \
: __TLS_CALL_CLOBBERS); \
__result; })
+# endif
#elif defined __powerpc__ && defined __powerpc64__