Add elfedit
[deliverable/binutils-gdb.git] / binutils / elfedit.c
CommitLineData
30fd33bb
L
1/* elfedit.c -- Update the ELF header of an ELF format file
2 Copyright 2010
3 Free Software Foundation, Inc.
4
5 This file is part of GNU Binutils.
6
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.
11
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.
16
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. */
21\f
22#include "config.h"
23#include "sysdep.h"
24#include <assert.h>
25#include <sys/stat.h>
26
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
34
35#include "bfd.h"
36#include "bucomm.h"
37
38#include "elf/common.h"
39#include "elf/external.h"
40#include "elf/internal.h"
41
42
43#include "aout/ar.h"
44
45#include "getopt.h"
46#include "libiberty.h"
47#include "safe-ctype.h"
48#include "filenames.h"
49
50char * program_name = "elfedit";
51static long archive_file_offset;
52static unsigned long archive_file_size;
53static Elf_Internal_Ehdr elf_header;
54static Elf32_External_Ehdr ehdr32;
55static Elf64_External_Ehdr ehdr64;
56static int input_elf_machine = -1;
57static int output_elf_machine = -1;
58static int input_elf_class = -1;
59
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)
63
64void
65non_fatal (const char *message, ...)
66{
67 va_list args;
68
69 va_start (args, message);
70 fprintf (stderr, _("%s: Error: "), program_name);
71 vfprintf (stderr, message, args);
72 va_end (args);
73}
74
75#define BYTE_GET(field) byte_get (field, sizeof (field))
76#define BYTE_PUT(field, val) byte_put (field, val, sizeof (field))
77
78static bfd_vma (*byte_get) (unsigned char *, int);
79static void (*byte_put) (unsigned char *, bfd_vma, int);
80
81static bfd_vma
82byte_get_little_endian (unsigned char *field, int size)
83{
84 switch (size)
85 {
86 case 1:
87 return *field;
88
89 case 2:
90 return ((unsigned int) (field[0]))
91 | (((unsigned int) (field[1])) << 8);
92
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);
98
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);
117
118 default:
119 non_fatal (_("Unhandled data length: %d\n"), size);
120 abort ();
121 }
122}
123
124static bfd_vma
125byte_get_big_endian (unsigned char *field, int size)
126{
127 switch (size)
128 {
129 case 1:
130 return *field;
131
132 case 2:
133 return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);
134
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);
140
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)
152 {
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);
160 }
161
162 default:
163 non_fatal (_("Unhandled data length: %d\n"), size);
164 abort ();
165 }
166}
167
168static void
169byte_put_little_endian (unsigned char * field, bfd_vma value, int size)
170{
171 switch (size)
172 {
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;
189
190 default:
191 non_fatal (_("Unhandled data length: %d\n"), size);
192 abort ();
193 }
194}
195
196static void
197byte_put_big_endian (unsigned char * field, bfd_vma value, int size)
198{
199 switch (size)
200 {
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;
221
222 default:
223 non_fatal (_("Unhandled data length: %d\n"), size);
224 abort ();
225 }
226}
227
228static int
229update_elf_header (const char *file_name, FILE *file)
230{
231 int status;
232
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)
237 {
238 non_fatal
239 (_("%s: Not an ELF file - wrong magic bytes at the start\n"),
240 file_name);
241 return 0;
242 }
243
244 if (elf_header.e_ident[EI_VERSION] != EV_CURRENT)
245 {
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;
251 }
252
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
257 if (elf_header.e_ident[EI_CLASS] != input_elf_class)
258 {
259 non_fatal
260 (_("%s: Unmatched EI_CLASS: %d is not %d\n"),
261 file_name, elf_header.e_ident[EI_CLASS],
262 input_elf_class);
263 return 0;
264 }
265
266 /* Return if e_machine is the same as output_elf_machine. */
267 if (output_elf_machine == elf_header.e_machine)
268 return 1;
269
270 /* Skip if e_machine doesn't match. */
271 if (input_elf_machine == -1)
272 input_elf_machine = elf_header.e_machine;
273 else if (elf_header.e_machine != input_elf_machine)
274 {
275 non_fatal
276 (_("%s: Unmatched e_machine: %d is not %d\n"),
277 file_name, elf_header.e_machine, input_elf_machine);
278 return 0;
279 }
280
281 /* Update e_machine. */
282 switch (input_elf_class)
283 {
284 default:
285 /* We should never get here. */
286 abort ();
287 break;
288 case ELFCLASS32:
289 BYTE_PUT (ehdr32.e_machine, output_elf_machine);
290 status = fwrite (&ehdr32, sizeof (ehdr32), 1, file) == 1;
291 break;
292 case ELFCLASS64:
293 BYTE_PUT (ehdr64.e_machine, output_elf_machine);
294 status = fwrite (&ehdr64, sizeof (ehdr64), 1, file) == 1;
295 break;
296 }
297
298 if (status != 1)
299 non_fatal (_("%s: Failed to update ELF header: %s\n"),
300 file_name, strerror (errno));
301
302 return status;
303}
304
305static int
306get_file_header (FILE * file)
307{
308 /* Read in the identity array. */
309 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
310 return 0;
311
312 /* Determine how to read the rest of the header. */
313 switch (elf_header.e_ident[EI_DATA])
314 {
315 default: /* fall through */
316 case ELFDATANONE: /* fall through */
317 case ELFDATA2LSB:
318 byte_get = byte_get_little_endian;
319 byte_put = byte_put_little_endian;
320 break;
321 case ELFDATA2MSB:
322 byte_get = byte_get_big_endian;
323 byte_put = byte_put_big_endian;
324 break;
325 }
326
327 /* Read in the rest of the header. For now we only support 32 bit
328 and 64 bit ELF files. */
329 switch (elf_header.e_ident[EI_CLASS])
330 {
331 default:
332 non_fatal (_("Unsupported EI_CLASS: %d\n"),
333 elf_header.e_ident[EI_CLASS]);
334 return 0;
335
336 case ELFCLASS32:
337 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT,
338 1, file) != 1)
339 return 0;
340
341 elf_header.e_type = BYTE_GET (ehdr32.e_type);
342 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
343 elf_header.e_version = BYTE_GET (ehdr32.e_version);
344 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
345 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
346 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
347 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
348 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
349 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
350 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
351 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
352 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
353 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
354
355 memcpy (&ehdr32, &elf_header, EI_NIDENT);
356 break;
357
358 case ELFCLASS64:
359 /* If we have been compiled with sizeof (bfd_vma) == 4, then
360 we will not be able to cope with the 64bit data found in
361 64 ELF files. Detect this now and abort before we start
362 overwriting things. */
363 if (sizeof (bfd_vma) < 8)
364 {
365 non_fatal (_("This executable has been built without support for a\n\
36664 bit data type and so it cannot process 64 bit ELF files.\n"));
367 return 0;
368 }
369
370 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT,
371 1, file) != 1)
372 return 0;
373
374 elf_header.e_type = BYTE_GET (ehdr64.e_type);
375 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
376 elf_header.e_version = BYTE_GET (ehdr64.e_version);
377 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
378 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
379 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
380 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
381 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
382 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
383 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
384 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
385 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
386 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
387
388 memcpy (&ehdr64, &elf_header, EI_NIDENT);
389 break;
390 }
391 return 1;
392}
393
394/* Process one ELF object file according to the command line options.
395 This file may actually be stored in an archive. The file is
396 positioned at the start of the ELF object. */
397
398static int
399process_object (const char *file_name, FILE *file)
400{
401 /* Rememeber where we are. */
402 long offset = ftell (file);
403
404 if (! get_file_header (file))
405 {
406 non_fatal (_("%s: Failed to read ELF header\n"), file_name);
407 return 1;
408 }
409
410 /* Go to the position of the ELF header. */
411 if (fseek (file, offset, SEEK_SET) != 0)
412 {
413 non_fatal (_("%s: Failed to seek to ELF header\n"), file_name);
414 }
415
416 if (! update_elf_header (file_name, file))
417 return 1;
418
419 return 0;
420}
421
422/* Return the path name for a proxy entry in a thin archive, adjusted relative
423 to the path name of the thin archive itself if necessary. Always returns
424 a pointer to malloc'ed memory. */
425
426static char *
427adjust_relative_path (const char *file_name, char * name, int name_len)
428{
429 char * member_file_name;
430 const char * base_name = lbasename (file_name);
431
432 /* This is a proxy entry for a thin archive member.
433 If the extended name table contains an absolute path
434 name, or if the archive is in the current directory,
435 use the path name as given. Otherwise, we need to
436 find the member relative to the directory where the
437 archive is located. */
438 if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
439 {
440 member_file_name = malloc (name_len + 1);
441 if (member_file_name == NULL)
442 {
443 non_fatal (_("Out of memory\n"));
444 return NULL;
445 }
446 memcpy (member_file_name, name, name_len);
447 member_file_name[name_len] = '\0';
448 }
449 else
450 {
451 /* Concatenate the path components of the archive file name
452 to the relative path name from the extended name table. */
453 size_t prefix_len = base_name - file_name;
454 member_file_name = malloc (prefix_len + name_len + 1);
455 if (member_file_name == NULL)
456 {
457 non_fatal (_("Out of memory\n"));
458 return NULL;
459 }
460 memcpy (member_file_name, file_name, prefix_len);
461 memcpy (member_file_name + prefix_len, name, name_len);
462 member_file_name[prefix_len + name_len] = '\0';
463 }
464 return member_file_name;
465}
466
467/* Structure to hold information about an archive file. */
468
469struct archive_info
470{
471 char * file_name; /* Archive file name. */
472 FILE * file; /* Open file descriptor. */
473 unsigned long index_num; /* Number of symbols in table. */
474 unsigned long * index_array; /* The array of member offsets. */
475 char * sym_table; /* The symbol table. */
476 unsigned long sym_size; /* Size of the symbol table. */
477 char * longnames; /* The long file names table. */
478 unsigned long longnames_size; /* Size of the long file names table. */
479 unsigned long nested_member_origin; /* Origin in the nested archive of the current member. */
480 unsigned long next_arhdr_offset; /* Offset of the next archive header. */
481 bfd_boolean is_thin_archive; /* TRUE if this is a thin archive. */
482 struct ar_hdr arhdr; /* Current archive header. */
483};
484
485/* Read the symbol table and long-name table from an archive. */
486
487static int
488setup_archive (struct archive_info * arch, const char * file_name,
489 FILE * file, bfd_boolean is_thin_archive)
490{
491 size_t got;
492 unsigned long size;
493
494 arch->file_name = strdup (file_name);
495 arch->file = file;
496 arch->index_num = 0;
497 arch->index_array = NULL;
498 arch->sym_table = NULL;
499 arch->sym_size = 0;
500 arch->longnames = NULL;
501 arch->longnames_size = 0;
502 arch->nested_member_origin = 0;
503 arch->is_thin_archive = is_thin_archive;
504 arch->next_arhdr_offset = SARMAG;
505
506 /* Read the first archive member header. */
507 if (fseek (file, SARMAG, SEEK_SET) != 0)
508 {
509 non_fatal (_("%s: failed to seek to first archive header\n"),
510 file_name);
511 return 1;
512 }
513 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
514 if (got != sizeof arch->arhdr)
515 {
516 if (got == 0)
517 return 0;
518
519 non_fatal (_("%s: failed to read archive header\n"), file_name);
520 return 1;
521 }
522
523 /* See if this is the archive symbol table. */
524 if (const_strneq (arch->arhdr.ar_name, "/ ")
525 || const_strneq (arch->arhdr.ar_name, "/SYM64/ "))
526 {
527 size = strtoul (arch->arhdr.ar_size, NULL, 10);
528 size = size + (size & 1);
529
530 arch->next_arhdr_offset += sizeof arch->arhdr + size;
531
532 if (fseek (file, size, SEEK_CUR) != 0)
533 {
534 non_fatal (_("%s: failed to skip archive symbol table\n"),
535 file_name);
536 return 1;
537 }
538
539 /* Read the next archive header. */
540 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
541 if (got != sizeof arch->arhdr)
542 {
543 if (got == 0)
544 return 0;
545 non_fatal (_("%s: failed to read archive header following archive index\n"),
546 file_name);
547 return 1;
548 }
549 }
550
551 if (const_strneq (arch->arhdr.ar_name, "// "))
552 {
553 /* This is the archive string table holding long member names. */
554 arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
555 arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
556
557 arch->longnames = malloc (arch->longnames_size);
558 if (arch->longnames == NULL)
559 {
560 non_fatal (_("Out of memory reading long symbol names in archive\n"));
561 return 1;
562 }
563
564 if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
565 {
566 free (arch->longnames);
567 arch->longnames = NULL;
568 non_fatal (_("%s: failed to read long symbol name string table\n")
569 , file_name);
570 return 1;
571 }
572
573 if ((arch->longnames_size & 1) != 0)
574 getc (file);
575 }
576
577 return 0;
578}
579
580/* Release the memory used for the archive information. */
581
582static void
583release_archive (struct archive_info * arch)
584{
585 if (arch->file_name != NULL)
586 free (arch->file_name);
587 if (arch->index_array != NULL)
588 free (arch->index_array);
589 if (arch->sym_table != NULL)
590 free (arch->sym_table);
591 if (arch->longnames != NULL)
592 free (arch->longnames);
593}
594
595/* Open and setup a nested archive, if not already open. */
596
597static int
598setup_nested_archive (struct archive_info * nested_arch, char * member_file_name)
599{
600 FILE * member_file;
601
602 /* Have we already setup this archive? */
603 if (nested_arch->file_name != NULL
604 && streq (nested_arch->file_name, member_file_name))
605 return 0;
606
607 /* Close previous file and discard cached information. */
608 if (nested_arch->file != NULL)
609 fclose (nested_arch->file);
610 release_archive (nested_arch);
611
612 member_file = fopen (member_file_name, "r+b");
613 if (member_file == NULL)
614 return 1;
615 return setup_archive (nested_arch, member_file_name, member_file,
616 FALSE);
617}
618
619static char *
620get_archive_member_name_at (struct archive_info * arch,
621 unsigned long offset,
622 struct archive_info * nested_arch);
623
624/* Get the name of an archive member from the current archive header.
625 For simple names, this will modify the ar_name field of the current
626 archive header. For long names, it will return a pointer to the
627 longnames table. For nested archives, it will open the nested archive
628 and get the name recursively. NESTED_ARCH is a single-entry cache so
629 we don't keep rereading the same information from a nested archive. */
630
631static char *
632get_archive_member_name (struct archive_info * arch,
633 struct archive_info * nested_arch)
634{
635 unsigned long j, k;
636
637 if (arch->arhdr.ar_name[0] == '/')
638 {
639 /* We have a long name. */
640 char * endp;
641 char * member_file_name;
642 char * member_name;
643
644 arch->nested_member_origin = 0;
645 k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
646 if (arch->is_thin_archive && endp != NULL && * endp == ':')
647 arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
648
649 while ((j < arch->longnames_size)
650 && (arch->longnames[j] != '\n')
651 && (arch->longnames[j] != '\0'))
652 j++;
653 if (arch->longnames[j-1] == '/')
654 j--;
655 arch->longnames[j] = '\0';
656
657 if (!arch->is_thin_archive || arch->nested_member_origin == 0)
658 return arch->longnames + k;
659
660 /* This is a proxy for a member of a nested archive.
661 Find the name of the member in that archive. */
662 member_file_name = adjust_relative_path (arch->file_name,
663 arch->longnames + k,
664 j - k);
665 if (member_file_name != NULL
666 && setup_nested_archive (nested_arch, member_file_name) == 0
667 && (member_name = get_archive_member_name_at (nested_arch,
668 arch->nested_member_origin,
669 NULL)) != NULL)
670 {
671 free (member_file_name);
672 return member_name;
673 }
674 free (member_file_name);
675
676 /* Last resort: just return the name of the nested archive. */
677 return arch->longnames + k;
678 }
679
680 /* We have a normal (short) name. */
681 j = 0;
682 while ((arch->arhdr.ar_name[j] != '/') && (j < 16))
683 j++;
684 arch->arhdr.ar_name[j] = '\0';
685 return arch->arhdr.ar_name;
686}
687
688/* Get the name of an archive member at a given OFFSET within an
689 archive ARCH. */
690
691static char *
692get_archive_member_name_at (struct archive_info * arch,
693 unsigned long offset,
694 struct archive_info * nested_arch)
695{
696 size_t got;
697
698 if (fseek (arch->file, offset, SEEK_SET) != 0)
699 {
700 non_fatal (_("%s: failed to seek to next file name\n"),
701 arch->file_name);
702 return NULL;
703 }
704 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
705 if (got != sizeof arch->arhdr)
706 {
707 non_fatal (_("%s: failed to read archive header\n"),
708 arch->file_name);
709 return NULL;
710 }
711 if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
712 {
713 non_fatal (_("%s: did not find a valid archive header\n"),
714 arch->file_name);
715 return NULL;
716 }
717
718 return get_archive_member_name (arch, nested_arch);
719}
720
721/* Construct a string showing the name of the archive member, qualified
722 with the name of the containing archive file. For thin archives, we
723 use square brackets to denote the indirection. For nested archives,
724 we show the qualified name of the external member inside the square
725 brackets (e.g., "thin.a[normal.a(foo.o)]"). */
726
727static char *
728make_qualified_name (struct archive_info * arch,
729 struct archive_info * nested_arch,
730 char * member_name)
731{
732 size_t len;
733 char * name;
734
735 len = strlen (arch->file_name) + strlen (member_name) + 3;
736 if (arch->is_thin_archive && arch->nested_member_origin != 0)
737 len += strlen (nested_arch->file_name) + 2;
738
739 name = malloc (len);
740 if (name == NULL)
741 {
742 non_fatal (_("Out of memory\n"));
743 return NULL;
744 }
745
746 if (arch->is_thin_archive && arch->nested_member_origin != 0)
747 snprintf (name, len, "%s[%s(%s)]", arch->file_name, nested_arch->file_name, member_name);
748 else if (arch->is_thin_archive)
749 snprintf (name, len, "%s[%s]", arch->file_name, member_name);
750 else
751 snprintf (name, len, "%s(%s)", arch->file_name, member_name);
752
753 return name;
754}
755
756/* Process an ELF archive.
757 On entry the file is positioned just after the ARMAG string. */
758
759static int
760process_archive (const char * file_name, FILE * file,
761 bfd_boolean is_thin_archive)
762{
763 struct archive_info arch;
764 struct archive_info nested_arch;
765 size_t got;
766 size_t file_name_size;
767 int ret;
768
769 /* The ARCH structure is used to hold information about this archive. */
770 arch.file_name = NULL;
771 arch.file = NULL;
772 arch.index_array = NULL;
773 arch.sym_table = NULL;
774 arch.longnames = NULL;
775
776 /* The NESTED_ARCH structure is used as a single-item cache of information
777 about a nested archive (when members of a thin archive reside within
778 another regular archive file). */
779 nested_arch.file_name = NULL;
780 nested_arch.file = NULL;
781 nested_arch.index_array = NULL;
782 nested_arch.sym_table = NULL;
783 nested_arch.longnames = NULL;
784
785 if (setup_archive (&arch, file_name, file, is_thin_archive) != 0)
786 {
787 ret = 1;
788 goto out;
789 }
790
791 file_name_size = strlen (file_name);
792 ret = 0;
793
794 while (1)
795 {
796 char * name;
797 size_t namelen;
798 char * qualified_name;
799
800 /* Read the next archive header. */
801 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
802 {
803 non_fatal (_("%s: failed to seek to next archive header\n"),
804 file_name);
805 return 1;
806 }
807 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
808 if (got != sizeof arch.arhdr)
809 {
810 if (got == 0)
811 break;
812 non_fatal (_("%s: failed to read archive header\n"),
813 file_name);
814 ret = 1;
815 break;
816 }
817 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
818 {
819 non_fatal (_("%s: did not find a valid archive header\n"),
820 arch.file_name);
821 ret = 1;
822 break;
823 }
824
825 arch.next_arhdr_offset += sizeof arch.arhdr;
826
827 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
828 if (archive_file_size & 01)
829 ++archive_file_size;
830
831 name = get_archive_member_name (&arch, &nested_arch);
832 if (name == NULL)
833 {
834 non_fatal (_("%s: bad archive file name\n"), file_name);
835 ret = 1;
836 break;
837 }
838 namelen = strlen (name);
839
840 qualified_name = make_qualified_name (&arch, &nested_arch, name);
841 if (qualified_name == NULL)
842 {
843 non_fatal (_("%s: bad archive file name\n"), file_name);
844 ret = 1;
845 break;
846 }
847
848 if (is_thin_archive && arch.nested_member_origin == 0)
849 {
850 /* This is a proxy for an external member of a thin archive. */
851 FILE *member_file;
852 char *member_file_name = adjust_relative_path (file_name,
853 name, namelen);
854 if (member_file_name == NULL)
855 {
856 ret = 1;
857 break;
858 }
859
860 member_file = fopen (member_file_name, "r+b");
861 if (member_file == NULL)
862 {
863 non_fatal (_("Input file '%s' is not readable\n"),
864 member_file_name);
865 free (member_file_name);
866 ret = 1;
867 break;
868 }
869
870 archive_file_offset = arch.nested_member_origin;
871
872 ret |= process_object (qualified_name, member_file);
873
874 fclose (member_file);
875 free (member_file_name);
876 }
877 else if (is_thin_archive)
878 {
879 /* This is a proxy for a member of a nested archive. */
880 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
881
882 /* The nested archive file will have been opened and setup by
883 get_archive_member_name. */
884 if (fseek (nested_arch.file, archive_file_offset,
885 SEEK_SET) != 0)
886 {
887 non_fatal (_("%s: failed to seek to archive member\n"),
888 nested_arch.file_name);
889 ret = 1;
890 break;
891 }
892
893 ret |= process_object (qualified_name, nested_arch.file);
894 }
895 else
896 {
897 archive_file_offset = arch.next_arhdr_offset;
898 arch.next_arhdr_offset += archive_file_size;
899
900 ret |= process_object (qualified_name, file);
901 }
902
903 free (qualified_name);
904 }
905
906 out:
907 if (nested_arch.file != NULL)
908 fclose (nested_arch.file);
909 release_archive (&nested_arch);
910 release_archive (&arch);
911
912 return ret;
913}
914
915static int
916check_file (const char *file_name, struct stat *statbuf_p)
917{
918 struct stat statbuf;
919
920 if (statbuf_p == NULL)
921 statbuf_p = &statbuf;
922
923 if (stat (file_name, statbuf_p) < 0)
924 {
925 if (errno == ENOENT)
926 non_fatal (_("'%s': No such file\n"), file_name);
927 else
928 non_fatal (_("Could not locate '%s'. System error message: %s\n"),
929 file_name, strerror (errno));
930 return 1;
931 }
932
933 if (! S_ISREG (statbuf_p->st_mode))
934 {
935 non_fatal (_("'%s' is not an ordinary file\n"), file_name);
936 return 1;
937 }
938
939 return 0;
940}
941
942static int
943process_file (const char *file_name)
944{
945 FILE * file;
946 char armag[SARMAG];
947 int ret;
948
949 if (check_file (file_name, NULL))
950 return 1;
951
952 file = fopen (file_name, "r+b");
953 if (file == NULL)
954 {
955 non_fatal (_("Input file '%s' is not readable\n"), file_name);
956 return 1;
957 }
958
959 if (fread (armag, SARMAG, 1, file) != 1)
960 {
961 non_fatal (_("%s: Failed to read file's magic number\n"),
962 file_name);
963 fclose (file);
964 return 1;
965 }
966
967 if (memcmp (armag, ARMAG, SARMAG) == 0)
968 ret = process_archive (file_name, file, FALSE);
969 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
970 ret = process_archive (file_name, file, TRUE);
971 else
972 {
973 rewind (file);
974 archive_file_size = archive_file_offset = 0;
975 ret = process_object (file_name, file);
976 }
977
978 fclose (file);
979
980 return ret;
981}
982
983/* Return EM_XXX for a machine string, MACH. */
984
985static int
986elf_machine (const char *mach)
987{
988 if (strcasecmp (mach, "l1om") == 0)
989 return EM_L1OM;
990 if (strcasecmp (mach, "x86_64") == 0)
991 return EM_X86_64;
992 if (strcasecmp (mach, "x86-64") == 0)
993 return EM_X86_64;
994 if (strcasecmp (mach, "none") == 0)
995 return EM_NONE;
996
997 non_fatal (_("Unknown machine type: %s\n"), mach);
998
999 return -1;
1000}
1001
1002/* Return ELF class for a machine type, MACH. */
1003
1004static int
1005elf_class (int mach)
1006{
1007 switch (mach)
1008 {
1009 case EM_L1OM:
1010 case EM_X86_64:
1011 return ELFCLASS64;
1012 case EM_NONE:
1013 return ELFCLASSNONE;
1014 default:
1015 non_fatal (_("Unknown machine type: %d\n"), mach);
1016 return -1;
1017 }
1018}
1019
1020enum command_line_switch
1021 {
1022 OPTION_INPUT_MACH = 150,
1023 OPTION_OUTPUT_MACH
1024 };
1025
1026static struct option options[] =
1027{
1028 {"input-mach", required_argument, 0, OPTION_INPUT_MACH},
1029 {"output-mach", required_argument, 0, OPTION_OUTPUT_MACH},
1030 {"version", no_argument, 0, 'v'},
1031 {"help", no_argument, 0, 'h'},
1032 {0, no_argument, 0, 0}
1033};
1034
1035static void
1036usage (FILE *stream, int exit_status)
1037{
1038 fprintf (stream, _("Usage: %s [option(s)] --output-mach <machine> elffile(s)\n"),
1039 program_name);
1040 fprintf (stream, _(" Update the ELF header of ELF files\n"));
1041 fprintf (stream, _(" The options are:\n"));
1042 fprintf (stream, _("\
1043 --input-mach <machine> Set input machine type to <machine>\n\
1044 --output-mach <machine> Set output machine type to <machine>\n\
1045 -h --help Display this information\n\
1046 -v --version Display the version number of %s\n\
1047"),
1048 program_name);
1049 if (REPORT_BUGS_TO[0] && exit_status == 0)
1050 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
1051 exit (exit_status);
1052}
1053
1054int
1055main (int argc, char ** argv)
1056{
1057 int c, status;
1058
1059#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
1060 setlocale (LC_MESSAGES, "");
1061#endif
1062#if defined (HAVE_SETLOCALE)
1063 setlocale (LC_CTYPE, "");
1064#endif
1065 bindtextdomain (PACKAGE, LOCALEDIR);
1066 textdomain (PACKAGE);
1067
1068 expandargv (&argc, &argv);
1069
1070 while ((c = getopt_long (argc, argv, "hv",
1071 options, (int *) 0)) != EOF)
1072 {
1073 switch (c)
1074 {
1075 case OPTION_INPUT_MACH:
1076 input_elf_machine = elf_machine (optarg);
1077 if (input_elf_machine < 0)
1078 return 1;
1079 input_elf_class = elf_class (input_elf_machine);
1080 if (input_elf_class < 0)
1081 return 1;
1082 break;
1083
1084 case OPTION_OUTPUT_MACH:
1085 output_elf_machine = elf_machine (optarg);
1086 if (output_elf_machine < 0)
1087 return 1;
1088 break;
1089
1090 case 'h':
1091 usage (stdout, 0);
1092
1093 case 'v':
1094 print_version (program_name);
1095 break;
1096
1097 default:
1098 usage (stderr, 1);
1099 }
1100 }
1101
1102 if (optind == argc || output_elf_machine == -1)
1103 usage (stderr, 1);
1104
1105 status = 0;
1106 while (optind < argc)
1107 status |= process_file (argv[optind++]);
1108
1109 return status;
1110}
This page took 0.062744 seconds and 4 git commands to generate.