1 /* elfedit.c -- Update the ELF header of an ELF format file
3 Free Software Foundation, Inc.
5 This file is part of GNU Binutils.
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.
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.
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
28 /* Define BFD64 here, even if our default architecture is 32 bit ELF
29 as this will allow us to read in and parse 64bit and 32bit ELF files.
30 Only do this if we believe that the compiler can support a 64 bit
31 data type. For now we only rely on GCC being able to do this. */
38 #include "elf/common.h"
39 #include "elf/external.h"
40 #include "elf/internal.h"
46 #include "libiberty.h"
47 #include "safe-ctype.h"
48 #include "filenames.h"
50 char * program_name = "elfedit";
51 static long archive_file_offset;
52 static unsigned long archive_file_size;
53 static Elf_Internal_Ehdr elf_header;
54 static Elf32_External_Ehdr ehdr32;
55 static Elf64_External_Ehdr ehdr64;
56 static int input_elf_machine = -1;
57 static int output_elf_machine = -1;
58 static int input_elf_type = -1;
59 static int output_elf_type = -1;
60 static int input_elf_class = -1;
62 #define streq(a,b) (strcmp ((a), (b)) == 0)
63 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
64 #define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0)
67 non_fatal (const char *message, ...)
71 va_start (args, message);
72 fprintf (stderr, _("%s: Error: "), program_name);
73 vfprintf (stderr, message, args);
77 #define BYTE_GET(field) byte_get (field, sizeof (field))
78 #define BYTE_PUT(field, val) byte_put (field, val, sizeof (field))
80 static bfd_vma (*byte_get) (unsigned char *, int);
81 static void (*byte_put) (unsigned char *, bfd_vma, int);
84 byte_get_little_endian (unsigned char *field, int size)
92 return ((unsigned int) (field[0]))
93 | (((unsigned int) (field[1])) << 8);
96 return ((unsigned long) (field[0]))
97 | (((unsigned long) (field[1])) << 8)
98 | (((unsigned long) (field[2])) << 16)
99 | (((unsigned long) (field[3])) << 24);
102 if (sizeof (bfd_vma) == 8)
103 return ((bfd_vma) (field[0]))
104 | (((bfd_vma) (field[1])) << 8)
105 | (((bfd_vma) (field[2])) << 16)
106 | (((bfd_vma) (field[3])) << 24)
107 | (((bfd_vma) (field[4])) << 32)
108 | (((bfd_vma) (field[5])) << 40)
109 | (((bfd_vma) (field[6])) << 48)
110 | (((bfd_vma) (field[7])) << 56);
111 else if (sizeof (bfd_vma) == 4)
112 /* We want to extract data from an 8 byte wide field and
113 place it into a 4 byte wide field. Since this is a little
114 endian source we can just use the 4 byte extraction code. */
115 return ((unsigned long) (field[0]))
116 | (((unsigned long) (field[1])) << 8)
117 | (((unsigned long) (field[2])) << 16)
118 | (((unsigned long) (field[3])) << 24);
121 non_fatal (_("Unhandled data length: %d\n"), size);
127 byte_get_big_endian (unsigned char *field, int size)
135 return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);
138 return ((unsigned long) (field[3]))
139 | (((unsigned long) (field[2])) << 8)
140 | (((unsigned long) (field[1])) << 16)
141 | (((unsigned long) (field[0])) << 24);
144 if (sizeof (bfd_vma) == 8)
145 return ((bfd_vma) (field[7]))
146 | (((bfd_vma) (field[6])) << 8)
147 | (((bfd_vma) (field[5])) << 16)
148 | (((bfd_vma) (field[4])) << 24)
149 | (((bfd_vma) (field[3])) << 32)
150 | (((bfd_vma) (field[2])) << 40)
151 | (((bfd_vma) (field[1])) << 48)
152 | (((bfd_vma) (field[0])) << 56);
153 else if (sizeof (bfd_vma) == 4)
155 /* Although we are extracing data from an 8 byte wide field,
156 we are returning only 4 bytes of data. */
158 return ((unsigned long) (field[3]))
159 | (((unsigned long) (field[2])) << 8)
160 | (((unsigned long) (field[1])) << 16)
161 | (((unsigned long) (field[0])) << 24);
165 non_fatal (_("Unhandled data length: %d\n"), size);
171 byte_put_little_endian (unsigned char * field, bfd_vma value, int size)
176 field[7] = (((value >> 24) >> 24) >> 8) & 0xff;
177 field[6] = ((value >> 24) >> 24) & 0xff;
178 field[5] = ((value >> 24) >> 16) & 0xff;
179 field[4] = ((value >> 24) >> 8) & 0xff;
182 field[3] = (value >> 24) & 0xff;
183 field[2] = (value >> 16) & 0xff;
186 field[1] = (value >> 8) & 0xff;
189 field[0] = value & 0xff;
193 non_fatal (_("Unhandled data length: %d\n"), size);
199 byte_put_big_endian (unsigned char * field, bfd_vma value, int size)
204 field[7] = value & 0xff;
205 field[6] = (value >> 8) & 0xff;
206 field[5] = (value >> 16) & 0xff;
207 field[4] = (value >> 24) & 0xff;
212 field[3] = value & 0xff;
213 field[2] = (value >> 8) & 0xff;
217 field[1] = value & 0xff;
221 field[0] = value & 0xff;
225 non_fatal (_("Unhandled data length: %d\n"), size);
231 update_elf_header (const char *file_name, FILE *file)
233 int class, machine, type, status;
235 if (elf_header.e_ident[EI_MAG0] != ELFMAG0
236 || elf_header.e_ident[EI_MAG1] != ELFMAG1
237 || elf_header.e_ident[EI_MAG2] != ELFMAG2
238 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
241 (_("%s: Not an ELF file - wrong magic bytes at the start\n"),
246 if (elf_header.e_ident[EI_VERSION] != EV_CURRENT)
249 (_("%s: Unsupported EI_VERSION: %d is not %d\n"),
250 file_name, elf_header.e_ident[EI_VERSION],
255 /* Return if e_machine is the same as output_elf_machine. */
256 if (output_elf_machine == elf_header.e_machine)
259 class = elf_header.e_ident[EI_CLASS];
261 /* Skip if class doesn't match. */
262 if (input_elf_class != -1 && class != input_elf_class)
265 (_("%s: Unmatched EI_CLASS: %d is not %d\n"),
266 file_name, class, input_elf_class);
270 machine = elf_header.e_machine;
272 /* Skip if e_machine doesn't match. */
273 if (input_elf_machine != -1 && machine != input_elf_machine)
276 (_("%s: Unmatched e_machine: %d is not %d\n"),
277 file_name, machine, input_elf_machine);
281 type = elf_header.e_type;
283 /* Skip if e_type doesn't match. */
284 if (input_elf_type != -1 && type != input_elf_type)
287 (_("%s: Unmatched e_type: %d is not %d\n"),
288 file_name, type, input_elf_type);
292 /* Update e_machine and e_type. */
296 /* We should never get here. */
300 if (output_elf_machine != -1)
301 BYTE_PUT (ehdr32.e_machine, output_elf_machine);
302 if (output_elf_type != -1)
303 BYTE_PUT (ehdr32.e_type, output_elf_type);
304 status = fwrite (&ehdr32, sizeof (ehdr32), 1, file) == 1;
307 if (output_elf_machine != -1)
308 BYTE_PUT (ehdr64.e_machine, output_elf_machine);
309 if (output_elf_type != -1)
310 BYTE_PUT (ehdr64.e_type, output_elf_type);
311 status = fwrite (&ehdr64, sizeof (ehdr64), 1, file) == 1;
316 non_fatal (_("%s: Failed to update ELF header: %s\n"),
317 file_name, strerror (errno));
323 get_file_header (FILE * file)
325 /* Read in the identity array. */
326 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
329 /* Determine how to read the rest of the header. */
330 switch (elf_header.e_ident[EI_DATA])
332 default: /* fall through */
333 case ELFDATANONE: /* fall through */
335 byte_get = byte_get_little_endian;
336 byte_put = byte_put_little_endian;
339 byte_get = byte_get_big_endian;
340 byte_put = byte_put_big_endian;
344 /* Read in the rest of the header. For now we only support 32 bit
345 and 64 bit ELF files. */
346 switch (elf_header.e_ident[EI_CLASS])
349 non_fatal (_("Unsupported EI_CLASS: %d\n"),
350 elf_header.e_ident[EI_CLASS]);
354 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT,
358 elf_header.e_type = BYTE_GET (ehdr32.e_type);
359 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
360 elf_header.e_version = BYTE_GET (ehdr32.e_version);
361 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
362 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
363 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
364 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
365 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
366 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
367 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
368 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
369 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
370 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
372 memcpy (&ehdr32, &elf_header, EI_NIDENT);
376 /* If we have been compiled with sizeof (bfd_vma) == 4, then
377 we will not be able to cope with the 64bit data found in
378 64 ELF files. Detect this now and abort before we start
379 overwriting things. */
380 if (sizeof (bfd_vma) < 8)
382 non_fatal (_("This executable has been built without support for a\n\
383 64 bit data type and so it cannot process 64 bit ELF files.\n"));
387 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT,
391 elf_header.e_type = BYTE_GET (ehdr64.e_type);
392 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
393 elf_header.e_version = BYTE_GET (ehdr64.e_version);
394 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
395 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
396 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
397 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
398 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
399 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
400 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
401 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
402 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
403 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
405 memcpy (&ehdr64, &elf_header, EI_NIDENT);
411 /* Process one ELF object file according to the command line options.
412 This file may actually be stored in an archive. The file is
413 positioned at the start of the ELF object. */
416 process_object (const char *file_name, FILE *file)
418 /* Rememeber where we are. */
419 long offset = ftell (file);
421 if (! get_file_header (file))
423 non_fatal (_("%s: Failed to read ELF header\n"), file_name);
427 /* Go to the position of the ELF header. */
428 if (fseek (file, offset, SEEK_SET) != 0)
430 non_fatal (_("%s: Failed to seek to ELF header\n"), file_name);
433 if (! update_elf_header (file_name, file))
439 /* Return the path name for a proxy entry in a thin archive, adjusted relative
440 to the path name of the thin archive itself if necessary. Always returns
441 a pointer to malloc'ed memory. */
444 adjust_relative_path (const char *file_name, char * name, int name_len)
446 char * member_file_name;
447 const char * base_name = lbasename (file_name);
449 /* This is a proxy entry for a thin archive member.
450 If the extended name table contains an absolute path
451 name, or if the archive is in the current directory,
452 use the path name as given. Otherwise, we need to
453 find the member relative to the directory where the
454 archive is located. */
455 if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
457 member_file_name = malloc (name_len + 1);
458 if (member_file_name == NULL)
460 non_fatal (_("Out of memory\n"));
463 memcpy (member_file_name, name, name_len);
464 member_file_name[name_len] = '\0';
468 /* Concatenate the path components of the archive file name
469 to the relative path name from the extended name table. */
470 size_t prefix_len = base_name - file_name;
471 member_file_name = malloc (prefix_len + name_len + 1);
472 if (member_file_name == NULL)
474 non_fatal (_("Out of memory\n"));
477 memcpy (member_file_name, file_name, prefix_len);
478 memcpy (member_file_name + prefix_len, name, name_len);
479 member_file_name[prefix_len + name_len] = '\0';
481 return member_file_name;
484 /* Structure to hold information about an archive file. */
488 char * file_name; /* Archive file name. */
489 FILE * file; /* Open file descriptor. */
490 unsigned long index_num; /* Number of symbols in table. */
491 unsigned long * index_array; /* The array of member offsets. */
492 char * sym_table; /* The symbol table. */
493 unsigned long sym_size; /* Size of the symbol table. */
494 char * longnames; /* The long file names table. */
495 unsigned long longnames_size; /* Size of the long file names table. */
496 unsigned long nested_member_origin; /* Origin in the nested archive of the current member. */
497 unsigned long next_arhdr_offset; /* Offset of the next archive header. */
498 bfd_boolean is_thin_archive; /* TRUE if this is a thin archive. */
499 struct ar_hdr arhdr; /* Current archive header. */
502 /* Read the symbol table and long-name table from an archive. */
505 setup_archive (struct archive_info * arch, const char * file_name,
506 FILE * file, bfd_boolean is_thin_archive)
511 arch->file_name = strdup (file_name);
514 arch->index_array = NULL;
515 arch->sym_table = NULL;
517 arch->longnames = NULL;
518 arch->longnames_size = 0;
519 arch->nested_member_origin = 0;
520 arch->is_thin_archive = is_thin_archive;
521 arch->next_arhdr_offset = SARMAG;
523 /* Read the first archive member header. */
524 if (fseek (file, SARMAG, SEEK_SET) != 0)
526 non_fatal (_("%s: failed to seek to first archive header\n"),
530 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
531 if (got != sizeof arch->arhdr)
536 non_fatal (_("%s: failed to read archive header\n"), file_name);
540 /* See if this is the archive symbol table. */
541 if (const_strneq (arch->arhdr.ar_name, "/ ")
542 || const_strneq (arch->arhdr.ar_name, "/SYM64/ "))
544 size = strtoul (arch->arhdr.ar_size, NULL, 10);
545 size = size + (size & 1);
547 arch->next_arhdr_offset += sizeof arch->arhdr + size;
549 if (fseek (file, size, SEEK_CUR) != 0)
551 non_fatal (_("%s: failed to skip archive symbol table\n"),
556 /* Read the next archive header. */
557 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
558 if (got != sizeof arch->arhdr)
562 non_fatal (_("%s: failed to read archive header following archive index\n"),
568 if (const_strneq (arch->arhdr.ar_name, "// "))
570 /* This is the archive string table holding long member names. */
571 arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
572 arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
574 arch->longnames = malloc (arch->longnames_size);
575 if (arch->longnames == NULL)
577 non_fatal (_("Out of memory reading long symbol names in archive\n"));
581 if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
583 free (arch->longnames);
584 arch->longnames = NULL;
585 non_fatal (_("%s: failed to read long symbol name string table\n")
590 if ((arch->longnames_size & 1) != 0)
597 /* Release the memory used for the archive information. */
600 release_archive (struct archive_info * arch)
602 if (arch->file_name != NULL)
603 free (arch->file_name);
604 if (arch->index_array != NULL)
605 free (arch->index_array);
606 if (arch->sym_table != NULL)
607 free (arch->sym_table);
608 if (arch->longnames != NULL)
609 free (arch->longnames);
612 /* Open and setup a nested archive, if not already open. */
615 setup_nested_archive (struct archive_info * nested_arch, char * member_file_name)
619 /* Have we already setup this archive? */
620 if (nested_arch->file_name != NULL
621 && streq (nested_arch->file_name, member_file_name))
624 /* Close previous file and discard cached information. */
625 if (nested_arch->file != NULL)
626 fclose (nested_arch->file);
627 release_archive (nested_arch);
629 member_file = fopen (member_file_name, "r+b");
630 if (member_file == NULL)
632 return setup_archive (nested_arch, member_file_name, member_file,
637 get_archive_member_name_at (struct archive_info * arch,
638 unsigned long offset,
639 struct archive_info * nested_arch);
641 /* Get the name of an archive member from the current archive header.
642 For simple names, this will modify the ar_name field of the current
643 archive header. For long names, it will return a pointer to the
644 longnames table. For nested archives, it will open the nested archive
645 and get the name recursively. NESTED_ARCH is a single-entry cache so
646 we don't keep rereading the same information from a nested archive. */
649 get_archive_member_name (struct archive_info * arch,
650 struct archive_info * nested_arch)
654 if (arch->arhdr.ar_name[0] == '/')
656 /* We have a long name. */
658 char * member_file_name;
661 arch->nested_member_origin = 0;
662 k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
663 if (arch->is_thin_archive && endp != NULL && * endp == ':')
664 arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
666 while ((j < arch->longnames_size)
667 && (arch->longnames[j] != '\n')
668 && (arch->longnames[j] != '\0'))
670 if (arch->longnames[j-1] == '/')
672 arch->longnames[j] = '\0';
674 if (!arch->is_thin_archive || arch->nested_member_origin == 0)
675 return arch->longnames + k;
677 /* This is a proxy for a member of a nested archive.
678 Find the name of the member in that archive. */
679 member_file_name = adjust_relative_path (arch->file_name,
682 if (member_file_name != NULL
683 && setup_nested_archive (nested_arch, member_file_name) == 0
684 && (member_name = get_archive_member_name_at (nested_arch,
685 arch->nested_member_origin,
688 free (member_file_name);
691 free (member_file_name);
693 /* Last resort: just return the name of the nested archive. */
694 return arch->longnames + k;
697 /* We have a normal (short) name. */
699 while ((arch->arhdr.ar_name[j] != '/') && (j < 16))
701 arch->arhdr.ar_name[j] = '\0';
702 return arch->arhdr.ar_name;
705 /* Get the name of an archive member at a given OFFSET within an
709 get_archive_member_name_at (struct archive_info * arch,
710 unsigned long offset,
711 struct archive_info * nested_arch)
715 if (fseek (arch->file, offset, SEEK_SET) != 0)
717 non_fatal (_("%s: failed to seek to next file name\n"),
721 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
722 if (got != sizeof arch->arhdr)
724 non_fatal (_("%s: failed to read archive header\n"),
728 if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
730 non_fatal (_("%s: did not find a valid archive header\n"),
735 return get_archive_member_name (arch, nested_arch);
738 /* Construct a string showing the name of the archive member, qualified
739 with the name of the containing archive file. For thin archives, we
740 use square brackets to denote the indirection. For nested archives,
741 we show the qualified name of the external member inside the square
742 brackets (e.g., "thin.a[normal.a(foo.o)]"). */
745 make_qualified_name (struct archive_info * arch,
746 struct archive_info * nested_arch,
752 len = strlen (arch->file_name) + strlen (member_name) + 3;
753 if (arch->is_thin_archive && arch->nested_member_origin != 0)
754 len += strlen (nested_arch->file_name) + 2;
759 non_fatal (_("Out of memory\n"));
763 if (arch->is_thin_archive && arch->nested_member_origin != 0)
764 snprintf (name, len, "%s[%s(%s)]", arch->file_name, nested_arch->file_name, member_name);
765 else if (arch->is_thin_archive)
766 snprintf (name, len, "%s[%s]", arch->file_name, member_name);
768 snprintf (name, len, "%s(%s)", arch->file_name, member_name);
773 /* Process an ELF archive.
774 On entry the file is positioned just after the ARMAG string. */
777 process_archive (const char * file_name, FILE * file,
778 bfd_boolean is_thin_archive)
780 struct archive_info arch;
781 struct archive_info nested_arch;
783 size_t file_name_size;
786 /* The ARCH structure is used to hold information about this archive. */
787 arch.file_name = NULL;
789 arch.index_array = NULL;
790 arch.sym_table = NULL;
791 arch.longnames = NULL;
793 /* The NESTED_ARCH structure is used as a single-item cache of information
794 about a nested archive (when members of a thin archive reside within
795 another regular archive file). */
796 nested_arch.file_name = NULL;
797 nested_arch.file = NULL;
798 nested_arch.index_array = NULL;
799 nested_arch.sym_table = NULL;
800 nested_arch.longnames = NULL;
802 if (setup_archive (&arch, file_name, file, is_thin_archive) != 0)
808 file_name_size = strlen (file_name);
815 char * qualified_name;
817 /* Read the next archive header. */
818 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
820 non_fatal (_("%s: failed to seek to next archive header\n"),
824 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
825 if (got != sizeof arch.arhdr)
829 non_fatal (_("%s: failed to read archive header\n"),
834 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
836 non_fatal (_("%s: did not find a valid archive header\n"),
842 arch.next_arhdr_offset += sizeof arch.arhdr;
844 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
845 if (archive_file_size & 01)
848 name = get_archive_member_name (&arch, &nested_arch);
851 non_fatal (_("%s: bad archive file name\n"), file_name);
855 namelen = strlen (name);
857 qualified_name = make_qualified_name (&arch, &nested_arch, name);
858 if (qualified_name == NULL)
860 non_fatal (_("%s: bad archive file name\n"), file_name);
865 if (is_thin_archive && arch.nested_member_origin == 0)
867 /* This is a proxy for an external member of a thin archive. */
869 char *member_file_name = adjust_relative_path (file_name,
871 if (member_file_name == NULL)
877 member_file = fopen (member_file_name, "r+b");
878 if (member_file == NULL)
880 non_fatal (_("Input file '%s' is not readable\n"),
882 free (member_file_name);
887 archive_file_offset = arch.nested_member_origin;
889 ret |= process_object (qualified_name, member_file);
891 fclose (member_file);
892 free (member_file_name);
894 else if (is_thin_archive)
896 /* This is a proxy for a member of a nested archive. */
897 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
899 /* The nested archive file will have been opened and setup by
900 get_archive_member_name. */
901 if (fseek (nested_arch.file, archive_file_offset,
904 non_fatal (_("%s: failed to seek to archive member\n"),
905 nested_arch.file_name);
910 ret |= process_object (qualified_name, nested_arch.file);
914 archive_file_offset = arch.next_arhdr_offset;
915 arch.next_arhdr_offset += archive_file_size;
917 ret |= process_object (qualified_name, file);
920 free (qualified_name);
924 if (nested_arch.file != NULL)
925 fclose (nested_arch.file);
926 release_archive (&nested_arch);
927 release_archive (&arch);
933 check_file (const char *file_name, struct stat *statbuf_p)
937 if (statbuf_p == NULL)
938 statbuf_p = &statbuf;
940 if (stat (file_name, statbuf_p) < 0)
943 non_fatal (_("'%s': No such file\n"), file_name);
945 non_fatal (_("Could not locate '%s'. System error message: %s\n"),
946 file_name, strerror (errno));
950 if (! S_ISREG (statbuf_p->st_mode))
952 non_fatal (_("'%s' is not an ordinary file\n"), file_name);
960 process_file (const char *file_name)
966 if (check_file (file_name, NULL))
969 file = fopen (file_name, "r+b");
972 non_fatal (_("Input file '%s' is not readable\n"), file_name);
976 if (fread (armag, SARMAG, 1, file) != 1)
978 non_fatal (_("%s: Failed to read file's magic number\n"),
984 if (memcmp (armag, ARMAG, SARMAG) == 0)
985 ret = process_archive (file_name, file, FALSE);
986 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
987 ret = process_archive (file_name, file, TRUE);
991 archive_file_size = archive_file_offset = 0;
992 ret = process_object (file_name, file);
1000 /* Return EM_XXX for a machine string, MACH. */
1003 elf_machine (const char *mach)
1005 if (strcasecmp (mach, "l1om") == 0)
1007 if (strcasecmp (mach, "x86_64") == 0)
1009 if (strcasecmp (mach, "x86-64") == 0)
1011 if (strcasecmp (mach, "none") == 0)
1014 non_fatal (_("Unknown machine type: %s\n"), mach);
1019 /* Return ELF class for a machine type, MACH. */
1022 elf_class (int mach)
1030 return ELFCLASSNONE;
1032 non_fatal (_("Unknown machine type: %d\n"), mach);
1037 /* Return ET_XXX for a type string, TYPE. */
1040 elf_type (const char *type)
1042 if (strcasecmp (type, "rel") == 0)
1044 if (strcasecmp (type, "exec") == 0)
1046 if (strcasecmp (type, "dyn") == 0)
1048 if (strcasecmp (type, "none") == 0)
1051 non_fatal (_("Unknown type: %s\n"), type);
1056 enum command_line_switch
1058 OPTION_INPUT_MACH = 150,
1064 static struct option options[] =
1066 {"input-mach", required_argument, 0, OPTION_INPUT_MACH},
1067 {"output-mach", required_argument, 0, OPTION_OUTPUT_MACH},
1068 {"input-type", required_argument, 0, OPTION_INPUT_TYPE},
1069 {"output-type", required_argument, 0, OPTION_OUTPUT_TYPE},
1070 {"version", no_argument, 0, 'v'},
1071 {"help", no_argument, 0, 'h'},
1072 {0, no_argument, 0, 0}
1076 usage (FILE *stream, int exit_status)
1078 fprintf (stream, _("Usage: %s [option(s)] {--output-mach <machine>|--output-type <type>} elffile(s)\n"),
1080 fprintf (stream, _(" Update the ELF header of ELF files\n"));
1081 fprintf (stream, _(" The options are:\n"));
1082 fprintf (stream, _("\
1083 --input-mach <machine> Set input machine type to <machine>\n\
1084 --output-mach <machine> Set output machine type to <machine>\n\
1085 --input-type <type> Set input file type to <type>\n\
1086 --output-type <type> Set output file type to <type>\n\
1087 -h --help Display this information\n\
1088 -v --version Display the version number of %s\n\
1091 if (REPORT_BUGS_TO[0] && exit_status == 0)
1092 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
1097 main (int argc, char ** argv)
1101 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
1102 setlocale (LC_MESSAGES, "");
1104 #if defined (HAVE_SETLOCALE)
1105 setlocale (LC_CTYPE, "");
1107 bindtextdomain (PACKAGE, LOCALEDIR);
1108 textdomain (PACKAGE);
1110 expandargv (&argc, &argv);
1112 while ((c = getopt_long (argc, argv, "hv",
1113 options, (int *) 0)) != EOF)
1117 case OPTION_INPUT_MACH:
1118 input_elf_machine = elf_machine (optarg);
1119 if (input_elf_machine < 0)
1121 input_elf_class = elf_class (input_elf_machine);
1122 if (input_elf_class < 0)
1126 case OPTION_OUTPUT_MACH:
1127 output_elf_machine = elf_machine (optarg);
1128 if (output_elf_machine < 0)
1132 case OPTION_INPUT_TYPE:
1133 input_elf_type = elf_type (optarg);
1134 if (input_elf_type < 0)
1138 case OPTION_OUTPUT_TYPE:
1139 output_elf_type = elf_type (optarg);
1140 if (output_elf_type < 0)
1148 print_version (program_name);
1157 || (output_elf_machine == -1
1158 && output_elf_type == -1))
1162 while (optind < argc)
1163 status |= process_file (argv[optind++]);