Revise kernel's ld.script on octeon
authorvisa <visa@openbsd.org>
Sat, 6 Feb 2021 09:31:47 +0000 (09:31 +0000)
committervisa <visa@openbsd.org>
Sat, 6 Feb 2021 09:31:47 +0000 (09:31 +0000)
This allows more control over the structure of the linked kernel image.
Now the ELF .openbsd.randomdata segment can be omitted from BOOT kernel.
The segment has caused trouble with broken firmware when the firmware
tries to load it on top of the actual kernel segment.

Discussed with and OK deraadt@

sys/arch/octeon/conf/BOOT
sys/arch/octeon/conf/Makefile.octeon
sys/arch/octeon/conf/ld.script

index fb1a6af..f27d126 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: BOOT,v 1.9 2020/10/10 10:11:54 visa Exp $
+#      $OpenBSD: BOOT,v 1.10 2021/02/06 09:31:47 visa Exp $
 
 machine                octeon mips64
 maxusers       4
@@ -7,6 +7,7 @@ option          BOOT_QUIET
 
 option         SMALL_KERNEL
 option         NO_PROPOLICE
+option         NO_RANDOMIZE
 
 option         RAMDISK_HOOKS
 option         MINIROOTSIZE=2048
index 4545885..42ccce9 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile.octeon,v 1.57 2021/01/28 17:39:03 deraadt Exp $
+#      $OpenBSD: Makefile.octeon,v 1.58 2021/02/06 09:31:47 visa Exp $
 
 # For instructions on building kernels consult the config(8) and options(4)
 # manual pages.
@@ -124,7 +124,18 @@ ioconf.o: ioconf.c
        ${NORMAL_C}
 
 ld.script: ${_machdir}/conf/ld.script
+.if ${IDENT:M-DNO_RANDOMIZE}
+       # Some broken firmware try to load ELF .openbsd.randomdata segment.
+       # This fails because the segment overlaps with the actual kernel
+       # ELF LOAD segment, and the firmware cannot allocate the memory region
+       # as it is already in use. Avoid this by omitting PT_OPENBSD_RANDOMIZE.
+       sed -e '/PT_OPENBSD_RANDOMIZE/d' \
+           -e 's/ :openbsd_randomize//' \
+           ${_machdir}/conf/ld.script > $@.tmp
+       mv $@.tmp $@
+.else
        cp ${_machdir}/conf/ld.script $@
+.endif
 
 gapdummy.o:
        echo '__asm(".section .rodata,\"a\"");' > gapdummy.c
index 95b7954..9fe8c66 100644 (file)
@@ -1,32 +1,63 @@
-/*     $OpenBSD: ld.script,v 1.5 2019/11/09 20:07:00 guenther Exp $    */
+/*     $OpenBSD: ld.script,v 1.6 2021/02/06 09:31:47 visa Exp $        */
 
 OUTPUT_FORMAT("elf64-tradbigmips")
 OUTPUT_ARCH(mips)
 ENTRY(__start)
 
+/*
+ * When the kernel is built with option NO_RANDOMIZE, PT_OPENBSD_RANDOMIZE
+ * and :openbsd_randomize are removed by the Makefile.
+ */
+
+PHDRS
+{
+       text PT_LOAD;
+       openbsd_randomize PT_OPENBSD_RANDOMIZE;
+}
+
 SECTIONS
 {
-       .text :         { *(.text .text.* .gnu.linkonce.t.*) }
+       .text :
+       {
+               *(.text .text.* .gnu.linkonce.t.*)
+       } :text
        PROVIDE (etext = .);
-       .rodata :       { *(.rodata .rodata.* .gnu.linkonce.r.*) }
-       _gp = ALIGN(16) + 0x7ff0;
-       .data :         { *(.data .data.* .gnu.linkonce.d.*) }
-       __kernel_randomdata = .;
+       .rodata :
+       {
+               *(.rodata .rodata.* .gnu.linkonce.r.*)
+       } :text
+
+       . = ALIGN(8);
+       PROVIDE (__kernel_randomdata = .);
        .openbsd.randomdata :
        {
-               /* XXX shouldn't this be placed next to rodata? */
                __retguard_start = ABSOLUTE(.);
                *(.openbsd.randomdata.retguard .openbsd.randomdata.retguard.*)
                /* XXX . = ALIGN(0x1000); */
                __retguard_end = ABSOLUTE(.);
                *(.openbsd.randomdata .openbsd.randomdata.*)
-       }
-       __kernel_randomdata_end = .;
+       } :text :openbsd_randomize
+       . = ALIGN(8);
+       PROVIDE (__kernel_randomdata_end = .);
+
+       _gp = ALIGN(16) + 0x7ff0;
+       .data :
+       {
+               *(.data .data.* .gnu.linkonce.d.*)
+       } :text
        PROVIDE (edata = .);
-       .sbss :         { *(.sbss .sbss.* .gnu.linkonce.sb.* .scommon) }
-       .bss :          { *(.bss .bss.* .gnu.linkonce.b.* COMMON) }
+       .sbss :
+       {
+               *(.sbss .sbss.* .gnu.linkonce.sb.* .scommon)
+       }
+       .bss :
+       {
+               *(.bss .bss.* .gnu.linkonce.b.* COMMON)
+       }
+       . = ALIGN(8);
        PROVIDE (_end = .);
        PROVIDE (end = .);
+
        /DISCARD/ :
        {
                *(.pdr)