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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [alpha/] [boot/] [tools/] [objstrip.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * arch/alpha/boot/tools/objstrip.c
3
 *
4
 * Strip the object file headers/trailers from an executable (ELF or ECOFF).
5
 *
6
 * Copyright (C) 1996 David Mosberger-Tang.
7
 */
8
/*
9
 * Converts an ECOFF or ELF object file into a bootable file.  The
10
 * object file must be a OMAGIC file (i.e., data and bss follow immediatly
11
 * behind the text).  See DEC "Assembly Language Programmer's Guide"
12
 * documentation for details.  The SRM boot process is documented in
13
 * the Alpha AXP Architecture Reference Manual, Second Edition by
14
 * Richard L. Sites and Richard T. Witek.
15
 */
16
#include <stdio.h>
17
#include <unistd.h>
18
 
19
#include <sys/fcntl.h>
20
#include <sys/stat.h>
21
#include <sys/types.h>
22
 
23
#include <linux/a.out.h>
24
#include <linux/coff.h>
25
#include <linux/param.h>
26
#include <linux/string.h>
27
#ifdef __ELF__
28
# include <asm/elf.h>
29
# include <linux/elf.h>
30
#endif
31
 
32
/* bootfile size must be multiple of BLOCK_SIZE: */
33
#define BLOCK_SIZE      512
34
 
35
const char * prog_name;
36
 
37
 
38
void
39
usage (void)
40
{
41
    fprintf(stderr,
42
            "usage: %s [-v] -p file primary\n"
43
            "       %s [-vb] file [secondary]\n", prog_name, prog_name);
44
    exit(1);
45
}
46
 
47
 
48
int
49
main (int argc, char *argv[])
50
{
51
    size_t nwritten, tocopy, n, mem_size, fil_size, pad = 0;
52
    int fd, ofd, i, j, verbose = 0, primary = 0;
53
    char buf[8192], *inname;
54
    struct exec * aout;         /* includes file & aout header */
55
    long offset;
56
#ifdef __ELF__
57
    struct elfhdr *elf;
58
    struct elf_phdr *elf_phdr;  /* program header */
59
    unsigned long long e_entry;
60
#endif
61
 
62
    prog_name = argv[0];
63
 
64
    for (i = 1; i < argc && argv[i][0] == '-'; ++i) {
65
        for (j = 1; argv[i][j]; ++j) {
66
            switch (argv[i][j]) {
67
              case 'v':
68
                  verbose = ~verbose;
69
                  break;
70
 
71
              case 'b':
72
                  pad = BLOCK_SIZE;
73
                  break;
74
 
75
              case 'p':
76
                  primary = 1;          /* make primary bootblock */
77
                  break;
78
            }
79
        }
80
    }
81
 
82
    if (i >= argc) {
83
        usage();
84
    }
85
    inname = argv[i++];
86
 
87
    fd = open(inname, O_RDONLY);
88
    if (fd == -1) {
89
        perror("open");
90
        exit(1);
91
    }
92
 
93
    ofd = 1;
94
    if (i < argc) {
95
        ofd = open(argv[i++], O_WRONLY | O_CREAT | O_TRUNC, 0666);
96
        if (fd == -1) {
97
            perror("open");
98
            exit(1);
99
        }
100
    }
101
 
102
    if (primary) {
103
        /* generate bootblock for primary loader */
104
 
105
        unsigned long bb[64], sum = 0;
106
        struct stat st;
107
        off_t size;
108
        int i;
109
 
110
        if (ofd == 1) {
111
            usage();
112
        }
113
 
114
        if (fstat(fd, &st) == -1) {
115
            perror("fstat");
116
            exit(1);
117
        }
118
 
119
        size = (st.st_size + BLOCK_SIZE - 1) & ~(BLOCK_SIZE - 1);
120
        memset(bb, 0, sizeof(bb));
121
        strcpy((char *) bb, "Linux SRM bootblock");
122
        bb[60] = size / BLOCK_SIZE;     /* count */
123
        bb[61] = 1;                     /* starting sector # */
124
        bb[62] = 0;                      /* flags---must be 0 */
125
        for (i = 0; i < 63; ++i) {
126
            sum += bb[i];
127
        }
128
        bb[63] = sum;
129
        if (write(ofd, bb, sizeof(bb)) != sizeof(bb)) {
130
            perror("boot-block write");
131
            exit(1);
132
        }
133
        printf("%lu\n", size);
134
        return 0;
135
    }
136
 
137
    /* read and inspect exec header: */
138
 
139
    if (read(fd, buf, sizeof(buf)) < 0) {
140
        perror("read");
141
        exit(1);
142
    }
143
 
144
#ifdef __ELF__
145
    elf = (struct elfhdr *) buf;
146
 
147
    if (elf->e_ident[0] == 0x7f && strncmp(elf->e_ident + 1, "ELF", 3) == 0) {
148
        if (elf->e_type != ET_EXEC) {
149
            fprintf(stderr, "%s: %s is not an ELF executable\n",
150
                    prog_name, inname);
151
            exit(1);
152
        }
153
        if (!elf_check_arch(elf->e_machine)) {
154
            fprintf(stderr, "%s: is not for this processor (e_machine=%d)\n",
155
                    prog_name, elf->e_machine);
156
            exit(1);
157
        }
158
        if (elf->e_phnum != 1) {
159
            fprintf(stderr,
160
                    "%s: %d program headers (forgot to link with -N?)\n",
161
                    prog_name, elf->e_phnum);
162
        }
163
 
164
        e_entry = elf->e_entry;
165
 
166
        lseek(fd, elf->e_phoff, SEEK_SET);
167
        if (read(fd, buf, sizeof(*elf_phdr)) != sizeof(*elf_phdr)) {
168
            perror("read");
169
            exit(1);
170
        }
171
 
172
        elf_phdr = (struct elf_phdr *) buf;
173
        offset   = elf_phdr->p_offset;
174
        mem_size = elf_phdr->p_memsz;
175
        fil_size = elf_phdr->p_filesz;
176
 
177
        /* work around ELF bug: */
178
        if (elf_phdr->p_vaddr < e_entry) {
179
            unsigned long delta = e_entry - elf_phdr->p_vaddr;
180
            offset   += delta;
181
            mem_size -= delta;
182
            fil_size -= delta;
183
            elf_phdr->p_vaddr += delta;
184
        }
185
 
186
        if (verbose) {
187
            fprintf(stderr, "%s: extracting %#016lx-%#016lx (at %lx)\n",
188
                    prog_name, (long) elf_phdr->p_vaddr,
189
                    elf_phdr->p_vaddr + fil_size, offset);
190
        }
191
    } else
192
#endif
193
    {
194
        aout = (struct exec *) buf;
195
 
196
        if (!(aout->fh.f_flags & COFF_F_EXEC)) {
197
            fprintf(stderr, "%s: %s is not in executable format\n",
198
                    prog_name, inname);
199
            exit(1);
200
        }
201
 
202
        if (aout->fh.f_opthdr != sizeof(aout->ah)) {
203
            fprintf(stderr, "%s: %s has unexpected optional header size\n",
204
                    prog_name, inname);
205
            exit(1);
206
        }
207
 
208
        if (N_MAGIC(*aout) != OMAGIC) {
209
            fprintf(stderr, "%s: %s is not an OMAGIC file\n",
210
                    prog_name, inname);
211
            exit(1);
212
        }
213
        offset = N_TXTOFF(*aout);
214
        fil_size = aout->ah.tsize + aout->ah.dsize;
215
        mem_size = fil_size + aout->ah.bsize;
216
 
217
        if (verbose) {
218
            fprintf(stderr, "%s: extracting %#016lx-%#016lx (at %lx)\n",
219
                    prog_name, aout->ah.text_start,
220
                    aout->ah.text_start + fil_size, offset);
221
        }
222
    }
223
 
224
    if (lseek(fd, offset, SEEK_SET) != offset) {
225
        perror("lseek");
226
        exit(1);
227
    }
228
 
229
    if (verbose) {
230
        fprintf(stderr, "%s: copying %lu byte from %s\n",
231
                prog_name, (unsigned long) fil_size, inname);
232
    }
233
 
234
    tocopy = fil_size;
235
    while (tocopy > 0) {
236
        n = tocopy;
237
        if (n > sizeof(buf)) {
238
            n = sizeof(buf);
239
        }
240
        tocopy -= n;
241
        if ((size_t) read(fd, buf, n) != n) {
242
            perror("read");
243
            exit(1);
244
        }
245
        do {
246
            nwritten = write(ofd, buf, n);
247
            if ((ssize_t) nwritten == -1) {
248
                perror("write");
249
                exit(1);
250
            }
251
            n -= nwritten;
252
        } while (n > 0);
253
    }
254
 
255
    if (pad) {
256
        mem_size = ((mem_size + pad - 1) / pad) * pad;
257
    }
258
 
259
    tocopy = mem_size - fil_size;
260
    if (tocopy > 0) {
261
        fprintf(stderr,
262
                "%s: zero-filling bss and aligning to %lu with %lu bytes\n",
263
                prog_name, pad, (unsigned long) tocopy);
264
 
265
        memset(buf, 0x00, sizeof(buf));
266
        do {
267
            n = tocopy;
268
            if (n > sizeof(buf)) {
269
                n = sizeof(buf);
270
            }
271
            nwritten = write(ofd, buf, n);
272
            if ((ssize_t) nwritten == -1) {
273
                perror("write");
274
                exit(1);
275
            }
276
            tocopy -= nwritten;
277
        } while (tocopy > 0);
278
    }
279
    return 0;
280
}

powered by: WebSVN 2.1.0

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