elf64_machdep.c revision 120422
1185377Ssam/*- 2187831Ssam * Copyright 1996-1998 John D. Polstra. 3185377Ssam * All rights reserved. 4185377Ssam * 5185377Ssam * Redistribution and use in source and binary forms, with or without 6185377Ssam * modification, are permitted provided that the following conditions 7185377Ssam * are met: 8185377Ssam * 1. Redistributions of source code must retain the above copyright 9185377Ssam * notice, this list of conditions and the following disclaimer. 10185377Ssam * 2. Redistributions in binary form must reproduce the above copyright 11185377Ssam * notice, this list of conditions and the following disclaimer in the 12185377Ssam * documentation and/or other materials provided with the distribution. 13185377Ssam * 14185377Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15185377Ssam * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16185377Ssam * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17185907Ssam * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18185377Ssam * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19185377Ssam * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20185377Ssam * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21185377Ssam * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22185377Ssam * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23185377Ssam * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24185377Ssam * 25185377Ssam * $FreeBSD: head/sys/powerpc/powerpc/elf_machdep.c 120422 2003-09-25 01:10:26Z peter $ 26185377Ssam */ 27185377Ssam 28185377Ssam#include <sys/param.h> 29185377Ssam#include <sys/kernel.h> 30185377Ssam#include <sys/systm.h> 31185377Ssam#include <sys/exec.h> 32185377Ssam#include <sys/imgact.h> 33185377Ssam#include <sys/malloc.h> 34185377Ssam#include <sys/proc.h> 35185377Ssam#include <sys/namei.h> 36185377Ssam#include <sys/fcntl.h> 37185377Ssam#include <sys/sysent.h> 38185377Ssam#include <sys/imgact_elf.h> 39185377Ssam#include <sys/syscall.h> 40185377Ssam#include <sys/signalvar.h> 41185377Ssam#include <sys/vnode.h> 42185377Ssam#include <sys/linker.h> 43185377Ssam 44185377Ssam#include <vm/vm.h> 45185377Ssam#include <vm/vm_param.h> 46185377Ssam 47185377Ssam#include <machine/elf.h> 48185377Ssam#include <machine/md_var.h> 49185377Ssam 50185377Ssamstruct sysentvec elf32_freebsd_sysvec = { 51185377Ssam SYS_MAXSYSCALL, 52185377Ssam sysent, 53185377Ssam 0, 54185377Ssam 0, 55185377Ssam NULL, 56185377Ssam 0, 57185377Ssam NULL, 58185377Ssam NULL, 59185377Ssam __elfN(freebsd_fixup), 60185377Ssam sendsig, 61185377Ssam sigcode, 62185377Ssam &szsigcode, 63185377Ssam NULL, 64185377Ssam "FreeBSD ELF32", 65185377Ssam __elfN(coredump), 66185377Ssam NULL, 67185377Ssam MINSIGSTKSZ, 68185377Ssam PAGE_SIZE, 69185377Ssam VM_MIN_ADDRESS, 70185377Ssam VM_MAXUSER_ADDRESS, 71185377Ssam USRSTACK, 72185377Ssam PS_STRINGS, 73185377Ssam VM_PROT_ALL, 74185377Ssam exec_copyout_strings, 75185377Ssam exec_setregs, 76185380Ssam NULL 77185380Ssam}; 78185380Ssam 79185380Ssamstatic Elf32_Brandinfo freebsd_brand_info = { 80185380Ssam ELFOSABI_FREEBSD, 81185380Ssam EM_PPC, 82185380Ssam "FreeBSD", 83185380Ssam "", 84185380Ssam "/libexec/ld-elf.so.1", 85185380Ssam &elf32_freebsd_sysvec 86185380Ssam }; 87185380Ssam 88185380SsamSYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY, 89185380Ssam (sysinit_cfunc_t) elf32_insert_brand_entry, 90185380Ssam &freebsd_brand_info); 91185380Ssam 92185380Ssam/* Process one elf relocation with addend. */ 93185380Ssamstatic int 94185380Ssamelf_reloc_internal(linker_file_t lf, const void *data, int type, int local) 95185380Ssam{ 96185380Ssam Elf_Addr relocbase = (Elf_Addr) lf->address; 97185380Ssam Elf_Addr *where; 98185380Ssam Elf_Addr addr; 99185380Ssam Elf_Addr addend; 100185380Ssam Elf_Word rtype, symidx; 101185380Ssam const Elf_Rel *rel; 102185380Ssam const Elf_Rela *rela; 103185380Ssam 104185380Ssam switch (type) { 105185380Ssam case ELF_RELOC_REL: 106185380Ssam rel = (const Elf_Rel *)data; 107185380Ssam where = (Elf_Addr *) (relocbase + rel->r_offset); 108185380Ssam addend = *where; 109185377Ssam rtype = ELF_R_TYPE(rel->r_info); 110185377Ssam symidx = ELF_R_SYM(rel->r_info); 111185377Ssam break; 112185377Ssam case ELF_RELOC_RELA: 113185377Ssam rela = (const Elf_Rela *)data; 114185377Ssam where = (Elf_Addr *) (relocbase + rela->r_offset); 115185377Ssam addend = rela->r_addend; 116185377Ssam rtype = ELF_R_TYPE(rela->r_info); 117185377Ssam symidx = ELF_R_SYM(rela->r_info); 118185377Ssam break; 119185377Ssam default: 120185377Ssam panic("elf_reloc: unknown relocation mode %d\n", type); 121185377Ssam } 122185377Ssam 123185380Ssam switch (rtype) { 124185380Ssam 125185380Ssam case R_PPC_NONE: 126185380Ssam break; 127185377Ssam 128185377Ssam case R_PPC_GLOB_DAT: 129185377Ssam addr = elf_lookup(lf, symidx, 1); 130185377Ssam if (addr == 0) 131185377Ssam return -1; 132185377Ssam addr += addend; 133185377Ssam if (*where != addr) 134185377Ssam *where = addr; 135185380Ssam break; 136185380Ssam 137185380Ssam case R_PPC_JMP_SLOT: 138185380Ssam /* No point in lazy binding for kernel modules. */ 139185377Ssam addr = elf_lookup(lf, symidx, 1); 140185377Ssam if (addr == 0) 141185377Ssam return -1; 142185377Ssam if (*where != addr) 143185377Ssam *where = addr; 144185377Ssam break; 145185377Ssam 146185377Ssam case R_PPC_RELATIVE: 147185377Ssam addr = relocbase + addend + *where; 148185377Ssam if (*where != addr) 149185377Ssam *where = addr; 150185377Ssam break; 151185377Ssam 152185377Ssam case R_PPC_COPY: 153185377Ssam /* 154185377Ssam * There shouldn't be copy relocations in kernel 155185377Ssam * objects. 156185377Ssam */ 157185377Ssam printf("kldload: unexpected R_COPY relocation\n"); 158185377Ssam return -1; 159185377Ssam 160185377Ssam default: 161185377Ssam printf("kldload: unexpected relocation type %d\n", 162185377Ssam (int) rtype); 163185377Ssam return -1; 164185377Ssam } 165185377Ssam return(0); 166185377Ssam} 167185377Ssam 168185377Ssamint 169185377Ssamelf_reloc(linker_file_t lf, const void *data, int type) 170185377Ssam{ 171185377Ssam 172185377Ssam return (elf_reloc_internal(lf, data, type, 0)); 173185377Ssam} 174185377Ssam 175185377Ssamint 176185377Ssamelf_reloc_local(linker_file_t lf, const void *data, int type) 177185377Ssam{ 178185377Ssam 179185377Ssam return (elf_reloc_internal(lf, data, type, 1)); 180185377Ssam} 181185377Ssam 182185377Ssamint 183185377Ssamelf_cpu_load_file(linker_file_t lf __unused) 184185377Ssam{ 185185377Ssam 186185377Ssam return (0); 187185377Ssam} 188185377Ssam 189185377Ssamint 190185377Ssamelf_cpu_unload_file(linker_file_t lf __unused) 191185377Ssam{ 192185377Ssam 193185377Ssam return (0); 194185377Ssam} 195185377Ssam