1 /* $OpenBSD: mopa.out.c,v 1.19 2024/10/16 18:47:48 miod 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 <a.out.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 83 u_char header[512]; /* The MOP header we generate is 1 block. */ 84 #if !defined(NOAOUT) 85 struct exec ex, ex_swap; 86 #endif 87 88 int 89 main (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