int arch_elf_relocate_rela(struct elf_image_info *image, struct elf_image_info *resolve_image, struct Elf32_Rela *rel, int rel_len) #endif { int i; struct Elf32_Sym *sym; int vlErr; addr_t S = 0; // symbol address addr_t R = 0; // section relative symbol address addr_t G = 0; // GOT address addr_t L = 0; // PLT address #define P ((addr_t)(image->text_region.delta + rel[i].r_offset)) #define A ((addr_t)rel[i].r_addend) #define B (image->text_region.delta) #warning ARM:define T correctly for thumb!!! #define T 0 // TODO: Get the GOT address! #define REQUIRE_GOT \ if (G == 0) { \ dprintf("arch_elf_relocate_rela(): Failed to get GOT address!\n"); \ return B_ERROR; \ } // TODO: Get the PLT address! #define REQUIRE_PLT \ if (L == 0) { \ dprintf("arch_elf_relocate_rela(): Failed to get PLT address!\n"); \ return B_ERROR; \ } for (i = 0; i * (int)sizeof(struct Elf32_Rela) < rel_len; i++) { #if CHATTY dprintf("looking at rel type %d, offset 0x%lx, " "sym 0x%lx, addend 0x%lx\n", ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), rel[i].r_addend); #endif switch (ELF32_R_TYPE(rel[i].r_info)) { #warning ARM:ADDOTHERREL case R_ARM_GLOB_DAT: sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); #ifdef _BOOT_MODE vlErr = boot_elf_resolve_symbol(image, sym, &S); #else vlErr = elf_resolve_symbol(image, sym, resolve_image, &S); #endif if (vlErr < 0) { dprintf("%s(): Failed to relocate " "entry index %d, rel type %d, offset 0x%lx, sym 0x%lx, " "addend 0x%lx\n", __FUNCTION__, i, ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), rel[i].r_addend); return vlErr; } break; } #warning ARM:ADDOTHERREL switch (ELF32_R_TYPE(rel[i].r_info)) { case R_ARM_GLOB_DAT: write_32(P, (S + A) | T); break; case R_ARM_NONE: break; default: dprintf("arch_elf_relocate_rela(): unhandled " "relocation type %d!\n", ELF32_R_TYPE(rel[i].r_info)); return B_ERROR; } } #warning ARM: FIXME!!!!!!! return B_NO_ERROR; }
int arch_elf_relocate_rel(struct elf_image_info *image, struct elf_image_info *resolveImage, struct Elf32_Rel *rel, int relLength) #endif { addr_t S; addr_t A; addr_t P; addr_t finalAddress; addr_t *resolveAddress; int i; S = A = P = 0; for (i = 0; i * (int)sizeof(struct Elf32_Rel) < relLength; i++) { TRACE(("looking at rel type %s, offset 0x%lx\n", kRelocations[ELF32_R_TYPE(rel[i].r_info)], rel[i].r_offset)); // calc S switch (ELF32_R_TYPE(rel[i].r_info)) { case R_ARM_JMP_SLOT: case R_ARM_GLOB_DAT: case R_ARM_ABS32: { struct Elf32_Sym *symbol; status_t status; symbol = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); #ifdef _BOOT_MODE status = boot_elf_resolve_symbol(image, symbol, &S); #else status = elf_resolve_symbol(image, symbol, resolveImage, &S); #endif if (status < B_OK) { #ifndef _BOOT_MODE TRACE(("failed relocating %s\n", SYMNAME(image, symbol))); #endif //IRA return status; return B_OK; } #ifndef _BOOT_MODE TRACE(("S %p (%s)\n", (void *)S, SYMNAME(image, symbol))); #endif } } // calc A switch (ELF32_R_TYPE(rel[i].r_info)) { case R_ARM_ABS32: case R_ARM_RELATIVE: A = *(addr_t *)(image->text_region.delta + rel[i].r_offset); TRACE(("A %p\n", (void *)A)); break; } switch (ELF32_R_TYPE(rel[i].r_info)) { case R_ARM_NONE: continue; case R_ARM_RELATIVE: // B + A; finalAddress = image->text_region.delta + A; break; case R_ARM_JMP_SLOT: case R_ARM_GLOB_DAT: finalAddress = S; break; case R_ARM_ABS32: finalAddress = S + A; break; default: dprintf("arch_elf_relocate_rel: unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info)); return B_BAD_DATA; } resolveAddress = (addr_t *)(image->text_region.delta + rel[i].r_offset); #ifndef _BOOT_MODE if (!is_in_image(image, (addr_t)resolveAddress)) { dprintf("arch_elf_relocate_rel: invalid offset %#lx\n", rel[i].r_offset); return B_BAD_ADDRESS; } #endif *resolveAddress = finalAddress; TRACE(("-> offset %#lx = %#lx\n", (image->text_region.delta + rel[i].r_offset), finalAddress)); } return B_NO_ERROR; }
int arch_elf_relocate_rel(struct elf_image_info *image, struct elf_image_info *resolveImage, Elf32_Rel *rel, int relLength) #endif { elf_addr S; uint32 A; uint32 P; uint32 finalAddress; uint32 *resolveAddress; int i; S = A = P = 0; for (i = 0; i * (int)sizeof(Elf32_Rel) < relLength; i++) { TRACE(("looking at rel type %s, offset 0x%lx\n", kRelocations[ELF32_R_TYPE(rel[i].r_info)], rel[i].r_offset)); // calc S switch (ELF32_R_TYPE(rel[i].r_info)) { case R_386_32: case R_386_PC32: case R_386_GLOB_DAT: case R_386_JMP_SLOT: case R_386_GOTOFF: { Elf32_Sym *symbol; status_t status; symbol = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); #ifdef _BOOT_MODE status = boot_elf_resolve_symbol(image, symbol, &S); #else status = elf_resolve_symbol(image, symbol, resolveImage, &S); #endif if (status < B_OK) return status; TRACE(("S %p (%s)\n", (void *)S, SYMNAME(image, symbol))); } } // calc A switch (ELF32_R_TYPE(rel[i].r_info)) { case R_386_32: case R_386_PC32: case R_386_GOT32: case R_386_PLT32: case R_386_RELATIVE: case R_386_GOTOFF: case R_386_GOTPC: A = *(uint32 *)(image->text_region.delta + rel[i].r_offset); TRACE(("A %p\n", (void *)A)); break; } // calc P switch (ELF32_R_TYPE(rel[i].r_info)) { case R_386_PC32: case R_386_GOT32: case R_386_PLT32: case R_386_GOTPC: P = image->text_region.delta + rel[i].r_offset; TRACE(("P %p\n", (void *)P)); break; } switch (ELF32_R_TYPE(rel[i].r_info)) { case R_386_NONE: continue; case R_386_32: finalAddress = S + A; break; case R_386_PC32: finalAddress = S + A - P; break; case R_386_RELATIVE: // B + A; finalAddress = image->text_region.delta + A; break; case R_386_JMP_SLOT: case R_386_GLOB_DAT: finalAddress = S; break; default: dprintf("arch_elf_relocate_rel: unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info)); return B_BAD_DATA; } resolveAddress = (uint32 *)(image->text_region.delta + rel[i].r_offset); #ifndef _BOOT_MODE if (!is_in_image(image, (addr_t)resolveAddress)) { dprintf("arch_elf_relocate_rel: invalid offset %#lx\n", rel[i].r_offset); return B_BAD_ADDRESS; } #endif *resolveAddress = finalAddress; TRACE(("-> offset %#lx (%#lx) = %#lx\n", (image->text_region.delta + rel[i].r_offset), rel[i].r_offset, finalAddress)); } return B_NO_ERROR; }
int arch_elf_relocate_rela(struct elf_image_info *image, struct elf_image_info *resolveImage, Elf64_Rela *rel, int relLength) #endif { for (int i = 0; i < relLength / (int)sizeof(Elf64_Rela); i++) { int type = ELF64_R_TYPE(rel[i].r_info); int symIndex = ELF64_R_SYM(rel[i].r_info); Elf64_Addr symAddr = 0; // Resolve the symbol, if any. if (symIndex != 0) { Elf64_Sym* symbol = SYMBOL(image, symIndex); status_t status; #ifdef _BOOT_MODE status = boot_elf_resolve_symbol(image, symbol, &symAddr); #else status = elf_resolve_symbol(image, symbol, resolveImage, &symAddr); #endif if (status < B_OK) return status; } // Address of the relocation. Elf64_Addr relocAddr = image->text_region.delta + rel[i].r_offset; // Calculate the relocation value. Elf64_Addr relocValue; switch (type) { case R_X86_64_NONE: continue; case R_X86_64_64: relocValue = symAddr + rel[i].r_addend; break; case R_X86_64_PC32: relocValue = symAddr + rel[i].r_addend - rel[i].r_offset; break; case R_X86_64_GLOB_DAT: case R_X86_64_JUMP_SLOT: relocValue = symAddr + rel[i].r_addend; break; case R_X86_64_RELATIVE: relocValue = image->text_region.delta + rel[i].r_addend; break; default: dprintf("arch_elf_relocate_rela: unhandled relocation type %d\n", type); return B_BAD_DATA; } #ifdef _BOOT_MODE boot_elf64_set_relocation(relocAddr, relocValue); #else if (!is_in_image(image, relocAddr)) { dprintf("arch_elf_relocate_rela: invalid offset %#lx\n", rel[i].r_offset); return B_BAD_ADDRESS; } if (type == R_X86_64_PC32) *(Elf32_Addr *)relocAddr = relocValue; else *(Elf64_Addr *)relocAddr = relocValue; #endif } return B_OK; }
int arch_elf_relocate_rela(struct elf_image_info *image, struct elf_image_info *resolve_image, struct Elf32_Rela *rel, int rel_len) #endif { int i; struct Elf32_Sym *sym; int vlErr; addr_t S = 0; // symbol address addr_t R = 0; // section relative symbol address addr_t G = 0; // GOT address addr_t L = 0; // PLT address #define P ((addr_t)(image->text_region.delta + rel[i].r_offset)) #define A ((addr_t)rel[i].r_addend) #define B (image->text_region.delta) // TODO: Get the GOT address! #define REQUIRE_GOT \ if (G == 0) { \ dprintf("arch_elf_relocate_rela(): Failed to get GOT address!\n"); \ return B_ERROR; \ } // TODO: Get the PLT address! #define REQUIRE_PLT \ if (L == 0) { \ dprintf("arch_elf_relocate_rela(): Failed to get PLT address!\n"); \ return B_ERROR; \ } for (i = 0; i * (int)sizeof(struct Elf32_Rela) < rel_len; i++) { #if CHATTY dprintf("looking at rel type %d, offset 0x%lx, sym 0x%lx, addend 0x%lx\n", ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), rel[i].r_addend); #endif switch (ELF32_R_TYPE(rel[i].r_info)) { case R_68K_32: case R_68K_16: case R_68K_8: case R_68K_PC32: case R_68K_PC16: case R_68K_PC8: case R_68K_GLOB_DAT: case R_68K_JMP_SLOT: sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); #ifdef _BOOT_MODE vlErr = boot_elf_resolve_symbol(image, sym, &S); #else vlErr = elf_resolve_symbol(image, sym, resolve_image, &S); #endif if (vlErr < 0) { dprintf("%s(): Failed to relocate " "entry index %d, rel type %d, offset 0x%lx, sym 0x%lx, " "addend 0x%lx\n", __FUNCTION__, i, ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), rel[i].r_addend); return vlErr; } break; } switch (ELF32_R_TYPE(rel[i].r_info)) { case R_68K_NONE: break; case R_68K_COPY: // TODO: Implement! dprintf("arch_elf_relocate_rela(): R_68K_COPY not yet " "supported!\n"); return B_ERROR; case R_68K_32: case R_68K_GLOB_DAT: write_32(P, S + A); break; case R_68K_16: if (write_16_check(P, S + A)) break; dprintf("R_68K_16 overflow\n"); return B_BAD_DATA; case R_68K_8: if (write_8_check(P, S + A)) break; dprintf("R_68K_8 overflow\n"); return B_BAD_DATA; case R_68K_PC32: write_32(P, (S + A - P)); break; case R_68K_PC16: if (write_16_check(P, (S + A - P))) break; dprintf("R_68K_PC16 overflow\n"); return B_BAD_DATA; case R_68K_PC8: if (write_8(P, (S + A - P))) break; dprintf("R_68K_PC8 overflow\n"); return B_BAD_DATA; case R_68K_GOT32: REQUIRE_GOT; write_32(P, (G + A - P)); break; case R_68K_GOT16: REQUIRE_GOT; if (write_16_check(P, (G + A - P))) break; dprintf("R_68K_GOT16 overflow\n"); return B_BAD_DATA; case R_68K_GOT8: REQUIRE_GOT; if (write_8_check(P, (G + A - P))) break; dprintf("R_68K_GOT8 overflow\n"); return B_BAD_DATA; case R_68K_GOT32O: REQUIRE_GOT; write_32(P, (G + A)); break; case R_68K_GOT16O: REQUIRE_GOT; if (write_16_check(P, (G + A))) break; dprintf("R_68K_GOT16 overflow\n"); return B_BAD_DATA; case R_68K_GOT8O: REQUIRE_GOT; if (write_8_check(P, (G + A))) break; dprintf("R_68K_GOT8 overflow\n"); return B_BAD_DATA; case R_68K_JMP_SLOT: write_32(P, (G + A)); break; case R_68K_RELATIVE: write_32(P, B + A); break; case R_68K_PLT32: REQUIRE_PLT; write_32(P, (L + A - P)); break; case R_68K_PLT16: REQUIRE_PLT; if (write_16_check(P, (L + A - P))) break; dprintf("R_68K_PLT16 overflow\n"); return B_BAD_DATA; case R_68K_PLT8: REQUIRE_PLT; if (write_8_check(P, (L + A - P))) break; dprintf("R_68K_PLT8 overflow\n"); return B_BAD_DATA; case R_68K_PLT32O: REQUIRE_PLT; write_32(P, (L + A)); break; case R_68K_PLT16O: REQUIRE_PLT; if (write_16_check(P, (L + A))) break; dprintf("R_68K_PLT16O overflow\n"); return B_BAD_DATA; case R_68K_PLT8O: REQUIRE_PLT; if (write_8_check(P, (L + A))) break; dprintf("R_68K_PLT8O overflow\n"); return B_BAD_DATA; default: dprintf("arch_elf_relocate_rela: unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info)); return B_ERROR; } } return B_NO_ERROR; }
int arch_elf_relocate_rel(struct elf_image_info *image, const char *sym_prepend, struct elf_image_info *resolve_image, struct Elf32_Rel *rel, int rel_len) { int i; struct Elf32_Sym *sym; int vlErr; addr_t S; addr_t A; addr_t P; addr_t final_val; S = A = P = 0; for(i = 0; i * (int)sizeof(struct Elf32_Rel) < rel_len; i++) { //dprintf("looking at rel type %d, offset 0x%x\n", ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset); // calc S switch(ELF32_R_TYPE(rel[i].r_info)) { case R_386_32: case R_386_PC32: case R_386_GLOB_DAT: case R_386_JMP_SLOT: case R_386_GOTOFF: sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); vlErr = elf_resolve_symbol(image, sym, resolve_image, sym_prepend, &S); if(vlErr<0) return vlErr; //dprintf("S 0x%x\n", S); } // calc A switch(ELF32_R_TYPE(rel[i].r_info)) { case R_386_32: case R_386_PC32: case R_386_GOT32: case R_386_PLT32: case R_386_RELATIVE: case R_386_GOTOFF: case R_386_GOTPC: A = *(addr_t *)(image->regions[0].delta + rel[i].r_offset); // dprintf("A 0x%x\n", A); break; } // calc P switch(ELF32_R_TYPE(rel[i].r_info)) { case R_386_PC32: case R_386_GOT32: case R_386_PLT32: case R_386_GOTPC: P = image->regions[0].delta + rel[i].r_offset; // dprintf("P 0x%x\n", P); break; } switch(ELF32_R_TYPE(rel[i].r_info)) { case R_386_NONE: continue; case R_386_32: final_val = S + A; break; case R_386_PC32: final_val = S + A - P; break; case R_386_RELATIVE: // B + A; final_val = image->regions[0].delta + A; break; case R_386_JMP_SLOT: final_val = S; //dprintf( "final = %lx\n", final_val ); break; default: dprintf("arch_elf_relocate_rel: unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info)); return ERR_NOT_ALLOWED; } *(addr_t *)(image->regions[0].delta + rel[i].r_offset) = final_val; } return NO_ERROR; }