1033f58dfSPeter Wemm /*- 2033f58dfSPeter Wemm * Copyright 1996-1998 John D. Polstra. 3033f58dfSPeter Wemm * All rights reserved. 4033f58dfSPeter Wemm * 5033f58dfSPeter Wemm * Redistribution and use in source and binary forms, with or without 6033f58dfSPeter Wemm * modification, are permitted provided that the following conditions 7033f58dfSPeter Wemm * are met: 8033f58dfSPeter Wemm * 1. Redistributions of source code must retain the above copyright 9033f58dfSPeter Wemm * notice, this list of conditions and the following disclaimer. 10033f58dfSPeter Wemm * 2. Redistributions in binary form must reproduce the above copyright 11033f58dfSPeter Wemm * notice, this list of conditions and the following disclaimer in the 12033f58dfSPeter Wemm * documentation and/or other materials provided with the distribution. 13033f58dfSPeter Wemm * 14033f58dfSPeter Wemm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15033f58dfSPeter Wemm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16033f58dfSPeter Wemm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17033f58dfSPeter Wemm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18033f58dfSPeter Wemm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19033f58dfSPeter Wemm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20033f58dfSPeter Wemm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21033f58dfSPeter Wemm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22033f58dfSPeter Wemm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23033f58dfSPeter Wemm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24033f58dfSPeter Wemm * 25033f58dfSPeter Wemm */ 26033f58dfSPeter Wemm 279676a785SDavid E. O'Brien #include <sys/cdefs.h> 289676a785SDavid E. O'Brien __FBSDID("$FreeBSD$"); 299676a785SDavid E. O'Brien 30033f58dfSPeter Wemm #include <sys/param.h> 313ebc1248SPeter Wemm #include <sys/kernel.h> 32033f58dfSPeter Wemm #include <sys/systm.h> 33f36ba452SJake Burkholder #include <sys/exec.h> 34f36ba452SJake Burkholder #include <sys/imgact.h> 35033f58dfSPeter Wemm #include <sys/linker.h> 363ebc1248SPeter Wemm #include <sys/sysent.h> 373ebc1248SPeter Wemm #include <sys/imgact_elf.h> 383ebc1248SPeter Wemm #include <sys/syscall.h> 393ebc1248SPeter Wemm #include <sys/signalvar.h> 403ebc1248SPeter Wemm #include <sys/vnode.h> 41f36ba452SJake Burkholder 42f36ba452SJake Burkholder #include <vm/vm.h> 43f36ba452SJake Burkholder #include <vm/pmap.h> 44f36ba452SJake Burkholder #include <vm/vm_param.h> 45f36ba452SJake Burkholder 46033f58dfSPeter Wemm #include <machine/elf.h> 473ebc1248SPeter Wemm #include <machine/md_var.h> 483ebc1248SPeter Wemm 493ebc1248SPeter Wemm struct sysentvec elf32_freebsd_sysvec = { 503ebc1248SPeter Wemm SYS_MAXSYSCALL, 513ebc1248SPeter Wemm sysent, 523ebc1248SPeter Wemm 0, 533ebc1248SPeter Wemm 0, 54f36ba452SJake Burkholder NULL, 553ebc1248SPeter Wemm 0, 56f36ba452SJake Burkholder NULL, 57f36ba452SJake Burkholder NULL, 58f36ba452SJake Burkholder __elfN(freebsd_fixup), 593ebc1248SPeter Wemm sendsig, 603ebc1248SPeter Wemm sigcode, 613ebc1248SPeter Wemm &szsigcode, 62f36ba452SJake Burkholder NULL, 633ebc1248SPeter Wemm "FreeBSD ELF32", 643ebc1248SPeter Wemm __elfN(coredump), 653ebc1248SPeter Wemm NULL, 66f36ba452SJake Burkholder MINSIGSTKSZ, 67f36ba452SJake Burkholder PAGE_SIZE, 68f36ba452SJake Burkholder VM_MIN_ADDRESS, 69f36ba452SJake Burkholder VM_MAXUSER_ADDRESS, 70f36ba452SJake Burkholder USRSTACK, 71f36ba452SJake Burkholder PS_STRINGS, 72f36ba452SJake Burkholder VM_PROT_ALL, 73f36ba452SJake Burkholder exec_copyout_strings, 74f36ba452SJake Burkholder exec_setregs 753ebc1248SPeter Wemm }; 763ebc1248SPeter Wemm 773ebc1248SPeter Wemm static Elf32_Brandinfo freebsd_brand_info = { 783ebc1248SPeter Wemm ELFOSABI_FREEBSD, 793ebc1248SPeter Wemm EM_386, 803ebc1248SPeter Wemm "FreeBSD", 813ebc1248SPeter Wemm "", 823ebc1248SPeter Wemm "/usr/libexec/ld-elf.so.1", 833ebc1248SPeter Wemm &elf32_freebsd_sysvec 843ebc1248SPeter Wemm }; 853ebc1248SPeter Wemm 863ebc1248SPeter Wemm SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY, 873ebc1248SPeter Wemm (sysinit_cfunc_t) elf32_insert_brand_entry, 883ebc1248SPeter Wemm &freebsd_brand_info); 89033f58dfSPeter Wemm 90bde362f5SPeter Wemm /* Process one elf relocation with addend. */ 917251b4bfSJake Burkholder static int 927251b4bfSJake Burkholder elf_reloc_internal(linker_file_t lf, const void *data, int type, int local) 93033f58dfSPeter Wemm { 94033f58dfSPeter Wemm Elf_Addr relocbase = (Elf_Addr) lf->address; 95aa855a59SPeter Wemm Elf_Addr *where; 96f1d19042SArchie Cobbs Elf_Addr addr; 97aa855a59SPeter Wemm Elf_Addr addend; 98d297ad16SMarcel Moolenaar Elf_Word rtype, symidx; 99aa855a59SPeter Wemm const Elf_Rel *rel; 100aa855a59SPeter Wemm const Elf_Rela *rela; 101033f58dfSPeter Wemm 102aa855a59SPeter Wemm switch (type) { 103aa855a59SPeter Wemm case ELF_RELOC_REL: 1040a5e03ddSMatthew Dillon rel = (const Elf_Rel *)data; 105aa855a59SPeter Wemm where = (Elf_Addr *) (relocbase + rel->r_offset); 106aa855a59SPeter Wemm addend = *where; 107aa855a59SPeter Wemm rtype = ELF_R_TYPE(rel->r_info); 108d297ad16SMarcel Moolenaar symidx = ELF_R_SYM(rel->r_info); 109aa855a59SPeter Wemm break; 110aa855a59SPeter Wemm case ELF_RELOC_RELA: 1110a5e03ddSMatthew Dillon rela = (const Elf_Rela *)data; 112aa855a59SPeter Wemm where = (Elf_Addr *) (relocbase + rela->r_offset); 113aa855a59SPeter Wemm addend = rela->r_addend; 114aa855a59SPeter Wemm rtype = ELF_R_TYPE(rela->r_info); 115d297ad16SMarcel Moolenaar symidx = ELF_R_SYM(rela->r_info); 116aa855a59SPeter Wemm break; 117aa855a59SPeter Wemm default: 118aa855a59SPeter Wemm panic("unknown reloc type %d\n", type); 119aa855a59SPeter Wemm } 120033f58dfSPeter Wemm 1217251b4bfSJake Burkholder if (local) { 1227251b4bfSJake Burkholder if (rtype == R_386_RELATIVE) { /* A + B */ 1237251b4bfSJake Burkholder addr = relocbase + addend; 1247251b4bfSJake Burkholder if (*where != addr) 1257251b4bfSJake Burkholder *where = addr; 1267251b4bfSJake Burkholder } 1277251b4bfSJake Burkholder return (0); 1287251b4bfSJake Burkholder } 1297251b4bfSJake Burkholder 130aa855a59SPeter Wemm switch (rtype) { 131aa855a59SPeter Wemm 132aa855a59SPeter Wemm case R_386_NONE: /* none */ 133033f58dfSPeter Wemm break; 134033f58dfSPeter Wemm 135aa855a59SPeter Wemm case R_386_32: /* S + A */ 136d297ad16SMarcel Moolenaar addr = elf_lookup(lf, symidx, 1); 137369dc8ceSEivind Eklund if (addr == 0) 138033f58dfSPeter Wemm return -1; 139aa855a59SPeter Wemm addr += addend; 140033f58dfSPeter Wemm if (*where != addr) 141033f58dfSPeter Wemm *where = addr; 142033f58dfSPeter Wemm break; 143033f58dfSPeter Wemm 144aa855a59SPeter Wemm case R_386_PC32: /* S + A - P */ 145d297ad16SMarcel Moolenaar addr = elf_lookup(lf, symidx, 1); 146369dc8ceSEivind Eklund if (addr == 0) 147033f58dfSPeter Wemm return -1; 148aa855a59SPeter Wemm addr += addend - (Elf_Addr)where; 149033f58dfSPeter Wemm if (*where != addr) 150033f58dfSPeter Wemm *where = addr; 151033f58dfSPeter Wemm break; 152033f58dfSPeter Wemm 153aa855a59SPeter Wemm case R_386_COPY: /* none */ 154033f58dfSPeter Wemm /* 155033f58dfSPeter Wemm * There shouldn't be copy relocations in kernel 156033f58dfSPeter Wemm * objects. 157033f58dfSPeter Wemm */ 158033f58dfSPeter Wemm printf("kldload: unexpected R_COPY relocation\n"); 159033f58dfSPeter Wemm return -1; 160033f58dfSPeter Wemm break; 161033f58dfSPeter Wemm 162aa855a59SPeter Wemm case R_386_GLOB_DAT: /* S */ 163d297ad16SMarcel Moolenaar addr = elf_lookup(lf, symidx, 1); 164369dc8ceSEivind Eklund if (addr == 0) 165033f58dfSPeter Wemm return -1; 166033f58dfSPeter Wemm if (*where != addr) 167033f58dfSPeter Wemm *where = addr; 168033f58dfSPeter Wemm break; 169033f58dfSPeter Wemm 1707251b4bfSJake Burkholder case R_386_RELATIVE: 171033f58dfSPeter Wemm break; 172033f58dfSPeter Wemm 173033f58dfSPeter Wemm default: 174033f58dfSPeter Wemm printf("kldload: unexpected relocation type %d\n", 175aa855a59SPeter Wemm rtype); 176033f58dfSPeter Wemm return -1; 177033f58dfSPeter Wemm } 178033f58dfSPeter Wemm return(0); 179033f58dfSPeter Wemm } 1801aeb23cdSMarcel Moolenaar 1811aeb23cdSMarcel Moolenaar int 1827251b4bfSJake Burkholder elf_reloc(linker_file_t lf, const void *data, int type) 1837251b4bfSJake Burkholder { 1847251b4bfSJake Burkholder 1857251b4bfSJake Burkholder return (elf_reloc_internal(lf, data, type, 0)); 1867251b4bfSJake Burkholder } 1877251b4bfSJake Burkholder 1887251b4bfSJake Burkholder int 1897251b4bfSJake Burkholder elf_reloc_local(linker_file_t lf, const void *data, int type) 1907251b4bfSJake Burkholder { 1917251b4bfSJake Burkholder 1927251b4bfSJake Burkholder return (elf_reloc_internal(lf, data, type, 1)); 1937251b4bfSJake Burkholder } 1947251b4bfSJake Burkholder 1957251b4bfSJake Burkholder int 1961aeb23cdSMarcel Moolenaar elf_cpu_load_file(linker_file_t lf __unused) 1971aeb23cdSMarcel Moolenaar { 1981aeb23cdSMarcel Moolenaar 1991aeb23cdSMarcel Moolenaar return (0); 2001aeb23cdSMarcel Moolenaar } 2011aeb23cdSMarcel Moolenaar 2021aeb23cdSMarcel Moolenaar int 2031aeb23cdSMarcel Moolenaar elf_cpu_unload_file(linker_file_t lf __unused) 2041aeb23cdSMarcel Moolenaar { 2051aeb23cdSMarcel Moolenaar 2061aeb23cdSMarcel Moolenaar return (0); 2071aeb23cdSMarcel Moolenaar } 208