[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

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