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