1 // SPDX-License-Identifier: GPL-2.0
3 * arch/alpha/boot/tools/objstrip.c
5 * Strip the object file headers/trailers from an executable (ELF or ECOFF).
7 * Copyright (C) 1996 David Mosberger-Tang.
10 * Converts an ECOFF or ELF object file into a bootable file. The
11 * object file must be a OMAGIC file (i.e., data and bss follow immediately
12 * behind the text). See DEC "Assembly Language Programmer's Guide"
13 * documentation for details. The SRM boot process is documented in
14 * the Alpha AXP Architecture Reference Manual, Second Edition by
15 * Richard L. Sites and Richard T. Witek.
22 #include <sys/fcntl.h>
24 #include <sys/types.h>
26 #include <linux/a.out.h>
27 #include <linux/coff.h>
28 #include <linux/param.h>
30 # include <linux/elf.h>
31 # define elfhdr elf64_hdr
32 # define elf_phdr elf64_phdr
33 # define elf_check_arch(x) ((x)->e_machine == EM_ALPHA)
36 /* bootfile size must be multiple of BLOCK_SIZE: */
37 #define BLOCK_SIZE 512
39 const char * prog_name
;
46 "usage: %s [-v] -p file primary\n"
47 " %s [-vb] file [secondary]\n", prog_name
, prog_name
);
53 main (int argc
, char *argv
[])
55 size_t nwritten
, tocopy
, n
, mem_size
, fil_size
, pad
= 0;
56 int fd
, ofd
, i
, j
, verbose
= 0, primary
= 0;
57 char buf
[8192], *inname
;
58 struct exec
* aout
; /* includes file & aout header */
62 struct elf_phdr
*elf_phdr
; /* program header */
63 unsigned long long e_entry
;
68 for (i
= 1; i
< argc
&& argv
[i
][0] == '-'; ++i
) {
69 for (j
= 1; argv
[i
][j
]; ++j
) {
80 primary
= 1; /* make primary bootblock */
91 fd
= open(inname
, O_RDONLY
);
99 ofd
= open(argv
[i
++], O_WRONLY
| O_CREAT
| O_TRUNC
, 0666);
107 /* generate bootblock for primary loader */
109 unsigned long bb
[64], sum
= 0;
118 if (fstat(fd
, &st
) == -1) {
123 size
= (st
.st_size
+ BLOCK_SIZE
- 1) & ~(BLOCK_SIZE
- 1);
124 memset(bb
, 0, sizeof(bb
));
125 strcpy((char *) bb
, "Linux SRM bootblock");
126 bb
[60] = size
/ BLOCK_SIZE
; /* count */
127 bb
[61] = 1; /* starting sector # */
128 bb
[62] = 0; /* flags---must be 0 */
129 for (i
= 0; i
< 63; ++i
) {
133 if (write(ofd
, bb
, sizeof(bb
)) != sizeof(bb
)) {
134 perror("boot-block write");
137 printf("%lu\n", size
);
141 /* read and inspect exec header: */
143 if (read(fd
, buf
, sizeof(buf
)) < 0) {
149 elf
= (struct elfhdr
*) buf
;
151 if (elf
->e_ident
[0] == 0x7f && strncmp((char *)elf
->e_ident
+ 1, "ELF", 3) == 0) {
152 if (elf
->e_type
!= ET_EXEC
) {
153 fprintf(stderr
, "%s: %s is not an ELF executable\n",
157 if (!elf_check_arch(elf
)) {
158 fprintf(stderr
, "%s: is not for this processor (e_machine=%d)\n",
159 prog_name
, elf
->e_machine
);
162 if (elf
->e_phnum
!= 1) {
164 "%s: %d program headers (forgot to link with -N?)\n",
165 prog_name
, elf
->e_phnum
);
168 e_entry
= elf
->e_entry
;
170 lseek(fd
, elf
->e_phoff
, SEEK_SET
);
171 if (read(fd
, buf
, sizeof(*elf_phdr
)) != sizeof(*elf_phdr
)) {
176 elf_phdr
= (struct elf_phdr
*) buf
;
177 offset
= elf_phdr
->p_offset
;
178 mem_size
= elf_phdr
->p_memsz
;
179 fil_size
= elf_phdr
->p_filesz
;
181 /* work around ELF bug: */
182 if (elf_phdr
->p_vaddr
< e_entry
) {
183 unsigned long delta
= e_entry
- elf_phdr
->p_vaddr
;
187 elf_phdr
->p_vaddr
+= delta
;
191 fprintf(stderr
, "%s: extracting %#016lx-%#016lx (at %lx)\n",
192 prog_name
, (long) elf_phdr
->p_vaddr
,
193 elf_phdr
->p_vaddr
+ fil_size
, offset
);
198 aout
= (struct exec
*) buf
;
200 if (!(aout
->fh
.f_flags
& COFF_F_EXEC
)) {
201 fprintf(stderr
, "%s: %s is not in executable format\n",
206 if (aout
->fh
.f_opthdr
!= sizeof(aout
->ah
)) {
207 fprintf(stderr
, "%s: %s has unexpected optional header size\n",
212 if (N_MAGIC(*aout
) != OMAGIC
) {
213 fprintf(stderr
, "%s: %s is not an OMAGIC file\n",
217 offset
= N_TXTOFF(*aout
);
218 fil_size
= aout
->ah
.tsize
+ aout
->ah
.dsize
;
219 mem_size
= fil_size
+ aout
->ah
.bsize
;
222 fprintf(stderr
, "%s: extracting %#016lx-%#016lx (at %lx)\n",
223 prog_name
, aout
->ah
.text_start
,
224 aout
->ah
.text_start
+ fil_size
, offset
);
228 if (lseek(fd
, offset
, SEEK_SET
) != offset
) {
234 fprintf(stderr
, "%s: copying %lu byte from %s\n",
235 prog_name
, (unsigned long) fil_size
, inname
);
241 if (n
> sizeof(buf
)) {
245 if ((size_t) read(fd
, buf
, n
) != n
) {
250 nwritten
= write(ofd
, buf
, n
);
251 if ((ssize_t
) nwritten
== -1) {
260 mem_size
= ((mem_size
+ pad
- 1) / pad
) * pad
;
263 tocopy
= mem_size
- fil_size
;
266 "%s: zero-filling bss and aligning to %lu with %lu bytes\n",
267 prog_name
, pad
, (unsigned long) tocopy
);
269 memset(buf
, 0x00, sizeof(buf
));
272 if (n
> sizeof(buf
)) {
275 nwritten
= write(ofd
, buf
, n
);
276 if ((ssize_t
) nwritten
== -1) {
281 } while (tocopy
> 0);