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 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.
19 #include <sys/fcntl.h>
21 #include <sys/types.h>
23 #include <linux/a.out.h>
24 #include <linux/coff.h>
25 #include <linux/param.h>
26 #include <linux/string.h>
29 # include <linux/elf.h>
32 /* bootfile size must be multiple of BLOCK_SIZE: */
33 #define BLOCK_SIZE 512
35 const char * prog_name
;
42 "usage: %s [-v] -p file primary\n"
43 " %s [-vb] file [secondary]\n", prog_name
, prog_name
);
49 main (int argc
, char *argv
[])
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 */
58 struct elf_phdr
*elf_phdr
; /* program header */
59 unsigned long long e_entry
;
64 for (i
= 1; i
< argc
&& argv
[i
][0] == '-'; ++i
) {
65 for (j
= 1; argv
[i
][j
]; ++j
) {
76 primary
= 1; /* make primary bootblock */
87 fd
= open(inname
, O_RDONLY
);
95 ofd
= open(argv
[i
++], O_WRONLY
| O_CREAT
| O_TRUNC
, 0666);
103 /* generate bootblock for primary loader */
105 unsigned long bb
[64], sum
= 0;
114 if (fstat(fd
, &st
) == -1) {
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
) {
129 if (write(ofd
, bb
, sizeof(bb
)) != sizeof(bb
)) {
130 perror("boot-block write");
133 printf("%lu\n", size
);
137 /* read and inspect exec header: */
139 if (read(fd
, buf
, sizeof(buf
)) < 0) {
145 elf
= (struct elfhdr
*) buf
;
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",
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
);
158 if (elf
->e_phnum
!= 1) {
160 "%s: %d program headers (forgot to link with -N?)\n",
161 prog_name
, elf
->e_phnum
);
164 e_entry
= elf
->e_entry
;
166 lseek(fd
, elf
->e_phoff
, SEEK_SET
);
167 if (read(fd
, buf
, sizeof(*elf_phdr
)) != sizeof(*elf_phdr
)) {
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
;
177 /* work around ELF bug: */
178 if (elf_phdr
->p_vaddr
< e_entry
) {
179 unsigned long delta
= e_entry
- elf_phdr
->p_vaddr
;
183 elf_phdr
->p_vaddr
+= delta
;
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
);
194 aout
= (struct exec
*) buf
;
196 if (!(aout
->fh
.f_flags
& COFF_F_EXEC
)) {
197 fprintf(stderr
, "%s: %s is not in executable format\n",
202 if (aout
->fh
.f_opthdr
!= sizeof(aout
->ah
)) {
203 fprintf(stderr
, "%s: %s has unexpected optional header size\n",
208 if (N_MAGIC(*aout
) != OMAGIC
) {
209 fprintf(stderr
, "%s: %s is not an OMAGIC file\n",
213 offset
= N_TXTOFF(*aout
);
214 fil_size
= aout
->ah
.tsize
+ aout
->ah
.dsize
;
215 mem_size
= fil_size
+ aout
->ah
.bsize
;
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
);
224 if (lseek(fd
, offset
, SEEK_SET
) != offset
) {
230 fprintf(stderr
, "%s: copying %lu byte from %s\n",
231 prog_name
, (unsigned long) fil_size
, inname
);
237 if (n
> sizeof(buf
)) {
241 if ((size_t) read(fd
, buf
, n
) != n
) {
246 nwritten
= write(ofd
, buf
, n
);
247 if ((ssize_t
) nwritten
== -1) {
256 mem_size
= ((mem_size
+ pad
- 1) / pad
) * pad
;
259 tocopy
= mem_size
- fil_size
;
262 "%s: zero-filling bss and aligning to %lu with %lu bytes\n",
263 prog_name
, pad
, (unsigned long) tocopy
);
265 memset(buf
, 0x00, sizeof(buf
));
268 if (n
> sizeof(buf
)) {
271 nwritten
= write(ofd
, buf
, n
);
272 if ((ssize_t
) nwritten
== -1) {
277 } while (tocopy
> 0);