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