tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

static pie support for x86 (from OpenBSD)



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".
 #


Home | Main Index | Thread Index | Old Index