MIPS: elf2ecoff: Ignore PT_MIPS_ABIFLAGS program headers.
[linux-drm-fsl-dcu.git] / arch / mips / boot / elf2ecoff.c
1 /*
2  * Copyright (c) 1995
3  *      Ted Lemon (hereinafter referred to as the author)
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  * 3. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 /* elf2ecoff.c
30
31    This program converts an elf executable to an ECOFF executable.
32    No symbol table is retained.   This is useful primarily in building
33    net-bootable kernels for machines (e.g., DECstation and Alpha) which
34    only support the ECOFF object file format. */
35
36 #include <stdio.h>
37 #include <string.h>
38 #include <errno.h>
39 #include <sys/types.h>
40 #include <fcntl.h>
41 #include <unistd.h>
42 #include <elf.h>
43 #include <limits.h>
44 #include <netinet/in.h>
45 #include <stdlib.h>
46
47 #include "ecoff.h"
48
49 /*
50  * Some extra ELF definitions
51  */
52 #define PT_MIPS_REGINFO         0x70000000      /* Register usage information */
53 #define PT_MIPS_ABIFLAGS        0x70000003      /* Records ABI related flags  */
54
55 /* -------------------------------------------------------------------- */
56
57 struct sect {
58         unsigned long vaddr;
59         unsigned long len;
60 };
61
62 int *symTypeTable;
63 int must_convert_endian;
64 int format_bigendian;
65
66 static void copy(int out, int in, off_t offset, off_t size)
67 {
68         char ibuf[4096];
69         int remaining, cur, count;
70
71         /* Go to the start of the ELF symbol table... */
72         if (lseek(in, offset, SEEK_SET) < 0) {
73                 perror("copy: lseek");
74                 exit(1);
75         }
76
77         remaining = size;
78         while (remaining) {
79                 cur = remaining;
80                 if (cur > sizeof ibuf)
81                         cur = sizeof ibuf;
82                 remaining -= cur;
83                 if ((count = read(in, ibuf, cur)) != cur) {
84                         fprintf(stderr, "copy: read: %s\n",
85                                 count ? strerror(errno) :
86                                 "premature end of file");
87                         exit(1);
88                 }
89                 if ((count = write(out, ibuf, cur)) != cur) {
90                         perror("copy: write");
91                         exit(1);
92                 }
93         }
94 }
95
96 /*
97  * Combine two segments, which must be contiguous.   If pad is true, it's
98  * okay for there to be padding between.
99  */
100 static void combine(struct sect *base, struct sect *new, int pad)
101 {
102         if (!base->len)
103                 *base = *new;
104         else if (new->len) {
105                 if (base->vaddr + base->len != new->vaddr) {
106                         if (pad)
107                                 base->len = new->vaddr - base->vaddr;
108                         else {
109                                 fprintf(stderr,
110                                         "Non-contiguous data can't be converted.\n");
111                                 exit(1);
112                         }
113                 }
114                 base->len += new->len;
115         }
116 }
117
118 static int phcmp(const void *v1, const void *v2)
119 {
120         const Elf32_Phdr *h1 = v1;
121         const Elf32_Phdr *h2 = v2;
122
123         if (h1->p_vaddr > h2->p_vaddr)
124                 return 1;
125         else if (h1->p_vaddr < h2->p_vaddr)
126                 return -1;
127         else
128                 return 0;
129 }
130
131 static char *saveRead(int file, off_t offset, off_t len, char *name)
132 {
133         char *tmp;
134         int count;
135         off_t off;
136         if ((off = lseek(file, offset, SEEK_SET)) < 0) {
137                 fprintf(stderr, "%s: fseek: %s\n", name, strerror(errno));
138                 exit(1);
139         }
140         if (!(tmp = (char *) malloc(len))) {
141                 fprintf(stderr, "%s: Can't allocate %ld bytes.\n", name,
142                         len);
143                 exit(1);
144         }
145         count = read(file, tmp, len);
146         if (count != len) {
147                 fprintf(stderr, "%s: read: %s.\n",
148                         name,
149                         count ? strerror(errno) : "End of file reached");
150                 exit(1);
151         }
152         return tmp;
153 }
154
155 #define swab16(x) \
156         ((unsigned short)( \
157                 (((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \
158                 (((unsigned short)(x) & (unsigned short)0xff00U) >> 8) ))
159
160 #define swab32(x) \
161         ((unsigned int)( \
162                 (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
163                 (((unsigned int)(x) & (unsigned int)0x0000ff00UL) <<  8) | \
164                 (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >>  8) | \
165                 (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
166
167 static void convert_elf_hdr(Elf32_Ehdr * e)
168 {
169         e->e_type = swab16(e->e_type);
170         e->e_machine = swab16(e->e_machine);
171         e->e_version = swab32(e->e_version);
172         e->e_entry = swab32(e->e_entry);
173         e->e_phoff = swab32(e->e_phoff);
174         e->e_shoff = swab32(e->e_shoff);
175         e->e_flags = swab32(e->e_flags);
176         e->e_ehsize = swab16(e->e_ehsize);
177         e->e_phentsize = swab16(e->e_phentsize);
178         e->e_phnum = swab16(e->e_phnum);
179         e->e_shentsize = swab16(e->e_shentsize);
180         e->e_shnum = swab16(e->e_shnum);
181         e->e_shstrndx = swab16(e->e_shstrndx);
182 }
183
184 static void convert_elf_phdrs(Elf32_Phdr * p, int num)
185 {
186         int i;
187
188         for (i = 0; i < num; i++, p++) {
189                 p->p_type = swab32(p->p_type);
190                 p->p_offset = swab32(p->p_offset);
191                 p->p_vaddr = swab32(p->p_vaddr);
192                 p->p_paddr = swab32(p->p_paddr);
193                 p->p_filesz = swab32(p->p_filesz);
194                 p->p_memsz = swab32(p->p_memsz);
195                 p->p_flags = swab32(p->p_flags);
196                 p->p_align = swab32(p->p_align);
197         }
198
199 }
200
201 static void convert_elf_shdrs(Elf32_Shdr * s, int num)
202 {
203         int i;
204
205         for (i = 0; i < num; i++, s++) {
206                 s->sh_name = swab32(s->sh_name);
207                 s->sh_type = swab32(s->sh_type);
208                 s->sh_flags = swab32(s->sh_flags);
209                 s->sh_addr = swab32(s->sh_addr);
210                 s->sh_offset = swab32(s->sh_offset);
211                 s->sh_size = swab32(s->sh_size);
212                 s->sh_link = swab32(s->sh_link);
213                 s->sh_info = swab32(s->sh_info);
214                 s->sh_addralign = swab32(s->sh_addralign);
215                 s->sh_entsize = swab32(s->sh_entsize);
216         }
217 }
218
219 static void convert_ecoff_filehdr(struct filehdr *f)
220 {
221         f->f_magic = swab16(f->f_magic);
222         f->f_nscns = swab16(f->f_nscns);
223         f->f_timdat = swab32(f->f_timdat);
224         f->f_symptr = swab32(f->f_symptr);
225         f->f_nsyms = swab32(f->f_nsyms);
226         f->f_opthdr = swab16(f->f_opthdr);
227         f->f_flags = swab16(f->f_flags);
228 }
229
230 static void convert_ecoff_aouthdr(struct aouthdr *a)
231 {
232         a->magic = swab16(a->magic);
233         a->vstamp = swab16(a->vstamp);
234         a->tsize = swab32(a->tsize);
235         a->dsize = swab32(a->dsize);
236         a->bsize = swab32(a->bsize);
237         a->entry = swab32(a->entry);
238         a->text_start = swab32(a->text_start);
239         a->data_start = swab32(a->data_start);
240         a->bss_start = swab32(a->bss_start);
241         a->gprmask = swab32(a->gprmask);
242         a->cprmask[0] = swab32(a->cprmask[0]);
243         a->cprmask[1] = swab32(a->cprmask[1]);
244         a->cprmask[2] = swab32(a->cprmask[2]);
245         a->cprmask[3] = swab32(a->cprmask[3]);
246         a->gp_value = swab32(a->gp_value);
247 }
248
249 static void convert_ecoff_esecs(struct scnhdr *s, int num)
250 {
251         int i;
252
253         for (i = 0; i < num; i++, s++) {
254                 s->s_paddr = swab32(s->s_paddr);
255                 s->s_vaddr = swab32(s->s_vaddr);
256                 s->s_size = swab32(s->s_size);
257                 s->s_scnptr = swab32(s->s_scnptr);
258                 s->s_relptr = swab32(s->s_relptr);
259                 s->s_lnnoptr = swab32(s->s_lnnoptr);
260                 s->s_nreloc = swab16(s->s_nreloc);
261                 s->s_nlnno = swab16(s->s_nlnno);
262                 s->s_flags = swab32(s->s_flags);
263         }
264 }
265
266 int main(int argc, char *argv[])
267 {
268         Elf32_Ehdr ex;
269         Elf32_Phdr *ph;
270         Elf32_Shdr *sh;
271         char *shstrtab;
272         int i, pad;
273         struct sect text, data, bss;
274         struct filehdr efh;
275         struct aouthdr eah;
276         struct scnhdr esecs[6];
277         int infile, outfile;
278         unsigned long cur_vma = ULONG_MAX;
279         int addflag = 0;
280         int nosecs;
281
282         text.len = data.len = bss.len = 0;
283         text.vaddr = data.vaddr = bss.vaddr = 0;
284
285         /* Check args... */
286         if (argc < 3 || argc > 4) {
287               usage:
288                 fprintf(stderr,
289                         "usage: elf2ecoff <elf executable> <ecoff executable> [-a]\n");
290                 exit(1);
291         }
292         if (argc == 4) {
293                 if (strcmp(argv[3], "-a"))
294                         goto usage;
295                 addflag = 1;
296         }
297
298         /* Try the input file... */
299         if ((infile = open(argv[1], O_RDONLY)) < 0) {
300                 fprintf(stderr, "Can't open %s for read: %s\n",
301                         argv[1], strerror(errno));
302                 exit(1);
303         }
304
305         /* Read the header, which is at the beginning of the file... */
306         i = read(infile, &ex, sizeof ex);
307         if (i != sizeof ex) {
308                 fprintf(stderr, "ex: %s: %s.\n",
309                         argv[1],
310                         i ? strerror(errno) : "End of file reached");
311                 exit(1);
312         }
313
314         if (ex.e_ident[EI_DATA] == ELFDATA2MSB)
315                 format_bigendian = 1;
316
317         if (ntohs(0xaa55) == 0xaa55) {
318                 if (!format_bigendian)
319                         must_convert_endian = 1;
320         } else {
321                 if (format_bigendian)
322                         must_convert_endian = 1;
323         }
324         if (must_convert_endian)
325                 convert_elf_hdr(&ex);
326
327         /* Read the program headers... */
328         ph = (Elf32_Phdr *) saveRead(infile, ex.e_phoff,
329                                      ex.e_phnum * sizeof(Elf32_Phdr),
330                                      "ph");
331         if (must_convert_endian)
332                 convert_elf_phdrs(ph, ex.e_phnum);
333         /* Read the section headers... */
334         sh = (Elf32_Shdr *) saveRead(infile, ex.e_shoff,
335                                      ex.e_shnum * sizeof(Elf32_Shdr),
336                                      "sh");
337         if (must_convert_endian)
338                 convert_elf_shdrs(sh, ex.e_shnum);
339         /* Read in the section string table. */
340         shstrtab = saveRead(infile, sh[ex.e_shstrndx].sh_offset,
341                             sh[ex.e_shstrndx].sh_size, "shstrtab");
342
343         /* Figure out if we can cram the program header into an ECOFF
344            header...  Basically, we can't handle anything but loadable
345            segments, but we can ignore some kinds of segments.  We can't
346            handle holes in the address space.  Segments may be out of order,
347            so we sort them first. */
348
349         qsort(ph, ex.e_phnum, sizeof(Elf32_Phdr), phcmp);
350
351         for (i = 0; i < ex.e_phnum; i++) {
352                 /* Section types we can ignore... */
353                 switch (ph[i].p_type) {
354                 case PT_NULL:
355                 case PT_NOTE:
356                 case PT_PHDR:
357                 case PT_MIPS_REGINFO:
358                 case PT_MIPS_ABIFLAGS:
359                         continue;
360
361                 case PT_LOAD:
362                         /* Writable (data) segment? */
363                         if (ph[i].p_flags & PF_W) {
364                                 struct sect ndata, nbss;
365
366                                 ndata.vaddr = ph[i].p_vaddr;
367                                 ndata.len = ph[i].p_filesz;
368                                 nbss.vaddr = ph[i].p_vaddr + ph[i].p_filesz;
369                                 nbss.len = ph[i].p_memsz - ph[i].p_filesz;
370
371                                 combine(&data, &ndata, 0);
372                                 combine(&bss, &nbss, 1);
373                         } else {
374                                 struct sect ntxt;
375
376                                 ntxt.vaddr = ph[i].p_vaddr;
377                                 ntxt.len = ph[i].p_filesz;
378
379                                 combine(&text, &ntxt, 0);
380                         }
381                         /* Remember the lowest segment start address. */
382                         if (ph[i].p_vaddr < cur_vma)
383                                 cur_vma = ph[i].p_vaddr;
384                         break;
385
386                 default:
387                         /* Section types we can't handle... */
388                         fprintf(stderr,
389                                 "Program header %d type %d can't be converted.\n",
390                                 ex.e_phnum, ph[i].p_type);
391                         exit(1);
392                 }
393         }
394
395         /* Sections must be in order to be converted... */
396         if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr ||
397             text.vaddr + text.len > data.vaddr
398             || data.vaddr + data.len > bss.vaddr) {
399                 fprintf(stderr,
400                         "Sections ordering prevents a.out conversion.\n");
401                 exit(1);
402         }
403
404         /* If there's a data section but no text section, then the loader
405            combined everything into one section.   That needs to be the
406            text section, so just make the data section zero length following
407            text. */
408         if (data.len && !text.len) {
409                 text = data;
410                 data.vaddr = text.vaddr + text.len;
411                 data.len = 0;
412         }
413
414         /* If there is a gap between text and data, we'll fill it when we copy
415            the data, so update the length of the text segment as represented in
416            a.out to reflect that, since a.out doesn't allow gaps in the program
417            address space. */
418         if (text.vaddr + text.len < data.vaddr)
419                 text.len = data.vaddr - text.vaddr;
420
421         /* We now have enough information to cons up an a.out header... */
422         eah.magic = OMAGIC;
423         eah.vstamp = 200;
424         eah.tsize = text.len;
425         eah.dsize = data.len;
426         eah.bsize = bss.len;
427         eah.entry = ex.e_entry;
428         eah.text_start = text.vaddr;
429         eah.data_start = data.vaddr;
430         eah.bss_start = bss.vaddr;
431         eah.gprmask = 0xf3fffffe;
432         memset(&eah.cprmask, '\0', sizeof eah.cprmask);
433         eah.gp_value = 0;       /* unused. */
434
435         if (format_bigendian)
436                 efh.f_magic = MIPSEBMAGIC;
437         else
438                 efh.f_magic = MIPSELMAGIC;
439         if (addflag)
440                 nosecs = 6;
441         else
442                 nosecs = 3;
443         efh.f_nscns = nosecs;
444         efh.f_timdat = 0;       /* bogus */
445         efh.f_symptr = 0;
446         efh.f_nsyms = 0;
447         efh.f_opthdr = sizeof eah;
448         efh.f_flags = 0x100f;   /* Stripped, not sharable. */
449
450         memset(esecs, 0, sizeof esecs);
451         strcpy(esecs[0].s_name, ".text");
452         strcpy(esecs[1].s_name, ".data");
453         strcpy(esecs[2].s_name, ".bss");
454         if (addflag) {
455                 strcpy(esecs[3].s_name, ".rdata");
456                 strcpy(esecs[4].s_name, ".sdata");
457                 strcpy(esecs[5].s_name, ".sbss");
458         }
459         esecs[0].s_paddr = esecs[0].s_vaddr = eah.text_start;
460         esecs[1].s_paddr = esecs[1].s_vaddr = eah.data_start;
461         esecs[2].s_paddr = esecs[2].s_vaddr = eah.bss_start;
462         if (addflag) {
463                 esecs[3].s_paddr = esecs[3].s_vaddr = 0;
464                 esecs[4].s_paddr = esecs[4].s_vaddr = 0;
465                 esecs[5].s_paddr = esecs[5].s_vaddr = 0;
466         }
467         esecs[0].s_size = eah.tsize;
468         esecs[1].s_size = eah.dsize;
469         esecs[2].s_size = eah.bsize;
470         if (addflag) {
471                 esecs[3].s_size = 0;
472                 esecs[4].s_size = 0;
473                 esecs[5].s_size = 0;
474         }
475         esecs[0].s_scnptr = N_TXTOFF(efh, eah);
476         esecs[1].s_scnptr = N_DATOFF(efh, eah);
477 #define ECOFF_SEGMENT_ALIGNMENT(a) 0x10
478 #define ECOFF_ROUND(s, a) (((s)+(a)-1)&~((a)-1))
479         esecs[2].s_scnptr = esecs[1].s_scnptr +
480             ECOFF_ROUND(esecs[1].s_size, ECOFF_SEGMENT_ALIGNMENT(&eah));
481         if (addflag) {
482                 esecs[3].s_scnptr = 0;
483                 esecs[4].s_scnptr = 0;
484                 esecs[5].s_scnptr = 0;
485         }
486         esecs[0].s_relptr = esecs[1].s_relptr = esecs[2].s_relptr = 0;
487         esecs[0].s_lnnoptr = esecs[1].s_lnnoptr = esecs[2].s_lnnoptr = 0;
488         esecs[0].s_nreloc = esecs[1].s_nreloc = esecs[2].s_nreloc = 0;
489         esecs[0].s_nlnno = esecs[1].s_nlnno = esecs[2].s_nlnno = 0;
490         if (addflag) {
491                 esecs[3].s_relptr = esecs[4].s_relptr
492                     = esecs[5].s_relptr = 0;
493                 esecs[3].s_lnnoptr = esecs[4].s_lnnoptr
494                     = esecs[5].s_lnnoptr = 0;
495                 esecs[3].s_nreloc = esecs[4].s_nreloc = esecs[5].s_nreloc =
496                     0;
497                 esecs[3].s_nlnno = esecs[4].s_nlnno = esecs[5].s_nlnno = 0;
498         }
499         esecs[0].s_flags = 0x20;
500         esecs[1].s_flags = 0x40;
501         esecs[2].s_flags = 0x82;
502         if (addflag) {
503                 esecs[3].s_flags = 0x100;
504                 esecs[4].s_flags = 0x200;
505                 esecs[5].s_flags = 0x400;
506         }
507
508         /* Make the output file... */
509         if ((outfile = open(argv[2], O_WRONLY | O_CREAT, 0777)) < 0) {
510                 fprintf(stderr, "Unable to create %s: %s\n", argv[2],
511                         strerror(errno));
512                 exit(1);
513         }
514
515         if (must_convert_endian)
516                 convert_ecoff_filehdr(&efh);
517         /* Write the headers... */
518         i = write(outfile, &efh, sizeof efh);
519         if (i != sizeof efh) {
520                 perror("efh: write");
521                 exit(1);
522
523                 for (i = 0; i < nosecs; i++) {
524                         printf
525                             ("Section %d: %s phys %lx  size %lx  file offset %lx\n",
526                              i, esecs[i].s_name, esecs[i].s_paddr,
527                              esecs[i].s_size, esecs[i].s_scnptr);
528                 }
529         }
530         fprintf(stderr, "wrote %d byte file header.\n", i);
531
532         if (must_convert_endian)
533                 convert_ecoff_aouthdr(&eah);
534         i = write(outfile, &eah, sizeof eah);
535         if (i != sizeof eah) {
536                 perror("eah: write");
537                 exit(1);
538         }
539         fprintf(stderr, "wrote %d byte a.out header.\n", i);
540
541         if (must_convert_endian)
542                 convert_ecoff_esecs(&esecs[0], nosecs);
543         i = write(outfile, &esecs, nosecs * sizeof(struct scnhdr));
544         if (i != nosecs * sizeof(struct scnhdr)) {
545                 perror("esecs: write");
546                 exit(1);
547         }
548         fprintf(stderr, "wrote %d bytes of section headers.\n", i);
549
550         pad = (sizeof(efh) + sizeof(eah) + nosecs * sizeof(struct scnhdr)) & 15;
551         if (pad) {
552                 pad = 16 - pad;
553                 i = write(outfile, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", pad);
554                 if (i < 0) {
555                         perror("ipad: write");
556                         exit(1);
557                 }
558                 fprintf(stderr, "wrote %d byte pad.\n", i);
559         }
560
561         /*
562          * Copy the loadable sections.   Zero-fill any gaps less than 64k;
563          * complain about any zero-filling, and die if we're asked to zero-fill
564          * more than 64k.
565          */
566         for (i = 0; i < ex.e_phnum; i++) {
567                 /* Unprocessable sections were handled above, so just verify that
568                    the section can be loaded before copying. */
569                 if (ph[i].p_type == PT_LOAD && ph[i].p_filesz) {
570                         if (cur_vma != ph[i].p_vaddr) {
571                                 unsigned long gap =
572                                     ph[i].p_vaddr - cur_vma;
573                                 char obuf[1024];
574                                 if (gap > 65536) {
575                                         fprintf(stderr,
576                                                 "Intersegment gap (%ld bytes) too large.\n",
577                                                 gap);
578                                         exit(1);
579                                 }
580                                 fprintf(stderr,
581                                         "Warning: %ld byte intersegment gap.\n",
582                                         gap);
583                                 memset(obuf, 0, sizeof obuf);
584                                 while (gap) {
585                                         int count =
586                                             write(outfile, obuf,
587                                                   (gap >
588                                                    sizeof obuf ? sizeof
589                                                    obuf : gap));
590                                         if (count < 0) {
591                                                 fprintf(stderr,
592                                                         "Error writing gap: %s\n",
593                                                         strerror(errno));
594                                                 exit(1);
595                                         }
596                                         gap -= count;
597                                 }
598                         }
599                         fprintf(stderr, "writing %d bytes...\n",
600                                 ph[i].p_filesz);
601                         copy(outfile, infile, ph[i].p_offset,
602                              ph[i].p_filesz);
603                         cur_vma = ph[i].p_vaddr + ph[i].p_filesz;
604                 }
605         }
606
607         /*
608          * Write a page of padding for boot PROMS that read entire pages.
609          * Without this, they may attempt to read past the end of the
610          * data section, incur an error, and refuse to boot.
611          */
612         {
613                 char obuf[4096];
614                 memset(obuf, 0, sizeof obuf);
615                 if (write(outfile, obuf, sizeof(obuf)) != sizeof(obuf)) {
616                         fprintf(stderr, "Error writing PROM padding: %s\n",
617                                 strerror(errno));
618                         exit(1);
619                 }
620         }
621
622         /* Looks like we won... */
623         exit(0);
624 }