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
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to