64 lines
1.6 KiB
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);
|
|
}
|