GDB crash with empty executable name (MinGW).
[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];
71a72a84 256 else if (elf_header.e_ident[EI_CLASS] != input_elf_class)
30fd33bb
L
257 {
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;
263 }
264
265 /* Return if e_machine is the same as output_elf_machine. */
266 if (output_elf_machine == elf_header.e_machine)
267 return 1;
268
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)
273 {
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;
278 }
279
280 /* Update e_machine. */
281 switch (input_elf_class)
282 {
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;
295 }
296
297 if (status != 1)
298 non_fatal (_("%s: Failed to update ELF header: %s\n"),
299 file_name, strerror (errno));
300
301 return status;
302}
303
304static int
305get_file_header (FILE * file)
306{
307 /* Read in the identity array. */
308 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
309 return 0;
310
311 /* Determine how to read the rest of the header. */
312 switch (elf_header.e_ident[EI_DATA])
313 {
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;
324 }
325
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])
329 {
330 default:
331 non_fatal (_("Unsupported EI_CLASS: %d\n"),
332 elf_header.e_ident[EI_CLASS]);
333 return 0;
334
335 case ELFCLASS32:
336 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT,
337 1, file) != 1)
338 return 0;
339
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);
353
354 memcpy (&ehdr32, &elf_header, EI_NIDENT);
355 break;
356
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)
363 {
364 non_fatal (_("This executable has been built without support for a\n\
36564 bit data type and so it cannot process 64 bit ELF files.\n"));
366 return 0;
367 }
368
369 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT,
370 1, file) != 1)
371 return 0;
372
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);
386
387 memcpy (&ehdr64, &elf_header, EI_NIDENT);
388 break;
389 }
390 return 1;
391}
392
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. */
396
397static int
398process_object (const char *file_name, FILE *file)
399{
400 /* Rememeber where we are. */
401 long offset = ftell (file);
402
403 if (! get_file_header (file))
404 {
405 non_fatal (_("%s: Failed to read ELF header\n"), file_name);
406 return 1;
407 }
408
409 /* Go to the position of the ELF header. */
410 if (fseek (file, offset, SEEK_SET) != 0)
411 {
412 non_fatal (_("%s: Failed to seek to ELF header\n"), file_name);
413 }
414
415 if (! update_elf_header (file_name, file))
416 return 1;
417
418 return 0;
419}
420
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. */
424
425static char *
426adjust_relative_path (const char *file_name, char * name, int name_len)
427{
428 char * member_file_name;
429 const char * base_name = lbasename (file_name);
430
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)
438 {
439 member_file_name = malloc (name_len + 1);
440 if (member_file_name == NULL)
441 {
442 non_fatal (_("Out of memory\n"));
443 return NULL;
444 }
445 memcpy (member_file_name, name, name_len);
446 member_file_name[name_len] = '\0';
447 }
448 else
449 {
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)
455 {
456 non_fatal (_("Out of memory\n"));
457 return NULL;
458 }
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';
462 }
463 return member_file_name;
464}
465
466/* Structure to hold information about an archive file. */
467
468struct archive_info
469{
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. */
482};
483
484/* Read the symbol table and long-name table from an archive. */
485
486static int
487setup_archive (struct archive_info * arch, const char * file_name,
488 FILE * file, bfd_boolean is_thin_archive)
489{
490 size_t got;
491 unsigned long size;
492
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;
504
505 /* Read the first archive member header. */
506 if (fseek (file, SARMAG, SEEK_SET) != 0)
507 {
508 non_fatal (_("%s: failed to seek to first archive header\n"),
509 file_name);
510 return 1;
511 }
512 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
513 if (got != sizeof arch->arhdr)
514 {
515 if (got == 0)
516 return 0;
517
518 non_fatal (_("%s: failed to read archive header\n"), file_name);
519 return 1;
520 }
521
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/ "))
525 {
526 size = strtoul (arch->arhdr.ar_size, NULL, 10);
527 size = size + (size & 1);
528
529 arch->next_arhdr_offset += sizeof arch->arhdr + size;
530
531 if (fseek (file, size, SEEK_CUR) != 0)
532 {
533 non_fatal (_("%s: failed to skip archive symbol table\n"),
534 file_name);
535 return 1;
536 }
537
538 /* Read the next archive header. */
539 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
540 if (got != sizeof arch->arhdr)
541 {
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;
547 }
548 }
549
550 if (const_strneq (arch->arhdr.ar_name, "// "))
551 {
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;
555
556 arch->longnames = malloc (arch->longnames_size);
557 if (arch->longnames == NULL)
558 {
559 non_fatal (_("Out of memory reading long symbol names in archive\n"));
560 return 1;
561 }
562
563 if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
564 {
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;
570 }
571
572 if ((arch->longnames_size & 1) != 0)
573 getc (file);
574 }
575
576 return 0;
577}
578
579/* Release the memory used for the archive information. */
580
581static void
582release_archive (struct archive_info * arch)
583{
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);
592}
593
594/* Open and setup a nested archive, if not already open. */
595
596static int
597setup_nested_archive (struct archive_info * nested_arch, char * member_file_name)
598{
599 FILE * member_file;
600
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;
605
606 /* Close previous file and discard cached information. */
607 if (nested_arch->file != NULL)
608 fclose (nested_arch->file);
609 release_archive (nested_arch);
610
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);
616}
617
618static char *
619get_archive_member_name_at (struct archive_info * arch,
620 unsigned long offset,
621 struct archive_info * nested_arch);
622
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. */
629
630static char *
631get_archive_member_name (struct archive_info * arch,
632 struct archive_info * nested_arch)
633{
634 unsigned long j, k;
635
636 if (arch->arhdr.ar_name[0] == '/')
637 {
638 /* We have a long name. */
639 char * endp;
640 char * member_file_name;
641 char * member_name;
642
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);
647
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';
655
656 if (!arch->is_thin_archive || arch->nested_member_origin == 0)
657 return arch->longnames + k;
658
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)
669 {
670 free (member_file_name);
671 return member_name;
672 }
673 free (member_file_name);
674
675 /* Last resort: just return the name of the nested archive. */
676 return arch->longnames + k;
677 }
678
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;
685}
686
687/* Get the name of an archive member at a given OFFSET within an
688 archive ARCH. */
689
690static char *
691get_archive_member_name_at (struct archive_info * arch,
692 unsigned long offset,
693 struct archive_info * nested_arch)
694{
695 size_t got;
696
697 if (fseek (arch->file, offset, SEEK_SET) != 0)
698 {
699 non_fatal (_("%s: failed to seek to next file name\n"),
700 arch->file_name);
701 return NULL;
702 }
703 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
704 if (got != sizeof arch->arhdr)
705 {
706 non_fatal (_("%s: failed to read archive header\n"),
707 arch->file_name);
708 return NULL;
709 }
710 if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
711 {
712 non_fatal (_("%s: did not find a valid archive header\n"),
713 arch->file_name);
714 return NULL;
715 }
716
717 return get_archive_member_name (arch, nested_arch);
718}
719
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)]"). */
725
726static char *
727make_qualified_name (struct archive_info * arch,
728 struct archive_info * nested_arch,
729 char * member_name)
730{
731 size_t len;
732 char * name;
733
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;
737
738 name = malloc (len);
739 if (name == NULL)
740 {
741 non_fatal (_("Out of memory\n"));
742 return NULL;
743 }
744
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);
751
752 return name;
753}
754
755/* Process an ELF archive.
756 On entry the file is positioned just after the ARMAG string. */
757
758static int
759process_archive (const char * file_name, FILE * file,
760 bfd_boolean is_thin_archive)
761{
762 struct archive_info arch;
763 struct archive_info nested_arch;
764 size_t got;
765 size_t file_name_size;
766 int ret;
767
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;
774
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;
783
784 if (setup_archive (&arch, file_name, file, is_thin_archive) != 0)
785 {
786 ret = 1;
787 goto out;
788 }
789
790 file_name_size = strlen (file_name);
791 ret = 0;
792
793 while (1)
794 {
795 char * name;
796 size_t namelen;
797 char * qualified_name;
798
799 /* Read the next archive header. */
800 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
801 {
802 non_fatal (_("%s: failed to seek to next archive header\n"),
803 file_name);
804 return 1;
805 }
806 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
807 if (got != sizeof arch.arhdr)
808 {
809 if (got == 0)
810 break;
811 non_fatal (_("%s: failed to read archive header\n"),
812 file_name);
813 ret = 1;
814 break;
815 }
816 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
817 {
818 non_fatal (_("%s: did not find a valid archive header\n"),
819 arch.file_name);
820 ret = 1;
821 break;
822 }
823
824 arch.next_arhdr_offset += sizeof arch.arhdr;
825
826 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
827 if (archive_file_size & 01)
828 ++archive_file_size;
829
830 name = get_archive_member_name (&arch, &nested_arch);
831 if (name == NULL)
832 {
833 non_fatal (_("%s: bad archive file name\n"), file_name);
834 ret = 1;
835 break;
836 }
837 namelen = strlen (name);
838
839 qualified_name = make_qualified_name (&arch, &nested_arch, name);
840 if (qualified_name == NULL)
841 {
842 non_fatal (_("%s: bad archive file name\n"), file_name);
843 ret = 1;
844 break;
845 }
846
847 if (is_thin_archive && arch.nested_member_origin == 0)
848 {
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)
854 {
855 ret = 1;
856 break;
857 }
858
859 member_file = fopen (member_file_name, "r+b");
860 if (member_file == NULL)
861 {
862 non_fatal (_("Input file '%s' is not readable\n"),
863 member_file_name);
864 free (member_file_name);
865 ret = 1;
866 break;
867 }
868
869 archive_file_offset = arch.nested_member_origin;
870
871 ret |= process_object (qualified_name, member_file);
872
873 fclose (member_file);
874 free (member_file_name);
875 }
876 else if (is_thin_archive)
877 {
878 /* This is a proxy for a member of a nested archive. */
879 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
880
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)
885 {
886 non_fatal (_("%s: failed to seek to archive member\n"),
887 nested_arch.file_name);
888 ret = 1;
889 break;
890 }
891
892 ret |= process_object (qualified_name, nested_arch.file);
893 }
894 else
895 {
896 archive_file_offset = arch.next_arhdr_offset;
897 arch.next_arhdr_offset += archive_file_size;
898
899 ret |= process_object (qualified_name, file);
900 }
901
902 free (qualified_name);
903 }
904
905 out:
906 if (nested_arch.file != NULL)
907 fclose (nested_arch.file);
908 release_archive (&nested_arch);
909 release_archive (&arch);
910
911 return ret;
912}
913
914static int
915check_file (const char *file_name, struct stat *statbuf_p)
916{
917 struct stat statbuf;
918
919 if (statbuf_p == NULL)
920 statbuf_p = &statbuf;
921
922 if (stat (file_name, statbuf_p) < 0)
923 {
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;
930 }
931
932 if (! S_ISREG (statbuf_p->st_mode))
933 {
934 non_fatal (_("'%s' is not an ordinary file\n"), file_name);
935 return 1;
936 }
937
938 return 0;
939}
940
941static int
942process_file (const char *file_name)
943{
944 FILE * file;
945 char armag[SARMAG];
946 int ret;
947
948 if (check_file (file_name, NULL))
949 return 1;
950
951 file = fopen (file_name, "r+b");
952 if (file == NULL)
953 {
954 non_fatal (_("Input file '%s' is not readable\n"), file_name);
955 return 1;
956 }
957
958 if (fread (armag, SARMAG, 1, file) != 1)
959 {
960 non_fatal (_("%s: Failed to read file's magic number\n"),
961 file_name);
962 fclose (file);
963 return 1;
964 }
965
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
971 {
972 rewind (file);
973 archive_file_size = archive_file_offset = 0;
974 ret = process_object (file_name, file);
975 }
976
977 fclose (file);
978
979 return ret;
980}
981
982/* Return EM_XXX for a machine string, MACH. */
983
984static int
985elf_machine (const char *mach)
986{
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;
995
996 non_fatal (_("Unknown machine type: %s\n"), mach);
997
998 return -1;
999}
1000
1001/* Return ELF class for a machine type, MACH. */
1002
1003static int
1004elf_class (int mach)
1005{
1006 switch (mach)
1007 {
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;
1016 }
1017}
1018
1019enum command_line_switch
1020 {
1021 OPTION_INPUT_MACH = 150,
1022 OPTION_OUTPUT_MACH
1023 };
1024
1025static struct option options[] =
1026{
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}
1032};
1033
1034static void
1035usage (FILE *stream, int exit_status)
1036{
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\
1046"),
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);
1051}
1052
1053int
1054main (int argc, char ** argv)
1055{
1056 int c, status;
1057
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);
1066
1067 expandargv (&argc, &argv);
1068
1069 while ((c = getopt_long (argc, argv, "hv",
1070 options, (int *) 0)) != EOF)
1071 {
1072 switch (c)
1073 {
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;
1082
1083 case OPTION_OUTPUT_MACH:
1084 output_elf_machine = elf_machine (optarg);
1085 if (output_elf_machine < 0)
1086 return 1;
1087 break;
1088
1089 case 'h':
1090 usage (stdout, 0);
1091
1092 case 'v':
1093 print_version (program_name);
1094 break;
1095
1096 default:
1097 usage (stderr, 1);
1098 }
1099 }
1100
1101 if (optind == argc || output_elf_machine == -1)
1102 usage (stderr, 1);
1103
1104 status = 0;
1105 while (optind < argc)
1106 status |= process_file (argv[optind++]);
1107
1108 return status;
1109}
This page took 0.072393 seconds and 4 git commands to generate.