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
;
785 /* The ARCH structure is used to hold information about this archive. */
786 arch
.file_name
= NULL
;
788 arch
.index_array
= NULL
;
789 arch
.sym_table
= NULL
;
790 arch
.longnames
= NULL
;
792 /* The NESTED_ARCH structure is used as a single-item cache of information
793 about a nested archive (when members of a thin archive reside within
794 another regular archive file). */
795 nested_arch
.file_name
= NULL
;
796 nested_arch
.file
= NULL
;
797 nested_arch
.index_array
= NULL
;
798 nested_arch
.sym_table
= NULL
;
799 nested_arch
.longnames
= NULL
;
801 if (setup_archive (&arch
, file_name
, file
, is_thin_archive
) != 0)
813 char * qualified_name
;
815 /* Read the next archive header. */
816 if (fseek (file
, arch
.next_arhdr_offset
, SEEK_SET
) != 0)
818 non_fatal (_("%s: failed to seek to next archive header\n"),
822 got
= fread (&arch
.arhdr
, 1, sizeof arch
.arhdr
, file
);
823 if (got
!= sizeof arch
.arhdr
)
827 non_fatal (_("%s: failed to read archive header\n"),
832 if (memcmp (arch
.arhdr
.ar_fmag
, ARFMAG
, 2) != 0)
834 non_fatal (_("%s: did not find a valid archive header\n"),
840 arch
.next_arhdr_offset
+= sizeof arch
.arhdr
;
842 archive_file_size
= strtoul (arch
.arhdr
.ar_size
, NULL
, 10);
843 if (archive_file_size
& 01)
846 name
= get_archive_member_name (&arch
, &nested_arch
);
849 non_fatal (_("%s: bad archive file name\n"), file_name
);
853 namelen
= strlen (name
);
855 qualified_name
= make_qualified_name (&arch
, &nested_arch
, name
);
856 if (qualified_name
== NULL
)
858 non_fatal (_("%s: bad archive file name\n"), file_name
);
863 if (is_thin_archive
&& arch
.nested_member_origin
== 0)
865 /* This is a proxy for an external member of a thin archive. */
867 char *member_file_name
= adjust_relative_path (file_name
,
869 if (member_file_name
== NULL
)
875 member_file
= fopen (member_file_name
, "r+b");
876 if (member_file
== NULL
)
878 non_fatal (_("Input file '%s' is not readable\n"),
880 free (member_file_name
);
885 archive_file_offset
= arch
.nested_member_origin
;
887 ret
|= process_object (qualified_name
, member_file
);
889 fclose (member_file
);
890 free (member_file_name
);
892 else if (is_thin_archive
)
894 /* This is a proxy for a member of a nested archive. */
895 archive_file_offset
= arch
.nested_member_origin
+ sizeof arch
.arhdr
;
897 /* The nested archive file will have been opened and setup by
898 get_archive_member_name. */
899 if (fseek (nested_arch
.file
, archive_file_offset
,
902 non_fatal (_("%s: failed to seek to archive member\n"),
903 nested_arch
.file_name
);
908 ret
|= process_object (qualified_name
, nested_arch
.file
);
912 archive_file_offset
= arch
.next_arhdr_offset
;
913 arch
.next_arhdr_offset
+= archive_file_size
;
915 ret
|= process_object (qualified_name
, file
);
918 free (qualified_name
);
922 if (nested_arch
.file
!= NULL
)
923 fclose (nested_arch
.file
);
924 release_archive (&nested_arch
);
925 release_archive (&arch
);
931 check_file (const char *file_name
, struct stat
*statbuf_p
)
935 if (statbuf_p
== NULL
)
936 statbuf_p
= &statbuf
;
938 if (stat (file_name
, statbuf_p
) < 0)
941 non_fatal (_("'%s': No such file\n"), file_name
);
943 non_fatal (_("Could not locate '%s'. System error message: %s\n"),
944 file_name
, strerror (errno
));
948 if (! S_ISREG (statbuf_p
->st_mode
))
950 non_fatal (_("'%s' is not an ordinary file\n"), file_name
);
958 process_file (const char *file_name
)
964 if (check_file (file_name
, NULL
))
967 file
= fopen (file_name
, "r+b");
970 non_fatal (_("Input file '%s' is not readable\n"), file_name
);
974 if (fread (armag
, SARMAG
, 1, file
) != 1)
976 non_fatal (_("%s: Failed to read file's magic number\n"),
982 if (memcmp (armag
, ARMAG
, SARMAG
) == 0)
983 ret
= process_archive (file_name
, file
, FALSE
);
984 else if (memcmp (armag
, ARMAGT
, SARMAG
) == 0)
985 ret
= process_archive (file_name
, file
, TRUE
);
989 archive_file_size
= archive_file_offset
= 0;
990 ret
= process_object (file_name
, file
);
998 /* Return EM_XXX for a machine string, MACH. */
1001 elf_machine (const char *mach
)
1003 if (strcasecmp (mach
, "l1om") == 0)
1005 if (strcasecmp (mach
, "x86_64") == 0)
1007 if (strcasecmp (mach
, "x86-64") == 0)
1009 if (strcasecmp (mach
, "none") == 0)
1012 non_fatal (_("Unknown machine type: %s\n"), mach
);
1017 /* Return ELF class for a machine type, MACH. */
1020 elf_class (int mach
)
1028 return ELFCLASSNONE
;
1030 non_fatal (_("Unknown machine type: %d\n"), mach
);
1035 /* Return ET_XXX for a type string, TYPE. */
1038 elf_type (const char *type
)
1040 if (strcasecmp (type
, "rel") == 0)
1042 if (strcasecmp (type
, "exec") == 0)
1044 if (strcasecmp (type
, "dyn") == 0)
1046 if (strcasecmp (type
, "none") == 0)
1049 non_fatal (_("Unknown type: %s\n"), type
);
1054 enum command_line_switch
1056 OPTION_INPUT_MACH
= 150,
1062 static struct option options
[] =
1064 {"input-mach", required_argument
, 0, OPTION_INPUT_MACH
},
1065 {"output-mach", required_argument
, 0, OPTION_OUTPUT_MACH
},
1066 {"input-type", required_argument
, 0, OPTION_INPUT_TYPE
},
1067 {"output-type", required_argument
, 0, OPTION_OUTPUT_TYPE
},
1068 {"version", no_argument
, 0, 'v'},
1069 {"help", no_argument
, 0, 'h'},
1070 {0, no_argument
, 0, 0}
1074 usage (FILE *stream
, int exit_status
)
1076 fprintf (stream
, _("Usage: %s [option(s)] {--output-mach <machine>|--output-type <type>} elffile(s)\n"),
1078 fprintf (stream
, _(" Update the ELF header of ELF files\n"));
1079 fprintf (stream
, _(" The options are:\n"));
1080 fprintf (stream
, _("\
1081 --input-mach <machine> Set input machine type to <machine>\n\
1082 --output-mach <machine> Set output machine type to <machine>\n\
1083 --input-type <type> Set input file type to <type>\n\
1084 --output-type <type> Set output file type to <type>\n\
1085 -h --help Display this information\n\
1086 -v --version Display the version number of %s\n\
1089 if (REPORT_BUGS_TO
[0] && exit_status
== 0)
1090 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);
1095 main (int argc
, char ** argv
)
1099 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
1100 setlocale (LC_MESSAGES
, "");
1102 #if defined (HAVE_SETLOCALE)
1103 setlocale (LC_CTYPE
, "");
1105 bindtextdomain (PACKAGE
, LOCALEDIR
);
1106 textdomain (PACKAGE
);
1108 expandargv (&argc
, &argv
);
1110 while ((c
= getopt_long (argc
, argv
, "hv",
1111 options
, (int *) 0)) != EOF
)
1115 case OPTION_INPUT_MACH
:
1116 input_elf_machine
= elf_machine (optarg
);
1117 if (input_elf_machine
< 0)
1119 input_elf_class
= elf_class (input_elf_machine
);
1120 if (input_elf_class
< 0)
1124 case OPTION_OUTPUT_MACH
:
1125 output_elf_machine
= elf_machine (optarg
);
1126 if (output_elf_machine
< 0)
1130 case OPTION_INPUT_TYPE
:
1131 input_elf_type
= elf_type (optarg
);
1132 if (input_elf_type
< 0)
1136 case OPTION_OUTPUT_TYPE
:
1137 output_elf_type
= elf_type (optarg
);
1138 if (output_elf_type
< 0)
1146 print_version (program_name
);
1155 || (output_elf_machine
== -1
1156 && output_elf_type
== -1))
1160 while (optind
< argc
)
1161 status
|= process_file (argv
[optind
++]);