[BACK]Return to a2coff.c CVS log [TXT][DIR] Up to [local] / sys / arch / aviion / stand / a2coff

Annotation of sys/arch/aviion/stand/a2coff/a2coff.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: a2coff.c,v 1.2 2006/05/14 17:49:54 miod Exp $ */
        !             2: /*
        !             3:  * Copyright (c) 2006, Miodrag Vallat
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms, with or without
        !             6:  * modification, are permitted provided that the following conditions
        !             7:  * are met:
        !             8:  * 1. Redistributions of source code must retain the above copyright
        !             9:  *    notice, this list of conditions and the following disclaimer.
        !            10:  * 2. Redistributions in binary form must reproduce the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer in the
        !            12:  *    documentation and/or other materials provided with the distribution.
        !            13:  *
        !            14:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            15:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            16:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        !            17:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
        !            18:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            19:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            20:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            21:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            22:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
        !            23:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            24:  * POSSIBILITY OF SUCH DAMAGE.
        !            25:  */
        !            26:
        !            27: /*
        !            28:  * Quick and dirty a.out to 88K BCS ECOFF converter. Will only work for
        !            29:  * standalone binaries with no relocations, and will drop symbols.
        !            30:  * Also, bss is merged into the data section to cope with PROMs which
        !            31:  * do not zero-fill the bss upon loading (sad but true).
        !            32:  *
        !            33:  * This should really only be used to build a BSD/dg88k bootloader.
        !            34:  */
        !            35:
        !            36: #include <unistd.h>
        !            37: #include <stdlib.h>
        !            38: #include <err.h>
        !            39: #include <fcntl.h>
        !            40: #include <stdio.h>
        !            41: #include <string.h>
        !            42: #include <sys/types.h>
        !            43:
        !            44: #include <a.out.h>
        !            45: /* overwrite __LDPGSZ if not a native binary */
        !            46: #ifndef        m88k
        !            47: #undef __LDPGSZ
        !            48: #define        __LDPGSZ        0x1000
        !            49: #endif /* m88k */
        !            50:
        !            51: /*
        !            52:  * We can't use the standard ecoff defines, first, because the system
        !            53:  * we are building this tool on might not have ecoff support at all (thus
        !            54:  * no <machine/ecoff_machdep.h> file), second, because the common defines
        !            55:  * do not know about the scnhdr changes for 88K BCS.
        !            56:  * So we'll provide our own, working, definitions.
        !            57:  */
        !            58: #if 0 /* defined(_KERN_DO_ECOFF) */
        !            59: #include <sys/exec_ecoff.h>
        !            60: #else
        !            61: struct ecoff_filehdr {
        !            62:        u_short f_magic;        /* magic number */
        !            63:        u_short f_nscns;        /* # of sections */
        !            64:        u_int   f_timdat;       /* time and date stamp */
        !            65:        u_long  f_symptr;       /* file offset of symbol table */
        !            66:        u_int   f_nsyms;        /* # of symbol table entries */
        !            67:        u_short f_opthdr;       /* sizeof the optional header */
        !            68:        u_short f_flags;        /* flags??? */
        !            69: };
        !            70:
        !            71: struct ecoff_aouthdr {
        !            72:        u_short magic;
        !            73:        u_short vstamp;
        !            74: #if 0
        !            75:        ECOFF_PAD
        !            76: #endif
        !            77:        u_long  tsize;
        !            78:        u_long  dsize;
        !            79:        u_long  bsize;
        !            80:        u_long  entry;
        !            81:        u_long  text_start;
        !            82:        u_long  data_start;
        !            83: #if 0  /* not on m88k */
        !            84:        u_long  bss_start;
        !            85:        ECOFF_MACHDEP;
        !            86: #endif
        !            87: };
        !            88:
        !            89: struct ecoff_scnhdr {          /* needed for size info */
        !            90:        char    s_name[8];      /* name */
        !            91:        u_long  s_paddr;        /* physical addr? for ROMing?*/
        !            92:        u_long  s_vaddr;        /* virtual addr? */
        !            93:        u_long  s_size;         /* size */
        !            94:        u_long  s_scnptr;       /* file offset of raw data */
        !            95:        u_long  s_relptr;       /* file offset of reloc data */
        !            96:        u_long  s_lnnoptr;      /* file offset of line data */
        !            97: #if 0
        !            98:        u_short s_nreloc;       /* # of relocation entries */
        !            99:        u_short s_nlnno;        /* # of line entries */
        !           100: #else
        !           101:        /* m88k specific changes */
        !           102:        u_long  s_nreloc;
        !           103:        union {
        !           104:         u_long _s_nlnno;
        !           105:         u_long _s_vendor;
        !           106:        } _s_s;
        !           107: #define        s_nlnno   _s_s._s_nlnno
        !           108: #define        s_vendor _s_s._s_vendor
        !           109: #endif
        !           110:        u_long  s_flags;
        !           111: };
        !           112:
        !           113: struct ecoff_exechdr {
        !           114:        struct ecoff_filehdr f;
        !           115:        struct ecoff_aouthdr a;
        !           116: };
        !           117: #endif
        !           118:
        !           119: #define        round(qty, pow2)        (((qty) + (pow2 - 1)) & ~(pow2 - 1UL))
        !           120:
        !           121: void   copybits(int, int, u_int32_t);
        !           122: void   usage(void);
        !           123: void   zerobits(int, u_int32_t);
        !           124:
        !           125: int
        !           126: main(int argc, char *argv[])
        !           127: {
        !           128:        struct exec head;
        !           129:        struct ecoff_exechdr ehead;
        !           130:        struct ecoff_scnhdr escn[3];
        !           131:        int infd, outfd;
        !           132:        int n;
        !           133:
        !           134:        if (argc != 3)
        !           135:                usage();
        !           136:
        !           137:        infd = open(argv[1], O_RDONLY);
        !           138:        if (infd < 0)
        !           139:                err(1, argv[1]);
        !           140:
        !           141:        outfd = open(argv[2], O_WRONLY | O_TRUNC | O_CREAT, 0644);
        !           142:        if (outfd < 0)
        !           143:                err(1, argv[2]);
        !           144:
        !           145:        n = read(infd, &head, sizeof(head));
        !           146:        if (n < sizeof(head))
        !           147:                err(1, "read");
        !           148:
        !           149:        if (N_BADMAG(head)) {
        !           150:                printf("%s: bad magic number\n", argv[1]);
        !           151:                exit(1);
        !           152:        }
        !           153:
        !           154:        if (head.a_trsize || head.a_drsize) {
        !           155:                printf("%s: has relocations\n", argv[1]);
        !           156:                exit(1);
        !           157:        }
        !           158:
        !           159:        /*
        !           160:         * Header
        !           161:         */
        !           162:
        !           163:        ehead.f.f_magic = 0x016d;               /* MC88OMAGIC */
        !           164:        ehead.f.f_nscns = 3;
        !           165:        ehead.f.f_timdat = 0;                   /* ignored */
        !           166:        ehead.f.f_symptr = 0;                   /* ignored */
        !           167:        ehead.f.f_nsyms = 0;                    /* ignored */
        !           168:        ehead.f.f_opthdr = sizeof ehead.a;
        !           169:        ehead.f.f_flags = 0x020f;
        !           170:                /* F_RELFLG | F_EXEC | F_LNNO | 8 | F_AR16WR */
        !           171:
        !           172:        ehead.a.magic = N_GETMAGIC(head);
        !           173:        ehead.a.vstamp = 0;                     /* ignored */
        !           174:        ehead.a.tsize = head.a_text;            /* ignored */
        !           175:        ehead.a.dsize = head.a_data;            /* ignored */
        !           176:        ehead.a.bsize = head.a_bss;             /* ignored */
        !           177:        ehead.a.entry = head.a_entry;
        !           178:        ehead.a.text_start = N_TXTADDR(head);   /* ignored */
        !           179:        ehead.a.data_start = N_DATADDR(head);   /* ignored */
        !           180:
        !           181:        n = write(outfd, &ehead, sizeof(ehead));
        !           182:        if (n < sizeof(ehead))
        !           183:                err(1, "write");
        !           184:
        !           185:        /*
        !           186:         * Sections.
        !           187:         * Note that we merge .bss into .data since the PROM will not
        !           188:         * clear it and locore does not do this either.
        !           189:         */
        !           190:
        !           191:        strncpy(escn[0].s_name, ".text", sizeof escn[0].s_name);
        !           192:        escn[0].s_paddr = N_TXTADDR(head);      /* ignored, 1:1 mapping */
        !           193:        escn[0].s_size = round(head.a_text, 8);
        !           194:        escn[0].s_scnptr = round(sizeof(ehead) + sizeof(escn), 0x10);
        !           195:        escn[0].s_relptr = 0;
        !           196:        escn[0].s_lnnoptr = 0;
        !           197:        escn[0].s_nlnno = 0;
        !           198:        escn[0].s_flags = 0x20; /* STYP_TEXT */
        !           199:
        !           200:        strncpy(escn[1].s_name, ".data", sizeof escn[1].s_name);
        !           201:        escn[1].s_paddr = N_DATADDR(head);              /* ignored, 1:1 mapping */
        !           202:        escn[1].s_scnptr = escn[0].s_scnptr + escn[0].s_size;
        !           203:        escn[1].s_size = round(head.a_data + head.a_bss, 8);
        !           204:        escn[1].s_relptr = 0;
        !           205:        escn[1].s_lnnoptr = 0;
        !           206:        escn[1].s_nlnno = 0;
        !           207:        escn[1].s_flags = 0x40; /* STYP_DATA */
        !           208:
        !           209:        strncpy(escn[2].s_name, ".bss", sizeof escn[2].s_name);
        !           210:        escn[2].s_paddr = N_BSSADDR(head) + head.a_bss; /* ignored, 1:1 mapping */
        !           211:        escn[2].s_scnptr = 0;           /* nothing in the file */
        !           212:        escn[2].s_size = 0;
        !           213:        escn[2].s_relptr = 0;
        !           214:        escn[2].s_lnnoptr = 0;
        !           215:        escn[2].s_nlnno = 0;
        !           216:        escn[2].s_flags = 0x80; /* STYP_BSS */
        !           217:
        !           218:        /* adjust load addresses */
        !           219:        escn[0].s_paddr += (head.a_entry & ~(__LDPGSZ - 1)) - __LDPGSZ;
        !           220:        escn[1].s_paddr += (head.a_entry & ~(__LDPGSZ - 1)) - __LDPGSZ;
        !           221:        escn[2].s_paddr += (head.a_entry & ~(__LDPGSZ - 1)) - __LDPGSZ;
        !           222:        escn[0].s_vaddr = escn[0].s_paddr;
        !           223:        escn[1].s_vaddr = escn[1].s_paddr;
        !           224:        escn[2].s_vaddr = escn[2].s_paddr;
        !           225:
        !           226:        n = write(outfd, &escn, sizeof(escn));
        !           227:        if (n < sizeof(escn))
        !           228:                err(1, "write");
        !           229:
        !           230:        /*
        !           231:         * Copy text section
        !           232:         */
        !           233:
        !           234: #ifdef DEBUG
        !           235:        printf("copying %s: source %lx dest %lx size %x\n",
        !           236:            escn[0].s_name, N_TXTOFF(head), escn[0].s_scnptr, head.a_text);
        !           237: #endif
        !           238:        lseek(outfd, escn[0].s_scnptr, SEEK_SET);
        !           239:        lseek(infd, N_TXTOFF(head), SEEK_SET);
        !           240:        copybits(infd, outfd, head.a_text);
        !           241:
        !           242:        /*
        !           243:         * Copy data section
        !           244:         */
        !           245:
        !           246: #ifdef DEBUG
        !           247:        printf("copying %s: source %lx dest %lx size %x\n",
        !           248:            escn[1].s_name, N_DATOFF(head), escn[1].s_scnptr, head.a_data);
        !           249: #endif
        !           250:        lseek(outfd, escn[1].s_scnptr, SEEK_SET);
        !           251:        lseek(infd, N_DATOFF(head), SEEK_SET);
        !           252:        copybits(infd, outfd, head.a_data);
        !           253:
        !           254:        /*
        !           255:         * ``Copy'' bss section
        !           256:         */
        !           257:
        !           258: #ifdef DEBUG
        !           259:        printf("copying %s: size %lx\n",
        !           260:            escn[2].s_name, round(head.a_data + head.a_bss, 8) - head.a_data);
        !           261: #endif
        !           262:        zerobits(outfd, round(head.a_data + head.a_bss, 8) - head.a_data);
        !           263:
        !           264:        close(infd);
        !           265:        close(outfd);
        !           266:        exit(0);
        !           267: }
        !           268:
        !           269: char buf[4096];
        !           270: #define        min(a ,b)       ((a) < (b) ? (a) : (b))
        !           271:
        !           272: void
        !           273: copybits(int from, int to, u_int32_t count)
        !           274: {
        !           275:        int chunk;
        !           276:
        !           277:        while (count != 0) {
        !           278:                chunk = min(count, sizeof buf);
        !           279:                if (read(from, buf, chunk) < chunk)
        !           280:                        err(1, "read");
        !           281:                if (write(to, buf, chunk) < chunk)
        !           282:                        err(1, "write");
        !           283:                count -= chunk;
        !           284:        }
        !           285: }
        !           286:
        !           287: void
        !           288: zerobits(int to, u_int32_t count)
        !           289: {
        !           290:        int chunk;
        !           291:
        !           292:        bzero(buf, sizeof buf);
        !           293:        while (count != 0) {
        !           294:                chunk = min(count, sizeof buf);
        !           295:                if (write(to, buf, chunk) < chunk)
        !           296:                        err(1, "write");
        !           297:                count -= chunk;
        !           298:        }
        !           299: }
        !           300:
        !           301: __dead void
        !           302: usage(void)
        !           303: {
        !           304:        extern char *__progname;
        !           305:
        !           306:        fprintf(stderr, "usage: %s infile outfile\n", __progname);
        !           307:        exit(1);
        !           308: }

CVSweb