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
];
256 else if (elf_header
.e_ident
[EI_CLASS
] != input_elf_class
)
259 (_("%s: Unmatched EI_CLASS: %d is not %d\n"),
260 file_name
, elf_header
.e_ident
[EI_CLASS
],
265 /* Return if e_machine is the same as output_elf_machine. */
266 if (output_elf_machine
== elf_header
.e_machine
)
269 /* Skip if e_machine doesn't match. */
270 if (input_elf_machine
== -1)
271 input_elf_machine
= elf_header
.e_machine
;
272 else if (elf_header
.e_machine
!= input_elf_machine
)
275 (_("%s: Unmatched e_machine: %d is not %d\n"),
276 file_name
, elf_header
.e_machine
, input_elf_machine
);
280 /* Update e_machine. */
281 switch (input_elf_class
)
284 /* We should never get here. */
288 BYTE_PUT (ehdr32
.e_machine
, output_elf_machine
);
289 status
= fwrite (&ehdr32
, sizeof (ehdr32
), 1, file
) == 1;
292 BYTE_PUT (ehdr64
.e_machine
, output_elf_machine
);
293 status
= fwrite (&ehdr64
, sizeof (ehdr64
), 1, file
) == 1;
298 non_fatal (_("%s: Failed to update ELF header: %s\n"),
299 file_name
, strerror (errno
));
305 get_file_header (FILE * file
)
307 /* Read in the identity array. */
308 if (fread (elf_header
.e_ident
, EI_NIDENT
, 1, file
) != 1)
311 /* Determine how to read the rest of the header. */
312 switch (elf_header
.e_ident
[EI_DATA
])
314 default: /* fall through */
315 case ELFDATANONE
: /* fall through */
317 byte_get
= byte_get_little_endian
;
318 byte_put
= byte_put_little_endian
;
321 byte_get
= byte_get_big_endian
;
322 byte_put
= byte_put_big_endian
;
326 /* Read in the rest of the header. For now we only support 32 bit
327 and 64 bit ELF files. */
328 switch (elf_header
.e_ident
[EI_CLASS
])
331 non_fatal (_("Unsupported EI_CLASS: %d\n"),
332 elf_header
.e_ident
[EI_CLASS
]);
336 if (fread (ehdr32
.e_type
, sizeof (ehdr32
) - EI_NIDENT
,
340 elf_header
.e_type
= BYTE_GET (ehdr32
.e_type
);
341 elf_header
.e_machine
= BYTE_GET (ehdr32
.e_machine
);
342 elf_header
.e_version
= BYTE_GET (ehdr32
.e_version
);
343 elf_header
.e_entry
= BYTE_GET (ehdr32
.e_entry
);
344 elf_header
.e_phoff
= BYTE_GET (ehdr32
.e_phoff
);
345 elf_header
.e_shoff
= BYTE_GET (ehdr32
.e_shoff
);
346 elf_header
.e_flags
= BYTE_GET (ehdr32
.e_flags
);
347 elf_header
.e_ehsize
= BYTE_GET (ehdr32
.e_ehsize
);
348 elf_header
.e_phentsize
= BYTE_GET (ehdr32
.e_phentsize
);
349 elf_header
.e_phnum
= BYTE_GET (ehdr32
.e_phnum
);
350 elf_header
.e_shentsize
= BYTE_GET (ehdr32
.e_shentsize
);
351 elf_header
.e_shnum
= BYTE_GET (ehdr32
.e_shnum
);
352 elf_header
.e_shstrndx
= BYTE_GET (ehdr32
.e_shstrndx
);
354 memcpy (&ehdr32
, &elf_header
, EI_NIDENT
);
358 /* If we have been compiled with sizeof (bfd_vma) == 4, then
359 we will not be able to cope with the 64bit data found in
360 64 ELF files. Detect this now and abort before we start
361 overwriting things. */
362 if (sizeof (bfd_vma
) < 8)
364 non_fatal (_("This executable has been built without support for a\n\
365 64 bit data type and so it cannot process 64 bit ELF files.\n"));
369 if (fread (ehdr64
.e_type
, sizeof (ehdr64
) - EI_NIDENT
,
373 elf_header
.e_type
= BYTE_GET (ehdr64
.e_type
);
374 elf_header
.e_machine
= BYTE_GET (ehdr64
.e_machine
);
375 elf_header
.e_version
= BYTE_GET (ehdr64
.e_version
);
376 elf_header
.e_entry
= BYTE_GET (ehdr64
.e_entry
);
377 elf_header
.e_phoff
= BYTE_GET (ehdr64
.e_phoff
);
378 elf_header
.e_shoff
= BYTE_GET (ehdr64
.e_shoff
);
379 elf_header
.e_flags
= BYTE_GET (ehdr64
.e_flags
);
380 elf_header
.e_ehsize
= BYTE_GET (ehdr64
.e_ehsize
);
381 elf_header
.e_phentsize
= BYTE_GET (ehdr64
.e_phentsize
);
382 elf_header
.e_phnum
= BYTE_GET (ehdr64
.e_phnum
);
383 elf_header
.e_shentsize
= BYTE_GET (ehdr64
.e_shentsize
);
384 elf_header
.e_shnum
= BYTE_GET (ehdr64
.e_shnum
);
385 elf_header
.e_shstrndx
= BYTE_GET (ehdr64
.e_shstrndx
);
387 memcpy (&ehdr64
, &elf_header
, EI_NIDENT
);
393 /* Process one ELF object file according to the command line options.
394 This file may actually be stored in an archive. The file is
395 positioned at the start of the ELF object. */
398 process_object (const char *file_name
, FILE *file
)
400 /* Rememeber where we are. */
401 long offset
= ftell (file
);
403 if (! get_file_header (file
))
405 non_fatal (_("%s: Failed to read ELF header\n"), file_name
);
409 /* Go to the position of the ELF header. */
410 if (fseek (file
, offset
, SEEK_SET
) != 0)
412 non_fatal (_("%s: Failed to seek to ELF header\n"), file_name
);
415 if (! update_elf_header (file_name
, file
))
421 /* Return the path name for a proxy entry in a thin archive, adjusted relative
422 to the path name of the thin archive itself if necessary. Always returns
423 a pointer to malloc'ed memory. */
426 adjust_relative_path (const char *file_name
, char * name
, int name_len
)
428 char * member_file_name
;
429 const char * base_name
= lbasename (file_name
);
431 /* This is a proxy entry for a thin archive member.
432 If the extended name table contains an absolute path
433 name, or if the archive is in the current directory,
434 use the path name as given. Otherwise, we need to
435 find the member relative to the directory where the
436 archive is located. */
437 if (IS_ABSOLUTE_PATH (name
) || base_name
== file_name
)
439 member_file_name
= malloc (name_len
+ 1);
440 if (member_file_name
== NULL
)
442 non_fatal (_("Out of memory\n"));
445 memcpy (member_file_name
, name
, name_len
);
446 member_file_name
[name_len
] = '\0';
450 /* Concatenate the path components of the archive file name
451 to the relative path name from the extended name table. */
452 size_t prefix_len
= base_name
- file_name
;
453 member_file_name
= malloc (prefix_len
+ name_len
+ 1);
454 if (member_file_name
== NULL
)
456 non_fatal (_("Out of memory\n"));
459 memcpy (member_file_name
, file_name
, prefix_len
);
460 memcpy (member_file_name
+ prefix_len
, name
, name_len
);
461 member_file_name
[prefix_len
+ name_len
] = '\0';
463 return member_file_name
;
466 /* Structure to hold information about an archive file. */
470 char * file_name
; /* Archive file name. */
471 FILE * file
; /* Open file descriptor. */
472 unsigned long index_num
; /* Number of symbols in table. */
473 unsigned long * index_array
; /* The array of member offsets. */
474 char * sym_table
; /* The symbol table. */
475 unsigned long sym_size
; /* Size of the symbol table. */
476 char * longnames
; /* The long file names table. */
477 unsigned long longnames_size
; /* Size of the long file names table. */
478 unsigned long nested_member_origin
; /* Origin in the nested archive of the current member. */
479 unsigned long next_arhdr_offset
; /* Offset of the next archive header. */
480 bfd_boolean is_thin_archive
; /* TRUE if this is a thin archive. */
481 struct ar_hdr arhdr
; /* Current archive header. */
484 /* Read the symbol table and long-name table from an archive. */
487 setup_archive (struct archive_info
* arch
, const char * file_name
,
488 FILE * file
, bfd_boolean is_thin_archive
)
493 arch
->file_name
= strdup (file_name
);
496 arch
->index_array
= NULL
;
497 arch
->sym_table
= NULL
;
499 arch
->longnames
= NULL
;
500 arch
->longnames_size
= 0;
501 arch
->nested_member_origin
= 0;
502 arch
->is_thin_archive
= is_thin_archive
;
503 arch
->next_arhdr_offset
= SARMAG
;
505 /* Read the first archive member header. */
506 if (fseek (file
, SARMAG
, SEEK_SET
) != 0)
508 non_fatal (_("%s: failed to seek to first archive header\n"),
512 got
= fread (&arch
->arhdr
, 1, sizeof arch
->arhdr
, file
);
513 if (got
!= sizeof arch
->arhdr
)
518 non_fatal (_("%s: failed to read archive header\n"), file_name
);
522 /* See if this is the archive symbol table. */
523 if (const_strneq (arch
->arhdr
.ar_name
, "/ ")
524 || const_strneq (arch
->arhdr
.ar_name
, "/SYM64/ "))
526 size
= strtoul (arch
->arhdr
.ar_size
, NULL
, 10);
527 size
= size
+ (size
& 1);
529 arch
->next_arhdr_offset
+= sizeof arch
->arhdr
+ size
;
531 if (fseek (file
, size
, SEEK_CUR
) != 0)
533 non_fatal (_("%s: failed to skip archive symbol table\n"),
538 /* Read the next archive header. */
539 got
= fread (&arch
->arhdr
, 1, sizeof arch
->arhdr
, file
);
540 if (got
!= sizeof arch
->arhdr
)
544 non_fatal (_("%s: failed to read archive header following archive index\n"),
550 if (const_strneq (arch
->arhdr
.ar_name
, "// "))
552 /* This is the archive string table holding long member names. */
553 arch
->longnames_size
= strtoul (arch
->arhdr
.ar_size
, NULL
, 10);
554 arch
->next_arhdr_offset
+= sizeof arch
->arhdr
+ arch
->longnames_size
;
556 arch
->longnames
= malloc (arch
->longnames_size
);
557 if (arch
->longnames
== NULL
)
559 non_fatal (_("Out of memory reading long symbol names in archive\n"));
563 if (fread (arch
->longnames
, arch
->longnames_size
, 1, file
) != 1)
565 free (arch
->longnames
);
566 arch
->longnames
= NULL
;
567 non_fatal (_("%s: failed to read long symbol name string table\n")
572 if ((arch
->longnames_size
& 1) != 0)
579 /* Release the memory used for the archive information. */
582 release_archive (struct archive_info
* arch
)
584 if (arch
->file_name
!= NULL
)
585 free (arch
->file_name
);
586 if (arch
->index_array
!= NULL
)
587 free (arch
->index_array
);
588 if (arch
->sym_table
!= NULL
)
589 free (arch
->sym_table
);
590 if (arch
->longnames
!= NULL
)
591 free (arch
->longnames
);
594 /* Open and setup a nested archive, if not already open. */
597 setup_nested_archive (struct archive_info
* nested_arch
, char * member_file_name
)
601 /* Have we already setup this archive? */
602 if (nested_arch
->file_name
!= NULL
603 && streq (nested_arch
->file_name
, member_file_name
))
606 /* Close previous file and discard cached information. */
607 if (nested_arch
->file
!= NULL
)
608 fclose (nested_arch
->file
);
609 release_archive (nested_arch
);
611 member_file
= fopen (member_file_name
, "r+b");
612 if (member_file
== NULL
)
614 return setup_archive (nested_arch
, member_file_name
, member_file
,
619 get_archive_member_name_at (struct archive_info
* arch
,
620 unsigned long offset
,
621 struct archive_info
* nested_arch
);
623 /* Get the name of an archive member from the current archive header.
624 For simple names, this will modify the ar_name field of the current
625 archive header. For long names, it will return a pointer to the
626 longnames table. For nested archives, it will open the nested archive
627 and get the name recursively. NESTED_ARCH is a single-entry cache so
628 we don't keep rereading the same information from a nested archive. */
631 get_archive_member_name (struct archive_info
* arch
,
632 struct archive_info
* nested_arch
)
636 if (arch
->arhdr
.ar_name
[0] == '/')
638 /* We have a long name. */
640 char * member_file_name
;
643 arch
->nested_member_origin
= 0;
644 k
= j
= strtoul (arch
->arhdr
.ar_name
+ 1, &endp
, 10);
645 if (arch
->is_thin_archive
&& endp
!= NULL
&& * endp
== ':')
646 arch
->nested_member_origin
= strtoul (endp
+ 1, NULL
, 10);
648 while ((j
< arch
->longnames_size
)
649 && (arch
->longnames
[j
] != '\n')
650 && (arch
->longnames
[j
] != '\0'))
652 if (arch
->longnames
[j
-1] == '/')
654 arch
->longnames
[j
] = '\0';
656 if (!arch
->is_thin_archive
|| arch
->nested_member_origin
== 0)
657 return arch
->longnames
+ k
;
659 /* This is a proxy for a member of a nested archive.
660 Find the name of the member in that archive. */
661 member_file_name
= adjust_relative_path (arch
->file_name
,
664 if (member_file_name
!= NULL
665 && setup_nested_archive (nested_arch
, member_file_name
) == 0
666 && (member_name
= get_archive_member_name_at (nested_arch
,
667 arch
->nested_member_origin
,
670 free (member_file_name
);
673 free (member_file_name
);
675 /* Last resort: just return the name of the nested archive. */
676 return arch
->longnames
+ k
;
679 /* We have a normal (short) name. */
681 while ((arch
->arhdr
.ar_name
[j
] != '/') && (j
< 16))
683 arch
->arhdr
.ar_name
[j
] = '\0';
684 return arch
->arhdr
.ar_name
;
687 /* Get the name of an archive member at a given OFFSET within an
691 get_archive_member_name_at (struct archive_info
* arch
,
692 unsigned long offset
,
693 struct archive_info
* nested_arch
)
697 if (fseek (arch
->file
, offset
, SEEK_SET
) != 0)
699 non_fatal (_("%s: failed to seek to next file name\n"),
703 got
= fread (&arch
->arhdr
, 1, sizeof arch
->arhdr
, arch
->file
);
704 if (got
!= sizeof arch
->arhdr
)
706 non_fatal (_("%s: failed to read archive header\n"),
710 if (memcmp (arch
->arhdr
.ar_fmag
, ARFMAG
, 2) != 0)
712 non_fatal (_("%s: did not find a valid archive header\n"),
717 return get_archive_member_name (arch
, nested_arch
);
720 /* Construct a string showing the name of the archive member, qualified
721 with the name of the containing archive file. For thin archives, we
722 use square brackets to denote the indirection. For nested archives,
723 we show the qualified name of the external member inside the square
724 brackets (e.g., "thin.a[normal.a(foo.o)]"). */
727 make_qualified_name (struct archive_info
* arch
,
728 struct archive_info
* nested_arch
,
734 len
= strlen (arch
->file_name
) + strlen (member_name
) + 3;
735 if (arch
->is_thin_archive
&& arch
->nested_member_origin
!= 0)
736 len
+= strlen (nested_arch
->file_name
) + 2;
741 non_fatal (_("Out of memory\n"));
745 if (arch
->is_thin_archive
&& arch
->nested_member_origin
!= 0)
746 snprintf (name
, len
, "%s[%s(%s)]", arch
->file_name
, nested_arch
->file_name
, member_name
);
747 else if (arch
->is_thin_archive
)
748 snprintf (name
, len
, "%s[%s]", arch
->file_name
, member_name
);
750 snprintf (name
, len
, "%s(%s)", arch
->file_name
, member_name
);
755 /* Process an ELF archive.
756 On entry the file is positioned just after the ARMAG string. */
759 process_archive (const char * file_name
, FILE * file
,
760 bfd_boolean is_thin_archive
)
762 struct archive_info arch
;
763 struct archive_info nested_arch
;
765 size_t file_name_size
;
768 /* The ARCH structure is used to hold information about this archive. */
769 arch
.file_name
= NULL
;
771 arch
.index_array
= NULL
;
772 arch
.sym_table
= NULL
;
773 arch
.longnames
= NULL
;
775 /* The NESTED_ARCH structure is used as a single-item cache of information
776 about a nested archive (when members of a thin archive reside within
777 another regular archive file). */
778 nested_arch
.file_name
= NULL
;
779 nested_arch
.file
= NULL
;
780 nested_arch
.index_array
= NULL
;
781 nested_arch
.sym_table
= NULL
;
782 nested_arch
.longnames
= NULL
;
784 if (setup_archive (&arch
, file_name
, file
, is_thin_archive
) != 0)
790 file_name_size
= strlen (file_name
);
797 char * qualified_name
;
799 /* Read the next archive header. */
800 if (fseek (file
, arch
.next_arhdr_offset
, SEEK_SET
) != 0)
802 non_fatal (_("%s: failed to seek to next archive header\n"),
806 got
= fread (&arch
.arhdr
, 1, sizeof arch
.arhdr
, file
);
807 if (got
!= sizeof arch
.arhdr
)
811 non_fatal (_("%s: failed to read archive header\n"),
816 if (memcmp (arch
.arhdr
.ar_fmag
, ARFMAG
, 2) != 0)
818 non_fatal (_("%s: did not find a valid archive header\n"),
824 arch
.next_arhdr_offset
+= sizeof arch
.arhdr
;
826 archive_file_size
= strtoul (arch
.arhdr
.ar_size
, NULL
, 10);
827 if (archive_file_size
& 01)
830 name
= get_archive_member_name (&arch
, &nested_arch
);
833 non_fatal (_("%s: bad archive file name\n"), file_name
);
837 namelen
= strlen (name
);
839 qualified_name
= make_qualified_name (&arch
, &nested_arch
, name
);
840 if (qualified_name
== NULL
)
842 non_fatal (_("%s: bad archive file name\n"), file_name
);
847 if (is_thin_archive
&& arch
.nested_member_origin
== 0)
849 /* This is a proxy for an external member of a thin archive. */
851 char *member_file_name
= adjust_relative_path (file_name
,
853 if (member_file_name
== NULL
)
859 member_file
= fopen (member_file_name
, "r+b");
860 if (member_file
== NULL
)
862 non_fatal (_("Input file '%s' is not readable\n"),
864 free (member_file_name
);
869 archive_file_offset
= arch
.nested_member_origin
;
871 ret
|= process_object (qualified_name
, member_file
);
873 fclose (member_file
);
874 free (member_file_name
);
876 else if (is_thin_archive
)
878 /* This is a proxy for a member of a nested archive. */
879 archive_file_offset
= arch
.nested_member_origin
+ sizeof arch
.arhdr
;
881 /* The nested archive file will have been opened and setup by
882 get_archive_member_name. */
883 if (fseek (nested_arch
.file
, archive_file_offset
,
886 non_fatal (_("%s: failed to seek to archive member\n"),
887 nested_arch
.file_name
);
892 ret
|= process_object (qualified_name
, nested_arch
.file
);
896 archive_file_offset
= arch
.next_arhdr_offset
;
897 arch
.next_arhdr_offset
+= archive_file_size
;
899 ret
|= process_object (qualified_name
, file
);
902 free (qualified_name
);
906 if (nested_arch
.file
!= NULL
)
907 fclose (nested_arch
.file
);
908 release_archive (&nested_arch
);
909 release_archive (&arch
);
915 check_file (const char *file_name
, struct stat
*statbuf_p
)
919 if (statbuf_p
== NULL
)
920 statbuf_p
= &statbuf
;
922 if (stat (file_name
, statbuf_p
) < 0)
925 non_fatal (_("'%s': No such file\n"), file_name
);
927 non_fatal (_("Could not locate '%s'. System error message: %s\n"),
928 file_name
, strerror (errno
));
932 if (! S_ISREG (statbuf_p
->st_mode
))
934 non_fatal (_("'%s' is not an ordinary file\n"), file_name
);
942 process_file (const char *file_name
)
948 if (check_file (file_name
, NULL
))
951 file
= fopen (file_name
, "r+b");
954 non_fatal (_("Input file '%s' is not readable\n"), file_name
);
958 if (fread (armag
, SARMAG
, 1, file
) != 1)
960 non_fatal (_("%s: Failed to read file's magic number\n"),
966 if (memcmp (armag
, ARMAG
, SARMAG
) == 0)
967 ret
= process_archive (file_name
, file
, FALSE
);
968 else if (memcmp (armag
, ARMAGT
, SARMAG
) == 0)
969 ret
= process_archive (file_name
, file
, TRUE
);
973 archive_file_size
= archive_file_offset
= 0;
974 ret
= process_object (file_name
, file
);
982 /* Return EM_XXX for a machine string, MACH. */
985 elf_machine (const char *mach
)
987 if (strcasecmp (mach
, "l1om") == 0)
989 if (strcasecmp (mach
, "x86_64") == 0)
991 if (strcasecmp (mach
, "x86-64") == 0)
993 if (strcasecmp (mach
, "none") == 0)
996 non_fatal (_("Unknown machine type: %s\n"), mach
);
1001 /* Return ELF class for a machine type, MACH. */
1004 elf_class (int mach
)
1012 return ELFCLASSNONE
;
1014 non_fatal (_("Unknown machine type: %d\n"), mach
);
1019 enum command_line_switch
1021 OPTION_INPUT_MACH
= 150,
1025 static struct option options
[] =
1027 {"input-mach", required_argument
, 0, OPTION_INPUT_MACH
},
1028 {"output-mach", required_argument
, 0, OPTION_OUTPUT_MACH
},
1029 {"version", no_argument
, 0, 'v'},
1030 {"help", no_argument
, 0, 'h'},
1031 {0, no_argument
, 0, 0}
1035 usage (FILE *stream
, int exit_status
)
1037 fprintf (stream
, _("Usage: %s [option(s)] --output-mach <machine> elffile(s)\n"),
1039 fprintf (stream
, _(" Update the ELF header of ELF files\n"));
1040 fprintf (stream
, _(" The options are:\n"));
1041 fprintf (stream
, _("\
1042 --input-mach <machine> Set input machine type to <machine>\n\
1043 --output-mach <machine> Set output machine type to <machine>\n\
1044 -h --help Display this information\n\
1045 -v --version Display the version number of %s\n\
1048 if (REPORT_BUGS_TO
[0] && exit_status
== 0)
1049 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);
1054 main (int argc
, char ** argv
)
1058 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
1059 setlocale (LC_MESSAGES
, "");
1061 #if defined (HAVE_SETLOCALE)
1062 setlocale (LC_CTYPE
, "");
1064 bindtextdomain (PACKAGE
, LOCALEDIR
);
1065 textdomain (PACKAGE
);
1067 expandargv (&argc
, &argv
);
1069 while ((c
= getopt_long (argc
, argv
, "hv",
1070 options
, (int *) 0)) != EOF
)
1074 case OPTION_INPUT_MACH
:
1075 input_elf_machine
= elf_machine (optarg
);
1076 if (input_elf_machine
< 0)
1078 input_elf_class
= elf_class (input_elf_machine
);
1079 if (input_elf_class
< 0)
1083 case OPTION_OUTPUT_MACH
:
1084 output_elf_machine
= elf_machine (optarg
);
1085 if (output_elf_machine
< 0)
1093 print_version (program_name
);
1101 if (optind
== argc
|| output_elf_machine
== -1)
1105 while (optind
< argc
)
1106 status
|= process_file (argv
[optind
++]);