svn commit: r356481 - in head/sys: conf riscv/riscv
John Baldwin
jhb at FreeBSD.org
Tue Jan 7 23:18:32 UTC 2020
Author: jhb
Date: Tue Jan 7 23:18:31 2020
New Revision: 356481
URL: https://svnweb.freebsd.org/changeset/base/356481
Log:
Work around lld's inability to handle undefined weak symbols on risc-v.
lld on RISC-V is not yet able to handle undefined weak symbols for
non-PIC code in the code model (medany/medium) used by the RISC-V
kernel.
Both GCC and clang emit an auipc / addi pair of instructions to
generate an address relative to the current PC with a 31-bit offset.
Undefined weak symbols need to have an address of 0, but the kernel
runs with PC values much greater than 2^31, so there is no way to
construct a NULL pointer as a PC-relative value. The bfd linker
rewrites the instruction pair to use lui / addi with values of 0 to
force a NULL pointer address. (There are similar cases for 'ld'
becoming auipc / ld that bfd rewrites to lui / ld with an address of
0.)
To work around this, compile the kernel with -fPIE when using lld.
This does not make the kernel position-independent, but it does
force the compiler to indirect address lookups through GOT entries
(so auipc / ld against a GOT entry to fetch the address). This
adds extra memory indirections for global symbols, so should be
disabled once lld is finally fixed.
A few 'la' instructions in locore that depend on PC-relative
addressing to load physical addresses before paging is enabled have to
use auipc / addi and not indirect via GOT entries, so change those to
use 'lla' which always uses auipc / addi for both PIC and non-PIC.
Submitted by: jrtc27
Sponsored by: DARPA
Differential Revision: https://reviews.freebsd.org/D23064
Modified:
head/sys/conf/kern.pre.mk
head/sys/riscv/riscv/locore.S
Modified: head/sys/conf/kern.pre.mk
==============================================================================
--- head/sys/conf/kern.pre.mk Tue Jan 7 23:10:38 2020 (r356480)
+++ head/sys/conf/kern.pre.mk Tue Jan 7 23:18:31 2020 (r356481)
@@ -170,6 +170,17 @@ LDFLAGS+= -z notext -z ifunc-noplt
.endif
.endif
+.if ${MACHINE_CPUARCH} == "riscv"
+# Hack: Work around undefined weak symbols being out of range when linking with
+# LLD (address is a PC-relative calculation, and BFD works around this by
+# rewriting the instructions to generate an absolute address of 0); -fPIE
+# avoids this since it uses the GOT for all extern symbols, which is overly
+# inefficient for us. Drop once undefined weak symbols work with medany.
+.if ${LINKER_TYPE} == "lld"
+CFLAGS+= -fPIE
+.endif
+.endif
+
NORMAL_C= ${CC} -c ${CFLAGS} ${WERROR} ${PROF} ${.IMPSRC}
NORMAL_S= ${CC:N${CCACHE_BIN}} -c ${ASM_CFLAGS} ${WERROR} ${.IMPSRC}
PROFILE_C= ${CC} -c ${CFLAGS} ${WERROR} ${.IMPSRC}
Modified: head/sys/riscv/riscv/locore.S
==============================================================================
--- head/sys/riscv/riscv/locore.S Tue Jan 7 23:10:38 2020 (r356480)
+++ head/sys/riscv/riscv/locore.S Tue Jan 7 23:18:31 2020 (r356481)
@@ -54,7 +54,7 @@
.globl _start
_start:
/* Get the physical address kernel loaded to */
- la t0, virt_map
+ lla t0, virt_map
ld t1, 0(t0)
sub t1, t1, t0
li t2, KERNBASE
@@ -66,7 +66,7 @@ _start:
*/
/* Pick a hart to run the boot process. */
- la t0, hart_lottery
+ lla t0, hart_lottery
li t1, 1
amoadd.w t0, t1, 0(t0)
@@ -82,8 +82,8 @@ _start:
*/
1:
/* Add L1 entry for kernel */
- la s1, pagetable_l1
- la s2, pagetable_l2 /* Link to next level PN */
+ lla s1, pagetable_l1
+ lla s2, pagetable_l2 /* Link to next level PN */
srli s2, s2, PAGE_SHIFT
li a5, KERNBASE
@@ -100,7 +100,7 @@ _start:
sd t6, (t0)
/* Level 2 superpages (512 x 2MiB) */
- la s1, pagetable_l2
+ lla s1, pagetable_l2
srli t4, s9, 21 /* Div physmem base by 2 MiB */
li t2, 512 /* Build 512 entries */
add t3, t4, t2
@@ -116,8 +116,8 @@ _start:
bltu t4, t3, 2b
/* Create an L1 page for early devmap */
- la s1, pagetable_l1
- la s2, pagetable_l2_devmap /* Link to next level PN */
+ lla s1, pagetable_l1
+ lla s2, pagetable_l2_devmap /* Link to next level PN */
srli s2, s2, PAGE_SHIFT
li a5, (VM_MAX_KERNEL_ADDRESS - L2_SIZE)
@@ -134,7 +134,7 @@ _start:
sd t6, (t0)
/* Create an L2 page superpage for DTB */
- la s1, pagetable_l2_devmap
+ lla s1, pagetable_l2_devmap
mv s2, a1
srli s2, s2, PAGE_SHIFT
@@ -152,14 +152,14 @@ _start:
/* Page tables END */
/* Setup supervisor trap vector */
- la t0, va
+ lla t0, va
sub t0, t0, s9
li t1, KERNBASE
add t0, t0, t1
csrw stvec, t0
/* Set page tables base register */
- la s2, pagetable_l1
+ lla s2, pagetable_l1
srli s2, s2, PAGE_SHIFT
li t0, SATP_MODE_SV39
or s2, s2, t0
More information about the svn-src-all
mailing list