1 /* $NetBSD: load_coff.cpp,v 1.6 2008/04/28 20:23:20 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by UCHIYAMA Yasushi. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <load.h> 33 #include <load_coff.h> 34 #undef DPRINTF // trash coff_machdep.h 's define. 35 #include <console.h> 36 #include <memory.h> 37 #include <file.h> 38 39 CoffLoader::CoffLoader(Console *&cons, MemoryManager *&mem) 40 : Loader(cons, mem) 41 { 42 memset(&_eh, 0, sizeof(struct coff_exechdr)); 43 _fh = &_eh.f; 44 _ah = &_eh.a; 45 46 DPRINTF((TEXT("Loader: COFF\n"))); 47 } 48 49 CoffLoader::~CoffLoader(void) 50 { 51 } 52 53 BOOL 54 CoffLoader::setFile(File *&file) 55 { 56 Loader::setFile(file); 57 58 /* read COFF header and check it */ 59 return read_header(); 60 } 61 62 size_t 63 CoffLoader::memorySize() 64 { 65 size_t sz = _ah->a_tsize + _ah->a_dsize; 66 67 DPRINTF((TEXT("file size: text 0x%x + data 0x%x = 0x%x byte\n"), 68 _ah->a_tsize, _ah->a_dsize, sz)); 69 return sz; 70 } 71 72 kaddr_t 73 CoffLoader::jumpAddr() 74 { 75 76 DPRINTF((TEXT("kernel entry address: 0x%08x\n"), _ah->a_entry)); 77 78 return _ah->a_entry; 79 } 80 81 BOOL 82 CoffLoader::load() 83 { 84 size_t filesz; 85 size_t memsz; 86 vaddr_t kv; 87 off_t fileofs; 88 89 /* start tag chain */ 90 _load_segment_start(); 91 92 /* text */ 93 filesz = memsz = _ah->a_tsize; 94 kv = _ah->a_tstart; 95 fileofs = COFF_ROUND(N_TXTOFF(_fh, _ah), 16); 96 DPRINTF((TEXT("[text]"))); 97 _load_segment(kv, memsz, fileofs, filesz); 98 /* data */ 99 fileofs += filesz; 100 filesz = memsz = _ah->a_dsize; 101 kv = _ah->a_dstart; 102 DPRINTF((TEXT("[data]"))); 103 _load_segment(kv, memsz, fileofs, filesz); 104 /* bss */ 105 filesz = 0; 106 memsz = _ah->a_bsize; 107 kv = _ah->a_dstart + _ah->a_dsize; 108 fileofs = 0; 109 DPRINTF((TEXT("[bss ]"))); 110 _load_segment(kv, memsz, fileofs, filesz); 111 112 /* tag chain still opening */ 113 return _load_success(); 114 } 115 116 BOOL 117 CoffLoader::read_header(void) 118 { 119 #ifndef COFF_BADMAG 120 DPRINTF((TEXT("coff loader not implemented.\n"))); 121 return FALSE; 122 #else 123 // read COFF header 124 _file->read(&_eh, sizeof(struct coff_exechdr), 0); 125 126 // check COFF Magic. 127 if (COFF_BADMAG(_fh)) { 128 DPRINTF((TEXT("not a COFF file.\n"))); 129 return FALSE; 130 } 131 132 return TRUE; 133 #endif 134 } 135