|
|
1.1 ! root 1: #include <u.h> ! 2: #include <libc.h> ! 3: #include <bio.h> ! 4: #include <bootexec.h> ! 5: #include <mach.h> ! 6: ! 7: /* ! 8: * All a.out header types. The dummy entry allows canonical ! 9: * processing of the union as a sequence of longs ! 10: */ ! 11: ! 12: typedef struct { ! 13: union{ ! 14: Exec; /* in a.out.h */ ! 15: struct mipsexec; /* Hobbit uses this header too */ ! 16: struct mips4kexec; ! 17: struct sparcexec; ! 18: struct nextexec; ! 19: struct i960exec; ! 20: } e; ! 21: long dummy; /* padding to ensure extra long */ ! 22: } ExecHdr; ! 23: ! 24: static void i960boot(Fhdr *, ExecHdr *); ! 25: static void nextboot(Fhdr *, ExecHdr *); ! 26: static void sparcboot(Fhdr *, ExecHdr *); ! 27: static void mipsboot(Fhdr *, ExecHdr *); ! 28: static void mips4kboot(Fhdr *, ExecHdr *); ! 29: static void common(Fhdr *, ExecHdr *); ! 30: static void adotout(Fhdr *, ExecHdr *); ! 31: static void setsym(Fhdr *, long, long, long, long); ! 32: static void setdata(Fhdr *, long, long, long, long); ! 33: static void settext(Fhdr *, long, long, long, long); ! 34: static void hswal(long *, int, long (*) (long)); ! 35: static long _round(long, long); ! 36: ! 37: /* ! 38: * definition of per-executable file type structures ! 39: */ ! 40: ! 41: typedef struct Exectable{ ! 42: long magic; /* big-endian magic number of file */ ! 43: char *name; /* executable identifier */ ! 44: int type; /* Internal code */ ! 45: Mach *mach; /* Per-machine data */ ! 46: ulong hsize; /* header size */ ! 47: long (*swal)(long); /* beswal or leswal */ ! 48: void (*hparse)(Fhdr *, ExecHdr *); ! 49: } ExecTable; ! 50: ! 51: extern Mach mmips; ! 52: extern Mach msparc; ! 53: extern Mach m68020; ! 54: extern Mach mi386; ! 55: extern Mach mi960; ! 56: extern Mach m3210; ! 57: ! 58: ExecTable exectab[] = ! 59: { ! 60: { V_MAGIC, /* Mips v.out */ ! 61: "mips plan 9 executable", ! 62: FMIPS, ! 63: &mmips, ! 64: sizeof(Exec), ! 65: beswal, ! 66: adotout }, ! 67: { 0x160<<16, /* Mips boot image */ ! 68: "mips plan 9 boot image", ! 69: FMIPSB, ! 70: &mmips, ! 71: sizeof(struct mipsexec), ! 72: beswal, ! 73: mipsboot }, ! 74: { (0x160<<16)|3, /* Mips boot image */ ! 75: "mips 4k plan 9 boot image", ! 76: FMIPSB, ! 77: &mmips, ! 78: sizeof(struct mips4kexec), ! 79: beswal, ! 80: mips4kboot }, ! 81: { K_MAGIC, /* Sparc k.out */ ! 82: "sparc plan 9 executable", ! 83: FSPARC, ! 84: &msparc, ! 85: sizeof(Exec), ! 86: beswal, ! 87: adotout }, ! 88: { 0x01030107, /* Sparc boot image */ ! 89: "sparc plan 9 boot image", ! 90: FSPARCB, ! 91: &msparc, ! 92: sizeof(struct sparcexec), ! 93: beswal, ! 94: sparcboot }, ! 95: { A_MAGIC, /* 68020 2.out & boot image */ ! 96: "68020 plan 9 executable", ! 97: F68020, ! 98: &m68020, ! 99: sizeof(Exec), ! 100: beswal, ! 101: common }, ! 102: { 0xFEEDFACE, /* Next boot image */ ! 103: "next plan 9 boot image", ! 104: FNEXTB, ! 105: &m68020, ! 106: sizeof(struct nextexec), ! 107: beswal, ! 108: nextboot }, ! 109: { I_MAGIC, /* I386 8.out & boot image */ ! 110: "386 plan 9 executable", ! 111: FI386, ! 112: &mi386, ! 113: sizeof(Exec), ! 114: beswal, ! 115: common }, ! 116: { J_MAGIC, /* I960 6.out (big-endian) */ ! 117: "960 plan 9 executable", ! 118: FI960, ! 119: &mi960, ! 120: sizeof(Exec), ! 121: beswal, ! 122: adotout }, ! 123: { 0x61010200, /* I960 boot image (little endian) */ ! 124: "960 plan 9 boot image", ! 125: FI960B, ! 126: &mi960, ! 127: sizeof(struct i960exec), ! 128: leswal, ! 129: i960boot }, ! 130: { X_MAGIC, /* 3210 x.out */ ! 131: "3210 plan 9 executable", ! 132: F3210, ! 133: &m3210, ! 134: sizeof(Exec), ! 135: beswal, ! 136: adotout }, ! 137: { 0 }, ! 138: }; ! 139: ! 140: Mach *mach = &mmips; /* Global current machine table */ ! 141: ! 142: int ! 143: crackhdr(int fd, Fhdr *fp) ! 144: { ! 145: ExecTable *mp; ! 146: ExecHdr d; ! 147: int nb, magic; ! 148: ! 149: fp->type = FNONE; ! 150: if ((nb = read(fd, (char *)&d.e, sizeof(d.e))) <= 0) ! 151: return 0; ! 152: fp->magic = magic = beswal(d.e.magic); /* big-endian */ ! 153: for (mp = exectab; mp->magic; mp++) { ! 154: if (mp->magic == magic && nb >= mp->hsize) { ! 155: hswal((long *) &d, sizeof(d.e)/sizeof(long), mp->swal); ! 156: fp->type = mp->type; ! 157: fp->name = mp->name; ! 158: fp->hdrsz = mp->hsize; /* zero on bootables */ ! 159: mach = mp->mach; ! 160: mp->hparse(fp, &d); ! 161: seek(fd, mp->hsize, 0); /* seek to end of header */ ! 162: return 1; ! 163: } ! 164: } ! 165: return 0; ! 166: } ! 167: /* ! 168: * Convert header to canonical form ! 169: */ ! 170: static void ! 171: hswal(long *lp, int n, long (*swap) (long)) ! 172: { ! 173: while (n--) { ! 174: *lp = (*swap) (*lp); ! 175: lp++; ! 176: } ! 177: } ! 178: /* ! 179: * Crack a normal a.out-type header ! 180: */ ! 181: static void ! 182: adotout(Fhdr *fp, ExecHdr *hp) ! 183: { ! 184: long pgsize = mach->pgsize; ! 185: ! 186: settext(fp, hp->e.entry, pgsize+sizeof(Exec), ! 187: hp->e.text, sizeof(Exec)); ! 188: setdata(fp, _round(pgsize+fp->txtsz+sizeof(Exec), pgsize), ! 189: hp->e.data, fp->txtsz+sizeof(Exec), hp->e.bss); ! 190: setsym(fp, hp->e.syms, hp->e.spsz, hp->e.pcsz, fp->datoff+fp->datsz); ! 191: } ! 192: ! 193: /* ! 194: * 68020 2.out and 68020 bootable images ! 195: * 386I 8.out and 386I bootable images ! 196: * ! 197: */ ! 198: static void ! 199: common(Fhdr *fp, ExecHdr *hp) ! 200: { ! 201: long kbase = mach->kbase; ! 202: ! 203: adotout(fp, hp); ! 204: if (fp->entry & kbase) { /* Boot image */ ! 205: switch(fp->type) { ! 206: case F68020: ! 207: fp->type = F68020B; ! 208: fp->name = "68020 plan 9 boot image"; ! 209: fp->hdrsz = 0; /* header stripped */ ! 210: break; ! 211: case FI386: ! 212: fp->type = FI386B; ! 213: fp->txtaddr = sizeof(Exec); ! 214: fp->name = "386 plan 9 boot image"; ! 215: fp->hdrsz = 0; /* header stripped */ ! 216: fp->dataddr = fp->txtaddr+fp->txtsz; ! 217: break; ! 218: default: ! 219: break; ! 220: } ! 221: fp->txtaddr |= kbase; ! 222: fp->entry |= kbase; ! 223: fp->dataddr |= kbase; ! 224: } ! 225: } ! 226: ! 227: /* ! 228: * mips bootable image. ! 229: */ ! 230: static void ! 231: mipsboot(Fhdr *fp, ExecHdr *hp) ! 232: { ! 233: switch(hp->e.amagic) { ! 234: default: ! 235: case 0407: /* some kind of mips */ ! 236: fp->type = FMIPSB; ! 237: settext(fp, hp->e.mentry, hp->e.text_start, hp->e.tsize, ! 238: sizeof(struct mipsexec)+4); ! 239: setdata(fp, hp->e.data_start, hp->e.dsize, ! 240: fp->txtoff+hp->e.tsize, hp->e.bsize); ! 241: break; ! 242: case 0413: /* some kind of mips */ ! 243: fp->type = FMIPSB; ! 244: settext(fp, hp->e.mentry, hp->e.text_start, hp->e.tsize, 0); ! 245: setdata(fp, hp->e.data_start, hp->e.dsize, hp->e.tsize, ! 246: hp->e.bsize); ! 247: break; ! 248: } ! 249: setsym(fp, hp->e.nsyms, 0, hp->e.pcsize, hp->e.symptr); ! 250: fp->hdrsz = 0; /* header stripped */ ! 251: } ! 252: ! 253: /* ! 254: * mips4k bootable image. ! 255: */ ! 256: static void ! 257: mips4kboot(Fhdr *fp, ExecHdr *hp) ! 258: { ! 259: switch(hp->e.h.amagic) { ! 260: default: ! 261: case 0407: /* some kind of mips */ ! 262: fp->type = FMIPSB; ! 263: settext(fp, hp->e.h.mentry, hp->e.h.text_start, hp->e.h.tsize, ! 264: sizeof(struct mips4kexec)); ! 265: setdata(fp, hp->e.h.data_start, hp->e.h.dsize, ! 266: fp->txtoff+hp->e.h.tsize, hp->e.h.bsize); ! 267: break; ! 268: case 0413: /* some kind of mips */ ! 269: fp->type = FMIPSB; ! 270: settext(fp, hp->e.h.mentry, hp->e.h.text_start, hp->e.h.tsize, 0); ! 271: setdata(fp, hp->e.h.data_start, hp->e.h.dsize, hp->e.h.tsize, ! 272: hp->e.h.bsize); ! 273: break; ! 274: } ! 275: setsym(fp, hp->e.h.nsyms, 0, hp->e.h.pcsize, hp->e.h.symptr); ! 276: fp->hdrsz = 0; /* header stripped */ ! 277: } ! 278: ! 279: /* ! 280: * sparc bootable image ! 281: */ ! 282: static void ! 283: sparcboot(Fhdr *fp, ExecHdr *hp) ! 284: { ! 285: fp->type = FSPARCB; ! 286: settext(fp, hp->e.sentry, hp->e.sentry, hp->e.stext, ! 287: sizeof(struct sparcexec)); ! 288: setdata(fp, hp->e.sentry+hp->e.stext, hp->e.sdata, ! 289: fp->txtoff+hp->e.stext, hp->e.sbss); ! 290: setsym(fp, hp->e.ssyms, 0, hp->e.sdrsize, fp->datoff+hp->e.sdata); ! 291: fp->hdrsz = 0; /* header stripped */ ! 292: } ! 293: ! 294: /* ! 295: * next bootable image ! 296: */ ! 297: static void ! 298: nextboot(Fhdr *fp, ExecHdr *hp) ! 299: { ! 300: fp->type = FNEXTB; ! 301: settext(fp, hp->e.textc.vmaddr, hp->e.textc.vmaddr, ! 302: hp->e.texts.size, hp->e.texts.offset); ! 303: setdata(fp, hp->e.datac.vmaddr, hp->e.datas.size, ! 304: hp->e.datas.offset, hp->e.bsss.size); ! 305: setsym(fp, hp->e.symc.nsyms, hp->e.symc.spoff, hp->e.symc.pcoff, ! 306: hp->e.symc.symoff); ! 307: fp->hdrsz = 0; /* header stripped */ ! 308: } ! 309: ! 310: /* ! 311: * I960 bootable image ! 312: */ ! 313: static void ! 314: i960boot(Fhdr *fp, ExecHdr *hp) ! 315: { ! 316: /* long n = hp->e.i6comments.fptrlineno-hp->e.i6comments.fptrreloc; */ ! 317: ! 318: settext(fp, hp->e.i6entry, hp->e.i6texts.virt, hp->e.i6texts.size, ! 319: hp->e.i6texts.fptr); ! 320: setdata(fp, hp->e.i6datas.virt, hp->e.i6datas.size, ! 321: hp->e.i6datas.fptr, hp->e.i6bsssize); ! 322: setsym(fp, 0, 0, 0, 0); ! 323: /*setsym(fp, n, 0, hp->e.i6comments.size-n, hp->e.i6comments.fptr); */ ! 324: fp->hdrsz = 0; /* header stripped */ ! 325: } ! 326: ! 327: ! 328: static void ! 329: settext(Fhdr *fp, long e, long a, long s, long off) ! 330: { ! 331: fp->txtaddr = a; ! 332: fp->entry = e; ! 333: fp->txtsz = s; ! 334: fp->txtoff = off; ! 335: } ! 336: static void ! 337: setdata(Fhdr *fp, long a, long s, long off, long bss) ! 338: { ! 339: fp->dataddr = a; ! 340: fp->datsz = s; ! 341: fp->datoff = off; ! 342: fp->bsssz = bss; ! 343: } ! 344: static void ! 345: setsym(Fhdr *fp, long sy, long sppc, long lnpc, long symoff) ! 346: { ! 347: fp->symsz = sy; ! 348: fp->symoff = symoff; ! 349: fp->sppcsz = sppc; ! 350: fp->sppcoff = fp->symoff+fp->symsz; ! 351: fp->lnpcsz = lnpc; ! 352: fp->lnpcoff = fp->sppcoff+fp->sppcsz; ! 353: } ! 354: ! 355: ! 356: static long ! 357: _round(long a, long b) ! 358: { ! 359: long w; ! 360: ! 361: w = (a/b)*b; ! 362: if (a!=w) ! 363: w += b; ! 364: return(w); ! 365: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.