xref: /minix3/sys/lib/libsa/loadfile_elf32.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /* $NetBSD: loadfile_elf32.c,v 1.31 2015/07/25 07:06:11 isaki Exp $ */
258a2b000SEvgeniy Ivanov 
358a2b000SEvgeniy Ivanov /*-
458a2b000SEvgeniy Ivanov  * Copyright (c) 1997, 2008 The NetBSD Foundation, Inc.
558a2b000SEvgeniy Ivanov  * All rights reserved.
658a2b000SEvgeniy Ivanov  *
758a2b000SEvgeniy Ivanov  * This code is derived from software contributed to The NetBSD Foundation
858a2b000SEvgeniy Ivanov  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
958a2b000SEvgeniy Ivanov  * NASA Ames Research Center and by Christos Zoulas.
1058a2b000SEvgeniy Ivanov  *
1158a2b000SEvgeniy Ivanov  * Redistribution and use in source and binary forms, with or without
1258a2b000SEvgeniy Ivanov  * modification, are permitted provided that the following conditions
1358a2b000SEvgeniy Ivanov  * are met:
1458a2b000SEvgeniy Ivanov  * 1. Redistributions of source code must retain the above copyright
1558a2b000SEvgeniy Ivanov  *    notice, this list of conditions and the following disclaimer.
1658a2b000SEvgeniy Ivanov  * 2. Redistributions in binary form must reproduce the above copyright
1758a2b000SEvgeniy Ivanov  *    notice, this list of conditions and the following disclaimer in the
1858a2b000SEvgeniy Ivanov  *    documentation and/or other materials provided with the distribution.
1958a2b000SEvgeniy Ivanov  *
2058a2b000SEvgeniy Ivanov  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2158a2b000SEvgeniy Ivanov  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2258a2b000SEvgeniy Ivanov  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2358a2b000SEvgeniy Ivanov  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2458a2b000SEvgeniy Ivanov  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2558a2b000SEvgeniy Ivanov  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2658a2b000SEvgeniy Ivanov  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2758a2b000SEvgeniy Ivanov  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2858a2b000SEvgeniy Ivanov  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2958a2b000SEvgeniy Ivanov  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3058a2b000SEvgeniy Ivanov  * POSSIBILITY OF SUCH DAMAGE.
3158a2b000SEvgeniy Ivanov  */
3258a2b000SEvgeniy Ivanov 
3358a2b000SEvgeniy Ivanov /* If not included by exec_elf64.c, ELFSIZE won't be defined. */
3458a2b000SEvgeniy Ivanov #ifndef ELFSIZE
3558a2b000SEvgeniy Ivanov #define	ELFSIZE	32
3658a2b000SEvgeniy Ivanov #endif
3758a2b000SEvgeniy Ivanov 
3858a2b000SEvgeniy Ivanov #ifdef _STANDALONE
3958a2b000SEvgeniy Ivanov #include <lib/libsa/stand.h>
4058a2b000SEvgeniy Ivanov #include <lib/libkern/libkern.h>
4158a2b000SEvgeniy Ivanov #else
4258a2b000SEvgeniy Ivanov #include <stdio.h>
4358a2b000SEvgeniy Ivanov #include <string.h>
4458a2b000SEvgeniy Ivanov #include <errno.h>
4558a2b000SEvgeniy Ivanov #include <stdlib.h>
4658a2b000SEvgeniy Ivanov #include <unistd.h>
4758a2b000SEvgeniy Ivanov #include <fcntl.h>
4858a2b000SEvgeniy Ivanov #include <err.h>
4958a2b000SEvgeniy Ivanov #endif
5058a2b000SEvgeniy Ivanov 
5158a2b000SEvgeniy Ivanov #include <sys/param.h>
5258a2b000SEvgeniy Ivanov #include <sys/exec.h>
5358a2b000SEvgeniy Ivanov 
5458a2b000SEvgeniy Ivanov #include "loadfile.h"
5558a2b000SEvgeniy Ivanov 
5658a2b000SEvgeniy Ivanov #if ((ELFSIZE == 32) && defined(BOOT_ELF32)) || \
5758a2b000SEvgeniy Ivanov     ((ELFSIZE == 64) && defined(BOOT_ELF64))
5858a2b000SEvgeniy Ivanov 
5958a2b000SEvgeniy Ivanov #define	ELFROUND	(ELFSIZE / 8)
6058a2b000SEvgeniy Ivanov 
6158a2b000SEvgeniy Ivanov #ifndef _STANDALONE
6258a2b000SEvgeniy Ivanov #include "byteorder.h"
6358a2b000SEvgeniy Ivanov 
6458a2b000SEvgeniy Ivanov /*
6558a2b000SEvgeniy Ivanov  * Byte swapping may be necessary in the non-_STANDLONE case because
6658a2b000SEvgeniy Ivanov  * we may be built with a host compiler.
6758a2b000SEvgeniy Ivanov  */
6858a2b000SEvgeniy Ivanov #define	E16(f)								\
6958a2b000SEvgeniy Ivanov 	f = (bo == ELFDATA2LSB) ? sa_htole16(f) : sa_htobe16(f)
7058a2b000SEvgeniy Ivanov #define	E32(f)								\
7158a2b000SEvgeniy Ivanov 	f = (bo == ELFDATA2LSB) ? sa_htole32(f) : sa_htobe32(f)
7258a2b000SEvgeniy Ivanov #define	E64(f)								\
7358a2b000SEvgeniy Ivanov 	f = (bo == ELFDATA2LSB) ? sa_htole64(f) : sa_htobe64(f)
7458a2b000SEvgeniy Ivanov 
7558a2b000SEvgeniy Ivanov #define	I16(f)								\
7658a2b000SEvgeniy Ivanov 	f = (bo == ELFDATA2LSB) ? sa_le16toh(f) : sa_be16toh(f)
7758a2b000SEvgeniy Ivanov #define	I32(f)								\
7858a2b000SEvgeniy Ivanov 	f = (bo == ELFDATA2LSB) ? sa_le32toh(f) : sa_be32toh(f)
7958a2b000SEvgeniy Ivanov #define	I64(f)								\
8058a2b000SEvgeniy Ivanov 	f = (bo == ELFDATA2LSB) ? sa_le64toh(f) : sa_be64toh(f)
8158a2b000SEvgeniy Ivanov 
8258a2b000SEvgeniy Ivanov static void
internalize_ehdr(Elf_Byte bo,Elf_Ehdr * ehdr)8358a2b000SEvgeniy Ivanov internalize_ehdr(Elf_Byte bo, Elf_Ehdr *ehdr)
8458a2b000SEvgeniy Ivanov {
8558a2b000SEvgeniy Ivanov 
8658a2b000SEvgeniy Ivanov #if ELFSIZE == 32
8758a2b000SEvgeniy Ivanov 	I16(ehdr->e_type);
8858a2b000SEvgeniy Ivanov 	I16(ehdr->e_machine);
8958a2b000SEvgeniy Ivanov 	I32(ehdr->e_version);
9058a2b000SEvgeniy Ivanov 	I32(ehdr->e_entry);
9158a2b000SEvgeniy Ivanov 	I32(ehdr->e_phoff);
9258a2b000SEvgeniy Ivanov 	I32(ehdr->e_shoff);
9358a2b000SEvgeniy Ivanov 	I32(ehdr->e_flags);
9458a2b000SEvgeniy Ivanov 	I16(ehdr->e_ehsize);
9558a2b000SEvgeniy Ivanov 	I16(ehdr->e_phentsize);
9658a2b000SEvgeniy Ivanov 	I16(ehdr->e_phnum);
9758a2b000SEvgeniy Ivanov 	I16(ehdr->e_shentsize);
9858a2b000SEvgeniy Ivanov 	I16(ehdr->e_shnum);
9958a2b000SEvgeniy Ivanov 	I16(ehdr->e_shstrndx);
10058a2b000SEvgeniy Ivanov #elif ELFSIZE == 64
10158a2b000SEvgeniy Ivanov 	I16(ehdr->e_type);
10258a2b000SEvgeniy Ivanov 	I16(ehdr->e_machine);
10358a2b000SEvgeniy Ivanov 	I32(ehdr->e_version);
10458a2b000SEvgeniy Ivanov 	I64(ehdr->e_entry);
10558a2b000SEvgeniy Ivanov 	I64(ehdr->e_phoff);
10658a2b000SEvgeniy Ivanov 	I64(ehdr->e_shoff);
10758a2b000SEvgeniy Ivanov 	I32(ehdr->e_flags);
10858a2b000SEvgeniy Ivanov 	I16(ehdr->e_ehsize);
10958a2b000SEvgeniy Ivanov 	I16(ehdr->e_phentsize);
11058a2b000SEvgeniy Ivanov 	I16(ehdr->e_phnum);
11158a2b000SEvgeniy Ivanov 	I16(ehdr->e_shentsize);
11258a2b000SEvgeniy Ivanov 	I16(ehdr->e_shnum);
11358a2b000SEvgeniy Ivanov 	I16(ehdr->e_shstrndx);
11458a2b000SEvgeniy Ivanov #else
11558a2b000SEvgeniy Ivanov #error ELFSIZE is not 32 or 64
11658a2b000SEvgeniy Ivanov #endif
11758a2b000SEvgeniy Ivanov }
11858a2b000SEvgeniy Ivanov 
11958a2b000SEvgeniy Ivanov static void
externalize_ehdr(Elf_Byte bo,Elf_Ehdr * ehdr)12058a2b000SEvgeniy Ivanov externalize_ehdr(Elf_Byte bo, Elf_Ehdr *ehdr)
12158a2b000SEvgeniy Ivanov {
12258a2b000SEvgeniy Ivanov 
12358a2b000SEvgeniy Ivanov #if ELFSIZE == 32
12458a2b000SEvgeniy Ivanov 	E16(ehdr->e_type);
12558a2b000SEvgeniy Ivanov 	E16(ehdr->e_machine);
12658a2b000SEvgeniy Ivanov 	E32(ehdr->e_version);
12758a2b000SEvgeniy Ivanov 	E32(ehdr->e_entry);
12858a2b000SEvgeniy Ivanov 	E32(ehdr->e_phoff);
12958a2b000SEvgeniy Ivanov 	E32(ehdr->e_shoff);
13058a2b000SEvgeniy Ivanov 	E32(ehdr->e_flags);
13158a2b000SEvgeniy Ivanov 	E16(ehdr->e_ehsize);
13258a2b000SEvgeniy Ivanov 	E16(ehdr->e_phentsize);
13358a2b000SEvgeniy Ivanov 	E16(ehdr->e_phnum);
13458a2b000SEvgeniy Ivanov 	E16(ehdr->e_shentsize);
13558a2b000SEvgeniy Ivanov 	E16(ehdr->e_shnum);
13658a2b000SEvgeniy Ivanov 	E16(ehdr->e_shstrndx);
13758a2b000SEvgeniy Ivanov #elif ELFSIZE == 64
13858a2b000SEvgeniy Ivanov 	E16(ehdr->e_type);
13958a2b000SEvgeniy Ivanov 	E16(ehdr->e_machine);
14058a2b000SEvgeniy Ivanov 	E32(ehdr->e_version);
14158a2b000SEvgeniy Ivanov 	E64(ehdr->e_entry);
14258a2b000SEvgeniy Ivanov 	E64(ehdr->e_phoff);
14358a2b000SEvgeniy Ivanov 	E64(ehdr->e_shoff);
14458a2b000SEvgeniy Ivanov 	E32(ehdr->e_flags);
14558a2b000SEvgeniy Ivanov 	E16(ehdr->e_ehsize);
14658a2b000SEvgeniy Ivanov 	E16(ehdr->e_phentsize);
14758a2b000SEvgeniy Ivanov 	E16(ehdr->e_phnum);
14858a2b000SEvgeniy Ivanov 	E16(ehdr->e_shentsize);
14958a2b000SEvgeniy Ivanov 	E16(ehdr->e_shnum);
15058a2b000SEvgeniy Ivanov 	E16(ehdr->e_shstrndx);
15158a2b000SEvgeniy Ivanov #else
15258a2b000SEvgeniy Ivanov #error ELFSIZE is not 32 or 64
15358a2b000SEvgeniy Ivanov #endif
15458a2b000SEvgeniy Ivanov }
15558a2b000SEvgeniy Ivanov 
15658a2b000SEvgeniy Ivanov static void
internalize_phdr(Elf_Byte bo,Elf_Phdr * phdr)15758a2b000SEvgeniy Ivanov internalize_phdr(Elf_Byte bo, Elf_Phdr *phdr)
15858a2b000SEvgeniy Ivanov {
15958a2b000SEvgeniy Ivanov 
16058a2b000SEvgeniy Ivanov #if ELFSIZE == 32
16158a2b000SEvgeniy Ivanov 	I32(phdr->p_type);
16258a2b000SEvgeniy Ivanov 	I32(phdr->p_offset);
16358a2b000SEvgeniy Ivanov 	I32(phdr->p_vaddr);
16458a2b000SEvgeniy Ivanov 	I32(phdr->p_paddr);
16558a2b000SEvgeniy Ivanov 	I32(phdr->p_filesz);
16658a2b000SEvgeniy Ivanov 	I32(phdr->p_memsz);
16758a2b000SEvgeniy Ivanov 	I32(phdr->p_flags);
16858a2b000SEvgeniy Ivanov 	I32(phdr->p_align);
16958a2b000SEvgeniy Ivanov #elif ELFSIZE == 64
17058a2b000SEvgeniy Ivanov 	I32(phdr->p_type);
17158a2b000SEvgeniy Ivanov 	I32(phdr->p_offset);
17258a2b000SEvgeniy Ivanov 	I64(phdr->p_vaddr);
17358a2b000SEvgeniy Ivanov 	I64(phdr->p_paddr);
17458a2b000SEvgeniy Ivanov 	I64(phdr->p_filesz);
17558a2b000SEvgeniy Ivanov 	I64(phdr->p_memsz);
17658a2b000SEvgeniy Ivanov 	I64(phdr->p_flags);
17758a2b000SEvgeniy Ivanov 	I64(phdr->p_align);
17858a2b000SEvgeniy Ivanov #else
17958a2b000SEvgeniy Ivanov #error ELFSIZE is not 32 or 64
18058a2b000SEvgeniy Ivanov #endif
18158a2b000SEvgeniy Ivanov }
18258a2b000SEvgeniy Ivanov 
18358a2b000SEvgeniy Ivanov static void
internalize_shdr(Elf_Byte bo,Elf_Shdr * shdr)18458a2b000SEvgeniy Ivanov internalize_shdr(Elf_Byte bo, Elf_Shdr *shdr)
18558a2b000SEvgeniy Ivanov {
18658a2b000SEvgeniy Ivanov 
18758a2b000SEvgeniy Ivanov #if ELFSIZE == 32
18858a2b000SEvgeniy Ivanov 	I32(shdr->sh_name);
18958a2b000SEvgeniy Ivanov 	I32(shdr->sh_type);
19058a2b000SEvgeniy Ivanov 	I32(shdr->sh_flags);
19158a2b000SEvgeniy Ivanov 	I32(shdr->sh_addr);
19258a2b000SEvgeniy Ivanov 	I32(shdr->sh_offset);
19358a2b000SEvgeniy Ivanov 	I32(shdr->sh_size);
19458a2b000SEvgeniy Ivanov 	I32(shdr->sh_link);
19558a2b000SEvgeniy Ivanov 	I32(shdr->sh_info);
19658a2b000SEvgeniy Ivanov 	I32(shdr->sh_addralign);
19758a2b000SEvgeniy Ivanov 	I32(shdr->sh_entsize);
19858a2b000SEvgeniy Ivanov #elif ELFSIZE == 64
19958a2b000SEvgeniy Ivanov 	I32(shdr->sh_name);
20058a2b000SEvgeniy Ivanov 	I32(shdr->sh_type);
20158a2b000SEvgeniy Ivanov 	I64(shdr->sh_flags);
20258a2b000SEvgeniy Ivanov 	I64(shdr->sh_addr);
20358a2b000SEvgeniy Ivanov 	I64(shdr->sh_offset);
20458a2b000SEvgeniy Ivanov 	I64(shdr->sh_size);
20558a2b000SEvgeniy Ivanov 	I32(shdr->sh_link);
20658a2b000SEvgeniy Ivanov 	I32(shdr->sh_info);
20758a2b000SEvgeniy Ivanov 	I64(shdr->sh_addralign);
20858a2b000SEvgeniy Ivanov 	I64(shdr->sh_entsize);
20958a2b000SEvgeniy Ivanov #else
21058a2b000SEvgeniy Ivanov #error ELFSIZE is not 32 or 64
21158a2b000SEvgeniy Ivanov #endif
21258a2b000SEvgeniy Ivanov }
21358a2b000SEvgeniy Ivanov 
21458a2b000SEvgeniy Ivanov static void
externalize_shdr(Elf_Byte bo,Elf_Shdr * shdr)21558a2b000SEvgeniy Ivanov externalize_shdr(Elf_Byte bo, Elf_Shdr *shdr)
21658a2b000SEvgeniy Ivanov {
21758a2b000SEvgeniy Ivanov 
21858a2b000SEvgeniy Ivanov #if ELFSIZE == 32
21958a2b000SEvgeniy Ivanov 	E32(shdr->sh_name);
22058a2b000SEvgeniy Ivanov 	E32(shdr->sh_type);
22158a2b000SEvgeniy Ivanov 	E32(shdr->sh_flags);
22258a2b000SEvgeniy Ivanov 	E32(shdr->sh_addr);
22358a2b000SEvgeniy Ivanov 	E32(shdr->sh_offset);
22458a2b000SEvgeniy Ivanov 	E32(shdr->sh_size);
22558a2b000SEvgeniy Ivanov 	E32(shdr->sh_link);
22658a2b000SEvgeniy Ivanov 	E32(shdr->sh_info);
22758a2b000SEvgeniy Ivanov 	E32(shdr->sh_addralign);
22858a2b000SEvgeniy Ivanov 	E32(shdr->sh_entsize);
22958a2b000SEvgeniy Ivanov #elif ELFSIZE == 64
23058a2b000SEvgeniy Ivanov 	E32(shdr->sh_name);
23158a2b000SEvgeniy Ivanov 	E32(shdr->sh_type);
23258a2b000SEvgeniy Ivanov 	E64(shdr->sh_flags);
23358a2b000SEvgeniy Ivanov 	E64(shdr->sh_addr);
23458a2b000SEvgeniy Ivanov 	E64(shdr->sh_offset);
23558a2b000SEvgeniy Ivanov 	E64(shdr->sh_size);
23658a2b000SEvgeniy Ivanov 	E32(shdr->sh_link);
23758a2b000SEvgeniy Ivanov 	E32(shdr->sh_info);
23858a2b000SEvgeniy Ivanov 	E64(shdr->sh_addralign);
23958a2b000SEvgeniy Ivanov 	E64(shdr->sh_entsize);
24058a2b000SEvgeniy Ivanov #else
24158a2b000SEvgeniy Ivanov #error ELFSIZE is not 32 or 64
24258a2b000SEvgeniy Ivanov #endif
24358a2b000SEvgeniy Ivanov }
24458a2b000SEvgeniy Ivanov #else /* _STANDALONE */
24558a2b000SEvgeniy Ivanov /*
24658a2b000SEvgeniy Ivanov  * Byte swapping is never necessary in the _STANDALONE case because
24758a2b000SEvgeniy Ivanov  * we are being built with the target compiler.
24858a2b000SEvgeniy Ivanov  */
24958a2b000SEvgeniy Ivanov #define	internalize_ehdr(bo, ehdr)	/* nothing */
25058a2b000SEvgeniy Ivanov #define	externalize_ehdr(bo, ehdr)	/* nothing */
25158a2b000SEvgeniy Ivanov 
25258a2b000SEvgeniy Ivanov #define	internalize_phdr(bo, phdr)	/* nothing */
25358a2b000SEvgeniy Ivanov 
25458a2b000SEvgeniy Ivanov #define	internalize_shdr(bo, shdr)	/* nothing */
25558a2b000SEvgeniy Ivanov #define	externalize_shdr(bo, shdr)	/* nothing */
25658a2b000SEvgeniy Ivanov #endif /* _STANDALONE */
25758a2b000SEvgeniy Ivanov 
25858a2b000SEvgeniy Ivanov int
ELFNAMEEND(loadfile)25958a2b000SEvgeniy Ivanov ELFNAMEEND(loadfile)(int fd, Elf_Ehdr *elf, u_long *marks, int flags)
26058a2b000SEvgeniy Ivanov {
26158a2b000SEvgeniy Ivanov 	Elf_Shdr *shp;
26258a2b000SEvgeniy Ivanov 	Elf_Phdr *phdr;
26358a2b000SEvgeniy Ivanov 	int i, j;
26458a2b000SEvgeniy Ivanov 	ssize_t sz;
26558a2b000SEvgeniy Ivanov 	int first;
26658a2b000SEvgeniy Ivanov 	Elf_Addr shpp;
26758a2b000SEvgeniy Ivanov 	Elf_Addr minp = ~0, maxp = 0, pos = 0, elfp = 0;
26858a2b000SEvgeniy Ivanov 	u_long offset = marks[MARK_START];
26958a2b000SEvgeniy Ivanov 	ssize_t nr;
27058a2b000SEvgeniy Ivanov 	struct __packed {
27158a2b000SEvgeniy Ivanov 		Elf_Nhdr	nh;
27258a2b000SEvgeniy Ivanov 		uint8_t		name[ELF_NOTE_NETBSD_NAMESZ + 1];
27358a2b000SEvgeniy Ivanov 		uint8_t		desc[ELF_NOTE_NETBSD_DESCSZ];
27458a2b000SEvgeniy Ivanov 	} note;
27558a2b000SEvgeniy Ivanov 	char *shstr = NULL;
27684d9c625SLionel Sambuc 	size_t shstrsz = 0;
27758a2b000SEvgeniy Ivanov 	int boot_load_ctf = 1;
27858a2b000SEvgeniy Ivanov 
27958a2b000SEvgeniy Ivanov 	/* some ports dont use the offset */
28058a2b000SEvgeniy Ivanov 	(void)&offset;
28158a2b000SEvgeniy Ivanov 
28258a2b000SEvgeniy Ivanov 	internalize_ehdr(elf->e_ident[EI_DATA], elf);
28358a2b000SEvgeniy Ivanov 
28458a2b000SEvgeniy Ivanov 	sz = elf->e_phnum * sizeof(Elf_Phdr);
28558a2b000SEvgeniy Ivanov 	phdr = ALLOC(sz);
28658a2b000SEvgeniy Ivanov 
28758a2b000SEvgeniy Ivanov 	if (lseek(fd, elf->e_phoff, SEEK_SET) == -1)  {
28858a2b000SEvgeniy Ivanov 		WARN(("lseek phdr"));
28958a2b000SEvgeniy Ivanov 		goto freephdr;
29058a2b000SEvgeniy Ivanov 	}
29158a2b000SEvgeniy Ivanov 	nr = read(fd, phdr, sz);
29258a2b000SEvgeniy Ivanov 	if (nr == -1) {
29358a2b000SEvgeniy Ivanov 		WARN(("read program headers"));
29458a2b000SEvgeniy Ivanov 		goto freephdr;
29558a2b000SEvgeniy Ivanov 	}
29658a2b000SEvgeniy Ivanov 	if (nr != sz) {
29758a2b000SEvgeniy Ivanov 		errno = EIO;
29858a2b000SEvgeniy Ivanov 		WARN(("read program headers"));
29958a2b000SEvgeniy Ivanov 		goto freephdr;
30058a2b000SEvgeniy Ivanov 	}
30158a2b000SEvgeniy Ivanov 
30258a2b000SEvgeniy Ivanov 	for (first = 1, i = 0; i < elf->e_phnum; i++) {
30358a2b000SEvgeniy Ivanov 		internalize_phdr(elf->e_ident[EI_DATA], &phdr[i]);
30458a2b000SEvgeniy Ivanov 
30558a2b000SEvgeniy Ivanov #ifndef MD_LOADSEG /* Allow processor ABI specific segment loads */
30658a2b000SEvgeniy Ivanov #define MD_LOADSEG(a) /*CONSTCOND*/0
30758a2b000SEvgeniy Ivanov #endif
30858a2b000SEvgeniy Ivanov 		if (MD_LOADSEG(&phdr[i]))
30958a2b000SEvgeniy Ivanov 			goto loadseg;
31058a2b000SEvgeniy Ivanov 
31158a2b000SEvgeniy Ivanov 		if (phdr[i].p_type != PT_LOAD ||
31258a2b000SEvgeniy Ivanov 		    (phdr[i].p_flags & (PF_W|PF_X)) == 0)
31358a2b000SEvgeniy Ivanov 			continue;
31458a2b000SEvgeniy Ivanov 
31558a2b000SEvgeniy Ivanov #define IS_TEXT(p)	(p.p_flags & PF_X)
31658a2b000SEvgeniy Ivanov #define IS_DATA(p)	(p.p_flags & PF_W)
31758a2b000SEvgeniy Ivanov #define IS_BSS(p)	(p.p_filesz < p.p_memsz)
31858a2b000SEvgeniy Ivanov 		/*
31958a2b000SEvgeniy Ivanov 		 * XXX: Assume first address is lowest
32058a2b000SEvgeniy Ivanov 		 */
32158a2b000SEvgeniy Ivanov 		if ((IS_TEXT(phdr[i]) && (flags & LOAD_TEXT)) ||
32258a2b000SEvgeniy Ivanov 		    (IS_DATA(phdr[i]) && (flags & LOAD_DATA))) {
32358a2b000SEvgeniy Ivanov 
32458a2b000SEvgeniy Ivanov 		loadseg:
32558a2b000SEvgeniy Ivanov 			if (marks[MARK_DATA] == 0 && IS_DATA(phdr[i]))
32658a2b000SEvgeniy Ivanov 				marks[MARK_DATA] = LOADADDR(phdr[i].p_vaddr);
32758a2b000SEvgeniy Ivanov 
32858a2b000SEvgeniy Ivanov 			/* Read in segment. */
32958a2b000SEvgeniy Ivanov 			PROGRESS(("%s%lu", first ? "" : "+",
33058a2b000SEvgeniy Ivanov 			    (u_long)phdr[i].p_filesz));
33158a2b000SEvgeniy Ivanov 
33258a2b000SEvgeniy Ivanov 			if (lseek(fd, phdr[i].p_offset, SEEK_SET) == -1)  {
33358a2b000SEvgeniy Ivanov 				WARN(("lseek text"));
33458a2b000SEvgeniy Ivanov 				goto freephdr;
33558a2b000SEvgeniy Ivanov 			}
33658a2b000SEvgeniy Ivanov 			nr = READ(fd, phdr[i].p_vaddr, phdr[i].p_filesz);
33758a2b000SEvgeniy Ivanov 			if (nr == -1) {
33858a2b000SEvgeniy Ivanov 				WARN(("read text error"));
33958a2b000SEvgeniy Ivanov 				goto freephdr;
34058a2b000SEvgeniy Ivanov 			}
34158a2b000SEvgeniy Ivanov 			if (nr != (ssize_t)phdr[i].p_filesz) {
34258a2b000SEvgeniy Ivanov 				errno = EIO;
34358a2b000SEvgeniy Ivanov 				WARN(("read text"));
34458a2b000SEvgeniy Ivanov 				goto freephdr;
34558a2b000SEvgeniy Ivanov 			}
34658a2b000SEvgeniy Ivanov 			first = 0;
34758a2b000SEvgeniy Ivanov 
34858a2b000SEvgeniy Ivanov 		}
34958a2b000SEvgeniy Ivanov 		if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT|COUNT_TEXT))) ||
35058a2b000SEvgeniy Ivanov 		    (IS_DATA(phdr[i]) && (flags & (LOAD_DATA|COUNT_TEXT)))) {
35158a2b000SEvgeniy Ivanov 			pos = phdr[i].p_vaddr;
35258a2b000SEvgeniy Ivanov 			if (minp > pos)
35358a2b000SEvgeniy Ivanov 				minp = pos;
35458a2b000SEvgeniy Ivanov 			pos += phdr[i].p_filesz;
35558a2b000SEvgeniy Ivanov 			if (maxp < pos)
35658a2b000SEvgeniy Ivanov 				maxp = pos;
35758a2b000SEvgeniy Ivanov 		}
35858a2b000SEvgeniy Ivanov 
35958a2b000SEvgeniy Ivanov 		/* Zero out bss. */
36058a2b000SEvgeniy Ivanov 		if (IS_BSS(phdr[i]) && (flags & LOAD_BSS)) {
36158a2b000SEvgeniy Ivanov 			PROGRESS(("+%lu",
36258a2b000SEvgeniy Ivanov 			    (u_long)(phdr[i].p_memsz - phdr[i].p_filesz)));
36358a2b000SEvgeniy Ivanov 			BZERO((phdr[i].p_vaddr + phdr[i].p_filesz),
36458a2b000SEvgeniy Ivanov 			    phdr[i].p_memsz - phdr[i].p_filesz);
36558a2b000SEvgeniy Ivanov 		}
36658a2b000SEvgeniy Ivanov 		if (IS_BSS(phdr[i]) && (flags & (LOAD_BSS|COUNT_BSS))) {
36758a2b000SEvgeniy Ivanov 			pos += phdr[i].p_memsz - phdr[i].p_filesz;
36858a2b000SEvgeniy Ivanov 			if (maxp < pos)
36958a2b000SEvgeniy Ivanov 				maxp = pos;
37058a2b000SEvgeniy Ivanov 		}
37158a2b000SEvgeniy Ivanov 	}
37258a2b000SEvgeniy Ivanov 	DEALLOC(phdr, sz);
37358a2b000SEvgeniy Ivanov 
37458a2b000SEvgeniy Ivanov 	/*
37558a2b000SEvgeniy Ivanov 	 * Copy the ELF and section headers.
37658a2b000SEvgeniy Ivanov 	 */
37758a2b000SEvgeniy Ivanov 	maxp = roundup(maxp, ELFROUND);
37858a2b000SEvgeniy Ivanov 	if (flags & (LOAD_HDR|COUNT_HDR)) {
37958a2b000SEvgeniy Ivanov 		elfp = maxp;
38058a2b000SEvgeniy Ivanov 		maxp += sizeof(Elf_Ehdr);
38158a2b000SEvgeniy Ivanov 	}
38258a2b000SEvgeniy Ivanov 
38358a2b000SEvgeniy Ivanov 	if (flags & (LOAD_SYM|COUNT_SYM)) {
38458a2b000SEvgeniy Ivanov 		if (lseek(fd, elf->e_shoff, SEEK_SET) == -1)  {
38558a2b000SEvgeniy Ivanov 			WARN(("lseek section headers"));
38658a2b000SEvgeniy Ivanov 			return 1;
38758a2b000SEvgeniy Ivanov 		}
38858a2b000SEvgeniy Ivanov 		sz = elf->e_shnum * sizeof(Elf_Shdr);
38958a2b000SEvgeniy Ivanov 
39058a2b000SEvgeniy Ivanov 		shp = ALLOC(sz);
39158a2b000SEvgeniy Ivanov 
39258a2b000SEvgeniy Ivanov 		nr = read(fd, shp, sz);
39358a2b000SEvgeniy Ivanov 		if (nr == -1) {
39458a2b000SEvgeniy Ivanov 			WARN(("read section headers"));
39558a2b000SEvgeniy Ivanov 			goto freeshp;
39658a2b000SEvgeniy Ivanov 		}
39758a2b000SEvgeniy Ivanov 		if (nr != sz) {
39858a2b000SEvgeniy Ivanov 			errno = EIO;
39958a2b000SEvgeniy Ivanov 			WARN(("read section headers"));
40058a2b000SEvgeniy Ivanov 			goto freeshp;
40158a2b000SEvgeniy Ivanov 		}
40258a2b000SEvgeniy Ivanov 
40358a2b000SEvgeniy Ivanov 		shpp = maxp;
40458a2b000SEvgeniy Ivanov 		maxp += roundup(sz, ELFROUND);
40558a2b000SEvgeniy Ivanov 
40658a2b000SEvgeniy Ivanov #ifndef _STANDALONE
40758a2b000SEvgeniy Ivanov 		/* Internalize the section headers. */
40858a2b000SEvgeniy Ivanov 		for (i = 0; i < elf->e_shnum; i++)
40958a2b000SEvgeniy Ivanov 			internalize_shdr(elf->e_ident[EI_DATA], &shp[i]);
41058a2b000SEvgeniy Ivanov #endif /* ! _STANDALONE */
41158a2b000SEvgeniy Ivanov 
41258a2b000SEvgeniy Ivanov 		/*
41358a2b000SEvgeniy Ivanov 		 * First load the section names section.
41458a2b000SEvgeniy Ivanov 		 */
41558a2b000SEvgeniy Ivanov 		if (boot_load_ctf && (elf->e_shstrndx != 0)) {
41658a2b000SEvgeniy Ivanov 			if (flags & LOAD_SYM) {
41758a2b000SEvgeniy Ivanov 				if (lseek(fd, shp[elf->e_shstrndx].sh_offset,
41858a2b000SEvgeniy Ivanov 				    SEEK_SET) == -1) {
41958a2b000SEvgeniy Ivanov 					WARN(("lseek symbols"));
42058a2b000SEvgeniy Ivanov 					goto freeshp;
42158a2b000SEvgeniy Ivanov 				}
42258a2b000SEvgeniy Ivanov 				nr = READ(fd, maxp,
42358a2b000SEvgeniy Ivanov 				    shp[elf->e_shstrndx].sh_size);
42458a2b000SEvgeniy Ivanov 				if (nr == -1) {
42558a2b000SEvgeniy Ivanov 					WARN(("read symbols"));
42658a2b000SEvgeniy Ivanov 					goto freeshp;
42758a2b000SEvgeniy Ivanov 				}
42858a2b000SEvgeniy Ivanov 				if (nr !=
42958a2b000SEvgeniy Ivanov 				    (ssize_t)shp[elf->e_shstrndx].sh_size) {
43058a2b000SEvgeniy Ivanov 					errno = EIO;
43158a2b000SEvgeniy Ivanov 					WARN(("read symbols"));
43258a2b000SEvgeniy Ivanov 					goto freeshp;
43358a2b000SEvgeniy Ivanov 				}
43458a2b000SEvgeniy Ivanov 
43558a2b000SEvgeniy Ivanov 				shstr = ALLOC(shp[elf->e_shstrndx].sh_size);
43684d9c625SLionel Sambuc 				shstrsz = shp[elf->e_shstrndx].sh_size;
43758a2b000SEvgeniy Ivanov 				if (lseek(fd, shp[elf->e_shstrndx].sh_offset,
43858a2b000SEvgeniy Ivanov 				    SEEK_SET) == -1) {
43958a2b000SEvgeniy Ivanov 					WARN(("lseek symbols"));
44058a2b000SEvgeniy Ivanov 					goto freeshp;
44158a2b000SEvgeniy Ivanov 				}
44258a2b000SEvgeniy Ivanov 				nr = read(fd, shstr,
44358a2b000SEvgeniy Ivanov 				    shp[elf->e_shstrndx].sh_size);
44458a2b000SEvgeniy Ivanov 				if (nr == -1) {
44558a2b000SEvgeniy Ivanov 					WARN(("read symbols"));
44658a2b000SEvgeniy Ivanov 					goto freeshp;
44758a2b000SEvgeniy Ivanov 				}
44858a2b000SEvgeniy Ivanov 			}
44958a2b000SEvgeniy Ivanov 			shp[elf->e_shstrndx].sh_offset = maxp - elfp;
45058a2b000SEvgeniy Ivanov 			maxp += roundup(shp[elf->e_shstrndx].sh_size, ELFROUND);
45158a2b000SEvgeniy Ivanov 		}
45258a2b000SEvgeniy Ivanov 
45358a2b000SEvgeniy Ivanov 		/*
45458a2b000SEvgeniy Ivanov 		 * Now load the symbol sections themselves.  Make sure
45558a2b000SEvgeniy Ivanov 		 * the sections are aligned. Don't bother with any
45658a2b000SEvgeniy Ivanov 		 * string table that isn't referenced by a symbol
45758a2b000SEvgeniy Ivanov 		 * table.
45858a2b000SEvgeniy Ivanov 		 */
45958a2b000SEvgeniy Ivanov 		for (first = 1, i = 0; i < elf->e_shnum; i++) {
46058a2b000SEvgeniy Ivanov 			if (i == elf->e_shstrndx) {
46158a2b000SEvgeniy Ivanov 				/* already loaded this section */
46258a2b000SEvgeniy Ivanov 				continue;
46358a2b000SEvgeniy Ivanov 			}
46458a2b000SEvgeniy Ivanov 			switch (shp[i].sh_type) {
46558a2b000SEvgeniy Ivanov 			case SHT_PROGBITS:
46658a2b000SEvgeniy Ivanov 				if (boot_load_ctf && shstr) {
46758a2b000SEvgeniy Ivanov 					/* got a CTF section? */
46858a2b000SEvgeniy Ivanov 					if (strncmp(".SUNW_ctf",
46958a2b000SEvgeniy Ivanov 					            &shstr[shp[i].sh_name],
47058a2b000SEvgeniy Ivanov 					            10) == 0) {
47158a2b000SEvgeniy Ivanov 						goto havesym;
47258a2b000SEvgeniy Ivanov 					}
47358a2b000SEvgeniy Ivanov 				}
47458a2b000SEvgeniy Ivanov 
47558a2b000SEvgeniy Ivanov 				/* Not loading this, so zero out the offset. */
47658a2b000SEvgeniy Ivanov 				shp[i].sh_offset = 0;
47758a2b000SEvgeniy Ivanov 				break;
47858a2b000SEvgeniy Ivanov 			case SHT_STRTAB:
47958a2b000SEvgeniy Ivanov 				for (j = 0; j < elf->e_shnum; j++)
48058a2b000SEvgeniy Ivanov 					if (shp[j].sh_type == SHT_SYMTAB &&
48158a2b000SEvgeniy Ivanov 					    shp[j].sh_link == (unsigned int)i)
48258a2b000SEvgeniy Ivanov 						goto havesym;
48358a2b000SEvgeniy Ivanov 				/* FALLTHROUGH */
48458a2b000SEvgeniy Ivanov 			default:
48558a2b000SEvgeniy Ivanov 				/* Not loading this, so zero out the offset. */
48658a2b000SEvgeniy Ivanov 				shp[i].sh_offset = 0;
48758a2b000SEvgeniy Ivanov 				break;
48858a2b000SEvgeniy Ivanov 			havesym:
48958a2b000SEvgeniy Ivanov 			case SHT_SYMTAB:
49058a2b000SEvgeniy Ivanov 				if (flags & LOAD_SYM) {
49158a2b000SEvgeniy Ivanov 					PROGRESS(("%s%ld", first ? " [" : "+",
49258a2b000SEvgeniy Ivanov 					    (u_long)shp[i].sh_size));
49358a2b000SEvgeniy Ivanov 					if (lseek(fd, shp[i].sh_offset,
49458a2b000SEvgeniy Ivanov 					    SEEK_SET) == -1) {
49558a2b000SEvgeniy Ivanov 						WARN(("lseek symbols"));
49658a2b000SEvgeniy Ivanov 						goto freeshp;
49758a2b000SEvgeniy Ivanov 					}
49858a2b000SEvgeniy Ivanov 					nr = READ(fd, maxp, shp[i].sh_size);
49958a2b000SEvgeniy Ivanov 					if (nr == -1) {
50058a2b000SEvgeniy Ivanov 						WARN(("read symbols"));
50158a2b000SEvgeniy Ivanov 						goto freeshp;
50258a2b000SEvgeniy Ivanov 					}
50358a2b000SEvgeniy Ivanov 					if (nr != (ssize_t)shp[i].sh_size) {
50458a2b000SEvgeniy Ivanov 						errno = EIO;
50558a2b000SEvgeniy Ivanov 						WARN(("read symbols"));
50658a2b000SEvgeniy Ivanov 						goto freeshp;
50758a2b000SEvgeniy Ivanov 					}
50858a2b000SEvgeniy Ivanov 				}
50958a2b000SEvgeniy Ivanov 				shp[i].sh_offset = maxp - elfp;
51058a2b000SEvgeniy Ivanov 				maxp += roundup(shp[i].sh_size, ELFROUND);
51158a2b000SEvgeniy Ivanov 				first = 0;
51258a2b000SEvgeniy Ivanov 				break;
51358a2b000SEvgeniy Ivanov 			case SHT_NOTE:
51458a2b000SEvgeniy Ivanov 				if ((flags & LOAD_NOTE) == 0)
51558a2b000SEvgeniy Ivanov 					break;
51658a2b000SEvgeniy Ivanov 				if (shp[i].sh_size < sizeof(note)) {
51758a2b000SEvgeniy Ivanov 					shp[i].sh_offset = 0;
51858a2b000SEvgeniy Ivanov 					break;
51958a2b000SEvgeniy Ivanov 				}
52058a2b000SEvgeniy Ivanov 				if (lseek(fd, shp[i].sh_offset, SEEK_SET)
52158a2b000SEvgeniy Ivanov 				    == -1) {
52258a2b000SEvgeniy Ivanov 					WARN(("lseek note"));
52358a2b000SEvgeniy Ivanov 					goto freeshp;
52458a2b000SEvgeniy Ivanov 				}
52558a2b000SEvgeniy Ivanov 				nr = read(fd, &note, sizeof(note));
52658a2b000SEvgeniy Ivanov 				if (nr == -1) {
52758a2b000SEvgeniy Ivanov 					WARN(("read note"));
52858a2b000SEvgeniy Ivanov 					goto freeshp;
52958a2b000SEvgeniy Ivanov 				}
53058a2b000SEvgeniy Ivanov 				if (note.nh.n_namesz ==
53158a2b000SEvgeniy Ivanov 				    ELF_NOTE_NETBSD_NAMESZ &&
53258a2b000SEvgeniy Ivanov 				    note.nh.n_descsz ==
53358a2b000SEvgeniy Ivanov 				    ELF_NOTE_NETBSD_DESCSZ &&
53458a2b000SEvgeniy Ivanov 				    note.nh.n_type ==
53558a2b000SEvgeniy Ivanov 				    ELF_NOTE_TYPE_NETBSD_TAG &&
53658a2b000SEvgeniy Ivanov 				    memcmp(note.name, ELF_NOTE_NETBSD_NAME,
53758a2b000SEvgeniy Ivanov 				    sizeof(note.name)) == 0) {
53858a2b000SEvgeniy Ivanov 					memcpy(&netbsd_version, &note.desc,
53958a2b000SEvgeniy Ivanov 					    sizeof(netbsd_version));
54058a2b000SEvgeniy Ivanov 				}
54158a2b000SEvgeniy Ivanov 				shp[i].sh_offset = 0;
54258a2b000SEvgeniy Ivanov 				break;
54358a2b000SEvgeniy Ivanov 			}
54458a2b000SEvgeniy Ivanov 		}
54558a2b000SEvgeniy Ivanov 		if (flags & LOAD_SYM) {
54658a2b000SEvgeniy Ivanov #ifndef _STANDALONE
54758a2b000SEvgeniy Ivanov 			/* Externalize the section headers. */
54858a2b000SEvgeniy Ivanov 			for (i = 0; i < elf->e_shnum; i++)
54958a2b000SEvgeniy Ivanov 				externalize_shdr(elf->e_ident[EI_DATA],
55058a2b000SEvgeniy Ivanov 				    &shp[i]);
55158a2b000SEvgeniy Ivanov #endif /* ! _STANDALONE */
55258a2b000SEvgeniy Ivanov 			BCOPY(shp, shpp, sz);
55358a2b000SEvgeniy Ivanov 
55458a2b000SEvgeniy Ivanov 			if (first == 0)
55558a2b000SEvgeniy Ivanov 				PROGRESS(("]"));
55658a2b000SEvgeniy Ivanov 		}
55758a2b000SEvgeniy Ivanov 		DEALLOC(shp, sz);
55858a2b000SEvgeniy Ivanov 	}
55958a2b000SEvgeniy Ivanov 
56058a2b000SEvgeniy Ivanov 	if (shstr) {
56184d9c625SLionel Sambuc 	    DEALLOC(shstr, shstrsz);
56258a2b000SEvgeniy Ivanov 	}
56358a2b000SEvgeniy Ivanov 
56458a2b000SEvgeniy Ivanov 	/*
56558a2b000SEvgeniy Ivanov 	 * Frob the copied ELF header to give information relative
56658a2b000SEvgeniy Ivanov 	 * to elfp.
56758a2b000SEvgeniy Ivanov 	 */
56858a2b000SEvgeniy Ivanov 	if (flags & LOAD_HDR) {
56958a2b000SEvgeniy Ivanov 		elf->e_phoff = 0;
57058a2b000SEvgeniy Ivanov 		elf->e_shoff = sizeof(Elf_Ehdr);
57158a2b000SEvgeniy Ivanov 		elf->e_phentsize = 0;
57258a2b000SEvgeniy Ivanov 		elf->e_phnum = 0;
57358a2b000SEvgeniy Ivanov 		externalize_ehdr(elf->e_ident[EI_DATA], elf);
57458a2b000SEvgeniy Ivanov 		BCOPY(elf, elfp, sizeof(*elf));
57558a2b000SEvgeniy Ivanov 		internalize_ehdr(elf->e_ident[EI_DATA], elf);
57658a2b000SEvgeniy Ivanov 	}
57758a2b000SEvgeniy Ivanov 
57858a2b000SEvgeniy Ivanov 	marks[MARK_START] = LOADADDR(minp);
57958a2b000SEvgeniy Ivanov 	marks[MARK_ENTRY] = LOADADDR(elf->e_entry);
58058a2b000SEvgeniy Ivanov 	/*
58158a2b000SEvgeniy Ivanov 	 * Since there can be more than one symbol section in the code
58258a2b000SEvgeniy Ivanov 	 * and we need to find strtab too in order to do anything
58358a2b000SEvgeniy Ivanov 	 * useful with the symbols, we just pass the whole elf
58458a2b000SEvgeniy Ivanov 	 * header back and we let the kernel debugger find the
58558a2b000SEvgeniy Ivanov 	 * location and number of symbols by itself.
58658a2b000SEvgeniy Ivanov 	 */
58758a2b000SEvgeniy Ivanov 	marks[MARK_NSYM] = 1;	/* XXX: Kernel needs >= 0 */
58858a2b000SEvgeniy Ivanov 	marks[MARK_SYM] = LOADADDR(elfp);
58958a2b000SEvgeniy Ivanov 	marks[MARK_END] = LOADADDR(maxp);
59058a2b000SEvgeniy Ivanov 	return 0;
59158a2b000SEvgeniy Ivanov freephdr:
59258a2b000SEvgeniy Ivanov 	DEALLOC(phdr, sz);
59358a2b000SEvgeniy Ivanov 	return 1;
59458a2b000SEvgeniy Ivanov freeshp:
59558a2b000SEvgeniy Ivanov 	DEALLOC(shp, sz);
59658a2b000SEvgeniy Ivanov 	return 1;
59758a2b000SEvgeniy Ivanov }
59858a2b000SEvgeniy Ivanov 
59958a2b000SEvgeniy Ivanov #ifdef TEST
60058a2b000SEvgeniy Ivanov #include <stdlib.h>
60158a2b000SEvgeniy Ivanov #include <fcntl.h>
60258a2b000SEvgeniy Ivanov #include <err.h>
60358a2b000SEvgeniy Ivanov #include <stdio.h>
60458a2b000SEvgeniy Ivanov u_int32_t netbsd_version;
60558a2b000SEvgeniy Ivanov int
main(int argc,char * argv[])60658a2b000SEvgeniy Ivanov main(int argc, char *argv[])
60758a2b000SEvgeniy Ivanov {
60858a2b000SEvgeniy Ivanov 	int fd;
60958a2b000SEvgeniy Ivanov 	u_long marks[MARK_MAX];
61058a2b000SEvgeniy Ivanov 	Elf_Ehdr elf;
61158a2b000SEvgeniy Ivanov 	if (argc != 2) {
61258a2b000SEvgeniy Ivanov 		(void)fprintf(stderr, "Usage: %s <file>\n", getprogname());
61358a2b000SEvgeniy Ivanov 		return 1;
61458a2b000SEvgeniy Ivanov 	}
61558a2b000SEvgeniy Ivanov 	if ((fd = open(argv[1], O_RDONLY)) == -1)
61658a2b000SEvgeniy Ivanov 		err(1, "Can't open `%s'", argv[1]);
61758a2b000SEvgeniy Ivanov 	if (read(fd, &elf, sizeof(elf)) != sizeof(elf))
61858a2b000SEvgeniy Ivanov 		err(1, "Can't read `%s'", argv[1]);
61958a2b000SEvgeniy Ivanov 	memset(marks, 0, sizeof(marks));
62058a2b000SEvgeniy Ivanov 	marks[MARK_START] = (u_long)malloc(2LL * 1024 * 2024 * 1024);
62158a2b000SEvgeniy Ivanov 	ELFNAMEEND(loadfile)(fd, &elf, marks, LOAD_ALL);
62258a2b000SEvgeniy Ivanov 	printf("%d\n", netbsd_version);
62358a2b000SEvgeniy Ivanov 	return 0;
62458a2b000SEvgeniy Ivanov }
62558a2b000SEvgeniy Ivanov #endif
62658a2b000SEvgeniy Ivanov 
62758a2b000SEvgeniy Ivanov #endif /* (ELFSIZE == 32 && BOOT_ELF32) || (ELFSIZE == 64 && BOOT_ELF64) */
628