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 * 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(int fd, struct ecoff_exechdr *coff, u_long *marks, int flags) 62 { 63 paddr_t offset = marks[MARK_START]; 64 paddr_t minp = ~0, maxp = 0, pos; 65 ssize_t nr; 66 67 /* some ports dont use the offset */ 68 offset = offset; 69 70 /* Read in text. */ 71 if (lseek(fd, ECOFF_TXTOFF(coff), SEEK_SET) == -1) { 72 WARN(("lseek text")); 73 return 1; 74 } 75 76 if (coff->a.tsize != 0) { 77 if (flags & LOAD_TEXT) { 78 PROGRESS(("%lu", coff->a.tsize)); 79 nr = READ(fd, coff->a.text_start, coff->a.tsize); 80 if (nr == -1) { 81 return 1; 82 } 83 if (nr != coff->a.tsize) { 84 errno = EIO; 85 return 1; 86 } 87 } 88 else { 89 if (lseek(fd, coff->a.tsize, SEEK_CUR) == -1) { 90 WARN(("read text")); 91 return 1; 92 } 93 } 94 if (flags & (COUNT_TEXT|LOAD_TEXT)) { 95 pos = coff->a.text_start; 96 if (minp > pos) 97 minp = pos; 98 pos += coff->a.tsize; 99 if (maxp < pos) 100 maxp = pos; 101 } 102 } 103 104 /* Read in data. */ 105 if (coff->a.dsize != 0) { 106 if (flags & LOAD_DATA) { 107 PROGRESS(("+%lu", coff->a.dsize)); 108 nr = READ(fd, coff->a.data_start, coff->a.dsize); 109 if (nr == -1) { 110 WARN(("read data")); 111 return 1; 112 } 113 if (nr != coff->a.dsize) { 114 errno = EIO; 115 WARN(("read data")); 116 return 1; 117 } 118 } 119 if (flags & (COUNT_DATA|LOAD_DATA)) { 120 pos = coff->a.data_start; 121 if (minp > pos) 122 minp = pos; 123 pos += coff->a.dsize; 124 if (maxp < pos) 125 maxp = pos; 126 } 127 } 128 129 /* Zero out bss. */ 130 if (coff->a.bsize != 0) { 131 if (flags & LOAD_BSS) { 132 PROGRESS(("+%lu", coff->a.bsize)); 133 BZERO(coff->a.bss_start, coff->a.bsize); 134 } 135 if (flags & (COUNT_BSS|LOAD_BSS)) { 136 pos = coff->a.bss_start; 137 if (minp > pos) 138 minp = pos; 139 pos = coff->a.bsize; 140 if (maxp < pos) 141 maxp = pos; 142 } 143 } 144 145 marks[MARK_START] = LOADADDR(minp); 146 marks[MARK_ENTRY] = LOADADDR(coff->a.entry); 147 marks[MARK_NSYM] = 1; /* XXX: Kernel needs >= 0 */ 148 marks[MARK_SYM] = LOADADDR(maxp); 149 marks[MARK_END] = LOADADDR(maxp); 150 marks[MARK_DATA] = LOADADDR(coff->a.data_start); 151 return 0; 152 } 153 154 #endif /* BOOT_ECOFF */ 155