OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [mips/] [boot/] [elf2ecoff.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.