[klibc] [klibc:master] riscv64: Make linker relaxation work and enable it
klibc-bot for Ben Hutchings
ben at decadent.org.uk
Sat Dec 12 15:27:04 PST 2020
Commit-ID: f41ee37972fb5b319bf19c9bc88e550b30f624c1
Gitweb: http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=f41ee37972fb5b319bf19c9bc88e550b30f624c1
Author: Ben Hutchings <ben at decadent.org.uk>
AuthorDate: Sat, 29 Aug 2020 21:59:24 +0100
Committer: Ben Hutchings <ben at decadent.org.uk>
CommitDate: Sat, 12 Dec 2020 21:58:15 +0100
[klibc] riscv64: Make linker relaxation work and enable it
RISC-V code generally needs two instructions to address static data,
but up to 4K of static data in an executable can be addressed using a
single instruction. The linker "relaxes" a two-instruction sequence
to one instruction, assuming that the gp register is initialised
appropriately.
In my initial port, I had this working for static executables but not
for those using the shared library, so I disabled relaxation.
gp-relative relaxation is *not* meant to be used in shared libraries,
but we should enable it in executables. pc-relative relaxation can be
enabled in all cases.
* When linking the shared library, define __global_pointer$ as 0 to
disable gp-relative relaxation
* For executables using the shared-library, add a _main routine in
_main.S that initialises gp and tail-calls main
* Add _main.o to $(KLIBCCRTSHARED) and change the entry point to _main
* Install _main.o so klcc can use it
* Drop the --no-relax linker option
Thanks: Jessica Clarke <jrtc27 at jrtc27.com>
Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
---
usr/klibc/arch/riscv64/Kbuild | 8 ++++++--
usr/klibc/arch/riscv64/MCONFIG | 7 ++++---
usr/klibc/arch/riscv64/_main.S | 17 +++++++++++++++++
3 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/usr/klibc/arch/riscv64/Kbuild b/usr/klibc/arch/riscv64/Kbuild
index 242ac5bb..218f3869 100644
--- a/usr/klibc/arch/riscv64/Kbuild
+++ b/usr/klibc/arch/riscv64/Kbuild
@@ -2,7 +2,11 @@
#
# klibc files for riscv64
-always := crt0.o
-targets := crt0.o
+always := crt0.o _main.o
+targets := crt0.o _main.o
klib-y := setjmp.o syscall.o
+
+install-rule:
+ $(Q)$(shell $(install-data) $(call objectify,_main.o) \
+ $(INSTALLROOT)$(INSTALLDIR)/$(KLIBCCROSS)lib)
diff --git a/usr/klibc/arch/riscv64/MCONFIG b/usr/klibc/arch/riscv64/MCONFIG
index 9bc7bd24..34061086 100644
--- a/usr/klibc/arch/riscv64/MCONFIG
+++ b/usr/klibc/arch/riscv64/MCONFIG
@@ -7,9 +7,6 @@
# accordingly.
#
-# We should get klibc.so and the executables to agree on what gp
-# should be. For now, disable gp-relative addressing.
-KLIBCLDFLAGS = --no-relax
KLIBCOPTFLAGS += -Os -fomit-frame-pointer
ifeq ($(DEBUG),y)
KLIBCOPTFLAGS += -g
@@ -18,6 +15,10 @@ KLIBCBITSIZE = 64
# Normal binaries start at 64 KB, so start the libary at 2 MB.
KLIBCSHAREDFLAGS = $(LD_IMAGE_BASE_OPT) 0x00200000
+KLIBCSHAREDFLAGS += --defsym '__global_pointer$$=0'
# Kernel has never used stack trampolines
KLIBCEXECSTACK := n
+
+KLIBCEMAIN := -e _main
+KLIBCCRTSHARED += $(KLIBCOBJ)/arch/riscv64/_main.o
diff --git a/usr/klibc/arch/riscv64/_main.S b/usr/klibc/arch/riscv64/_main.S
new file mode 100644
index 00000000..284a2222
--- /dev/null
+++ b/usr/klibc/arch/riscv64/_main.S
@@ -0,0 +1,17 @@
+#
+# arch/riscv64/_main.S
+#
+# Does arch-specific initialization and invokes main with the
+# appropriate arguments.
+#
+
+#include <machine/asm.h>
+
+ENTRY(_main)
+ .option push
+ .option norelax
+ lla gp, __global_pointer$
+ .option pop
+
+ j main
+END(_main)
More information about the klibc
mailing list