2 * arch/alpha/boot/tools/objstrip.c
4 * Strip the object file headers/trailers from an executable (ELF or ECOFF).
6 * Copyright (C) 1996 David Mosberger-Tang.
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.
21 #include <sys/fcntl.h>
23 #include <sys/types.h>
25 #include <linux/a.out.h>
26 #include <linux/coff.h>
27 #include <linux/param.h>
28 #include <linux/string.h>
30 # include <linux/elf.h>
33 /* bootfile size must be multiple of BLOCK_SIZE: */
34 #define BLOCK_SIZE 512
36 const char * prog_name
;
43 "usage: %s [-v] -p file primary\n"
44 " %s [-vb] file [secondary]\n", prog_name
, prog_name
);
50 main (int argc
, char *argv
[])
52 size_t nwritten
, tocopy
, n
, mem_size
, fil_size
, pad
= 0;
53 int fd
, ofd
, i
, j
, verbose
= 0, primary
= 0;
54 char buf
[8192], *inname
;
55 struct exec
* aout
; /* includes file & aout header */
59 struct elf_phdr
*elf_phdr
; /* program header */
60 unsigned long long e_entry
;
65 for (i
= 1; i
< argc
&& argv
[i
][0] == '-'; ++i
) {
66 for (j
= 1; argv
[i
][j
]; ++j
) {
77 primary
= 1; /* make primary bootblock */
88 fd
= open(inname
, O_RDONLY
);
96 ofd
= open(argv
[i
++], O_WRONLY
| O_CREAT
| O_TRUNC
, 0666);
104 /* generate bootblock for primary loader */
106 unsigned long bb
[64], sum
= 0;
115 if (fstat(fd
, &st
) == -1) {
120 size
= (st
.st_size
+ BLOCK_SIZE
- 1) & ~(BLOCK_SIZE
- 1);
121 memset(bb
, 0, sizeof(bb
));
122 strcpy((char *) bb
, "Linux SRM bootblock");
123 bb
[60] = size
/ BLOCK_SIZE
; /* count */
124 bb
[61] = 1; /* starting sector # */
125 bb
[62] = 0; /* flags---must be 0 */
126 for (i
= 0; i
< 63; ++i
) {
130 if (write(ofd
, bb
, sizeof(bb
)) != sizeof(bb
)) {
131 perror("boot-block write");
134 printf("%lu\n", size
);
138 /* read and inspect exec header: */
140 if (read(fd
, buf
, sizeof(buf
)) < 0) {
146 elf
= (struct elfhdr
*) buf
;
148 if (elf
->e_ident
[0] == 0x7f && strncmp(elf
->e_ident
+ 1, "ELF", 3) == 0) {
149 if (elf
->e_type
!= ET_EXEC
) {
150 fprintf(stderr
, "%s: %s is not an ELF executable\n",
154 if (!elf_check_arch(elf
)) {
155 fprintf(stderr
, "%s: is not for this processor (e_machine=%d)\n",
156 prog_name
, elf
->e_machine
);
159 if (elf
->e_phnum
!= 1) {
161 "%s: %d program headers (forgot to link with -N?)\n",
162 prog_name
, elf
->e_phnum
);
165 e_entry
= elf
->e_entry
;
167 lseek(fd
, elf
->e_phoff
, SEEK_SET
);
168 if (read(fd
, buf
, sizeof(*elf_phdr
)) != sizeof(*elf_phdr
)) {
173 elf_phdr
= (struct elf_phdr
*) buf
;
174 offset
= elf_phdr
->p_offset
;
175 mem_size
= elf_phdr
->p_memsz
;
176 fil_size
= elf_phdr
->p_filesz
;
178 /* work around ELF bug: */
179 if (elf_phdr
->p_vaddr
< e_entry
) {
180 unsigned long delta
= e_entry
- elf_phdr
->p_vaddr
;
184 elf_phdr
->p_vaddr
+= delta
;
188 fprintf(stderr
, "%s: extracting %#016lx-%#016lx (at %lx)\n",
189 prog_name
, (long) elf_phdr
->p_vaddr
,
190 elf_phdr
->p_vaddr
+ fil_size
, offset
);
195 aout
= (struct exec
*) buf
;
197 if (!(aout
->fh
.f_flags
& COFF_F_EXEC
)) {
198 fprintf(stderr
, "%s: %s is not in executable format\n",
203 if (aout
->fh
.f_opthdr
!= sizeof(aout
->ah
)) {
204 fprintf(stderr
, "%s: %s has unexpected optional header size\n",
209 if (N_MAGIC(*aout
) != OMAGIC
) {
210 fprintf(stderr
, "%s: %s is not an OMAGIC file\n",
214 offset
= N_TXTOFF(*aout
);
215 fil_size
= aout
->ah
.tsize
+ aout
->ah
.dsize
;
216 mem_size
= fil_size
+ aout
->ah
.bsize
;
219 fprintf(stderr
, "%s: extracting %#016lx-%#016lx (at %lx)\n",
220 prog_name
, aout
->ah
.text_start
,
221 aout
->ah
.text_start
+ fil_size
, offset
);
225 if (lseek(fd
, offset
, SEEK_SET
) != offset
) {
231 fprintf(stderr
, "%s: copying %lu byte from %s\n",
232 prog_name
, (unsigned long) fil_size
, inname
);
238 if (n
> sizeof(buf
)) {
242 if ((size_t) read(fd
, buf
, n
) != n
) {
247 nwritten
= write(ofd
, buf
, n
);
248 if ((ssize_t
) nwritten
== -1) {
257 mem_size
= ((mem_size
+ pad
- 1) / pad
) * pad
;
260 tocopy
= mem_size
- fil_size
;
263 "%s: zero-filling bss and aligning to %lu with %lu bytes\n",
264 prog_name
, pad
, (unsigned long) tocopy
);
266 memset(buf
, 0x00, sizeof(buf
));
269 if (n
> sizeof(buf
)) {
272 nwritten
= write(ofd
, buf
, n
);
273 if ((ssize_t
) nwritten
== -1) {
278 } while (tocopy
> 0);