Revamp relocation handling.
Move more code to common dl.c. Add missing veneers for arm and arm64. Decreases kernel size by 70 bytes on i386-pc (40-50 compressed)
This commit is contained in:
parent
a846dd4b3a
commit
8c534b85f1
18 changed files with 1097 additions and 987 deletions
|
@ -229,7 +229,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
|
|||
unsigned i;
|
||||
Elf_Shdr *s;
|
||||
grub_size_t tsize = 0, talign = 1;
|
||||
#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__)
|
||||
#if !defined (__i386__) && !defined (__x86_64__) && !defined (__sparc__)
|
||||
grub_size_t tramp;
|
||||
grub_size_t got;
|
||||
grub_err_t err;
|
||||
|
@ -245,7 +245,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
|
|||
talign = s->sh_addralign;
|
||||
}
|
||||
|
||||
#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__)
|
||||
#if !defined (__i386__) && !defined (__x86_64__) && !defined (__sparc__)
|
||||
err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -314,12 +314,14 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
|
|||
mod->segment = seg;
|
||||
}
|
||||
}
|
||||
#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__)
|
||||
#if !defined (__i386__) && !defined (__x86_64__) && !defined (__sparc__)
|
||||
ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN);
|
||||
mod->tramp = ptr;
|
||||
mod->trampptr = ptr;
|
||||
ptr += tramp;
|
||||
ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_GOT_ALIGN);
|
||||
mod->got = ptr;
|
||||
mod->gotptr = ptr;
|
||||
ptr += got;
|
||||
#endif
|
||||
|
||||
|
@ -352,6 +354,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
|
|||
#else
|
||||
mod->symtab = (Elf_Sym *) ((char *) e + s->sh_offset);
|
||||
#endif
|
||||
mod->symsize = s->sh_entsize;
|
||||
sym = mod->symtab;
|
||||
size = s->sh_size;
|
||||
entsize = s->sh_entsize;
|
||||
|
@ -561,6 +564,37 @@ grub_dl_flush_cache (grub_dl_t mod)
|
|||
grub_arch_sync_caches (mod->base, mod->sz);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||
{
|
||||
Elf_Ehdr *e = ehdr;
|
||||
Elf_Shdr *s;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
||||
i < e->e_shnum;
|
||||
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
|
||||
if (s->sh_type == SHT_REL || s->sh_type == SHT_RELA)
|
||||
{
|
||||
grub_dl_segment_t seg;
|
||||
grub_err_t err;
|
||||
|
||||
/* Find the target segment. */
|
||||
for (seg = mod->segment; seg; seg = seg->next)
|
||||
if (seg->section == s->sh_info)
|
||||
break;
|
||||
|
||||
if (seg)
|
||||
{
|
||||
err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* Load a module from core memory. */
|
||||
grub_dl_t
|
||||
grub_dl_load_core_noinit (void *addr, grub_size_t size)
|
||||
|
@ -607,7 +641,7 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size)
|
|||
|| grub_dl_resolve_dependencies (mod, e)
|
||||
|| grub_dl_load_segments (mod, e)
|
||||
|| grub_dl_resolve_symbols (mod, e)
|
||||
|| grub_arch_dl_relocate_symbols (mod, e))
|
||||
|| grub_dl_relocate_symbols (mod, e))
|
||||
{
|
||||
mod->fini = 0;
|
||||
grub_dl_unload (mod);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue