Add --input-type and --output-type to elfedit
[deliverable/binutils-gdb.git] / binutils / elfedit.c
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
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;
61
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)
65
66 void
67 non_fatal (const char *message, ...)
68 {
69 va_list args;
70
71 va_start (args, message);
72 fprintf (stderr, _("%s: Error: "), program_name);
73 vfprintf (stderr, message, args);
74 va_end (args);
75 }
76
77 #define BYTE_GET(field) byte_get (field, sizeof (field))
78 #define BYTE_PUT(field, val) byte_put (field, val, sizeof (field))
79
80 static bfd_vma (*byte_get) (unsigned char *, int);
81 static void (*byte_put) (unsigned char *, bfd_vma, int);
82
83 static bfd_vma
84 byte_get_little_endian (unsigned char *field, int size)
85 {
86 switch (size)
87 {
88 case 1:
89 return *field;
90
91 case 2:
92 return ((unsigned int) (field[0]))
93 | (((unsigned int) (field[1])) << 8);
94
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);
100
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);
119
120 default:
121 non_fatal (_("Unhandled data length: %d\n"), size);
122 abort ();
123 }
124 }
125
126 static bfd_vma
127 byte_get_big_endian (unsigned char *field, int size)
128 {
129 switch (size)
130 {
131 case 1:
132 return *field;
133
134 case 2:
135 return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);
136
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);
142
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)
154 {
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);
162 }
163
164 default:
165 non_fatal (_("Unhandled data length: %d\n"), size);
166 abort ();
167 }
168 }
169
170 static void
171 byte_put_little_endian (unsigned char * field, bfd_vma value, int size)
172 {
173 switch (size)
174 {
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;
191
192 default:
193 non_fatal (_("Unhandled data length: %d\n"), size);
194 abort ();
195 }
196 }
197
198 static void
199 byte_put_big_endian (unsigned char * field, bfd_vma value, int size)
200 {
201 switch (size)
202 {
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;
223
224 default:
225 non_fatal (_("Unhandled data length: %d\n"), size);
226 abort ();
227 }
228 }
229
230 static int
231 update_elf_header (const char *file_name, FILE *file)
232 {
233 int class, machine, type, status;
234
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)
239 {
240 non_fatal
241 (_("%s: Not an ELF file - wrong magic bytes at the start\n"),
242 file_name);
243 return 0;
244 }
245
246 if (elf_header.e_ident[EI_VERSION] != EV_CURRENT)
247 {
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;
253 }
254
255 /* Return if e_machine is the same as output_elf_machine. */
256 if (output_elf_machine == elf_header.e_machine)
257 return 1;
258
259 class = elf_header.e_ident[EI_CLASS];
260
261 /* Skip if class doesn't match. */
262 if (input_elf_class != -1 && class != input_elf_class)
263 {
264 non_fatal
265 (_("%s: Unmatched EI_CLASS: %d is not %d\n"),
266 file_name, class, input_elf_class);
267 return 0;
268 }
269
270 machine = elf_header.e_machine;
271
272 /* Skip if e_machine doesn't match. */
273 if (input_elf_machine != -1 && machine != input_elf_machine)
274 {
275 non_fatal
276 (_("%s: Unmatched e_machine: %d is not %d\n"),
277 file_name, machine, input_elf_machine);
278 return 0;
279 }
280
281 type = elf_header.e_type;
282
283 /* Skip if e_type doesn't match. */
284 if (input_elf_type != -1 && type != input_elf_type)
285 {
286 non_fatal
287 (_("%s: Unmatched e_type: %d is not %d\n"),
288 file_name, type, input_elf_type);
289 return 0;
290 }
291
292 /* Update e_machine and e_type. */
293 switch (class)
294 {
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;
313 }
314
315 if (status != 1)
316 non_fatal (_("%s: Failed to update ELF header: %s\n"),
317 file_name, strerror (errno));
318
319 return status;
320 }
321
322 static int
323 get_file_header (FILE * file)
324 {
325 /* Read in the identity array. */
326 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
327 return 0;
328
329 /* Determine how to read the rest of the header. */
330 switch (elf_header.e_ident[EI_DATA])
331 {
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;
342 }
343
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])
347 {
348 default:
349 non_fatal (_("Unsupported EI_CLASS: %d\n"),
350 elf_header.e_ident[EI_CLASS]);
351 return 0;
352
353 case ELFCLASS32:
354 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT,
355 1, file) != 1)
356 return 0;
357
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);
371
372 memcpy (&ehdr32, &elf_header, EI_NIDENT);
373 break;
374
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)
381 {
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;
385 }
386
387 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT,
388 1, file) != 1)
389 return 0;
390
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);
404
405 memcpy (&ehdr64, &elf_header, EI_NIDENT);
406 break;
407 }
408 return 1;
409 }
410
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. */
414
415 static int
416 process_object (const char *file_name, FILE *file)
417 {
418 /* Rememeber where we are. */
419 long offset = ftell (file);
420
421 if (! get_file_header (file))
422 {
423 non_fatal (_("%s: Failed to read ELF header\n"), file_name);
424 return 1;
425 }
426
427 /* Go to the position of the ELF header. */
428 if (fseek (file, offset, SEEK_SET) != 0)
429 {
430 non_fatal (_("%s: Failed to seek to ELF header\n"), file_name);
431 }
432
433 if (! update_elf_header (file_name, file))
434 return 1;
435
436 return 0;
437 }
438
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. */
442
443 static char *
444 adjust_relative_path (const char *file_name, char * name, int name_len)
445 {
446 char * member_file_name;
447 const char * base_name = lbasename (file_name);
448
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)
456 {
457 member_file_name = malloc (name_len + 1);
458 if (member_file_name == NULL)
459 {
460 non_fatal (_("Out of memory\n"));
461 return NULL;
462 }
463 memcpy (member_file_name, name, name_len);
464 member_file_name[name_len] = '\0';
465 }
466 else
467 {
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)
473 {
474 non_fatal (_("Out of memory\n"));
475 return NULL;
476 }
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';
480 }
481 return member_file_name;
482 }
483
484 /* Structure to hold information about an archive file. */
485
486 struct archive_info
487 {
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. */
500 };
501
502 /* Read the symbol table and long-name table from an archive. */
503
504 static int
505 setup_archive (struct archive_info * arch, const char * file_name,
506 FILE * file, bfd_boolean is_thin_archive)
507 {
508 size_t got;
509 unsigned long size;
510
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;
522
523 /* Read the first archive member header. */
524 if (fseek (file, SARMAG, SEEK_SET) != 0)
525 {
526 non_fatal (_("%s: failed to seek to first archive header\n"),
527 file_name);
528 return 1;
529 }
530 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
531 if (got != sizeof arch->arhdr)
532 {
533 if (got == 0)
534 return 0;
535
536 non_fatal (_("%s: failed to read archive header\n"), file_name);
537 return 1;
538 }
539
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/ "))
543 {
544 size = strtoul (arch->arhdr.ar_size, NULL, 10);
545 size = size + (size & 1);
546
547 arch->next_arhdr_offset += sizeof arch->arhdr + size;
548
549 if (fseek (file, size, SEEK_CUR) != 0)
550 {
551 non_fatal (_("%s: failed to skip archive symbol table\n"),
552 file_name);
553 return 1;
554 }
555
556 /* Read the next archive header. */
557 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
558 if (got != sizeof arch->arhdr)
559 {
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;
565 }
566 }
567
568 if (const_strneq (arch->arhdr.ar_name, "// "))
569 {
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;
573
574 arch->longnames = malloc (arch->longnames_size);
575 if (arch->longnames == NULL)
576 {
577 non_fatal (_("Out of memory reading long symbol names in archive\n"));
578 return 1;
579 }
580
581 if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
582 {
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;
588 }
589
590 if ((arch->longnames_size & 1) != 0)
591 getc (file);
592 }
593
594 return 0;
595 }
596
597 /* Release the memory used for the archive information. */
598
599 static void
600 release_archive (struct archive_info * arch)
601 {
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);
610 }
611
612 /* Open and setup a nested archive, if not already open. */
613
614 static int
615 setup_nested_archive (struct archive_info * nested_arch, char * member_file_name)
616 {
617 FILE * member_file;
618
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;
623
624 /* Close previous file and discard cached information. */
625 if (nested_arch->file != NULL)
626 fclose (nested_arch->file);
627 release_archive (nested_arch);
628
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);
634 }
635
636 static char *
637 get_archive_member_name_at (struct archive_info * arch,
638 unsigned long offset,
639 struct archive_info * nested_arch);
640
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. */
647
648 static char *
649 get_archive_member_name (struct archive_info * arch,
650 struct archive_info * nested_arch)
651 {
652 unsigned long j, k;
653
654 if (arch->arhdr.ar_name[0] == '/')
655 {
656 /* We have a long name. */
657 char * endp;
658 char * member_file_name;
659 char * member_name;
660
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);
665
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';
673
674 if (!arch->is_thin_archive || arch->nested_member_origin == 0)
675 return arch->longnames + k;
676
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)
687 {
688 free (member_file_name);
689 return member_name;
690 }
691 free (member_file_name);
692
693 /* Last resort: just return the name of the nested archive. */
694 return arch->longnames + k;
695 }
696
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;
703 }
704
705 /* Get the name of an archive member at a given OFFSET within an
706 archive ARCH. */
707
708 static char *
709 get_archive_member_name_at (struct archive_info * arch,
710 unsigned long offset,
711 struct archive_info * nested_arch)
712 {
713 size_t got;
714
715 if (fseek (arch->file, offset, SEEK_SET) != 0)
716 {
717 non_fatal (_("%s: failed to seek to next file name\n"),
718 arch->file_name);
719 return NULL;
720 }
721 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
722 if (got != sizeof arch->arhdr)
723 {
724 non_fatal (_("%s: failed to read archive header\n"),
725 arch->file_name);
726 return NULL;
727 }
728 if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
729 {
730 non_fatal (_("%s: did not find a valid archive header\n"),
731 arch->file_name);
732 return NULL;
733 }
734
735 return get_archive_member_name (arch, nested_arch);
736 }
737
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)]"). */
743
744 static char *
745 make_qualified_name (struct archive_info * arch,
746 struct archive_info * nested_arch,
747 char * member_name)
748 {
749 size_t len;
750 char * name;
751
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;
755
756 name = malloc (len);
757 if (name == NULL)
758 {
759 non_fatal (_("Out of memory\n"));
760 return NULL;
761 }
762
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);
769
770 return name;
771 }
772
773 /* Process an ELF archive.
774 On entry the file is positioned just after the ARMAG string. */
775
776 static int
777 process_archive (const char * file_name, FILE * file,
778 bfd_boolean is_thin_archive)
779 {
780 struct archive_info arch;
781 struct archive_info nested_arch;
782 size_t got;
783 size_t file_name_size;
784 int ret;
785
786 /* The ARCH structure is used to hold information about this archive. */
787 arch.file_name = NULL;
788 arch.file = NULL;
789 arch.index_array = NULL;
790 arch.sym_table = NULL;
791 arch.longnames = NULL;
792
793 /* The NESTED_ARCH structure is used as a single-item cache of information
794 about a nested archive (when members of a thin archive reside within
795 another regular archive file). */
796 nested_arch.file_name = NULL;
797 nested_arch.file = NULL;
798 nested_arch.index_array = NULL;
799 nested_arch.sym_table = NULL;
800 nested_arch.longnames = NULL;
801
802 if (setup_archive (&arch, file_name, file, is_thin_archive) != 0)
803 {
804 ret = 1;
805 goto out;
806 }
807
808 file_name_size = strlen (file_name);
809 ret = 0;
810
811 while (1)
812 {
813 char * name;
814 size_t namelen;
815 char * qualified_name;
816
817 /* Read the next archive header. */
818 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
819 {
820 non_fatal (_("%s: failed to seek to next archive header\n"),
821 file_name);
822 return 1;
823 }
824 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
825 if (got != sizeof arch.arhdr)
826 {
827 if (got == 0)
828 break;
829 non_fatal (_("%s: failed to read archive header\n"),
830 file_name);
831 ret = 1;
832 break;
833 }
834 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
835 {
836 non_fatal (_("%s: did not find a valid archive header\n"),
837 arch.file_name);
838 ret = 1;
839 break;
840 }
841
842 arch.next_arhdr_offset += sizeof arch.arhdr;
843
844 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
845 if (archive_file_size & 01)
846 ++archive_file_size;
847
848 name = get_archive_member_name (&arch, &nested_arch);
849 if (name == NULL)
850 {
851 non_fatal (_("%s: bad archive file name\n"), file_name);
852 ret = 1;
853 break;
854 }
855 namelen = strlen (name);
856
857 qualified_name = make_qualified_name (&arch, &nested_arch, name);
858 if (qualified_name == NULL)
859 {
860 non_fatal (_("%s: bad archive file name\n"), file_name);
861 ret = 1;
862 break;
863 }
864
865 if (is_thin_archive && arch.nested_member_origin == 0)
866 {
867 /* This is a proxy for an external member of a thin archive. */
868 FILE *member_file;
869 char *member_file_name = adjust_relative_path (file_name,
870 name, namelen);
871 if (member_file_name == NULL)
872 {
873 ret = 1;
874 break;
875 }
876
877 member_file = fopen (member_file_name, "r+b");
878 if (member_file == NULL)
879 {
880 non_fatal (_("Input file '%s' is not readable\n"),
881 member_file_name);
882 free (member_file_name);
883 ret = 1;
884 break;
885 }
886
887 archive_file_offset = arch.nested_member_origin;
888
889 ret |= process_object (qualified_name, member_file);
890
891 fclose (member_file);
892 free (member_file_name);
893 }
894 else if (is_thin_archive)
895 {
896 /* This is a proxy for a member of a nested archive. */
897 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
898
899 /* The nested archive file will have been opened and setup by
900 get_archive_member_name. */
901 if (fseek (nested_arch.file, archive_file_offset,
902 SEEK_SET) != 0)
903 {
904 non_fatal (_("%s: failed to seek to archive member\n"),
905 nested_arch.file_name);
906 ret = 1;
907 break;
908 }
909
910 ret |= process_object (qualified_name, nested_arch.file);
911 }
912 else
913 {
914 archive_file_offset = arch.next_arhdr_offset;
915 arch.next_arhdr_offset += archive_file_size;
916
917 ret |= process_object (qualified_name, file);
918 }
919
920 free (qualified_name);
921 }
922
923 out:
924 if (nested_arch.file != NULL)
925 fclose (nested_arch.file);
926 release_archive (&nested_arch);
927 release_archive (&arch);
928
929 return ret;
930 }
931
932 static int
933 check_file (const char *file_name, struct stat *statbuf_p)
934 {
935 struct stat statbuf;
936
937 if (statbuf_p == NULL)
938 statbuf_p = &statbuf;
939
940 if (stat (file_name, statbuf_p) < 0)
941 {
942 if (errno == ENOENT)
943 non_fatal (_("'%s': No such file\n"), file_name);
944 else
945 non_fatal (_("Could not locate '%s'. System error message: %s\n"),
946 file_name, strerror (errno));
947 return 1;
948 }
949
950 if (! S_ISREG (statbuf_p->st_mode))
951 {
952 non_fatal (_("'%s' is not an ordinary file\n"), file_name);
953 return 1;
954 }
955
956 return 0;
957 }
958
959 static int
960 process_file (const char *file_name)
961 {
962 FILE * file;
963 char armag[SARMAG];
964 int ret;
965
966 if (check_file (file_name, NULL))
967 return 1;
968
969 file = fopen (file_name, "r+b");
970 if (file == NULL)
971 {
972 non_fatal (_("Input file '%s' is not readable\n"), file_name);
973 return 1;
974 }
975
976 if (fread (armag, SARMAG, 1, file) != 1)
977 {
978 non_fatal (_("%s: Failed to read file's magic number\n"),
979 file_name);
980 fclose (file);
981 return 1;
982 }
983
984 if (memcmp (armag, ARMAG, SARMAG) == 0)
985 ret = process_archive (file_name, file, FALSE);
986 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
987 ret = process_archive (file_name, file, TRUE);
988 else
989 {
990 rewind (file);
991 archive_file_size = archive_file_offset = 0;
992 ret = process_object (file_name, file);
993 }
994
995 fclose (file);
996
997 return ret;
998 }
999
1000 /* Return EM_XXX for a machine string, MACH. */
1001
1002 static int
1003 elf_machine (const char *mach)
1004 {
1005 if (strcasecmp (mach, "l1om") == 0)
1006 return EM_L1OM;
1007 if (strcasecmp (mach, "x86_64") == 0)
1008 return EM_X86_64;
1009 if (strcasecmp (mach, "x86-64") == 0)
1010 return EM_X86_64;
1011 if (strcasecmp (mach, "none") == 0)
1012 return EM_NONE;
1013
1014 non_fatal (_("Unknown machine type: %s\n"), mach);
1015
1016 return -1;
1017 }
1018
1019 /* Return ELF class for a machine type, MACH. */
1020
1021 static int
1022 elf_class (int mach)
1023 {
1024 switch (mach)
1025 {
1026 case EM_L1OM:
1027 case EM_X86_64:
1028 return ELFCLASS64;
1029 case EM_NONE:
1030 return ELFCLASSNONE;
1031 default:
1032 non_fatal (_("Unknown machine type: %d\n"), mach);
1033 return -1;
1034 }
1035 }
1036
1037 /* Return ET_XXX for a type string, TYPE. */
1038
1039 static int
1040 elf_type (const char *type)
1041 {
1042 if (strcasecmp (type, "rel") == 0)
1043 return ET_REL;
1044 if (strcasecmp (type, "exec") == 0)
1045 return ET_EXEC;
1046 if (strcasecmp (type, "dyn") == 0)
1047 return ET_DYN;
1048 if (strcasecmp (type, "none") == 0)
1049 return ET_NONE;
1050
1051 non_fatal (_("Unknown type: %s\n"), type);
1052
1053 return -1;
1054 }
1055
1056 enum command_line_switch
1057 {
1058 OPTION_INPUT_MACH = 150,
1059 OPTION_OUTPUT_MACH,
1060 OPTION_INPUT_TYPE,
1061 OPTION_OUTPUT_TYPE
1062 };
1063
1064 static struct option options[] =
1065 {
1066 {"input-mach", required_argument, 0, OPTION_INPUT_MACH},
1067 {"output-mach", required_argument, 0, OPTION_OUTPUT_MACH},
1068 {"input-type", required_argument, 0, OPTION_INPUT_TYPE},
1069 {"output-type", required_argument, 0, OPTION_OUTPUT_TYPE},
1070 {"version", no_argument, 0, 'v'},
1071 {"help", no_argument, 0, 'h'},
1072 {0, no_argument, 0, 0}
1073 };
1074
1075 static void
1076 usage (FILE *stream, int exit_status)
1077 {
1078 fprintf (stream, _("Usage: %s [option(s)] {--output-mach <machine>|--output-type <type>} elffile(s)\n"),
1079 program_name);
1080 fprintf (stream, _(" Update the ELF header of ELF files\n"));
1081 fprintf (stream, _(" The options are:\n"));
1082 fprintf (stream, _("\
1083 --input-mach <machine> Set input machine type to <machine>\n\
1084 --output-mach <machine> Set output machine type to <machine>\n\
1085 --input-type <type> Set input file type to <type>\n\
1086 --output-type <type> Set output file type to <type>\n\
1087 -h --help Display this information\n\
1088 -v --version Display the version number of %s\n\
1089 "),
1090 program_name);
1091 if (REPORT_BUGS_TO[0] && exit_status == 0)
1092 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
1093 exit (exit_status);
1094 }
1095
1096 int
1097 main (int argc, char ** argv)
1098 {
1099 int c, status;
1100
1101 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
1102 setlocale (LC_MESSAGES, "");
1103 #endif
1104 #if defined (HAVE_SETLOCALE)
1105 setlocale (LC_CTYPE, "");
1106 #endif
1107 bindtextdomain (PACKAGE, LOCALEDIR);
1108 textdomain (PACKAGE);
1109
1110 expandargv (&argc, &argv);
1111
1112 while ((c = getopt_long (argc, argv, "hv",
1113 options, (int *) 0)) != EOF)
1114 {
1115 switch (c)
1116 {
1117 case OPTION_INPUT_MACH:
1118 input_elf_machine = elf_machine (optarg);
1119 if (input_elf_machine < 0)
1120 return 1;
1121 input_elf_class = elf_class (input_elf_machine);
1122 if (input_elf_class < 0)
1123 return 1;
1124 break;
1125
1126 case OPTION_OUTPUT_MACH:
1127 output_elf_machine = elf_machine (optarg);
1128 if (output_elf_machine < 0)
1129 return 1;
1130 break;
1131
1132 case OPTION_INPUT_TYPE:
1133 input_elf_type = elf_type (optarg);
1134 if (input_elf_type < 0)
1135 return 1;
1136 break;
1137
1138 case OPTION_OUTPUT_TYPE:
1139 output_elf_type = elf_type (optarg);
1140 if (output_elf_type < 0)
1141 return 1;
1142 break;
1143
1144 case 'h':
1145 usage (stdout, 0);
1146
1147 case 'v':
1148 print_version (program_name);
1149 break;
1150
1151 default:
1152 usage (stderr, 1);
1153 }
1154 }
1155
1156 if (optind == argc
1157 || (output_elf_machine == -1
1158 && output_elf_type == -1))
1159 usage (stderr, 1);
1160
1161 status = 0;
1162 while (optind < argc)
1163 status |= process_file (argv[optind++]);
1164
1165 return status;
1166 }
This page took 0.071826 seconds and 5 git commands to generate.