Annotation of lucent/sys/src/libmach/f003252, revision 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.