support for registering functions from modules (not tested yet)
This commit is contained in:
parent
daca6c5f45
commit
73911575dd
4 changed files with 54 additions and 13 deletions
|
@ -360,9 +360,22 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
|
||||||
sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
|
sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
|
||||||
sym->st_shndx);
|
sym->st_shndx);
|
||||||
if (bind != STB_LOCAL)
|
if (bind != STB_LOCAL)
|
||||||
if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
|
{
|
||||||
return grub_errno;
|
#ifdef __ia64__
|
||||||
|
/* FIXME: free descriptor once it's not used anymore. */
|
||||||
|
char **desc;
|
||||||
|
desc = grub_malloc (2 * sizeof (char *));
|
||||||
|
if (!desc)
|
||||||
|
return grub_errno;
|
||||||
|
desc[0] = (void *) sym->st_value;
|
||||||
|
desc[1] = mod->gp;
|
||||||
|
if (grub_dl_register_symbol (name, (void *) desc, mod))
|
||||||
|
return grub_errno;
|
||||||
|
#else
|
||||||
|
if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
|
||||||
|
return grub_errno;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
if (grub_strcmp (name, "grub_mod_init") == 0)
|
if (grub_strcmp (name, "grub_mod_init") == 0)
|
||||||
mod->init = sym->st_value;
|
mod->init = sym->st_value;
|
||||||
else if (grub_strcmp (name, "grub_mod_fini") == 0)
|
else if (grub_strcmp (name, "grub_mod_fini") == 0)
|
||||||
|
@ -552,6 +565,7 @@ grub_dl_load_core (void *addr, grub_size_t size)
|
||||||
if (grub_dl_resolve_name (mod, e)
|
if (grub_dl_resolve_name (mod, e)
|
||||||
|| grub_dl_resolve_dependencies (mod, e)
|
|| grub_dl_resolve_dependencies (mod, e)
|
||||||
|| grub_dl_load_segments (mod, e)
|
|| grub_dl_load_segments (mod, e)
|
||||||
|
|| grub_arch_dl_allocate_gp (mod, e)
|
||||||
|| grub_dl_resolve_symbols (mod, e)
|
|| grub_dl_resolve_symbols (mod, e)
|
||||||
|| grub_arch_dl_relocate_symbols (mod, e))
|
|| grub_arch_dl_relocate_symbols (mod, e))
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,4 +56,12 @@ grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
return ~(grub_size_t)0;
|
return ~(grub_size_t)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_arch_dl_allocate_gp (grub_dl_t mod __attribute__ ((unused)),
|
||||||
|
const void *ehdr __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
return GRUB_ERR_BAD_MODULE;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -154,16 +154,13 @@ grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec)
|
||||||
return cnt * sizeof (struct ia64_trampoline);
|
return cnt * sizeof (struct ia64_trampoline);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Relocate symbols. */
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr)
|
||||||
{
|
{
|
||||||
Elf_Ehdr *e = ehdr;
|
|
||||||
Elf_Shdr *s;
|
|
||||||
Elf_Word entsize;
|
|
||||||
unsigned i;
|
|
||||||
grub_uint64_t *gp, *gpptr;
|
|
||||||
grub_size_t gp_size = 0;
|
grub_size_t gp_size = 0;
|
||||||
|
const Elf_Ehdr *e = ehdr;
|
||||||
|
const Elf_Shdr *s;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
||||||
i < e->e_shnum;
|
i < e->e_shnum;
|
||||||
|
@ -199,10 +196,23 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||||
if (gp_size > MASK19)
|
if (gp_size > MASK19)
|
||||||
return grub_error (GRUB_ERR_OUT_OF_RANGE, "gp too big");
|
return grub_error (GRUB_ERR_OUT_OF_RANGE, "gp too big");
|
||||||
|
|
||||||
gpptr = gp = grub_malloc (gp_size);
|
mod->gp = grub_malloc (gp_size);
|
||||||
if (!gp)
|
if (!mod->gp)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
mod->gp = (char *) gp;
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Relocate symbols. */
|
||||||
|
grub_err_t
|
||||||
|
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||||
|
{
|
||||||
|
Elf_Ehdr *e = ehdr;
|
||||||
|
Elf_Shdr *s;
|
||||||
|
Elf_Word entsize;
|
||||||
|
unsigned i;
|
||||||
|
grub_uint64_t *gp, *gpptr;
|
||||||
|
|
||||||
|
gp = gpptr = (grub_uint64_t *) mod->gp;
|
||||||
|
|
||||||
/* Find a symbol table. */
|
/* Find a symbol table. */
|
||||||
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
||||||
|
|
|
@ -124,6 +124,8 @@ void grub_arch_dl_init_linker (void);
|
||||||
|
|
||||||
#ifdef __ia64__
|
#ifdef __ia64__
|
||||||
grub_size_t grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec);
|
grub_size_t grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec);
|
||||||
|
grub_err_t grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr);
|
||||||
|
|
||||||
#define GRUB_ARCH_DL_TRAMP_ALIGN 16
|
#define GRUB_ARCH_DL_TRAMP_ALIGN 16
|
||||||
#else
|
#else
|
||||||
static inline grub_size_t
|
static inline grub_size_t
|
||||||
|
@ -131,6 +133,13 @@ grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)), int sec
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
static inline grub_err_t
|
||||||
|
grub_arch_dl_allocate_gp (grub_dl_t mod __attribute__ ((unused)),
|
||||||
|
const void *ehdr __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
#define GRUB_ARCH_DL_TRAMP_ALIGN 1
|
#define GRUB_ARCH_DL_TRAMP_ALIGN 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue