vxBoot/src/loader/elf/got.c

64 lines
1.6 KiB
C

#include "vxBoot/loader.h"
#include "vxBoot/terminal.h"
#include <string.h>
/* loader_get_symbols() : get symbols information */
static void *loader_get_symbol(
struct kernel * restrict const kernel,
char const * restrict const name
) {
char * strtab;
uintptr_t sym;
strtab = kernel->elf.strtab;
for (int i = 0 ; i < kernel->elf.sym.nb ; ++i) {
if (strcmp(&strtab[kernel->elf.sym.tab[i].st_name], name) != 0)
continue;
sym = (uintptr_t)kernel->elf.sym.tab[i].st_value;
sym += (uintptr_t)kernel->hardware.ram.physical.kernel_addr;
sym |= (uintptr_t)0xa0000000;
return((void*)sym);
}
return (NULL);
}
/* loader_got_patch() : Try to patch the GOT/PLT section */
int loader_got_patch(struct kernel * const kernel)
{
uintptr_t *__got__;
uintptr_t addr;
uintptr_t got;
/* first, try to find the _GLOBAL_OFFSET_TABLE_ symbol */
__got__ = loader_get_symbol(kernel, "_GLOBAL_OFFSET_TABLE_");
if (__got__ == NULL) {
terminal_log(
LOG_NOTICE,
"_GLOBAL_OFFSET_TABLE_ not found...\n"
);
return (0);
}
got = (uintptr_t)kernel->elf.got;
got += (uintptr_t)kernel->hardware.ram.physical.kernel_addr;
got |= (uintptr_t)0xa0000000;
/* perform transation */
terminal_log(LOG_DEBUG, " _GOT_ found at %p...\n", __got__);
terminal_log(LOG_DEBUG, " .got found at %p...\n", got);
for (int i = 0 ; i < kernel->elf.got_nb ; ++i) {
terminal_log(
LOG_DEBUG,
" patch symbols %p...\n",
((uintptr_t*)got)[i]
);
addr = ((uintptr_t*)got)[i];
addr += (uintptr_t)kernel->hardware.ram.physical.kernel_addr;
addr |= (uintptr_t)0x80000000;
__got__[i] = addr;
}
return (0);
}