123d0f849SIan Dowse /*- 223d0f849SIan Dowse * Copyright (c) 2003 Jake Burkholder. 323d0f849SIan Dowse * Copyright 1996-1998 John D. Polstra. 423d0f849SIan Dowse * All rights reserved. 523d0f849SIan Dowse * 623d0f849SIan Dowse * Redistribution and use in source and binary forms, with or without 723d0f849SIan Dowse * modification, are permitted provided that the following conditions 823d0f849SIan Dowse * are met: 923d0f849SIan Dowse * 1. Redistributions of source code must retain the above copyright 1023d0f849SIan Dowse * notice, this list of conditions and the following disclaimer. 1123d0f849SIan Dowse * 2. Redistributions in binary form must reproduce the above copyright 1223d0f849SIan Dowse * notice, this list of conditions and the following disclaimer in the 1323d0f849SIan Dowse * documentation and/or other materials provided with the distribution. 1423d0f849SIan Dowse * 1523d0f849SIan Dowse * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1623d0f849SIan Dowse * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1723d0f849SIan Dowse * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1823d0f849SIan Dowse * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1923d0f849SIan Dowse * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2023d0f849SIan Dowse * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2123d0f849SIan Dowse * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2223d0f849SIan Dowse * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2323d0f849SIan Dowse * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2423d0f849SIan Dowse * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2523d0f849SIan Dowse * SUCH DAMAGE. 2623d0f849SIan Dowse * 2723d0f849SIan Dowse * $FreeBSD$ 2823d0f849SIan Dowse */ 2923d0f849SIan Dowse 3023d0f849SIan Dowse #include <sys/types.h> 3123d0f849SIan Dowse #include <machine/elf.h> 3223d0f849SIan Dowse 3323d0f849SIan Dowse #include <err.h> 3423d0f849SIan Dowse #include <errno.h> 3523d0f849SIan Dowse #include <string.h> 3623d0f849SIan Dowse 3723d0f849SIan Dowse #include "ef.h" 3823d0f849SIan Dowse 3923d0f849SIan Dowse /* 409dba198bSIan Dowse * Apply relocations to the values we got from the file. `relbase' is the 419dba198bSIan Dowse * target relocation address of the section, and `dataoff' is the target 429dba198bSIan Dowse * relocation address of the data in `dest'. 4323d0f849SIan Dowse */ 4423d0f849SIan Dowse int 459dba198bSIan Dowse ef_reloc(struct elf_file *ef, const void *reldata, int reltype, Elf_Off relbase, 469dba198bSIan Dowse Elf_Off dataoff, size_t len, void *dest) 4723d0f849SIan Dowse { 4823d0f849SIan Dowse Elf_Addr *where, addr, addend; 4923d0f849SIan Dowse Elf_Word rtype, symidx; 5023d0f849SIan Dowse const Elf_Rel *rel; 5123d0f849SIan Dowse const Elf_Rela *rela; 5223d0f849SIan Dowse 539dba198bSIan Dowse switch (reltype) { 5423d0f849SIan Dowse case EF_RELOC_REL: 559dba198bSIan Dowse rel = (const Elf_Rel *)reldata; 569dba198bSIan Dowse where = (Elf_Addr *)(dest + relbase + rel->r_offset - dataoff); 579dba198bSIan Dowse addend = 0; 5823d0f849SIan Dowse rtype = ELF_R_TYPE(rel->r_info); 5923d0f849SIan Dowse symidx = ELF_R_SYM(rel->r_info); 6023d0f849SIan Dowse break; 6123d0f849SIan Dowse case EF_RELOC_RELA: 629dba198bSIan Dowse rela = (const Elf_Rela *)reldata; 639dba198bSIan Dowse where = (Elf_Addr *)(dest + relbase + rela->r_offset - dataoff); 6423d0f849SIan Dowse addend = rela->r_addend; 6523d0f849SIan Dowse rtype = ELF_R_TYPE(rela->r_info); 6623d0f849SIan Dowse symidx = ELF_R_SYM(rela->r_info); 6723d0f849SIan Dowse break; 6823d0f849SIan Dowse default: 6923d0f849SIan Dowse return (EINVAL); 7023d0f849SIan Dowse } 7123d0f849SIan Dowse 7223d0f849SIan Dowse if ((char *)where < (char *)dest || (char *)where >= (char *)dest + len) 7323d0f849SIan Dowse return (0); 7423d0f849SIan Dowse 759dba198bSIan Dowse if (reltype == EF_RELOC_REL) 7623d0f849SIan Dowse addend = *where; 7723d0f849SIan Dowse 7823d0f849SIan Dowse switch (rtype) { 7923d0f849SIan Dowse case R_386_RELATIVE: /* A + B */ 809dba198bSIan Dowse addr = (Elf_Addr)addend + relbase; 8123d0f849SIan Dowse *where = addr; 8223d0f849SIan Dowse break; 8323d0f849SIan Dowse case R_386_32: /* S + A - P */ 8423d0f849SIan Dowse addr = EF_SYMADDR(ef, symidx); 8523d0f849SIan Dowse addr += addend; 8623d0f849SIan Dowse *where = addr; 8723d0f849SIan Dowse break; 8823d0f849SIan Dowse case R_386_GLOB_DAT: /* S */ 8923d0f849SIan Dowse addr = EF_SYMADDR(ef, symidx); 9023d0f849SIan Dowse *where = addr; 9123d0f849SIan Dowse break; 9223d0f849SIan Dowse default: 9323d0f849SIan Dowse warnx("unhandled relocation type %d", (int)rtype); 9423d0f849SIan Dowse } 9523d0f849SIan Dowse return (0); 9623d0f849SIan Dowse } 97