1 /* 2 * Copyright 2012-2022, Haiku, Inc. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ithamar R. Adema <ithamar@upgrade-android.com> 7 */ 8 9 #include <string.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 13 #include "runtime_loader_private.h" 14 15 #include <runtime_loader.h> 16 17 //#define TRACE_RLD 18 #ifdef TRACE_RLD 19 # define TRACE(x...) dprintf(x) 20 #else 21 # define TRACE(x...) ; 22 #endif 23 24 25 static int 26 relocate_rel(image_t *rootImage, image_t *image, Elf32_Rel *rel, int rel_len, 27 SymbolLookupCache* cache) 28 { 29 # define P ((addr_t *)(image->regions[0].delta + rel[i].r_offset)) 30 # define A (*(P)) 31 # define B (image->regions[0].delta) 32 33 for (int i = 0; i * (int)sizeof(Elf32_Rel) < rel_len; i++) { 34 unsigned type = ELF32_R_TYPE(rel[i].r_info); 35 unsigned symbolIndex = ELF32_R_SYM(rel[i].r_info); 36 addr_t final_val; 37 addr_t S; 38 39 image_t* symbolImage = NULL; 40 if (symbolIndex != 0) { 41 Elf32_Sym* sym = SYMBOL(image, symbolIndex); 42 status_t status = resolve_symbol(rootImage, image, sym, cache, &S, 43 &symbolImage); 44 if (status < B_OK) { 45 TRACE("resolve symbol \"%s\" returned: %ld\n", 46 SYMNAME(image, sym), status); 47 return status; 48 } 49 } 50 51 switch (type) { 52 case R_ARM_NONE: 53 continue; 54 case R_ARM_RELATIVE: 55 final_val = B + A; 56 break; 57 case R_ARM_JMP_SLOT: 58 case R_ARM_GLOB_DAT: 59 final_val = S; 60 break; 61 case R_ARM_ABS32: 62 final_val = S + A; 63 break; 64 default: 65 TRACE("unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info)); 66 return B_NOT_ALLOWED; 67 } 68 69 *P = final_val; 70 } 71 72 # undef P 73 # undef A 74 # undef B 75 76 return B_NO_ERROR; 77 } 78 79 80 status_t 81 arch_relocate_image(image_t *rootImage, image_t *image, 82 SymbolLookupCache* cache) 83 { 84 status_t status; 85 86 // deal with the rels first 87 if (image->rel) { 88 status = relocate_rel(rootImage, image, image->rel, image->rel_len, 89 cache); 90 if (status < B_OK) 91 return status; 92 } 93 94 if (image->pltrel) { 95 status = relocate_rel(rootImage, image, image->pltrel, 96 image->pltrel_len, cache); 97 if (status < B_OK) 98 return status; 99 } 100 101 if (image->rela) { 102 TRACE("RELA relocations not supported\n"); 103 return EOPNOTSUPP; 104 } 105 106 return B_OK; 107 } 108