x86: correctly handle KMOVD with VEX.W set outside of 64-bit mode
[deliverable/binutils-gdb.git] / binutils / elfedit.c
1 /* elfedit.c -- Update the ELF header of an ELF format file
2 Copyright (C) 2010-2018 Free Software Foundation, Inc.
3
4 This file is part of GNU Binutils.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
19 02110-1301, USA. */
20 \f
21 #include "sysdep.h"
22 #include <assert.h>
23
24 #if __GNUC__ >= 2
25 /* Define BFD64 here, even if our default architecture is 32 bit ELF
26 as this will allow us to read in and parse 64bit and 32bit ELF files.
27 Only do this if we believe that the compiler can support a 64 bit
28 data type. For now we only rely on GCC being able to do this. */
29 #define BFD64
30 #endif
31
32 #include "bfd.h"
33 #include "elfcomm.h"
34 #include "bucomm.h"
35
36 #include "elf/common.h"
37 #include "elf/external.h"
38 #include "elf/internal.h"
39
40 #include "getopt.h"
41 #include "libiberty.h"
42 #include "safe-ctype.h"
43 #include "filenames.h"
44
45 char * program_name = "elfedit";
46 static long archive_file_offset;
47 static unsigned long archive_file_size;
48 static Elf_Internal_Ehdr elf_header;
49 static Elf32_External_Ehdr ehdr32;
50 static Elf64_External_Ehdr ehdr64;
51 static int input_elf_machine = -1;
52 static int output_elf_machine = -1;
53 static int input_elf_type = -1;
54 static int output_elf_type = -1;
55 static int input_elf_osabi = -1;
56 static int output_elf_osabi = -1;
57 enum elfclass
58 {
59 ELF_CLASS_UNKNOWN = -1,
60 ELF_CLASS_NONE = ELFCLASSNONE,
61 ELF_CLASS_32 = ELFCLASS32,
62 ELF_CLASS_64 = ELFCLASS64,
63 ELF_CLASS_BOTH
64 };
65 static enum elfclass input_elf_class = ELF_CLASS_UNKNOWN;
66 static enum elfclass output_elf_class = ELF_CLASS_BOTH;
67
68 /* Return ELF class for a machine type, MACH. */
69
70 static enum elfclass
71 elf_class (int mach)
72 {
73 switch (mach)
74 {
75 case EM_386:
76 case EM_IAMCU:
77 return ELF_CLASS_32;
78 case EM_L1OM:
79 case EM_K1OM:
80 return ELF_CLASS_64;
81 case EM_X86_64:
82 case EM_NONE:
83 return ELF_CLASS_BOTH;
84 default:
85 return ELF_CLASS_BOTH;
86 }
87 }
88
89 static int
90 update_elf_header (const char *file_name, FILE *file)
91 {
92 int class, machine, type, status, osabi;
93
94 if (elf_header.e_ident[EI_VERSION] != EV_CURRENT)
95 {
96 error
97 (_("%s: Unsupported EI_VERSION: %d is not %d\n"),
98 file_name, elf_header.e_ident[EI_VERSION],
99 EV_CURRENT);
100 return 0;
101 }
102
103 /* Return if e_machine is the same as output_elf_machine. */
104 if (output_elf_machine == elf_header.e_machine)
105 return 1;
106
107 class = elf_header.e_ident[EI_CLASS];
108 machine = elf_header.e_machine;
109
110 /* Skip if class doesn't match. */
111 if (input_elf_class == ELF_CLASS_UNKNOWN)
112 input_elf_class = elf_class (machine);
113
114 if (input_elf_class != ELF_CLASS_BOTH
115 && (int) input_elf_class != class)
116 {
117 error
118 (_("%s: Unmatched input EI_CLASS: %d is not %d\n"),
119 file_name, class, input_elf_class);
120 return 0;
121 }
122
123 if (output_elf_class != ELF_CLASS_BOTH
124 && (int) output_elf_class != class)
125 {
126 error
127 (_("%s: Unmatched output EI_CLASS: %d is not %d\n"),
128 file_name, class, output_elf_class);
129 return 0;
130 }
131
132 /* Skip if e_machine doesn't match. */
133 if (input_elf_machine != -1 && machine != input_elf_machine)
134 {
135 error
136 (_("%s: Unmatched e_machine: %d is not %d\n"),
137 file_name, machine, input_elf_machine);
138 return 0;
139 }
140
141 type = elf_header.e_type;
142
143 /* Skip if e_type doesn't match. */
144 if (input_elf_type != -1 && type != input_elf_type)
145 {
146 error
147 (_("%s: Unmatched e_type: %d is not %d\n"),
148 file_name, type, input_elf_type);
149 return 0;
150 }
151
152 osabi = elf_header.e_ident[EI_OSABI];
153
154 /* Skip if OSABI doesn't match. */
155 if (input_elf_osabi != -1 && osabi != input_elf_osabi)
156 {
157 error
158 (_("%s: Unmatched EI_OSABI: %d is not %d\n"),
159 file_name, osabi, input_elf_osabi);
160 return 0;
161 }
162
163 /* Update e_machine, e_type and EI_OSABI. */
164 switch (class)
165 {
166 default:
167 /* We should never get here. */
168 abort ();
169 break;
170 case ELFCLASS32:
171 if (output_elf_machine != -1)
172 BYTE_PUT (ehdr32.e_machine, output_elf_machine);
173 if (output_elf_type != -1)
174 BYTE_PUT (ehdr32.e_type, output_elf_type);
175 if (output_elf_osabi != -1)
176 ehdr32.e_ident[EI_OSABI] = output_elf_osabi;
177 status = fwrite (&ehdr32, sizeof (ehdr32), 1, file) == 1;
178 break;
179 case ELFCLASS64:
180 if (output_elf_machine != -1)
181 BYTE_PUT (ehdr64.e_machine, output_elf_machine);
182 if (output_elf_type != -1)
183 BYTE_PUT (ehdr64.e_type, output_elf_type);
184 if (output_elf_osabi != -1)
185 ehdr64.e_ident[EI_OSABI] = output_elf_osabi;
186 status = fwrite (&ehdr64, sizeof (ehdr64), 1, file) == 1;
187 break;
188 }
189
190 if (status != 1)
191 error (_("%s: Failed to update ELF header: %s\n"),
192 file_name, strerror (errno));
193
194 return status;
195 }
196
197 static int
198 get_file_header (FILE * file)
199 {
200 /* Read in the identity array. */
201 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
202 return 0;
203
204 if (elf_header.e_ident[EI_MAG0] != ELFMAG0
205 || elf_header.e_ident[EI_MAG1] != ELFMAG1
206 || elf_header.e_ident[EI_MAG2] != ELFMAG2
207 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
208 return 0;
209
210 /* Determine how to read the rest of the header. */
211 switch (elf_header.e_ident[EI_DATA])
212 {
213 default: /* fall through */
214 case ELFDATANONE: /* fall through */
215 case ELFDATA2LSB:
216 byte_get = byte_get_little_endian;
217 byte_put = byte_put_little_endian;
218 break;
219 case ELFDATA2MSB:
220 byte_get = byte_get_big_endian;
221 byte_put = byte_put_big_endian;
222 break;
223 }
224
225 /* Read in the rest of the header. For now we only support 32 bit
226 and 64 bit ELF files. */
227 switch (elf_header.e_ident[EI_CLASS])
228 {
229 default:
230 return 0;
231
232 case ELFCLASS32:
233 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT,
234 1, file) != 1)
235 return 0;
236
237 elf_header.e_type = BYTE_GET (ehdr32.e_type);
238 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
239 elf_header.e_version = BYTE_GET (ehdr32.e_version);
240 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
241 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
242 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
243 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
244 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
245 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
246 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
247 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
248 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
249 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
250
251 memcpy (&ehdr32, &elf_header, EI_NIDENT);
252 break;
253
254 case ELFCLASS64:
255 /* If we have been compiled with sizeof (bfd_vma) == 4, then
256 we will not be able to cope with the 64bit data found in
257 64 ELF files. Detect this now and abort before we start
258 overwriting things. */
259 if (sizeof (bfd_vma) < 8)
260 {
261 error (_("This executable has been built without support for a\n\
262 64 bit data type and so it cannot process 64 bit ELF files.\n"));
263 return 0;
264 }
265
266 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT,
267 1, file) != 1)
268 return 0;
269
270 elf_header.e_type = BYTE_GET (ehdr64.e_type);
271 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
272 elf_header.e_version = BYTE_GET (ehdr64.e_version);
273 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
274 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
275 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
276 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
277 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
278 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
279 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
280 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
281 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
282 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
283
284 memcpy (&ehdr64, &elf_header, EI_NIDENT);
285 break;
286 }
287 return 1;
288 }
289
290 /* Process one ELF object file according to the command line options.
291 This file may actually be stored in an archive. The file is
292 positioned at the start of the ELF object. */
293
294 static int
295 process_object (const char *file_name, FILE *file)
296 {
297 /* Rememeber where we are. */
298 long offset = ftell (file);
299
300 if (! get_file_header (file))
301 {
302 error (_("%s: Failed to read ELF header\n"), file_name);
303 return 1;
304 }
305
306 /* Go to the position of the ELF header. */
307 if (fseek (file, offset, SEEK_SET) != 0)
308 {
309 error (_("%s: Failed to seek to ELF header\n"), file_name);
310 }
311
312 if (! update_elf_header (file_name, file))
313 return 1;
314
315 return 0;
316 }
317
318 /* Process an ELF archive.
319 On entry the file is positioned just after the ARMAG string. */
320
321 static int
322 process_archive (const char * file_name, FILE * file,
323 bfd_boolean is_thin_archive)
324 {
325 struct archive_info arch;
326 struct archive_info nested_arch;
327 size_t got;
328 int ret;
329
330 /* The ARCH structure is used to hold information about this archive. */
331 arch.file_name = NULL;
332 arch.file = NULL;
333 arch.index_array = NULL;
334 arch.sym_table = NULL;
335 arch.longnames = NULL;
336
337 /* The NESTED_ARCH structure is used as a single-item cache of information
338 about a nested archive (when members of a thin archive reside within
339 another regular archive file). */
340 nested_arch.file_name = NULL;
341 nested_arch.file = NULL;
342 nested_arch.index_array = NULL;
343 nested_arch.sym_table = NULL;
344 nested_arch.longnames = NULL;
345
346 if (setup_archive (&arch, file_name, file, is_thin_archive, FALSE) != 0)
347 {
348 ret = 1;
349 goto out;
350 }
351
352 ret = 0;
353
354 while (1)
355 {
356 char * name;
357 size_t namelen;
358 char * qualified_name;
359
360 /* Read the next archive header. */
361 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
362 {
363 error (_("%s: failed to seek to next archive header\n"),
364 file_name);
365 return 1;
366 }
367 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
368 if (got != sizeof arch.arhdr)
369 {
370 if (got == 0)
371 break;
372 error (_("%s: failed to read archive header\n"),
373 file_name);
374 ret = 1;
375 break;
376 }
377 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
378 {
379 error (_("%s: did not find a valid archive header\n"),
380 arch.file_name);
381 ret = 1;
382 break;
383 }
384
385 arch.next_arhdr_offset += sizeof arch.arhdr;
386
387 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
388 if (archive_file_size & 01)
389 ++archive_file_size;
390
391 name = get_archive_member_name (&arch, &nested_arch);
392 if (name == NULL)
393 {
394 error (_("%s: bad archive file name\n"), file_name);
395 ret = 1;
396 break;
397 }
398 namelen = strlen (name);
399
400 qualified_name = make_qualified_name (&arch, &nested_arch, name);
401 if (qualified_name == NULL)
402 {
403 error (_("%s: bad archive file name\n"), file_name);
404 ret = 1;
405 break;
406 }
407
408 if (is_thin_archive && arch.nested_member_origin == 0)
409 {
410 /* This is a proxy for an external member of a thin archive. */
411 FILE *member_file;
412 char *member_file_name = adjust_relative_path (file_name,
413 name, namelen);
414 if (member_file_name == NULL)
415 {
416 ret = 1;
417 break;
418 }
419
420 member_file = fopen (member_file_name, "r+b");
421 if (member_file == NULL)
422 {
423 error (_("Input file '%s' is not readable\n"),
424 member_file_name);
425 free (member_file_name);
426 ret = 1;
427 break;
428 }
429
430 archive_file_offset = arch.nested_member_origin;
431
432 ret |= process_object (qualified_name, member_file);
433
434 fclose (member_file);
435 free (member_file_name);
436 }
437 else if (is_thin_archive)
438 {
439 /* This is a proxy for a member of a nested archive. */
440 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
441
442 /* The nested archive file will have been opened and setup by
443 get_archive_member_name. */
444 if (fseek (nested_arch.file, archive_file_offset,
445 SEEK_SET) != 0)
446 {
447 error (_("%s: failed to seek to archive member\n"),
448 nested_arch.file_name);
449 ret = 1;
450 break;
451 }
452
453 ret |= process_object (qualified_name, nested_arch.file);
454 }
455 else
456 {
457 archive_file_offset = arch.next_arhdr_offset;
458 arch.next_arhdr_offset += archive_file_size;
459
460 ret |= process_object (qualified_name, file);
461 }
462
463 free (qualified_name);
464 }
465
466 out:
467 if (nested_arch.file != NULL)
468 fclose (nested_arch.file);
469 release_archive (&nested_arch);
470 release_archive (&arch);
471
472 return ret;
473 }
474
475 static int
476 check_file (const char *file_name, struct stat *statbuf_p)
477 {
478 struct stat statbuf;
479
480 if (statbuf_p == NULL)
481 statbuf_p = &statbuf;
482
483 if (stat (file_name, statbuf_p) < 0)
484 {
485 if (errno == ENOENT)
486 error (_("'%s': No such file\n"), file_name);
487 else
488 error (_("Could not locate '%s'. System error message: %s\n"),
489 file_name, strerror (errno));
490 return 1;
491 }
492
493 if (! S_ISREG (statbuf_p->st_mode))
494 {
495 error (_("'%s' is not an ordinary file\n"), file_name);
496 return 1;
497 }
498
499 return 0;
500 }
501
502 static int
503 process_file (const char *file_name)
504 {
505 FILE * file;
506 char armag[SARMAG];
507 int ret;
508
509 if (check_file (file_name, NULL))
510 return 1;
511
512 file = fopen (file_name, "r+b");
513 if (file == NULL)
514 {
515 error (_("Input file '%s' is not readable\n"), file_name);
516 return 1;
517 }
518
519 if (fread (armag, SARMAG, 1, file) != 1)
520 {
521 error (_("%s: Failed to read file's magic number\n"),
522 file_name);
523 fclose (file);
524 return 1;
525 }
526
527 if (memcmp (armag, ARMAG, SARMAG) == 0)
528 ret = process_archive (file_name, file, FALSE);
529 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
530 ret = process_archive (file_name, file, TRUE);
531 else
532 {
533 rewind (file);
534 archive_file_size = archive_file_offset = 0;
535 ret = process_object (file_name, file);
536 }
537
538 fclose (file);
539
540 return ret;
541 }
542
543 static const struct
544 {
545 int osabi;
546 const char *name;
547 }
548 osabis[] =
549 {
550 { ELFOSABI_NONE, "none" },
551 { ELFOSABI_HPUX, "HPUX" },
552 { ELFOSABI_NETBSD, "NetBSD" },
553 { ELFOSABI_GNU, "GNU" },
554 { ELFOSABI_GNU, "Linux" },
555 { ELFOSABI_SOLARIS, "Solaris" },
556 { ELFOSABI_AIX, "AIX" },
557 { ELFOSABI_IRIX, "Irix" },
558 { ELFOSABI_FREEBSD, "FreeBSD" },
559 { ELFOSABI_TRU64, "TRU64" },
560 { ELFOSABI_MODESTO, "Modesto" },
561 { ELFOSABI_OPENBSD, "OpenBSD" },
562 { ELFOSABI_OPENVMS, "OpenVMS" },
563 { ELFOSABI_NSK, "NSK" },
564 { ELFOSABI_AROS, "AROS" },
565 { ELFOSABI_FENIXOS, "FenixOS" }
566 };
567
568 /* Return ELFOSABI_XXX for an OSABI string, OSABI. */
569
570 static int
571 elf_osabi (const char *osabi)
572 {
573 unsigned int i;
574
575 for (i = 0; i < ARRAY_SIZE (osabis); i++)
576 if (strcasecmp (osabi, osabis[i].name) == 0)
577 return osabis[i].osabi;
578
579 error (_("Unknown OSABI: %s\n"), osabi);
580
581 return -1;
582 }
583
584 /* Return EM_XXX for a machine string, MACH. */
585
586 static int
587 elf_machine (const char *mach)
588 {
589 if (strcasecmp (mach, "i386") == 0)
590 return EM_386;
591 if (strcasecmp (mach, "iamcu") == 0)
592 return EM_IAMCU;
593 if (strcasecmp (mach, "l1om") == 0)
594 return EM_L1OM;
595 if (strcasecmp (mach, "k1om") == 0)
596 return EM_K1OM;
597 if (strcasecmp (mach, "x86_64") == 0)
598 return EM_X86_64;
599 if (strcasecmp (mach, "x86-64") == 0)
600 return EM_X86_64;
601 if (strcasecmp (mach, "none") == 0)
602 return EM_NONE;
603
604 error (_("Unknown machine type: %s\n"), mach);
605
606 return -1;
607 }
608
609 /* Return ET_XXX for a type string, TYPE. */
610
611 static int
612 elf_type (const char *type)
613 {
614 if (strcasecmp (type, "rel") == 0)
615 return ET_REL;
616 if (strcasecmp (type, "exec") == 0)
617 return ET_EXEC;
618 if (strcasecmp (type, "dyn") == 0)
619 return ET_DYN;
620 if (strcasecmp (type, "none") == 0)
621 return ET_NONE;
622
623 error (_("Unknown type: %s\n"), type);
624
625 return -1;
626 }
627
628 enum command_line_switch
629 {
630 OPTION_INPUT_MACH = 150,
631 OPTION_OUTPUT_MACH,
632 OPTION_INPUT_TYPE,
633 OPTION_OUTPUT_TYPE,
634 OPTION_INPUT_OSABI,
635 OPTION_OUTPUT_OSABI
636 };
637
638 static struct option options[] =
639 {
640 {"input-mach", required_argument, 0, OPTION_INPUT_MACH},
641 {"output-mach", required_argument, 0, OPTION_OUTPUT_MACH},
642 {"input-type", required_argument, 0, OPTION_INPUT_TYPE},
643 {"output-type", required_argument, 0, OPTION_OUTPUT_TYPE},
644 {"input-osabi", required_argument, 0, OPTION_INPUT_OSABI},
645 {"output-osabi", required_argument, 0, OPTION_OUTPUT_OSABI},
646 {"version", no_argument, 0, 'v'},
647 {"help", no_argument, 0, 'h'},
648 {0, no_argument, 0, 0}
649 };
650
651 ATTRIBUTE_NORETURN static void
652 usage (FILE *stream, int exit_status)
653 {
654 fprintf (stream, _("Usage: %s <option(s)> elffile(s)\n"),
655 program_name);
656 fprintf (stream, _(" Update the ELF header of ELF files\n"));
657 fprintf (stream, _(" The options are:\n"));
658 fprintf (stream, _("\
659 --input-mach <machine> Set input machine type to <machine>\n\
660 --output-mach <machine> Set output machine type to <machine>\n\
661 --input-type <type> Set input file type to <type>\n\
662 --output-type <type> Set output file type to <type>\n\
663 --input-osabi <osabi> Set input OSABI to <osabi>\n\
664 --output-osabi <osabi> Set output OSABI to <osabi>\n\
665 -h --help Display this information\n\
666 -v --version Display the version number of %s\n\
667 "),
668 program_name);
669 if (REPORT_BUGS_TO[0] && exit_status == 0)
670 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
671 exit (exit_status);
672 }
673
674 int
675 main (int argc, char ** argv)
676 {
677 int c, status;
678
679 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
680 setlocale (LC_MESSAGES, "");
681 #endif
682 #if defined (HAVE_SETLOCALE)
683 setlocale (LC_CTYPE, "");
684 #endif
685 bindtextdomain (PACKAGE, LOCALEDIR);
686 textdomain (PACKAGE);
687
688 expandargv (&argc, &argv);
689
690 while ((c = getopt_long (argc, argv, "hv",
691 options, (int *) 0)) != EOF)
692 {
693 switch (c)
694 {
695 case OPTION_INPUT_MACH:
696 input_elf_machine = elf_machine (optarg);
697 if (input_elf_machine < 0)
698 return 1;
699 input_elf_class = elf_class (input_elf_machine);
700 if (input_elf_class == ELF_CLASS_UNKNOWN)
701 return 1;
702 break;
703
704 case OPTION_OUTPUT_MACH:
705 output_elf_machine = elf_machine (optarg);
706 if (output_elf_machine < 0)
707 return 1;
708 output_elf_class = elf_class (output_elf_machine);
709 if (output_elf_class == ELF_CLASS_UNKNOWN)
710 return 1;
711 break;
712
713 case OPTION_INPUT_TYPE:
714 input_elf_type = elf_type (optarg);
715 if (input_elf_type < 0)
716 return 1;
717 break;
718
719 case OPTION_OUTPUT_TYPE:
720 output_elf_type = elf_type (optarg);
721 if (output_elf_type < 0)
722 return 1;
723 break;
724
725 case OPTION_INPUT_OSABI:
726 input_elf_osabi = elf_osabi (optarg);
727 if (input_elf_osabi < 0)
728 return 1;
729 break;
730
731 case OPTION_OUTPUT_OSABI:
732 output_elf_osabi = elf_osabi (optarg);
733 if (output_elf_osabi < 0)
734 return 1;
735 break;
736
737 case 'h':
738 usage (stdout, 0);
739
740 case 'v':
741 print_version (program_name);
742 break;
743
744 default:
745 usage (stderr, 1);
746 }
747 }
748
749 if (optind == argc
750 || (output_elf_machine == -1
751 && output_elf_type == -1
752 && output_elf_osabi == -1))
753 usage (stderr, 1);
754
755 status = 0;
756 while (optind < argc)
757 status |= process_file (argv[optind++]);
758
759 return status;
760 }
This page took 0.045564 seconds and 4 git commands to generate.