Hi,

I ported OpenBSD's static pie support to x86. Here's what it looks like.
I left some debugging stuff in the csu Makefile that needs cleanup?
Opinions? Should I add it?

Thanks,

christos

Index: external/gpl3/gcc/dist/gcc/config/netbsd-elf.h
===================================================================
RCS file: /cvsroot/src/external/gpl3/gcc/dist/gcc/config/netbsd-elf.h,v
retrieving revision 1.11
diff -u -u -r1.11 netbsd-elf.h
--- external/gpl3/gcc/dist/gcc/config/netbsd-elf.h      21 Oct 2016 07:24:30 
-0000      1.11
+++ external/gpl3/gcc/dist/gcc/config/netbsd-elf.h      30 May 2017 21:35:18 
-0000
@@ -34,10 +34,22 @@
 
 #define NETBSD_STARTFILE_SPEC  \
   "%{!shared:                  \
-     %{pg:gcrt0%O%s}           \
+     %{pg:                     \
+       %{pie:                  \
+        %{static:mcrt0%O%s}    \
+        %{!static:gcrt0%O%s}}  \
+       %{!pie:gcrt0%O%s}}      \
      %{!pg:                    \
-       %{p:gcrt0%O%s}          \
-       %{!p:crt0%O%s}}}                \
+       %{p:                    \
+        %{pie                  \
+          %{static:mcrt0%O%s}  \
+          %{!static:gcrt0%O%s}}\
+        %{!pie:gcrt0%O%s}}     \
+       %{!p:                   \
+        %{pie:                 \
+          %{static:rcrt0%O%s}  \
+          %{!static:crt0%O%s}} \
+        %{!pie:crt0%O%s}}}}    \
    %:if-exists(crti%O%s)       \
    %{static:%:if-exists-else(crtbeginT%O%s crtbegin%O%s)} \
    %{!static:                   \
@@ -89,7 +101,7 @@
        %{rdynamic:-export-dynamic} \
        %(netbsd_link_ld_elf_so)} \
      %{static:-static \
-       %{pie: %(netbsd_link_ld_elf_so)}}} \
+       %{pie: -no-dynamic-linker}}} \
    %{!nostdlib:%{!nodefaultlibs:\
      %{%:sanitize(address): -lasan } \
      %{%:sanitize(undefined): -lubsan}}}"
Index: sys/kern/exec_elf.c
===================================================================
RCS file: /cvsroot/src/sys/kern/exec_elf.c,v
retrieving revision 1.90
diff -u -u -r1.90 exec_elf.c
--- sys/kern/exec_elf.c 21 Apr 2017 13:17:42 -0000      1.90
+++ sys/kern/exec_elf.c 30 May 2017 21:35:18 -0000
@@ -815,9 +815,9 @@
                interp = NULL;
        } else {
                epp->ep_entry = eh->e_entry;
-               if (epp->ep_flags & EXEC_FORCEAUX) {
+               if (is_dyn || epp->ep_flags & EXEC_FORCEAUX) {
                        ap = kmem_alloc(sizeof(*ap), KM_SLEEP);
-                       ap->arg_interp = (vaddr_t)NULL;
+                       ap->arg_interp = epp->ep_entryoffset;
                } else
                        ap = NULL;
        }
Index: lib/csu/arch/i386/archdep.h
===================================================================
RCS file: lib/csu/arch/i386/archdep.h
diff -N lib/csu/arch/i386/archdep.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/csu/arch/i386/archdep.h 30 May 2017 21:35:18 -0000
@@ -0,0 +1,59 @@
+/*     $OpenBSD: archdep.h,v 1.19 2017/01/24 07:48:37 guenther Exp $ */
+
+/*
+ * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef _I386_ARCHDEP_H_
+#define _I386_ARCHDEP_H_
+
+#define        RELOC_TAG       DT_REL
+
+#define        MACHID  EM_386          /* ELF e_machine ID value checked */
+
+// #include <elf_abi.h>
+// #include <machine/reloc.h>
+// #include "syscall.h"
+// #include "util.h"
+
+
+static inline void
+RELOC_DYN(Elf32_Rel *r, const Elf32_Sym *s, Elf32_Addr *p, unsigned long v)
+{
+
+       if (ELF32_R_TYPE(r->r_info) == R_386_RELATIVE) {
+               *p += v;
+       } else if (ELF32_R_TYPE(r->r_info) == R_386_GLOB_DAT) {
+               *p += v + s->st_value;
+       } else if (ELF32_R_TYPE(r->r_info) == R_386_32) {
+               *p += v + s->st_value;
+       } else {
+               _dl_exit(6);
+       }
+}
+
+#define RELOC_GOT(obj, offs)
+
+#endif /* _I386_ARCHDEP_H_ */
Index: lib/csu/arch/i386/rcrt0.S
===================================================================
RCS file: lib/csu/arch/i386/rcrt0.S
diff -N lib/csu/arch/i386/rcrt0.S
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/csu/arch/i386/rcrt0.S   30 May 2017 21:35:18 -0000
@@ -0,0 +1,64 @@
+/*     $NetBSD$        */
+
+/*-
+ * Copyright (c) 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD$")
+
+STRONG_ALIAS(_start,__start)
+.hidden ___start
+
+_ENTRY(__start)
+       movl    %esp, %eax              # save SP
+       # Push the arguments for ___start now...
+       pushl   %ebx                    # push __ps_strings
+       pushl   %ecx                    # push Obj_Entry
+       pushl   %edx                    # push cleanup
+       subl    $(17 * 4), %esp         # space for dl_data + _DYNAMIC
+       call    1f
+1:     addl    $(_DYNAMIC-1b), (%esp)  # save &_DYNAMIC
+       movl    %esp, %ebx
+       addl    $4, %ebx                # leave space for &_DYNAMIC
+       pushl   %ebx                    # push dl_data for dl_boot_bind
+       pushl   %eax                    # push saved SP for dl_boot_bind
+
+       call    _dl_boot_bind@PLT       # _dl_boot_bind(sp, dl_data, &_DYNAMIC)
+       addl    $(20 * 4), %esp         # pop args plus space for dl_data
+       xorl    %ebp, %ebp
+       call    ___start                # ___start(cleanup, obj, __ps_strings)
+
+_ENTRY(_dl_exit)
+       mov     $1, %eax
+       int     $0x80
+       ret
Index: lib/csu/arch/x86_64/archdep.h
===================================================================
RCS file: lib/csu/arch/x86_64/archdep.h
diff -N lib/csu/arch/x86_64/archdep.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/csu/arch/x86_64/archdep.h       30 May 2017 21:35:18 -0000
@@ -0,0 +1,58 @@
+/*     $OpenBSD: archdep.h,v 1.11 2017/01/21 01:15:00 guenther Exp $   */
+
+/*
+ * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef _X86_64_ARCHDEP_H_
+#define _X86_64_ARCHDEP_H_
+
+#define        RELOC_TAG       DT_RELA
+
+#define        MACHID  EM_AMD64        /* ELF e_machine ID value checked */
+
+// #include <elf_abi.h>
+// #include <machine/reloc.h>
+// #include "syscall.h"
+// #include "util.h"
+
+
+static inline void
+RELOC_DYN(Elf64_Rela *r, const Elf64_Sym *s, Elf64_Addr *p, unsigned long v)
+{
+       if (ELF64_R_TYPE(r->r_info) == R_X86_64_RELATIVE) {
+               *p = v + r->r_addend;
+       } else if (ELF64_R_TYPE(r->r_info) == R_X86_64_GLOB_DAT) {
+               *p = v + s->st_value + r->r_addend;
+       } else if (ELF64_R_TYPE(r->r_info) == R_X86_64_64) {
+               *p = v + s->st_value + r->r_addend;
+       } else {
+               _dl_exit(6);
+       }
+}
+
+#define RELOC_GOT(obj, offs)
+
+#endif /* _X86_64_ARCHDEP_H_ */
Index: lib/csu/arch/x86_64/rcrt0.S
===================================================================
RCS file: lib/csu/arch/x86_64/rcrt0.S
diff -N lib/csu/arch/x86_64/rcrt0.S
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/csu/arch/x86_64/rcrt0.S 30 May 2017 21:35:18 -0000
@@ -0,0 +1,69 @@
+/*     $NetBSD$        */
+
+/*-
+ * Copyright (c) 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD$")
+
+STRONG_ALIAS(_start,__start)
+.hidden ___start
+
+_ENTRY(__start)
+       movq    %rsp, %r12              # save SP
+       subq    $8, %rsp
+       andq    $~15, %rsp
+       addq    $8, %rsp                # align
+       subq    $(16 * 8), %rsp         # space for 16 aux entries (dl_data)
+       leaq    _DYNAMIC(%rip), %rdx    # a2 = &_DYNAMIC
+       movq    %rsp, %rsi              # a1 = dl_data
+       movq    %r12, %rdi              # a0 = sp
+       call    _dl_boot_bind@PLT       # _dl_boot_bind(sp, dl_data, &_DYNAMIC)
+       movq    %r12, %rsp              # restore SP
+       movq    %rbx, %rdx              # a2 = __ps_strings
+       xorq    %rsi, %rsi              # a1 = Obj_Entry = NULL
+       leaq    16(%rsp,%rdi,8), %rdi   # a0 = cleanup
+       subq    $8,%rsp
+       andq    $~15,%rsp
+       addq    $8,%rsp                 # align
+       jmp     ___start
+
+_ENTRY(_dl_exit)
+       movl    $1, %eax
+       movq    %rcx, %r10
+       syscall
+       jb      1f
+       ret
+1:
+       neg     %rax
+       ret
Index: lib/csu/common/Makefile.inc
===================================================================
RCS file: /cvsroot/src/lib/csu/common/Makefile.inc,v
retrieving revision 1.32
diff -u -u -r1.32 Makefile.inc
--- lib/csu/common/Makefile.inc 1 Jun 2016 21:24:55 -0000       1.32
+++ lib/csu/common/Makefile.inc 30 May 2017 21:35:18 -0000
@@ -13,6 +13,9 @@
 OBJS+=         crt0.o gcrt0.o crti.o crtn.o
 OBJS+=         crtbegin.o crtend.o
 OBJS+=         sysident.o
+.if ${MKSTATICPIE} == "yes"
+OBJS+=         rcrt0.o mcrt0.o
+.endif
 
 .if ${MKPIC} == "yes"
 OBJS+=         crtbeginS.o
@@ -91,6 +94,21 @@
        ${OBJCOPY} -R .ident ${.TARGET}
 .endif
 
+boot.o: boot.c
+       ${COMPILE.c:S/-O2//} ${CFLAGS.boot.c:S/-O//} -I${ARCHDIR} -g3 
${MY_PICFLAGS} -DRCRT0 ${COMMON_DIR}/boot.c -o ${.TARGET}
+
+rcrt0.o: rcrt0.S crt0-common.c boot.o
+       ${_MKTARGET_COMPILE}
+       ${COMPILE.S} ${ARCHDIR}/rcrt0.S -o ${.TARGET}.S.o
+       ${COMPILE.c} ${CFLAGS.crt0-common.c} ${MY_PICFLAGS} -DRCRT0 
${COMMON_DIR}/crt0-common.c -o ${.TARGET}.c.o
+       ${LD} -r -o ${.TARGET}.o ${.TARGET}.S.o ${.TARGET}.c.o boot.o
+#      ${OBJCOPY} ${OBJCOPYLIBFLAGS} ${.TARGET}.o ${.TARGET} 
+       cp ${.TARGET}.o ${.TARGET}
+       rm -f ${.TARGET}.S.o ${.TARGET}.c.o ${.TARGET}.o
+.if ${MKSTRIPIDENT} != "no"
+       ${OBJCOPY} -R .ident ${.TARGET}
+.endif
+
 gcrt0.o: crt0.S crt0-common.c
        ${_MKTARGET_COMPILE}
        ${COMPILE.S} ${ARCHDIR}/crt0.S -o ${.TARGET}.S.o
@@ -102,6 +120,18 @@
        ${OBJCOPY} -R .ident ${.TARGET}
 .endif
 
+mcrt0.o: crt0.S crt0-common.c boot.o
+       ${_MKTARGET_COMPILE}
+       ${COMPILE.S} ${ARCHDIR}/rcrt0.S -o ${.TARGET}.S.o
+       ${COMPILE.c} ${MY_PICFLAGS} -DRCRT0 -DMCRT0 ${COMMON_DIR}/crt0-common.c 
-o ${.TARGET}.c.o
+       ${LD} -r -o ${.TARGET}.o ${.TARGET}.S.o ${.TARGET}.c.o boot.o
+#      ${OBJCOPY} ${OBJCOPYLIBFLAGS} ${.TARGET}.o ${.TARGET} 
+       cp ${.TARGET}.o ${.TARGET}
+       rm -f ${.TARGET}.S.o ${.TARGET}.c.o ${.TARGET}.o
+.if ${MKSTRIPIDENT} != "no"
+#      ${OBJCOPY} -R .ident ${.TARGET}
+.endif
+
 .if ${MACHINE_ARCH} == "alpha"
 # can't do this in Makefile.inc otherwise it will before realall:
 crtfm.o: crtfm.c
@@ -119,7 +149,7 @@
            ${GENASSYM_CPPFLAGS} > sysident_assym.h.tmp && \
        mv -f sysident_assym.h.tmp sysident_assym.h
 
-CLEANFILES+=   sysident_assym.h
+CLEANFILES+=   sysident_assym.h boot.o
 
 crti.o: crti.S sysident_assym.h sysident.S
 crtn.o: crtn.S
Index: lib/csu/common/boot.c
===================================================================
RCS file: lib/csu/common/boot.c
diff -N lib/csu/common/boot.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/csu/common/boot.c       30 May 2017 21:35:18 -0000
@@ -0,0 +1,287 @@
+/*     $OpenBSD: boot.h,v 1.28 2017/01/29 22:31:09 chl Exp $ */
+
+/*
+ * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+/*
+ * IMPORTANT: any functions below are NOT protected by SSP.  Please
+ * do not add anything except what is required to reach GOT with
+ * an adjustment.
+ */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/exec.h>
+#include <sys/sysctl.h>
+#include <sys/syscall.h>
+#include <nlist.h>
+#include <link.h>
+#include <dlfcn.h>
+
+#ifdef __NetBSD__
+extern void _dl_exit(int);
+#define _dl_memset memset
+#define au_id a_type
+#define au_v a_v
+#define AUX_entry 15 /* ELF_AUX_ENTRIES */
+#define AUX_null AT_NULL
+#define AUX_phdr AT_PHDR
+#define AUX_base AT_BASE
+#define AUX_phnum AT_PHNUM
+#define Elf_RelA Elf_Rela
+#define mprotect(addr, len, prot) __syscall(SYS_mprotect, (addr), (len), 
(prot))
+
+#include <string.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include "archdep.h"
+#endif
+
+#ifdef __OpenBSD__
+#include "syscall.h"
+#include "archdep.h"
+#include "path.h"
+#include "resolve.h"
+#include "sod.h"
+#include "stdlib.h"
+
+/*
+ * Use the internal, hidden name for any syscalls we need, to avoid
+ * accidental override by application code
+ */
+#define REDIRECT_SYSCALL(x)    typeof(x) x asm("_libc_"#x) __dso_hidden
+REDIRECT_SYSCALL(mprotect);
+#endif
+
+
+#ifdef RCRT0
+
+#define        DT_PROC(n)      ((n) - DT_LOPROC)
+
+#if RELOC_TAG == DT_RELA
+typedef        Elf_RelA        RELOC_TYPE;
+#elif RELOC_TAG == DT_REL
+typedef        Elf_Rel         RELOC_TYPE;
+#else
+# error "unknown RELOC_TAG"
+#endif
+
+/* The set of dynamic tags that we're interested in for bootstrapping */
+struct boot_dyn {
+       RELOC_TYPE      *dt_reloc;      /* DT_RELA   or DT_REL */
+       Elf_Addr        dt_relocsz;     /* DT_RELASZ or DT_RELSZ */
+       Elf_Addr        *dt_pltgot;
+       Elf_Addr        dt_pltrelsz;
+       const Elf_Sym   *dt_symtab;
+       RELOC_TYPE      *dt_jmprel;
+#if DT_PROCNUM > 0
+       u_long          dt_proc[DT_PROCNUM];
+#endif
+};
+
+/*
+ * Local decls.
+ */
+void _dl_boot_bind(const long, long *, Elf_Dyn *);
+
+void
+_dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
+{
+       struct boot_dyn dynld;          /* Resolver data for the loader */
+       AuxInfo         *auxstack;
+       long            *stack;
+       Elf_Dyn         *dynp;
+       int             n, argc;
+       char            **argv, **envp;
+       long            loff;
+       RELOC_TYPE      *rp;
+       Elf_Phdr        *phdp;
+       Elf_Addr        i;
+
+       /*
+        * Scan argument and environment vectors. Find dynamic
+        * data vector put after them.
+        */
+       stack = (long *)sp;
+       argc = *stack++;
+       argv = (char **)stack;
+       envp = &argv[argc + 1];
+       stack = (long *)envp;
+       while (*stack++ != 0L)
+               continue;
+
+       /*
+        * Zero out dl_data.
+        */
+       for (n = 0; n <= AUX_entry; n++)
+               dl_data[n] = 0;
+
+       /*
+        * Dig out auxiliary data set up by exec call. Move all known
+        * tags to an indexed local table for easy access.
+        */
+       for (auxstack = (AuxInfo *)stack; auxstack->au_id != AUX_null;
+           auxstack++) {
+               if (auxstack->au_id > AUX_entry)
+                       continue;
+               dl_data[auxstack->au_id] = auxstack->au_v;
+       }
+       loff = dl_data[AUX_base];       /* XXX assumes ld.so is linked at 0x0 */
+
+       /*
+        * We need to do 'selfreloc' in case the code weren't
+        * loaded at the address it was linked to.
+        *
+        * Scan the DYNAMIC section for the loader.
+        * Cache the data for easier access.
+        */
+       dynp = dynamicp;
+
+       _dl_memset(&dynld, 0, sizeof(dynld));
+       while (dynp->d_tag != DT_NULL) {
+               /* first the tags that are pointers to be relocated */
+               if (dynp->d_tag == DT_PLTGOT)
+                       dynld.dt_pltgot = (void *)(dynp->d_un.d_ptr + loff);
+               else if (dynp->d_tag == DT_SYMTAB)
+                       dynld.dt_symtab = (void *)(dynp->d_un.d_ptr + loff);
+               else if (dynp->d_tag == RELOC_TAG)      /* DT_{RELA,REL} */
+                       dynld.dt_reloc = (void *)(dynp->d_un.d_ptr + loff);
+               else if (dynp->d_tag == DT_JMPREL)
+                       dynld.dt_jmprel = (void *)(dynp->d_un.d_ptr + loff);
+
+               /* Now for the tags that are just sizes or counts */
+               else if (dynp->d_tag == DT_PLTRELSZ)
+                       dynld.dt_pltrelsz = dynp->d_un.d_val;
+               else if (dynp->d_tag == RELOC_TAG+1)    /* DT_{RELA,REL}SZ */
+                       dynld.dt_relocsz = dynp->d_un.d_val;
+#if DT_PROCNUM > 0
+               else if (dynp->d_tag >= DT_LOPROC &&
+                   dynp->d_tag < DT_LOPROC + DT_PROCNUM)
+                       dynld.dt_proc[dynp->d_tag - DT_LOPROC] =
+                           dynp->d_un.d_val;
+#endif /* DT_PROCNUM */
+               dynp++;
+       }
+
+       rp = dynld.dt_jmprel;
+       for (i = 0; i < dynld.dt_pltrelsz; i += sizeof *rp) {
+               const Elf_Sym *sym;
+
+               sym = dynld.dt_symtab + ELF_R_SYM(rp->r_info);
+               if (!ELF_R_SYM(rp->r_info) || sym->st_value != 0) {
+#ifdef HAVE_JMPREL
+                       Elf_Addr *ra = (Elf_Addr *)(rp->r_offset + loff);
+                       RELOC_JMPREL(rp, sym, ra, loff, dynld.dt_pltgot);
+#else
+                       _dl_exit(6);
+#endif
+               }
+               rp++;
+       }
+
+       rp = dynld.dt_reloc;
+       for (i = 0; i < dynld.dt_relocsz; i += sizeof *rp) {
+               Elf_Addr *ra;
+               const Elf_Sym *sym;
+
+               sym = dynld.dt_symtab + ELF_R_SYM(rp->r_info);
+               if (!ELF_R_SYM(rp->r_info) || sym->st_value != 0) {
+                       ra = (Elf_Addr *)(rp->r_offset + loff);
+                       RELOC_DYN(rp, sym, ra, loff);
+               }
+               rp++;
+       }
+
+       RELOC_GOT(&dynld, loff);
+
+       /*
+        * we have been fully relocated here, so most things no longer
+        * need the loff adjustment
+        */
+
+       /*
+        * No further changes to the PLT and/or GOT are needed so make
+        * them read-only.
+        */
+
+       /* do any RWX -> RX fixups for executable PLTs and apply GNU_RELRO */
+       phdp = (Elf_Phdr *)dl_data[AUX_phdr];
+       for (i = 0; i < (Elf_Addr)dl_data[AUX_phnum]; i++, phdp++) {
+               switch (phdp->p_type) {
+#if defined(__alpha__) || defined(__hppa__) || defined(__powerpc__) || \
+    defined(__sparc64__)
+               case PT_LOAD:
+                       if ((phdp->p_flags & (PF_X | PF_W)) != (PF_X | PF_W))
+                               break;
+                       mprotect((void *)(phdp->p_vaddr + loff), phdp->p_memsz,
+                           PROT_READ);
+                       break;
+#endif
+               case PT_GNU_RELRO:
+                       mprotect((void *)(phdp->p_vaddr + loff), phdp->p_memsz,
+                           PROT_READ);
+                       /*
+                        * GNU_RELRO (a) covers the GOT, and (b) comes after
+                        * all LOAD sections, so if we found it then we're done
+                        */
+                       break;
+               }
+       }
+}
+
+#ifdef __alpha__
+
+void   _reloc_alpha_got(Elf_Dyn *dynp, Elf_Addr relocbase);
+
+void
+_reloc_alpha_got(Elf_Dyn *dynp, Elf_Addr relocbase)
+{
+       const Elf_RelA *rela = 0, *relalim;
+       Elf_Addr relasz = 0;
+       Elf_Addr *where;
+
+       for (; dynp->d_tag != DT_NULL; dynp++) {
+               switch (dynp->d_tag) {
+               case DT_RELA:
+                       rela = (const Elf_RelA *)(relocbase + dynp->d_un.d_ptr);
+                       break;
+               case DT_RELASZ:
+                       relasz = dynp->d_un.d_val;
+                       break;
+               }
+       }
+       relalim = (const Elf_RelA *)((caddr_t)rela + relasz);
+       for (; rela < relalim; rela++) {
+               if (ELF64_R_TYPE(rela->r_info) != RELOC_RELATIVE)
+                       continue;
+               where = (Elf_Addr *)(relocbase + rela->r_offset);
+               *where += (Elf_Addr)relocbase;
+       }
+}
+
+#endif
+
+#endif /* RCRT0 */
Index: lib/csu/common/crt0-common.c
===================================================================
RCS file: /cvsroot/src/lib/csu/common/crt0-common.c,v
retrieving revision 1.14
diff -u -u -r1.14 crt0-common.c
--- lib/csu/common/crt0-common.c        7 Jun 2016 12:07:35 -0000       1.14
+++ lib/csu/common/crt0-common.c        30 May 2017 21:35:18 -0000
@@ -150,6 +150,7 @@
                __progname = empty_string;
        }
 
+#ifndef RCRT0
        if (&rtld_DYNAMIC != NULL) {
                if (obj == NULL)
                        _FATAL("NULL Obj_Entry pointer in GOT\n");
@@ -159,6 +160,7 @@
                        _FATAL("Dynamic linker version mismatch\n");
                atexit(cleanup);
        }
+#endif
 
        _libc_init();
 
Index: share/mk/bsd.README
===================================================================
RCS file: /cvsroot/src/share/mk/bsd.README,v
retrieving revision 1.362
diff -u -u -r1.362 bsd.README
--- share/mk/bsd.README 21 May 2017 15:28:42 -0000      1.362
+++ share/mk/bsd.README 30 May 2017 21:35:18 -0000
@@ -402,6 +402,10 @@
                libraries.
                Default: yes
 
+MKSTATICPIE    Compile in support for static pie binaries. These binaries
+               use a special rcrt0.o/mcrt0.o that do the necessary relocations
+               Default: yes on platforms that support it.
+
 MKSTRIPSYM     If "yes", strip all local symbols from shared libraries;
                the affect is equivalent to -x option of ld(1). If "no",
                strip only temporary local symbols; the affect is equivalent
Index: share/mk/bsd.own.mk
===================================================================
RCS file: /cvsroot/src/share/mk/bsd.own.mk,v
retrieving revision 1.1009
diff -u -u -r1.1009 bsd.own.mk
--- share/mk/bsd.own.mk 21 May 2017 15:28:42 -0000      1.1009
+++ share/mk/bsd.own.mk 30 May 2017 21:35:18 -0000
@@ -1028,6 +1028,13 @@
 MKRELRO?=      no
 .endif
 
+.if ${MACHINE_ARCH} == "i386" || \
+    ${MACHINE_ARCH} == "x86_64"
+MKSTATICPIE?=  yes
+.else
+MKSTATICPIE?=  no
+.endif
+
 #
 # MK* options which default to "yes".
 #

Reply via email to