diff --git a/fdpp/elf.c b/fdpp/elf.c index f2e2adf6..f2884528 100644 --- a/fdpp/elf.c +++ b/fdpp/elf.c @@ -181,3 +181,9 @@ void *elf_getloadaddr(void *arg) struct elfstate *state = (struct elfstate *)arg; return state->addr + state->load_offs; } + +int elf_getloadoff(void *arg) +{ + struct elfstate *state = (struct elfstate *)arg; + return state->load_offs; +} diff --git a/fdpp/elf_priv.h b/fdpp/elf_priv.h index 03d519e2..e26a53e1 100644 --- a/fdpp/elf_priv.h +++ b/fdpp/elf_priv.h @@ -4,3 +4,4 @@ void elf_close(void *arg); void *elf_getsym(void *arg, const char *name); int elf_getsymoff(void *arg, const char *name); void *elf_getloadaddr(void *arg); +int elf_getloadoff(void *arg); diff --git a/fdpp/thunks.cc b/fdpp/thunks.cc index 8908a470..6a6f391f 100644 --- a/fdpp/thunks.cc +++ b/fdpp/thunks.cc @@ -711,11 +711,15 @@ void *FdppKernelLoad(const char *dname, int *len, struct fdpp_bss_list **bss, return NULL; } -const void *FdppKernelReloc(void *handle, uint16_t seg) +const void *FdppKernelReloc(void *handle, uint16_t seg, uint16_t *r_seg) { int i; far_s f; struct krnl_hndl *h = (struct krnl_hndl *)handle; + unsigned load_off = elf_getloadoff(h->elf); + + assert(!(load_off & 0xf)); + seg -= load_off >> 4; elf_reloc(h->elf, seg); farhlp_init(&sym_tab); @@ -743,6 +747,7 @@ const void *FdppKernelReloc(void *handle, uint16_t seg) f.off = elf_getsymoff(h->elf, "init_near_wrp"); near_wrp[1] = f; + *r_seg = seg; return h->start; } diff --git a/include/fdpp/thunks.h b/include/fdpp/thunks.h index c50f8bde..bf6805f4 100644 --- a/include/fdpp/thunks.h +++ b/include/fdpp/thunks.h @@ -23,7 +23,7 @@ #include #include -#define FDPP_API_VER 33 +#define FDPP_API_VER 34 #ifndef FDPP struct fdpp_far_s { @@ -87,7 +87,7 @@ struct fdpp_bss_list { void *FdppKernelLoad(const char *dname, int *len, struct fdpp_bss_list **bss, uint32_t *_start); -const void *FdppKernelReloc(void *handle, uint16_t seg); +const void *FdppKernelReloc(void *handle, uint16_t seg, uint16_t *r_seg); void FdppKernelFree(void *handle); #ifdef __cplusplus