klibc-bot for Ben Hutchings
2020-Dec-12 23:27 UTC
[klibc] [klibc:master] riscv64: Make linker relaxation work and enable it
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)