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_class
= -1;
60 #define streq(a,b) (strcmp ((a), (b)) == 0)
61 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
62 #define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0)
65 non_fatal (const char *message
, ...)
69 va_start (args
, message
);
70 fprintf (stderr
, _("%s: Error: "), program_name
);
71 vfprintf (stderr
, message
, args
);
75 #define BYTE_GET(field) byte_get (field, sizeof (field))
76 #define BYTE_PUT(field, val) byte_put (field, val, sizeof (field))
78 static bfd_vma (*byte_get
) (unsigned char *, int);
79 static void (*byte_put
) (unsigned char *, bfd_vma
, int);
82 byte_get_little_endian (unsigned char *field
, int size
)
90 return ((unsigned int) (field
[0]))
91 | (((unsigned int) (field
[1])) << 8);
94 return ((unsigned long) (field
[0]))
95 | (((unsigned long) (field
[1])) << 8)
96 | (((unsigned long) (field
[2])) << 16)
97 | (((unsigned long) (field
[3])) << 24);
100 if (sizeof (bfd_vma
) == 8)
101 return ((bfd_vma
) (field
[0]))
102 | (((bfd_vma
) (field
[1])) << 8)
103 | (((bfd_vma
) (field
[2])) << 16)
104 | (((bfd_vma
) (field
[3])) << 24)
105 | (((bfd_vma
) (field
[4])) << 32)
106 | (((bfd_vma
) (field
[5])) << 40)
107 | (((bfd_vma
) (field
[6])) << 48)
108 | (((bfd_vma
) (field
[7])) << 56);
109 else if (sizeof (bfd_vma
) == 4)
110 /* We want to extract data from an 8 byte wide field and
111 place it into a 4 byte wide field. Since this is a little
112 endian source we can just use the 4 byte extraction code. */
113 return ((unsigned long) (field
[0]))
114 | (((unsigned long) (field
[1])) << 8)
115 | (((unsigned long) (field
[2])) << 16)
116 | (((unsigned long) (field
[3])) << 24);
119 non_fatal (_("Unhandled data length: %d\n"), size
);
125 byte_get_big_endian (unsigned char *field
, int size
)
133 return ((unsigned int) (field
[1])) | (((int) (field
[0])) << 8);
136 return ((unsigned long) (field
[3]))
137 | (((unsigned long) (field
[2])) << 8)
138 | (((unsigned long) (field
[1])) << 16)
139 | (((unsigned long) (field
[0])) << 24);
142 if (sizeof (bfd_vma
) == 8)
143 return ((bfd_vma
) (field
[7]))
144 | (((bfd_vma
) (field
[6])) << 8)
145 | (((bfd_vma
) (field
[5])) << 16)
146 | (((bfd_vma
) (field
[4])) << 24)
147 | (((bfd_vma
) (field
[3])) << 32)
148 | (((bfd_vma
) (field
[2])) << 40)
149 | (((bfd_vma
) (field
[1])) << 48)
150 | (((bfd_vma
) (field
[0])) << 56);
151 else if (sizeof (bfd_vma
) == 4)
153 /* Although we are extracing data from an 8 byte wide field,
154 we are returning only 4 bytes of data. */
156 return ((unsigned long) (field
[3]))
157 | (((unsigned long) (field
[2])) << 8)
158 | (((unsigned long) (field
[1])) << 16)
159 | (((unsigned long) (field
[0])) << 24);
163 non_fatal (_("Unhandled data length: %d\n"), size
);
169 byte_put_little_endian (unsigned char * field
, bfd_vma value
, int size
)
174 field
[7] = (((value
>> 24) >> 24) >> 8) & 0xff;
175 field
[6] = ((value
>> 24) >> 24) & 0xff;
176 field
[5] = ((value
>> 24) >> 16) & 0xff;
177 field
[4] = ((value
>> 24) >> 8) & 0xff;
180 field
[3] = (value
>> 24) & 0xff;
181 field
[2] = (value
>> 16) & 0xff;
184 field
[1] = (value
>> 8) & 0xff;
187 field
[0] = value
& 0xff;
191 non_fatal (_("Unhandled data length: %d\n"), size
);
197 byte_put_big_endian (unsigned char * field
, bfd_vma value
, int size
)
202 field
[7] = value
& 0xff;
203 field
[6] = (value
>> 8) & 0xff;
204 field
[5] = (value
>> 16) & 0xff;
205 field
[4] = (value
>> 24) & 0xff;
210 field
[3] = value
& 0xff;
211 field
[2] = (value
>> 8) & 0xff;
215 field
[1] = value
& 0xff;
219 field
[0] = value
& 0xff;
223 non_fatal (_("Unhandled data length: %d\n"), size
);
229 update_elf_header (const char *file_name
, FILE *file
)
233 if (elf_header
.e_ident
[EI_MAG0
] != ELFMAG0
234 || elf_header
.e_ident
[EI_MAG1
] != ELFMAG1
235 || elf_header
.e_ident
[EI_MAG2
] != ELFMAG2
236 || elf_header
.e_ident
[EI_MAG3
] != ELFMAG3
)
239 (_("%s: Not an ELF file - wrong magic bytes at the start\n"),
244 if (elf_header
.e_ident
[EI_VERSION
] != EV_CURRENT
)
247 (_("%s: Unsupported EI_VERSION: %d is not %d\n"),
248 file_name
, elf_header
.e_ident
[EI_VERSION
],
253 /* Skip if class doesn't match. */
254 if (input_elf_class
== -1)
255 input_elf_class
= elf_header
.e_ident
[EI_CLASS
];
257 if (elf_header
.e_ident
[EI_CLASS
] != input_elf_class
)
260 (_("%s: Unmatched EI_CLASS: %d is not %d\n"),
261 file_name
, elf_header
.e_ident
[EI_CLASS
],
266 /* Return if e_machine is the same as output_elf_machine. */
267 if (output_elf_machine
== elf_header
.e_machine
)
270 /* Skip if e_machine doesn't match. */
271 if (input_elf_machine
== -1)
272 input_elf_machine
= elf_header
.e_machine
;
273 else if (elf_header
.e_machine
!= input_elf_machine
)
276 (_("%s: Unmatched e_machine: %d is not %d\n"),
277 file_name
, elf_header
.e_machine
, input_elf_machine
);
281 /* Update e_machine. */
282 switch (input_elf_class
)
285 /* We should never get here. */
289 BYTE_PUT (ehdr32
.e_machine
, output_elf_machine
);
290 status
= fwrite (&ehdr32
, sizeof (ehdr32
), 1, file
) == 1;
293 BYTE_PUT (ehdr64
.e_machine
, output_elf_machine
);
294 status
= fwrite (&ehdr64
, sizeof (ehdr64
), 1, file
) == 1;
299 non_fatal (_("%s: Failed to update ELF header: %s\n"),
300 file_name
, strerror (errno
));
306 get_file_header (FILE * file
)
308 /* Read in the identity array. */
309 if (fread (elf_header
.e_ident
, EI_NIDENT
, 1, file
) != 1)
312 /* Determine how to read the rest of the header. */
313 switch (elf_header
.e_ident
[EI_DATA
])
315 default: /* fall through */
316 case ELFDATANONE
: /* fall through */
318 byte_get
= byte_get_little_endian
;
319 byte_put
= byte_put_little_endian
;
322 byte_get
= byte_get_big_endian
;
323 byte_put
= byte_put_big_endian
;
327 /* Read in the rest of the header. For now we only support 32 bit
328 and 64 bit ELF files. */
329 switch (elf_header
.e_ident
[EI_CLASS
])
332 non_fatal (_("Unsupported EI_CLASS: %d\n"),
333 elf_header
.e_ident
[EI_CLASS
]);
337 if (fread (ehdr32
.e_type
, sizeof (ehdr32
) - EI_NIDENT
,
341 elf_header
.e_type
= BYTE_GET (ehdr32
.e_type
);
342 elf_header
.e_machine
= BYTE_GET (ehdr32
.e_machine
);
343 elf_header
.e_version
= BYTE_GET (ehdr32
.e_version
);
344 elf_header
.e_entry
= BYTE_GET (ehdr32
.e_entry
);
345 elf_header
.e_phoff
= BYTE_GET (ehdr32
.e_phoff
);
346 elf_header
.e_shoff
= BYTE_GET (ehdr32
.e_shoff
);
347 elf_header
.e_flags
= BYTE_GET (ehdr32
.e_flags
);
348 elf_header
.e_ehsize
= BYTE_GET (ehdr32
.e_ehsize
);
349 elf_header
.e_phentsize
= BYTE_GET (ehdr32
.e_phentsize
);
350 elf_header
.e_phnum
= BYTE_GET (ehdr32
.e_phnum
);
351 elf_header
.e_shentsize
= BYTE_GET (ehdr32
.e_shentsize
);
352 elf_header
.e_shnum
= BYTE_GET (ehdr32
.e_shnum
);
353 elf_header
.e_shstrndx
= BYTE_GET (ehdr32
.e_shstrndx
);
355 memcpy (&ehdr32
, &elf_header
, EI_NIDENT
);
359 /* If we have been compiled with sizeof (bfd_vma) == 4, then
360 we will not be able to cope with the 64bit data found in
361 64 ELF files. Detect this now and abort before we start
362 overwriting things. */
363 if (sizeof (bfd_vma
) < 8)
365 non_fatal (_("This executable has been built without support for a\n\
366 64 bit data type and so it cannot process 64 bit ELF files.\n"));
370 if (fread (ehdr64
.e_type
, sizeof (ehdr64
) - EI_NIDENT
,
374 elf_header
.e_type
= BYTE_GET (ehdr64
.e_type
);
375 elf_header
.e_machine
= BYTE_GET (ehdr64
.e_machine
);
376 elf_header
.e_version
= BYTE_GET (ehdr64
.e_version
);
377 elf_header
.e_entry
= BYTE_GET (ehdr64
.e_entry
);
378 elf_header
.e_phoff
= BYTE_GET (ehdr64
.e_phoff
);
379 elf_header
.e_shoff
= BYTE_GET (ehdr64
.e_shoff
);
380 elf_header
.e_flags
= BYTE_GET (ehdr64
.e_flags
);
381 elf_header
.e_ehsize
= BYTE_GET (ehdr64
.e_ehsize
);
382 elf_header
.e_phentsize
= BYTE_GET (ehdr64
.e_phentsize
);
383 elf_header
.e_phnum
= BYTE_GET (ehdr64
.e_phnum
);
384 elf_header
.e_shentsize
= BYTE_GET (ehdr64
.e_shentsize
);
385 elf_header
.e_shnum
= BYTE_GET (ehdr64
.e_shnum
);
386 elf_header
.e_shstrndx
= BYTE_GET (ehdr64
.e_shstrndx
);
388 memcpy (&ehdr64
, &elf_header
, EI_NIDENT
);
394 /* Process one ELF object file according to the command line options.
395 This file may actually be stored in an archive. The file is
396 positioned at the start of the ELF object. */
399 process_object (const char *file_name
, FILE *file
)
401 /* Rememeber where we are. */
402 long offset
= ftell (file
);
404 if (! get_file_header (file
))
406 non_fatal (_("%s: Failed to read ELF header\n"), file_name
);
410 /* Go to the position of the ELF header. */
411 if (fseek (file
, offset
, SEEK_SET
) != 0)
413 non_fatal (_("%s: Failed to seek to ELF header\n"), file_name
);
416 if (! update_elf_header (file_name
, file
))
422 /* Return the path name for a proxy entry in a thin archive, adjusted relative
423 to the path name of the thin archive itself if necessary. Always returns
424 a pointer to malloc'ed memory. */
427 adjust_relative_path (const char *file_name
, char * name
, int name_len
)
429 char * member_file_name
;
430 const char * base_name
= lbasename (file_name
);
432 /* This is a proxy entry for a thin archive member.
433 If the extended name table contains an absolute path
434 name, or if the archive is in the current directory,
435 use the path name as given. Otherwise, we need to
436 find the member relative to the directory where the
437 archive is located. */
438 if (IS_ABSOLUTE_PATH (name
) || base_name
== file_name
)
440 member_file_name
= malloc (name_len
+ 1);
441 if (member_file_name
== NULL
)
443 non_fatal (_("Out of memory\n"));
446 memcpy (member_file_name
, name
, name_len
);
447 member_file_name
[name_len
] = '\0';
451 /* Concatenate the path components of the archive file name
452 to the relative path name from the extended name table. */
453 size_t prefix_len
= base_name
- file_name
;
454 member_file_name
= malloc (prefix_len
+ name_len
+ 1);
455 if (member_file_name
== NULL
)
457 non_fatal (_("Out of memory\n"));
460 memcpy (member_file_name
, file_name
, prefix_len
);
461 memcpy (member_file_name
+ prefix_len
, name
, name_len
);
462 member_file_name
[prefix_len
+ name_len
] = '\0';
464 return member_file_name
;
467 /* Structure to hold information about an archive file. */
471 char * file_name
; /* Archive file name. */
472 FILE * file
; /* Open file descriptor. */
473 unsigned long index_num
; /* Number of symbols in table. */
474 unsigned long * index_array
; /* The array of member offsets. */
475 char * sym_table
; /* The symbol table. */
476 unsigned long sym_size
; /* Size of the symbol table. */
477 char * longnames
; /* The long file names table. */
478 unsigned long longnames_size
; /* Size of the long file names table. */
479 unsigned long nested_member_origin
; /* Origin in the nested archive of the current member. */
480 unsigned long next_arhdr_offset
; /* Offset of the next archive header. */
481 bfd_boolean is_thin_archive
; /* TRUE if this is a thin archive. */
482 struct ar_hdr arhdr
; /* Current archive header. */
485 /* Read the symbol table and long-name table from an archive. */
488 setup_archive (struct archive_info
* arch
, const char * file_name
,
489 FILE * file
, bfd_boolean is_thin_archive
)
494 arch
->file_name
= strdup (file_name
);
497 arch
->index_array
= NULL
;
498 arch
->sym_table
= NULL
;
500 arch
->longnames
= NULL
;
501 arch
->longnames_size
= 0;
502 arch
->nested_member_origin
= 0;
503 arch
->is_thin_archive
= is_thin_archive
;
504 arch
->next_arhdr_offset
= SARMAG
;
506 /* Read the first archive member header. */
507 if (fseek (file
, SARMAG
, SEEK_SET
) != 0)
509 non_fatal (_("%s: failed to seek to first archive header\n"),
513 got
= fread (&arch
->arhdr
, 1, sizeof arch
->arhdr
, file
);
514 if (got
!= sizeof arch
->arhdr
)
519 non_fatal (_("%s: failed to read archive header\n"), file_name
);
523 /* See if this is the archive symbol table. */
524 if (const_strneq (arch
->arhdr
.ar_name
, "/ ")
525 || const_strneq (arch
->arhdr
.ar_name
, "/SYM64/ "))
527 size
= strtoul (arch
->arhdr
.ar_size
, NULL
, 10);
528 size
= size
+ (size
& 1);
530 arch
->next_arhdr_offset
+= sizeof arch
->arhdr
+ size
;
532 if (fseek (file
, size
, SEEK_CUR
) != 0)
534 non_fatal (_("%s: failed to skip archive symbol table\n"),
539 /* Read the next archive header. */
540 got
= fread (&arch
->arhdr
, 1, sizeof arch
->arhdr
, file
);
541 if (got
!= sizeof arch
->arhdr
)
545 non_fatal (_("%s: failed to read archive header following archive index\n"),
551 if (const_strneq (arch
->arhdr
.ar_name
, "// "))
553 /* This is the archive string table holding long member names. */
554 arch
->longnames_size
= strtoul (arch
->arhdr
.ar_size
, NULL
, 10);
555 arch
->next_arhdr_offset
+= sizeof arch
->arhdr
+ arch
->longnames_size
;
557 arch
->longnames
= malloc (arch
->longnames_size
);
558 if (arch
->longnames
== NULL
)
560 non_fatal (_("Out of memory reading long symbol names in archive\n"));
564 if (fread (arch
->longnames
, arch
->longnames_size
, 1, file
) != 1)
566 free (arch
->longnames
);
567 arch
->longnames
= NULL
;
568 non_fatal (_("%s: failed to read long symbol name string table\n")
573 if ((arch
->longnames_size
& 1) != 0)
580 /* Release the memory used for the archive information. */
583 release_archive (struct archive_info
* arch
)
585 if (arch
->file_name
!= NULL
)
586 free (arch
->file_name
);
587 if (arch
->index_array
!= NULL
)
588 free (arch
->index_array
);
589 if (arch
->sym_table
!= NULL
)
590 free (arch
->sym_table
);
591 if (arch
->longnames
!= NULL
)
592 free (arch
->longnames
);
595 /* Open and setup a nested archive, if not already open. */
598 setup_nested_archive (struct archive_info
* nested_arch
, char * member_file_name
)
602 /* Have we already setup this archive? */
603 if (nested_arch
->file_name
!= NULL
604 && streq (nested_arch
->file_name
, member_file_name
))
607 /* Close previous file and discard cached information. */
608 if (nested_arch
->file
!= NULL
)
609 fclose (nested_arch
->file
);
610 release_archive (nested_arch
);
612 member_file
= fopen (member_file_name
, "r+b");
613 if (member_file
== NULL
)
615 return setup_archive (nested_arch
, member_file_name
, member_file
,
620 get_archive_member_name_at (struct archive_info
* arch
,
621 unsigned long offset
,
622 struct archive_info
* nested_arch
);
624 /* Get the name of an archive member from the current archive header.
625 For simple names, this will modify the ar_name field of the current
626 archive header. For long names, it will return a pointer to the
627 longnames table. For nested archives, it will open the nested archive
628 and get the name recursively. NESTED_ARCH is a single-entry cache so
629 we don't keep rereading the same information from a nested archive. */
632 get_archive_member_name (struct archive_info
* arch
,
633 struct archive_info
* nested_arch
)
637 if (arch
->arhdr
.ar_name
[0] == '/')
639 /* We have a long name. */
641 char * member_file_name
;
644 arch
->nested_member_origin
= 0;
645 k
= j
= strtoul (arch
->arhdr
.ar_name
+ 1, &endp
, 10);
646 if (arch
->is_thin_archive
&& endp
!= NULL
&& * endp
== ':')
647 arch
->nested_member_origin
= strtoul (endp
+ 1, NULL
, 10);
649 while ((j
< arch
->longnames_size
)
650 && (arch
->longnames
[j
] != '\n')
651 && (arch
->longnames
[j
] != '\0'))
653 if (arch
->longnames
[j
-1] == '/')
655 arch
->longnames
[j
] = '\0';
657 if (!arch
->is_thin_archive
|| arch
->nested_member_origin
== 0)
658 return arch
->longnames
+ k
;
660 /* This is a proxy for a member of a nested archive.
661 Find the name of the member in that archive. */
662 member_file_name
= adjust_relative_path (arch
->file_name
,
665 if (member_file_name
!= NULL
666 && setup_nested_archive (nested_arch
, member_file_name
) == 0
667 && (member_name
= get_archive_member_name_at (nested_arch
,
668 arch
->nested_member_origin
,
671 free (member_file_name
);
674 free (member_file_name
);
676 /* Last resort: just return the name of the nested archive. */
677 return arch
->longnames
+ k
;
680 /* We have a normal (short) name. */
682 while ((arch
->arhdr
.ar_name
[j
] != '/') && (j
< 16))
684 arch
->arhdr
.ar_name
[j
] = '\0';
685 return arch
->arhdr
.ar_name
;
688 /* Get the name of an archive member at a given OFFSET within an
692 get_archive_member_name_at (struct archive_info
* arch
,
693 unsigned long offset
,
694 struct archive_info
* nested_arch
)
698 if (fseek (arch
->file
, offset
, SEEK_SET
) != 0)
700 non_fatal (_("%s: failed to seek to next file name\n"),
704 got
= fread (&arch
->arhdr
, 1, sizeof arch
->arhdr
, arch
->file
);
705 if (got
!= sizeof arch
->arhdr
)
707 non_fatal (_("%s: failed to read archive header\n"),
711 if (memcmp (arch
->arhdr
.ar_fmag
, ARFMAG
, 2) != 0)
713 non_fatal (_("%s: did not find a valid archive header\n"),
718 return get_archive_member_name (arch
, nested_arch
);
721 /* Construct a string showing the name of the archive member, qualified
722 with the name of the containing archive file. For thin archives, we
723 use square brackets to denote the indirection. For nested archives,
724 we show the qualified name of the external member inside the square
725 brackets (e.g., "thin.a[normal.a(foo.o)]"). */
728 make_qualified_name (struct archive_info
* arch
,
729 struct archive_info
* nested_arch
,
735 len
= strlen (arch
->file_name
) + strlen (member_name
) + 3;
736 if (arch
->is_thin_archive
&& arch
->nested_member_origin
!= 0)
737 len
+= strlen (nested_arch
->file_name
) + 2;
742 non_fatal (_("Out of memory\n"));
746 if (arch
->is_thin_archive
&& arch
->nested_member_origin
!= 0)
747 snprintf (name
, len
, "%s[%s(%s)]", arch
->file_name
, nested_arch
->file_name
, member_name
);
748 else if (arch
->is_thin_archive
)
749 snprintf (name
, len
, "%s[%s]", arch
->file_name
, member_name
);
751 snprintf (name
, len
, "%s(%s)", arch
->file_name
, member_name
);
756 /* Process an ELF archive.
757 On entry the file is positioned just after the ARMAG string. */
760 process_archive (const char * file_name
, FILE * file
,
761 bfd_boolean is_thin_archive
)
763 struct archive_info arch
;
764 struct archive_info nested_arch
;
766 size_t file_name_size
;
769 /* The ARCH structure is used to hold information about this archive. */
770 arch
.file_name
= NULL
;
772 arch
.index_array
= NULL
;
773 arch
.sym_table
= NULL
;
774 arch
.longnames
= NULL
;
776 /* The NESTED_ARCH structure is used as a single-item cache of information
777 about a nested archive (when members of a thin archive reside within
778 another regular archive file). */
779 nested_arch
.file_name
= NULL
;
780 nested_arch
.file
= NULL
;
781 nested_arch
.index_array
= NULL
;
782 nested_arch
.sym_table
= NULL
;
783 nested_arch
.longnames
= NULL
;
785 if (setup_archive (&arch
, file_name
, file
, is_thin_archive
) != 0)
791 file_name_size
= strlen (file_name
);
798 char * qualified_name
;
800 /* Read the next archive header. */
801 if (fseek (file
, arch
.next_arhdr_offset
, SEEK_SET
) != 0)
803 non_fatal (_("%s: failed to seek to next archive header\n"),
807 got
= fread (&arch
.arhdr
, 1, sizeof arch
.arhdr
, file
);
808 if (got
!= sizeof arch
.arhdr
)
812 non_fatal (_("%s: failed to read archive header\n"),
817 if (memcmp (arch
.arhdr
.ar_fmag
, ARFMAG
, 2) != 0)
819 non_fatal (_("%s: did not find a valid archive header\n"),
825 arch
.next_arhdr_offset
+= sizeof arch
.arhdr
;
827 archive_file_size
= strtoul (arch
.arhdr
.ar_size
, NULL
, 10);
828 if (archive_file_size
& 01)
831 name
= get_archive_member_name (&arch
, &nested_arch
);
834 non_fatal (_("%s: bad archive file name\n"), file_name
);
838 namelen
= strlen (name
);
840 qualified_name
= make_qualified_name (&arch
, &nested_arch
, name
);
841 if (qualified_name
== NULL
)
843 non_fatal (_("%s: bad archive file name\n"), file_name
);
848 if (is_thin_archive
&& arch
.nested_member_origin
== 0)
850 /* This is a proxy for an external member of a thin archive. */
852 char *member_file_name
= adjust_relative_path (file_name
,
854 if (member_file_name
== NULL
)
860 member_file
= fopen (member_file_name
, "r+b");
861 if (member_file
== NULL
)
863 non_fatal (_("Input file '%s' is not readable\n"),
865 free (member_file_name
);
870 archive_file_offset
= arch
.nested_member_origin
;
872 ret
|= process_object (qualified_name
, member_file
);
874 fclose (member_file
);
875 free (member_file_name
);
877 else if (is_thin_archive
)
879 /* This is a proxy for a member of a nested archive. */
880 archive_file_offset
= arch
.nested_member_origin
+ sizeof arch
.arhdr
;
882 /* The nested archive file will have been opened and setup by
883 get_archive_member_name. */
884 if (fseek (nested_arch
.file
, archive_file_offset
,
887 non_fatal (_("%s: failed to seek to archive member\n"),
888 nested_arch
.file_name
);
893 ret
|= process_object (qualified_name
, nested_arch
.file
);
897 archive_file_offset
= arch
.next_arhdr_offset
;
898 arch
.next_arhdr_offset
+= archive_file_size
;
900 ret
|= process_object (qualified_name
, file
);
903 free (qualified_name
);
907 if (nested_arch
.file
!= NULL
)
908 fclose (nested_arch
.file
);
909 release_archive (&nested_arch
);
910 release_archive (&arch
);
916 check_file (const char *file_name
, struct stat
*statbuf_p
)
920 if (statbuf_p
== NULL
)
921 statbuf_p
= &statbuf
;
923 if (stat (file_name
, statbuf_p
) < 0)
926 non_fatal (_("'%s': No such file\n"), file_name
);
928 non_fatal (_("Could not locate '%s'. System error message: %s\n"),
929 file_name
, strerror (errno
));
933 if (! S_ISREG (statbuf_p
->st_mode
))
935 non_fatal (_("'%s' is not an ordinary file\n"), file_name
);
943 process_file (const char *file_name
)
949 if (check_file (file_name
, NULL
))
952 file
= fopen (file_name
, "r+b");
955 non_fatal (_("Input file '%s' is not readable\n"), file_name
);
959 if (fread (armag
, SARMAG
, 1, file
) != 1)
961 non_fatal (_("%s: Failed to read file's magic number\n"),
967 if (memcmp (armag
, ARMAG
, SARMAG
) == 0)
968 ret
= process_archive (file_name
, file
, FALSE
);
969 else if (memcmp (armag
, ARMAGT
, SARMAG
) == 0)
970 ret
= process_archive (file_name
, file
, TRUE
);
974 archive_file_size
= archive_file_offset
= 0;
975 ret
= process_object (file_name
, file
);
983 /* Return EM_XXX for a machine string, MACH. */
986 elf_machine (const char *mach
)
988 if (strcasecmp (mach
, "l1om") == 0)
990 if (strcasecmp (mach
, "x86_64") == 0)
992 if (strcasecmp (mach
, "x86-64") == 0)
994 if (strcasecmp (mach
, "none") == 0)
997 non_fatal (_("Unknown machine type: %s\n"), mach
);
1002 /* Return ELF class for a machine type, MACH. */
1005 elf_class (int mach
)
1013 return ELFCLASSNONE
;
1015 non_fatal (_("Unknown machine type: %d\n"), mach
);
1020 enum command_line_switch
1022 OPTION_INPUT_MACH
= 150,
1026 static struct option options
[] =
1028 {"input-mach", required_argument
, 0, OPTION_INPUT_MACH
},
1029 {"output-mach", required_argument
, 0, OPTION_OUTPUT_MACH
},
1030 {"version", no_argument
, 0, 'v'},
1031 {"help", no_argument
, 0, 'h'},
1032 {0, no_argument
, 0, 0}
1036 usage (FILE *stream
, int exit_status
)
1038 fprintf (stream
, _("Usage: %s [option(s)] --output-mach <machine> elffile(s)\n"),
1040 fprintf (stream
, _(" Update the ELF header of ELF files\n"));
1041 fprintf (stream
, _(" The options are:\n"));
1042 fprintf (stream
, _("\
1043 --input-mach <machine> Set input machine type to <machine>\n\
1044 --output-mach <machine> Set output machine type to <machine>\n\
1045 -h --help Display this information\n\
1046 -v --version Display the version number of %s\n\
1049 if (REPORT_BUGS_TO
[0] && exit_status
== 0)
1050 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);
1055 main (int argc
, char ** argv
)
1059 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
1060 setlocale (LC_MESSAGES
, "");
1062 #if defined (HAVE_SETLOCALE)
1063 setlocale (LC_CTYPE
, "");
1065 bindtextdomain (PACKAGE
, LOCALEDIR
);
1066 textdomain (PACKAGE
);
1068 expandargv (&argc
, &argv
);
1070 while ((c
= getopt_long (argc
, argv
, "hv",
1071 options
, (int *) 0)) != EOF
)
1075 case OPTION_INPUT_MACH
:
1076 input_elf_machine
= elf_machine (optarg
);
1077 if (input_elf_machine
< 0)
1079 input_elf_class
= elf_class (input_elf_machine
);
1080 if (input_elf_class
< 0)
1084 case OPTION_OUTPUT_MACH
:
1085 output_elf_machine
= elf_machine (optarg
);
1086 if (output_elf_machine
< 0)
1094 print_version (program_name
);
1102 if (optind
== argc
|| output_elf_machine
== -1)
1106 while (optind
< argc
)
1107 status
|= process_file (argv
[optind
++]);