/* elf.c - load ELF files */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
GRUB_MOD_LICENSE ("GPLv3+");
/* Check if EHDR is a valid ELF header. */
static grub_err_t
{
|| e->e_version != EV_CURRENT)
return GRUB_ERR_NONE;
}
{
if (file)
return grub_errno;
}
{
if (! elf)
return 0;
goto fail;
{
grub_error_push ();
goto fail;
}
if (grub_elf_check_header (elf))
goto fail;
return elf;
fail:
return 0;
}
{
if (! file)
return 0;
if (! elf)
return elf;
}
/* 32-bit */
int
{
}
static grub_err_t
{
(unsigned long) phdrs_size);
return grub_errno;
{
grub_error_push ();
}
return GRUB_ERR_NONE;
}
void *hook_arg)
{
unsigned int i;
if (grub_elf32_load_phdrs (elf))
return grub_errno;
{
grub_dprintf ("elf",
"Segment %u: type 0x%x paddr 0x%lx memsz 0x%lx "
"filesz %lx\n",
break;
}
return grub_errno;
}
/* Calculate the amount of memory spanned by the segments. */
{
int nr_phdrs = 0;
/* Run through the program headers to calculate the total memory size we
* should claim. */
{
/* Only consider loadable segments. */
return 0;
nr_phdrs++;
return 0;
}
if (base)
*base = 0;
if (nr_phdrs == 0)
{
return 0;
}
if (segments_end < segments_start)
{
/* Very bad addresses. */
return 0;
}
if (base)
*base = segments_start;
if (max_align)
*max_align = curr_align;
return segments_end - segments_start;
}
/* Load every loadable segment into memory specified by `_load_hook'. */
{
{
return 1;
if (! do_load)
return 0;
(unsigned long long) load_addr,
{
grub_error_push ();
return grub_error (GRUB_ERR_BAD_OS,
"invalid offset in program header");
}
{
{
/* XXX How can we free memory from `load_hook'? */
grub_error_push ();
return grub_error (GRUB_ERR_BAD_OS,
"couldn't read segment from file: "
"wanted 0x%lx bytes; read 0x%lx bytes",
}
}
return 0;
}
if (base)
if (size)
return err;
}
/* 64-bit */
int
{
}
static grub_err_t
{
(unsigned long) phdrs_size);
return grub_errno;
{
grub_error_push ();
}
return GRUB_ERR_NONE;
}
void *hook_arg)
{
unsigned int i;
if (grub_elf64_load_phdrs (elf))
return grub_errno;
{
grub_dprintf ("elf",
"Segment %u: type 0x%x paddr 0x%lx memsz 0x%lx "
"filesz %lx\n",
break;
}
return grub_errno;
}
/* Calculate the amount of memory spanned by the segments. */
{
int nr_phdrs = 0;
/* Run through the program headers to calculate the total memory size we
* should claim. */
{
/* Only consider loadable segments. */
return 0;
nr_phdrs++;
return 0;
}
if (base)
*base = 0;
if (nr_phdrs == 0)
{
return 0;
}
if (segments_end < segments_start)
{
/* Very bad addresses. */
return 0;
}
if (base)
*base = segments_start;
if (max_align)
*max_align = curr_align;
return segments_end - segments_start;
}
/* Load every loadable segment into memory specified by `_load_hook'. */
{
void *hook);
{
return 1;
if (! do_load)
return 0;
(unsigned long long) load_addr,
{
grub_error_push ();
return grub_error (GRUB_ERR_BAD_OS,
"invalid offset in program header");
}
{
{
/* XXX How can we free memory from `load_hook'? */
grub_error_push ();
return grub_error (GRUB_ERR_BAD_OS,
"couldn't read segment from file: "
"wanted 0x%lx bytes; read 0x%lx bytes",
}
}
return 0;
}
if (base)
if (size)
return err;
}