1 /* elfedit.c -- Update the ELF header of an ELF format file
2 Copyright (C) 2010-2015 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
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. */
36 #include "elf/common.h"
37 #include "elf/external.h"
38 #include "elf/internal.h"
41 #include "libiberty.h"
42 #include "safe-ctype.h"
43 #include "filenames.h"
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;
59 ELF_CLASS_UNKNOWN = -1,
60 ELF_CLASS_NONE = ELFCLASSNONE,
61 ELF_CLASS_32 = ELFCLASS32,
62 ELF_CLASS_64 = ELFCLASS64,
65 static enum elfclass input_elf_class = ELF_CLASS_UNKNOWN;
66 static enum elfclass output_elf_class = ELF_CLASS_BOTH;
68 /* Return ELF class for a machine type, MACH. */
83 return ELF_CLASS_BOTH;
85 error (_("Unknown machine type: %d\n"), mach);
86 return ELF_CLASS_UNKNOWN;
91 update_elf_header (const char *file_name, FILE *file)
93 int class, machine, type, status, osabi;
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)
101 (_("%s: Not an ELF file - wrong magic bytes at the start\n"),
106 if (elf_header.e_ident[EI_VERSION] != EV_CURRENT)
109 (_("%s: Unsupported EI_VERSION: %d is not %d\n"),
110 file_name, elf_header.e_ident[EI_VERSION],
115 /* Return if e_machine is the same as output_elf_machine. */
116 if (output_elf_machine == elf_header.e_machine)
119 class = elf_header.e_ident[EI_CLASS];
120 machine = elf_header.e_machine;
122 /* Skip if class doesn't match. */
123 if (input_elf_class == ELF_CLASS_UNKNOWN)
124 input_elf_class = elf_class (machine);
126 if (input_elf_class != ELF_CLASS_BOTH
127 && (int) input_elf_class != class)
130 (_("%s: Unmatched input EI_CLASS: %d is not %d\n"),
131 file_name, class, input_elf_class);
135 if (output_elf_class != ELF_CLASS_BOTH
136 && (int) output_elf_class != class)
139 (_("%s: Unmatched output EI_CLASS: %d is not %d\n"),
140 file_name, class, output_elf_class);
144 /* Skip if e_machine doesn't match. */
145 if (input_elf_machine != -1 && machine != input_elf_machine)
148 (_("%s: Unmatched e_machine: %d is not %d\n"),
149 file_name, machine, input_elf_machine);
153 type = elf_header.e_type;
155 /* Skip if e_type doesn't match. */
156 if (input_elf_type != -1 && type != input_elf_type)
159 (_("%s: Unmatched e_type: %d is not %d\n"),
160 file_name, type, input_elf_type);
164 osabi = elf_header.e_ident[EI_OSABI];
166 /* Skip if OSABI doesn't match. */
167 if (input_elf_osabi != -1 && osabi != input_elf_osabi)
170 (_("%s: Unmatched EI_OSABI: %d is not %d\n"),
171 file_name, osabi, input_elf_osabi);
175 /* Update e_machine, e_type and EI_OSABI. */
179 /* We should never get here. */
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;
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;
203 error (_("%s: Failed to update ELF header: %s\n"),
204 file_name, strerror (errno));
210 get_file_header (FILE * file)
212 /* Read in the identity array. */
213 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
216 /* Determine how to read the rest of the header. */
217 switch (elf_header.e_ident[EI_DATA])
219 default: /* fall through */
220 case ELFDATANONE: /* fall through */
222 byte_get = byte_get_little_endian;
223 byte_put = byte_put_little_endian;
226 byte_get = byte_get_big_endian;
227 byte_put = byte_put_big_endian;
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])
236 error (_("Unsupported EI_CLASS: %d\n"),
237 elf_header.e_ident[EI_CLASS]);
241 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT,
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);
259 memcpy (&ehdr32, &elf_header, EI_NIDENT);
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)
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"));
274 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT,
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);
292 memcpy (&ehdr64, &elf_header, EI_NIDENT);
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. */
303 process_object (const char *file_name, FILE *file)
305 /* Rememeber where we are. */
306 long offset = ftell (file);
308 if (! get_file_header (file))
310 error (_("%s: Failed to read ELF header\n"), file_name);
314 /* Go to the position of the ELF header. */
315 if (fseek (file, offset, SEEK_SET) != 0)
317 error (_("%s: Failed to seek to ELF header\n"), file_name);
320 if (! update_elf_header (file_name, file))
326 /* Process an ELF archive.
327 On entry the file is positioned just after the ARMAG string. */
330 process_archive (const char * file_name, FILE * file,
331 bfd_boolean is_thin_archive)
333 struct archive_info arch;
334 struct archive_info nested_arch;
338 /* The ARCH structure is used to hold information about this archive. */
339 arch.file_name = NULL;
341 arch.index_array = NULL;
342 arch.sym_table = NULL;
343 arch.longnames = NULL;
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;
354 if (setup_archive (&arch, file_name, file, is_thin_archive, FALSE) != 0)
366 char * qualified_name;
368 /* Read the next archive header. */
369 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
371 error (_("%s: failed to seek to next archive header\n"),
375 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
376 if (got != sizeof arch.arhdr)
380 error (_("%s: failed to read archive header\n"),
385 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
387 error (_("%s: did not find a valid archive header\n"),
393 arch.next_arhdr_offset += sizeof arch.arhdr;
395 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
396 if (archive_file_size & 01)
399 name = get_archive_member_name (&arch, &nested_arch);
402 error (_("%s: bad archive file name\n"), file_name);
406 namelen = strlen (name);
408 qualified_name = make_qualified_name (&arch, &nested_arch, name);
409 if (qualified_name == NULL)
411 error (_("%s: bad archive file name\n"), file_name);
416 if (is_thin_archive && arch.nested_member_origin == 0)
418 /* This is a proxy for an external member of a thin archive. */
420 char *member_file_name = adjust_relative_path (file_name,
422 if (member_file_name == NULL)
428 member_file = fopen (member_file_name, "r+b");
429 if (member_file == NULL)
431 error (_("Input file '%s' is not readable\n"),
433 free (member_file_name);
438 archive_file_offset = arch.nested_member_origin;
440 ret |= process_object (qualified_name, member_file);
442 fclose (member_file);
443 free (member_file_name);
445 else if (is_thin_archive)
447 /* This is a proxy for a member of a nested archive. */
448 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
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,
455 error (_("%s: failed to seek to archive member\n"),
456 nested_arch.file_name);
461 ret |= process_object (qualified_name, nested_arch.file);
465 archive_file_offset = arch.next_arhdr_offset;
466 arch.next_arhdr_offset += archive_file_size;
468 ret |= process_object (qualified_name, file);
471 free (qualified_name);
475 if (nested_arch.file != NULL)
476 fclose (nested_arch.file);
477 release_archive (&nested_arch);
478 release_archive (&arch);
484 check_file (const char *file_name, struct stat *statbuf_p)
488 if (statbuf_p == NULL)
489 statbuf_p = &statbuf;
491 if (stat (file_name, statbuf_p) < 0)
494 error (_("'%s': No such file\n"), file_name);
496 error (_("Could not locate '%s'. System error message: %s\n"),
497 file_name, strerror (errno));
501 if (! S_ISREG (statbuf_p->st_mode))
503 error (_("'%s' is not an ordinary file\n"), file_name);
511 process_file (const char *file_name)
517 if (check_file (file_name, NULL))
520 file = fopen (file_name, "r+b");
523 error (_("Input file '%s' is not readable\n"), file_name);
527 if (fread (armag, SARMAG, 1, file) != 1)
529 error (_("%s: Failed to read file's magic number\n"),
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);
542 archive_file_size = archive_file_offset = 0;
543 ret = process_object (file_name, file);
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" }
576 /* Return ELFOSABI_XXX for an OSABI string, OSABI. */
579 elf_osabi (const char *osabi)
583 for (i = 0; i < ARRAY_SIZE (osabis); i++)
584 if (strcasecmp (osabi, osabis[i].name) == 0)
585 return osabis[i].osabi;
587 error (_("Unknown OSABI: %s\n"), osabi);
592 /* Return EM_XXX for a machine string, MACH. */
595 elf_machine (const char *mach)
597 if (strcasecmp (mach, "i386") == 0)
599 if (strcasecmp (mach, "iamcu") == 0)
601 if (strcasecmp (mach, "l1om") == 0)
603 if (strcasecmp (mach, "k1om") == 0)
605 if (strcasecmp (mach, "x86_64") == 0)
607 if (strcasecmp (mach, "x86-64") == 0)
609 if (strcasecmp (mach, "none") == 0)
612 error (_("Unknown machine type: %s\n"), mach);
617 /* Return ET_XXX for a type string, TYPE. */
620 elf_type (const char *type)
622 if (strcasecmp (type, "rel") == 0)
624 if (strcasecmp (type, "exec") == 0)
626 if (strcasecmp (type, "dyn") == 0)
628 if (strcasecmp (type, "none") == 0)
631 error (_("Unknown type: %s\n"), type);
636 enum command_line_switch
638 OPTION_INPUT_MACH = 150,
646 static struct option options[] =
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}
660 usage (FILE *stream, int exit_status)
662 fprintf (stream, _("Usage: %s <option(s)> elffile(s)\n"),
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\
677 if (REPORT_BUGS_TO[0] && exit_status == 0)
678 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
683 main (int argc, char ** argv)
687 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
688 setlocale (LC_MESSAGES, "");
690 #if defined (HAVE_SETLOCALE)
691 setlocale (LC_CTYPE, "");
693 bindtextdomain (PACKAGE, LOCALEDIR);
694 textdomain (PACKAGE);
696 expandargv (&argc, &argv);
698 while ((c = getopt_long (argc, argv, "hv",
699 options, (int *) 0)) != EOF)
703 case OPTION_INPUT_MACH:
704 input_elf_machine = elf_machine (optarg);
705 if (input_elf_machine < 0)
707 input_elf_class = elf_class (input_elf_machine);
708 if (input_elf_class == ELF_CLASS_UNKNOWN)
712 case OPTION_OUTPUT_MACH:
713 output_elf_machine = elf_machine (optarg);
714 if (output_elf_machine < 0)
716 output_elf_class = elf_class (output_elf_machine);
717 if (output_elf_class == ELF_CLASS_UNKNOWN)
721 case OPTION_INPUT_TYPE:
722 input_elf_type = elf_type (optarg);
723 if (input_elf_type < 0)
727 case OPTION_OUTPUT_TYPE:
728 output_elf_type = elf_type (optarg);
729 if (output_elf_type < 0)
733 case OPTION_INPUT_OSABI:
734 input_elf_osabi = elf_osabi (optarg);
735 if (input_elf_osabi < 0)
739 case OPTION_OUTPUT_OSABI:
740 output_elf_osabi = elf_osabi (optarg);
741 if (output_elf_osabi < 0)
749 print_version (program_name);
758 || (output_elf_machine == -1
759 && output_elf_type == -1
760 && output_elf_osabi == -1))
764 while (optind < argc)
765 status |= process_file (argv[optind++]);