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 * 25c3aac50fSPeter Wemm * $FreeBSD$ 26033f58dfSPeter Wemm */ 27033f58dfSPeter Wemm 28033f58dfSPeter Wemm #include <sys/param.h> 293ebc1248SPeter Wemm #include <sys/kernel.h> 30033f58dfSPeter Wemm #include <sys/systm.h> 31f36ba452SJake Burkholder #include <sys/exec.h> 32f36ba452SJake Burkholder #include <sys/imgact.h> 33033f58dfSPeter Wemm #include <sys/linker.h> 343ebc1248SPeter Wemm #include <sys/sysent.h> 353ebc1248SPeter Wemm #include <sys/imgact_elf.h> 363ebc1248SPeter Wemm #include <sys/syscall.h> 373ebc1248SPeter Wemm #include <sys/signalvar.h> 383ebc1248SPeter Wemm #include <sys/vnode.h> 39f36ba452SJake Burkholder 40f36ba452SJake Burkholder #include <vm/vm.h> 41f36ba452SJake Burkholder #include <vm/pmap.h> 42f36ba452SJake Burkholder #include <vm/vm_param.h> 43f36ba452SJake Burkholder 44033f58dfSPeter Wemm #include <machine/elf.h> 453ebc1248SPeter Wemm #include <machine/md_var.h> 463ebc1248SPeter Wemm 473ebc1248SPeter Wemm struct sysentvec elf32_freebsd_sysvec = { 483ebc1248SPeter Wemm SYS_MAXSYSCALL, 493ebc1248SPeter Wemm sysent, 503ebc1248SPeter Wemm 0, 513ebc1248SPeter Wemm 0, 52f36ba452SJake Burkholder NULL, 533ebc1248SPeter Wemm 0, 54f36ba452SJake Burkholder NULL, 55f36ba452SJake Burkholder NULL, 56f36ba452SJake Burkholder __elfN(freebsd_fixup), 573ebc1248SPeter Wemm sendsig, 583ebc1248SPeter Wemm sigcode, 593ebc1248SPeter Wemm &szsigcode, 60f36ba452SJake Burkholder NULL, 613ebc1248SPeter Wemm "FreeBSD ELF32", 623ebc1248SPeter Wemm __elfN(coredump), 633ebc1248SPeter Wemm NULL, 64f36ba452SJake Burkholder MINSIGSTKSZ, 65f36ba452SJake Burkholder PAGE_SIZE, 66f36ba452SJake Burkholder VM_MIN_ADDRESS, 67f36ba452SJake Burkholder VM_MAXUSER_ADDRESS, 68f36ba452SJake Burkholder USRSTACK, 69f36ba452SJake Burkholder PS_STRINGS, 70f36ba452SJake Burkholder VM_PROT_ALL, 71f36ba452SJake Burkholder exec_copyout_strings, 72f36ba452SJake Burkholder exec_setregs 733ebc1248SPeter Wemm }; 743ebc1248SPeter Wemm 753ebc1248SPeter Wemm static Elf32_Brandinfo freebsd_brand_info = { 763ebc1248SPeter Wemm ELFOSABI_FREEBSD, 773ebc1248SPeter Wemm EM_386, 783ebc1248SPeter Wemm "FreeBSD", 793ebc1248SPeter Wemm "", 803ebc1248SPeter Wemm "/usr/libexec/ld-elf.so.1", 813ebc1248SPeter Wemm &elf32_freebsd_sysvec 823ebc1248SPeter Wemm }; 833ebc1248SPeter Wemm 843ebc1248SPeter Wemm SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY, 853ebc1248SPeter Wemm (sysinit_cfunc_t) elf32_insert_brand_entry, 863ebc1248SPeter Wemm &freebsd_brand_info); 87033f58dfSPeter Wemm 88bde362f5SPeter Wemm /* Process one elf relocation with addend. */ 89033f58dfSPeter Wemm int 90d297ad16SMarcel Moolenaar elf_reloc(linker_file_t lf, const void *data, int type) 91033f58dfSPeter Wemm { 92033f58dfSPeter Wemm Elf_Addr relocbase = (Elf_Addr) lf->address; 93aa855a59SPeter Wemm Elf_Addr *where; 94f1d19042SArchie Cobbs Elf_Addr addr; 95aa855a59SPeter Wemm Elf_Addr addend; 96d297ad16SMarcel Moolenaar Elf_Word rtype, symidx; 97aa855a59SPeter Wemm const Elf_Rel *rel; 98aa855a59SPeter Wemm const Elf_Rela *rela; 99033f58dfSPeter Wemm 100aa855a59SPeter Wemm switch (type) { 101aa855a59SPeter Wemm case ELF_RELOC_REL: 1020a5e03ddSMatthew Dillon rel = (const Elf_Rel *)data; 103aa855a59SPeter Wemm where = (Elf_Addr *) (relocbase + rel->r_offset); 104aa855a59SPeter Wemm addend = *where; 105aa855a59SPeter Wemm rtype = ELF_R_TYPE(rel->r_info); 106d297ad16SMarcel Moolenaar symidx = ELF_R_SYM(rel->r_info); 107aa855a59SPeter Wemm break; 108aa855a59SPeter Wemm case ELF_RELOC_RELA: 1090a5e03ddSMatthew Dillon rela = (const Elf_Rela *)data; 110aa855a59SPeter Wemm where = (Elf_Addr *) (relocbase + rela->r_offset); 111aa855a59SPeter Wemm addend = rela->r_addend; 112aa855a59SPeter Wemm rtype = ELF_R_TYPE(rela->r_info); 113d297ad16SMarcel Moolenaar symidx = ELF_R_SYM(rela->r_info); 114aa855a59SPeter Wemm break; 115aa855a59SPeter Wemm default: 116aa855a59SPeter Wemm panic("unknown reloc type %d\n", type); 117aa855a59SPeter Wemm } 118033f58dfSPeter Wemm 119aa855a59SPeter Wemm switch (rtype) { 120aa855a59SPeter Wemm 121aa855a59SPeter Wemm case R_386_NONE: /* none */ 122033f58dfSPeter Wemm break; 123033f58dfSPeter Wemm 124aa855a59SPeter Wemm case R_386_32: /* S + A */ 125d297ad16SMarcel Moolenaar addr = elf_lookup(lf, symidx, 1); 126369dc8ceSEivind Eklund if (addr == 0) 127033f58dfSPeter Wemm return -1; 128aa855a59SPeter Wemm addr += addend; 129033f58dfSPeter Wemm if (*where != addr) 130033f58dfSPeter Wemm *where = addr; 131033f58dfSPeter Wemm break; 132033f58dfSPeter Wemm 133aa855a59SPeter Wemm case R_386_PC32: /* S + A - P */ 134d297ad16SMarcel Moolenaar addr = elf_lookup(lf, symidx, 1); 135369dc8ceSEivind Eklund if (addr == 0) 136033f58dfSPeter Wemm return -1; 137aa855a59SPeter Wemm addr += addend - (Elf_Addr)where; 138033f58dfSPeter Wemm if (*where != addr) 139033f58dfSPeter Wemm *where = addr; 140033f58dfSPeter Wemm break; 141033f58dfSPeter Wemm 142aa855a59SPeter Wemm case R_386_COPY: /* none */ 143033f58dfSPeter Wemm /* 144033f58dfSPeter Wemm * There shouldn't be copy relocations in kernel 145033f58dfSPeter Wemm * objects. 146033f58dfSPeter Wemm */ 147033f58dfSPeter Wemm printf("kldload: unexpected R_COPY relocation\n"); 148033f58dfSPeter Wemm return -1; 149033f58dfSPeter Wemm break; 150033f58dfSPeter Wemm 151aa855a59SPeter Wemm case R_386_GLOB_DAT: /* S */ 152d297ad16SMarcel Moolenaar addr = elf_lookup(lf, symidx, 1); 153369dc8ceSEivind Eklund if (addr == 0) 154033f58dfSPeter Wemm return -1; 155033f58dfSPeter Wemm if (*where != addr) 156033f58dfSPeter Wemm *where = addr; 157033f58dfSPeter Wemm break; 158033f58dfSPeter Wemm 159aa855a59SPeter Wemm case R_386_RELATIVE: /* B + A */ 160aa855a59SPeter Wemm addr = relocbase + addend; 161aa855a59SPeter Wemm if (*where != addr) 162aa855a59SPeter Wemm *where = addr; 163033f58dfSPeter Wemm break; 164033f58dfSPeter Wemm 165033f58dfSPeter Wemm default: 166033f58dfSPeter Wemm printf("kldload: unexpected relocation type %d\n", 167aa855a59SPeter Wemm rtype); 168033f58dfSPeter Wemm return -1; 169033f58dfSPeter Wemm } 170033f58dfSPeter Wemm return(0); 171033f58dfSPeter Wemm } 1721aeb23cdSMarcel Moolenaar 1731aeb23cdSMarcel Moolenaar int 1741aeb23cdSMarcel Moolenaar elf_cpu_load_file(linker_file_t lf __unused) 1751aeb23cdSMarcel Moolenaar { 1761aeb23cdSMarcel Moolenaar 1771aeb23cdSMarcel Moolenaar return (0); 1781aeb23cdSMarcel Moolenaar } 1791aeb23cdSMarcel Moolenaar 1801aeb23cdSMarcel Moolenaar int 1811aeb23cdSMarcel Moolenaar elf_cpu_unload_file(linker_file_t lf __unused) 1821aeb23cdSMarcel Moolenaar { 1831aeb23cdSMarcel Moolenaar 1841aeb23cdSMarcel Moolenaar return (0); 1851aeb23cdSMarcel Moolenaar } 186