elf symbols
This commit is contained in:
parent
4a04699258
commit
865a0f8aa7
3 changed files with 95 additions and 1 deletions
|
@ -43,6 +43,9 @@ grub_err_t grub_multiboot_init_mbi (int argc, char *argv[]);
|
||||||
grub_err_t grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
|
grub_err_t grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
void grub_multiboot_set_bootdev (void);
|
void grub_multiboot_set_bootdev (void);
|
||||||
|
void
|
||||||
|
grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize,
|
||||||
|
unsigned shndx, void *data);
|
||||||
|
|
||||||
|
|
||||||
#endif /* ! GRUB_MULTIBOOT_HEADER */
|
#endif /* ! GRUB_MULTIBOOT_HEADER */
|
||||||
|
|
|
@ -129,6 +129,67 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
|
||||||
if (i == ehdr->e_phnum)
|
if (i == ehdr->e_phnum)
|
||||||
return grub_error (GRUB_ERR_BAD_OS, "entry point isn't in a segment");
|
return grub_error (GRUB_ERR_BAD_OS, "entry point isn't in a segment");
|
||||||
|
|
||||||
|
if (ehdr->e_shnum)
|
||||||
|
{
|
||||||
|
grub_uint8_t *shdr, *shdrptr;
|
||||||
|
|
||||||
|
shdr = grub_malloc (ehdr->e_shnum * ehdr->e_shentsize);
|
||||||
|
if (!shdr)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
if (grub_file_seek (file, ehdr->e_shoff) == (grub_off_t) -1)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS,
|
||||||
|
"invalid offset to section headers");
|
||||||
|
|
||||||
|
if (grub_file_read (file, shdr, ehdr->e_shnum * ehdr->e_shentsize)
|
||||||
|
!= (grub_ssize_t) ehdr->e_shnum * ehdr->e_shentsize)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS,
|
||||||
|
"couldn't read sections headers from file");
|
||||||
|
|
||||||
|
for (shdrptr = shdr, i = 0; i < ehdr->e_shnum;
|
||||||
|
shdrptr += ehdr->e_shentsize, i++)
|
||||||
|
{
|
||||||
|
Elf_Shdr *sh = (Elf_Shdr *) shdrptr;
|
||||||
|
void *src;
|
||||||
|
grub_addr_t target;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
/* This section is a loaded section,
|
||||||
|
so we don't care. */
|
||||||
|
if (sh->sh_addr != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* This section is empty, so we don't care. */
|
||||||
|
if (sh->sh_size == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
err
|
||||||
|
= grub_relocator_alloc_chunk_align (grub_multiboot_relocator,
|
||||||
|
&src, &target, 0,
|
||||||
|
(0xffffffff - sh->sh_size) + 1,
|
||||||
|
sh->sh_size,
|
||||||
|
sh->sh_addralign,
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_file_seek (file, sh->sh_offset) == (grub_off_t) -1)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS,
|
||||||
|
"invalid offset in section header");
|
||||||
|
|
||||||
|
if (grub_file_read (file, src, sh->sh_size)
|
||||||
|
!= (grub_ssize_t) sh->sh_size)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS,
|
||||||
|
"couldn't read segment from file");
|
||||||
|
sh->sh_addr = target;
|
||||||
|
}
|
||||||
|
grub_multiboot_add_elfsyms (ehdr->e_shnum, ehdr->e_shentsize,
|
||||||
|
ehdr->e_shstrndx, shdr);
|
||||||
|
}
|
||||||
|
|
||||||
#undef phdr
|
#undef phdr
|
||||||
|
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
|
@ -46,6 +46,9 @@ static unsigned modcnt;
|
||||||
static char *cmdline = NULL;
|
static char *cmdline = NULL;
|
||||||
static grub_uint32_t bootdev;
|
static grub_uint32_t bootdev;
|
||||||
static int bootdev_set;
|
static int bootdev_set;
|
||||||
|
static grub_size_t elf_sec_num, elf_sec_entsize;
|
||||||
|
static unsigned elf_sec_shstrndx;
|
||||||
|
static void *elf_sections;
|
||||||
|
|
||||||
/* Return the length of the Multiboot mmap that will be needed to allocate
|
/* Return the length of the Multiboot mmap that will be needed to allocate
|
||||||
our platform's map. */
|
our platform's map. */
|
||||||
|
@ -73,7 +76,8 @@ grub_multiboot_get_mbi_size (void)
|
||||||
{
|
{
|
||||||
return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4)
|
return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4)
|
||||||
+ modcnt * sizeof (struct multiboot_mod_list) + total_modcmd
|
+ modcnt * sizeof (struct multiboot_mod_list) + total_modcmd
|
||||||
+ ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_len ();
|
+ ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_len ()
|
||||||
|
+ elf_sec_entsize * elf_sec_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill previously allocated Multiboot mmap. */
|
/* Fill previously allocated Multiboot mmap. */
|
||||||
|
@ -192,9 +196,30 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
||||||
mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
|
mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (elf_sec_num)
|
||||||
|
{
|
||||||
|
mbi->u.elf_sec.addr = ptrdest;
|
||||||
|
grub_memcpy (ptrorig, elf_sections, elf_sec_entsize * elf_sec_num);
|
||||||
|
mbi->u.elf_sec.num = elf_sec_num;
|
||||||
|
mbi->u.elf_sec.size = elf_sec_entsize;
|
||||||
|
mbi->u.elf_sec.shndx = elf_sec_shstrndx;
|
||||||
|
|
||||||
|
mbi->flags |= MULTIBOOT_INFO_ELF_SHDR;
|
||||||
|
}
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize,
|
||||||
|
unsigned shndx, void *data)
|
||||||
|
{
|
||||||
|
elf_sec_num = num;
|
||||||
|
elf_sec_shstrndx = shndx;
|
||||||
|
elf_sec_entsize = entsize;
|
||||||
|
elf_sections = data;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_multiboot_free_mbi (void)
|
grub_multiboot_free_mbi (void)
|
||||||
{
|
{
|
||||||
|
@ -215,6 +240,11 @@ grub_multiboot_free_mbi (void)
|
||||||
}
|
}
|
||||||
modules = NULL;
|
modules = NULL;
|
||||||
modules_last = NULL;
|
modules_last = NULL;
|
||||||
|
|
||||||
|
grub_free (elf_sections);
|
||||||
|
elf_sections = NULL;
|
||||||
|
elf_sec_entsize = 0;
|
||||||
|
elf_sec_num = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
|
|
Loading…
Reference in a new issue