1/* $OpenBSD: mopa.out.c,v 1.18 2022/12/28 21:30:17 jmc Exp $ */ 2 3/* 4 * mopa.out - Convert a Unix format kernel into something that 5 * can be transferred via MOP. 6 * 7 * This code was written while referring to the NetBSD/vax boot 8 * loader. Therefore anything that can be booted by the Vax 9 * should be convertible with this program. 10 * 11 * If necessary, the a.out header is stripped, and the program 12 * segments are padded out. The BSS segment is zero filled. 13 * A header is prepended that looks like an IHD header. In 14 * particular the Unix machine ID is placed where mopd expects 15 * the image type to be (offset is IHD_W_ALIAS). If the machine 16 * ID could be mistaken for a DEC image type, then the conversion 17 * is aborted. The original a.out header is copied into the front 18 * of the header so that once we have detected the Unix machine 19 * ID we can haul the load address and the xfer address out. 20 */ 21 22/* 23 * Copyright (c) 1996 Lloyd Parkes. All rights reserved. 24 * 25 * Redistribution and use in source and binary forms, with or without 26 * modification, are permitted provided that the following conditions 27 * are met: 28 * 1. Redistributions of source code must retain the above copyright 29 * notice, this list of conditions and the following disclaimer. 30 * 2. Redistributions in binary form must reproduce the above copyright 31 * notice, this list of conditions and the following disclaimer in the 32 * documentation and/or other materials provided with the distribution. 33 * 3. All advertising materials mentioning features or use of this software 34 * must display the following acknowledgement: 35 * This product includes software developed by Lloyd Parkes. 36 * 4. The name of the author may not be used to endorse or promote products 37 * derived from this software without specific prior written permission. 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 40 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 41 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 42 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 43 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 45 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 46 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 47 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 48 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 49 */ 50 51#include "os.h" 52#include "common/common.h" 53#include "common/mopdef.h" 54#include "common/file.h" 55#if defined(__OpenBSD__) 56#include <sys/exec.h> 57#endif 58#if defined(__FreeBSD__) 59#include <sys/imgact_aout.h> 60#endif 61#if defined(__bsdi__) 62#include <a.out.h> 63#define NOAOUT 64#endif 65#if !defined(MID_VAX) 66#define MID_VAX 140 67#endif 68 69#ifndef NOELF 70#if defined(__NetBSD__) || defined(__OpenBSD__) 71#include <elf.h> 72#else 73#define NOELF 74#endif 75#endif 76 77#ifndef NOELF 78#if !defined(_LP64) 79#define NOELF64 80#endif 81#endif 82 83u_char header[512]; /* The MOP header we generate is 1 block. */ 84#if !defined(NOAOUT) 85struct exec ex, ex_swap; 86#endif 87 88int 89main (int argc, char **argv) 90{ 91 FILE *out; /* A FILE because that is easier. */ 92 int i, j; 93 struct dllist dl; 94 short image_type; 95 96#ifdef NOAOUT 97 fprintf(stderr, "%s: has no function in OS/BSD\n", argv[0]); 98 return(1); 99#endif 100 101 if (argc != 3) { 102 fprintf (stderr, "usage: %s infile outfile\n", argv[0]); 103 return (1); 104 } 105 106 dl.ldfd = open (argv[1], O_RDONLY); 107 if (dl.ldfd == -1) 108 err(2, "open `%s'", argv[1]); 109 110 if (GetFileInfo(&dl, 0) == -1) 111 errx(3, "`%s' is an unknown file type", argv[1]); 112 113 switch (dl.image_type) { 114 case IMAGE_TYPE_MOP: 115 errx(3, "`%s' is already a MOP image", argv[1]); 116 break; 117 118#ifndef NOELF 119 case IMAGE_TYPE_ELF32: 120 if (dl.e_machine != EM_VAX) 121 printf("WARNING: `%s' is not a VAX image " 122 "(machine=%d)\n", argv[1], dl.e_machine); 123 for (i = 0, j = 0; j < dl.e_nsec; j++) 124 i += dl.e_sections[j].s_fsize + dl.e_sections[j].s_pad; 125 image_type = IHD_C_NATIVE; 126 break; 127#endif 128 129#if !defined(NOELF) && !defined(NOELF64) 130 case IMAGE_TYPE_ELF64: 131 if (dl.e_machine != EM_ALPHA && dl.e_machine != EM_ALPHA_EXP) 132 printf("WARNING: `%s' is not an ALPHA image " 133 "(machine=%d)\n", argv[1], dl.e_machine); 134 for (i = 0, j = 0; j < dl.e_nsec; j++) 135 i += dl.e_sections[j].s_fsize + dl.e_sections[j].s_pad; 136 image_type = IHD_C_ALPHA; 137 break; 138#endif 139 140#ifndef NOAOUT 141 case IMAGE_TYPE_AOUT: 142 if (dl.a_mid != MID_VAX) 143 printf("WARNING: `%s' is not a VAX image (mid=%d)\n", 144 argv[1], dl.a_mid); 145 i = dl.a_text + dl.a_text_fill + dl.a_data + dl.a_data_fill + 146 dl.a_bss + dl.a_bss_fill; 147 image_type = IHD_C_NATIVE; 148 break; 149#endif 150 151 default: 152 errx(3, "Image type `%s' not supported", 153 FileTypeName(dl.image_type)); 154 } 155 156 dl.nloadaddr = dl.loadaddr; 157 dl.lseek = lseek(dl.ldfd,0L,SEEK_CUR); 158 dl.a_lseek = 0; 159 dl.count = 0; 160 dl.dl_bsz = 512; 161 162 switch (image_type) { 163 default: 164 case IHD_C_NATIVE: 165 /* Offset to ISD section. */ 166 mopFilePutLX(header, IHD_W_SIZE, 0xd4, 2); 167 /* Offset to 1st section.*/ 168 mopFilePutLX(header, IHD_W_ACTIVOFF, 0x30, 2); 169 /* It's a VAX image.*/ 170 mopFilePutLX(header, IHD_W_ALIAS, IHD_C_NATIVE, 2); 171 /* Only one header block. */ 172 mopFilePutLX(header, IHD_B_HDRBLKCNT, 1, 1); 173 174 /* Xfer Addr */ 175 mopFilePutLX(header, 0x30 + IHA_L_TFRADR1, dl.xferaddr, 4); 176 177 /* load Addr */ 178 mopFilePutLX(header, 0xd4 + ISD_V_VPN, dl.loadaddr / 512, 2); 179 /* Imagesize in blks.*/ 180 i = (i + 1) / 512; 181 mopFilePutLX(header, 0xd4 + ISD_W_PAGCNT, i, 2); 182 break; 183 case IHD_C_ALPHA: 184 /* Offset to ISD section. */ 185 mopFilePutLX(header, EIHD_L_ISDOFF, 0xd4, 4); 186 /* It's an alpha image.*/ 187 mopFilePutLX(header, IHD_W_ALIAS, IHD_C_ALPHA, 2); 188 /* Only one header block. */ 189 mopFilePutLX(header, EIHD_L_HDRBLKCNT, 1, 4); 190 191 /* Imagesize in bytes.*/ 192 mopFilePutLX(header, 0xd4 + EISD_L_SECSIZE, i, 4); 193 break; 194 } 195 196 out = fopen (argv[2], "w"); 197 if (!out) 198 err(2, "writing `%s'", argv[2]); 199 200 /* Now we do the actual work. Write MOP-image header */ 201 202 fwrite (header, sizeof (header), 1, out); 203 204 switch (dl.image_type) { 205 case IMAGE_TYPE_MOP: 206 abort(); 207 208 case IMAGE_TYPE_ELF32: 209#ifdef NOELF 210 abort(); 211#else 212 fprintf(stderr, "copying "); 213 for (j = 0; j < dl.e_nsec; j++) 214 fprintf(stderr, "%s%u+%u", j == 0 ? "" : "+", 215 dl.e_sections[j].s_fsize, 216 dl.e_sections[j].s_pad); 217 fprintf(stderr, "->0x%x\n", dl.xferaddr); 218#endif 219 break; 220 221 case IMAGE_TYPE_AOUT: 222#ifdef NOAOUT 223 abort(); 224#else 225 fprintf(stderr, "copying %u+%u+%u->0x%x\n", dl.a_text, 226 dl.a_data, dl.a_bss, dl.xferaddr); 227#endif 228 break; 229 default: 230 break; 231 } 232 233 while ((i = mopFileRead(&dl,header)) > 0) { 234 (void)fwrite(header, i, 1, out); 235 } 236 237 fclose (out); 238 exit(0); 239} 240