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.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -16,15 +16,92 @@
|
|||||||
|
|
||||||
//#define TRACE_RLD
|
//#define TRACE_RLD
|
||||||
#ifdef TRACE_RLD
|
#ifdef TRACE_RLD
|
||||||
# define TRACE(x) dprintf x
|
# define TRACE(x...) dprintf(x)
|
||||||
#else
|
#else
|
||||||
# define TRACE(x) ;
|
# define TRACE(x...) ;
|
||||||
#endif
|
#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
|
status_t
|
||||||
arch_relocate_image(image_t *rootImage, image_t *image,
|
arch_relocate_image(image_t *rootImage, image_t *image,
|
||||||
SymbolLookupCache* cache)
|
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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user