OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [binutils/] [elfcomm.c] - Blame information for rev 198

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 khays
/* 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
 
33
void
34
error (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
 
44
void
45
warn (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
 
55
void (*byte_put) (unsigned char *, elf_vma, int);
56
 
57
void
58
byte_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
 
87
void
88
byte_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
 
122
elf_vma (*byte_get) (unsigned char *, int);
123
 
124
elf_vma
125
byte_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
 
172
elf_vma
173
byte_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
 
221
elf_vma
222
byte_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 166 khays
/* Return the high-order 32-bits and the low-order 32-bits
242
   of an 8-byte value separately.  */
243
 
244
void
245
byte_get_64 (unsigned char *field, elf_vma *high, elf_vma *low)
246
{
247
  if (byte_get == byte_get_big_endian)
248
    {
249
      *high = byte_get_big_endian (field, 4);
250
      *low = byte_get_big_endian (field + 4, 4);
251
    }
252
  else
253
    {
254
      *high = byte_get_little_endian (field + 4, 4);
255
      *low = byte_get_little_endian (field, 4);
256
    }
257
  return;
258
}
259
 
260 15 khays
/* Return the path name for a proxy entry in a thin archive, adjusted
261
   relative to the path name of the thin archive itself if necessary.
262
   Always returns a pointer to malloc'ed memory.  */
263
 
264
char *
265
adjust_relative_path (const char *file_name, const char *name,
266
                      int name_len)
267
{
268
  char * member_file_name;
269
  const char * base_name = lbasename (file_name);
270
 
271
  /* This is a proxy entry for a thin archive member.
272
     If the extended name table contains an absolute path
273
     name, or if the archive is in the current directory,
274
     use the path name as given.  Otherwise, we need to
275
     find the member relative to the directory where the
276
     archive is located.  */
277
  if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
278
    {
279
      member_file_name = (char *) malloc (name_len + 1);
280
      if (member_file_name == NULL)
281
        {
282
          error (_("Out of memory\n"));
283
          return NULL;
284
        }
285
      memcpy (member_file_name, name, name_len);
286
      member_file_name[name_len] = '\0';
287
    }
288
  else
289
    {
290
      /* Concatenate the path components of the archive file name
291
         to the relative path name from the extended name table.  */
292
      size_t prefix_len = base_name - file_name;
293
      member_file_name = (char *) malloc (prefix_len + name_len + 1);
294
      if (member_file_name == NULL)
295
        {
296
          error (_("Out of memory\n"));
297
          return NULL;
298
        }
299
      memcpy (member_file_name, file_name, prefix_len);
300
      memcpy (member_file_name + prefix_len, name, name_len);
301
      member_file_name[prefix_len + name_len] = '\0';
302
    }
303
  return member_file_name;
304
}
305
 
306
/* Read the symbol table and long-name table from an archive.  */
307
 
308
int
309
setup_archive (struct archive_info *arch, const char *file_name,
310
               FILE *file, bfd_boolean is_thin_archive,
311
               bfd_boolean read_symbols)
312
{
313
  size_t got;
314
  unsigned long size;
315
 
316
  arch->file_name = strdup (file_name);
317
  arch->file = file;
318
  arch->index_num = 0;
319
  arch->index_array = NULL;
320
  arch->sym_table = NULL;
321
  arch->sym_size = 0;
322
  arch->longnames = NULL;
323
  arch->longnames_size = 0;
324
  arch->nested_member_origin = 0;
325
  arch->is_thin_archive = is_thin_archive;
326
  arch->next_arhdr_offset = SARMAG;
327
 
328
  /* Read the first archive member header.  */
329
  if (fseek (file, SARMAG, SEEK_SET) != 0)
330
    {
331
      error (_("%s: failed to seek to first archive header\n"), file_name);
332
      return 1;
333
    }
334
  got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
335
  if (got != sizeof arch->arhdr)
336
    {
337
      if (got == 0)
338
        return 0;
339
 
340
      error (_("%s: failed to read archive header\n"), file_name);
341
      return 1;
342
    }
343
 
344
  /* See if this is the archive symbol table.  */
345
  if (const_strneq (arch->arhdr.ar_name, "/               ")
346
      || const_strneq (arch->arhdr.ar_name, "/SYM64/         "))
347
    {
348
      size = strtoul (arch->arhdr.ar_size, NULL, 10);
349
      size = size + (size & 1);
350
 
351
      arch->next_arhdr_offset += sizeof arch->arhdr + size;
352
 
353
      if (read_symbols)
354
        {
355
          unsigned long i;
356
          /* A buffer used to hold numbers read in from an archive index.
357
             These are always 4 bytes long and stored in big-endian
358
             format.  */
359
#define SIZEOF_AR_INDEX_NUMBERS 4
360
          unsigned char integer_buffer[SIZEOF_AR_INDEX_NUMBERS];
361
          unsigned char * index_buffer;
362
 
363
          /* Check the size of the archive index.  */
364
          if (size < SIZEOF_AR_INDEX_NUMBERS)
365
            {
366
              error (_("%s: the archive index is empty\n"), file_name);
367
              return 1;
368
            }
369
 
370
          /* Read the numer of entries in the archive index.  */
371
          got = fread (integer_buffer, 1, sizeof integer_buffer, file);
372
          if (got != sizeof (integer_buffer))
373
            {
374
              error (_("%s: failed to read archive index\n"), file_name);
375
              return 1;
376
            }
377
          arch->index_num = byte_get_big_endian (integer_buffer,
378
                                                 sizeof integer_buffer);
379
          size -= SIZEOF_AR_INDEX_NUMBERS;
380
 
381
          /* Read in the archive index.  */
382
          if (size < arch->index_num * SIZEOF_AR_INDEX_NUMBERS)
383
            {
384
              error (_("%s: the archive index is supposed to have %ld entries, but the size in the header is too small\n"),
385
                     file_name, arch->index_num);
386
              return 1;
387
            }
388
          index_buffer = (unsigned char *)
389
              malloc (arch->index_num * SIZEOF_AR_INDEX_NUMBERS);
390
          if (index_buffer == NULL)
391
            {
392
              error (_("Out of memory whilst trying to read archive symbol index\n"));
393
              return 1;
394
            }
395
          got = fread (index_buffer, SIZEOF_AR_INDEX_NUMBERS,
396
                       arch->index_num, file);
397
          if (got != arch->index_num)
398
            {
399
              free (index_buffer);
400
              error (_("%s: failed to read archive index\n"), file_name);
401
              return 1;
402
            }
403
          size -= arch->index_num * SIZEOF_AR_INDEX_NUMBERS;
404
 
405
          /* Convert the index numbers into the host's numeric format.  */
406
          arch->index_array = (long unsigned int *)
407
              malloc (arch->index_num * sizeof (* arch->index_array));
408
          if (arch->index_array == NULL)
409
            {
410
              free (index_buffer);
411
              error (_("Out of memory whilst trying to convert the archive symbol index\n"));
412
              return 1;
413
            }
414
 
415
          for (i = 0; i < arch->index_num; i++)
416
            arch->index_array[i] = byte_get_big_endian ((unsigned char *) (index_buffer + (i * SIZEOF_AR_INDEX_NUMBERS)),
417
                                                        SIZEOF_AR_INDEX_NUMBERS);
418
          free (index_buffer);
419
 
420
          /* The remaining space in the header is taken up by the symbol
421
             table.  */
422
          if (size < 1)
423
            {
424
              error (_("%s: the archive has an index but no symbols\n"),
425
                     file_name);
426
              return 1;
427
            }
428
          arch->sym_table = (char *) malloc (size);
429
          arch->sym_size = size;
430
          if (arch->sym_table == NULL)
431
            {
432
              error (_("Out of memory whilst trying to read archive index symbol table\n"));
433
              return 1;
434
            }
435
          got = fread (arch->sym_table, 1, size, file);
436
          if (got != size)
437
            {
438
              error (_("%s: failed to read archive index symbol table\n"),
439
                     file_name);
440
              return 1;
441
            }
442
        }
443
      else
444
        {
445
          if (fseek (file, size, SEEK_CUR) != 0)
446
            {
447
              error (_("%s: failed to skip archive symbol table\n"),
448
                     file_name);
449
              return 1;
450
            }
451
        }
452
 
453
      /* Read the next archive header.  */
454
      got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
455
      if (got != sizeof arch->arhdr)
456
        {
457
          if (got == 0)
458
            return 0;
459
          error (_("%s: failed to read archive header following archive index\n"),
460
                 file_name);
461
          return 1;
462
        }
463
    }
464
  else if (read_symbols)
465
    printf (_("%s has no archive index\n"), file_name);
466
 
467
  if (const_strneq (arch->arhdr.ar_name, "//              "))
468
    {
469
      /* This is the archive string table holding long member names.  */
470
      arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
471
      arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
472
 
473
      arch->longnames = (char *) malloc (arch->longnames_size);
474
      if (arch->longnames == NULL)
475
        {
476
          error (_("Out of memory reading long symbol names in archive\n"));
477
          return 1;
478
        }
479
 
480
      if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
481
        {
482
          free (arch->longnames);
483
          arch->longnames = NULL;
484
          error (_("%s: failed to read long symbol name string table\n"),
485
                 file_name);
486
          return 1;
487
        }
488
 
489
      if ((arch->longnames_size & 1) != 0)
490
        getc (file);
491
    }
492
 
493
  return 0;
494
}
495
 
496
/* Open and setup a nested archive, if not already open.  */
497
 
498
int
499
setup_nested_archive (struct archive_info *nested_arch,
500
                      const char *member_file_name)
501
{
502
  FILE * member_file;
503
 
504
  /* Have we already setup this archive?  */
505
  if (nested_arch->file_name != NULL
506
      && streq (nested_arch->file_name, member_file_name))
507
    return 0;
508
 
509
  /* Close previous file and discard cached information.  */
510
  if (nested_arch->file != NULL)
511
    fclose (nested_arch->file);
512
  release_archive (nested_arch);
513
 
514
  member_file = fopen (member_file_name, "rb");
515
  if (member_file == NULL)
516
    return 1;
517
  return setup_archive (nested_arch, member_file_name, member_file,
518
                        FALSE, FALSE);
519
}
520
 
521
/* Release the memory used for the archive information.  */
522
 
523
void
524
release_archive (struct archive_info * arch)
525
{
526
  if (arch->file_name != NULL)
527
    free (arch->file_name);
528
  if (arch->index_array != NULL)
529
    free (arch->index_array);
530
  if (arch->sym_table != NULL)
531
    free (arch->sym_table);
532
  if (arch->longnames != NULL)
533
    free (arch->longnames);
534
}
535
 
536
/* Get the name of an archive member from the current archive header.
537
   For simple names, this will modify the ar_name field of the current
538
   archive header.  For long names, it will return a pointer to the
539
   longnames table.  For nested archives, it will open the nested archive
540
   and get the name recursively.  NESTED_ARCH is a single-entry cache so
541
   we don't keep rereading the same information from a nested archive.  */
542
 
543
char *
544
get_archive_member_name (struct archive_info *arch,
545
                         struct archive_info *nested_arch)
546
{
547
  unsigned long j, k;
548
 
549
  if (arch->arhdr.ar_name[0] == '/')
550
    {
551
      /* We have a long name.  */
552
      char *endp;
553
      char *member_file_name;
554
      char *member_name;
555
 
556
      arch->nested_member_origin = 0;
557
      k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
558
      if (arch->is_thin_archive && endp != NULL && * endp == ':')
559
        arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
560
 
561
      while ((j < arch->longnames_size)
562
             && (arch->longnames[j] != '\n')
563
             && (arch->longnames[j] != '\0'))
564
        j++;
565
      if (arch->longnames[j-1] == '/')
566
        j--;
567
      arch->longnames[j] = '\0';
568
 
569
      if (!arch->is_thin_archive || arch->nested_member_origin == 0)
570
        return arch->longnames + k;
571
 
572
      /* This is a proxy for a member of a nested archive.
573
         Find the name of the member in that archive.  */
574
      member_file_name = adjust_relative_path (arch->file_name,
575
                                               arch->longnames + k, j - k);
576
      if (member_file_name != NULL
577
          && setup_nested_archive (nested_arch, member_file_name) == 0)
578
        {
579
          member_name = get_archive_member_name_at (nested_arch,
580
                                                    arch->nested_member_origin,
581
                                                    NULL);
582
          if (member_name != NULL)
583
            {
584
              free (member_file_name);
585
              return member_name;
586
            }
587
        }
588
      free (member_file_name);
589
 
590
      /* Last resort: just return the name of the nested archive.  */
591
      return arch->longnames + k;
592
    }
593
 
594
  /* We have a normal (short) name.  */
595
  for (j = 0; j < sizeof (arch->arhdr.ar_name); j++)
596
    if (arch->arhdr.ar_name[j] == '/')
597
      {
598
        arch->arhdr.ar_name[j] = '\0';
599
        return arch->arhdr.ar_name;
600
      }
601
 
602
  /* The full ar_name field is used.  Don't rely on ar_date starting
603
     with a zero byte.  */
604
  {
605
    char *name = xmalloc (sizeof (arch->arhdr.ar_name) + 1);
606
    memcpy (name, arch->arhdr.ar_name, sizeof (arch->arhdr.ar_name));
607
    name[sizeof (arch->arhdr.ar_name)] = '\0';
608
    return name;
609
  }
610
}
611
 
612
/* Get the name of an archive member at a given OFFSET within an archive
613
   ARCH.  */
614
 
615
char *
616
get_archive_member_name_at (struct archive_info *arch,
617
                            unsigned long offset,
618
                            struct archive_info *nested_arch)
619
{
620
  size_t got;
621
 
622
  if (fseek (arch->file, offset, SEEK_SET) != 0)
623
    {
624
      error (_("%s: failed to seek to next file name\n"), arch->file_name);
625
      return NULL;
626
    }
627
  got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
628
  if (got != sizeof arch->arhdr)
629
    {
630
      error (_("%s: failed to read archive header\n"), arch->file_name);
631
      return NULL;
632
    }
633
  if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
634
    {
635
      error (_("%s: did not find a valid archive header\n"),
636
             arch->file_name);
637
      return NULL;
638
    }
639
 
640
  return get_archive_member_name (arch, nested_arch);
641
}
642
 
643
/* Construct a string showing the name of the archive member, qualified
644
   with the name of the containing archive file.  For thin archives, we
645
   use square brackets to denote the indirection.  For nested archives,
646
   we show the qualified name of the external member inside the square
647
   brackets (e.g., "thin.a[normal.a(foo.o)]").  */
648
 
649
char *
650
make_qualified_name (struct archive_info * arch,
651
                     struct archive_info * nested_arch,
652
                     const char *member_name)
653
{
654
  size_t len;
655
  char * name;
656
 
657
  len = strlen (arch->file_name) + strlen (member_name) + 3;
658
  if (arch->is_thin_archive && arch->nested_member_origin != 0)
659
    len += strlen (nested_arch->file_name) + 2;
660
 
661
  name = (char *) malloc (len);
662
  if (name == NULL)
663
    {
664
      error (_("Out of memory\n"));
665
      return NULL;
666
    }
667
 
668
  if (arch->is_thin_archive && arch->nested_member_origin != 0)
669
    snprintf (name, len, "%s[%s(%s)]", arch->file_name,
670
              nested_arch->file_name, member_name);
671
  else if (arch->is_thin_archive)
672
    snprintf (name, len, "%s[%s]", arch->file_name, member_name);
673
  else
674
    snprintf (name, len, "%s(%s)", arch->file_name, member_name);
675
 
676
  return name;
677
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.