1 /* elfedit.c -- Update the ELF header of an ELF format file
2    Copyright (C) 2010-2016 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 
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 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 }
768