elfedit: Move ELF header magic bytes check to get_file_header
[external/binutils.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 }