Annotation of lucent/sys/src/libmach/f003252, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.