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