1 /* elfedit.c -- Update the ELF header of an ELF format file
2 Copyright (C) 2010-2020 Free Software Foundation, Inc.
3 Copyright (C) 2019-2020 Advanced Micro Devices, Inc. All rights reserved.
5 This file is part of GNU Binutils.
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.
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.
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
27 /* Define BFD64 here, even if our default architecture is 32 bit ELF
28 as this will allow us to read in and parse 64bit and 32bit ELF files.
29 Only do this if we believe that the compiler can support a 64 bit
30 data type. For now we only rely on GCC being able to do this. */
38 #include "elf/common.h"
39 #include "elf/external.h"
40 #include "elf/internal.h"
43 #include "libiberty.h"
44 #include "safe-ctype.h"
45 #include "filenames.h"
47 char * program_name
= "elfedit";
48 static long archive_file_offset
;
49 static unsigned long archive_file_size
;
50 static Elf_Internal_Ehdr elf_header
;
51 static Elf32_External_Ehdr ehdr32
;
52 static Elf64_External_Ehdr ehdr64
;
53 static int input_elf_machine
= -1;
54 static int output_elf_machine
= -1;
55 static int input_elf_type
= -1;
56 static int output_elf_type
= -1;
57 static int input_elf_osabi
= -1;
58 static int output_elf_osabi
= -1;
61 ELF_CLASS_UNKNOWN
= -1,
62 ELF_CLASS_NONE
= ELFCLASSNONE
,
63 ELF_CLASS_32
= ELFCLASS32
,
64 ELF_CLASS_64
= ELFCLASS64
,
67 static enum elfclass input_elf_class
= ELF_CLASS_UNKNOWN
;
68 static enum elfclass output_elf_class
= ELF_CLASS_BOTH
;
73 static unsigned int enable_x86_features
;
74 static unsigned int disable_x86_features
;
77 update_gnu_property (const char *file_name
, FILE *file
)
80 Elf_Internal_Phdr
*phdrs
;
85 if (!enable_x86_features
&& !disable_x86_features
)
88 if (elf_header
.e_machine
!= EM_386
89 && elf_header
.e_machine
!= EM_X86_64
)
91 error (_("%s: Not an i386 nor x86-64 ELF file\n"), file_name
);
95 if (fstat (fileno (file
), &st_buf
) < 0)
97 error (_("%s: stat () failed\n"), file_name
);
101 map
= mmap (NULL
, st_buf
.st_size
, PROT_READ
| PROT_WRITE
,
102 MAP_SHARED
, fileno (file
), 0);
103 if (map
== MAP_FAILED
)
105 error (_("%s: mmap () failed\n"), file_name
);
109 phdrs
= xmalloc (elf_header
.e_phnum
* sizeof (*phdrs
));
111 if (elf_header
.e_ident
[EI_CLASS
] == ELFCLASS32
)
113 Elf32_External_Phdr
*phdrs32
114 = (Elf32_External_Phdr
*) (map
+ elf_header
.e_phoff
);
115 for (i
= 0; i
< elf_header
.e_phnum
; i
++)
117 phdrs
[i
].p_type
= BYTE_GET (phdrs32
[i
].p_type
);
118 phdrs
[i
].p_offset
= BYTE_GET (phdrs32
[i
].p_offset
);
119 phdrs
[i
].p_vaddr
= BYTE_GET (phdrs32
[i
].p_vaddr
);
120 phdrs
[i
].p_paddr
= BYTE_GET (phdrs32
[i
].p_paddr
);
121 phdrs
[i
].p_filesz
= BYTE_GET (phdrs32
[i
].p_filesz
);
122 phdrs
[i
].p_memsz
= BYTE_GET (phdrs32
[i
].p_memsz
);
123 phdrs
[i
].p_flags
= BYTE_GET (phdrs32
[i
].p_flags
);
124 phdrs
[i
].p_align
= BYTE_GET (phdrs32
[i
].p_align
);
129 Elf64_External_Phdr
*phdrs64
130 = (Elf64_External_Phdr
*) (map
+ elf_header
.e_phoff
);
131 for (i
= 0; i
< elf_header
.e_phnum
; i
++)
133 phdrs
[i
].p_type
= BYTE_GET (phdrs64
[i
].p_type
);
134 phdrs
[i
].p_offset
= BYTE_GET (phdrs64
[i
].p_offset
);
135 phdrs
[i
].p_vaddr
= BYTE_GET (phdrs64
[i
].p_vaddr
);
136 phdrs
[i
].p_paddr
= BYTE_GET (phdrs64
[i
].p_paddr
);
137 phdrs
[i
].p_filesz
= BYTE_GET (phdrs64
[i
].p_filesz
);
138 phdrs
[i
].p_memsz
= BYTE_GET (phdrs64
[i
].p_memsz
);
139 phdrs
[i
].p_flags
= BYTE_GET (phdrs64
[i
].p_flags
);
140 phdrs
[i
].p_align
= BYTE_GET (phdrs64
[i
].p_align
);
145 for (i
= 0; i
< elf_header
.e_phnum
; i
++)
146 if (phdrs
[i
].p_type
== PT_NOTE
)
148 size_t offset
= phdrs
[i
].p_offset
;
149 size_t size
= phdrs
[i
].p_filesz
;
150 size_t align
= phdrs
[i
].p_align
;
151 char *buf
= map
+ offset
;
154 while (p
< buf
+ size
)
156 Elf_External_Note
*xnp
= (Elf_External_Note
*) p
;
157 Elf_Internal_Note in
;
159 if (offsetof (Elf_External_Note
, name
) > buf
- p
+ size
)
165 in
.type
= BYTE_GET (xnp
->type
);
166 in
.namesz
= BYTE_GET (xnp
->namesz
);
167 in
.namedata
= xnp
->name
;
168 if (in
.namesz
> buf
- in
.namedata
+ size
)
174 in
.descsz
= BYTE_GET (xnp
->descsz
);
175 in
.descdata
= p
+ ELF_NOTE_DESC_OFFSET (in
.namesz
, align
);
176 in
.descpos
= offset
+ (in
.descdata
- buf
);
178 && (in
.descdata
>= buf
+ size
179 || in
.descsz
> buf
- in
.descdata
+ size
))
185 if (in
.namesz
== sizeof "GNU"
186 && strcmp (in
.namedata
, "GNU") == 0
187 && in
.type
== NT_GNU_PROPERTY_TYPE_0
)
190 unsigned char *ptr_end
;
192 if (in
.descsz
< 8 || (in
.descsz
% align
) != 0)
198 ptr
= (unsigned char *) in
.descdata
;
199 ptr_end
= ptr
+ in
.descsz
;
203 unsigned int type
= byte_get (ptr
, 4);
204 unsigned int datasz
= byte_get (ptr
+ 4, 4);
205 unsigned int bitmask
, old_bitmask
;
208 if ((ptr
+ datasz
) > ptr_end
)
214 if (type
== GNU_PROPERTY_X86_FEATURE_1_AND
)
222 old_bitmask
= byte_get (ptr
, 4);
223 bitmask
= old_bitmask
;
224 if (enable_x86_features
)
225 bitmask
|= enable_x86_features
;
226 if (disable_x86_features
)
227 bitmask
&= ~disable_x86_features
;
228 if (old_bitmask
!= bitmask
)
229 byte_put (ptr
, bitmask
, 4);
233 ptr
+= ELF_ALIGN_UP (datasz
, align
);
235 while ((ptr_end
- ptr
) >= 8);
238 p
+= ELF_NOTE_NEXT_OFFSET (in
.namesz
, in
.descsz
, align
);
244 error (_("%s: Invalid PT_NOTE segment\n"), file_name
);
247 munmap (map
, st_buf
.st_size
);
252 /* Set enable_x86_features and disable_x86_features for a feature
256 elf_x86_feature (const char *feature
, int enable
)
258 unsigned int x86_feature
;
259 if (strcasecmp (feature
, "ibt") == 0)
260 x86_feature
= GNU_PROPERTY_X86_FEATURE_1_IBT
;
261 else if (strcasecmp (feature
, "shstk") == 0)
262 x86_feature
= GNU_PROPERTY_X86_FEATURE_1_SHSTK
;
265 error (_("Unknown x86 feature: %s\n"), feature
);
271 enable_x86_features
|= x86_feature
;
272 disable_x86_features
&= ~x86_feature
;
276 disable_x86_features
|= x86_feature
;
277 enable_x86_features
&= ~x86_feature
;
284 /* Return ELF class for a machine type, MACH. */
300 return ELF_CLASS_BOTH
;
302 return ELF_CLASS_BOTH
;
307 update_elf_header (const char *file_name
, FILE *file
)
309 int class, machine
, type
, status
, osabi
;
311 if (elf_header
.e_ident
[EI_VERSION
] != EV_CURRENT
)
314 (_("%s: Unsupported EI_VERSION: %d is not %d\n"),
315 file_name
, elf_header
.e_ident
[EI_VERSION
],
320 /* Return if e_machine is the same as output_elf_machine. */
321 if (output_elf_machine
== elf_header
.e_machine
)
324 class = elf_header
.e_ident
[EI_CLASS
];
325 machine
= elf_header
.e_machine
;
327 /* Skip if class doesn't match. */
328 if (input_elf_class
== ELF_CLASS_UNKNOWN
)
329 input_elf_class
= elf_class (machine
);
331 if (input_elf_class
!= ELF_CLASS_BOTH
332 && (int) input_elf_class
!= class)
335 (_("%s: Unmatched input EI_CLASS: %d is not %d\n"),
336 file_name
, class, input_elf_class
);
340 if (output_elf_class
!= ELF_CLASS_BOTH
341 && (int) output_elf_class
!= class)
344 (_("%s: Unmatched output EI_CLASS: %d is not %d\n"),
345 file_name
, class, output_elf_class
);
349 /* Skip if e_machine doesn't match. */
350 if (input_elf_machine
!= -1 && machine
!= input_elf_machine
)
353 (_("%s: Unmatched e_machine: %d is not %d\n"),
354 file_name
, machine
, input_elf_machine
);
358 type
= elf_header
.e_type
;
360 /* Skip if e_type doesn't match. */
361 if (input_elf_type
!= -1 && type
!= input_elf_type
)
364 (_("%s: Unmatched e_type: %d is not %d\n"),
365 file_name
, type
, input_elf_type
);
369 osabi
= elf_header
.e_ident
[EI_OSABI
];
371 /* Skip if OSABI doesn't match. */
372 if (input_elf_osabi
!= -1 && osabi
!= input_elf_osabi
)
375 (_("%s: Unmatched EI_OSABI: %d is not %d\n"),
376 file_name
, osabi
, input_elf_osabi
);
380 /* Update e_machine, e_type and EI_OSABI. */
384 /* We should never get here. */
388 if (output_elf_machine
!= -1)
389 BYTE_PUT (ehdr32
.e_machine
, output_elf_machine
);
390 if (output_elf_type
!= -1)
391 BYTE_PUT (ehdr32
.e_type
, output_elf_type
);
392 if (output_elf_osabi
!= -1)
393 ehdr32
.e_ident
[EI_OSABI
] = output_elf_osabi
;
394 status
= fwrite (&ehdr32
, sizeof (ehdr32
), 1, file
) == 1;
397 if (output_elf_machine
!= -1)
398 BYTE_PUT (ehdr64
.e_machine
, output_elf_machine
);
399 if (output_elf_type
!= -1)
400 BYTE_PUT (ehdr64
.e_type
, output_elf_type
);
401 if (output_elf_osabi
!= -1)
402 ehdr64
.e_ident
[EI_OSABI
] = output_elf_osabi
;
403 status
= fwrite (&ehdr64
, sizeof (ehdr64
), 1, file
) == 1;
408 error (_("%s: Failed to update ELF header: %s\n"),
409 file_name
, strerror (errno
));
415 get_file_header (FILE * file
)
417 /* Read in the identity array. */
418 if (fread (elf_header
.e_ident
, EI_NIDENT
, 1, file
) != 1)
421 if (elf_header
.e_ident
[EI_MAG0
] != ELFMAG0
422 || elf_header
.e_ident
[EI_MAG1
] != ELFMAG1
423 || elf_header
.e_ident
[EI_MAG2
] != ELFMAG2
424 || elf_header
.e_ident
[EI_MAG3
] != ELFMAG3
)
427 /* Determine how to read the rest of the header. */
428 switch (elf_header
.e_ident
[EI_DATA
])
430 default: /* fall through */
431 case ELFDATANONE
: /* fall through */
433 byte_get
= byte_get_little_endian
;
434 byte_put
= byte_put_little_endian
;
437 byte_get
= byte_get_big_endian
;
438 byte_put
= byte_put_big_endian
;
442 /* Read in the rest of the header. For now we only support 32 bit
443 and 64 bit ELF files. */
444 switch (elf_header
.e_ident
[EI_CLASS
])
450 if (fread (ehdr32
.e_type
, sizeof (ehdr32
) - EI_NIDENT
,
454 elf_header
.e_type
= BYTE_GET (ehdr32
.e_type
);
455 elf_header
.e_machine
= BYTE_GET (ehdr32
.e_machine
);
456 elf_header
.e_version
= BYTE_GET (ehdr32
.e_version
);
457 elf_header
.e_entry
= BYTE_GET (ehdr32
.e_entry
);
458 elf_header
.e_phoff
= BYTE_GET (ehdr32
.e_phoff
);
459 elf_header
.e_shoff
= BYTE_GET (ehdr32
.e_shoff
);
460 elf_header
.e_flags
= BYTE_GET (ehdr32
.e_flags
);
461 elf_header
.e_ehsize
= BYTE_GET (ehdr32
.e_ehsize
);
462 elf_header
.e_phentsize
= BYTE_GET (ehdr32
.e_phentsize
);
463 elf_header
.e_phnum
= BYTE_GET (ehdr32
.e_phnum
);
464 elf_header
.e_shentsize
= BYTE_GET (ehdr32
.e_shentsize
);
465 elf_header
.e_shnum
= BYTE_GET (ehdr32
.e_shnum
);
466 elf_header
.e_shstrndx
= BYTE_GET (ehdr32
.e_shstrndx
);
468 memcpy (&ehdr32
, &elf_header
, EI_NIDENT
);
472 /* If we have been compiled with sizeof (bfd_vma) == 4, then
473 we will not be able to cope with the 64bit data found in
474 64 ELF files. Detect this now and abort before we start
475 overwriting things. */
476 if (sizeof (bfd_vma
) < 8)
478 error (_("This executable has been built without support for a\n\
479 64 bit data type and so it cannot process 64 bit ELF files.\n"));
483 if (fread (ehdr64
.e_type
, sizeof (ehdr64
) - EI_NIDENT
,
487 elf_header
.e_type
= BYTE_GET (ehdr64
.e_type
);
488 elf_header
.e_machine
= BYTE_GET (ehdr64
.e_machine
);
489 elf_header
.e_version
= BYTE_GET (ehdr64
.e_version
);
490 elf_header
.e_entry
= BYTE_GET (ehdr64
.e_entry
);
491 elf_header
.e_phoff
= BYTE_GET (ehdr64
.e_phoff
);
492 elf_header
.e_shoff
= BYTE_GET (ehdr64
.e_shoff
);
493 elf_header
.e_flags
= BYTE_GET (ehdr64
.e_flags
);
494 elf_header
.e_ehsize
= BYTE_GET (ehdr64
.e_ehsize
);
495 elf_header
.e_phentsize
= BYTE_GET (ehdr64
.e_phentsize
);
496 elf_header
.e_phnum
= BYTE_GET (ehdr64
.e_phnum
);
497 elf_header
.e_shentsize
= BYTE_GET (ehdr64
.e_shentsize
);
498 elf_header
.e_shnum
= BYTE_GET (ehdr64
.e_shnum
);
499 elf_header
.e_shstrndx
= BYTE_GET (ehdr64
.e_shstrndx
);
501 memcpy (&ehdr64
, &elf_header
, EI_NIDENT
);
507 /* Process one ELF object file according to the command line options.
508 This file may actually be stored in an archive. The file is
509 positioned at the start of the ELF object. */
512 process_object (const char *file_name
, FILE *file
)
514 /* Rememeber where we are. */
515 long offset
= ftell (file
);
517 if (! get_file_header (file
))
519 error (_("%s: Failed to read ELF header\n"), file_name
);
523 /* Go to the position of the ELF header. */
524 if (fseek (file
, offset
, SEEK_SET
) != 0)
526 error (_("%s: Failed to seek to ELF header\n"), file_name
);
529 if (! update_elf_header (file_name
, file
))
535 /* Process an ELF archive.
536 On entry the file is positioned just after the ARMAG string. */
539 process_archive (const char * file_name
, FILE * file
,
540 bfd_boolean is_thin_archive
)
542 struct archive_info arch
;
543 struct archive_info nested_arch
;
547 /* The ARCH structure is used to hold information about this archive. */
548 arch
.file_name
= NULL
;
550 arch
.index_array
= NULL
;
551 arch
.sym_table
= NULL
;
552 arch
.longnames
= NULL
;
554 /* The NESTED_ARCH structure is used as a single-item cache of information
555 about a nested archive (when members of a thin archive reside within
556 another regular archive file). */
557 nested_arch
.file_name
= NULL
;
558 nested_arch
.file
= NULL
;
559 nested_arch
.index_array
= NULL
;
560 nested_arch
.sym_table
= NULL
;
561 nested_arch
.longnames
= NULL
;
563 if (setup_archive (&arch
, file_name
, file
, is_thin_archive
, FALSE
) != 0)
575 char * qualified_name
;
577 /* Read the next archive header. */
578 if (fseek (file
, arch
.next_arhdr_offset
, SEEK_SET
) != 0)
580 error (_("%s: failed to seek to next archive header\n"),
584 got
= fread (&arch
.arhdr
, 1, sizeof arch
.arhdr
, file
);
585 if (got
!= sizeof arch
.arhdr
)
589 error (_("%s: failed to read archive header\n"),
594 if (memcmp (arch
.arhdr
.ar_fmag
, ARFMAG
, 2) != 0)
596 error (_("%s: did not find a valid archive header\n"),
602 arch
.next_arhdr_offset
+= sizeof arch
.arhdr
;
604 archive_file_size
= strtoul (arch
.arhdr
.ar_size
, NULL
, 10);
605 if (archive_file_size
& 01)
608 name
= get_archive_member_name (&arch
, &nested_arch
);
611 error (_("%s: bad archive file name\n"), file_name
);
615 namelen
= strlen (name
);
617 qualified_name
= make_qualified_name (&arch
, &nested_arch
, name
);
618 if (qualified_name
== NULL
)
620 error (_("%s: bad archive file name\n"), file_name
);
625 if (is_thin_archive
&& arch
.nested_member_origin
== 0)
627 /* This is a proxy for an external member of a thin archive. */
629 char *member_file_name
= adjust_relative_path (file_name
,
631 if (member_file_name
== NULL
)
637 member_file
= fopen (member_file_name
, "r+b");
638 if (member_file
== NULL
)
640 error (_("Input file '%s' is not readable\n"),
642 free (member_file_name
);
647 archive_file_offset
= arch
.nested_member_origin
;
649 ret
|= process_object (qualified_name
, member_file
);
651 fclose (member_file
);
652 free (member_file_name
);
654 else if (is_thin_archive
)
656 /* This is a proxy for a member of a nested archive. */
657 archive_file_offset
= arch
.nested_member_origin
+ sizeof arch
.arhdr
;
659 /* The nested archive file will have been opened and setup by
660 get_archive_member_name. */
661 if (fseek (nested_arch
.file
, archive_file_offset
,
664 error (_("%s: failed to seek to archive member\n"),
665 nested_arch
.file_name
);
670 ret
|= process_object (qualified_name
, nested_arch
.file
);
674 archive_file_offset
= arch
.next_arhdr_offset
;
675 arch
.next_arhdr_offset
+= archive_file_size
;
677 ret
|= process_object (qualified_name
, file
);
680 free (qualified_name
);
684 if (nested_arch
.file
!= NULL
)
685 fclose (nested_arch
.file
);
686 release_archive (&nested_arch
);
687 release_archive (&arch
);
693 check_file (const char *file_name
, struct stat
*statbuf_p
)
697 if (statbuf_p
== NULL
)
698 statbuf_p
= &statbuf
;
700 if (stat (file_name
, statbuf_p
) < 0)
703 error (_("'%s': No such file\n"), file_name
);
705 error (_("Could not locate '%s'. System error message: %s\n"),
706 file_name
, strerror (errno
));
710 if (! S_ISREG (statbuf_p
->st_mode
))
712 error (_("'%s' is not an ordinary file\n"), file_name
);
720 process_file (const char *file_name
)
726 if (check_file (file_name
, NULL
))
729 file
= fopen (file_name
, "r+b");
732 error (_("Input file '%s' is not readable\n"), file_name
);
736 if (fread (armag
, SARMAG
, 1, file
) != 1)
738 error (_("%s: Failed to read file's magic number\n"),
744 if (memcmp (armag
, ARMAG
, SARMAG
) == 0)
745 ret
= process_archive (file_name
, file
, FALSE
);
746 else if (memcmp (armag
, ARMAGT
, SARMAG
) == 0)
747 ret
= process_archive (file_name
, file
, TRUE
);
751 archive_file_size
= archive_file_offset
= 0;
752 ret
= process_object (file_name
, file
);
755 && (elf_header
.e_type
== ET_EXEC
756 || elf_header
.e_type
== ET_DYN
))
757 ret
= update_gnu_property (file_name
, file
);
773 { ELFOSABI_NONE
, "none" },
774 { ELFOSABI_HPUX
, "HPUX" },
775 { ELFOSABI_NETBSD
, "NetBSD" },
776 { ELFOSABI_GNU
, "GNU" },
777 { ELFOSABI_GNU
, "Linux" },
778 { ELFOSABI_SOLARIS
, "Solaris" },
779 { ELFOSABI_AIX
, "AIX" },
780 { ELFOSABI_IRIX
, "Irix" },
781 { ELFOSABI_FREEBSD
, "FreeBSD" },
782 { ELFOSABI_TRU64
, "TRU64" },
783 { ELFOSABI_MODESTO
, "Modesto" },
784 { ELFOSABI_OPENBSD
, "OpenBSD" },
785 { ELFOSABI_OPENVMS
, "OpenVMS" },
786 { ELFOSABI_NSK
, "NSK" },
787 { ELFOSABI_AROS
, "AROS" },
788 { ELFOSABI_FENIXOS
, "FenixOS" }
791 /* Return ELFOSABI_XXX for an OSABI string, OSABI. */
794 elf_osabi (const char *osabi
)
798 for (i
= 0; i
< ARRAY_SIZE (osabis
); i
++)
799 if (strcasecmp (osabi
, osabis
[i
].name
) == 0)
800 return osabis
[i
].osabi
;
802 error (_("Unknown OSABI: %s\n"), osabi
);
807 /* Return EM_XXX for a machine string, MACH. */
810 elf_machine (const char *mach
)
812 if (strcasecmp (mach
, "i386") == 0)
814 if (strcasecmp (mach
, "iamcu") == 0)
816 if (strcasecmp (mach
, "l1om") == 0)
818 if (strcasecmp (mach
, "k1om") == 0)
820 if (strcasecmp (mach
, "x86_64") == 0)
822 if (strcasecmp (mach
, "x86-64") == 0)
824 if (strcasecmp (mach
, "amdgcn") == 0)
826 if (strcasecmp (mach
, "none") == 0)
829 error (_("Unknown machine type: %s\n"), mach
);
834 /* Return ET_XXX for a type string, TYPE. */
837 elf_type (const char *type
)
839 if (strcasecmp (type
, "rel") == 0)
841 if (strcasecmp (type
, "exec") == 0)
843 if (strcasecmp (type
, "dyn") == 0)
845 if (strcasecmp (type
, "none") == 0)
848 error (_("Unknown type: %s\n"), type
);
853 enum command_line_switch
855 OPTION_INPUT_MACH
= 150,
862 OPTION_ENABLE_X86_FEATURE
,
863 OPTION_DISABLE_X86_FEATURE
,
867 static struct option options
[] =
869 {"input-mach", required_argument
, 0, OPTION_INPUT_MACH
},
870 {"output-mach", required_argument
, 0, OPTION_OUTPUT_MACH
},
871 {"input-type", required_argument
, 0, OPTION_INPUT_TYPE
},
872 {"output-type", required_argument
, 0, OPTION_OUTPUT_TYPE
},
873 {"input-osabi", required_argument
, 0, OPTION_INPUT_OSABI
},
874 {"output-osabi", required_argument
, 0, OPTION_OUTPUT_OSABI
},
876 {"enable-x86-feature",
877 required_argument
, 0, OPTION_ENABLE_X86_FEATURE
},
878 {"disable-x86-feature",
879 required_argument
, 0, OPTION_DISABLE_X86_FEATURE
},
881 {"version", no_argument
, 0, 'v'},
882 {"help", no_argument
, 0, 'h'},
883 {0, no_argument
, 0, 0}
886 ATTRIBUTE_NORETURN
static void
887 usage (FILE *stream
, int exit_status
)
889 fprintf (stream
, _("Usage: %s <option(s)> elffile(s)\n"),
891 fprintf (stream
, _(" Update the ELF header of ELF files\n"));
892 fprintf (stream
, _(" The options are:\n"));
893 fprintf (stream
, _("\
894 --input-mach <machine> Set input machine type to <machine>\n\
895 --output-mach <machine> Set output machine type to <machine>\n\
896 --input-type <type> Set input file type to <type>\n\
897 --output-type <type> Set output file type to <type>\n\
898 --input-osabi <osabi> Set input OSABI to <osabi>\n\
899 --output-osabi <osabi> Set output OSABI to <osabi>\n"));
901 fprintf (stream
, _("\
902 --enable-x86-feature <feature>\n\
903 Enable x86 feature <feature>\n\
904 --disable-x86-feature <feature>\n\
905 Disable x86 feature <feature>\n"));
907 fprintf (stream
, _("\
908 -h --help Display this information\n\
909 -v --version Display the version number of %s\n\
912 if (REPORT_BUGS_TO
[0] && exit_status
== 0)
913 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);
918 main (int argc
, char ** argv
)
922 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
923 setlocale (LC_MESSAGES
, "");
925 #if defined (HAVE_SETLOCALE)
926 setlocale (LC_CTYPE
, "");
928 bindtextdomain (PACKAGE
, LOCALEDIR
);
929 textdomain (PACKAGE
);
931 expandargv (&argc
, &argv
);
933 while ((c
= getopt_long (argc
, argv
, "hv",
934 options
, (int *) 0)) != EOF
)
938 case OPTION_INPUT_MACH
:
939 input_elf_machine
= elf_machine (optarg
);
940 if (input_elf_machine
< 0)
942 input_elf_class
= elf_class (input_elf_machine
);
943 if (input_elf_class
== ELF_CLASS_UNKNOWN
)
947 case OPTION_OUTPUT_MACH
:
948 output_elf_machine
= elf_machine (optarg
);
949 if (output_elf_machine
< 0)
951 output_elf_class
= elf_class (output_elf_machine
);
952 if (output_elf_class
== ELF_CLASS_UNKNOWN
)
956 case OPTION_INPUT_TYPE
:
957 input_elf_type
= elf_type (optarg
);
958 if (input_elf_type
< 0)
962 case OPTION_OUTPUT_TYPE
:
963 output_elf_type
= elf_type (optarg
);
964 if (output_elf_type
< 0)
968 case OPTION_INPUT_OSABI
:
969 input_elf_osabi
= elf_osabi (optarg
);
970 if (input_elf_osabi
< 0)
974 case OPTION_OUTPUT_OSABI
:
975 output_elf_osabi
= elf_osabi (optarg
);
976 if (output_elf_osabi
< 0)
981 case OPTION_ENABLE_X86_FEATURE
:
982 if (elf_x86_feature (optarg
, 1) < 0)
986 case OPTION_DISABLE_X86_FEATURE
:
987 if (elf_x86_feature (optarg
, 0) < 0)
996 print_version (program_name
);
1005 || (output_elf_machine
== -1
1007 && ! enable_x86_features
1008 && ! disable_x86_features
1010 && output_elf_type
== -1
1011 && output_elf_osabi
== -1))
1015 while (optind
< argc
)
1016 status
|= process_file (argv
[optind
++]);