elf_machdep.c (40130) | elf_machdep.c (40435) |
---|---|
1/*- 2 * Copyright 1996-1998 John D. Polstra. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 8 unchanged lines hidden (view full) --- 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * | 1/*- 2 * Copyright 1996-1998 John D. Polstra. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 8 unchanged lines hidden (view full) --- 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * |
25 * $Id: elf_machdep.c,v 1.1 1998/10/09 20:35:45 peter Exp $ | 25 * $Id: elf_machdep.c,v 1.2 1998/10/09 20:38:03 peter Exp $ |
26 */ 27 28#include <sys/param.h> 29#include <sys/kernel.h> 30#include <sys/systm.h> 31#include <sys/malloc.h> 32#include <sys/proc.h> 33#include <sys/namei.h> 34#include <sys/fcntl.h> 35#include <sys/vnode.h> 36#include <sys/linker.h> 37#include <machine/elf.h> 38 39/* Process one elf relocation with addend. */ 40int | 26 */ 27 28#include <sys/param.h> 29#include <sys/kernel.h> 30#include <sys/systm.h> 31#include <sys/malloc.h> 32#include <sys/proc.h> 33#include <sys/namei.h> 34#include <sys/fcntl.h> 35#include <sys/vnode.h> 36#include <sys/linker.h> 37#include <machine/elf.h> 38 39/* Process one elf relocation with addend. */ 40int |
41elf_reloc(linker_file_t lf, const Elf_Rela *rela, const char *sym) | 41elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) |
42{ 43 Elf_Addr relocbase = (Elf_Addr) lf->address; | 42{ 43 Elf_Addr relocbase = (Elf_Addr) lf->address; |
44 Elf_Addr *where = (Elf_Addr *) (relocbase + rela->r_offset); | 44 Elf_Addr *where; |
45 Elf_Addr addr, tmp_value; | 45 Elf_Addr addr, tmp_value; |
46 Elf_Addr addend; 47 Elf_Word rtype; 48 const Elf_Rel *rel; 49 const Elf_Rela *rela; |
|
46 | 50 |
47 switch (ELF_R_TYPE(rela->r_info)) { | 51 switch (type) { 52 case ELF_RELOC_REL: 53 rel = (Elf_Rel *)data; 54 where = (Elf_Addr *) (relocbase + rel->r_offset); 55 addend = *where; 56 rtype = ELF_R_TYPE(rel->r_info); 57 break; 58 case ELF_RELOC_RELA: 59 rela = (Elf_Rela *)data; 60 where = (Elf_Addr *) (relocbase + rela->r_offset); 61 addend = rela->r_addend; 62 rtype = ELF_R_TYPE(rela->r_info); 63 break; 64 default: 65 panic("unknown reloc type %d\n", type); 66 } |
48 | 67 |
49 case R_386_NONE: | 68 switch (rtype) { 69 70 case R_386_NONE: /* none */ |
50 break; 51 | 71 break; 72 |
52 case R_386_32: | 73 case R_386_32: /* S + A */ 74 if (sym == NULL) 75 return -1; |
53 addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); 54 if (addr == NULL) 55 return -1; | 76 addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); 77 if (addr == NULL) 78 return -1; |
56 57 addr += rela->r_addend; | 79 addr += addend; |
58 if (*where != addr) 59 *where = addr; 60 break; 61 | 80 if (*where != addr) 81 *where = addr; 82 break; 83 |
62 case R_386_PC32: | 84 case R_386_PC32: /* S + A - P */ 85 if (sym == NULL) 86 return -1; |
63 addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); 64 if (addr == NULL) 65 return -1; | 87 addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); 88 if (addr == NULL) 89 return -1; |
66 67 addr += *where - (Elf_Addr)where + rela->r_addend; | 90 addr += addend - (Elf_Addr)where; |
68 if (*where != addr) 69 *where = addr; 70 break; 71 | 91 if (*where != addr) 92 *where = addr; 93 break; 94 |
72 case R_386_COPY: | 95 case R_386_COPY: /* none */ |
73 /* 74 * There shouldn't be copy relocations in kernel 75 * objects. 76 */ 77 printf("kldload: unexpected R_COPY relocation\n"); 78 return -1; 79 break; 80 | 96 /* 97 * There shouldn't be copy relocations in kernel 98 * objects. 99 */ 100 printf("kldload: unexpected R_COPY relocation\n"); 101 return -1; 102 break; 103 |
81 case R_386_GLOB_DAT: | 104 case R_386_GLOB_DAT: /* S */ 105 if (sym == NULL) 106 return -1; |
82 addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); 83 if (addr == NULL) 84 return -1; | 107 addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); 108 if (addr == NULL) 109 return -1; |
85 | |
86 if (*where != addr) 87 *where = addr; 88 break; 89 | 110 if (*where != addr) 111 *where = addr; 112 break; 113 |
90 case R_386_RELATIVE: 91 *where += relocbase; | 114 case R_386_RELATIVE: /* B + A */ 115 addr = relocbase + addend; 116 if (*where != addr) 117 *where = addr; |
92 break; 93 94 default: 95 printf("kldload: unexpected relocation type %d\n", | 118 break; 119 120 default: 121 printf("kldload: unexpected relocation type %d\n", |
96 ELF_R_TYPE(rela->r_info)); | 122 rtype); |
97 return -1; 98 } 99 return(0); 100} | 123 return -1; 124 } 125 return(0); 126} |