1/* elfedit.c -- Update the ELF header of an ELF format file
2   Copyright (C) 2010-2017 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
45char * program_name = "elfedit";
46static long archive_file_offset;
47static unsigned long archive_file_size;
48static Elf_Internal_Ehdr elf_header;
49static Elf32_External_Ehdr ehdr32;
50static Elf64_External_Ehdr ehdr64;
51static int input_elf_machine = -1;
52static int output_elf_machine = -1;
53static int input_elf_type = -1;
54static int output_elf_type = -1;
55static int input_elf_osabi = -1;
56static int output_elf_osabi = -1;
57enum 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  };
65static enum elfclass input_elf_class = ELF_CLASS_UNKNOWN;
66static enum elfclass output_elf_class = ELF_CLASS_BOTH;
67
68/* Return ELF class for a machine type, MACH.  */
69
70static enum elfclass
71elf_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
89static int
90update_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
208static int
209get_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\
26964 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
301static int
302process_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
328static int
329process_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
482static int
483check_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
509static int
510process_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
550static const struct
551{
552  int osabi;
553  const char *name;
554}
555osabis[] =
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
577static int
578elf_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
593static int
594elf_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
618static int
619elf_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
635enum 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
645static 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
658ATTRIBUTE_NORETURN static void
659usage (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
681int
682main (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