* ARM: Initial stab at fixing ELF relocations (much more to do though for full ELF relocation support).

We now boot right up to "INIT: main: done... begin idle loop on cpu 0" ! :)
(Please note that there's still *lots* stubbed out)



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39219 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ithamar R. Adema 2010-10-30 22:53:32 +00:00
parent f3a3804efa
commit c9a4637342

View File

@ -146,17 +146,97 @@ static const char *kRelocations[] = {
};
#endif
#ifndef _BOOT_MODE
static bool
is_in_image(struct elf_image_info *image, addr_t address)
{
return (address >= image->text_region.start
&& address < image->text_region.start + image->text_region.size)
|| (address >= image->data_region.start
&& address < image->data_region.start + image->data_region.size);
}
#endif // !_BOOT_MODE
#ifdef _BOOT_MODE
status_t
boot_arch_elf_relocate_rel(struct preloaded_image *image,
struct Elf32_Rel *rel, int rel_len)
struct Elf32_Rel *rel, int relLength)
#else
int
arch_elf_relocate_rel(struct elf_image_info *image,
struct elf_image_info *resolve_image, struct Elf32_Rel *rel, int rel_len)
struct elf_image_info *resolveImage, struct Elf32_Rel *rel, int relLength)
#endif
{
// there are no rel entries in M68K elf
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:
{
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
}
}
switch (ELF32_R_TYPE(rel[i].r_info)) {
case R_ARM_NONE:
continue;
case R_ARM_JMP_SLOT:
case R_ARM_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 = (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;
}