PR ld/11843
[binutils.git] / binutils / elfedit.c
blobce77af4589ebc30f358624f38977aec56c27369b
1 /* elfedit.c -- Update the ELF header of an ELF format file
2 Copyright 2010
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
20 02110-1301, USA. */
22 #include "config.h"
23 #include "sysdep.h"
24 #include <assert.h>
25 #include <sys/stat.h>
27 #if __GNUC__ >= 2
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. */
32 #define BFD64
33 #endif
35 #include "bfd.h"
36 #include "bucomm.h"
38 #include "elf/common.h"
39 #include "elf/external.h"
40 #include "elf/internal.h"
43 #include "aout/ar.h"
45 #include "getopt.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)
66 void
67 non_fatal (const char *message, ...)
69 va_list args;
71 va_start (args, message);
72 fprintf (stderr, _("%s: Error: "), program_name);
73 vfprintf (stderr, message, args);
74 va_end (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);
83 static bfd_vma
84 byte_get_little_endian (unsigned char *field, int size)
86 switch (size)
88 case 1:
89 return *field;
91 case 2:
92 return ((unsigned int) (field[0]))
93 | (((unsigned int) (field[1])) << 8);
95 case 4:
96 return ((unsigned long) (field[0]))
97 | (((unsigned long) (field[1])) << 8)
98 | (((unsigned long) (field[2])) << 16)
99 | (((unsigned long) (field[3])) << 24);
101 case 8:
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);
120 default:
121 non_fatal (_("Unhandled data length: %d\n"), size);
122 abort ();
126 static bfd_vma
127 byte_get_big_endian (unsigned char *field, int size)
129 switch (size)
131 case 1:
132 return *field;
134 case 2:
135 return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);
137 case 4:
138 return ((unsigned long) (field[3]))
139 | (((unsigned long) (field[2])) << 8)
140 | (((unsigned long) (field[1])) << 16)
141 | (((unsigned long) (field[0])) << 24);
143 case 8:
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. */
157 field += 4;
158 return ((unsigned long) (field[3]))
159 | (((unsigned long) (field[2])) << 8)
160 | (((unsigned long) (field[1])) << 16)
161 | (((unsigned long) (field[0])) << 24);
164 default:
165 non_fatal (_("Unhandled data length: %d\n"), size);
166 abort ();
170 static void
171 byte_put_little_endian (unsigned char * field, bfd_vma value, int size)
173 switch (size)
175 case 8:
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;
180 /* Fall through. */
181 case 4:
182 field[3] = (value >> 24) & 0xff;
183 field[2] = (value >> 16) & 0xff;
184 /* Fall through. */
185 case 2:
186 field[1] = (value >> 8) & 0xff;
187 /* Fall through. */
188 case 1:
189 field[0] = value & 0xff;
190 break;
192 default:
193 non_fatal (_("Unhandled data length: %d\n"), size);
194 abort ();
198 static void
199 byte_put_big_endian (unsigned char * field, bfd_vma value, int size)
201 switch (size)
203 case 8:
204 field[7] = value & 0xff;
205 field[6] = (value >> 8) & 0xff;
206 field[5] = (value >> 16) & 0xff;
207 field[4] = (value >> 24) & 0xff;
208 value >>= 16;
209 value >>= 16;
210 /* Fall through. */
211 case 4:
212 field[3] = value & 0xff;
213 field[2] = (value >> 8) & 0xff;
214 value >>= 16;
215 /* Fall through. */
216 case 2:
217 field[1] = value & 0xff;
218 value >>= 8;
219 /* Fall through. */
220 case 1:
221 field[0] = value & 0xff;
222 break;
224 default:
225 non_fatal (_("Unhandled data length: %d\n"), size);
226 abort ();
230 static int
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)
240 non_fatal
241 (_("%s: Not an ELF file - wrong magic bytes at the start\n"),
242 file_name);
243 return 0;
246 if (elf_header.e_ident[EI_VERSION] != EV_CURRENT)
248 non_fatal
249 (_("%s: Unsupported EI_VERSION: %d is not %d\n"),
250 file_name, elf_header.e_ident[EI_VERSION],
251 EV_CURRENT);
252 return 0;
255 /* Return if e_machine is the same as output_elf_machine. */
256 if (output_elf_machine == elf_header.e_machine)
257 return 1;
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)
264 non_fatal
265 (_("%s: Unmatched EI_CLASS: %d is not %d\n"),
266 file_name, class, input_elf_class);
267 return 0;
270 machine = elf_header.e_machine;
272 /* Skip if e_machine doesn't match. */
273 if (input_elf_machine != -1 && machine != input_elf_machine)
275 non_fatal
276 (_("%s: Unmatched e_machine: %d is not %d\n"),
277 file_name, machine, input_elf_machine);
278 return 0;
281 type = elf_header.e_type;
283 /* Skip if e_type doesn't match. */
284 if (input_elf_type != -1 && type != input_elf_type)
286 non_fatal
287 (_("%s: Unmatched e_type: %d is not %d\n"),
288 file_name, type, input_elf_type);
289 return 0;
292 /* Update e_machine and e_type. */
293 switch (class)
295 default:
296 /* We should never get here. */
297 abort ();
298 break;
299 case ELFCLASS32:
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;
305 break;
306 case ELFCLASS64:
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;
312 break;
315 if (status != 1)
316 non_fatal (_("%s: Failed to update ELF header: %s\n"),
317 file_name, strerror (errno));
319 return status;
322 static int
323 get_file_header (FILE * file)
325 /* Read in the identity array. */
326 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
327 return 0;
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 */
334 case ELFDATA2LSB:
335 byte_get = byte_get_little_endian;
336 byte_put = byte_put_little_endian;
337 break;
338 case ELFDATA2MSB:
339 byte_get = byte_get_big_endian;
340 byte_put = byte_put_big_endian;
341 break;
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])
348 default:
349 non_fatal (_("Unsupported EI_CLASS: %d\n"),
350 elf_header.e_ident[EI_CLASS]);
351 return 0;
353 case ELFCLASS32:
354 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT,
355 1, file) != 1)
356 return 0;
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);
373 break;
375 case ELFCLASS64:
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"));
384 return 0;
387 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT,
388 1, file) != 1)
389 return 0;
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);
406 break;
408 return 1;
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. */
415 static int
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);
424 return 1;
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))
434 return 1;
436 return 0;
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. */
443 static char *
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"));
461 return NULL;
463 memcpy (member_file_name, name, name_len);
464 member_file_name[name_len] = '\0';
466 else
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"));
475 return NULL;
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. */
486 struct archive_info
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. */
504 static int
505 setup_archive (struct archive_info * arch, const char * file_name,
506 FILE * file, bfd_boolean is_thin_archive)
508 size_t got;
509 unsigned long size;
511 arch->file_name = strdup (file_name);
512 arch->file = file;
513 arch->index_num = 0;
514 arch->index_array = NULL;
515 arch->sym_table = NULL;
516 arch->sym_size = 0;
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"),
527 file_name);
528 return 1;
530 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
531 if (got != sizeof arch->arhdr)
533 if (got == 0)
534 return 0;
536 non_fatal (_("%s: failed to read archive header\n"), file_name);
537 return 1;
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"),
552 file_name);
553 return 1;
556 /* Read the next archive header. */
557 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
558 if (got != sizeof arch->arhdr)
560 if (got == 0)
561 return 0;
562 non_fatal (_("%s: failed to read archive header following archive index\n"),
563 file_name);
564 return 1;
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"));
578 return 1;
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")
586 , file_name);
587 return 1;
590 if ((arch->longnames_size & 1) != 0)
591 getc (file);
594 return 0;
597 /* Release the memory used for the archive information. */
599 static void
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. */
614 static int
615 setup_nested_archive (struct archive_info * nested_arch, char * member_file_name)
617 FILE * member_file;
619 /* Have we already setup this archive? */
620 if (nested_arch->file_name != NULL
621 && streq (nested_arch->file_name, member_file_name))
622 return 0;
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)
631 return 1;
632 return setup_archive (nested_arch, member_file_name, member_file,
633 FALSE);
636 static char *
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. */
648 static char *
649 get_archive_member_name (struct archive_info * arch,
650 struct archive_info * nested_arch)
652 unsigned long j, k;
654 if (arch->arhdr.ar_name[0] == '/')
656 /* We have a long name. */
657 char * endp;
658 char * member_file_name;
659 char * member_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'))
669 j++;
670 if (arch->longnames[j-1] == '/')
671 j--;
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,
680 arch->longnames + k,
681 j - k);
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,
686 NULL)) != NULL)
688 free (member_file_name);
689 return member_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. */
698 j = 0;
699 while ((arch->arhdr.ar_name[j] != '/') && (j < 16))
700 j++;
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
706 archive ARCH. */
708 static char *
709 get_archive_member_name_at (struct archive_info * arch,
710 unsigned long offset,
711 struct archive_info * nested_arch)
713 size_t got;
715 if (fseek (arch->file, offset, SEEK_SET) != 0)
717 non_fatal (_("%s: failed to seek to next file name\n"),
718 arch->file_name);
719 return NULL;
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"),
725 arch->file_name);
726 return NULL;
728 if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
730 non_fatal (_("%s: did not find a valid archive header\n"),
731 arch->file_name);
732 return NULL;
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)]"). */
744 static char *
745 make_qualified_name (struct archive_info * arch,
746 struct archive_info * nested_arch,
747 char * member_name)
749 size_t len;
750 char * name;
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;
756 name = malloc (len);
757 if (name == NULL)
759 non_fatal (_("Out of memory\n"));
760 return NULL;
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);
767 else
768 snprintf (name, len, "%s(%s)", arch->file_name, member_name);
770 return name;
773 /* Process an ELF archive.
774 On entry the file is positioned just after the ARMAG string. */
776 static int
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;
782 size_t got;
783 int ret;
785 /* The ARCH structure is used to hold information about this archive. */
786 arch.file_name = NULL;
787 arch.file = 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)
803 ret = 1;
804 goto out;
807 ret = 0;
809 while (1)
811 char * name;
812 size_t namelen;
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"),
819 file_name);
820 return 1;
822 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
823 if (got != sizeof arch.arhdr)
825 if (got == 0)
826 break;
827 non_fatal (_("%s: failed to read archive header\n"),
828 file_name);
829 ret = 1;
830 break;
832 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
834 non_fatal (_("%s: did not find a valid archive header\n"),
835 arch.file_name);
836 ret = 1;
837 break;
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)
844 ++archive_file_size;
846 name = get_archive_member_name (&arch, &nested_arch);
847 if (name == NULL)
849 non_fatal (_("%s: bad archive file name\n"), file_name);
850 ret = 1;
851 break;
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);
859 ret = 1;
860 break;
863 if (is_thin_archive && arch.nested_member_origin == 0)
865 /* This is a proxy for an external member of a thin archive. */
866 FILE *member_file;
867 char *member_file_name = adjust_relative_path (file_name,
868 name, namelen);
869 if (member_file_name == NULL)
871 ret = 1;
872 break;
875 member_file = fopen (member_file_name, "r+b");
876 if (member_file == NULL)
878 non_fatal (_("Input file '%s' is not readable\n"),
879 member_file_name);
880 free (member_file_name);
881 ret = 1;
882 break;
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,
900 SEEK_SET) != 0)
902 non_fatal (_("%s: failed to seek to archive member\n"),
903 nested_arch.file_name);
904 ret = 1;
905 break;
908 ret |= process_object (qualified_name, nested_arch.file);
910 else
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);
921 out:
922 if (nested_arch.file != NULL)
923 fclose (nested_arch.file);
924 release_archive (&nested_arch);
925 release_archive (&arch);
927 return ret;
930 static int
931 check_file (const char *file_name, struct stat *statbuf_p)
933 struct stat statbuf;
935 if (statbuf_p == NULL)
936 statbuf_p = &statbuf;
938 if (stat (file_name, statbuf_p) < 0)
940 if (errno == ENOENT)
941 non_fatal (_("'%s': No such file\n"), file_name);
942 else
943 non_fatal (_("Could not locate '%s'. System error message: %s\n"),
944 file_name, strerror (errno));
945 return 1;
948 if (! S_ISREG (statbuf_p->st_mode))
950 non_fatal (_("'%s' is not an ordinary file\n"), file_name);
951 return 1;
954 return 0;
957 static int
958 process_file (const char *file_name)
960 FILE * file;
961 char armag[SARMAG];
962 int ret;
964 if (check_file (file_name, NULL))
965 return 1;
967 file = fopen (file_name, "r+b");
968 if (file == NULL)
970 non_fatal (_("Input file '%s' is not readable\n"), file_name);
971 return 1;
974 if (fread (armag, SARMAG, 1, file) != 1)
976 non_fatal (_("%s: Failed to read file's magic number\n"),
977 file_name);
978 fclose (file);
979 return 1;
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);
986 else
988 rewind (file);
989 archive_file_size = archive_file_offset = 0;
990 ret = process_object (file_name, file);
993 fclose (file);
995 return ret;
998 /* Return EM_XXX for a machine string, MACH. */
1000 static int
1001 elf_machine (const char *mach)
1003 if (strcasecmp (mach, "l1om") == 0)
1004 return EM_L1OM;
1005 if (strcasecmp (mach, "x86_64") == 0)
1006 return EM_X86_64;
1007 if (strcasecmp (mach, "x86-64") == 0)
1008 return EM_X86_64;
1009 if (strcasecmp (mach, "none") == 0)
1010 return EM_NONE;
1012 non_fatal (_("Unknown machine type: %s\n"), mach);
1014 return -1;
1017 /* Return ELF class for a machine type, MACH. */
1019 static int
1020 elf_class (int mach)
1022 switch (mach)
1024 case EM_L1OM:
1025 case EM_X86_64:
1026 return ELFCLASS64;
1027 case EM_NONE:
1028 return ELFCLASSNONE;
1029 default:
1030 non_fatal (_("Unknown machine type: %d\n"), mach);
1031 return -1;
1035 /* Return ET_XXX for a type string, TYPE. */
1037 static int
1038 elf_type (const char *type)
1040 if (strcasecmp (type, "rel") == 0)
1041 return ET_REL;
1042 if (strcasecmp (type, "exec") == 0)
1043 return ET_EXEC;
1044 if (strcasecmp (type, "dyn") == 0)
1045 return ET_DYN;
1046 if (strcasecmp (type, "none") == 0)
1047 return ET_NONE;
1049 non_fatal (_("Unknown type: %s\n"), type);
1051 return -1;
1054 enum command_line_switch
1056 OPTION_INPUT_MACH = 150,
1057 OPTION_OUTPUT_MACH,
1058 OPTION_INPUT_TYPE,
1059 OPTION_OUTPUT_TYPE
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}
1073 static void
1074 usage (FILE *stream, int exit_status)
1076 fprintf (stream, _("Usage: %s [option(s)] {--output-mach <machine>|--output-type <type>} elffile(s)\n"),
1077 program_name);
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\
1088 program_name);
1089 if (REPORT_BUGS_TO[0] && exit_status == 0)
1090 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
1091 exit (exit_status);
1095 main (int argc, char ** argv)
1097 int c, status;
1099 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
1100 setlocale (LC_MESSAGES, "");
1101 #endif
1102 #if defined (HAVE_SETLOCALE)
1103 setlocale (LC_CTYPE, "");
1104 #endif
1105 bindtextdomain (PACKAGE, LOCALEDIR);
1106 textdomain (PACKAGE);
1108 expandargv (&argc, &argv);
1110 while ((c = getopt_long (argc, argv, "hv",
1111 options, (int *) 0)) != EOF)
1113 switch (c)
1115 case OPTION_INPUT_MACH:
1116 input_elf_machine = elf_machine (optarg);
1117 if (input_elf_machine < 0)
1118 return 1;
1119 input_elf_class = elf_class (input_elf_machine);
1120 if (input_elf_class < 0)
1121 return 1;
1122 break;
1124 case OPTION_OUTPUT_MACH:
1125 output_elf_machine = elf_machine (optarg);
1126 if (output_elf_machine < 0)
1127 return 1;
1128 break;
1130 case OPTION_INPUT_TYPE:
1131 input_elf_type = elf_type (optarg);
1132 if (input_elf_type < 0)
1133 return 1;
1134 break;
1136 case OPTION_OUTPUT_TYPE:
1137 output_elf_type = elf_type (optarg);
1138 if (output_elf_type < 0)
1139 return 1;
1140 break;
1142 case 'h':
1143 usage (stdout, 0);
1145 case 'v':
1146 print_version (program_name);
1147 break;
1149 default:
1150 usage (stderr, 1);
1154 if (optind == argc
1155 || (output_elf_machine == -1
1156 && output_elf_type == -1))
1157 usage (stderr, 1);
1159 status = 0;
1160 while (optind < argc)
1161 status |= process_file (argv[optind++]);
1163 return status;