* elfcomm.c (setup_archive): Extract index table and symbol table
[deliverable/binutils-gdb.git] / binutils / elfcomm.c
1 /* elfcomm.c -- common code for ELF format file.
2 Copyright 2010
3 Free Software Foundation, Inc.
4
5 Originally developed by Eric Youngdale <eric@andante.jic.com>
6 Modifications by Nick Clifton <nickc@redhat.com>
7
8 This file is part of GNU Binutils.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
23 02110-1301, USA. */
24
25 #include "sysdep.h"
26 #include "libiberty.h"
27 #include "filenames.h"
28 #include "bfd.h"
29 #include "aout/ar.h"
30 #include "bucomm.h"
31 #include "elfcomm.h"
32 #include <assert.h>
33
34 void
35 error (const char *message, ...)
36 {
37 va_list args;
38
39 va_start (args, message);
40 fprintf (stderr, _("%s: Error: "), program_name);
41 vfprintf (stderr, message, args);
42 va_end (args);
43 }
44
45 void
46 warn (const char *message, ...)
47 {
48 va_list args;
49
50 va_start (args, message);
51 fprintf (stderr, _("%s: Warning: "), program_name);
52 vfprintf (stderr, message, args);
53 va_end (args);
54 }
55
56 void (*byte_put) (unsigned char *, elf_vma, int);
57
58 void
59 byte_put_little_endian (unsigned char * field, elf_vma value, int size)
60 {
61 switch (size)
62 {
63 case 8:
64 field[7] = (((value >> 24) >> 24) >> 8) & 0xff;
65 field[6] = ((value >> 24) >> 24) & 0xff;
66 field[5] = ((value >> 24) >> 16) & 0xff;
67 field[4] = ((value >> 24) >> 8) & 0xff;
68 /* Fall through. */
69 case 4:
70 field[3] = (value >> 24) & 0xff;
71 /* Fall through. */
72 case 3:
73 field[2] = (value >> 16) & 0xff;
74 /* Fall through. */
75 case 2:
76 field[1] = (value >> 8) & 0xff;
77 /* Fall through. */
78 case 1:
79 field[0] = value & 0xff;
80 break;
81
82 default:
83 error (_("Unhandled data length: %d\n"), size);
84 abort ();
85 }
86 }
87
88 void
89 byte_put_big_endian (unsigned char * field, elf_vma value, int size)
90 {
91 switch (size)
92 {
93 case 8:
94 field[7] = value & 0xff;
95 field[6] = (value >> 8) & 0xff;
96 field[5] = (value >> 16) & 0xff;
97 field[4] = (value >> 24) & 0xff;
98 value >>= 16;
99 value >>= 16;
100 /* Fall through. */
101 case 4:
102 field[3] = value & 0xff;
103 value >>= 8;
104 /* Fall through. */
105 case 3:
106 field[2] = value & 0xff;
107 value >>= 8;
108 /* Fall through. */
109 case 2:
110 field[1] = value & 0xff;
111 value >>= 8;
112 /* Fall through. */
113 case 1:
114 field[0] = value & 0xff;
115 break;
116
117 default:
118 error (_("Unhandled data length: %d\n"), size);
119 abort ();
120 }
121 }
122
123 elf_vma (*byte_get) (unsigned char *, int);
124
125 elf_vma
126 byte_get_little_endian (unsigned char *field, int size)
127 {
128 switch (size)
129 {
130 case 1:
131 return *field;
132
133 case 2:
134 return ((unsigned int) (field[0]))
135 | (((unsigned int) (field[1])) << 8);
136
137 case 3:
138 return ((unsigned long) (field[0]))
139 | (((unsigned long) (field[1])) << 8)
140 | (((unsigned long) (field[2])) << 16);
141
142 case 4:
143 return ((unsigned long) (field[0]))
144 | (((unsigned long) (field[1])) << 8)
145 | (((unsigned long) (field[2])) << 16)
146 | (((unsigned long) (field[3])) << 24);
147
148 case 8:
149 if (sizeof (elf_vma) == 8)
150 return ((elf_vma) (field[0]))
151 | (((elf_vma) (field[1])) << 8)
152 | (((elf_vma) (field[2])) << 16)
153 | (((elf_vma) (field[3])) << 24)
154 | (((elf_vma) (field[4])) << 32)
155 | (((elf_vma) (field[5])) << 40)
156 | (((elf_vma) (field[6])) << 48)
157 | (((elf_vma) (field[7])) << 56);
158 else if (sizeof (elf_vma) == 4)
159 /* We want to extract data from an 8 byte wide field and
160 place it into a 4 byte wide field. Since this is a little
161 endian source we can just use the 4 byte extraction code. */
162 return ((unsigned long) (field[0]))
163 | (((unsigned long) (field[1])) << 8)
164 | (((unsigned long) (field[2])) << 16)
165 | (((unsigned long) (field[3])) << 24);
166
167 default:
168 error (_("Unhandled data length: %d\n"), size);
169 abort ();
170 }
171 }
172
173 elf_vma
174 byte_get_big_endian (unsigned char *field, int size)
175 {
176 switch (size)
177 {
178 case 1:
179 return *field;
180
181 case 2:
182 return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);
183
184 case 3:
185 return ((unsigned long) (field[2]))
186 | (((unsigned long) (field[1])) << 8)
187 | (((unsigned long) (field[0])) << 16);
188
189 case 4:
190 return ((unsigned long) (field[3]))
191 | (((unsigned long) (field[2])) << 8)
192 | (((unsigned long) (field[1])) << 16)
193 | (((unsigned long) (field[0])) << 24);
194
195 case 8:
196 if (sizeof (elf_vma) == 8)
197 return ((elf_vma) (field[7]))
198 | (((elf_vma) (field[6])) << 8)
199 | (((elf_vma) (field[5])) << 16)
200 | (((elf_vma) (field[4])) << 24)
201 | (((elf_vma) (field[3])) << 32)
202 | (((elf_vma) (field[2])) << 40)
203 | (((elf_vma) (field[1])) << 48)
204 | (((elf_vma) (field[0])) << 56);
205 else if (sizeof (elf_vma) == 4)
206 {
207 /* Although we are extracing data from an 8 byte wide field,
208 we are returning only 4 bytes of data. */
209 field += 4;
210 return ((unsigned long) (field[3]))
211 | (((unsigned long) (field[2])) << 8)
212 | (((unsigned long) (field[1])) << 16)
213 | (((unsigned long) (field[0])) << 24);
214 }
215
216 default:
217 error (_("Unhandled data length: %d\n"), size);
218 abort ();
219 }
220 }
221
222 elf_vma
223 byte_get_signed (unsigned char *field, int size)
224 {
225 elf_vma x = byte_get (field, size);
226
227 switch (size)
228 {
229 case 1:
230 return (x ^ 0x80) - 0x80;
231 case 2:
232 return (x ^ 0x8000) - 0x8000;
233 case 4:
234 return (x ^ 0x80000000) - 0x80000000;
235 case 8:
236 return x;
237 default:
238 abort ();
239 }
240 }
241
242 /* Return the high-order 32-bits and the low-order 32-bits
243 of an 8-byte value separately. */
244
245 void
246 byte_get_64 (unsigned char *field, elf_vma *high, elf_vma *low)
247 {
248 if (byte_get == byte_get_big_endian)
249 {
250 *high = byte_get_big_endian (field, 4);
251 *low = byte_get_big_endian (field + 4, 4);
252 }
253 else
254 {
255 *high = byte_get_little_endian (field + 4, 4);
256 *low = byte_get_little_endian (field, 4);
257 }
258 return;
259 }
260
261 /* Return the path name for a proxy entry in a thin archive, adjusted
262 relative to the path name of the thin archive itself if necessary.
263 Always returns a pointer to malloc'ed memory. */
264
265 char *
266 adjust_relative_path (const char *file_name, const char *name,
267 int name_len)
268 {
269 char * member_file_name;
270 const char * base_name = lbasename (file_name);
271
272 /* This is a proxy entry for a thin archive member.
273 If the extended name table contains an absolute path
274 name, or if the archive is in the current directory,
275 use the path name as given. Otherwise, we need to
276 find the member relative to the directory where the
277 archive is located. */
278 if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
279 {
280 member_file_name = (char *) malloc (name_len + 1);
281 if (member_file_name == NULL)
282 {
283 error (_("Out of memory\n"));
284 return NULL;
285 }
286 memcpy (member_file_name, name, name_len);
287 member_file_name[name_len] = '\0';
288 }
289 else
290 {
291 /* Concatenate the path components of the archive file name
292 to the relative path name from the extended name table. */
293 size_t prefix_len = base_name - file_name;
294 member_file_name = (char *) malloc (prefix_len + name_len + 1);
295 if (member_file_name == NULL)
296 {
297 error (_("Out of memory\n"));
298 return NULL;
299 }
300 memcpy (member_file_name, file_name, prefix_len);
301 memcpy (member_file_name + prefix_len, name, name_len);
302 member_file_name[prefix_len + name_len] = '\0';
303 }
304 return member_file_name;
305 }
306
307 /* Processes the archive index table and symbol table in ARCH.
308 Entries in the index table are SIZEOF_AR_INDEX bytes long.
309 Fills in ARCH->next_arhdr_offset and ARCH->arhdr.
310 If READ_SYMBOLS is true then fills in ARCH->index_num, ARCH->index_array,
311 ARCH->sym_size and ARCH->sym_table.
312 It is the caller's responsibility to free ARCH->index_array and
313 ARCH->sym_table.
314 Returns TRUE upon success, FALSE otherwise.
315 If failure occurs an error message is printed. */
316
317 static bfd_boolean
318 process_archive_index_and_symbols (struct archive_info * arch,
319 unsigned int sizeof_ar_index,
320 bfd_boolean read_symbols)
321 {
322 size_t got;
323 unsigned long size;
324
325 size = strtoul (arch->arhdr.ar_size, NULL, 10);
326 size = size + (size & 1);
327
328 arch->next_arhdr_offset += sizeof arch->arhdr + size;
329
330 if (! read_symbols)
331 {
332 if (fseek (arch->file, size, SEEK_CUR) != 0)
333 {
334 error (_("%s: failed to skip archive symbol table\n"),
335 arch->file_name);
336 return FALSE;
337 }
338 }
339 else
340 {
341 unsigned long i;
342 /* A buffer used to hold numbers read in from an archive index.
343 These are always SIZEOF_AR_INDEX bytes long and stored in
344 big-endian format. */
345 unsigned char integer_buffer[sizeof arch->index_num];
346 unsigned char * index_buffer;
347
348 assert (sizeof_ar_index <= sizeof integer_buffer);
349
350 /* Check the size of the archive index. */
351 if (size < sizeof_ar_index)
352 {
353 error (_("%s: the archive index is empty\n"), arch->file_name);
354 return FALSE;
355 }
356
357 /* Read the number of entries in the archive index. */
358 got = fread (integer_buffer, 1, sizeof_ar_index, arch->file);
359 if (got != sizeof_ar_index)
360 {
361 error (_("%s: failed to read archive index\n"), arch->file_name);
362 return FALSE;
363 }
364
365 arch->index_num = byte_get_big_endian (integer_buffer, sizeof_ar_index);
366 size -= sizeof_ar_index;
367
368 if (size < arch->index_num * sizeof_ar_index)
369 {
370 error (_("%s: the archive index is supposed to have %ld entries of %d bytes, but the size is only %ld\n"),
371 arch->file_name, (long) arch->index_num, sizeof_ar_index, size);
372 return FALSE;
373 }
374
375 /* Read in the archive index. */
376 index_buffer = (unsigned char *)
377 malloc (arch->index_num * sizeof_ar_index);
378 if (index_buffer == NULL)
379 {
380 error (_("Out of memory whilst trying to read archive symbol index\n"));
381 return FALSE;
382 }
383
384 got = fread (index_buffer, sizeof_ar_index, arch->index_num, arch->file);
385 if (got != arch->index_num)
386 {
387 free (index_buffer);
388 error (_("%s: failed to read archive index\n"), arch->file_name);
389 return FALSE;
390 }
391
392 size -= arch->index_num * sizeof_ar_index;
393
394 /* Convert the index numbers into the host's numeric format. */
395 arch->index_array = (elf_vma *)
396 malloc (arch->index_num * sizeof (* arch->index_array));
397 if (arch->index_array == NULL)
398 {
399 free (index_buffer);
400 error (_("Out of memory whilst trying to convert the archive symbol index\n"));
401 return FALSE;
402 }
403
404 for (i = 0; i < arch->index_num; i++)
405 arch->index_array[i] =
406 byte_get_big_endian ((unsigned char *) (index_buffer + (i * sizeof_ar_index)),
407 sizeof_ar_index);
408 free (index_buffer);
409
410 /* The remaining space in the header is taken up by the symbol table. */
411 if (size < 1)
412 {
413 error (_("%s: the archive has an index but no symbols\n"),
414 arch->file_name);
415 return FALSE;
416 }
417
418 arch->sym_table = (char *) malloc (size);
419 if (arch->sym_table == NULL)
420 {
421 error (_("Out of memory whilst trying to read archive index symbol table\n"));
422 return FALSE;
423 }
424
425 arch->sym_size = size;
426 got = fread (arch->sym_table, 1, size, arch->file);
427 if (got != size)
428 {
429 error (_("%s: failed to read archive index symbol table\n"),
430 arch->file_name);
431 return FALSE;
432 }
433 }
434
435 /* Read the next archive header. */
436 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
437 if (got != sizeof arch->arhdr && got != 0)
438 {
439 error (_("%s: failed to read archive header following archive index\n"),
440 arch->file_name);
441 return FALSE;
442 }
443
444 return TRUE;
445 }
446
447 /* Read the symbol table and long-name table from an archive. */
448
449 int
450 setup_archive (struct archive_info *arch, const char *file_name,
451 FILE *file, bfd_boolean is_thin_archive,
452 bfd_boolean read_symbols)
453 {
454 size_t got;
455
456 arch->file_name = strdup (file_name);
457 arch->file = file;
458 arch->index_num = 0;
459 arch->index_array = NULL;
460 arch->sym_table = NULL;
461 arch->sym_size = 0;
462 arch->longnames = NULL;
463 arch->longnames_size = 0;
464 arch->nested_member_origin = 0;
465 arch->is_thin_archive = is_thin_archive;
466 arch->uses_64bit_indicies = FALSE;
467 arch->next_arhdr_offset = SARMAG;
468
469 /* Read the first archive member header. */
470 if (fseek (file, SARMAG, SEEK_SET) != 0)
471 {
472 error (_("%s: failed to seek to first archive header\n"), file_name);
473 return 1;
474 }
475 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
476 if (got != sizeof arch->arhdr)
477 {
478 if (got == 0)
479 return 0;
480
481 error (_("%s: failed to read archive header\n"), file_name);
482 return 1;
483 }
484
485 /* See if this is the archive symbol table. */
486 if (const_strneq (arch->arhdr.ar_name, "/ "))
487 {
488 if (! process_archive_index_and_symbols (arch, 4, read_symbols))
489 return 1;
490 }
491 else if (const_strneq (arch->arhdr.ar_name, "/SYM64/ "))
492 {
493 arch->uses_64bit_indicies = TRUE;
494 if (! process_archive_index_and_symbols (arch, 8, read_symbols))
495 return 1;
496 }
497 else if (read_symbols)
498 printf (_("%s has no archive index\n"), file_name);
499
500 if (const_strneq (arch->arhdr.ar_name, "// "))
501 {
502 /* This is the archive string table holding long member names. */
503 arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
504 arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
505
506 arch->longnames = (char *) malloc (arch->longnames_size);
507 if (arch->longnames == NULL)
508 {
509 error (_("Out of memory reading long symbol names in archive\n"));
510 return 1;
511 }
512
513 if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
514 {
515 free (arch->longnames);
516 arch->longnames = NULL;
517 error (_("%s: failed to read long symbol name string table\n"),
518 file_name);
519 return 1;
520 }
521
522 if ((arch->longnames_size & 1) != 0)
523 getc (file);
524 }
525
526 return 0;
527 }
528
529 /* Open and setup a nested archive, if not already open. */
530
531 int
532 setup_nested_archive (struct archive_info *nested_arch,
533 const char *member_file_name)
534 {
535 FILE * member_file;
536
537 /* Have we already setup this archive? */
538 if (nested_arch->file_name != NULL
539 && streq (nested_arch->file_name, member_file_name))
540 return 0;
541
542 /* Close previous file and discard cached information. */
543 if (nested_arch->file != NULL)
544 fclose (nested_arch->file);
545 release_archive (nested_arch);
546
547 member_file = fopen (member_file_name, "rb");
548 if (member_file == NULL)
549 return 1;
550 return setup_archive (nested_arch, member_file_name, member_file,
551 FALSE, FALSE);
552 }
553
554 /* Release the memory used for the archive information. */
555
556 void
557 release_archive (struct archive_info * arch)
558 {
559 if (arch->file_name != NULL)
560 free (arch->file_name);
561 if (arch->index_array != NULL)
562 free (arch->index_array);
563 if (arch->sym_table != NULL)
564 free (arch->sym_table);
565 if (arch->longnames != NULL)
566 free (arch->longnames);
567 }
568
569 /* Get the name of an archive member from the current archive header.
570 For simple names, this will modify the ar_name field of the current
571 archive header. For long names, it will return a pointer to the
572 longnames table. For nested archives, it will open the nested archive
573 and get the name recursively. NESTED_ARCH is a single-entry cache so
574 we don't keep rereading the same information from a nested archive. */
575
576 char *
577 get_archive_member_name (struct archive_info *arch,
578 struct archive_info *nested_arch)
579 {
580 unsigned long j, k;
581
582 if (arch->arhdr.ar_name[0] == '/')
583 {
584 /* We have a long name. */
585 char *endp;
586 char *member_file_name;
587 char *member_name;
588
589 arch->nested_member_origin = 0;
590 k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
591 if (arch->is_thin_archive && endp != NULL && * endp == ':')
592 arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
593
594 while ((j < arch->longnames_size)
595 && (arch->longnames[j] != '\n')
596 && (arch->longnames[j] != '\0'))
597 j++;
598 if (arch->longnames[j-1] == '/')
599 j--;
600 arch->longnames[j] = '\0';
601
602 if (!arch->is_thin_archive || arch->nested_member_origin == 0)
603 return arch->longnames + k;
604
605 /* This is a proxy for a member of a nested archive.
606 Find the name of the member in that archive. */
607 member_file_name = adjust_relative_path (arch->file_name,
608 arch->longnames + k, j - k);
609 if (member_file_name != NULL
610 && setup_nested_archive (nested_arch, member_file_name) == 0)
611 {
612 member_name = get_archive_member_name_at (nested_arch,
613 arch->nested_member_origin,
614 NULL);
615 if (member_name != NULL)
616 {
617 free (member_file_name);
618 return member_name;
619 }
620 }
621 free (member_file_name);
622
623 /* Last resort: just return the name of the nested archive. */
624 return arch->longnames + k;
625 }
626
627 /* We have a normal (short) name. */
628 for (j = 0; j < sizeof (arch->arhdr.ar_name); j++)
629 if (arch->arhdr.ar_name[j] == '/')
630 {
631 arch->arhdr.ar_name[j] = '\0';
632 return arch->arhdr.ar_name;
633 }
634
635 /* The full ar_name field is used. Don't rely on ar_date starting
636 with a zero byte. */
637 {
638 char *name = xmalloc (sizeof (arch->arhdr.ar_name) + 1);
639 memcpy (name, arch->arhdr.ar_name, sizeof (arch->arhdr.ar_name));
640 name[sizeof (arch->arhdr.ar_name)] = '\0';
641 return name;
642 }
643 }
644
645 /* Get the name of an archive member at a given OFFSET within an archive
646 ARCH. */
647
648 char *
649 get_archive_member_name_at (struct archive_info *arch,
650 unsigned long offset,
651 struct archive_info *nested_arch)
652 {
653 size_t got;
654
655 if (fseek (arch->file, offset, SEEK_SET) != 0)
656 {
657 error (_("%s: failed to seek to next file name\n"), arch->file_name);
658 return NULL;
659 }
660 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
661 if (got != sizeof arch->arhdr)
662 {
663 error (_("%s: failed to read archive header\n"), arch->file_name);
664 return NULL;
665 }
666 if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
667 {
668 error (_("%s: did not find a valid archive header\n"),
669 arch->file_name);
670 return NULL;
671 }
672
673 return get_archive_member_name (arch, nested_arch);
674 }
675
676 /* Construct a string showing the name of the archive member, qualified
677 with the name of the containing archive file. For thin archives, we
678 use square brackets to denote the indirection. For nested archives,
679 we show the qualified name of the external member inside the square
680 brackets (e.g., "thin.a[normal.a(foo.o)]"). */
681
682 char *
683 make_qualified_name (struct archive_info * arch,
684 struct archive_info * nested_arch,
685 const char *member_name)
686 {
687 size_t len;
688 char * name;
689
690 len = strlen (arch->file_name) + strlen (member_name) + 3;
691 if (arch->is_thin_archive && arch->nested_member_origin != 0)
692 len += strlen (nested_arch->file_name) + 2;
693
694 name = (char *) malloc (len);
695 if (name == NULL)
696 {
697 error (_("Out of memory\n"));
698 return NULL;
699 }
700
701 if (arch->is_thin_archive && arch->nested_member_origin != 0)
702 snprintf (name, len, "%s[%s(%s)]", arch->file_name,
703 nested_arch->file_name, member_name);
704 else if (arch->is_thin_archive)
705 snprintf (name, len, "%s[%s]", arch->file_name, member_name);
706 else
707 snprintf (name, len, "%s(%s)", arch->file_name, member_name);
708
709 return name;
710 }
This page took 0.051166 seconds and 5 git commands to generate.