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>
29 # include <linux/elf.h>
30 # define elfhdr elf64_hdr
31 # define elf_phdr elf64_phdr
32 # define elf_check_arch(x) ((x)->e_machine == EM_ALPHA)
35 /* bootfile size must be multiple of BLOCK_SIZE: */
36 #define BLOCK_SIZE 512
38 const char * prog_name
;
45 "usage: %s [-v] -p file primary\n"
46 " %s [-vb] file [secondary]\n", prog_name
, prog_name
);
52 main (int argc
, char *argv
[])
54 size_t nwritten
, tocopy
, n
, mem_size
, fil_size
, pad
= 0;
55 int fd
, ofd
, i
, j
, verbose
= 0, primary
= 0;
56 char buf
[8192], *inname
;
57 struct exec
* aout
; /* includes file & aout header */
61 struct elf_phdr
*elf_phdr
; /* program header */
62 unsigned long long e_entry
;
67 for (i
= 1; i
< argc
&& argv
[i
][0] == '-'; ++i
) {
68 for (j
= 1; argv
[i
][j
]; ++j
) {
79 primary
= 1; /* make primary bootblock */
90 fd
= open(inname
, O_RDONLY
);
98 ofd
= open(argv
[i
++], O_WRONLY
| O_CREAT
| O_TRUNC
, 0666);
106 /* generate bootblock for primary loader */
108 unsigned long bb
[64], sum
= 0;
117 if (fstat(fd
, &st
) == -1) {
122 size
= (st
.st_size
+ BLOCK_SIZE
- 1) & ~(BLOCK_SIZE
- 1);
123 memset(bb
, 0, sizeof(bb
));
124 strcpy((char *) bb
, "Linux SRM bootblock");
125 bb
[60] = size
/ BLOCK_SIZE
; /* count */
126 bb
[61] = 1; /* starting sector # */
127 bb
[62] = 0; /* flags---must be 0 */
128 for (i
= 0; i
< 63; ++i
) {
132 if (write(ofd
, bb
, sizeof(bb
)) != sizeof(bb
)) {
133 perror("boot-block write");
136 printf("%lu\n", size
);
140 /* read and inspect exec header: */
142 if (read(fd
, buf
, sizeof(buf
)) < 0) {
148 elf
= (struct elfhdr
*) buf
;
150 if (elf
->e_ident
[0] == 0x7f && strncmp((char *)elf
->e_ident
+ 1, "ELF", 3) == 0) {
151 if (elf
->e_type
!= ET_EXEC
) {
152 fprintf(stderr
, "%s: %s is not an ELF executable\n",
156 if (!elf_check_arch(elf
)) {
157 fprintf(stderr
, "%s: is not for this processor (e_machine=%d)\n",
158 prog_name
, elf
->e_machine
);
161 if (elf
->e_phnum
!= 1) {
163 "%s: %d program headers (forgot to link with -N?)\n",
164 prog_name
, elf
->e_phnum
);
167 e_entry
= elf
->e_entry
;
169 lseek(fd
, elf
->e_phoff
, SEEK_SET
);
170 if (read(fd
, buf
, sizeof(*elf_phdr
)) != sizeof(*elf_phdr
)) {
175 elf_phdr
= (struct elf_phdr
*) buf
;
176 offset
= elf_phdr
->p_offset
;
177 mem_size
= elf_phdr
->p_memsz
;
178 fil_size
= elf_phdr
->p_filesz
;
180 /* work around ELF bug: */
181 if (elf_phdr
->p_vaddr
< e_entry
) {
182 unsigned long delta
= e_entry
- elf_phdr
->p_vaddr
;
186 elf_phdr
->p_vaddr
+= delta
;
190 fprintf(stderr
, "%s: extracting %#016lx-%#016lx (at %lx)\n",
191 prog_name
, (long) elf_phdr
->p_vaddr
,
192 elf_phdr
->p_vaddr
+ fil_size
, offset
);
197 aout
= (struct exec
*) buf
;
199 if (!(aout
->fh
.f_flags
& COFF_F_EXEC
)) {
200 fprintf(stderr
, "%s: %s is not in executable format\n",
205 if (aout
->fh
.f_opthdr
!= sizeof(aout
->ah
)) {
206 fprintf(stderr
, "%s: %s has unexpected optional header size\n",
211 if (N_MAGIC(*aout
) != OMAGIC
) {
212 fprintf(stderr
, "%s: %s is not an OMAGIC file\n",
216 offset
= N_TXTOFF(*aout
);
217 fil_size
= aout
->ah
.tsize
+ aout
->ah
.dsize
;
218 mem_size
= fil_size
+ aout
->ah
.bsize
;
221 fprintf(stderr
, "%s: extracting %#016lx-%#016lx (at %lx)\n",
222 prog_name
, aout
->ah
.text_start
,
223 aout
->ah
.text_start
+ fil_size
, offset
);
227 if (lseek(fd
, offset
, SEEK_SET
) != offset
) {
233 fprintf(stderr
, "%s: copying %lu byte from %s\n",
234 prog_name
, (unsigned long) fil_size
, inname
);
240 if (n
> sizeof(buf
)) {
244 if ((size_t) read(fd
, buf
, n
) != n
) {
249 nwritten
= write(ofd
, buf
, n
);
250 if ((ssize_t
) nwritten
== -1) {
259 mem_size
= ((mem_size
+ pad
- 1) / pad
) * pad
;
262 tocopy
= mem_size
- fil_size
;
265 "%s: zero-filling bss and aligning to %lu with %lu bytes\n",
266 prog_name
, pad
, (unsigned long) tocopy
);
268 memset(buf
, 0x00, sizeof(buf
));
271 if (n
> sizeof(buf
)) {
274 nwritten
= write(ofd
, buf
, n
);
275 if ((ssize_t
) nwritten
== -1) {
280 } while (tocopy
> 0);