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
23 #include "libiberty.h"
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. */
299 return ELF_CLASS_BOTH
;
301 return ELF_CLASS_BOTH
;
306 update_elf_header (const char *file_name
, FILE *file
)
308 int class, machine
, type
, status
, osabi
;
310 if (elf_header
.e_ident
[EI_VERSION
] != EV_CURRENT
)
313 (_("%s: Unsupported EI_VERSION: %d is not %d\n"),
314 file_name
, elf_header
.e_ident
[EI_VERSION
],
319 /* Return if e_machine is the same as output_elf_machine. */
320 if (output_elf_machine
== elf_header
.e_machine
)
323 class = elf_header
.e_ident
[EI_CLASS
];
324 machine
= elf_header
.e_machine
;
326 /* Skip if class doesn't match. */
327 if (input_elf_class
== ELF_CLASS_UNKNOWN
)
328 input_elf_class
= elf_class (machine
);
330 if (input_elf_class
!= ELF_CLASS_BOTH
331 && (int) input_elf_class
!= class)
334 (_("%s: Unmatched input EI_CLASS: %d is not %d\n"),
335 file_name
, class, input_elf_class
);
339 if (output_elf_class
!= ELF_CLASS_BOTH
340 && (int) output_elf_class
!= class)
343 (_("%s: Unmatched output EI_CLASS: %d is not %d\n"),
344 file_name
, class, output_elf_class
);
348 /* Skip if e_machine doesn't match. */
349 if (input_elf_machine
!= -1 && machine
!= input_elf_machine
)
352 (_("%s: Unmatched e_machine: %d is not %d\n"),
353 file_name
, machine
, input_elf_machine
);
357 type
= elf_header
.e_type
;
359 /* Skip if e_type doesn't match. */
360 if (input_elf_type
!= -1 && type
!= input_elf_type
)
363 (_("%s: Unmatched e_type: %d is not %d\n"),
364 file_name
, type
, input_elf_type
);
368 osabi
= elf_header
.e_ident
[EI_OSABI
];
370 /* Skip if OSABI doesn't match. */
371 if (input_elf_osabi
!= -1 && osabi
!= input_elf_osabi
)
374 (_("%s: Unmatched EI_OSABI: %d is not %d\n"),
375 file_name
, osabi
, input_elf_osabi
);
379 /* Update e_machine, e_type and EI_OSABI. */
383 /* We should never get here. */
387 if (output_elf_machine
!= -1)
388 BYTE_PUT (ehdr32
.e_machine
, output_elf_machine
);
389 if (output_elf_type
!= -1)
390 BYTE_PUT (ehdr32
.e_type
, output_elf_type
);
391 if (output_elf_osabi
!= -1)
392 ehdr32
.e_ident
[EI_OSABI
] = output_elf_osabi
;
393 status
= fwrite (&ehdr32
, sizeof (ehdr32
), 1, file
) == 1;
396 if (output_elf_machine
!= -1)
397 BYTE_PUT (ehdr64
.e_machine
, output_elf_machine
);
398 if (output_elf_type
!= -1)
399 BYTE_PUT (ehdr64
.e_type
, output_elf_type
);
400 if (output_elf_osabi
!= -1)
401 ehdr64
.e_ident
[EI_OSABI
] = output_elf_osabi
;
402 status
= fwrite (&ehdr64
, sizeof (ehdr64
), 1, file
) == 1;
407 error (_("%s: Failed to update ELF header: %s\n"),
408 file_name
, strerror (errno
));
414 get_file_header (FILE * file
)
416 /* Read in the identity array. */
417 if (fread (elf_header
.e_ident
, EI_NIDENT
, 1, file
) != 1)
420 if (elf_header
.e_ident
[EI_MAG0
] != ELFMAG0
421 || elf_header
.e_ident
[EI_MAG1
] != ELFMAG1
422 || elf_header
.e_ident
[EI_MAG2
] != ELFMAG2
423 || elf_header
.e_ident
[EI_MAG3
] != ELFMAG3
)
426 /* Determine how to read the rest of the header. */
427 switch (elf_header
.e_ident
[EI_DATA
])
429 default: /* fall through */
430 case ELFDATANONE
: /* fall through */
432 byte_get
= byte_get_little_endian
;
433 byte_put
= byte_put_little_endian
;
436 byte_get
= byte_get_big_endian
;
437 byte_put
= byte_put_big_endian
;
441 /* Read in the rest of the header. For now we only support 32 bit
442 and 64 bit ELF files. */
443 switch (elf_header
.e_ident
[EI_CLASS
])
449 if (fread (ehdr32
.e_type
, sizeof (ehdr32
) - EI_NIDENT
,
453 elf_header
.e_type
= BYTE_GET (ehdr32
.e_type
);
454 elf_header
.e_machine
= BYTE_GET (ehdr32
.e_machine
);
455 elf_header
.e_version
= BYTE_GET (ehdr32
.e_version
);
456 elf_header
.e_entry
= BYTE_GET (ehdr32
.e_entry
);
457 elf_header
.e_phoff
= BYTE_GET (ehdr32
.e_phoff
);
458 elf_header
.e_shoff
= BYTE_GET (ehdr32
.e_shoff
);
459 elf_header
.e_flags
= BYTE_GET (ehdr32
.e_flags
);
460 elf_header
.e_ehsize
= BYTE_GET (ehdr32
.e_ehsize
);
461 elf_header
.e_phentsize
= BYTE_GET (ehdr32
.e_phentsize
);
462 elf_header
.e_phnum
= BYTE_GET (ehdr32
.e_phnum
);
463 elf_header
.e_shentsize
= BYTE_GET (ehdr32
.e_shentsize
);
464 elf_header
.e_shnum
= BYTE_GET (ehdr32
.e_shnum
);
465 elf_header
.e_shstrndx
= BYTE_GET (ehdr32
.e_shstrndx
);
467 memcpy (&ehdr32
, &elf_header
, EI_NIDENT
);
471 /* If we have been compiled with sizeof (bfd_vma) == 4, then
472 we will not be able to cope with the 64bit data found in
473 64 ELF files. Detect this now and abort before we start
474 overwriting things. */
475 if (sizeof (bfd_vma
) < 8)
477 error (_("This executable has been built without support for a\n\
478 64 bit data type and so it cannot process 64 bit ELF files.\n"));
482 if (fread (ehdr64
.e_type
, sizeof (ehdr64
) - EI_NIDENT
,
486 elf_header
.e_type
= BYTE_GET (ehdr64
.e_type
);
487 elf_header
.e_machine
= BYTE_GET (ehdr64
.e_machine
);
488 elf_header
.e_version
= BYTE_GET (ehdr64
.e_version
);
489 elf_header
.e_entry
= BYTE_GET (ehdr64
.e_entry
);
490 elf_header
.e_phoff
= BYTE_GET (ehdr64
.e_phoff
);
491 elf_header
.e_shoff
= BYTE_GET (ehdr64
.e_shoff
);
492 elf_header
.e_flags
= BYTE_GET (ehdr64
.e_flags
);
493 elf_header
.e_ehsize
= BYTE_GET (ehdr64
.e_ehsize
);
494 elf_header
.e_phentsize
= BYTE_GET (ehdr64
.e_phentsize
);
495 elf_header
.e_phnum
= BYTE_GET (ehdr64
.e_phnum
);
496 elf_header
.e_shentsize
= BYTE_GET (ehdr64
.e_shentsize
);
497 elf_header
.e_shnum
= BYTE_GET (ehdr64
.e_shnum
);
498 elf_header
.e_shstrndx
= BYTE_GET (ehdr64
.e_shstrndx
);
500 memcpy (&ehdr64
, &elf_header
, EI_NIDENT
);
506 /* Process one ELF object file according to the command line options.
507 This file may actually be stored in an archive. The file is
508 positioned at the start of the ELF object. */
511 process_object (const char *file_name
, FILE *file
)
513 /* Rememeber where we are. */
514 long offset
= ftell (file
);
516 if (! get_file_header (file
))
518 error (_("%s: Failed to read ELF header\n"), file_name
);
522 /* Go to the position of the ELF header. */
523 if (fseek (file
, offset
, SEEK_SET
) != 0)
525 error (_("%s: Failed to seek to ELF header\n"), file_name
);
528 if (! update_elf_header (file_name
, file
))
534 /* Process an ELF archive.
535 On entry the file is positioned just after the ARMAG string. */
538 process_archive (const char * file_name
, FILE * file
,
539 bfd_boolean is_thin_archive
)
541 struct archive_info arch
;
542 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 (fstat (fileno (file
), &statbuf
) < 0
564 || setup_archive (&arch
, file_name
, file
, statbuf
.st_size
,
565 is_thin_archive
, FALSE
) != 0)
577 char * qualified_name
;
579 /* Read the next archive header. */
580 if (fseek (file
, arch
.next_arhdr_offset
, SEEK_SET
) != 0)
582 error (_("%s: failed to seek to next archive header\n"),
586 got
= fread (&arch
.arhdr
, 1, sizeof arch
.arhdr
, file
);
587 if (got
!= sizeof arch
.arhdr
)
591 error (_("%s: failed to read archive header\n"),
596 if (memcmp (arch
.arhdr
.ar_fmag
, ARFMAG
, 2) != 0)
598 error (_("%s: did not find a valid archive header\n"),
604 arch
.next_arhdr_offset
+= sizeof arch
.arhdr
;
606 archive_file_size
= strtoul (arch
.arhdr
.ar_size
, NULL
, 10);
607 if (archive_file_size
& 01)
610 name
= get_archive_member_name (&arch
, &nested_arch
);
613 error (_("%s: bad archive file name\n"), file_name
);
617 namelen
= strlen (name
);
619 qualified_name
= make_qualified_name (&arch
, &nested_arch
, name
);
620 if (qualified_name
== NULL
)
622 error (_("%s: bad archive file name\n"), file_name
);
628 if (is_thin_archive
&& arch
.nested_member_origin
== 0)
630 /* This is a proxy for an external member of a thin archive. */
632 char *member_file_name
= adjust_relative_path (file_name
,
635 if (member_file_name
== NULL
)
637 free (qualified_name
);
642 member_file
= fopen (member_file_name
, "r+b");
643 if (member_file
== NULL
)
645 error (_("Input file '%s' is not readable\n"),
647 free (member_file_name
);
648 free (qualified_name
);
653 archive_file_offset
= arch
.nested_member_origin
;
655 ret
|= process_object (qualified_name
, member_file
);
657 fclose (member_file
);
658 free (member_file_name
);
660 else if (is_thin_archive
)
664 /* This is a proxy for a member of a nested archive. */
665 archive_file_offset
= arch
.nested_member_origin
+ sizeof arch
.arhdr
;
667 /* The nested archive file will have been opened and setup by
668 get_archive_member_name. */
669 if (fseek (nested_arch
.file
, archive_file_offset
,
672 error (_("%s: failed to seek to archive member\n"),
673 nested_arch
.file_name
);
674 free (qualified_name
);
679 ret
|= process_object (qualified_name
, nested_arch
.file
);
684 archive_file_offset
= arch
.next_arhdr_offset
;
685 arch
.next_arhdr_offset
+= archive_file_size
;
687 ret
|= process_object (qualified_name
, file
);
690 free (qualified_name
);
694 if (nested_arch
.file
!= NULL
)
695 fclose (nested_arch
.file
);
696 release_archive (&nested_arch
);
697 release_archive (&arch
);
703 check_file (const char *file_name
, struct stat
*statbuf_p
)
707 if (statbuf_p
== NULL
)
708 statbuf_p
= &statbuf
;
710 if (stat (file_name
, statbuf_p
) < 0)
713 error (_("'%s': No such file\n"), file_name
);
715 error (_("Could not locate '%s'. System error message: %s\n"),
716 file_name
, strerror (errno
));
720 if (! S_ISREG (statbuf_p
->st_mode
))
722 error (_("'%s' is not an ordinary file\n"), file_name
);
730 process_file (const char *file_name
)
736 if (check_file (file_name
, NULL
))
739 file
= fopen (file_name
, "r+b");
742 error (_("Input file '%s' is not readable\n"), file_name
);
746 if (fread (armag
, SARMAG
, 1, file
) != 1)
748 error (_("%s: Failed to read file's magic number\n"),
754 if (memcmp (armag
, ARMAG
, SARMAG
) == 0)
755 ret
= process_archive (file_name
, file
, FALSE
);
756 else if (memcmp (armag
, ARMAGT
, SARMAG
) == 0)
757 ret
= process_archive (file_name
, file
, TRUE
);
761 archive_file_size
= archive_file_offset
= 0;
762 ret
= process_object (file_name
, file
);
765 && (elf_header
.e_type
== ET_EXEC
766 || elf_header
.e_type
== ET_DYN
))
767 ret
= update_gnu_property (file_name
, file
);
783 { ELFOSABI_NONE
, "none" },
784 { ELFOSABI_HPUX
, "HPUX" },
785 { ELFOSABI_NETBSD
, "NetBSD" },
786 { ELFOSABI_GNU
, "GNU" },
787 { ELFOSABI_GNU
, "Linux" },
788 { ELFOSABI_SOLARIS
, "Solaris" },
789 { ELFOSABI_AIX
, "AIX" },
790 { ELFOSABI_IRIX
, "Irix" },
791 { ELFOSABI_FREEBSD
, "FreeBSD" },
792 { ELFOSABI_TRU64
, "TRU64" },
793 { ELFOSABI_MODESTO
, "Modesto" },
794 { ELFOSABI_OPENBSD
, "OpenBSD" },
795 { ELFOSABI_OPENVMS
, "OpenVMS" },
796 { ELFOSABI_NSK
, "NSK" },
797 { ELFOSABI_AROS
, "AROS" },
798 { ELFOSABI_FENIXOS
, "FenixOS" }
801 /* Return ELFOSABI_XXX for an OSABI string, OSABI. */
804 elf_osabi (const char *osabi
)
808 for (i
= 0; i
< ARRAY_SIZE (osabis
); i
++)
809 if (strcasecmp (osabi
, osabis
[i
].name
) == 0)
810 return osabis
[i
].osabi
;
812 error (_("Unknown OSABI: %s\n"), osabi
);
817 /* Return EM_XXX for a machine string, MACH. */
820 elf_machine (const char *mach
)
822 if (strcasecmp (mach
, "i386") == 0)
824 if (strcasecmp (mach
, "iamcu") == 0)
826 if (strcasecmp (mach
, "l1om") == 0)
828 if (strcasecmp (mach
, "k1om") == 0)
830 if (strcasecmp (mach
, "x86_64") == 0)
832 if (strcasecmp (mach
, "x86-64") == 0)
834 if (strcasecmp (mach
, "none") == 0)
837 error (_("Unknown machine type: %s\n"), mach
);
842 /* Return ET_XXX for a type string, TYPE. */
845 elf_type (const char *type
)
847 if (strcasecmp (type
, "rel") == 0)
849 if (strcasecmp (type
, "exec") == 0)
851 if (strcasecmp (type
, "dyn") == 0)
853 if (strcasecmp (type
, "none") == 0)
856 error (_("Unknown type: %s\n"), type
);
861 enum command_line_switch
863 OPTION_INPUT_MACH
= 150,
870 OPTION_ENABLE_X86_FEATURE
,
871 OPTION_DISABLE_X86_FEATURE
,
875 static struct option options
[] =
877 {"input-mach", required_argument
, 0, OPTION_INPUT_MACH
},
878 {"output-mach", required_argument
, 0, OPTION_OUTPUT_MACH
},
879 {"input-type", required_argument
, 0, OPTION_INPUT_TYPE
},
880 {"output-type", required_argument
, 0, OPTION_OUTPUT_TYPE
},
881 {"input-osabi", required_argument
, 0, OPTION_INPUT_OSABI
},
882 {"output-osabi", required_argument
, 0, OPTION_OUTPUT_OSABI
},
884 {"enable-x86-feature",
885 required_argument
, 0, OPTION_ENABLE_X86_FEATURE
},
886 {"disable-x86-feature",
887 required_argument
, 0, OPTION_DISABLE_X86_FEATURE
},
889 {"version", no_argument
, 0, 'v'},
890 {"help", no_argument
, 0, 'h'},
891 {0, no_argument
, 0, 0}
894 ATTRIBUTE_NORETURN
static void
895 usage (FILE *stream
, int exit_status
)
898 char *osabi
= concat (osabis
[0].name
, NULL
);
900 for (i
= 1; i
< ARRAY_SIZE (osabis
); i
++)
901 osabi
= reconcat (osabi
, "|", osabis
[i
].name
, NULL
);
903 fprintf (stream
, _("Usage: %s <option(s)> elffile(s)\n"),
905 fprintf (stream
, _(" Update the ELF header of ELF files\n"));
906 fprintf (stream
, _(" The options are:\n"));
907 fprintf (stream
, _("\
908 --input-mach [none|i386|iamcu|l1om|k1om|x86_64]\n\
909 Set input machine type\n\
910 --output-mach [none|i386|iamcu|l1om|k1om|x86_64]\n\
911 Set output machine type\n\
912 --input-type [none|rel|exec|dyn]\n\
913 Set input file type\n\
914 --output-type [none|rel|exec|dyn]\n\
915 Set output file type\n\
916 --input-osabi [%s]\n\
918 --output-osabi [%s]\n\
919 Set output OSABI\n"),
922 fprintf (stream
, _("\
923 --enable-x86-feature [ibt|shstk]\n\
924 Enable x86 feature\n\
925 --disable-x86-feature [ibt|shstk]\n\
926 Disable x86 feature\n"));
928 fprintf (stream
, _("\
929 -h --help Display this information\n\
930 -v --version Display the version number of %s\n\
933 if (REPORT_BUGS_TO
[0] && exit_status
== 0)
934 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);
940 main (int argc
, char ** argv
)
944 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
945 setlocale (LC_MESSAGES
, "");
947 #if defined (HAVE_SETLOCALE)
948 setlocale (LC_CTYPE
, "");
950 bindtextdomain (PACKAGE
, LOCALEDIR
);
951 textdomain (PACKAGE
);
953 expandargv (&argc
, &argv
);
955 while ((c
= getopt_long (argc
, argv
, "hv",
956 options
, (int *) 0)) != EOF
)
960 case OPTION_INPUT_MACH
:
961 input_elf_machine
= elf_machine (optarg
);
962 if (input_elf_machine
< 0)
964 input_elf_class
= elf_class (input_elf_machine
);
965 if (input_elf_class
== ELF_CLASS_UNKNOWN
)
969 case OPTION_OUTPUT_MACH
:
970 output_elf_machine
= elf_machine (optarg
);
971 if (output_elf_machine
< 0)
973 output_elf_class
= elf_class (output_elf_machine
);
974 if (output_elf_class
== ELF_CLASS_UNKNOWN
)
978 case OPTION_INPUT_TYPE
:
979 input_elf_type
= elf_type (optarg
);
980 if (input_elf_type
< 0)
984 case OPTION_OUTPUT_TYPE
:
985 output_elf_type
= elf_type (optarg
);
986 if (output_elf_type
< 0)
990 case OPTION_INPUT_OSABI
:
991 input_elf_osabi
= elf_osabi (optarg
);
992 if (input_elf_osabi
< 0)
996 case OPTION_OUTPUT_OSABI
:
997 output_elf_osabi
= elf_osabi (optarg
);
998 if (output_elf_osabi
< 0)
1003 case OPTION_ENABLE_X86_FEATURE
:
1004 if (elf_x86_feature (optarg
, 1) < 0)
1008 case OPTION_DISABLE_X86_FEATURE
:
1009 if (elf_x86_feature (optarg
, 0) < 0)
1018 print_version (program_name
);
1027 || (output_elf_machine
== -1
1029 && ! enable_x86_features
1030 && ! disable_x86_features
1032 && output_elf_type
== -1
1033 && output_elf_osabi
== -1))
1037 while (optind
< argc
)
1038 status
|= process_file (argv
[optind
++]);