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