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 //#define TRACE_RLD 21 #ifdef TRACE_RLD 22 # define TRACE(x) dprintf x 23 #else 24 # define TRACE(x) ; 25 #endif 26 27 28 static int 29 relocate_rel(image_t *rootImage, image_t *image, struct Elf32_Rel *rel, 30 int rel_len) 31 { 32 int i; 33 addr_t S; 34 addr_t final_val; 35 36 # define P ((addr_t *)(image->regions[0].delta + rel[i].r_offset)) 37 # define A (*(P)) 38 # define B (image->regions[0].delta) 39 40 for (i = 0; i * (int)sizeof(struct Elf32_Rel) < rel_len; i++) { 41 unsigned type = ELF32_R_TYPE(rel[i].r_info); 42 43 switch (type) { 44 case R_386_32: 45 case R_386_PC32: 46 case R_386_GLOB_DAT: 47 case R_386_JMP_SLOT: 48 case R_386_GOTOFF: 49 { 50 struct Elf32_Sym *sym; 51 status_t status; 52 sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); 53 54 status = resolve_symbol(rootImage, image, sym, &S); 55 if (status < B_OK) { 56 TRACE(("resolve symbol \"%s\" returned: %ld\n", 57 SYMNAME(image, sym), status)); 58 printf("resolve symbol \"%s\" returned: %ld\n", 59 SYMNAME(image, sym), status); 60 return status; 61 } 62 } 63 } 64 switch (type) { 65 case R_386_NONE: 66 continue; 67 case R_386_32: 68 final_val = S + A; 69 break; 70 case R_386_PC32: 71 final_val = S + A - (addr_t)P; 72 break; 73 #if 0 74 case R_386_GOT32: 75 final_val = G + A; 76 break; 77 case R_386_PLT32: 78 final_val = L + A - (addr_t)P; 79 break; 80 #endif 81 case R_386_COPY: 82 /* what ? */ 83 continue; 84 case R_386_GLOB_DAT: 85 final_val = S; 86 break; 87 case R_386_JMP_SLOT: 88 final_val = S; 89 break; 90 case R_386_RELATIVE: 91 final_val = B + A; 92 break; 93 #if 0 94 case R_386_GOTOFF: 95 final_val = S + A - GOT; 96 break; 97 case R_386_GOTPC: 98 final_val = GOT + A - P; 99 break; 100 #endif 101 default: 102 TRACE(("unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info))); 103 return B_NOT_ALLOWED; 104 } 105 106 *P = final_val; 107 } 108 109 # undef P 110 # undef A 111 # undef B 112 113 return B_NO_ERROR; 114 } 115 116 117 status_t 118 arch_relocate_image(image_t *rootImage, image_t *image) 119 { 120 status_t status; 121 122 // deal with the rels first 123 if (image->rel) { 124 status = relocate_rel(rootImage, image, image->rel, image->rel_len); 125 if (status < B_OK) 126 return status; 127 } 128 129 if (image->pltrel) { 130 status = relocate_rel(rootImage, image, image->pltrel, 131 image->pltrel_len); 132 if (status < B_OK) 133 return status; 134 } 135 136 if (image->rela) { 137 //int i; 138 TRACE(("RELA relocations not supported\n")); 139 return EOPNOTSUPP; 140 141 //for (i = 1; i * (int)sizeof(struct Elf32_Rela) < image->rela_len; i++) { 142 // printf("rela: type %d\n", ELF32_R_TYPE(image->rela[i].r_info)); 143 //} 144 } 145 146 return B_OK; 147 } 148