1 /* 2 * Copyright 2010, Ithamar R. Adema <ithamar.adema@team-embedded.nl> 3 * All rights reserved. Distributed under the terms of the MIT License. 4 * 5 * Copyright 2009, Johannes Wischert, johanneswi@gmail.com. 6 * All rights reserved. Distributed under the terms of the MIT License. 7 * 8 * Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>. 9 * All rights reserved. Distributed under the terms of the MIT License. 10 * 11 * Copyright 2002, Travis Geiselbrecht. All rights reserved. 12 * Distributed under the terms of the NewOS License. 13 */ 14 15 #ifdef _BOOT_MODE 16 #include <boot/arch.h> 17 #endif 18 19 #include <KernelExport.h> 20 21 #include <elf_priv.h> 22 #include <arch/elf.h> 23 24 25 //#define TRACE_ARCH_ELF 26 #ifdef TRACE_ARCH_ELF 27 # define TRACE(x) dprintf x 28 # define CHATTY 1 29 #else 30 # define TRACE(x) ; 31 # define CHATTY 0 32 #endif 33 34 35 #ifdef TRACE_ARCH_ELF 36 static const char *kRelocations[] = { 37 "R_ARM_NONE", //0 Static Miscellaneous 38 "R_ARM_PC24", //1 Deprecated ARM ((S + A) | T) ? P 39 "R_ARM_ABS32", //2 Static Data (S + A) | T 40 "R_ARM_REL32", //3 Static Data ((S + A) | T) ? P 41 "R_ARM_LDR_PC_G0", //4 Static ARM S + A ? P 42 "R_ARM_ABS16", //5 Static Data S + A 43 "R_ARM_ABS12", //6 Static ARM S + A 44 "R_ARM_THM_ABS5", //7 Static Thumb16 S + A 45 "R_ARM_ABS8", //8 Static Data S + A 46 "R_ARM_SBREL32", //9 Static Data ((S + A) | T) ? B(S) 47 "R_ARM_THM_CALL", //10 Static Thumb32 ((S + A) | T) ? P 48 "R_ARM_THM_PC8", //11 Static Thumb16 S + A ? Pa 49 "R_ARM_BREL_ADJ", //12 Dynamic Data ?B(S) + A 50 "R_ARM_TLS_DESC", //13 Dynamic Data 51 "R_ARM_THM_SWI8", //14 Obsolete 52 "R_ARM_XPC25", //15 Obsolete 53 "R_ARM_THM_XPC22", //16 Obsolete Encodings reserved for future 54 // Dynamic relocations 55 "R_ARM_TLS_DTPMOD32", //17 Dynamic Data Module[S] 56 "R_ARM_TLS_DTPOFF32", //18 Dynamic Data S + A ? TLS 57 "R_ARM_TLS_TPOFF32", //19 Dynamic Data S + A ? tp 58 "R_ARM_COPY", //20 Dynamic Miscellaneous 59 "R_ARM_GLOB_DAT", //21 Dynamic Data (S + A) | T 60 "R_ARM_JUMP_SLOT", //22 Dynamic Data (S + A) | T 61 "R_ARM_RELATIVE", //23 Dynamic Data B(S) + A [Note: see Table 4-16] 62 "R_ARM_GOTOFF32", //24 Static Data ((S + A) | T) ? GOT_ORG 63 "R_ARM_BASE_PREL", //25 Static Data B(S) + A ? P 64 "R_ARM_GOT_BREL", //26 Static Data GOT(S) + A ? GOT_ORG 65 "R_ARM_PLT32", //27 Deprecated ARM ((S + A) | T) ? P 66 "R_ARM_CALL", //28 Static ARM ((S + A) | T) ? P 67 "R_ARM_JUMP24", //29 Static ARM ((S + A) | T) ? P 68 "R_ARM_THM_JUMP24", //30 Static Thumb32 ((S + A) | T) ? P 69 "R_ARM_BASE_ABS", //31 Static Data B(S) + A 70 "R_ARM_ALU_PCREL_7_0", //32 Obsolete 71 "R_ARM_ALU_PCREL_15_8", //33 Obsolete 72 "R_ARM_ALU_PCREL_23_15", //34 Obsolete Note ? Legacy (ARM ELF B02) 73 // names have been retained for these obsolete relocations. 74 "R_ARM_LDR_SBREL_11_0_NC", //35 Deprecated ARM S + A ? B(S) 75 "R_ARM_ALU_SBREL_19_12_NC", //36 Deprecated ARM S + A ? B(S) 76 "R_ARM_ALU_SBREL_27_20_CK", //37 Deprecated ARM S + A ? B(S) 77 "R_ARM_TARGET1", //38 Static Miscellaneous (S + A) | T or ((S + A) | T) ? P 78 "R_ARM_SBREL31", //39 Deprecated Data ((S + A) | T) ? B(S) 79 "R_ARM_V4BX", //40 Static Miscellaneous 80 "R_ARM_TARGET2", //41 Static Miscellaneous 81 "R_ARM_PREL31", //42 Static Data ((S + A) | T) ? P 82 "R_ARM_MOVW_ABS_NC", //43 Static ARM (S + A) | T 83 "R_ARM_MOVT_ABS", //44 Static ARM S + A 84 "R_ARM_MOVW_PREL_NC", //45 Static ARM ((S + A) | T) ? P 85 "R_ARM_MOVT_PREL", //46 Static ARM S + A ? P 86 "R_ARM_THM_MOVW_ABS_NC", //47 Static Thumb32 (S + A) | T 87 "R_ARM_THM_MOVT_ABS", //48 Static Thumb32 S + A 88 "R_ARM_THM_MOVW_PREL_NC", //49 Static Thumb32 ((S + A) | T) ? P 89 "R_ARM_THM_MOVT_PREL", //50 Static Thumb32 S + A ? P 90 "R_ARM_THM_JUMP19", //51 Static Thumb32 ((S + A) | T) ? P 91 "R_ARM_THM_JUMP6", //52 Static Thumb16 S + A ? P 92 "R_ARM_THM_ALU_PREL_11_0", //53 Static Thumb32 ((S + A) | T) ? Pa 93 "R_ARM_THM_PC12", //54 Static Thumb32 S + A ? Pa 94 "R_ARM_ABS32_NOI", //55 Static Data S + A 95 "R_ARM_REL32_NOI", //56 Static Data S + A ? P 96 "R_ARM_ALU_PC_G0_NC", //57 Static ARM ((S + A) | T) ? P 97 "R_ARM_ALU_PC_G0", //58 Static ARM ((S + A) | T) ? P 98 "R_ARM_ALU_PC_G1_NC", //59 Static ARM ((S + A) | T) ? P 99 "R_ARM_ALU_PC_G1", //60 Static ARM ((S + A) | T) ? P 100 "R_ARM_ALU_PC_G2", //61 Static ARM ((S + A) | T) ? P 101 "R_ARM_LDR_PC_G1", //62 Static ARM S + A ? P 102 "R_ARM_LDR_PC_G2", //63 Static ARM S + A ? P 103 "R_ARM_LDRS_PC_G0", //64 Static ARM S + A ? P 104 "R_ARM_LDRS_PC_G1", //65 Static ARM S + A ? P 105 "R_ARM_LDRS_PC_G2", //66 Static ARM S + A ? P 106 "R_ARM_LDC_PC_G0", //67 Static ARM S + A ? P 107 "R_ARM_LDC_PC_G1", //68 Static ARM S + A ? P 108 "R_ARM_LDC_PC_G2", //69 Static ARM S + A ? P 109 "R_ARM_ALU_SB_G0_NC", //70 Static ARM ((S + A) | T) ? B(S) 110 "R_ARM_ALU_SB_G0", //71 Static ARM ((S + A) | T) ? B(S) 111 "R_ARM_ALU_SB_G1_NC", //72 Static ARM ((S + A) | T) ? B(S) 112 "R_ARM_ALU_SB_G1", //73 Static ARM ((S + A) | T) ? B(S) 113 "R_ARM_ALU_SB_G2", //74 Static ARM ((S + A) | T) ? B(S) 114 "R_ARM_LDR_SB_G0", //75 Static ARM S + A ? B(S) 115 "R_ARM_LDR_SB_G1", //76 Static ARM S + A ? B(S) 116 "R_ARM_LDR_SB_G2", //77 Static ARM S + A ? B(S) 117 "R_ARM_LDRS_SB_G0", //78 Static ARM S + A ? B(S) 118 "R_ARM_LDRS_SB_G1", //79 Static ARM S + A ? B(S) 119 "R_ARM_LDRS_SB_G2", //80 Static ARM S + A ? B(S) 120 "R_ARM_LDC_SB_G0", //81 Static ARM S + A ? B(S) 121 "R_ARM_LDC_SB_G1", //82 Static ARM S + A ? B(S) 122 "R_ARM_LDC_SB_G2", //83 Static ARM S + A ? B(S) 123 "R_ARM_MOVW_BREL_NC", //84 Static ARM ((S + A) | T) ? B(S) 124 "R_ARM_MOVT_BREL", //85 Static ARM S + A ? B(S) 125 "R_ARM_MOVW_BREL", //86 Static ARM ((S + A) | T) ? B(S) 126 "R_ARM_THM_MOVW_BREL_NC", //87 Static Thumb32 ((S + A) | T) ? B(S) 127 "R_ARM_THM_MOVT_BREL", //88 Static Thumb32 S + A ? B(S) 128 "R_ARM_THM_MOVW_BREL", //89 Static Thumb32 ((S + A) | T) ? B(S) 129 "R_ARM_TLS_GOTDESC", //90 Static Data 130 "R_ARM_TLS_CALL", //91 Static ARM 131 "R_ARM_TLS_DESCSEQ", //92 Static ARM TLS relaxation 132 "R_ARM_THM_TLS_CALL", //93 Static Thumb32 133 "R_ARM_PLT32_ABS", //94 Static Data PLT(S) + A 134 "R_ARM_GOT_ABS", //95 Static Data GOT(S) + A 135 "R_ARM_GOT_PREL", //96 Static Data GOT(S) + A ? P 136 "R_ARM_GOT_BREL12", //97 Static ARM GOT(S) + A ? GOT_ORG 137 "R_ARM_GOTOFF12", //98 Static ARM S + A ? GOT_ORG 138 "R_ARM_GOTRELAX", //99 Static Miscellaneous 139 "R_ARM_GNU_VTENTRY", //100 Deprecated Data ??? 140 "R_ARM_GNU_VTINHERIT", //101 Deprecated Data ??? 141 "R_ARM_THM_JUMP11", //102 Static Thumb16 S + A ? P 142 "R_ARM_THM_JUMP8", //103 Static Thumb16 S + A ? P 143 "R_ARM_TLS_GD32", //104 Static Data GOT(S) + A ? P 144 "R_ARM_TLS_LDM32", //105 Static Data GOT(S) + A ? P 145 "R_ARM_TLS_LDO32", //106 Static Data S + A ? TLS 146 "R_ARM_TLS_IE32", //107 Static Data GOT(S) + A ? P 147 "R_ARM_TLS_LE32", //108 Static Data S + A ? tp 148 "R_ARM_TLS_LDO12", //109 Static ARM S + A ? TLS 149 "R_ARM_TLS_LE12", //110 Static ARM S + A ? tp 150 "R_ARM_TLS_IE12GP", //111 Static ARM GOT(S) + A ? GOT_ORG 151 }; 152 #endif 153 154 155 #ifndef _BOOT_MODE 156 static bool 157 is_in_image(struct elf_image_info *image, addr_t address) 158 { 159 return (address >= image->text_region.start 160 && address < image->text_region.start + image->text_region.size) 161 || (address >= image->data_region.start 162 && address < image->data_region.start + image->data_region.size); 163 } 164 #endif // !_BOOT_MODE 165 166 167 #ifdef _BOOT_MODE 168 status_t 169 boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image, Elf32_Rel *rel, 170 int relLength) 171 #else 172 int 173 arch_elf_relocate_rel(struct elf_image_info *image, 174 struct elf_image_info *resolveImage, Elf32_Rel *rel, int relLength) 175 #endif 176 { 177 elf_addr S; 178 addr_t A; 179 addr_t P; 180 addr_t finalAddress; 181 addr_t *resolveAddress; 182 int i; 183 184 S = A = P = 0; 185 186 for (i = 0; i * (int)sizeof(Elf32_Rel) < relLength; i++) { 187 TRACE(("looking at rel type %s, offset 0x%lx\n", 188 kRelocations[ELF32_R_TYPE(rel[i].r_info)], rel[i].r_offset)); 189 190 // calc S 191 switch (ELF32_R_TYPE(rel[i].r_info)) { 192 case R_ARM_JMP_SLOT: 193 case R_ARM_GLOB_DAT: 194 case R_ARM_ABS32: 195 { 196 Elf32_Sym *symbol; 197 status_t status; 198 199 symbol = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); 200 201 #ifdef _BOOT_MODE 202 status = boot_elf_resolve_symbol(image, symbol, &S); 203 #else 204 status = elf_resolve_symbol(image, symbol, resolveImage, &S); 205 #endif 206 if (status < B_OK) { 207 #ifndef _BOOT_MODE 208 TRACE(("failed relocating %s\n", SYMNAME(image, symbol))); 209 #endif 210 //IRA return status; 211 return B_OK; 212 } 213 #ifndef _BOOT_MODE 214 TRACE(("S %p (%s)\n", (void *)S, SYMNAME(image, symbol))); 215 #endif 216 } 217 } 218 219 // calc A 220 switch (ELF32_R_TYPE(rel[i].r_info)) { 221 case R_ARM_ABS32: 222 case R_ARM_RELATIVE: 223 #ifndef _BOOT_MODE 224 A = *(addr_t *)(image->text_region.delta + rel[i].r_offset); 225 #else 226 A = boot_elf32_get_relocation(image->text_region.delta + rel[i].r_offset); 227 #endif 228 TRACE(("A %p\n", (void *)A)); 229 break; 230 } 231 232 switch (ELF32_R_TYPE(rel[i].r_info)) { 233 case R_ARM_NONE: 234 continue; 235 case R_ARM_RELATIVE: 236 // B + A; 237 finalAddress = image->text_region.delta + A; 238 break; 239 case R_ARM_JMP_SLOT: 240 case R_ARM_GLOB_DAT: 241 finalAddress = S; 242 break; 243 case R_ARM_ABS32: 244 finalAddress = S + A; 245 break; 246 default: 247 dprintf("arch_elf_relocate_rel: unhandled relocation type %d\n", 248 ELF32_R_TYPE(rel[i].r_info)); 249 return B_BAD_DATA; 250 } 251 252 resolveAddress = (addr_t *)(image->text_region.delta + rel[i].r_offset); 253 #ifndef _BOOT_MODE 254 if (!is_in_image(image, (addr_t)resolveAddress)) { 255 dprintf("arch_elf_relocate_rel: invalid offset %#lx\n", 256 rel[i].r_offset); 257 return B_BAD_ADDRESS; 258 } 259 *resolveAddress = finalAddress; 260 #else 261 boot_elf32_set_relocation((Elf32_Addr)resolveAddress, finalAddress); 262 #endif 263 TRACE(("-> offset %#lx = %#lx\n", 264 (image->text_region.delta + rel[i].r_offset), finalAddress)); 265 } 266 267 return B_NO_ERROR; 268 } 269 270 271 static inline void 272 write_32(addr_t P, Elf32_Word value) 273 { 274 *(Elf32_Word*)P = value; 275 } 276 277 278 static inline void 279 write_16(addr_t P, Elf32_Word value) 280 { 281 // bits 16:29 282 *(Elf32_Half*)P = (Elf32_Half)value; 283 } 284 285 286 static inline bool 287 write_16_check(addr_t P, Elf32_Word value) 288 { 289 // bits 15:0 290 if ((value & 0xffff0000) && (~value & 0xffff8000)) 291 return false; 292 *(Elf32_Half*)P = (Elf32_Half)value; 293 return true; 294 } 295 296 297 static inline bool 298 write_8(addr_t P, Elf32_Word value) 299 { 300 // bits 7:0 301 *(uint8 *)P = (uint8)value; 302 return true; 303 } 304 305 306 static inline bool 307 write_8_check(addr_t P, Elf32_Word value) 308 { 309 // bits 7:0 310 if ((value & 0xffffff00) && (~value & 0xffffff80)) 311 return false; 312 *(uint8 *)P = (uint8)value; 313 return true; 314 } 315 316 317 #ifdef _BOOT_MODE 318 status_t 319 boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image, 320 Elf32_Rela *rel, int rel_len) 321 #else 322 int 323 arch_elf_relocate_rela(struct elf_image_info *image, 324 struct elf_image_info *resolve_image, Elf32_Rela *rel, int rel_len) 325 #endif 326 { 327 int i; 328 Elf32_Sym *sym; 329 int vlErr; 330 elf_addr S = 0; // symbol address 331 addr_t R = 0; // section relative symbol address 332 333 addr_t G = 0; // GOT address 334 addr_t L = 0; // PLT address 335 336 #define P ((addr_t)(image->text_region.delta + rel[i].r_offset)) 337 #define A ((addr_t)rel[i].r_addend) 338 #define B (image->text_region.delta) 339 #warning ARM:define T correctly for thumb!!! 340 #define T 0 341 342 // TODO: Get the GOT address! 343 #define REQUIRE_GOT \ 344 if (G == 0) { \ 345 dprintf("arch_elf_relocate_rela(): Failed to get GOT address!\n"); \ 346 return B_ERROR; \ 347 } 348 349 // TODO: Get the PLT address! 350 #define REQUIRE_PLT \ 351 if (L == 0) { \ 352 dprintf("arch_elf_relocate_rela(): Failed to get PLT address!\n"); \ 353 return B_ERROR; \ 354 } 355 356 for (i = 0; i * (int)sizeof(Elf32_Rela) < rel_len; i++) { 357 #if CHATTY 358 dprintf("looking at rel type %d, offset 0x%lx, " 359 "sym 0x%lx, addend 0x%lx\n", ELF32_R_TYPE(rel[i].r_info), 360 rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), rel[i].r_addend); 361 #endif 362 switch (ELF32_R_TYPE(rel[i].r_info)) { 363 #warning ARM:ADDOTHERREL 364 case R_ARM_GLOB_DAT: 365 sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); 366 367 #ifdef _BOOT_MODE 368 vlErr = boot_elf_resolve_symbol(image, sym, &S); 369 #else 370 vlErr = elf_resolve_symbol(image, sym, resolve_image, &S); 371 #endif 372 if (vlErr < 0) { 373 dprintf("%s(): Failed to relocate " 374 "entry index %d, rel type %d, offset 0x%lx, sym 0x%lx, " 375 "addend 0x%lx\n", __FUNCTION__, i, 376 ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, 377 ELF32_R_SYM(rel[i].r_info), rel[i].r_addend); 378 return vlErr; 379 } 380 break; 381 } 382 383 #warning ARM:ADDOTHERREL 384 switch (ELF32_R_TYPE(rel[i].r_info)) { 385 case R_ARM_GLOB_DAT: 386 write_32(P, (S + A) | T); 387 break; 388 389 case R_ARM_NONE: 390 break; 391 392 default: 393 dprintf("arch_elf_relocate_rela(): unhandled " 394 "relocation type %d!\n", ELF32_R_TYPE(rel[i].r_info)); 395 return B_ERROR; 396 } 397 } 398 399 #warning ARM: FIXME!!!!!!! 400 return B_NO_ERROR; 401 } 402