summaryrefslogtreecommitdiff
path: root/LoongArch-Add-static-PIE-support.patch
blob: 79df004ccc447ddc09113576c8b5a1d5a2417ee6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
From d12d80cdcafd2f84321d311d6ce3e291f0e7b9a9 Mon Sep 17 00:00:00 2001
From: XingLi <lixing@loongson.cn>
Date: Thu, 27 Jul 2023 09:25:19 +0800
Subject: [PATCH 2/3] LoongArch: Add static PIE support

If the compiler is new enough, enable static PIE support.  In the static
PIE version of _start (in rcrt1.o), use la.pcrel instead of la.got
because in a static PIE we cannot use GOT entries until the dynamic
relocations for GOT are resolved.

From: Xi Ruoyao <xry111@xry111.site>
Date: Sat, 24 Sep 2022 15:45:34 +0800
---
 sysdeps/loongarch/configure    | 51 ++++++++++++++++++++++++++++++++++
 sysdeps/loongarch/configure.ac | 38 ++++++++++++++++++++++++-
 sysdeps/loongarch/start.S      | 16 +++++++----
 3 files changed, 99 insertions(+), 6 deletions(-)

diff --git a/sysdeps/loongarch/configure b/sysdeps/loongarch/configure
index 1e5abf81..db6341e8 100644
--- a/sysdeps/loongarch/configure
+++ b/sysdeps/loongarch/configure
@@ -2,3 +2,54 @@
  # Local configure fragment for sysdeps/loongarch/elf.
 
 #AC_DEFINE(PI_STATIC_AND_HIDDEN)
+$as_echo "#define HIDDEN_VAR_NEEDS_DYNAMIC_RELOC 1" >>confdefs.h
+ 
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the toolchain is sufficient to build static PIE on LoongArch" >&5
+$as_echo_n "checking if the toolchain is sufficient to build static PIE on LoongArch... " >&6; }
+if ${libc_cv_static_pie_on_loongarch+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  cat > conftest.S << EOF
+.global _start
+.type _start, @function
+_start:
+  li.w \$a7, 93
+  /* This ensures the assembler supports explicit reloc.  */
+  pcalau12i \$a0, %pc_hi20(x)
+  ld.w \$a0, \$a0, %pc_lo12(x)
+  syscall 0
+
+.data
+x:
+  .word 0
+  /* This should produce an R_LARCH_RELATIVE in the static PIE.  */
+  .dword _start
+EOF
+  libc_cv_static_pie_on_loongarch=no
+  if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static-pie -nostdlib -fPIE -o conftest conftest.S'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } \
+     && { ac_try='LC_ALL=C $READELF -Wr conftest | grep -q R_LARCH_RELATIVE'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+  then
+    libc_cv_static_pie_on_loongarch=yes
+  fi
+  rm -rf conftest.*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_static_pie_on_loongarch" >&5
+$as_echo "$libc_cv_static_pie_on_loongarch" >&6; }
+
+if test "$libc_cv_static_pie_on_loongarch" = yes; then
+  $as_echo "#define SUPPORT_STATIC_PIE 1" >>confdefs.h
+
+fi
+
diff --git a/sysdeps/loongarch/configure.ac b/sysdeps/loongarch/configure.ac
index 67b46ce0..603085cd 100644
--- a/sysdeps/loongarch/configure.ac
+++ b/sysdeps/loongarch/configure.ac
@@ -3,4 +3,40 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
 
 dnl It is always possible to access static and hidden symbols in an
 dnl position independent way.
-#AC_DEFINE(PI_STATIC_AND_HIDDEN)
+ AC_DEFINE(HIDDEN_VAR_NEEDS_DYNAMIC_RELOC)
+
+dnl Test if the toolchain is new enough for static PIE.
+dnl We need a GAS supporting explicit reloc (older GAS produces stack-based
+dnl reloc and triggers an internal error in the linker).  And, we need GCC to
+dnl pass the correct linker flags for static PIE.  GCC >= 13 and GAS >= 2.40
+dnl satisify the requirement, but a distro may backport static PIE support into
+dnl earlier GCC or Binutils releases as well.
+AC_CACHE_CHECK([if the toolchain is sufficient to build static PIE on LoongArch],
+libc_cv_static_pie_on_loongarch, [
+  cat > conftest.S << EOF
+.global _start
+.type _start, @function
+_start:
+  li.w \$a7, 93
+  /* This ensures the assembler supports explicit reloc.  */
+  pcalau12i \$a0, %pc_hi20(x)
+  ld.w \$a0, \$a0, %pc_lo12(x)
+  syscall 0
+
+.data
+x:
+  .word 0
+  /* This should produce an R_LARCH_RELATIVE in the static PIE.  */
+  .dword _start
+EOF
+  libc_cv_static_pie_on_loongarch=no
+  if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static-pie -nostdlib -fPIE -o conftest conftest.S]) \
+     && AC_TRY_COMMAND([LC_ALL=C $READELF -Wr conftest | grep -q R_LARCH_RELATIVE])
+  then
+    libc_cv_static_pie_on_loongarch=yes
+  fi
+  rm -rf conftest.*])
+
+if test "$libc_cv_static_pie_on_loongarch" = yes; then
+  AC_DEFINE(SUPPORT_STATIC_PIE)
+fi
diff --git a/sysdeps/loongarch/start.S b/sysdeps/loongarch/start.S
index 0deda78a..1b15fc9c 100644
--- a/sysdeps/loongarch/start.S
+++ b/sysdeps/loongarch/start.S
@@ -44,9 +44,15 @@ ENTRY (ENTRY_POINT)
 	cfi_undefined (1)
 	or		a5, a0, zero /* rtld_fini */
 
-/* We must get symbol main through GOT table, since main may not be local.
-   For instance: googletest defines main in dynamic library.  */
-	la.got		a0, t0, main
+#if defined(PIC) && !defined(SHARED)
+/* For static PIE, the GOT cannot be used in _start because the GOT entries are
+   offsets instead of real addresses before __libc_start_main.  */
+# define LA la.pcrel
+#else
+# define LA la.got
+#endif
+
+	LA		a0, t0, main
 #ifdef __loongarch_lp64
 	ld.d		a1, sp, 0
 	addi.d		a2, sp, SZREG
@@ -61,9 +67,9 @@ ENTRY (ENTRY_POINT)
 	move		a4, zero /* used to be fini */
 	or		a6, sp, zero /* stack_end */
 
-	la.got		ra, t0, __libc_start_main
+	LA		ra, t0, __libc_start_main
 	jirl		ra, ra, 0
 
-	la.got		ra, t0, abort
+	LA		ra, t0, abort
 	jirl		ra, ra, 0
 END (ENTRY_POINT)
-- 
2.33.0