mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-05 12:56:08 +00:00
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
This commit is contained in:
parent
1c7dd40e58
commit
f39b4f8899
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=356481
@ -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}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user