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