1*58a2b000SEvgeniy Ivanov /* $NetBSD: loadfile_aout.c,v 1.14 2009/08/16 13:26:16 matt Exp $ */ 2*58a2b000SEvgeniy Ivanov 3*58a2b000SEvgeniy Ivanov /*- 4*58a2b000SEvgeniy Ivanov * Copyright (c) 1997 The NetBSD Foundation, Inc. 5*58a2b000SEvgeniy Ivanov * All rights reserved. 6*58a2b000SEvgeniy Ivanov * 7*58a2b000SEvgeniy Ivanov * This code is derived from software contributed to The NetBSD Foundation 8*58a2b000SEvgeniy Ivanov * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9*58a2b000SEvgeniy Ivanov * NASA Ames Research Center and by Christos Zoulas. 10*58a2b000SEvgeniy Ivanov * 11*58a2b000SEvgeniy Ivanov * Redistribution and use in source and binary forms, with or without 12*58a2b000SEvgeniy Ivanov * modification, are permitted provided that the following conditions 13*58a2b000SEvgeniy Ivanov * are met: 14*58a2b000SEvgeniy Ivanov * 1. Redistributions of source code must retain the above copyright 15*58a2b000SEvgeniy Ivanov * notice, this list of conditions and the following disclaimer. 16*58a2b000SEvgeniy Ivanov * 2. Redistributions in binary form must reproduce the above copyright 17*58a2b000SEvgeniy Ivanov * notice, this list of conditions and the following disclaimer in the 18*58a2b000SEvgeniy Ivanov * documentation and/or other materials provided with the distribution. 19*58a2b000SEvgeniy Ivanov * 20*58a2b000SEvgeniy Ivanov * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21*58a2b000SEvgeniy Ivanov * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22*58a2b000SEvgeniy Ivanov * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23*58a2b000SEvgeniy Ivanov * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24*58a2b000SEvgeniy Ivanov * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25*58a2b000SEvgeniy Ivanov * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26*58a2b000SEvgeniy Ivanov * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27*58a2b000SEvgeniy Ivanov * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28*58a2b000SEvgeniy Ivanov * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29*58a2b000SEvgeniy Ivanov * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30*58a2b000SEvgeniy Ivanov * POSSIBILITY OF SUCH DAMAGE. 31*58a2b000SEvgeniy Ivanov */ 32*58a2b000SEvgeniy Ivanov 33*58a2b000SEvgeniy Ivanov /* 34*58a2b000SEvgeniy Ivanov * Copyright (c) 1992, 1993 35*58a2b000SEvgeniy Ivanov * The Regents of the University of California. All rights reserved. 36*58a2b000SEvgeniy Ivanov * 37*58a2b000SEvgeniy Ivanov * This code is derived from software contributed to Berkeley by 38*58a2b000SEvgeniy Ivanov * Ralph Campbell. 39*58a2b000SEvgeniy Ivanov * 40*58a2b000SEvgeniy Ivanov * Redistribution and use in source and binary forms, with or without 41*58a2b000SEvgeniy Ivanov * modification, are permitted provided that the following conditions 42*58a2b000SEvgeniy Ivanov * are met: 43*58a2b000SEvgeniy Ivanov * 1. Redistributions of source code must retain the above copyright 44*58a2b000SEvgeniy Ivanov * notice, this list of conditions and the following disclaimer. 45*58a2b000SEvgeniy Ivanov * 2. Redistributions in binary form must reproduce the above copyright 46*58a2b000SEvgeniy Ivanov * notice, this list of conditions and the following disclaimer in the 47*58a2b000SEvgeniy Ivanov * documentation and/or other materials provided with the distribution. 48*58a2b000SEvgeniy Ivanov * 3. Neither the name of the University nor the names of its contributors 49*58a2b000SEvgeniy Ivanov * may be used to endorse or promote products derived from this software 50*58a2b000SEvgeniy Ivanov * without specific prior written permission. 51*58a2b000SEvgeniy Ivanov * 52*58a2b000SEvgeniy Ivanov * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53*58a2b000SEvgeniy Ivanov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54*58a2b000SEvgeniy Ivanov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55*58a2b000SEvgeniy Ivanov * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56*58a2b000SEvgeniy Ivanov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57*58a2b000SEvgeniy Ivanov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58*58a2b000SEvgeniy Ivanov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59*58a2b000SEvgeniy Ivanov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60*58a2b000SEvgeniy Ivanov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61*58a2b000SEvgeniy Ivanov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62*58a2b000SEvgeniy Ivanov * SUCH DAMAGE. 63*58a2b000SEvgeniy Ivanov * 64*58a2b000SEvgeniy Ivanov * @(#)boot.c 8.1 (Berkeley) 6/10/93 65*58a2b000SEvgeniy Ivanov */ 66*58a2b000SEvgeniy Ivanov 67*58a2b000SEvgeniy Ivanov #ifdef _STANDALONE 68*58a2b000SEvgeniy Ivanov #include <lib/libsa/stand.h> 69*58a2b000SEvgeniy Ivanov #include <lib/libkern/libkern.h> 70*58a2b000SEvgeniy Ivanov #else 71*58a2b000SEvgeniy Ivanov #include <stdio.h> 72*58a2b000SEvgeniy Ivanov #include <string.h> 73*58a2b000SEvgeniy Ivanov #include <errno.h> 74*58a2b000SEvgeniy Ivanov #include <stdlib.h> 75*58a2b000SEvgeniy Ivanov #include <unistd.h> 76*58a2b000SEvgeniy Ivanov #include <fcntl.h> 77*58a2b000SEvgeniy Ivanov #include <err.h> 78*58a2b000SEvgeniy Ivanov #endif 79*58a2b000SEvgeniy Ivanov 80*58a2b000SEvgeniy Ivanov #include <sys/param.h> 81*58a2b000SEvgeniy Ivanov #include <sys/exec_aout.h> 82*58a2b000SEvgeniy Ivanov 83*58a2b000SEvgeniy Ivanov #include "loadfile.h" 84*58a2b000SEvgeniy Ivanov 85*58a2b000SEvgeniy Ivanov #ifdef BOOT_AOUT 86*58a2b000SEvgeniy Ivanov 87*58a2b000SEvgeniy Ivanov int 88*58a2b000SEvgeniy Ivanov loadfile_aout(int fd, struct exec *x, u_long *marks, int flags) 89*58a2b000SEvgeniy Ivanov { 90*58a2b000SEvgeniy Ivanov u_long entry = x->a_entry; 91*58a2b000SEvgeniy Ivanov paddr_t aoutp = 0; 92*58a2b000SEvgeniy Ivanov paddr_t minp, maxp; 93*58a2b000SEvgeniy Ivanov int cc; 94*58a2b000SEvgeniy Ivanov paddr_t offset = marks[MARK_START]; 95*58a2b000SEvgeniy Ivanov u_long magic = N_GETMAGIC(*x); 96*58a2b000SEvgeniy Ivanov int sub; 97*58a2b000SEvgeniy Ivanov ssize_t nr; 98*58a2b000SEvgeniy Ivanov 99*58a2b000SEvgeniy Ivanov /* some ports dont use the offset */ 100*58a2b000SEvgeniy Ivanov offset = offset; 101*58a2b000SEvgeniy Ivanov 102*58a2b000SEvgeniy Ivanov /* In OMAGIC and NMAGIC, exec header isn't part of text segment */ 103*58a2b000SEvgeniy Ivanov if (magic == OMAGIC || magic == NMAGIC) 104*58a2b000SEvgeniy Ivanov sub = 0; 105*58a2b000SEvgeniy Ivanov else 106*58a2b000SEvgeniy Ivanov sub = sizeof(*x); 107*58a2b000SEvgeniy Ivanov 108*58a2b000SEvgeniy Ivanov minp = maxp = ALIGNENTRY(entry); 109*58a2b000SEvgeniy Ivanov 110*58a2b000SEvgeniy Ivanov if (lseek(fd, sizeof(*x), SEEK_SET) == -1) { 111*58a2b000SEvgeniy Ivanov WARN(("lseek text")); 112*58a2b000SEvgeniy Ivanov return 1; 113*58a2b000SEvgeniy Ivanov } 114*58a2b000SEvgeniy Ivanov 115*58a2b000SEvgeniy Ivanov /* 116*58a2b000SEvgeniy Ivanov * Leave a copy of the exec header before the text. 117*58a2b000SEvgeniy Ivanov * The kernel may use this to verify that the 118*58a2b000SEvgeniy Ivanov * symbols were loaded by this boot program. 119*58a2b000SEvgeniy Ivanov */ 120*58a2b000SEvgeniy Ivanov if (magic == OMAGIC || magic == NMAGIC) { 121*58a2b000SEvgeniy Ivanov if (flags & LOAD_HDR && maxp >= sizeof(*x)) 122*58a2b000SEvgeniy Ivanov BCOPY(x, maxp - sizeof(*x), sizeof(*x)); 123*58a2b000SEvgeniy Ivanov } 124*58a2b000SEvgeniy Ivanov else { 125*58a2b000SEvgeniy Ivanov if (flags & LOAD_HDR) 126*58a2b000SEvgeniy Ivanov BCOPY(x, maxp, sizeof(*x)); 127*58a2b000SEvgeniy Ivanov if (flags & (LOAD_HDR|COUNT_HDR)) 128*58a2b000SEvgeniy Ivanov maxp += sizeof(*x); 129*58a2b000SEvgeniy Ivanov } 130*58a2b000SEvgeniy Ivanov 131*58a2b000SEvgeniy Ivanov /* 132*58a2b000SEvgeniy Ivanov * Read in the text segment. 133*58a2b000SEvgeniy Ivanov */ 134*58a2b000SEvgeniy Ivanov if (flags & LOAD_TEXT) { 135*58a2b000SEvgeniy Ivanov PROGRESS(("%ld", x->a_text)); 136*58a2b000SEvgeniy Ivanov 137*58a2b000SEvgeniy Ivanov nr = READ(fd, maxp, x->a_text - sub); 138*58a2b000SEvgeniy Ivanov if (nr == -1) { 139*58a2b000SEvgeniy Ivanov WARN(("read text")); 140*58a2b000SEvgeniy Ivanov return 1; 141*58a2b000SEvgeniy Ivanov } 142*58a2b000SEvgeniy Ivanov if (nr != (ssize_t)(x->a_text - sub)) { 143*58a2b000SEvgeniy Ivanov errno = EIO; 144*58a2b000SEvgeniy Ivanov WARN(("read text")); 145*58a2b000SEvgeniy Ivanov return 1; 146*58a2b000SEvgeniy Ivanov } 147*58a2b000SEvgeniy Ivanov } else { 148*58a2b000SEvgeniy Ivanov if (lseek(fd, x->a_text - sub, SEEK_CUR) == -1) { 149*58a2b000SEvgeniy Ivanov WARN(("seek text")); 150*58a2b000SEvgeniy Ivanov return 1; 151*58a2b000SEvgeniy Ivanov } 152*58a2b000SEvgeniy Ivanov } 153*58a2b000SEvgeniy Ivanov if (flags & (LOAD_TEXT|COUNT_TEXT)) 154*58a2b000SEvgeniy Ivanov maxp += x->a_text - sub; 155*58a2b000SEvgeniy Ivanov 156*58a2b000SEvgeniy Ivanov /* 157*58a2b000SEvgeniy Ivanov * Provide alignment if required 158*58a2b000SEvgeniy Ivanov */ 159*58a2b000SEvgeniy Ivanov if (magic == ZMAGIC || magic == NMAGIC) { 160*58a2b000SEvgeniy Ivanov int size = -(unsigned int)maxp & (AOUT_LDPGSZ - 1); 161*58a2b000SEvgeniy Ivanov 162*58a2b000SEvgeniy Ivanov if (flags & LOAD_TEXTA) { 163*58a2b000SEvgeniy Ivanov PROGRESS(("/%d", size)); 164*58a2b000SEvgeniy Ivanov BZERO(maxp, size); 165*58a2b000SEvgeniy Ivanov } 166*58a2b000SEvgeniy Ivanov 167*58a2b000SEvgeniy Ivanov if (flags & (LOAD_TEXTA|COUNT_TEXTA)) 168*58a2b000SEvgeniy Ivanov maxp += size; 169*58a2b000SEvgeniy Ivanov } 170*58a2b000SEvgeniy Ivanov 171*58a2b000SEvgeniy Ivanov /* 172*58a2b000SEvgeniy Ivanov * Read in the data segment. 173*58a2b000SEvgeniy Ivanov */ 174*58a2b000SEvgeniy Ivanov if (flags & LOAD_DATA) { 175*58a2b000SEvgeniy Ivanov PROGRESS(("+%ld", x->a_data)); 176*58a2b000SEvgeniy Ivanov 177*58a2b000SEvgeniy Ivanov marks[MARK_DATA] = LOADADDR(maxp); 178*58a2b000SEvgeniy Ivanov nr = READ(fd, maxp, x->a_data); 179*58a2b000SEvgeniy Ivanov if (nr == -1) { 180*58a2b000SEvgeniy Ivanov WARN(("read data")); 181*58a2b000SEvgeniy Ivanov return 1; 182*58a2b000SEvgeniy Ivanov } 183*58a2b000SEvgeniy Ivanov if (nr != (ssize_t)x->a_data) { 184*58a2b000SEvgeniy Ivanov errno = EIO; 185*58a2b000SEvgeniy Ivanov WARN(("read data")); 186*58a2b000SEvgeniy Ivanov return 1; 187*58a2b000SEvgeniy Ivanov } 188*58a2b000SEvgeniy Ivanov } 189*58a2b000SEvgeniy Ivanov else { 190*58a2b000SEvgeniy Ivanov if (lseek(fd, x->a_data, SEEK_CUR) == -1) { 191*58a2b000SEvgeniy Ivanov WARN(("seek data")); 192*58a2b000SEvgeniy Ivanov return 1; 193*58a2b000SEvgeniy Ivanov } 194*58a2b000SEvgeniy Ivanov } 195*58a2b000SEvgeniy Ivanov if (flags & (LOAD_DATA|COUNT_DATA)) 196*58a2b000SEvgeniy Ivanov maxp += x->a_data; 197*58a2b000SEvgeniy Ivanov 198*58a2b000SEvgeniy Ivanov /* 199*58a2b000SEvgeniy Ivanov * Zero out the BSS section. 200*58a2b000SEvgeniy Ivanov * (Kernel doesn't care, but do it anyway.) 201*58a2b000SEvgeniy Ivanov */ 202*58a2b000SEvgeniy Ivanov if (flags & LOAD_BSS) { 203*58a2b000SEvgeniy Ivanov PROGRESS(("+%ld", x->a_bss)); 204*58a2b000SEvgeniy Ivanov 205*58a2b000SEvgeniy Ivanov BZERO(maxp, x->a_bss); 206*58a2b000SEvgeniy Ivanov } 207*58a2b000SEvgeniy Ivanov 208*58a2b000SEvgeniy Ivanov if (flags & (LOAD_BSS|COUNT_BSS)) 209*58a2b000SEvgeniy Ivanov maxp += x->a_bss; 210*58a2b000SEvgeniy Ivanov 211*58a2b000SEvgeniy Ivanov /* 212*58a2b000SEvgeniy Ivanov * Read in the symbol table and strings. 213*58a2b000SEvgeniy Ivanov * (Always set the symtab size word.) 214*58a2b000SEvgeniy Ivanov */ 215*58a2b000SEvgeniy Ivanov if (flags & LOAD_SYM) 216*58a2b000SEvgeniy Ivanov BCOPY(&x->a_syms, maxp, sizeof(x->a_syms)); 217*58a2b000SEvgeniy Ivanov 218*58a2b000SEvgeniy Ivanov if (flags & (LOAD_SYM|COUNT_SYM)) { 219*58a2b000SEvgeniy Ivanov maxp += sizeof(x->a_syms); 220*58a2b000SEvgeniy Ivanov aoutp = maxp; 221*58a2b000SEvgeniy Ivanov } 222*58a2b000SEvgeniy Ivanov 223*58a2b000SEvgeniy Ivanov if (x->a_syms > 0) { 224*58a2b000SEvgeniy Ivanov /* Symbol table and string table length word. */ 225*58a2b000SEvgeniy Ivanov 226*58a2b000SEvgeniy Ivanov if (flags & LOAD_SYM) { 227*58a2b000SEvgeniy Ivanov PROGRESS(("+[%ld", x->a_syms)); 228*58a2b000SEvgeniy Ivanov 229*58a2b000SEvgeniy Ivanov nr = READ(fd, maxp, x->a_syms); 230*58a2b000SEvgeniy Ivanov if (nr == -1) { 231*58a2b000SEvgeniy Ivanov WARN(("read symbols")); 232*58a2b000SEvgeniy Ivanov return 1; 233*58a2b000SEvgeniy Ivanov } 234*58a2b000SEvgeniy Ivanov if (nr != (ssize_t)x->a_syms) { 235*58a2b000SEvgeniy Ivanov errno = EIO; 236*58a2b000SEvgeniy Ivanov WARN(("read symbols")); 237*58a2b000SEvgeniy Ivanov return 1; 238*58a2b000SEvgeniy Ivanov } 239*58a2b000SEvgeniy Ivanov } else { 240*58a2b000SEvgeniy Ivanov if (lseek(fd, x->a_syms, SEEK_CUR) == -1) { 241*58a2b000SEvgeniy Ivanov WARN(("seek symbols")); 242*58a2b000SEvgeniy Ivanov return 1; 243*58a2b000SEvgeniy Ivanov } 244*58a2b000SEvgeniy Ivanov } 245*58a2b000SEvgeniy Ivanov if (flags & (LOAD_SYM|COUNT_SYM)) 246*58a2b000SEvgeniy Ivanov maxp += x->a_syms; 247*58a2b000SEvgeniy Ivanov 248*58a2b000SEvgeniy Ivanov nr = read(fd, &cc, sizeof(cc)); 249*58a2b000SEvgeniy Ivanov if (nr == -1) { 250*58a2b000SEvgeniy Ivanov WARN(("read string table")); 251*58a2b000SEvgeniy Ivanov return 1; 252*58a2b000SEvgeniy Ivanov } 253*58a2b000SEvgeniy Ivanov if (nr != sizeof(cc)) { 254*58a2b000SEvgeniy Ivanov errno = EIO; 255*58a2b000SEvgeniy Ivanov WARN(("read string table")); 256*58a2b000SEvgeniy Ivanov return 1; 257*58a2b000SEvgeniy Ivanov } 258*58a2b000SEvgeniy Ivanov 259*58a2b000SEvgeniy Ivanov if (flags & LOAD_SYM) { 260*58a2b000SEvgeniy Ivanov BCOPY(&cc, maxp, sizeof(cc)); 261*58a2b000SEvgeniy Ivanov 262*58a2b000SEvgeniy Ivanov /* String table. Length word includes itself. */ 263*58a2b000SEvgeniy Ivanov 264*58a2b000SEvgeniy Ivanov PROGRESS(("+%d]", cc)); 265*58a2b000SEvgeniy Ivanov } 266*58a2b000SEvgeniy Ivanov if (flags & (LOAD_SYM|COUNT_SYM)) 267*58a2b000SEvgeniy Ivanov maxp += sizeof(cc); 268*58a2b000SEvgeniy Ivanov 269*58a2b000SEvgeniy Ivanov cc -= sizeof(int); 270*58a2b000SEvgeniy Ivanov if (cc <= 0) { 271*58a2b000SEvgeniy Ivanov WARN(("symbol table too short")); 272*58a2b000SEvgeniy Ivanov return 1; 273*58a2b000SEvgeniy Ivanov } 274*58a2b000SEvgeniy Ivanov 275*58a2b000SEvgeniy Ivanov if (flags & LOAD_SYM) { 276*58a2b000SEvgeniy Ivanov nr = READ(fd, maxp, cc); 277*58a2b000SEvgeniy Ivanov if (nr == -1) { 278*58a2b000SEvgeniy Ivanov WARN(("read strings")); 279*58a2b000SEvgeniy Ivanov return 1; 280*58a2b000SEvgeniy Ivanov } 281*58a2b000SEvgeniy Ivanov if (nr != cc) { 282*58a2b000SEvgeniy Ivanov errno = EIO; 283*58a2b000SEvgeniy Ivanov WARN(("read strings")); 284*58a2b000SEvgeniy Ivanov return 1; 285*58a2b000SEvgeniy Ivanov } 286*58a2b000SEvgeniy Ivanov } else { 287*58a2b000SEvgeniy Ivanov if (lseek(fd, cc, SEEK_CUR) == -1) { 288*58a2b000SEvgeniy Ivanov WARN(("seek strings")); 289*58a2b000SEvgeniy Ivanov return 1; 290*58a2b000SEvgeniy Ivanov } 291*58a2b000SEvgeniy Ivanov } 292*58a2b000SEvgeniy Ivanov if (flags & (LOAD_SYM|COUNT_SYM)) 293*58a2b000SEvgeniy Ivanov maxp += cc; 294*58a2b000SEvgeniy Ivanov } 295*58a2b000SEvgeniy Ivanov 296*58a2b000SEvgeniy Ivanov marks[MARK_START] = LOADADDR(minp); 297*58a2b000SEvgeniy Ivanov marks[MARK_ENTRY] = LOADADDR(entry); 298*58a2b000SEvgeniy Ivanov marks[MARK_NSYM] = x->a_syms; 299*58a2b000SEvgeniy Ivanov marks[MARK_SYM] = LOADADDR(aoutp); 300*58a2b000SEvgeniy Ivanov marks[MARK_END] = LOADADDR(maxp); 301*58a2b000SEvgeniy Ivanov return 0; 302*58a2b000SEvgeniy Ivanov } 303*58a2b000SEvgeniy Ivanov 304*58a2b000SEvgeniy Ivanov #endif /* BOOT_AOUT */ 305