]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - binutils/elfedit.c
ChangeLog rotatation and copyright year update
[thirdparty/binutils-gdb.git] / binutils / elfedit.c
1 /* elfedit.c -- Update the ELF header of an ELF format file
2 Copyright (C) 2010-2015 Free Software Foundation, Inc.
3
4 This file is part of GNU Binutils.
5
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.
10
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.
15
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. */
20 \f
21 #include "sysdep.h"
22 #include <assert.h>
23
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
31
32 #include "bfd.h"
33 #include "elfcomm.h"
34 #include "bucomm.h"
35
36 #include "elf/common.h"
37 #include "elf/external.h"
38 #include "elf/internal.h"
39
40 #include "getopt.h"
41 #include "libiberty.h"
42 #include "safe-ctype.h"
43 #include "filenames.h"
44
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 static int input_elf_class = -1;
58
59 static int
60 update_elf_header (const char *file_name, FILE *file)
61 {
62 int class, machine, type, status, osabi;
63
64 if (elf_header.e_ident[EI_MAG0] != ELFMAG0
65 || elf_header.e_ident[EI_MAG1] != ELFMAG1
66 || elf_header.e_ident[EI_MAG2] != ELFMAG2
67 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
68 {
69 error
70 (_("%s: Not an ELF file - wrong magic bytes at the start\n"),
71 file_name);
72 return 0;
73 }
74
75 if (elf_header.e_ident[EI_VERSION] != EV_CURRENT)
76 {
77 error
78 (_("%s: Unsupported EI_VERSION: %d is not %d\n"),
79 file_name, elf_header.e_ident[EI_VERSION],
80 EV_CURRENT);
81 return 0;
82 }
83
84 /* Return if e_machine is the same as output_elf_machine. */
85 if (output_elf_machine == elf_header.e_machine)
86 return 1;
87
88 class = elf_header.e_ident[EI_CLASS];
89
90 /* Skip if class doesn't match. */
91 if (input_elf_class != -1 && class != input_elf_class)
92 {
93 error
94 (_("%s: Unmatched EI_CLASS: %d is not %d\n"),
95 file_name, class, input_elf_class);
96 return 0;
97 }
98
99 machine = elf_header.e_machine;
100
101 /* Skip if e_machine doesn't match. */
102 if (input_elf_machine != -1 && machine != input_elf_machine)
103 {
104 error
105 (_("%s: Unmatched e_machine: %d is not %d\n"),
106 file_name, machine, input_elf_machine);
107 return 0;
108 }
109
110 type = elf_header.e_type;
111
112 /* Skip if e_type doesn't match. */
113 if (input_elf_type != -1 && type != input_elf_type)
114 {
115 error
116 (_("%s: Unmatched e_type: %d is not %d\n"),
117 file_name, type, input_elf_type);
118 return 0;
119 }
120
121 osabi = elf_header.e_ident[EI_OSABI];
122
123 /* Skip if OSABI doesn't match. */
124 if (input_elf_osabi != -1 && osabi != input_elf_osabi)
125 {
126 error
127 (_("%s: Unmatched EI_OSABI: %d is not %d\n"),
128 file_name, osabi, input_elf_osabi);
129 return 0;
130 }
131
132 /* Update e_machine, e_type and EI_OSABI. */
133 switch (class)
134 {
135 default:
136 /* We should never get here. */
137 abort ();
138 break;
139 case ELFCLASS32:
140 if (output_elf_machine != -1)
141 BYTE_PUT (ehdr32.e_machine, output_elf_machine);
142 if (output_elf_type != -1)
143 BYTE_PUT (ehdr32.e_type, output_elf_type);
144 if (output_elf_osabi != -1)
145 ehdr32.e_ident[EI_OSABI] = output_elf_osabi;
146 status = fwrite (&ehdr32, sizeof (ehdr32), 1, file) == 1;
147 break;
148 case ELFCLASS64:
149 if (output_elf_machine != -1)
150 BYTE_PUT (ehdr64.e_machine, output_elf_machine);
151 if (output_elf_type != -1)
152 BYTE_PUT (ehdr64.e_type, output_elf_type);
153 if (output_elf_osabi != -1)
154 ehdr64.e_ident[EI_OSABI] = output_elf_osabi;
155 status = fwrite (&ehdr64, sizeof (ehdr64), 1, file) == 1;
156 break;
157 }
158
159 if (status != 1)
160 error (_("%s: Failed to update ELF header: %s\n"),
161 file_name, strerror (errno));
162
163 return status;
164 }
165
166 static int
167 get_file_header (FILE * file)
168 {
169 /* Read in the identity array. */
170 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
171 return 0;
172
173 /* Determine how to read the rest of the header. */
174 switch (elf_header.e_ident[EI_DATA])
175 {
176 default: /* fall through */
177 case ELFDATANONE: /* fall through */
178 case ELFDATA2LSB:
179 byte_get = byte_get_little_endian;
180 byte_put = byte_put_little_endian;
181 break;
182 case ELFDATA2MSB:
183 byte_get = byte_get_big_endian;
184 byte_put = byte_put_big_endian;
185 break;
186 }
187
188 /* Read in the rest of the header. For now we only support 32 bit
189 and 64 bit ELF files. */
190 switch (elf_header.e_ident[EI_CLASS])
191 {
192 default:
193 error (_("Unsupported EI_CLASS: %d\n"),
194 elf_header.e_ident[EI_CLASS]);
195 return 0;
196
197 case ELFCLASS32:
198 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT,
199 1, file) != 1)
200 return 0;
201
202 elf_header.e_type = BYTE_GET (ehdr32.e_type);
203 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
204 elf_header.e_version = BYTE_GET (ehdr32.e_version);
205 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
206 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
207 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
208 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
209 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
210 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
211 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
212 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
213 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
214 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
215
216 memcpy (&ehdr32, &elf_header, EI_NIDENT);
217 break;
218
219 case ELFCLASS64:
220 /* If we have been compiled with sizeof (bfd_vma) == 4, then
221 we will not be able to cope with the 64bit data found in
222 64 ELF files. Detect this now and abort before we start
223 overwriting things. */
224 if (sizeof (bfd_vma) < 8)
225 {
226 error (_("This executable has been built without support for a\n\
227 64 bit data type and so it cannot process 64 bit ELF files.\n"));
228 return 0;
229 }
230
231 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT,
232 1, file) != 1)
233 return 0;
234
235 elf_header.e_type = BYTE_GET (ehdr64.e_type);
236 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
237 elf_header.e_version = BYTE_GET (ehdr64.e_version);
238 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
239 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
240 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
241 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
242 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
243 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
244 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
245 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
246 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
247 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
248
249 memcpy (&ehdr64, &elf_header, EI_NIDENT);
250 break;
251 }
252 return 1;
253 }
254
255 /* Process one ELF object file according to the command line options.
256 This file may actually be stored in an archive. The file is
257 positioned at the start of the ELF object. */
258
259 static int
260 process_object (const char *file_name, FILE *file)
261 {
262 /* Rememeber where we are. */
263 long offset = ftell (file);
264
265 if (! get_file_header (file))
266 {
267 error (_("%s: Failed to read ELF header\n"), file_name);
268 return 1;
269 }
270
271 /* Go to the position of the ELF header. */
272 if (fseek (file, offset, SEEK_SET) != 0)
273 {
274 error (_("%s: Failed to seek to ELF header\n"), file_name);
275 }
276
277 if (! update_elf_header (file_name, file))
278 return 1;
279
280 return 0;
281 }
282
283 /* Process an ELF archive.
284 On entry the file is positioned just after the ARMAG string. */
285
286 static int
287 process_archive (const char * file_name, FILE * file,
288 bfd_boolean is_thin_archive)
289 {
290 struct archive_info arch;
291 struct archive_info nested_arch;
292 size_t got;
293 int ret;
294
295 /* The ARCH structure is used to hold information about this archive. */
296 arch.file_name = NULL;
297 arch.file = NULL;
298 arch.index_array = NULL;
299 arch.sym_table = NULL;
300 arch.longnames = NULL;
301
302 /* The NESTED_ARCH structure is used as a single-item cache of information
303 about a nested archive (when members of a thin archive reside within
304 another regular archive file). */
305 nested_arch.file_name = NULL;
306 nested_arch.file = NULL;
307 nested_arch.index_array = NULL;
308 nested_arch.sym_table = NULL;
309 nested_arch.longnames = NULL;
310
311 if (setup_archive (&arch, file_name, file, is_thin_archive, FALSE) != 0)
312 {
313 ret = 1;
314 goto out;
315 }
316
317 ret = 0;
318
319 while (1)
320 {
321 char * name;
322 size_t namelen;
323 char * qualified_name;
324
325 /* Read the next archive header. */
326 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
327 {
328 error (_("%s: failed to seek to next archive header\n"),
329 file_name);
330 return 1;
331 }
332 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
333 if (got != sizeof arch.arhdr)
334 {
335 if (got == 0)
336 break;
337 error (_("%s: failed to read archive header\n"),
338 file_name);
339 ret = 1;
340 break;
341 }
342 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
343 {
344 error (_("%s: did not find a valid archive header\n"),
345 arch.file_name);
346 ret = 1;
347 break;
348 }
349
350 arch.next_arhdr_offset += sizeof arch.arhdr;
351
352 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
353 if (archive_file_size & 01)
354 ++archive_file_size;
355
356 name = get_archive_member_name (&arch, &nested_arch);
357 if (name == NULL)
358 {
359 error (_("%s: bad archive file name\n"), file_name);
360 ret = 1;
361 break;
362 }
363 namelen = strlen (name);
364
365 qualified_name = make_qualified_name (&arch, &nested_arch, name);
366 if (qualified_name == NULL)
367 {
368 error (_("%s: bad archive file name\n"), file_name);
369 ret = 1;
370 break;
371 }
372
373 if (is_thin_archive && arch.nested_member_origin == 0)
374 {
375 /* This is a proxy for an external member of a thin archive. */
376 FILE *member_file;
377 char *member_file_name = adjust_relative_path (file_name,
378 name, namelen);
379 if (member_file_name == NULL)
380 {
381 ret = 1;
382 break;
383 }
384
385 member_file = fopen (member_file_name, "r+b");
386 if (member_file == NULL)
387 {
388 error (_("Input file '%s' is not readable\n"),
389 member_file_name);
390 free (member_file_name);
391 ret = 1;
392 break;
393 }
394
395 archive_file_offset = arch.nested_member_origin;
396
397 ret |= process_object (qualified_name, member_file);
398
399 fclose (member_file);
400 free (member_file_name);
401 }
402 else if (is_thin_archive)
403 {
404 /* This is a proxy for a member of a nested archive. */
405 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
406
407 /* The nested archive file will have been opened and setup by
408 get_archive_member_name. */
409 if (fseek (nested_arch.file, archive_file_offset,
410 SEEK_SET) != 0)
411 {
412 error (_("%s: failed to seek to archive member\n"),
413 nested_arch.file_name);
414 ret = 1;
415 break;
416 }
417
418 ret |= process_object (qualified_name, nested_arch.file);
419 }
420 else
421 {
422 archive_file_offset = arch.next_arhdr_offset;
423 arch.next_arhdr_offset += archive_file_size;
424
425 ret |= process_object (qualified_name, file);
426 }
427
428 free (qualified_name);
429 }
430
431 out:
432 if (nested_arch.file != NULL)
433 fclose (nested_arch.file);
434 release_archive (&nested_arch);
435 release_archive (&arch);
436
437 return ret;
438 }
439
440 static int
441 check_file (const char *file_name, struct stat *statbuf_p)
442 {
443 struct stat statbuf;
444
445 if (statbuf_p == NULL)
446 statbuf_p = &statbuf;
447
448 if (stat (file_name, statbuf_p) < 0)
449 {
450 if (errno == ENOENT)
451 error (_("'%s': No such file\n"), file_name);
452 else
453 error (_("Could not locate '%s'. System error message: %s\n"),
454 file_name, strerror (errno));
455 return 1;
456 }
457
458 if (! S_ISREG (statbuf_p->st_mode))
459 {
460 error (_("'%s' is not an ordinary file\n"), file_name);
461 return 1;
462 }
463
464 return 0;
465 }
466
467 static int
468 process_file (const char *file_name)
469 {
470 FILE * file;
471 char armag[SARMAG];
472 int ret;
473
474 if (check_file (file_name, NULL))
475 return 1;
476
477 file = fopen (file_name, "r+b");
478 if (file == NULL)
479 {
480 error (_("Input file '%s' is not readable\n"), file_name);
481 return 1;
482 }
483
484 if (fread (armag, SARMAG, 1, file) != 1)
485 {
486 error (_("%s: Failed to read file's magic number\n"),
487 file_name);
488 fclose (file);
489 return 1;
490 }
491
492 if (memcmp (armag, ARMAG, SARMAG) == 0)
493 ret = process_archive (file_name, file, FALSE);
494 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
495 ret = process_archive (file_name, file, TRUE);
496 else
497 {
498 rewind (file);
499 archive_file_size = archive_file_offset = 0;
500 ret = process_object (file_name, file);
501 }
502
503 fclose (file);
504
505 return ret;
506 }
507
508 static const struct
509 {
510 int osabi;
511 const char *name;
512 }
513 osabis[] =
514 {
515 { ELFOSABI_NONE, "none" },
516 { ELFOSABI_HPUX, "HPUX" },
517 { ELFOSABI_NETBSD, "NetBSD" },
518 { ELFOSABI_GNU, "GNU" },
519 { ELFOSABI_GNU, "Linux" },
520 { ELFOSABI_SOLARIS, "Solaris" },
521 { ELFOSABI_AIX, "AIX" },
522 { ELFOSABI_IRIX, "Irix" },
523 { ELFOSABI_FREEBSD, "FreeBSD" },
524 { ELFOSABI_TRU64, "TRU64" },
525 { ELFOSABI_MODESTO, "Modesto" },
526 { ELFOSABI_OPENBSD, "OpenBSD" },
527 { ELFOSABI_OPENVMS, "OpenVMS" },
528 { ELFOSABI_NSK, "NSK" },
529 { ELFOSABI_AROS, "AROS" },
530 { ELFOSABI_FENIXOS, "FenixOS" }
531 };
532
533 /* Return ELFOSABI_XXX for an OSABI string, OSABI. */
534
535 static int
536 elf_osabi (const char *osabi)
537 {
538 unsigned int i;
539
540 for (i = 0; i < ARRAY_SIZE (osabis); i++)
541 if (strcasecmp (osabi, osabis[i].name) == 0)
542 return osabis[i].osabi;
543
544 error (_("Unknown OSABI: %s\n"), osabi);
545
546 return -1;
547 }
548
549 /* Return EM_XXX for a machine string, MACH. */
550
551 static int
552 elf_machine (const char *mach)
553 {
554 if (strcasecmp (mach, "l1om") == 0)
555 return EM_L1OM;
556 if (strcasecmp (mach, "k1om") == 0)
557 return EM_K1OM;
558 if (strcasecmp (mach, "x86_64") == 0)
559 return EM_X86_64;
560 if (strcasecmp (mach, "x86-64") == 0)
561 return EM_X86_64;
562 if (strcasecmp (mach, "none") == 0)
563 return EM_NONE;
564
565 error (_("Unknown machine type: %s\n"), mach);
566
567 return -1;
568 }
569
570 /* Return ELF class for a machine type, MACH. */
571
572 static int
573 elf_class (int mach)
574 {
575 switch (mach)
576 {
577 case EM_L1OM:
578 case EM_K1OM:
579 case EM_X86_64:
580 return ELFCLASS64;
581 case EM_NONE:
582 return ELFCLASSNONE;
583 default:
584 error (_("Unknown machine type: %d\n"), mach);
585 return -1;
586 }
587 }
588
589 /* Return ET_XXX for a type string, TYPE. */
590
591 static int
592 elf_type (const char *type)
593 {
594 if (strcasecmp (type, "rel") == 0)
595 return ET_REL;
596 if (strcasecmp (type, "exec") == 0)
597 return ET_EXEC;
598 if (strcasecmp (type, "dyn") == 0)
599 return ET_DYN;
600 if (strcasecmp (type, "none") == 0)
601 return ET_NONE;
602
603 error (_("Unknown type: %s\n"), type);
604
605 return -1;
606 }
607
608 enum command_line_switch
609 {
610 OPTION_INPUT_MACH = 150,
611 OPTION_OUTPUT_MACH,
612 OPTION_INPUT_TYPE,
613 OPTION_OUTPUT_TYPE,
614 OPTION_INPUT_OSABI,
615 OPTION_OUTPUT_OSABI
616 };
617
618 static struct option options[] =
619 {
620 {"input-mach", required_argument, 0, OPTION_INPUT_MACH},
621 {"output-mach", required_argument, 0, OPTION_OUTPUT_MACH},
622 {"input-type", required_argument, 0, OPTION_INPUT_TYPE},
623 {"output-type", required_argument, 0, OPTION_OUTPUT_TYPE},
624 {"input-osabi", required_argument, 0, OPTION_INPUT_OSABI},
625 {"output-osabi", required_argument, 0, OPTION_OUTPUT_OSABI},
626 {"version", no_argument, 0, 'v'},
627 {"help", no_argument, 0, 'h'},
628 {0, no_argument, 0, 0}
629 };
630
631 static void
632 usage (FILE *stream, int exit_status)
633 {
634 fprintf (stream, _("Usage: %s <option(s)> elffile(s)\n"),
635 program_name);
636 fprintf (stream, _(" Update the ELF header of ELF files\n"));
637 fprintf (stream, _(" The options are:\n"));
638 fprintf (stream, _("\
639 --input-mach <machine> Set input machine type to <machine>\n\
640 --output-mach <machine> Set output machine type to <machine>\n\
641 --input-type <type> Set input file type to <type>\n\
642 --output-type <type> Set output file type to <type>\n\
643 --input-osabi <osabi> Set input OSABI to <osabi>\n\
644 --output-osabi <osabi> Set output OSABI to <osabi>\n\
645 -h --help Display this information\n\
646 -v --version Display the version number of %s\n\
647 "),
648 program_name);
649 if (REPORT_BUGS_TO[0] && exit_status == 0)
650 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
651 exit (exit_status);
652 }
653
654 int
655 main (int argc, char ** argv)
656 {
657 int c, status;
658
659 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
660 setlocale (LC_MESSAGES, "");
661 #endif
662 #if defined (HAVE_SETLOCALE)
663 setlocale (LC_CTYPE, "");
664 #endif
665 bindtextdomain (PACKAGE, LOCALEDIR);
666 textdomain (PACKAGE);
667
668 expandargv (&argc, &argv);
669
670 while ((c = getopt_long (argc, argv, "hv",
671 options, (int *) 0)) != EOF)
672 {
673 switch (c)
674 {
675 case OPTION_INPUT_MACH:
676 input_elf_machine = elf_machine (optarg);
677 if (input_elf_machine < 0)
678 return 1;
679 input_elf_class = elf_class (input_elf_machine);
680 if (input_elf_class < 0)
681 return 1;
682 break;
683
684 case OPTION_OUTPUT_MACH:
685 output_elf_machine = elf_machine (optarg);
686 if (output_elf_machine < 0)
687 return 1;
688 break;
689
690 case OPTION_INPUT_TYPE:
691 input_elf_type = elf_type (optarg);
692 if (input_elf_type < 0)
693 return 1;
694 break;
695
696 case OPTION_OUTPUT_TYPE:
697 output_elf_type = elf_type (optarg);
698 if (output_elf_type < 0)
699 return 1;
700 break;
701
702 case OPTION_INPUT_OSABI:
703 input_elf_osabi = elf_osabi (optarg);
704 if (input_elf_osabi < 0)
705 return 1;
706 break;
707
708 case OPTION_OUTPUT_OSABI:
709 output_elf_osabi = elf_osabi (optarg);
710 if (output_elf_osabi < 0)
711 return 1;
712 break;
713
714 case 'h':
715 usage (stdout, 0);
716
717 case 'v':
718 print_version (program_name);
719 break;
720
721 default:
722 usage (stderr, 1);
723 }
724 }
725
726 if (optind == argc
727 || (output_elf_machine == -1
728 && output_elf_type == -1
729 && output_elf_osabi == -1))
730 usage (stderr, 1);
731
732 status = 0;
733 while (optind < argc)
734 status |= process_file (argv[optind++]);
735
736 return status;
737 }