1 /* $NetBSD: loadfile_ecoff.c,v 1.10 2007/12/03 09:51:30 isaki 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 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 #ifdef _STANDALONE 41 #include <lib/libsa/stand.h> 42 #include <lib/libkern/libkern.h> 43 #else 44 #include <stdio.h> 45 #include <string.h> 46 #include <errno.h> 47 #include <stdlib.h> 48 #include <unistd.h> 49 #include <fcntl.h> 50 #include <err.h> 51 #endif 52 53 #include <sys/param.h> 54 #include <sys/exec.h> 55 56 #include "loadfile.h" 57 58 #ifdef BOOT_ECOFF 59 60 int 61 loadfile_coff(fd, coff, marks, flags) 62 int fd; 63 struct ecoff_exechdr *coff; 64 u_long *marks; 65 int flags; 66 { 67 paddr_t offset = marks[MARK_START]; 68 paddr_t minp = ~0, maxp = 0, pos; 69 ssize_t nr; 70 71 /* some ports dont use the offset */ 72 offset = offset; 73 74 /* Read in text. */ 75 if (lseek(fd, ECOFF_TXTOFF(coff), SEEK_SET) == -1) { 76 WARN(("lseek text")); 77 return 1; 78 } 79 80 if (coff->a.tsize != 0) { 81 if (flags & LOAD_TEXT) { 82 PROGRESS(("%lu", coff->a.tsize)); 83 nr = READ(fd, coff->a.text_start, coff->a.tsize); 84 if (nr == -1) { 85 return 1; 86 } 87 if (nr != coff->a.tsize) { 88 errno = EIO; 89 return 1; 90 } 91 } 92 else { 93 if (lseek(fd, coff->a.tsize, SEEK_CUR) == -1) { 94 WARN(("read text")); 95 return 1; 96 } 97 } 98 if (flags & (COUNT_TEXT|LOAD_TEXT)) { 99 pos = coff->a.text_start; 100 if (minp > pos) 101 minp = pos; 102 pos += coff->a.tsize; 103 if (maxp < pos) 104 maxp = pos; 105 } 106 } 107 108 /* Read in data. */ 109 if (coff->a.dsize != 0) { 110 if (flags & LOAD_DATA) { 111 PROGRESS(("+%lu", coff->a.dsize)); 112 nr = READ(fd, coff->a.data_start, coff->a.dsize); 113 if (nr == -1) { 114 WARN(("read data")); 115 return 1; 116 } 117 if (nr != coff->a.dsize) { 118 errno = EIO; 119 WARN(("read data")); 120 return 1; 121 } 122 } 123 if (flags & (COUNT_DATA|LOAD_DATA)) { 124 pos = coff->a.data_start; 125 if (minp > pos) 126 minp = pos; 127 pos += coff->a.dsize; 128 if (maxp < pos) 129 maxp = pos; 130 } 131 } 132 133 /* Zero out bss. */ 134 if (coff->a.bsize != 0) { 135 if (flags & LOAD_BSS) { 136 PROGRESS(("+%lu", coff->a.bsize)); 137 BZERO(coff->a.bss_start, coff->a.bsize); 138 } 139 if (flags & (COUNT_BSS|LOAD_BSS)) { 140 pos = coff->a.bss_start; 141 if (minp > pos) 142 minp = pos; 143 pos = coff->a.bsize; 144 if (maxp < pos) 145 maxp = pos; 146 } 147 } 148 149 marks[MARK_START] = LOADADDR(minp); 150 marks[MARK_ENTRY] = LOADADDR(coff->a.entry); 151 marks[MARK_NSYM] = 1; /* XXX: Kernel needs >= 0 */ 152 marks[MARK_SYM] = LOADADDR(maxp); 153 marks[MARK_END] = LOADADDR(maxp); 154 marks[MARK_DATA] = LOADADDR(coff->a.data_start); 155 return 0; 156 } 157 158 #endif /* BOOT_ECOFF */ 159