1 /* elfedit.c -- Update the ELF header of an ELF format file
2 Copyright (C) 2010-2020 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
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.
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.
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
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. */
37 #include "elf/common.h"
38 #include "elf/external.h"
39 #include "elf/internal.h"
42 #include "libiberty.h"
43 #include "safe-ctype.h"
44 #include "filenames.h"
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;
60 ELF_CLASS_UNKNOWN
= -1,
61 ELF_CLASS_NONE
= ELFCLASSNONE
,
62 ELF_CLASS_32
= ELFCLASS32
,
63 ELF_CLASS_64
= ELFCLASS64
,
66 static enum elfclass input_elf_class
= ELF_CLASS_UNKNOWN
;
67 static enum elfclass output_elf_class
= ELF_CLASS_BOTH
;
72 static unsigned int enable_x86_features
;
73 static unsigned int disable_x86_features
;
76 update_gnu_property (const char *file_name
, FILE *file
)
79 Elf_Internal_Phdr
*phdrs
;
84 if (!enable_x86_features
&& !disable_x86_features
)
87 if (elf_header
.e_machine
!= EM_386
88 && elf_header
.e_machine
!= EM_X86_64
)
90 error (_("%s: Not an i386 nor x86-64 ELF file\n"), file_name
);
94 if (fstat (fileno (file
), &st_buf
) < 0)
96 error (_("%s: stat () failed\n"), file_name
);
100 map
= mmap (NULL
, st_buf
.st_size
, PROT_READ
| PROT_WRITE
,
101 MAP_SHARED
, fileno (file
), 0);
102 if (map
== MAP_FAILED
)
104 error (_("%s: mmap () failed\n"), file_name
);
108 phdrs
= xmalloc (elf_header
.e_phnum
* sizeof (*phdrs
));
110 if (elf_header
.e_ident
[EI_CLASS
] == ELFCLASS32
)
112 Elf32_External_Phdr
*phdrs32
113 = (Elf32_External_Phdr
*) (map
+ elf_header
.e_phoff
);
114 for (i
= 0; i
< elf_header
.e_phnum
; i
++)
116 phdrs
[i
].p_type
= BYTE_GET (phdrs32
[i
].p_type
);
117 phdrs
[i
].p_offset
= BYTE_GET (phdrs32
[i
].p_offset
);
118 phdrs
[i
].p_vaddr
= BYTE_GET (phdrs32
[i
].p_vaddr
);
119 phdrs
[i
].p_paddr
= BYTE_GET (phdrs32
[i
].p_paddr
);
120 phdrs
[i
].p_filesz
= BYTE_GET (phdrs32
[i
].p_filesz
);
121 phdrs
[i
].p_memsz
= BYTE_GET (phdrs32
[i
].p_memsz
);
122 phdrs
[i
].p_flags
= BYTE_GET (phdrs32
[i
].p_flags
);
123 phdrs
[i
].p_align
= BYTE_GET (phdrs32
[i
].p_align
);
128 Elf64_External_Phdr
*phdrs64
129 = (Elf64_External_Phdr
*) (map
+ elf_header
.e_phoff
);
130 for (i
= 0; i
< elf_header
.e_phnum
; i
++)
132 phdrs
[i
].p_type
= BYTE_GET (phdrs64
[i
].p_type
);
133 phdrs
[i
].p_offset
= BYTE_GET (phdrs64
[i
].p_offset
);
134 phdrs
[i
].p_vaddr
= BYTE_GET (phdrs64
[i
].p_vaddr
);
135 phdrs
[i
].p_paddr
= BYTE_GET (phdrs64
[i
].p_paddr
);
136 phdrs
[i
].p_filesz
= BYTE_GET (phdrs64
[i
].p_filesz
);
137 phdrs
[i
].p_memsz
= BYTE_GET (phdrs64
[i
].p_memsz
);
138 phdrs
[i
].p_flags
= BYTE_GET (phdrs64
[i
].p_flags
);
139 phdrs
[i
].p_align
= BYTE_GET (phdrs64
[i
].p_align
);
144 for (i
= 0; i
< elf_header
.e_phnum
; i
++)
145 if (phdrs
[i
].p_type
== PT_NOTE
)
147 size_t offset
= phdrs
[i
].p_offset
;
148 size_t size
= phdrs
[i
].p_filesz
;
149 size_t align
= phdrs
[i
].p_align
;
150 char *buf
= map
+ offset
;
153 while (p
< buf
+ size
)
155 Elf_External_Note
*xnp
= (Elf_External_Note
*) p
;
156 Elf_Internal_Note in
;
158 if (offsetof (Elf_External_Note
, name
) > buf
- p
+ size
)
164 in
.type
= BYTE_GET (xnp
->type
);
165 in
.namesz
= BYTE_GET (xnp
->namesz
);
166 in
.namedata
= xnp
->name
;
167 if (in
.namesz
> buf
- in
.namedata
+ size
)
173 in
.descsz
= BYTE_GET (xnp
->descsz
);
174 in
.descdata
= p
+ ELF_NOTE_DESC_OFFSET (in
.namesz
, align
);
175 in
.descpos
= offset
+ (in
.descdata
- buf
);
177 && (in
.descdata
>= buf
+ size
178 || in
.descsz
> buf
- in
.descdata
+ size
))
184 if (in
.namesz
== sizeof "GNU"
185 && strcmp (in
.namedata
, "GNU") == 0
186 && in
.type
== NT_GNU_PROPERTY_TYPE_0
)
189 unsigned char *ptr_end
;
191 if (in
.descsz
< 8 || (in
.descsz
% align
) != 0)
197 ptr
= (unsigned char *) in
.descdata
;
198 ptr_end
= ptr
+ in
.descsz
;
202 unsigned int type
= byte_get (ptr
, 4);
203 unsigned int datasz
= byte_get (ptr
+ 4, 4);
204 unsigned int bitmask
, old_bitmask
;
207 if ((ptr
+ datasz
) > ptr_end
)
213 if (type
== GNU_PROPERTY_X86_FEATURE_1_AND
)
221 old_bitmask
= byte_get (ptr
, 4);
222 bitmask
= old_bitmask
;
223 if (enable_x86_features
)
224 bitmask
|= enable_x86_features
;
225 if (disable_x86_features
)
226 bitmask
&= ~disable_x86_features
;
227 if (old_bitmask
!= bitmask
)
228 byte_put (ptr
, bitmask
, 4);
232 ptr
+= ELF_ALIGN_UP (datasz
, align
);
234 while ((ptr_end
- ptr
) >= 8);
237 p
+= ELF_NOTE_NEXT_OFFSET (in
.namesz
, in
.descsz
, align
);
243 error (_("%s: Invalid PT_NOTE segment\n"), file_name
);
246 munmap (map
, st_buf
.st_size
);
251 /* Set enable_x86_features and disable_x86_features for a feature
255 elf_x86_feature (const char *feature
, int enable
)
257 unsigned int x86_feature
;
258 if (strcasecmp (feature
, "ibt") == 0)
259 x86_feature
= GNU_PROPERTY_X86_FEATURE_1_IBT
;
260 else if (strcasecmp (feature
, "shstk") == 0)
261 x86_feature
= GNU_PROPERTY_X86_FEATURE_1_SHSTK
;
264 error (_("Unknown x86 feature: %s\n"), feature
);
270 enable_x86_features
|= x86_feature
;
271 disable_x86_features
&= ~x86_feature
;
275 disable_x86_features
|= x86_feature
;
276 enable_x86_features
&= ~x86_feature
;
283 /* Return ELF class for a machine type, MACH. */
298 return ELF_CLASS_BOTH
;
300 return ELF_CLASS_BOTH
;
305 update_elf_header (const char *file_name
, FILE *file
)
307 int class, machine
, type
, status
, osabi
;
309 if (elf_header
.e_ident
[EI_VERSION
] != EV_CURRENT
)
312 (_("%s: Unsupported EI_VERSION: %d is not %d\n"),
313 file_name
, elf_header
.e_ident
[EI_VERSION
],
318 /* Return if e_machine is the same as output_elf_machine. */
319 if (output_elf_machine
== elf_header
.e_machine
)
322 class = elf_header
.e_ident
[EI_CLASS
];
323 machine
= elf_header
.e_machine
;
325 /* Skip if class doesn't match. */
326 if (input_elf_class
== ELF_CLASS_UNKNOWN
)
327 input_elf_class
= elf_class (machine
);
329 if (input_elf_class
!= ELF_CLASS_BOTH
330 && (int) input_elf_class
!= class)
333 (_("%s: Unmatched input EI_CLASS: %d is not %d\n"),
334 file_name
, class, input_elf_class
);
338 if (output_elf_class
!= ELF_CLASS_BOTH
339 && (int) output_elf_class
!= class)
342 (_("%s: Unmatched output EI_CLASS: %d is not %d\n"),
343 file_name
, class, output_elf_class
);
347 /* Skip if e_machine doesn't match. */
348 if (input_elf_machine
!= -1 && machine
!= input_elf_machine
)
351 (_("%s: Unmatched e_machine: %d is not %d\n"),
352 file_name
, machine
, input_elf_machine
);
356 type
= elf_header
.e_type
;
358 /* Skip if e_type doesn't match. */
359 if (input_elf_type
!= -1 && type
!= input_elf_type
)
362 (_("%s: Unmatched e_type: %d is not %d\n"),
363 file_name
, type
, input_elf_type
);
367 osabi
= elf_header
.e_ident
[EI_OSABI
];
369 /* Skip if OSABI doesn't match. */
370 if (input_elf_osabi
!= -1 && osabi
!= input_elf_osabi
)
373 (_("%s: Unmatched EI_OSABI: %d is not %d\n"),
374 file_name
, osabi
, input_elf_osabi
);
378 /* Update e_machine, e_type and EI_OSABI. */
382 /* We should never get here. */
386 if (output_elf_machine
!= -1)
387 BYTE_PUT (ehdr32
.e_machine
, output_elf_machine
);
388 if (output_elf_type
!= -1)
389 BYTE_PUT (ehdr32
.e_type
, output_elf_type
);
390 if (output_elf_osabi
!= -1)
391 ehdr32
.e_ident
[EI_OSABI
] = output_elf_osabi
;
392 status
= fwrite (&ehdr32
, sizeof (ehdr32
), 1, file
) == 1;
395 if (output_elf_machine
!= -1)
396 BYTE_PUT (ehdr64
.e_machine
, output_elf_machine
);
397 if (output_elf_type
!= -1)
398 BYTE_PUT (ehdr64
.e_type
, output_elf_type
);
399 if (output_elf_osabi
!= -1)
400 ehdr64
.e_ident
[EI_OSABI
] = output_elf_osabi
;
401 status
= fwrite (&ehdr64
, sizeof (ehdr64
), 1, file
) == 1;
406 error (_("%s: Failed to update ELF header: %s\n"),
407 file_name
, strerror (errno
));
413 get_file_header (FILE * file
)
415 /* Read in the identity array. */
416 if (fread (elf_header
.e_ident
, EI_NIDENT
, 1, file
) != 1)
419 if (elf_header
.e_ident
[EI_MAG0
] != ELFMAG0
420 || elf_header
.e_ident
[EI_MAG1
] != ELFMAG1
421 || elf_header
.e_ident
[EI_MAG2
] != ELFMAG2
422 || elf_header
.e_ident
[EI_MAG3
] != ELFMAG3
)
425 /* Determine how to read the rest of the header. */
426 switch (elf_header
.e_ident
[EI_DATA
])
428 default: /* fall through */
429 case ELFDATANONE
: /* fall through */
431 byte_get
= byte_get_little_endian
;
432 byte_put
= byte_put_little_endian
;
435 byte_get
= byte_get_big_endian
;
436 byte_put
= byte_put_big_endian
;
440 /* Read in the rest of the header. For now we only support 32 bit
441 and 64 bit ELF files. */
442 switch (elf_header
.e_ident
[EI_CLASS
])
448 if (fread (ehdr32
.e_type
, sizeof (ehdr32
) - EI_NIDENT
,
452 elf_header
.e_type
= BYTE_GET (ehdr32
.e_type
);
453 elf_header
.e_machine
= BYTE_GET (ehdr32
.e_machine
);
454 elf_header
.e_version
= BYTE_GET (ehdr32
.e_version
);
455 elf_header
.e_entry
= BYTE_GET (ehdr32
.e_entry
);
456 elf_header
.e_phoff
= BYTE_GET (ehdr32
.e_phoff
);
457 elf_header
.e_shoff
= BYTE_GET (ehdr32
.e_shoff
);
458 elf_header
.e_flags
= BYTE_GET (ehdr32
.e_flags
);
459 elf_header
.e_ehsize
= BYTE_GET (ehdr32
.e_ehsize
);
460 elf_header
.e_phentsize
= BYTE_GET (ehdr32
.e_phentsize
);
461 elf_header
.e_phnum
= BYTE_GET (ehdr32
.e_phnum
);
462 elf_header
.e_shentsize
= BYTE_GET (ehdr32
.e_shentsize
);
463 elf_header
.e_shnum
= BYTE_GET (ehdr32
.e_shnum
);
464 elf_header
.e_shstrndx
= BYTE_GET (ehdr32
.e_shstrndx
);
466 memcpy (&ehdr32
, &elf_header
, EI_NIDENT
);
470 /* If we have been compiled with sizeof (bfd_vma) == 4, then
471 we will not be able to cope with the 64bit data found in
472 64 ELF files. Detect this now and abort before we start
473 overwriting things. */
474 if (sizeof (bfd_vma
) < 8)
476 error (_("This executable has been built without support for a\n\
477 64 bit data type and so it cannot process 64 bit ELF files.\n"));
481 if (fread (ehdr64
.e_type
, sizeof (ehdr64
) - EI_NIDENT
,
485 elf_header
.e_type
= BYTE_GET (ehdr64
.e_type
);
486 elf_header
.e_machine
= BYTE_GET (ehdr64
.e_machine
);
487 elf_header
.e_version
= BYTE_GET (ehdr64
.e_version
);
488 elf_header
.e_entry
= BYTE_GET (ehdr64
.e_entry
);
489 elf_header
.e_phoff
= BYTE_GET (ehdr64
.e_phoff
);
490 elf_header
.e_shoff
= BYTE_GET (ehdr64
.e_shoff
);
491 elf_header
.e_flags
= BYTE_GET (ehdr64
.e_flags
);
492 elf_header
.e_ehsize
= BYTE_GET (ehdr64
.e_ehsize
);
493 elf_header
.e_phentsize
= BYTE_GET (ehdr64
.e_phentsize
);
494 elf_header
.e_phnum
= BYTE_GET (ehdr64
.e_phnum
);
495 elf_header
.e_shentsize
= BYTE_GET (ehdr64
.e_shentsize
);
496 elf_header
.e_shnum
= BYTE_GET (ehdr64
.e_shnum
);
497 elf_header
.e_shstrndx
= BYTE_GET (ehdr64
.e_shstrndx
);
499 memcpy (&ehdr64
, &elf_header
, EI_NIDENT
);
505 /* Process one ELF object file according to the command line options.
506 This file may actually be stored in an archive. The file is
507 positioned at the start of the ELF object. */
510 process_object (const char *file_name
, FILE *file
)
512 /* Rememeber where we are. */
513 long offset
= ftell (file
);
515 if (! get_file_header (file
))
517 error (_("%s: Failed to read ELF header\n"), file_name
);
521 /* Go to the position of the ELF header. */
522 if (fseek (file
, offset
, SEEK_SET
) != 0)
524 error (_("%s: Failed to seek to ELF header\n"), file_name
);
527 if (! update_elf_header (file_name
, file
))
533 /* Process an ELF archive.
534 On entry the file is positioned just after the ARMAG string. */
537 process_archive (const char * file_name
, FILE * file
,
538 bfd_boolean is_thin_archive
)
540 struct archive_info arch
;
541 struct archive_info nested_arch
;
545 /* The ARCH structure is used to hold information about this archive. */
546 arch
.file_name
= NULL
;
548 arch
.index_array
= NULL
;
549 arch
.sym_table
= NULL
;
550 arch
.longnames
= NULL
;
552 /* The NESTED_ARCH structure is used as a single-item cache of information
553 about a nested archive (when members of a thin archive reside within
554 another regular archive file). */
555 nested_arch
.file_name
= NULL
;
556 nested_arch
.file
= NULL
;
557 nested_arch
.index_array
= NULL
;
558 nested_arch
.sym_table
= NULL
;
559 nested_arch
.longnames
= NULL
;
561 if (setup_archive (&arch
, file_name
, file
, is_thin_archive
, FALSE
) != 0)
573 char * qualified_name
;
575 /* Read the next archive header. */
576 if (fseek (file
, arch
.next_arhdr_offset
, SEEK_SET
) != 0)
578 error (_("%s: failed to seek to next archive header\n"),
582 got
= fread (&arch
.arhdr
, 1, sizeof arch
.arhdr
, file
);
583 if (got
!= sizeof arch
.arhdr
)
587 error (_("%s: failed to read archive header\n"),
592 if (memcmp (arch
.arhdr
.ar_fmag
, ARFMAG
, 2) != 0)
594 error (_("%s: did not find a valid archive header\n"),
600 arch
.next_arhdr_offset
+= sizeof arch
.arhdr
;
602 archive_file_size
= strtoul (arch
.arhdr
.ar_size
, NULL
, 10);
603 if (archive_file_size
& 01)
606 name
= get_archive_member_name (&arch
, &nested_arch
);
609 error (_("%s: bad archive file name\n"), file_name
);
613 namelen
= strlen (name
);
615 qualified_name
= make_qualified_name (&arch
, &nested_arch
, name
);
616 if (qualified_name
== NULL
)
618 error (_("%s: bad archive file name\n"), file_name
);
623 if (is_thin_archive
&& arch
.nested_member_origin
== 0)
625 /* This is a proxy for an external member of a thin archive. */
627 char *member_file_name
= adjust_relative_path (file_name
,
629 if (member_file_name
== NULL
)
635 member_file
= fopen (member_file_name
, "r+b");
636 if (member_file
== NULL
)
638 error (_("Input file '%s' is not readable\n"),
640 free (member_file_name
);
645 archive_file_offset
= arch
.nested_member_origin
;
647 ret
|= process_object (qualified_name
, member_file
);
649 fclose (member_file
);
650 free (member_file_name
);
652 else if (is_thin_archive
)
654 /* This is a proxy for a member of a nested archive. */
655 archive_file_offset
= arch
.nested_member_origin
+ sizeof arch
.arhdr
;
657 /* The nested archive file will have been opened and setup by
658 get_archive_member_name. */
659 if (fseek (nested_arch
.file
, archive_file_offset
,
662 error (_("%s: failed to seek to archive member\n"),
663 nested_arch
.file_name
);
668 ret
|= process_object (qualified_name
, nested_arch
.file
);
672 archive_file_offset
= arch
.next_arhdr_offset
;
673 arch
.next_arhdr_offset
+= archive_file_size
;
675 ret
|= process_object (qualified_name
, file
);
678 free (qualified_name
);
682 if (nested_arch
.file
!= NULL
)
683 fclose (nested_arch
.file
);
684 release_archive (&nested_arch
);
685 release_archive (&arch
);
691 check_file (const char *file_name
, struct stat
*statbuf_p
)
695 if (statbuf_p
== NULL
)
696 statbuf_p
= &statbuf
;
698 if (stat (file_name
, statbuf_p
) < 0)
701 error (_("'%s': No such file\n"), file_name
);
703 error (_("Could not locate '%s'. System error message: %s\n"),
704 file_name
, strerror (errno
));
708 if (! S_ISREG (statbuf_p
->st_mode
))
710 error (_("'%s' is not an ordinary file\n"), file_name
);
718 process_file (const char *file_name
)
724 if (check_file (file_name
, NULL
))
727 file
= fopen (file_name
, "r+b");
730 error (_("Input file '%s' is not readable\n"), file_name
);
734 if (fread (armag
, SARMAG
, 1, file
) != 1)
736 error (_("%s: Failed to read file's magic number\n"),
742 if (memcmp (armag
, ARMAG
, SARMAG
) == 0)
743 ret
= process_archive (file_name
, file
, FALSE
);
744 else if (memcmp (armag
, ARMAGT
, SARMAG
) == 0)
745 ret
= process_archive (file_name
, file
, TRUE
);
749 archive_file_size
= archive_file_offset
= 0;
750 ret
= process_object (file_name
, file
);
753 && (elf_header
.e_type
== ET_EXEC
754 || elf_header
.e_type
== ET_DYN
))
755 ret
= update_gnu_property (file_name
, file
);
771 { ELFOSABI_NONE
, "none" },
772 { ELFOSABI_HPUX
, "HPUX" },
773 { ELFOSABI_NETBSD
, "NetBSD" },
774 { ELFOSABI_GNU
, "GNU" },
775 { ELFOSABI_GNU
, "Linux" },
776 { ELFOSABI_SOLARIS
, "Solaris" },
777 { ELFOSABI_AIX
, "AIX" },
778 { ELFOSABI_IRIX
, "Irix" },
779 { ELFOSABI_FREEBSD
, "FreeBSD" },
780 { ELFOSABI_TRU64
, "TRU64" },
781 { ELFOSABI_MODESTO
, "Modesto" },
782 { ELFOSABI_OPENBSD
, "OpenBSD" },
783 { ELFOSABI_OPENVMS
, "OpenVMS" },
784 { ELFOSABI_NSK
, "NSK" },
785 { ELFOSABI_AROS
, "AROS" },
786 { ELFOSABI_FENIXOS
, "FenixOS" }
789 /* Return ELFOSABI_XXX for an OSABI string, OSABI. */
792 elf_osabi (const char *osabi
)
796 for (i
= 0; i
< ARRAY_SIZE (osabis
); i
++)
797 if (strcasecmp (osabi
, osabis
[i
].name
) == 0)
798 return osabis
[i
].osabi
;
800 error (_("Unknown OSABI: %s\n"), osabi
);
805 /* Return EM_XXX for a machine string, MACH. */
808 elf_machine (const char *mach
)
810 if (strcasecmp (mach
, "i386") == 0)
812 if (strcasecmp (mach
, "iamcu") == 0)
814 if (strcasecmp (mach
, "l1om") == 0)
816 if (strcasecmp (mach
, "k1om") == 0)
818 if (strcasecmp (mach
, "x86_64") == 0)
820 if (strcasecmp (mach
, "x86-64") == 0)
822 if (strcasecmp (mach
, "none") == 0)
825 error (_("Unknown machine type: %s\n"), mach
);
830 /* Return ET_XXX for a type string, TYPE. */
833 elf_type (const char *type
)
835 if (strcasecmp (type
, "rel") == 0)
837 if (strcasecmp (type
, "exec") == 0)
839 if (strcasecmp (type
, "dyn") == 0)
841 if (strcasecmp (type
, "none") == 0)
844 error (_("Unknown type: %s\n"), type
);
849 enum command_line_switch
851 OPTION_INPUT_MACH
= 150,
858 OPTION_ENABLE_X86_FEATURE
,
859 OPTION_DISABLE_X86_FEATURE
,
863 static struct option options
[] =
865 {"input-mach", required_argument
, 0, OPTION_INPUT_MACH
},
866 {"output-mach", required_argument
, 0, OPTION_OUTPUT_MACH
},
867 {"input-type", required_argument
, 0, OPTION_INPUT_TYPE
},
868 {"output-type", required_argument
, 0, OPTION_OUTPUT_TYPE
},
869 {"input-osabi", required_argument
, 0, OPTION_INPUT_OSABI
},
870 {"output-osabi", required_argument
, 0, OPTION_OUTPUT_OSABI
},
872 {"enable-x86-feature",
873 required_argument
, 0, OPTION_ENABLE_X86_FEATURE
},
874 {"disable-x86-feature",
875 required_argument
, 0, OPTION_DISABLE_X86_FEATURE
},
877 {"version", no_argument
, 0, 'v'},
878 {"help", no_argument
, 0, 'h'},
879 {0, no_argument
, 0, 0}
882 ATTRIBUTE_NORETURN
static void
883 usage (FILE *stream
, int exit_status
)
885 fprintf (stream
, _("Usage: %s <option(s)> elffile(s)\n"),
887 fprintf (stream
, _(" Update the ELF header of ELF files\n"));
888 fprintf (stream
, _(" The options are:\n"));
889 fprintf (stream
, _("\
890 --input-mach <machine> Set input machine type to <machine>\n\
891 --output-mach <machine> Set output machine type to <machine>\n\
892 --input-type <type> Set input file type to <type>\n\
893 --output-type <type> Set output file type to <type>\n\
894 --input-osabi <osabi> Set input OSABI to <osabi>\n\
895 --output-osabi <osabi> Set output OSABI to <osabi>\n"));
897 fprintf (stream
, _("\
898 --enable-x86-feature <feature>\n\
899 Enable x86 feature <feature>\n\
900 --disable-x86-feature <feature>\n\
901 Disable x86 feature <feature>\n"));
903 fprintf (stream
, _("\
904 -h --help Display this information\n\
905 -v --version Display the version number of %s\n\
908 if (REPORT_BUGS_TO
[0] && exit_status
== 0)
909 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);
914 main (int argc
, char ** argv
)
918 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
919 setlocale (LC_MESSAGES
, "");
921 #if defined (HAVE_SETLOCALE)
922 setlocale (LC_CTYPE
, "");
924 bindtextdomain (PACKAGE
, LOCALEDIR
);
925 textdomain (PACKAGE
);
927 expandargv (&argc
, &argv
);
929 while ((c
= getopt_long (argc
, argv
, "hv",
930 options
, (int *) 0)) != EOF
)
934 case OPTION_INPUT_MACH
:
935 input_elf_machine
= elf_machine (optarg
);
936 if (input_elf_machine
< 0)
938 input_elf_class
= elf_class (input_elf_machine
);
939 if (input_elf_class
== ELF_CLASS_UNKNOWN
)
943 case OPTION_OUTPUT_MACH
:
944 output_elf_machine
= elf_machine (optarg
);
945 if (output_elf_machine
< 0)
947 output_elf_class
= elf_class (output_elf_machine
);
948 if (output_elf_class
== ELF_CLASS_UNKNOWN
)
952 case OPTION_INPUT_TYPE
:
953 input_elf_type
= elf_type (optarg
);
954 if (input_elf_type
< 0)
958 case OPTION_OUTPUT_TYPE
:
959 output_elf_type
= elf_type (optarg
);
960 if (output_elf_type
< 0)
964 case OPTION_INPUT_OSABI
:
965 input_elf_osabi
= elf_osabi (optarg
);
966 if (input_elf_osabi
< 0)
970 case OPTION_OUTPUT_OSABI
:
971 output_elf_osabi
= elf_osabi (optarg
);
972 if (output_elf_osabi
< 0)
977 case OPTION_ENABLE_X86_FEATURE
:
978 if (elf_x86_feature (optarg
, 1) < 0)
982 case OPTION_DISABLE_X86_FEATURE
:
983 if (elf_x86_feature (optarg
, 0) < 0)
992 print_version (program_name
);
1001 || (output_elf_machine
== -1
1003 && ! enable_x86_features
1004 && ! disable_x86_features
1006 && output_elf_type
== -1
1007 && output_elf_osabi
== -1))
1011 while (optind
< argc
)
1012 status
|= process_file (argv
[optind
++]);