/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Leo Weppelman.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Load an elf image.
* Exit codes:
* -1 : Not an ELF file.
* 0 : OK
* error# : Error during load (*errp might contain error string).
*/
#define ELFMAGIC ((ELFMAG0 << 24) | (ELFMAG1 << 16) | \
(ELFMAG2 << 8) | ELFMAG3)
int
elf_load(int fd, osdsc_t *od, char **errp, int loadsyms)
{
int i,j;
int err;
Elf32_Ehdr ehdr;
Elf32_Phdr *phdrs;
Elf32_Word ident, symsize, symstart;
long kernsize;
memcpy(&ident, ehdr.e_ident, sizeof ident);
if (ident != ELFMAGIC)
return -1;
/*
* calculate highest used address
*/
i = ehdr.e_phnum * sizeof(Elf32_Phdr);
err = 1;
if ((phdrs = (Elf32_Phdr *)MALLOC(i)) == NULL)
goto error;
err = 2;
if (read(fd, phdrs, i) != i)
goto error;
kernsize = 0;
for (i = 0; i < ehdr.e_phnum; i++) {
Elf32_Word sum;
sum = phdrs[i].p_vaddr + phdrs[i].p_memsz;
if ((phdrs[i].p_flags & (PF_W|PF_X)) && (sum > kernsize))
kernsize = sum;
}
/*
* look for symbols and calculate the size
* XXX: This increases the load time by a factor 2 for gzipped
* images!
*/
symsize = 0;
symstart = 0;
if (loadsyms) {
i = ehdr.e_shnum + 1;
err = 3;
if (lseek(fd, (off_t)ehdr.e_shoff, SEEK_SET) != ehdr.e_shoff)
goto error;
while (--i) {
Elf32_Shdr shdr;