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