1/* $NetBSD: loadfile_ecoff.c,v 1.11 2007/12/29 17:54:42 tsutsui Exp $ */ 2 3/*- 4 * Copyright (c) 1997 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center and by Christos Zoulas. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#ifdef _STANDALONE 34#include <lib/libsa/stand.h> 35#include <lib/libkern/libkern.h> 36#else 37#include <stdio.h> 38#include <string.h> 39#include <errno.h> 40#include <stdlib.h> 41#include <unistd.h> 42#include <fcntl.h> 43#include <err.h> 44#endif 45 46#include <sys/param.h> 47#include <sys/exec.h> 48 49#include "loadfile.h" 50 51#ifdef BOOT_ECOFF 52 53int 54loadfile_coff(int fd, struct ecoff_exechdr *coff, u_long *marks, int flags) 55{ 56 paddr_t offset = marks[MARK_START]; 57 paddr_t minp = ~0, maxp = 0, pos; 58 ssize_t nr; 59 60 /* some ports dont use the offset */ 61 offset = offset; 62 63 /* Read in text. */ 64 if (lseek(fd, ECOFF_TXTOFF(coff), SEEK_SET) == -1) { 65 WARN(("lseek text")); 66 return 1; 67 } 68 69 if (coff->a.tsize != 0) { 70 if (flags & LOAD_TEXT) { 71 PROGRESS(("%lu", coff->a.tsize)); 72 nr = READ(fd, coff->a.text_start, coff->a.tsize); 73 if (nr == -1) { 74 return 1; 75 } 76 if (nr != coff->a.tsize) { 77 errno = EIO; 78 return 1; 79 } 80 } 81 else { 82 if (lseek(fd, coff->a.tsize, SEEK_CUR) == -1) { 83 WARN(("read text")); 84 return 1; 85 } 86 } 87 if (flags & (COUNT_TEXT|LOAD_TEXT)) { 88 pos = coff->a.text_start; 89 if (minp > pos) 90 minp = pos; 91 pos += coff->a.tsize; 92 if (maxp < pos) 93 maxp = pos; 94 } 95 } 96 97 /* Read in data. */ 98 if (coff->a.dsize != 0) { 99 if (flags & LOAD_DATA) { 100 PROGRESS(("+%lu", coff->a.dsize)); 101 nr = READ(fd, coff->a.data_start, coff->a.dsize); 102 if (nr == -1) { 103 WARN(("read data")); 104 return 1; 105 } 106 if (nr != coff->a.dsize) { 107 errno = EIO; 108 WARN(("read data")); 109 return 1; 110 } 111 } 112 if (flags & (COUNT_DATA|LOAD_DATA)) { 113 pos = coff->a.data_start; 114 if (minp > pos) 115 minp = pos; 116 pos += coff->a.dsize; 117 if (maxp < pos) 118 maxp = pos; 119 } 120 } 121 122 /* Zero out bss. */ 123 if (coff->a.bsize != 0) { 124 if (flags & LOAD_BSS) { 125 PROGRESS(("+%lu", coff->a.bsize)); 126 BZERO(coff->a.bss_start, coff->a.bsize); 127 } 128 if (flags & (COUNT_BSS|LOAD_BSS)) { 129 pos = coff->a.bss_start; 130 if (minp > pos) 131 minp = pos; 132 pos = coff->a.bsize; 133 if (maxp < pos) 134 maxp = pos; 135 } 136 } 137 138 marks[MARK_START] = LOADADDR(minp); 139 marks[MARK_ENTRY] = LOADADDR(coff->a.entry); 140 marks[MARK_NSYM] = 1; /* XXX: Kernel needs >= 0 */ 141 marks[MARK_SYM] = LOADADDR(maxp); 142 marks[MARK_END] = LOADADDR(maxp); 143 marks[MARK_DATA] = LOADADDR(coff->a.data_start); 144 return 0; 145} 146 147#endif /* BOOT_ECOFF */ 148