1 /* elfedit.c -- Update the ELF header of an ELF format file
2 Copyright (C) 2010-2018 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 return ELF_CLASS_BOTH;
90 update_elf_header (const char *file_name, FILE *file)
92 int class, machine, type, status, osabi;
94 if (elf_header.e_ident[EI_VERSION] != EV_CURRENT)
97 (_("%s: Unsupported EI_VERSION: %d is not %d\n"),
98 file_name, elf_header.e_ident[EI_VERSION],
103 /* Return if e_machine is the same as output_elf_machine. */
104 if (output_elf_machine == elf_header.e_machine)
107 class = elf_header.e_ident[EI_CLASS];
108 machine = elf_header.e_machine;
110 /* Skip if class doesn't match. */
111 if (input_elf_class == ELF_CLASS_UNKNOWN)
112 input_elf_class = elf_class (machine);
114 if (input_elf_class != ELF_CLASS_BOTH
115 && (int) input_elf_class != class)
118 (_("%s: Unmatched input EI_CLASS: %d is not %d\n"),
119 file_name, class, input_elf_class);
123 if (output_elf_class != ELF_CLASS_BOTH
124 && (int) output_elf_class != class)
127 (_("%s: Unmatched output EI_CLASS: %d is not %d\n"),
128 file_name, class, output_elf_class);
132 /* Skip if e_machine doesn't match. */
133 if (input_elf_machine != -1 && machine != input_elf_machine)
136 (_("%s: Unmatched e_machine: %d is not %d\n"),
137 file_name, machine, input_elf_machine);
141 type = elf_header.e_type;
143 /* Skip if e_type doesn't match. */
144 if (input_elf_type != -1 && type != input_elf_type)
147 (_("%s: Unmatched e_type: %d is not %d\n"),
148 file_name, type, input_elf_type);
152 osabi = elf_header.e_ident[EI_OSABI];
154 /* Skip if OSABI doesn't match. */
155 if (input_elf_osabi != -1 && osabi != input_elf_osabi)
158 (_("%s: Unmatched EI_OSABI: %d is not %d\n"),
159 file_name, osabi, input_elf_osabi);
163 /* Update e_machine, e_type and EI_OSABI. */
167 /* We should never get here. */
171 if (output_elf_machine != -1)
172 BYTE_PUT (ehdr32.e_machine, output_elf_machine);
173 if (output_elf_type != -1)
174 BYTE_PUT (ehdr32.e_type, output_elf_type);
175 if (output_elf_osabi != -1)
176 ehdr32.e_ident[EI_OSABI] = output_elf_osabi;
177 status = fwrite (&ehdr32, sizeof (ehdr32), 1, file) == 1;
180 if (output_elf_machine != -1)
181 BYTE_PUT (ehdr64.e_machine, output_elf_machine);
182 if (output_elf_type != -1)
183 BYTE_PUT (ehdr64.e_type, output_elf_type);
184 if (output_elf_osabi != -1)
185 ehdr64.e_ident[EI_OSABI] = output_elf_osabi;
186 status = fwrite (&ehdr64, sizeof (ehdr64), 1, file) == 1;
191 error (_("%s: Failed to update ELF header: %s\n"),
192 file_name, strerror (errno));
198 get_file_header (FILE * file)
200 /* Read in the identity array. */
201 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
204 if (elf_header.e_ident[EI_MAG0] != ELFMAG0
205 || elf_header.e_ident[EI_MAG1] != ELFMAG1
206 || elf_header.e_ident[EI_MAG2] != ELFMAG2
207 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
210 /* Determine how to read the rest of the header. */
211 switch (elf_header.e_ident[EI_DATA])
213 default: /* fall through */
214 case ELFDATANONE: /* fall through */
216 byte_get = byte_get_little_endian;
217 byte_put = byte_put_little_endian;
220 byte_get = byte_get_big_endian;
221 byte_put = byte_put_big_endian;
225 /* Read in the rest of the header. For now we only support 32 bit
226 and 64 bit ELF files. */
227 switch (elf_header.e_ident[EI_CLASS])
233 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT,
237 elf_header.e_type = BYTE_GET (ehdr32.e_type);
238 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
239 elf_header.e_version = BYTE_GET (ehdr32.e_version);
240 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
241 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
242 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
243 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
244 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
245 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
246 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
247 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
248 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
249 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
251 memcpy (&ehdr32, &elf_header, EI_NIDENT);
255 /* If we have been compiled with sizeof (bfd_vma) == 4, then
256 we will not be able to cope with the 64bit data found in
257 64 ELF files. Detect this now and abort before we start
258 overwriting things. */
259 if (sizeof (bfd_vma) < 8)
261 error (_("This executable has been built without support for a\n\
262 64 bit data type and so it cannot process 64 bit ELF files.\n"));
266 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT,
270 elf_header.e_type = BYTE_GET (ehdr64.e_type);
271 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
272 elf_header.e_version = BYTE_GET (ehdr64.e_version);
273 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
274 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
275 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
276 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
277 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
278 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
279 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
280 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
281 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
282 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
284 memcpy (&ehdr64, &elf_header, EI_NIDENT);
290 /* Process one ELF object file according to the command line options.
291 This file may actually be stored in an archive. The file is
292 positioned at the start of the ELF object. */
295 process_object (const char *file_name, FILE *file)
297 /* Rememeber where we are. */
298 long offset = ftell (file);
300 if (! get_file_header (file))
302 error (_("%s: Failed to read ELF header\n"), file_name);
306 /* Go to the position of the ELF header. */
307 if (fseek (file, offset, SEEK_SET) != 0)
309 error (_("%s: Failed to seek to ELF header\n"), file_name);
312 if (! update_elf_header (file_name, file))
318 /* Process an ELF archive.
319 On entry the file is positioned just after the ARMAG string. */
322 process_archive (const char * file_name, FILE * file,
323 bfd_boolean is_thin_archive)
325 struct archive_info arch;
326 struct archive_info nested_arch;
330 /* The ARCH structure is used to hold information about this archive. */
331 arch.file_name = NULL;
333 arch.index_array = NULL;
334 arch.sym_table = NULL;
335 arch.longnames = NULL;
337 /* The NESTED_ARCH structure is used as a single-item cache of information
338 about a nested archive (when members of a thin archive reside within
339 another regular archive file). */
340 nested_arch.file_name = NULL;
341 nested_arch.file = NULL;
342 nested_arch.index_array = NULL;
343 nested_arch.sym_table = NULL;
344 nested_arch.longnames = NULL;
346 if (setup_archive (&arch, file_name, file, is_thin_archive, FALSE) != 0)
358 char * qualified_name;
360 /* Read the next archive header. */
361 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
363 error (_("%s: failed to seek to next archive header\n"),
367 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
368 if (got != sizeof arch.arhdr)
372 error (_("%s: failed to read archive header\n"),
377 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
379 error (_("%s: did not find a valid archive header\n"),
385 arch.next_arhdr_offset += sizeof arch.arhdr;
387 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
388 if (archive_file_size & 01)
391 name = get_archive_member_name (&arch, &nested_arch);
394 error (_("%s: bad archive file name\n"), file_name);
398 namelen = strlen (name);
400 qualified_name = make_qualified_name (&arch, &nested_arch, name);
401 if (qualified_name == NULL)
403 error (_("%s: bad archive file name\n"), file_name);
408 if (is_thin_archive && arch.nested_member_origin == 0)
410 /* This is a proxy for an external member of a thin archive. */
412 char *member_file_name = adjust_relative_path (file_name,
414 if (member_file_name == NULL)
420 member_file = fopen (member_file_name, "r+b");
421 if (member_file == NULL)
423 error (_("Input file '%s' is not readable\n"),
425 free (member_file_name);
430 archive_file_offset = arch.nested_member_origin;
432 ret |= process_object (qualified_name, member_file);
434 fclose (member_file);
435 free (member_file_name);
437 else if (is_thin_archive)
439 /* This is a proxy for a member of a nested archive. */
440 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
442 /* The nested archive file will have been opened and setup by
443 get_archive_member_name. */
444 if (fseek (nested_arch.file, archive_file_offset,
447 error (_("%s: failed to seek to archive member\n"),
448 nested_arch.file_name);
453 ret |= process_object (qualified_name, nested_arch.file);
457 archive_file_offset = arch.next_arhdr_offset;
458 arch.next_arhdr_offset += archive_file_size;
460 ret |= process_object (qualified_name, file);
463 free (qualified_name);
467 if (nested_arch.file != NULL)
468 fclose (nested_arch.file);
469 release_archive (&nested_arch);
470 release_archive (&arch);
476 check_file (const char *file_name, struct stat *statbuf_p)
480 if (statbuf_p == NULL)
481 statbuf_p = &statbuf;
483 if (stat (file_name, statbuf_p) < 0)
486 error (_("'%s': No such file\n"), file_name);
488 error (_("Could not locate '%s'. System error message: %s\n"),
489 file_name, strerror (errno));
493 if (! S_ISREG (statbuf_p->st_mode))
495 error (_("'%s' is not an ordinary file\n"), file_name);
503 process_file (const char *file_name)
509 if (check_file (file_name, NULL))
512 file = fopen (file_name, "r+b");
515 error (_("Input file '%s' is not readable\n"), file_name);
519 if (fread (armag, SARMAG, 1, file) != 1)
521 error (_("%s: Failed to read file's magic number\n"),
527 if (memcmp (armag, ARMAG, SARMAG) == 0)
528 ret = process_archive (file_name, file, FALSE);
529 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
530 ret = process_archive (file_name, file, TRUE);
534 archive_file_size = archive_file_offset = 0;
535 ret = process_object (file_name, file);
550 { ELFOSABI_NONE, "none" },
551 { ELFOSABI_HPUX, "HPUX" },
552 { ELFOSABI_NETBSD, "NetBSD" },
553 { ELFOSABI_GNU, "GNU" },
554 { ELFOSABI_GNU, "Linux" },
555 { ELFOSABI_SOLARIS, "Solaris" },
556 { ELFOSABI_AIX, "AIX" },
557 { ELFOSABI_IRIX, "Irix" },
558 { ELFOSABI_FREEBSD, "FreeBSD" },
559 { ELFOSABI_TRU64, "TRU64" },
560 { ELFOSABI_MODESTO, "Modesto" },
561 { ELFOSABI_OPENBSD, "OpenBSD" },
562 { ELFOSABI_OPENVMS, "OpenVMS" },
563 { ELFOSABI_NSK, "NSK" },
564 { ELFOSABI_AROS, "AROS" },
565 { ELFOSABI_FENIXOS, "FenixOS" }
568 /* Return ELFOSABI_XXX for an OSABI string, OSABI. */
571 elf_osabi (const char *osabi)
575 for (i = 0; i < ARRAY_SIZE (osabis); i++)
576 if (strcasecmp (osabi, osabis[i].name) == 0)
577 return osabis[i].osabi;
579 error (_("Unknown OSABI: %s\n"), osabi);
584 /* Return EM_XXX for a machine string, MACH. */
587 elf_machine (const char *mach)
589 if (strcasecmp (mach, "i386") == 0)
591 if (strcasecmp (mach, "iamcu") == 0)
593 if (strcasecmp (mach, "l1om") == 0)
595 if (strcasecmp (mach, "k1om") == 0)
597 if (strcasecmp (mach, "x86_64") == 0)
599 if (strcasecmp (mach, "x86-64") == 0)
601 if (strcasecmp (mach, "none") == 0)
604 error (_("Unknown machine type: %s\n"), mach);
609 /* Return ET_XXX for a type string, TYPE. */
612 elf_type (const char *type)
614 if (strcasecmp (type, "rel") == 0)
616 if (strcasecmp (type, "exec") == 0)
618 if (strcasecmp (type, "dyn") == 0)
620 if (strcasecmp (type, "none") == 0)
623 error (_("Unknown type: %s\n"), type);
628 enum command_line_switch
630 OPTION_INPUT_MACH = 150,
638 static struct option options[] =
640 {"input-mach", required_argument, 0, OPTION_INPUT_MACH},
641 {"output-mach", required_argument, 0, OPTION_OUTPUT_MACH},
642 {"input-type", required_argument, 0, OPTION_INPUT_TYPE},
643 {"output-type", required_argument, 0, OPTION_OUTPUT_TYPE},
644 {"input-osabi", required_argument, 0, OPTION_INPUT_OSABI},
645 {"output-osabi", required_argument, 0, OPTION_OUTPUT_OSABI},
646 {"version", no_argument, 0, 'v'},
647 {"help", no_argument, 0, 'h'},
648 {0, no_argument, 0, 0}
651 ATTRIBUTE_NORETURN static void
652 usage (FILE *stream, int exit_status)
654 fprintf (stream, _("Usage: %s <option(s)> elffile(s)\n"),
656 fprintf (stream, _(" Update the ELF header of ELF files\n"));
657 fprintf (stream, _(" The options are:\n"));
658 fprintf (stream, _("\
659 --input-mach <machine> Set input machine type to <machine>\n\
660 --output-mach <machine> Set output machine type to <machine>\n\
661 --input-type <type> Set input file type to <type>\n\
662 --output-type <type> Set output file type to <type>\n\
663 --input-osabi <osabi> Set input OSABI to <osabi>\n\
664 --output-osabi <osabi> Set output OSABI to <osabi>\n\
665 -h --help Display this information\n\
666 -v --version Display the version number of %s\n\
669 if (REPORT_BUGS_TO[0] && exit_status == 0)
670 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
675 main (int argc, char ** argv)
679 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
680 setlocale (LC_MESSAGES, "");
682 #if defined (HAVE_SETLOCALE)
683 setlocale (LC_CTYPE, "");
685 bindtextdomain (PACKAGE, LOCALEDIR);
686 textdomain (PACKAGE);
688 expandargv (&argc, &argv);
690 while ((c = getopt_long (argc, argv, "hv",
691 options, (int *) 0)) != EOF)
695 case OPTION_INPUT_MACH:
696 input_elf_machine = elf_machine (optarg);
697 if (input_elf_machine < 0)
699 input_elf_class = elf_class (input_elf_machine);
700 if (input_elf_class == ELF_CLASS_UNKNOWN)
704 case OPTION_OUTPUT_MACH:
705 output_elf_machine = elf_machine (optarg);
706 if (output_elf_machine < 0)
708 output_elf_class = elf_class (output_elf_machine);
709 if (output_elf_class == ELF_CLASS_UNKNOWN)
713 case OPTION_INPUT_TYPE:
714 input_elf_type = elf_type (optarg);
715 if (input_elf_type < 0)
719 case OPTION_OUTPUT_TYPE:
720 output_elf_type = elf_type (optarg);
721 if (output_elf_type < 0)
725 case OPTION_INPUT_OSABI:
726 input_elf_osabi = elf_osabi (optarg);
727 if (input_elf_osabi < 0)
731 case OPTION_OUTPUT_OSABI:
732 output_elf_osabi = elf_osabi (optarg);
733 if (output_elf_osabi < 0)
741 print_version (program_name);
750 || (output_elf_machine == -1
751 && output_elf_type == -1
752 && output_elf_osabi == -1))
756 while (optind < argc)
757 status |= process_file (argv[optind++]);