Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/alpha/boot/tools/objstrip.c
17263 views
1
/*
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 immediately
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 <string.h>
18
#include <stdlib.h>
19
#include <unistd.h>
20
21
#include <sys/fcntl.h>
22
#include <sys/stat.h>
23
#include <sys/types.h>
24
25
#include <linux/a.out.h>
26
#include <linux/coff.h>
27
#include <linux/param.h>
28
#ifdef __ELF__
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
static 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 (ofd == -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((char *)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)) {
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
}
281
282