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