Initial import of binutils 2.27 on vendor branch
[dragonfly.git] / contrib / binutils-2.27 / binutils / elfedit.c
blob1223b25a657ba2073027e4c9cfe844828ff6d60b
1 /* elfedit.c -- Update the ELF header of an ELF format file
2 Copyright (C) 2010-2016 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
19 02110-1301, USA. */
21 #include "sysdep.h"
22 #include <assert.h>
24 #if __GNUC__ >= 2
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. */
29 #define BFD64
30 #endif
32 #include "bfd.h"
33 #include "elfcomm.h"
34 #include "bucomm.h"
36 #include "elf/common.h"
37 #include "elf/external.h"
38 #include "elf/internal.h"
40 #include "getopt.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;
57 enum elfclass
59 ELF_CLASS_UNKNOWN = -1,
60 ELF_CLASS_NONE = ELFCLASSNONE,
61 ELF_CLASS_32 = ELFCLASS32,
62 ELF_CLASS_64 = ELFCLASS64,
63 ELF_CLASS_BOTH
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. */
70 static enum elfclass
71 elf_class (int mach)
73 switch (mach)
75 case EM_386:
76 case EM_IAMCU:
77 return ELF_CLASS_32;
78 case EM_L1OM:
79 case EM_K1OM:
80 return ELF_CLASS_64;
81 case EM_X86_64:
82 case EM_NONE:
83 return ELF_CLASS_BOTH;
84 default:
85 return ELF_CLASS_BOTH;
89 static int
90 update_elf_header (const char *file_name, FILE *file)
92 int class, machine, type, status, osabi;
94 if (elf_header.e_ident[EI_MAG0] != ELFMAG0
95 || elf_header.e_ident[EI_MAG1] != ELFMAG1
96 || elf_header.e_ident[EI_MAG2] != ELFMAG2
97 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
99 error
100 (_("%s: Not an ELF file - wrong magic bytes at the start\n"),
101 file_name);
102 return 0;
105 if (elf_header.e_ident[EI_VERSION] != EV_CURRENT)
107 error
108 (_("%s: Unsupported EI_VERSION: %d is not %d\n"),
109 file_name, elf_header.e_ident[EI_VERSION],
110 EV_CURRENT);
111 return 0;
114 /* Return if e_machine is the same as output_elf_machine. */
115 if (output_elf_machine == elf_header.e_machine)
116 return 1;
118 class = elf_header.e_ident[EI_CLASS];
119 machine = elf_header.e_machine;
121 /* Skip if class doesn't match. */
122 if (input_elf_class == ELF_CLASS_UNKNOWN)
123 input_elf_class = elf_class (machine);
125 if (input_elf_class != ELF_CLASS_BOTH
126 && (int) input_elf_class != class)
128 error
129 (_("%s: Unmatched input EI_CLASS: %d is not %d\n"),
130 file_name, class, input_elf_class);
131 return 0;
134 if (output_elf_class != ELF_CLASS_BOTH
135 && (int) output_elf_class != class)
137 error
138 (_("%s: Unmatched output EI_CLASS: %d is not %d\n"),
139 file_name, class, output_elf_class);
140 return 0;
143 /* Skip if e_machine doesn't match. */
144 if (input_elf_machine != -1 && machine != input_elf_machine)
146 error
147 (_("%s: Unmatched e_machine: %d is not %d\n"),
148 file_name, machine, input_elf_machine);
149 return 0;
152 type = elf_header.e_type;
154 /* Skip if e_type doesn't match. */
155 if (input_elf_type != -1 && type != input_elf_type)
157 error
158 (_("%s: Unmatched e_type: %d is not %d\n"),
159 file_name, type, input_elf_type);
160 return 0;
163 osabi = elf_header.e_ident[EI_OSABI];
165 /* Skip if OSABI doesn't match. */
166 if (input_elf_osabi != -1 && osabi != input_elf_osabi)
168 error
169 (_("%s: Unmatched EI_OSABI: %d is not %d\n"),
170 file_name, osabi, input_elf_osabi);
171 return 0;
174 /* Update e_machine, e_type and EI_OSABI. */
175 switch (class)
177 default:
178 /* We should never get here. */
179 abort ();
180 break;
181 case ELFCLASS32:
182 if (output_elf_machine != -1)
183 BYTE_PUT (ehdr32.e_machine, output_elf_machine);
184 if (output_elf_type != -1)
185 BYTE_PUT (ehdr32.e_type, output_elf_type);
186 if (output_elf_osabi != -1)
187 ehdr32.e_ident[EI_OSABI] = output_elf_osabi;
188 status = fwrite (&ehdr32, sizeof (ehdr32), 1, file) == 1;
189 break;
190 case ELFCLASS64:
191 if (output_elf_machine != -1)
192 BYTE_PUT (ehdr64.e_machine, output_elf_machine);
193 if (output_elf_type != -1)
194 BYTE_PUT (ehdr64.e_type, output_elf_type);
195 if (output_elf_osabi != -1)
196 ehdr64.e_ident[EI_OSABI] = output_elf_osabi;
197 status = fwrite (&ehdr64, sizeof (ehdr64), 1, file) == 1;
198 break;
201 if (status != 1)
202 error (_("%s: Failed to update ELF header: %s\n"),
203 file_name, strerror (errno));
205 return status;
208 static int
209 get_file_header (FILE * file)
211 /* Read in the identity array. */
212 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
213 return 0;
215 /* Determine how to read the rest of the header. */
216 switch (elf_header.e_ident[EI_DATA])
218 default: /* fall through */
219 case ELFDATANONE: /* fall through */
220 case ELFDATA2LSB:
221 byte_get = byte_get_little_endian;
222 byte_put = byte_put_little_endian;
223 break;
224 case ELFDATA2MSB:
225 byte_get = byte_get_big_endian;
226 byte_put = byte_put_big_endian;
227 break;
230 /* Read in the rest of the header. For now we only support 32 bit
231 and 64 bit ELF files. */
232 switch (elf_header.e_ident[EI_CLASS])
234 default:
235 error (_("Unsupported EI_CLASS: %d\n"),
236 elf_header.e_ident[EI_CLASS]);
237 return 0;
239 case ELFCLASS32:
240 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT,
241 1, file) != 1)
242 return 0;
244 elf_header.e_type = BYTE_GET (ehdr32.e_type);
245 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
246 elf_header.e_version = BYTE_GET (ehdr32.e_version);
247 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
248 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
249 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
250 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
251 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
252 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
253 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
254 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
255 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
256 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
258 memcpy (&ehdr32, &elf_header, EI_NIDENT);
259 break;
261 case ELFCLASS64:
262 /* If we have been compiled with sizeof (bfd_vma) == 4, then
263 we will not be able to cope with the 64bit data found in
264 64 ELF files. Detect this now and abort before we start
265 overwriting things. */
266 if (sizeof (bfd_vma) < 8)
268 error (_("This executable has been built without support for a\n\
269 64 bit data type and so it cannot process 64 bit ELF files.\n"));
270 return 0;
273 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT,
274 1, file) != 1)
275 return 0;
277 elf_header.e_type = BYTE_GET (ehdr64.e_type);
278 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
279 elf_header.e_version = BYTE_GET (ehdr64.e_version);
280 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
281 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
282 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
283 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
284 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
285 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
286 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
287 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
288 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
289 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
291 memcpy (&ehdr64, &elf_header, EI_NIDENT);
292 break;
294 return 1;
297 /* Process one ELF object file according to the command line options.
298 This file may actually be stored in an archive. The file is
299 positioned at the start of the ELF object. */
301 static int
302 process_object (const char *file_name, FILE *file)
304 /* Rememeber where we are. */
305 long offset = ftell (file);
307 if (! get_file_header (file))
309 error (_("%s: Failed to read ELF header\n"), file_name);
310 return 1;
313 /* Go to the position of the ELF header. */
314 if (fseek (file, offset, SEEK_SET) != 0)
316 error (_("%s: Failed to seek to ELF header\n"), file_name);
319 if (! update_elf_header (file_name, file))
320 return 1;
322 return 0;
325 /* Process an ELF archive.
326 On entry the file is positioned just after the ARMAG string. */
328 static int
329 process_archive (const char * file_name, FILE * file,
330 bfd_boolean is_thin_archive)
332 struct archive_info arch;
333 struct archive_info nested_arch;
334 size_t got;
335 int ret;
337 /* The ARCH structure is used to hold information about this archive. */
338 arch.file_name = NULL;
339 arch.file = NULL;
340 arch.index_array = NULL;
341 arch.sym_table = NULL;
342 arch.longnames = NULL;
344 /* The NESTED_ARCH structure is used as a single-item cache of information
345 about a nested archive (when members of a thin archive reside within
346 another regular archive file). */
347 nested_arch.file_name = NULL;
348 nested_arch.file = NULL;
349 nested_arch.index_array = NULL;
350 nested_arch.sym_table = NULL;
351 nested_arch.longnames = NULL;
353 if (setup_archive (&arch, file_name, file, is_thin_archive, FALSE) != 0)
355 ret = 1;
356 goto out;
359 ret = 0;
361 while (1)
363 char * name;
364 size_t namelen;
365 char * qualified_name;
367 /* Read the next archive header. */
368 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
370 error (_("%s: failed to seek to next archive header\n"),
371 file_name);
372 return 1;
374 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
375 if (got != sizeof arch.arhdr)
377 if (got == 0)
378 break;
379 error (_("%s: failed to read archive header\n"),
380 file_name);
381 ret = 1;
382 break;
384 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
386 error (_("%s: did not find a valid archive header\n"),
387 arch.file_name);
388 ret = 1;
389 break;
392 arch.next_arhdr_offset += sizeof arch.arhdr;
394 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
395 if (archive_file_size & 01)
396 ++archive_file_size;
398 name = get_archive_member_name (&arch, &nested_arch);
399 if (name == NULL)
401 error (_("%s: bad archive file name\n"), file_name);
402 ret = 1;
403 break;
405 namelen = strlen (name);
407 qualified_name = make_qualified_name (&arch, &nested_arch, name);
408 if (qualified_name == NULL)
410 error (_("%s: bad archive file name\n"), file_name);
411 ret = 1;
412 break;
415 if (is_thin_archive && arch.nested_member_origin == 0)
417 /* This is a proxy for an external member of a thin archive. */
418 FILE *member_file;
419 char *member_file_name = adjust_relative_path (file_name,
420 name, namelen);
421 if (member_file_name == NULL)
423 ret = 1;
424 break;
427 member_file = fopen (member_file_name, "r+b");
428 if (member_file == NULL)
430 error (_("Input file '%s' is not readable\n"),
431 member_file_name);
432 free (member_file_name);
433 ret = 1;
434 break;
437 archive_file_offset = arch.nested_member_origin;
439 ret |= process_object (qualified_name, member_file);
441 fclose (member_file);
442 free (member_file_name);
444 else if (is_thin_archive)
446 /* This is a proxy for a member of a nested archive. */
447 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
449 /* The nested archive file will have been opened and setup by
450 get_archive_member_name. */
451 if (fseek (nested_arch.file, archive_file_offset,
452 SEEK_SET) != 0)
454 error (_("%s: failed to seek to archive member\n"),
455 nested_arch.file_name);
456 ret = 1;
457 break;
460 ret |= process_object (qualified_name, nested_arch.file);
462 else
464 archive_file_offset = arch.next_arhdr_offset;
465 arch.next_arhdr_offset += archive_file_size;
467 ret |= process_object (qualified_name, file);
470 free (qualified_name);
473 out:
474 if (nested_arch.file != NULL)
475 fclose (nested_arch.file);
476 release_archive (&nested_arch);
477 release_archive (&arch);
479 return ret;
482 static int
483 check_file (const char *file_name, struct stat *statbuf_p)
485 struct stat statbuf;
487 if (statbuf_p == NULL)
488 statbuf_p = &statbuf;
490 if (stat (file_name, statbuf_p) < 0)
492 if (errno == ENOENT)
493 error (_("'%s': No such file\n"), file_name);
494 else
495 error (_("Could not locate '%s'. System error message: %s\n"),
496 file_name, strerror (errno));
497 return 1;
500 if (! S_ISREG (statbuf_p->st_mode))
502 error (_("'%s' is not an ordinary file\n"), file_name);
503 return 1;
506 return 0;
509 static int
510 process_file (const char *file_name)
512 FILE * file;
513 char armag[SARMAG];
514 int ret;
516 if (check_file (file_name, NULL))
517 return 1;
519 file = fopen (file_name, "r+b");
520 if (file == NULL)
522 error (_("Input file '%s' is not readable\n"), file_name);
523 return 1;
526 if (fread (armag, SARMAG, 1, file) != 1)
528 error (_("%s: Failed to read file's magic number\n"),
529 file_name);
530 fclose (file);
531 return 1;
534 if (memcmp (armag, ARMAG, SARMAG) == 0)
535 ret = process_archive (file_name, file, FALSE);
536 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
537 ret = process_archive (file_name, file, TRUE);
538 else
540 rewind (file);
541 archive_file_size = archive_file_offset = 0;
542 ret = process_object (file_name, file);
545 fclose (file);
547 return ret;
550 static const struct
552 int osabi;
553 const char *name;
555 osabis[] =
557 { ELFOSABI_NONE, "none" },
558 { ELFOSABI_HPUX, "HPUX" },
559 { ELFOSABI_NETBSD, "NetBSD" },
560 { ELFOSABI_GNU, "GNU" },
561 { ELFOSABI_GNU, "Linux" },
562 { ELFOSABI_SOLARIS, "Solaris" },
563 { ELFOSABI_AIX, "AIX" },
564 { ELFOSABI_IRIX, "Irix" },
565 { ELFOSABI_FREEBSD, "FreeBSD" },
566 { ELFOSABI_TRU64, "TRU64" },
567 { ELFOSABI_MODESTO, "Modesto" },
568 { ELFOSABI_OPENBSD, "OpenBSD" },
569 { ELFOSABI_OPENVMS, "OpenVMS" },
570 { ELFOSABI_NSK, "NSK" },
571 { ELFOSABI_AROS, "AROS" },
572 { ELFOSABI_FENIXOS, "FenixOS" }
575 /* Return ELFOSABI_XXX for an OSABI string, OSABI. */
577 static int
578 elf_osabi (const char *osabi)
580 unsigned int i;
582 for (i = 0; i < ARRAY_SIZE (osabis); i++)
583 if (strcasecmp (osabi, osabis[i].name) == 0)
584 return osabis[i].osabi;
586 error (_("Unknown OSABI: %s\n"), osabi);
588 return -1;
591 /* Return EM_XXX for a machine string, MACH. */
593 static int
594 elf_machine (const char *mach)
596 if (strcasecmp (mach, "i386") == 0)
597 return EM_386;
598 if (strcasecmp (mach, "iamcu") == 0)
599 return EM_IAMCU;
600 if (strcasecmp (mach, "l1om") == 0)
601 return EM_L1OM;
602 if (strcasecmp (mach, "k1om") == 0)
603 return EM_K1OM;
604 if (strcasecmp (mach, "x86_64") == 0)
605 return EM_X86_64;
606 if (strcasecmp (mach, "x86-64") == 0)
607 return EM_X86_64;
608 if (strcasecmp (mach, "none") == 0)
609 return EM_NONE;
611 error (_("Unknown machine type: %s\n"), mach);
613 return -1;
616 /* Return ET_XXX for a type string, TYPE. */
618 static int
619 elf_type (const char *type)
621 if (strcasecmp (type, "rel") == 0)
622 return ET_REL;
623 if (strcasecmp (type, "exec") == 0)
624 return ET_EXEC;
625 if (strcasecmp (type, "dyn") == 0)
626 return ET_DYN;
627 if (strcasecmp (type, "none") == 0)
628 return ET_NONE;
630 error (_("Unknown type: %s\n"), type);
632 return -1;
635 enum command_line_switch
637 OPTION_INPUT_MACH = 150,
638 OPTION_OUTPUT_MACH,
639 OPTION_INPUT_TYPE,
640 OPTION_OUTPUT_TYPE,
641 OPTION_INPUT_OSABI,
642 OPTION_OUTPUT_OSABI
645 static struct option options[] =
647 {"input-mach", required_argument, 0, OPTION_INPUT_MACH},
648 {"output-mach", required_argument, 0, OPTION_OUTPUT_MACH},
649 {"input-type", required_argument, 0, OPTION_INPUT_TYPE},
650 {"output-type", required_argument, 0, OPTION_OUTPUT_TYPE},
651 {"input-osabi", required_argument, 0, OPTION_INPUT_OSABI},
652 {"output-osabi", required_argument, 0, OPTION_OUTPUT_OSABI},
653 {"version", no_argument, 0, 'v'},
654 {"help", no_argument, 0, 'h'},
655 {0, no_argument, 0, 0}
658 static void
659 usage (FILE *stream, int exit_status)
661 fprintf (stream, _("Usage: %s <option(s)> elffile(s)\n"),
662 program_name);
663 fprintf (stream, _(" Update the ELF header of ELF files\n"));
664 fprintf (stream, _(" The options are:\n"));
665 fprintf (stream, _("\
666 --input-mach <machine> Set input machine type to <machine>\n\
667 --output-mach <machine> Set output machine type to <machine>\n\
668 --input-type <type> Set input file type to <type>\n\
669 --output-type <type> Set output file type to <type>\n\
670 --input-osabi <osabi> Set input OSABI to <osabi>\n\
671 --output-osabi <osabi> Set output OSABI to <osabi>\n\
672 -h --help Display this information\n\
673 -v --version Display the version number of %s\n\
675 program_name);
676 if (REPORT_BUGS_TO[0] && exit_status == 0)
677 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
678 exit (exit_status);
682 main (int argc, char ** argv)
684 int c, status;
686 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
687 setlocale (LC_MESSAGES, "");
688 #endif
689 #if defined (HAVE_SETLOCALE)
690 setlocale (LC_CTYPE, "");
691 #endif
692 bindtextdomain (PACKAGE, LOCALEDIR);
693 textdomain (PACKAGE);
695 expandargv (&argc, &argv);
697 while ((c = getopt_long (argc, argv, "hv",
698 options, (int *) 0)) != EOF)
700 switch (c)
702 case OPTION_INPUT_MACH:
703 input_elf_machine = elf_machine (optarg);
704 if (input_elf_machine < 0)
705 return 1;
706 input_elf_class = elf_class (input_elf_machine);
707 if (input_elf_class == ELF_CLASS_UNKNOWN)
708 return 1;
709 break;
711 case OPTION_OUTPUT_MACH:
712 output_elf_machine = elf_machine (optarg);
713 if (output_elf_machine < 0)
714 return 1;
715 output_elf_class = elf_class (output_elf_machine);
716 if (output_elf_class == ELF_CLASS_UNKNOWN)
717 return 1;
718 break;
720 case OPTION_INPUT_TYPE:
721 input_elf_type = elf_type (optarg);
722 if (input_elf_type < 0)
723 return 1;
724 break;
726 case OPTION_OUTPUT_TYPE:
727 output_elf_type = elf_type (optarg);
728 if (output_elf_type < 0)
729 return 1;
730 break;
732 case OPTION_INPUT_OSABI:
733 input_elf_osabi = elf_osabi (optarg);
734 if (input_elf_osabi < 0)
735 return 1;
736 break;
738 case OPTION_OUTPUT_OSABI:
739 output_elf_osabi = elf_osabi (optarg);
740 if (output_elf_osabi < 0)
741 return 1;
742 break;
744 case 'h':
745 usage (stdout, 0);
747 case 'v':
748 print_version (program_name);
749 break;
751 default:
752 usage (stderr, 1);
756 if (optind == argc
757 || (output_elf_machine == -1
758 && output_elf_type == -1
759 && output_elf_osabi == -1))
760 usage (stderr, 1);
762 status = 0;
763 while (optind < argc)
764 status |= process_file (argv[optind++]);
766 return status;