OBVIOUS Fix a typo in ada-lang.c add_prefix_cmd for "set ada"
[deliverable/binutils-gdb.git] / binutils / elfedit.c
CommitLineData
30fd33bb 1/* elfedit.c -- Update the ELF header of an ELF format file
219d1afa 2 Copyright (C) 2010-2018 Free Software Foundation, Inc.
30fd33bb
L
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
30fd33bb
L
21#include "sysdep.h"
22#include <assert.h>
30fd33bb
L
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"
3284fe0c 33#include "elfcomm.h"
30fd33bb
L
34#include "bucomm.h"
35
36#include "elf/common.h"
37#include "elf/external.h"
38#include "elf/internal.h"
39
30fd33bb
L
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;
dd35de74
L
53static int input_elf_type = -1;
54static int output_elf_type = -1;
d0514c49
L
55static int input_elf_osabi = -1;
56static int output_elf_osabi = -1;
6c14750f
L
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:
aa9f7286 85 return ELF_CLASS_BOTH;
6c14750f
L
86 }
87}
30fd33bb 88
30fd33bb
L
89static int
90update_elf_header (const char *file_name, FILE *file)
91{
d0514c49 92 int class, machine, type, status, osabi;
30fd33bb
L
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 {
3284fe0c 99 error
30fd33bb
L
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 {
3284fe0c 107 error
30fd33bb
L
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
2dc654c3
L
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];
6c14750f 119 machine = elf_header.e_machine;
2dc654c3 120
30fd33bb 121 /* Skip if class doesn't match. */
6c14750f
L
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)
30fd33bb 127 {
3284fe0c 128 error
6c14750f 129 (_("%s: Unmatched input EI_CLASS: %d is not %d\n"),
2dc654c3 130 file_name, class, input_elf_class);
30fd33bb
L
131 return 0;
132 }
133
6c14750f
L
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 }
30fd33bb
L
142
143 /* Skip if e_machine doesn't match. */
2dc654c3 144 if (input_elf_machine != -1 && machine != input_elf_machine)
30fd33bb 145 {
3284fe0c 146 error
30fd33bb 147 (_("%s: Unmatched e_machine: %d is not %d\n"),
2dc654c3 148 file_name, machine, input_elf_machine);
30fd33bb
L
149 return 0;
150 }
151
dd35de74
L
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 {
3284fe0c 157 error
dd35de74
L
158 (_("%s: Unmatched e_type: %d is not %d\n"),
159 file_name, type, input_elf_type);
160 return 0;
161 }
162
d0514c49
L
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 {
3284fe0c 168 error
d0514c49
L
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. */
2dc654c3 175 switch (class)
30fd33bb
L
176 {
177 default:
178 /* We should never get here. */
179 abort ();
180 break;
181 case ELFCLASS32:
dd35de74
L
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);
d0514c49
L
186 if (output_elf_osabi != -1)
187 ehdr32.e_ident[EI_OSABI] = output_elf_osabi;
30fd33bb
L
188 status = fwrite (&ehdr32, sizeof (ehdr32), 1, file) == 1;
189 break;
190 case ELFCLASS64:
dd35de74
L
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);
d0514c49
L
195 if (output_elf_osabi != -1)
196 ehdr64.e_ident[EI_OSABI] = output_elf_osabi;
30fd33bb
L
197 status = fwrite (&ehdr64, sizeof (ehdr64), 1, file) == 1;
198 break;
199 }
200
201 if (status != 1)
3284fe0c 202 error (_("%s: Failed to update ELF header: %s\n"),
30fd33bb
L
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:
3284fe0c 235 error (_("Unsupported EI_CLASS: %d\n"),
30fd33bb
L
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 {
3284fe0c 268 error (_("This executable has been built without support for a\n\
30fd33bb
L
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 {
3284fe0c 309 error (_("%s: Failed to read ELF header\n"), file_name);
30fd33bb
L
310 return 1;
311 }
312
313 /* Go to the position of the ELF header. */
314 if (fseek (file, offset, SEEK_SET) != 0)
315 {
3284fe0c 316 error (_("%s: Failed to seek to ELF header\n"), file_name);
30fd33bb
L
317 }
318
319 if (! update_elf_header (file_name, file))
320 return 1;
321
322 return 0;
323}
324
30fd33bb
L
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;
30fd33bb
L
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
3284fe0c 353 if (setup_archive (&arch, file_name, file, is_thin_archive, FALSE) != 0)
30fd33bb
L
354 {
355 ret = 1;
356 goto out;
357 }
358
30fd33bb
L
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 {
3284fe0c 370 error (_("%s: failed to seek to next archive header\n"),
30fd33bb
L
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;
3284fe0c 379 error (_("%s: failed to read archive header\n"),
30fd33bb
L
380 file_name);
381 ret = 1;
382 break;
383 }
384 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
385 {
3284fe0c 386 error (_("%s: did not find a valid archive header\n"),
30fd33bb
L
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 {
3284fe0c 401 error (_("%s: bad archive file name\n"), file_name);
30fd33bb
L
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 {
3284fe0c 410 error (_("%s: bad archive file name\n"), file_name);
30fd33bb
L
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 {
3284fe0c 430 error (_("Input file '%s' is not readable\n"),
30fd33bb
L
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 {
3284fe0c 454 error (_("%s: failed to seek to archive member\n"),
30fd33bb
L
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)
3284fe0c 493 error (_("'%s': No such file\n"), file_name);
30fd33bb 494 else
3284fe0c 495 error (_("Could not locate '%s'. System error message: %s\n"),
30fd33bb
L
496 file_name, strerror (errno));
497 return 1;
498 }
499
500 if (! S_ISREG (statbuf_p->st_mode))
501 {
3284fe0c 502 error (_("'%s' is not an ordinary file\n"), file_name);
30fd33bb
L
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 {
3284fe0c 522 error (_("Input file '%s' is not readable\n"), file_name);
30fd33bb
L
523 return 1;
524 }
525
526 if (fread (armag, SARMAG, 1, file) != 1)
527 {
3284fe0c 528 error (_("%s: Failed to read file's magic number\n"),
30fd33bb
L
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
d0514c49
L
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" },
9c55345c
TS
560 { ELFOSABI_GNU, "GNU" },
561 { ELFOSABI_GNU, "Linux" },
d0514c49
L
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
3284fe0c 586 error (_("Unknown OSABI: %s\n"), osabi);
d0514c49
L
587
588 return -1;
589}
590
30fd33bb
L
591/* Return EM_XXX for a machine string, MACH. */
592
593static int
594elf_machine (const char *mach)
595{
6c14750f
L
596 if (strcasecmp (mach, "i386") == 0)
597 return EM_386;
598 if (strcasecmp (mach, "iamcu") == 0)
599 return EM_IAMCU;
30fd33bb
L
600 if (strcasecmp (mach, "l1om") == 0)
601 return EM_L1OM;
7a9068fe
L
602 if (strcasecmp (mach, "k1om") == 0)
603 return EM_K1OM;
30fd33bb
L
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
3284fe0c 611 error (_("Unknown machine type: %s\n"), mach);
30fd33bb
L
612
613 return -1;
614}
615
dd35de74
L
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
3284fe0c 630 error (_("Unknown type: %s\n"), type);
dd35de74
L
631
632 return -1;
633}
634
30fd33bb
L
635enum command_line_switch
636 {
637 OPTION_INPUT_MACH = 150,
dd35de74
L
638 OPTION_OUTPUT_MACH,
639 OPTION_INPUT_TYPE,
d0514c49
L
640 OPTION_OUTPUT_TYPE,
641 OPTION_INPUT_OSABI,
642 OPTION_OUTPUT_OSABI
30fd33bb
L
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},
dd35de74
L
649 {"input-type", required_argument, 0, OPTION_INPUT_TYPE},
650 {"output-type", required_argument, 0, OPTION_OUTPUT_TYPE},
d0514c49
L
651 {"input-osabi", required_argument, 0, OPTION_INPUT_OSABI},
652 {"output-osabi", required_argument, 0, OPTION_OUTPUT_OSABI},
30fd33bb
L
653 {"version", no_argument, 0, 'v'},
654 {"help", no_argument, 0, 'h'},
655 {0, no_argument, 0, 0}
656};
657
1e0f0b4d 658ATTRIBUTE_NORETURN static void
30fd33bb
L
659usage (FILE *stream, int exit_status)
660{
d0514c49 661 fprintf (stream, _("Usage: %s <option(s)> elffile(s)\n"),
30fd33bb
L
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\
dd35de74
L
668 --input-type <type> Set input file type to <type>\n\
669 --output-type <type> Set output file type to <type>\n\
d0514c49
L
670 --input-osabi <osabi> Set input OSABI to <osabi>\n\
671 --output-osabi <osabi> Set output OSABI to <osabi>\n\
30fd33bb
L
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);
6c14750f 707 if (input_elf_class == ELF_CLASS_UNKNOWN)
30fd33bb
L
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;
6c14750f
L
715 output_elf_class = elf_class (output_elf_machine);
716 if (output_elf_class == ELF_CLASS_UNKNOWN)
717 return 1;
30fd33bb
L
718 break;
719
dd35de74
L
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
d0514c49
L
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
30fd33bb
L
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
dd35de74
L
756 if (optind == argc
757 || (output_elf_machine == -1
d0514c49
L
758 && output_elf_type == -1
759 && output_elf_osabi == -1))
30fd33bb
L
760 usage (stderr, 1);
761
762 status = 0;
763 while (optind < argc)
764 status |= process_file (argv[optind++]);
765
766 return status;
767}
This page took 0.768195 seconds and 4 git commands to generate.