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