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 -p -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 31 May 2017 16:48:42 -0000 @@ -34,10 +34,22 @@ along with GCC; see the file COPYING3. #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 @@ along with GCC; see the file COPYING3. %{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 -p -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 31 May 2017 16:48:42 -0000 @@ -113,6 +113,7 @@ int netbsd_elf_probe(struct lwp *, struc static void elf_free_emul_arg(void *); +#define DEBUG_ELF #ifdef DEBUG_ELF #define DPRINTF(a, ...) printf("%s: " a "\n", __func__, ##__VA_ARGS__) #else @@ -815,11 +816,12 @@ exec_elf_makecmds(struct lwp *l, struct interp = NULL; } else { epp->ep_entry = eh->e_entry; - if (epp->ep_flags & EXEC_FORCEAUX) { - ap = kmem_alloc(sizeof(*ap), KM_SLEEP); - ap->arg_interp = (vaddr_t)NULL; - } else + if (is_dyn || (epp->ep_flags & EXEC_FORCEAUX)) { + ap = kmem_zalloc(sizeof(*ap), KM_SLEEP); + ap->arg_interp = epp->ep_entryoffset; + } else { ap = NULL; + } } if (ap) { Index: usr.bin/crunch/crunchgen/crunchgen.1 =================================================================== RCS file: /cvsroot/src/usr.bin/crunch/crunchgen/crunchgen.1,v retrieving revision 1.32 diff -u -p -u -r1.32 crunchgen.1 --- usr.bin/crunch/crunchgen/crunchgen.1 18 Mar 2014 18:20:44 -0000 1.32 +++ usr.bin/crunch/crunchgen/crunchgen.1 31 May 2017 16:48:42 -0000 @@ -24,7 +24,7 @@ .\" Computer Science Department .\" University of Maryland at College Park .\" -.Dd June 10, 2013 +.Dd May 31, 2017 .Dt CRUNCHGEN 1 .Os .Sh NAME @@ -32,7 +32,7 @@ .Nd generates build environment for a crunched binary .Sh SYNOPSIS .Nm -.Op Fl fOoq +.Op Fl fOopq .Op Fl c Ar c-file-name .Op Fl D Ar src-root .Op Fl d Ar build-options @@ -124,6 +124,8 @@ the program objects into a single reloca Use existing object files. Rather than rebuilding object files via reach-over makefiles, instead search for and use existing object files. +.It Fl p +Produce static pie (position independent executables). .It Fl q Quiet operation. Status messages are suppressed. Index: usr.bin/crunch/crunchgen/crunchgen.c =================================================================== RCS file: /cvsroot/src/usr.bin/crunch/crunchgen/crunchgen.c,v retrieving revision 1.84 diff -u -p -u -r1.84 crunchgen.c --- usr.bin/crunch/crunchgen/crunchgen.c 29 May 2016 16:12:58 -0000 1.84 +++ usr.bin/crunch/crunchgen/crunchgen.c 31 May 2017 16:48:42 -0000 @@ -102,7 +102,7 @@ static int goterror = 0; static const char *pname = "crunchgen"; -static int verbose, readcache, useobjs, oneobj; /* options */ +static int verbose, readcache, useobjs, oneobj, pie; /* options */ static int reading_cache; static char *machine; static char *makeobjdirprefix; @@ -151,14 +151,16 @@ main(int argc, char **argv) readcache = 1; useobjs = 0; oneobj = 1; + pie = 0; *outmkname = *outcfname = *execfname = '\0'; if (argc > 0) pname = argv[0]; - while ((optc = getopt(argc, argv, "m:c:d:e:foqD:L:Ov:")) != -1) { + while ((optc = getopt(argc, argv, "m:c:d:e:fopqD:L:Ov:")) != -1) { switch(optc) { case 'f': readcache = 0; break; + case 'p': pie = 1; break; case 'q': verbose = 0; break; case 'O': oneobj = 0; break; case 'o': useobjs = 1, oneobj = 0; break; @@ -918,7 +920,8 @@ top_makefile_rules(FILE *outmk) { prog_t *p; - fprintf(outmk, "NOPIE=\n"); + if (!pie) + fprintf(outmk, "NOPIE=\n"); fprintf(outmk, "NOMAN=\n\n"); fprintf(outmk, "DBG=%s\n", dbg); @@ -948,7 +951,7 @@ top_makefile_rules(FILE *outmk) fprintf(outmk, " %s_make", p->ident); fprintf(outmk, "\n\n"); - fprintf(outmk, "LDSTATIC=-static\n\n"); + fprintf(outmk, "LDSTATIC=-static%s\n\n", pie ? " -pie" : ""); fprintf(outmk, "PROG=%s\n\n", execfname); fprintf(outmk, "all: ${PROG}.crunched\n"); Index: rescue/Makefile =================================================================== RCS file: /cvsroot/src/rescue/Makefile,v retrieving revision 1.32 diff -u -p -u -r1.32 Makefile --- rescue/Makefile 21 May 2017 15:28:41 -0000 1.32 +++ rescue/Makefile 31 May 2017 16:48:42 -0000 @@ -11,6 +11,11 @@ DBG+= -Os CRUNCHGEN_FLAGS=-d "${DBG}" +.if ${MKSTATICPIE:Uno} == "yes" +CRUNCHGEN_FLAGS+=-p +CFLAGS+=-fPIE +.endif + RESCUEDIR= /rescue CRUNCHBIN= rescue CRUNCHENV= RESCUEDIR=${RESCUEDIR} 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 31 May 2017 16:48:42 -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 +// #include +// #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 31 May 2017 16:48:42 -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 + +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 + movl %esp, %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 31 May 2017 16:48:42 -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 +// #include +// #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 31 May 2017 16:48:42 -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 + +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 -p -u -r1.32 Makefile.inc --- lib/csu/common/Makefile.inc 1 Jun 2016 21:24:55 -0000 1.32 +++ lib/csu/common/Makefile.inc 31 May 2017 16:48:42 -0000 @@ -13,6 +13,9 @@ CPPFLAGS+= -I${NETBSDSRCDIR}/libexec/ld. 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 @@ crt0.o: crt0.S crt0-common.c ${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 @@ gcrt0.o: crt0.S crt0-common.c ${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 @@ sysident_assym.h: ${GENASSYM_CONF} ${GEN ${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 31 May 2017 16:48:42 -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 +#include +#include +#include +#include +#include +#include +#include + +#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 +#include +#include +#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 -p -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 31 May 2017 16:48:42 -0000 @@ -150,6 +150,7 @@ ___start(void (*cleanup)(void), /* fro __progname = empty_string; } +#ifndef RCRT0 if (&rtld_DYNAMIC != NULL) { if (obj == NULL) _FATAL("NULL Obj_Entry pointer in GOT\n"); @@ -159,6 +160,7 @@ ___start(void (*cleanup)(void), /* fro _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 -p -u -r1.362 bsd.README --- share/mk/bsd.README 21 May 2017 15:28:42 -0000 1.362 +++ share/mk/bsd.README 31 May 2017 16:48:42 -0000 @@ -402,6 +402,10 @@ MKSTATICLIB If "no", don't build or inst 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 -p -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 31 May 2017 16:48:42 -0000 @@ -1028,6 +1028,12 @@ MKRELRO?= partial MKRELRO?= no .endif +.if ${MACHINE_ARCH} == "x86_64" +MKSTATICPIE?= yes +.else +MKSTATICPIE?= no +.endif + # # MK* options which default to "yes". #