Set SEC_KEEP on section XXX for undefined __start_XXX/__stop_XXX
[binutils.git] / binutils / elfedit.c
blob6e2f8db4268d2b5b6d6f1c22590e574015755b33
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_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)
64 void
65 non_fatal (const char *message, ...)
67 va_list args;
69 va_start (args, message);
70 fprintf (stderr, _("%s: Error: "), program_name);
71 vfprintf (stderr, message, args);
72 va_end (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);
81 static bfd_vma
82 byte_get_little_endian (unsigned char *field, int size)
84 switch (size)
86 case 1:
87 return *field;
89 case 2:
90 return ((unsigned int) (field[0]))
91 | (((unsigned int) (field[1])) << 8);
93 case 4:
94 return ((unsigned long) (field[0]))
95 | (((unsigned long) (field[1])) << 8)
96 | (((unsigned long) (field[2])) << 16)
97 | (((unsigned long) (field[3])) << 24);
99 case 8:
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);
118 default:
119 non_fatal (_("Unhandled data length: %d\n"), size);
120 abort ();
124 static bfd_vma
125 byte_get_big_endian (unsigned char *field, int size)
127 switch (size)
129 case 1:
130 return *field;
132 case 2:
133 return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);
135 case 4:
136 return ((unsigned long) (field[3]))
137 | (((unsigned long) (field[2])) << 8)
138 | (((unsigned long) (field[1])) << 16)
139 | (((unsigned long) (field[0])) << 24);
141 case 8:
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. */
155 field += 4;
156 return ((unsigned long) (field[3]))
157 | (((unsigned long) (field[2])) << 8)
158 | (((unsigned long) (field[1])) << 16)
159 | (((unsigned long) (field[0])) << 24);
162 default:
163 non_fatal (_("Unhandled data length: %d\n"), size);
164 abort ();
168 static void
169 byte_put_little_endian (unsigned char * field, bfd_vma value, int size)
171 switch (size)
173 case 8:
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;
178 /* Fall through. */
179 case 4:
180 field[3] = (value >> 24) & 0xff;
181 field[2] = (value >> 16) & 0xff;
182 /* Fall through. */
183 case 2:
184 field[1] = (value >> 8) & 0xff;
185 /* Fall through. */
186 case 1:
187 field[0] = value & 0xff;
188 break;
190 default:
191 non_fatal (_("Unhandled data length: %d\n"), size);
192 abort ();
196 static void
197 byte_put_big_endian (unsigned char * field, bfd_vma value, int size)
199 switch (size)
201 case 8:
202 field[7] = value & 0xff;
203 field[6] = (value >> 8) & 0xff;
204 field[5] = (value >> 16) & 0xff;
205 field[4] = (value >> 24) & 0xff;
206 value >>= 16;
207 value >>= 16;
208 /* Fall through. */
209 case 4:
210 field[3] = value & 0xff;
211 field[2] = (value >> 8) & 0xff;
212 value >>= 16;
213 /* Fall through. */
214 case 2:
215 field[1] = value & 0xff;
216 value >>= 8;
217 /* Fall through. */
218 case 1:
219 field[0] = value & 0xff;
220 break;
222 default:
223 non_fatal (_("Unhandled data length: %d\n"), size);
224 abort ();
228 static int
229 update_elf_header (const char *file_name, FILE *file)
231 int status;
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)
238 non_fatal
239 (_("%s: Not an ELF file - wrong magic bytes at the start\n"),
240 file_name);
241 return 0;
244 if (elf_header.e_ident[EI_VERSION] != EV_CURRENT)
246 non_fatal
247 (_("%s: Unsupported EI_VERSION: %d is not %d\n"),
248 file_name, elf_header.e_ident[EI_VERSION],
249 EV_CURRENT);
250 return 0;
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)
258 non_fatal
259 (_("%s: Unmatched EI_CLASS: %d is not %d\n"),
260 file_name, elf_header.e_ident[EI_CLASS],
261 input_elf_class);
262 return 0;
265 /* Return if e_machine is the same as output_elf_machine. */
266 if (output_elf_machine == elf_header.e_machine)
267 return 1;
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)
274 non_fatal
275 (_("%s: Unmatched e_machine: %d is not %d\n"),
276 file_name, elf_header.e_machine, input_elf_machine);
277 return 0;
280 /* Update e_machine. */
281 switch (input_elf_class)
283 default:
284 /* We should never get here. */
285 abort ();
286 break;
287 case ELFCLASS32:
288 BYTE_PUT (ehdr32.e_machine, output_elf_machine);
289 status = fwrite (&ehdr32, sizeof (ehdr32), 1, file) == 1;
290 break;
291 case ELFCLASS64:
292 BYTE_PUT (ehdr64.e_machine, output_elf_machine);
293 status = fwrite (&ehdr64, sizeof (ehdr64), 1, file) == 1;
294 break;
297 if (status != 1)
298 non_fatal (_("%s: Failed to update ELF header: %s\n"),
299 file_name, strerror (errno));
301 return status;
304 static int
305 get_file_header (FILE * file)
307 /* Read in the identity array. */
308 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
309 return 0;
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 */
316 case ELFDATA2LSB:
317 byte_get = byte_get_little_endian;
318 byte_put = byte_put_little_endian;
319 break;
320 case ELFDATA2MSB:
321 byte_get = byte_get_big_endian;
322 byte_put = byte_put_big_endian;
323 break;
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])
330 default:
331 non_fatal (_("Unsupported EI_CLASS: %d\n"),
332 elf_header.e_ident[EI_CLASS]);
333 return 0;
335 case ELFCLASS32:
336 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT,
337 1, file) != 1)
338 return 0;
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);
355 break;
357 case ELFCLASS64:
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"));
366 return 0;
369 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT,
370 1, file) != 1)
371 return 0;
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);
388 break;
390 return 1;
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. */
397 static int
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);
406 return 1;
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))
416 return 1;
418 return 0;
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. */
425 static char *
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"));
443 return NULL;
445 memcpy (member_file_name, name, name_len);
446 member_file_name[name_len] = '\0';
448 else
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"));
457 return NULL;
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. */
468 struct archive_info
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. */
486 static int
487 setup_archive (struct archive_info * arch, const char * file_name,
488 FILE * file, bfd_boolean is_thin_archive)
490 size_t got;
491 unsigned long size;
493 arch->file_name = strdup (file_name);
494 arch->file = file;
495 arch->index_num = 0;
496 arch->index_array = NULL;
497 arch->sym_table = NULL;
498 arch->sym_size = 0;
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"),
509 file_name);
510 return 1;
512 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
513 if (got != sizeof arch->arhdr)
515 if (got == 0)
516 return 0;
518 non_fatal (_("%s: failed to read archive header\n"), file_name);
519 return 1;
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"),
534 file_name);
535 return 1;
538 /* Read the next archive header. */
539 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
540 if (got != sizeof arch->arhdr)
542 if (got == 0)
543 return 0;
544 non_fatal (_("%s: failed to read archive header following archive index\n"),
545 file_name);
546 return 1;
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"));
560 return 1;
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")
568 , file_name);
569 return 1;
572 if ((arch->longnames_size & 1) != 0)
573 getc (file);
576 return 0;
579 /* Release the memory used for the archive information. */
581 static void
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. */
596 static int
597 setup_nested_archive (struct archive_info * nested_arch, char * member_file_name)
599 FILE * member_file;
601 /* Have we already setup this archive? */
602 if (nested_arch->file_name != NULL
603 && streq (nested_arch->file_name, member_file_name))
604 return 0;
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)
613 return 1;
614 return setup_archive (nested_arch, member_file_name, member_file,
615 FALSE);
618 static char *
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. */
630 static char *
631 get_archive_member_name (struct archive_info * arch,
632 struct archive_info * nested_arch)
634 unsigned long j, k;
636 if (arch->arhdr.ar_name[0] == '/')
638 /* We have a long name. */
639 char * endp;
640 char * member_file_name;
641 char * member_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'))
651 j++;
652 if (arch->longnames[j-1] == '/')
653 j--;
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,
662 arch->longnames + k,
663 j - k);
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,
668 NULL)) != NULL)
670 free (member_file_name);
671 return member_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. */
680 j = 0;
681 while ((arch->arhdr.ar_name[j] != '/') && (j < 16))
682 j++;
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
688 archive ARCH. */
690 static char *
691 get_archive_member_name_at (struct archive_info * arch,
692 unsigned long offset,
693 struct archive_info * nested_arch)
695 size_t got;
697 if (fseek (arch->file, offset, SEEK_SET) != 0)
699 non_fatal (_("%s: failed to seek to next file name\n"),
700 arch->file_name);
701 return NULL;
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"),
707 arch->file_name);
708 return NULL;
710 if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
712 non_fatal (_("%s: did not find a valid archive header\n"),
713 arch->file_name);
714 return NULL;
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)]"). */
726 static char *
727 make_qualified_name (struct archive_info * arch,
728 struct archive_info * nested_arch,
729 char * member_name)
731 size_t len;
732 char * name;
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;
738 name = malloc (len);
739 if (name == NULL)
741 non_fatal (_("Out of memory\n"));
742 return NULL;
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);
749 else
750 snprintf (name, len, "%s(%s)", arch->file_name, member_name);
752 return name;
755 /* Process an ELF archive.
756 On entry the file is positioned just after the ARMAG string. */
758 static int
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;
764 size_t got;
765 size_t file_name_size;
766 int ret;
768 /* The ARCH structure is used to hold information about this archive. */
769 arch.file_name = NULL;
770 arch.file = 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)
786 ret = 1;
787 goto out;
790 file_name_size = strlen (file_name);
791 ret = 0;
793 while (1)
795 char * name;
796 size_t namelen;
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"),
803 file_name);
804 return 1;
806 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
807 if (got != sizeof arch.arhdr)
809 if (got == 0)
810 break;
811 non_fatal (_("%s: failed to read archive header\n"),
812 file_name);
813 ret = 1;
814 break;
816 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
818 non_fatal (_("%s: did not find a valid archive header\n"),
819 arch.file_name);
820 ret = 1;
821 break;
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)
828 ++archive_file_size;
830 name = get_archive_member_name (&arch, &nested_arch);
831 if (name == NULL)
833 non_fatal (_("%s: bad archive file name\n"), file_name);
834 ret = 1;
835 break;
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);
843 ret = 1;
844 break;
847 if (is_thin_archive && arch.nested_member_origin == 0)
849 /* This is a proxy for an external member of a thin archive. */
850 FILE *member_file;
851 char *member_file_name = adjust_relative_path (file_name,
852 name, namelen);
853 if (member_file_name == NULL)
855 ret = 1;
856 break;
859 member_file = fopen (member_file_name, "r+b");
860 if (member_file == NULL)
862 non_fatal (_("Input file '%s' is not readable\n"),
863 member_file_name);
864 free (member_file_name);
865 ret = 1;
866 break;
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,
884 SEEK_SET) != 0)
886 non_fatal (_("%s: failed to seek to archive member\n"),
887 nested_arch.file_name);
888 ret = 1;
889 break;
892 ret |= process_object (qualified_name, nested_arch.file);
894 else
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);
905 out:
906 if (nested_arch.file != NULL)
907 fclose (nested_arch.file);
908 release_archive (&nested_arch);
909 release_archive (&arch);
911 return ret;
914 static int
915 check_file (const char *file_name, struct stat *statbuf_p)
917 struct stat statbuf;
919 if (statbuf_p == NULL)
920 statbuf_p = &statbuf;
922 if (stat (file_name, statbuf_p) < 0)
924 if (errno == ENOENT)
925 non_fatal (_("'%s': No such file\n"), file_name);
926 else
927 non_fatal (_("Could not locate '%s'. System error message: %s\n"),
928 file_name, strerror (errno));
929 return 1;
932 if (! S_ISREG (statbuf_p->st_mode))
934 non_fatal (_("'%s' is not an ordinary file\n"), file_name);
935 return 1;
938 return 0;
941 static int
942 process_file (const char *file_name)
944 FILE * file;
945 char armag[SARMAG];
946 int ret;
948 if (check_file (file_name, NULL))
949 return 1;
951 file = fopen (file_name, "r+b");
952 if (file == NULL)
954 non_fatal (_("Input file '%s' is not readable\n"), file_name);
955 return 1;
958 if (fread (armag, SARMAG, 1, file) != 1)
960 non_fatal (_("%s: Failed to read file's magic number\n"),
961 file_name);
962 fclose (file);
963 return 1;
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);
970 else
972 rewind (file);
973 archive_file_size = archive_file_offset = 0;
974 ret = process_object (file_name, file);
977 fclose (file);
979 return ret;
982 /* Return EM_XXX for a machine string, MACH. */
984 static int
985 elf_machine (const char *mach)
987 if (strcasecmp (mach, "l1om") == 0)
988 return EM_L1OM;
989 if (strcasecmp (mach, "x86_64") == 0)
990 return EM_X86_64;
991 if (strcasecmp (mach, "x86-64") == 0)
992 return EM_X86_64;
993 if (strcasecmp (mach, "none") == 0)
994 return EM_NONE;
996 non_fatal (_("Unknown machine type: %s\n"), mach);
998 return -1;
1001 /* Return ELF class for a machine type, MACH. */
1003 static int
1004 elf_class (int mach)
1006 switch (mach)
1008 case EM_L1OM:
1009 case EM_X86_64:
1010 return ELFCLASS64;
1011 case EM_NONE:
1012 return ELFCLASSNONE;
1013 default:
1014 non_fatal (_("Unknown machine type: %d\n"), mach);
1015 return -1;
1019 enum command_line_switch
1021 OPTION_INPUT_MACH = 150,
1022 OPTION_OUTPUT_MACH
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}
1034 static void
1035 usage (FILE *stream, int exit_status)
1037 fprintf (stream, _("Usage: %s [option(s)] --output-mach <machine> elffile(s)\n"),
1038 program_name);
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\
1047 program_name);
1048 if (REPORT_BUGS_TO[0] && exit_status == 0)
1049 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
1050 exit (exit_status);
1054 main (int argc, char ** argv)
1056 int c, status;
1058 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
1059 setlocale (LC_MESSAGES, "");
1060 #endif
1061 #if defined (HAVE_SETLOCALE)
1062 setlocale (LC_CTYPE, "");
1063 #endif
1064 bindtextdomain (PACKAGE, LOCALEDIR);
1065 textdomain (PACKAGE);
1067 expandargv (&argc, &argv);
1069 while ((c = getopt_long (argc, argv, "hv",
1070 options, (int *) 0)) != EOF)
1072 switch (c)
1074 case OPTION_INPUT_MACH:
1075 input_elf_machine = elf_machine (optarg);
1076 if (input_elf_machine < 0)
1077 return 1;
1078 input_elf_class = elf_class (input_elf_machine);
1079 if (input_elf_class < 0)
1080 return 1;
1081 break;
1083 case OPTION_OUTPUT_MACH:
1084 output_elf_machine = elf_machine (optarg);
1085 if (output_elf_machine < 0)
1086 return 1;
1087 break;
1089 case 'h':
1090 usage (stdout, 0);
1092 case 'v':
1093 print_version (program_name);
1094 break;
1096 default:
1097 usage (stderr, 1);
1101 if (optind == argc || output_elf_machine == -1)
1102 usage (stderr, 1);
1104 status = 0;
1105 while (optind < argc)
1106 status |= process_file (argv[optind++]);
1108 return status;