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 A = *(addr_t *)(image->text_region.delta + rel[i].r_offset); 224 TRACE(("A %p\n", (void *)A)); 225 break; 226 } 227 228 switch (ELF32_R_TYPE(rel[i].r_info)) { 229 case R_ARM_NONE: 230 continue; 231 case R_ARM_RELATIVE: 232 // B + A; 233 finalAddress = image->text_region.delta + A; 234 break; 235 case R_ARM_JMP_SLOT: 236 case R_ARM_GLOB_DAT: 237 finalAddress = S; 238 break; 239 case R_ARM_ABS32: 240 finalAddress = S + A; 241 break; 242 default: 243 dprintf("arch_elf_relocate_rel: unhandled relocation type %d\n", 244 ELF32_R_TYPE(rel[i].r_info)); 245 return B_BAD_DATA; 246 } 247 248 resolveAddress = (addr_t *)(image->text_region.delta + rel[i].r_offset); 249 #ifndef _BOOT_MODE 250 if (!is_in_image(image, (addr_t)resolveAddress)) { 251 dprintf("arch_elf_relocate_rel: invalid offset %#lx\n", 252 rel[i].r_offset); 253 return B_BAD_ADDRESS; 254 } 255 #endif 256 *resolveAddress = finalAddress; 257 TRACE(("-> offset %#lx = %#lx\n", 258 (image->text_region.delta + rel[i].r_offset), finalAddress)); 259 } 260 261 return B_NO_ERROR; 262 } 263 264 265 static inline void 266 write_32(addr_t P, Elf32_Word value) 267 { 268 *(Elf32_Word*)P = value; 269 } 270 271 272 static inline void 273 write_16(addr_t P, Elf32_Word value) 274 { 275 // bits 16:29 276 *(Elf32_Half*)P = (Elf32_Half)value; 277 } 278 279 280 static inline bool 281 write_16_check(addr_t P, Elf32_Word value) 282 { 283 // bits 15:0 284 if ((value & 0xffff0000) && (~value & 0xffff8000)) 285 return false; 286 *(Elf32_Half*)P = (Elf32_Half)value; 287 return true; 288 } 289 290 291 static inline bool 292 write_8(addr_t P, Elf32_Word value) 293 { 294 // bits 7:0 295 *(uint8 *)P = (uint8)value; 296 return true; 297 } 298 299 300 static inline bool 301 write_8_check(addr_t P, Elf32_Word value) 302 { 303 // bits 7:0 304 if ((value & 0xffffff00) && (~value & 0xffffff80)) 305 return false; 306 *(uint8 *)P = (uint8)value; 307 return true; 308 } 309 310 311 #ifdef _BOOT_MODE 312 status_t 313 boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image, 314 Elf32_Rela *rel, int rel_len) 315 #else 316 int 317 arch_elf_relocate_rela(struct elf_image_info *image, 318 struct elf_image_info *resolve_image, Elf32_Rela *rel, int rel_len) 319 #endif 320 { 321 int i; 322 Elf32_Sym *sym; 323 int vlErr; 324 elf_addr S = 0; // symbol address 325 addr_t R = 0; // section relative symbol address 326 327 addr_t G = 0; // GOT address 328 addr_t L = 0; // PLT address 329 330 #define P ((addr_t)(image->text_region.delta + rel[i].r_offset)) 331 #define A ((addr_t)rel[i].r_addend) 332 #define B (image->text_region.delta) 333 #warning ARM:define T correctly for thumb!!! 334 #define T 0 335 336 // TODO: Get the GOT address! 337 #define REQUIRE_GOT \ 338 if (G == 0) { \ 339 dprintf("arch_elf_relocate_rela(): Failed to get GOT address!\n"); \ 340 return B_ERROR; \ 341 } 342 343 // TODO: Get the PLT address! 344 #define REQUIRE_PLT \ 345 if (L == 0) { \ 346 dprintf("arch_elf_relocate_rela(): Failed to get PLT address!\n"); \ 347 return B_ERROR; \ 348 } 349 350 for (i = 0; i * (int)sizeof(Elf32_Rela) < rel_len; i++) { 351 #if CHATTY 352 dprintf("looking at rel type %d, offset 0x%lx, " 353 "sym 0x%lx, addend 0x%lx\n", ELF32_R_TYPE(rel[i].r_info), 354 rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), rel[i].r_addend); 355 #endif 356 switch (ELF32_R_TYPE(rel[i].r_info)) { 357 #warning ARM:ADDOTHERREL 358 case R_ARM_GLOB_DAT: 359 sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); 360 361 #ifdef _BOOT_MODE 362 vlErr = boot_elf_resolve_symbol(image, sym, &S); 363 #else 364 vlErr = elf_resolve_symbol(image, sym, resolve_image, &S); 365 #endif 366 if (vlErr < 0) { 367 dprintf("%s(): Failed to relocate " 368 "entry index %d, rel type %d, offset 0x%lx, sym 0x%lx, " 369 "addend 0x%lx\n", __FUNCTION__, i, 370 ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, 371 ELF32_R_SYM(rel[i].r_info), rel[i].r_addend); 372 return vlErr; 373 } 374 break; 375 } 376 377 #warning ARM:ADDOTHERREL 378 switch (ELF32_R_TYPE(rel[i].r_info)) { 379 case R_ARM_GLOB_DAT: 380 write_32(P, (S + A) | T); 381 break; 382 383 case R_ARM_NONE: 384 break; 385 386 default: 387 dprintf("arch_elf_relocate_rela(): unhandled " 388 "relocation type %d!\n", ELF32_R_TYPE(rel[i].r_info)); 389 return B_ERROR; 390 } 391 } 392 393 #warning ARM: FIXME!!!!!!! 394 return B_NO_ERROR; 395 } 396