Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 May 2020 19:19:40 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r360793 - in stable/12/sys: conf riscv/riscv
Message-ID:  <202005071919.047JJeRu020230@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Thu May  7 19:19:39 2020
New Revision: 360793
URL: https://svnweb.freebsd.org/changeset/base/360793

Log:
  MFC 356481:
  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.
  
  Note that the followup fix for SMP (r356675) was previously merged to
  stable/12.

Modified:
  stable/12/sys/conf/kern.pre.mk
  stable/12/sys/riscv/riscv/locore.S
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/conf/kern.pre.mk
==============================================================================
--- stable/12/sys/conf/kern.pre.mk	Thu May  7 18:47:54 2020	(r360792)
+++ stable/12/sys/conf/kern.pre.mk	Thu May  7 19:19:39 2020	(r360793)
@@ -143,6 +143,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: stable/12/sys/riscv/riscv/locore.S
==============================================================================
--- stable/12/sys/riscv/riscv/locore.S	Thu May  7 18:47:54 2020	(r360792)
+++ stable/12/sys/riscv/riscv/locore.S	Thu May  7 19:19:39 2020	(r360793)
@@ -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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202005071919.047JJeRu020230>