~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/alpha/boot/tools/objstrip.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * arch/alpha/boot/tools/objstrip.c
  4  *
  5  * Strip the object file headers/trailers from an executable (ELF or ECOFF).
  6  *
  7  * Copyright (C) 1996 David Mosberger-Tang.
  8  */
  9 /*
 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.
 16  */
 17 #include <stdio.h>
 18 #include <string.h>
 19 #include <stdlib.h>
 20 #include <unistd.h>
 21 
 22 #include <sys/fcntl.h>
 23 #include <sys/stat.h>
 24 #include <sys/types.h>
 25 
 26 #include <linux/a.out.h>
 27 #include <linux/coff.h>
 28 #include <linux/param.h>
 29 #ifdef __ELF__
 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)
 34 #endif
 35 
 36 /* bootfile size must be multiple of BLOCK_SIZE: */
 37 #define BLOCK_SIZE      512
 38 
 39 const char * prog_name;
 40 
 41 
 42 static void
 43 usage (void)
 44 {
 45     fprintf(stderr,
 46             "usage: %s [-v] -p file primary\n"
 47             "       %s [-vb] file [secondary]\n", prog_name, prog_name);
 48     exit(1);
 49 }
 50 
 51 
 52 int
 53 main (int argc, char *argv[])
 54 {
 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 */
 59     long offset;
 60 #ifdef __ELF__
 61     struct elfhdr *elf;
 62     struct elf_phdr *elf_phdr;  /* program header */
 63     unsigned long long e_entry;
 64 #endif
 65 
 66     prog_name = argv[0];
 67 
 68     for (i = 1; i < argc && argv[i][0] == '-'; ++i) {
 69         for (j = 1; argv[i][j]; ++j) {
 70             switch (argv[i][j]) {
 71               case 'v':
 72                   verbose = ~verbose;
 73                   break;
 74 
 75               case 'b':
 76                   pad = BLOCK_SIZE;
 77                   break;
 78 
 79               case 'p':
 80                   primary = 1;          /* make primary bootblock */
 81                   break;
 82             }
 83         }
 84     }
 85 
 86     if (i >= argc) {
 87         usage();
 88     }
 89     inname = argv[i++];
 90 
 91     fd = open(inname, O_RDONLY);
 92     if (fd == -1) {
 93         perror("open");
 94         exit(1);
 95     }
 96 
 97     ofd = 1;
 98     if (i < argc) {
 99         ofd = open(argv[i++], O_WRONLY | O_CREAT | O_TRUNC, 0666);
100         if (ofd == -1) {
101             perror("open");
102             exit(1);
103         }
104     }
105 
106     if (primary) {
107         /* generate bootblock for primary loader */
108         
109         unsigned long bb[64], sum = 0;
110         struct stat st;
111         off_t size;
112         int i;
113 
114         if (ofd == 1) {
115             usage();
116         }
117 
118         if (fstat(fd, &st) == -1) {
119             perror("fstat");
120             exit(1);
121         }
122 
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) {
130             sum += bb[i];
131         }
132         bb[63] = sum;
133         if (write(ofd, bb, sizeof(bb)) != sizeof(bb)) {
134             perror("boot-block write");
135             exit(1);
136         }
137         printf("%lu\n", size);
138         return 0;
139     }
140 
141     /* read and inspect exec header: */
142 
143     if (read(fd, buf, sizeof(buf)) < 0) {
144         perror("read");
145         exit(1);
146     }
147 
148 #ifdef __ELF__
149     elf = (struct elfhdr *) buf;
150 
151     if (memcmp(&elf->e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0) {
152         if (elf->e_type != ET_EXEC) {
153             fprintf(stderr, "%s: %s is not an ELF executable\n",
154                     prog_name, inname);
155             exit(1);
156         }
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);
160             exit(1);
161         }
162         if (elf->e_phnum != 1) {
163             fprintf(stderr,
164                     "%s: %d program headers (forgot to link with -N?)\n",
165                     prog_name, elf->e_phnum);
166         }
167 
168         e_entry = elf->e_entry;
169 
170         lseek(fd, elf->e_phoff, SEEK_SET);
171         if (read(fd, buf, sizeof(*elf_phdr)) != sizeof(*elf_phdr)) {
172             perror("read");
173             exit(1);
174         }
175 
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;
180 
181         /* work around ELF bug: */
182         if (elf_phdr->p_vaddr < e_entry) {
183             unsigned long delta = e_entry - elf_phdr->p_vaddr;
184             offset   += delta;
185             mem_size -= delta;
186             fil_size -= delta;
187             elf_phdr->p_vaddr += delta;
188         }
189 
190         if (verbose) {
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);
194         }
195     } else
196 #endif
197     {
198         aout = (struct exec *) buf;
199 
200         if (!(aout->fh.f_flags & COFF_F_EXEC)) {
201             fprintf(stderr, "%s: %s is not in executable format\n",
202                     prog_name, inname);
203             exit(1);
204         }
205 
206         if (aout->fh.f_opthdr != sizeof(aout->ah)) {
207             fprintf(stderr, "%s: %s has unexpected optional header size\n",
208                     prog_name, inname);
209             exit(1);
210         }
211 
212         if (N_MAGIC(*aout) != OMAGIC) {
213             fprintf(stderr, "%s: %s is not an OMAGIC file\n",
214                     prog_name, inname);
215             exit(1);
216         }
217         offset = N_TXTOFF(*aout);
218         fil_size = aout->ah.tsize + aout->ah.dsize;
219         mem_size = fil_size + aout->ah.bsize;
220 
221         if (verbose) {
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);
225         }
226     }
227 
228     if (lseek(fd, offset, SEEK_SET) != offset) {
229         perror("lseek");
230         exit(1);
231     }
232 
233     if (verbose) {
234         fprintf(stderr, "%s: copying %lu byte from %s\n",
235                 prog_name, (unsigned long) fil_size, inname);
236     }
237 
238     tocopy = fil_size;
239     while (tocopy > 0) {
240         n = tocopy;
241         if (n > sizeof(buf)) {
242             n = sizeof(buf);
243         }
244         tocopy -= n;
245         if ((size_t) read(fd, buf, n) != n) {
246             perror("read");
247             exit(1);
248         }
249         do {
250             nwritten = write(ofd, buf, n);
251             if ((ssize_t) nwritten == -1) {
252                 perror("write");
253                 exit(1);
254             }
255             n -= nwritten;
256         } while (n > 0);
257     }
258 
259     if (pad) {
260         mem_size = ((mem_size + pad - 1) / pad) * pad;
261     }
262 
263     tocopy = mem_size - fil_size;
264     if (tocopy > 0) {
265         fprintf(stderr,
266                 "%s: zero-filling bss and aligning to %lu with %lu bytes\n",
267                 prog_name, pad, (unsigned long) tocopy);
268 
269         memset(buf, 0x00, sizeof(buf));
270         do {
271             n = tocopy;
272             if (n > sizeof(buf)) {
273                 n = sizeof(buf);
274             }
275             nwritten = write(ofd, buf, n);
276             if ((ssize_t) nwritten == -1) {
277                 perror("write");
278                 exit(1);
279             }
280             tocopy -= nwritten;
281         } while (tocopy > 0);
282     }
283     return 0;
284 }
285 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php