Add EM_386/EM_IAMCU support to elfedit.c
[deliverable/binutils-gdb.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 }
This page took 0.050377 seconds and 5 git commands to generate.