Make elfload not use hooks. Opt for flags and iterators instead.

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2013-03-02 16:45:57 +01:00
parent 7f8c105f61
commit 73bf57e2c8
9 changed files with 298 additions and 629 deletions

View file

@ -1311,89 +1311,6 @@ grub_bsd_load_aout (grub_file_t file, const char *filename)
bss_size);
}
static int
grub_bsd_elf32_size_hook (grub_elf_t elf __attribute__ ((unused)),
Elf32_Phdr *phdr, void *arg __attribute__ ((unused)))
{
Elf32_Addr paddr;
if (phdr->p_type != PT_LOAD
&& phdr->p_type != PT_DYNAMIC)
return 0;
paddr = phdr->p_paddr & 0xFFFFFFF;
if (paddr < kern_start)
kern_start = paddr;
if (paddr + phdr->p_memsz > kern_end)
kern_end = paddr + phdr->p_memsz;
return 0;
}
static grub_err_t
grub_bsd_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr, int *do_load)
{
Elf32_Addr paddr;
if (phdr->p_type != PT_LOAD
&& phdr->p_type != PT_DYNAMIC)
{
*do_load = 0;
return 0;
}
*do_load = 1;
phdr->p_paddr &= 0xFFFFFFF;
paddr = phdr->p_paddr;
*addr = (grub_addr_t) (paddr - kern_start + (grub_uint8_t *) kern_chunk_src);
return GRUB_ERR_NONE;
}
static int
grub_bsd_elf64_size_hook (grub_elf_t elf __attribute__ ((unused)),
Elf64_Phdr *phdr, void *arg __attribute__ ((unused)))
{
Elf64_Addr paddr;
if (phdr->p_type != PT_LOAD
&& phdr->p_type != PT_DYNAMIC)
return 0;
paddr = phdr->p_paddr & 0xfffffff;
if (paddr < kern_start)
kern_start = paddr;
if (paddr + phdr->p_memsz > kern_end)
kern_end = paddr + phdr->p_memsz;
return 0;
}
static grub_err_t
grub_bsd_elf64_hook (Elf64_Phdr * phdr, grub_addr_t * addr, int *do_load)
{
Elf64_Addr paddr;
if (phdr->p_type != PT_LOAD
&& phdr->p_type != PT_DYNAMIC)
{
*do_load = 0;
return 0;
}
*do_load = 1;
paddr = phdr->p_paddr & 0xfffffff;
*addr = (grub_addr_t) (paddr - kern_start + (grub_uint8_t *) kern_chunk_src);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_bsd_load_elf (grub_elf_t elf, const char *filename)
{
@ -1405,12 +1322,29 @@ grub_bsd_load_elf (grub_elf_t elf, const char *filename)
if (grub_elf_is_elf32 (elf))
{
grub_relocator_chunk_t ch;
Elf32_Phdr *phdr;
entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFFF;
err = grub_elf32_phdr_iterate (elf, filename,
grub_bsd_elf32_size_hook, NULL);
if (err)
return err;
FOR_ELF32_PHDRS (elf, phdr)
{
Elf32_Addr paddr;
if (phdr->p_type != PT_LOAD
&& phdr->p_type != PT_DYNAMIC)
continue;
paddr = phdr->p_paddr & 0xFFFFFFF;
if (paddr < kern_start)
kern_start = paddr;
if (paddr + phdr->p_memsz > kern_end)
kern_end = paddr + phdr->p_memsz;
}
if (grub_errno)
return grub_errno;
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
kern_start, kern_end - kern_start);
if (err)
@ -1418,7 +1352,7 @@ grub_bsd_load_elf (grub_elf_t elf, const char *filename)
kern_chunk_src = get_virtual_current_address (ch);
err = grub_elf32_load (elf, filename, grub_bsd_elf32_hook, 0, 0);
err = grub_elf32_load (elf, filename, (grub_uint8_t *) kern_chunk_src - kern_start, GRUB_ELF_LOAD_FLAGS_LOAD_PT_DYNAMIC | GRUB_ELF_LOAD_FLAGS_28BITS, 0, 0);
if (err)
return err;
if (kernel_type != KERNEL_TYPE_OPENBSD)
@ -1428,6 +1362,8 @@ grub_bsd_load_elf (grub_elf_t elf, const char *filename)
}
else if (grub_elf_is_elf64 (elf))
{
Elf64_Phdr *phdr;
is_64bit = 1;
if (! grub_cpuid_has_longmode)
@ -1445,10 +1381,25 @@ grub_bsd_load_elf (grub_elf_t elf, const char *filename)
entry_hi = 0;
}
err = grub_elf64_phdr_iterate (elf, filename,
grub_bsd_elf64_size_hook, NULL);
if (err)
return err;
FOR_ELF64_PHDRS (elf, phdr)
{
Elf64_Addr paddr;
if (phdr->p_type != PT_LOAD
&& phdr->p_type != PT_DYNAMIC)
continue;
paddr = phdr->p_paddr & 0xFFFFFFF;
if (paddr < kern_start)
kern_start = paddr;
if (paddr + phdr->p_memsz > kern_end)
kern_end = paddr + phdr->p_memsz;
}
if (grub_errno)
return grub_errno;
grub_dprintf ("bsd", "kern_start = %lx, kern_end = %lx\n",
(unsigned long) kern_start, (unsigned long) kern_end);
@ -1463,7 +1414,7 @@ grub_bsd_load_elf (grub_elf_t elf, const char *filename)
}
err = grub_elf64_load (elf, filename,
grub_bsd_elf64_hook, 0, 0);
(grub_uint8_t *) kern_chunk_src - kern_start, GRUB_ELF_LOAD_FLAGS_LOAD_PT_DYNAMIC | GRUB_ELF_LOAD_FLAGS_28BITS, 0, 0);
if (err)
return err;
if (kernel_type != KERNEL_TYPE_OPENBSD)