1 /* 2 * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de 3 * Distributed under the terms of the MIT License. 4 * 5 * Copyright 2001, Travis Geiselbrecht. All rights reserved. 6 * Copyright 2002, Manuel J. Petit. All rights reserved. 7 * Distributed under the terms of the NewOS License. 8 */ 9 10 11 #include "runtime_loader_private.h" 12 13 #include <runtime_loader.h> 14 15 #include <string.h> 16 #include <stdio.h> 17 #include <stdlib.h> 18 19 20 static int 21 relocate_rel(image_t *rootImage, image_t *image, struct Elf32_Rel *rel, 22 int rel_len, SymbolLookupCache* cache) 23 { 24 int i; 25 addr_t S; 26 addr_t final_val; 27 28 # define P ((addr_t *)(image->regions[0].delta + rel[i].r_offset)) 29 # define A (*(P)) 30 # define B (image->regions[0].delta) 31 32 for (i = 0; i * (int)sizeof(struct Elf32_Rel) < rel_len; i++) { 33 unsigned type = ELF32_R_TYPE(rel[i].r_info); 34 35 switch (type) { 36 case R_386_32: 37 case R_386_PC32: 38 case R_386_GLOB_DAT: 39 case R_386_JMP_SLOT: 40 case R_386_GOTOFF: 41 { 42 struct Elf32_Sym *sym; 43 status_t status; 44 sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); 45 46 status = resolve_symbol(rootImage, image, sym, cache, &S); 47 if (status < B_OK) { 48 TRACE(("resolve symbol \"%s\" returned: %ld\n", 49 SYMNAME(image, sym), status)); 50 printf("resolve symbol \"%s\" returned: %ld\n", 51 SYMNAME(image, sym), status); 52 return status; 53 } 54 } 55 } 56 switch (type) { 57 case R_386_NONE: 58 continue; 59 case R_386_32: 60 final_val = S + A; 61 break; 62 case R_386_PC32: 63 final_val = S + A - (addr_t)P; 64 break; 65 #if 0 66 case R_386_GOT32: 67 final_val = G + A; 68 break; 69 case R_386_PLT32: 70 final_val = L + A - (addr_t)P; 71 break; 72 #endif 73 case R_386_COPY: 74 /* what ? */ 75 continue; 76 case R_386_GLOB_DAT: 77 final_val = S; 78 break; 79 case R_386_JMP_SLOT: 80 final_val = S; 81 break; 82 case R_386_RELATIVE: 83 final_val = B + A; 84 break; 85 #if 0 86 case R_386_GOTOFF: 87 final_val = S + A - GOT; 88 break; 89 case R_386_GOTPC: 90 final_val = GOT + A - P; 91 break; 92 #endif 93 default: 94 TRACE(("unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info))); 95 return B_NOT_ALLOWED; 96 } 97 98 *P = final_val; 99 } 100 101 # undef P 102 # undef A 103 # undef B 104 105 return B_NO_ERROR; 106 } 107 108 109 status_t 110 arch_relocate_image(image_t* rootImage, image_t* image, 111 SymbolLookupCache* cache) 112 { 113 status_t status; 114 115 // deal with the rels first 116 if (image->rel) { 117 status = relocate_rel(rootImage, image, image->rel, image->rel_len, 118 cache); 119 if (status < B_OK) 120 return status; 121 } 122 123 if (image->pltrel) { 124 status = relocate_rel(rootImage, image, image->pltrel, 125 image->pltrel_len, cache); 126 if (status < B_OK) 127 return status; 128 } 129 130 if (image->rela) { 131 //int i; 132 TRACE(("RELA relocations not supported\n")); 133 return EOPNOTSUPP; 134 135 //for (i = 1; i * (int)sizeof(struct Elf32_Rela) < image->rela_len; i++) { 136 // printf("rela: type %d\n", ELF32_R_TYPE(image->rela[i].r_info)); 137 //} 138 } 139 140 return B_OK; 141 } 142