This series changes the base addresses for klibc.so and/or klibc-using executables on several architectures, to fix build-time and run-time failures. Ben. Ben Hutchings (3): [klibc] mips64: Compatibility with R6 compact branches [klibc] arm: Move shared library below executables [klibc] riscv64: Move shared library below executables usr/klibc/README.klibc | 6 ++++++ usr/klibc/arch/arm/MCONFIG | 12 ++++++++---- usr/klibc/arch/mips64/MCONFIG | 20 +++++++++++++++----- usr/klibc/arch/riscv64/MCONFIG | 9 +++++++-- 4 files changed, 36 insertions(+), 11 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: <https://lists.zytor.com/archives/klibc/attachments/20230716/48b7e4cc/attachment.sig>
Ben Hutchings
2023-Jul-16 16:12 UTC
[klibc] [PATCH klibc 1/3] mips64: Compatibility with R6 compact branches
MIPS R6 introduced compact branch instructions, including BALC as a replacement for JAL. Both BALC and JAL have a 26-bit offset field that's shifted 2 bits left. However, in BALC this is treated as a PC-relative signed offset (?128 MiB) rather than a segment-relative unsigned offset (0-256 MiB). The base address of the klibc shared library therefore needs to change depending on whether the executable calls it with JAL or BALC. gcc (but not Clang, currently) generates BALC instructions for external function calls on R6 targets, which breaks shared library builds of klibc for these targets. Add a config symbol to control whether compact branches are used and to change the shared library base address accordingly. Signed-off-by: Ben Hutchings <ben at decadent.org.uk> --- usr/klibc/README.klibc | 6 ++++++ usr/klibc/arch/mips64/MCONFIG | 20 +++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/usr/klibc/README.klibc b/usr/klibc/README.klibc index efbb70ff..1a9e09fe 100644 --- a/usr/klibc/README.klibc +++ b/usr/klibc/README.klibc @@ -80,6 +80,12 @@ and the old system call ABI are used. * CONFIG_REGPARM (bool): Optimise function calls by passing the first 3 function parameters in registers. +For mips64 only: + +* CONFIG_KLIBC_MIPS_USE_CB (bool): Use compact branch instructions. + This should be enabled when targetting MIPS R6 and must be disabled + for older MIPS ISAs. + Building without kernel source ------------------------------ diff --git a/usr/klibc/arch/mips64/MCONFIG b/usr/klibc/arch/mips64/MCONFIG index ae879f49..e078dad7 100644 --- a/usr/klibc/arch/mips64/MCONFIG +++ b/usr/klibc/arch/mips64/MCONFIG @@ -13,12 +13,22 @@ KLIBCBITSIZE = 64 # Extra linkflags when building the shared version of the library # This address needs to be reachable using normal inter-module -# calls, and work on the memory models for this architecture -# 4862 MB - normal binaries start at 4608 MB. Non-PIC jumps usually -# use the JAL instruction which requires a destination within the same -# 256M aligned region. Since we can't put ourselves below the normal -# load address, use the very top of the 256M region (minus 2MB) +# calls, and work on the memory models for this architecture. +# Normal binaries start at 0x120000000 (4608 MiB). +# * On R5 and earlier, non-PIC jumps usually use the JAL instruction +# which requires a destination within the same 256 MiB aligned +# region. Since we can't put ourselves below the normal load +# address, use the very top of the 256 MiB region (minus 2 MiB). +# * On R6, non-PIC jumps may use either the JAL instruction or the +# BALC instruction which requires a destination within ?128 MiB. Put +# ourselves just under 128 MiB above the executable base address. +ifneq ($(CONFIG_KLIBC_MIPS_USE_CB),y) +KLIBCARCHREQFLAGS += $(call cc-option,-mcompact-branches=never) KLIBCSHAREDFLAGS = $(LD_IMAGE_BASE_OPT) 0x12FE00000 +else +KLIBCARCHREQFLAGS += -mcompact-branches=optimal +KLIBCSHAREDFLAGS = $(LD_IMAGE_BASE_OPT) 0x127E00000 +endif # Kernel uses vDSO for signal return since 2.6.34 KLIBCEXECSTACK := n -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: <https://lists.zytor.com/archives/klibc/attachments/20230716/478fb254/attachment.sig>
Ben Hutchings
2023-Jul-16 16:12 UTC
[klibc] [PATCH klibc 2/3] arm: Move shared library below executables
The default base address for arm executables is 64 kiB, and the base address for the shared library is 3.5 MiB when generating Thumb instructions. This limits the size of executables using it to be < 3.5 MiB, and it also interacts with a bug in QEMU's user-mode emulation, causing executables to immediately crash. Moving the shared library to the end of the 16 MiB range didn't help. Instead, move the shared library to 2 MiB and executables to 4 MiB. This works for both Thumb and non-Thumb configurations, so make it unconditional. References: https://bugs.debian.org/1040981 Signed-off-by: Ben Hutchings <ben at decadent.org.uk> --- usr/klibc/arch/arm/MCONFIG | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/usr/klibc/arch/arm/MCONFIG b/usr/klibc/arch/arm/MCONFIG index 41f39a0e..db5b14ac 100644 --- a/usr/klibc/arch/arm/MCONFIG +++ b/usr/klibc/arch/arm/MCONFIG @@ -19,12 +19,8 @@ ifeq ($(CONFIG_KLIBC_THUMB),y) CPU_ARCH := $(CPU_ARCH)t KLIBCREQFLAGS += -mthumb KLIBCREQFLAGS += -mabi=aapcs-linux -KLIBCSHAREDFLAGS = $(LD_IMAGE_BASE_OPT) 0x380000 else # Extra linkflags when building the shared version of the library -# This address needs to be reachable using normal inter-module -# calls, and work on the memory models for this architecture -KLIBCSHAREDFLAGS = $(LD_IMAGE_BASE_OPT) 0x01800000 ifeq ($(CONFIG_AEABI),y) KLIBCREQFLAGS += -mabi=aapcs-linux -mno-thumb-interwork else @@ -32,5 +28,13 @@ KLIBCREQFLAGS += -mabi=apcs-gnu -mno-thumb-interwork endif endif +# Normal binaries start at 64 kiB. A32 branch instructions have a +# range of ?32 MiB and T32 branch instructions only ?16 MiB, so we +# have to put klibc.so in that range. Putting it close above the +# executable can cause breakage, so instead swap them around: +# klibc.so at 2 MiB and executable at 4 MiB. +KLIBCLDFLAGS = $(LD_IMAGE_BASE_OPT) 0x400000 +KLIBCSHAREDFLAGS = $(LD_IMAGE_BASE_OPT) 0x200000 + # Kernel uses dedicated page or vDSO for signal return since 2.6.13 KLIBCEXECSTACK := n -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: <https://lists.zytor.com/archives/klibc/attachments/20230716/a0a84365/attachment.sig>
Ben Hutchings
2023-Jul-16 16:12 UTC
[klibc] [PATCH klibc 3/3] riscv64: Move shared library below executables
The default base address for riscv64 executables is 64 kiB, and I originally selected a base address for the shared library of 2 MiB. This limits the size of executables using it to be < 2 MiB, and it also interacts with a bug in QEMU's user-mode emulation, causing executables to immediately crash. It doesn't help code generation, because single-instruction jumps have a range of only ?1 MiB and two-instruction jumps have a range of ?2 GiB. Move the shared library to 64 kiB and executables to 576 kiB, to allow for generation of single-instruction jumps. (klibc.so is currently much smaller than the 512 kiB this allows for.) References: https://bugs.debian.org/1040981 Signed-off-by: Ben Hutchings <ben at decadent.org.uk> --- usr/klibc/arch/riscv64/MCONFIG | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/usr/klibc/arch/riscv64/MCONFIG b/usr/klibc/arch/riscv64/MCONFIG index 34061086..717aedaa 100644 --- a/usr/klibc/arch/riscv64/MCONFIG +++ b/usr/klibc/arch/riscv64/MCONFIG @@ -13,8 +13,13 @@ KLIBCOPTFLAGS += -g endif KLIBCBITSIZE = 64 -# Normal binaries start at 64 KB, so start the libary at 2 MB. -KLIBCSHAREDFLAGS = $(LD_IMAGE_BASE_OPT) 0x00200000 +# Normal binaries start at 64 kiB. Jumps can use either a single +# instruction with offset of ?1 MiB, or two instructions with offset +# of ?2 GiB. Putting klibc.so close above the executable can cause +# breakage, so instead swap them around: klibc.so at 64 kiB and +# executable at 576 kiB. +KLIBCLDFLAGS = $(LD_IMAGE_BASE_OPT) 0x90000 +KLIBCSHAREDFLAGS = $(LD_IMAGE_BASE_OPT) 0x10000 KLIBCSHAREDFLAGS += --defsym '__global_pointer$$=0' # Kernel has never used stack trampolines -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: <https://lists.zytor.com/archives/klibc/attachments/20230716/dd8eed1a/attachment.sig>