runtimer_loader/arm: implement relocations
Change-Id: Ibda978e37d6dbdaf33ac054adbbda70768fe0d97 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4975 Tested-by: Commit checker robot <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
f98f9bccb8
commit
24b174f4f9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012, Haiku, Inc.
|
||||
* Copyright 2012-2022, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -16,15 +16,92 @@
|
||||
|
||||
//#define TRACE_RLD
|
||||
#ifdef TRACE_RLD
|
||||
# define TRACE(x) dprintf x
|
||||
# define TRACE(x...) dprintf(x)
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
# define TRACE(x...) ;
|
||||
#endif
|
||||
|
||||
|
||||
static int
|
||||
relocate_rel(image_t *rootImage, image_t *image, Elf32_Rel *rel, int rel_len,
|
||||
SymbolLookupCache* cache)
|
||||
{
|
||||
# define P ((addr_t *)(image->regions[0].delta + rel[i].r_offset))
|
||||
# define A (*(P))
|
||||
# define B (image->regions[0].delta)
|
||||
|
||||
for (int i = 0; i * (int)sizeof(Elf32_Rel) < rel_len; i++) {
|
||||
unsigned type = ELF32_R_TYPE(rel[i].r_info);
|
||||
unsigned symbolIndex = ELF32_R_SYM(rel[i].r_info);
|
||||
addr_t final_val;
|
||||
addr_t S;
|
||||
|
||||
image_t* symbolImage = NULL;
|
||||
if (symbolIndex != 0) {
|
||||
Elf32_Sym* sym = SYMBOL(image, symbolIndex);
|
||||
status_t status = resolve_symbol(rootImage, image, sym, cache, &S,
|
||||
&symbolImage);
|
||||
if (status < B_OK) {
|
||||
TRACE("resolve symbol \"%s\" returned: %ld\n",
|
||||
SYMNAME(image, sym), status);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case R_ARM_NONE:
|
||||
continue;
|
||||
case R_ARM_RELATIVE:
|
||||
final_val = B + A;
|
||||
break;
|
||||
case R_ARM_JMP_SLOT:
|
||||
case R_ARM_GLOB_DAT:
|
||||
final_val = S;
|
||||
break;
|
||||
case R_ARM_ABS32:
|
||||
final_val = S + A;
|
||||
break;
|
||||
default:
|
||||
TRACE("unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info));
|
||||
return B_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
*P = final_val;
|
||||
}
|
||||
|
||||
# undef P
|
||||
# undef A
|
||||
# undef B
|
||||
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
arch_relocate_image(image_t *rootImage, image_t *image,
|
||||
SymbolLookupCache* cache)
|
||||
{
|
||||
debugger("arch_relocate_image: Not Yet Implemented!");
|
||||
status_t status;
|
||||
|
||||
// deal with the rels first
|
||||
if (image->rel) {
|
||||
status = relocate_rel(rootImage, image, image->rel, image->rel_len,
|
||||
cache);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (image->pltrel) {
|
||||
status = relocate_rel(rootImage, image, image->pltrel,
|
||||
image->pltrel_len, cache);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (image->rela) {
|
||||
TRACE("RELA relocations not supported\n");
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user