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 19

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
/* 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
 
245
char *
246
adjust_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
 
289
int
290
setup_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
 
479
int
480
setup_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
 
504
void
505
release_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
 
524
char *
525
get_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
 
596
char *
597
get_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
 
630
char *
631
make_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
}

powered by: WebSVN 2.1.0

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