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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [archive.c] - Blame information for rev 14

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

Line No. Rev Author Line
1 14 khays
/* BFD back-end for archive files (libraries).
2
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3
   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4
   Free Software Foundation, Inc.
5
   Written by Cygnus Support.  Mostly Gumby Henkel-Wallace's fault.
6
 
7
   This file is part of BFD, the Binary File Descriptor library.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program; if not, write to the Free Software
21
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
22
 
23
/*
24
@setfilename archive-info
25
SECTION
26
        Archives
27
 
28
DESCRIPTION
29
        An archive (or library) is just another BFD.  It has a symbol
30
        table, although there's not much a user program will do with it.
31
 
32
        The big difference between an archive BFD and an ordinary BFD
33
        is that the archive doesn't have sections.  Instead it has a
34
        chain of BFDs that are considered its contents.  These BFDs can
35
        be manipulated like any other.  The BFDs contained in an
36
        archive opened for reading will all be opened for reading.  You
37
        may put either input or output BFDs into an archive opened for
38
        output; they will be handled correctly when the archive is closed.
39
 
40
        Use <<bfd_openr_next_archived_file>> to step through
41
        the contents of an archive opened for input.  You don't
42
        have to read the entire archive if you don't want
43
        to!  Read it until you find what you want.
44
 
45
        Archive contents of output BFDs are chained through the
46
        <<next>> pointer in a BFD.  The first one is findable through
47
        the <<archive_head>> slot of the archive.  Set it with
48
        <<bfd_set_archive_head>> (q.v.).  A given BFD may be in only one
49
        open output archive at a time.
50
 
51
        As expected, the BFD archive code is more general than the
52
        archive code of any given environment.  BFD archives may
53
        contain files of different formats (e.g., a.out and coff) and
54
        even different architectures.  You may even place archives
55
        recursively into archives!
56
 
57
        This can cause unexpected confusion, since some archive
58
        formats are more expressive than others.  For instance, Intel
59
        COFF archives can preserve long filenames; SunOS a.out archives
60
        cannot.  If you move a file from the first to the second
61
        format and back again, the filename may be truncated.
62
        Likewise, different a.out environments have different
63
        conventions as to how they truncate filenames, whether they
64
        preserve directory names in filenames, etc.  When
65
        interoperating with native tools, be sure your files are
66
        homogeneous.
67
 
68
        Beware: most of these formats do not react well to the
69
        presence of spaces in filenames.  We do the best we can, but
70
        can't always handle this case due to restrictions in the format of
71
        archives.  Many Unix utilities are braindead in regards to
72
        spaces and such in filenames anyway, so this shouldn't be much
73
        of a restriction.
74
 
75
        Archives are supported in BFD in <<archive.c>>.
76
 
77
SUBSECTION
78
        Archive functions
79
*/
80
 
81
/* Assumes:
82
   o - all archive elements start on an even boundary, newline padded;
83
   o - all arch headers are char *;
84
   o - all arch headers are the same size (across architectures).
85
*/
86
 
87
/* Some formats provide a way to cram a long filename into the short
88
   (16 chars) space provided by a BSD archive.  The trick is: make a
89
   special "file" in the front of the archive, sort of like the SYMDEF
90
   entry.  If the filename is too long to fit, put it in the extended
91
   name table, and use its index as the filename.  To prevent
92
   confusion prepend the index with a space.  This means you can't
93
   have filenames that start with a space, but then again, many Unix
94
   utilities can't handle that anyway.
95
 
96
   This scheme unfortunately requires that you stand on your head in
97
   order to write an archive since you need to put a magic file at the
98
   front, and need to touch every entry to do so.  C'est la vie.
99
 
100
   We support two variants of this idea:
101
   The SVR4 format (extended name table is named "//"),
102
   and an extended pseudo-BSD variant (extended name table is named
103
   "ARFILENAMES/").  The origin of the latter format is uncertain.
104
 
105
   BSD 4.4 uses a third scheme:  It writes a long filename
106
   directly after the header.  This allows 'ar q' to work.
107
*/
108
 
109
/* Summary of archive member names:
110
 
111
 Symbol table (must be first):
112
 "__.SYMDEF       " - Symbol table, Berkeley style, produced by ranlib.
113
 "/               " - Symbol table, system 5 style.
114
 
115
 Long name table (must be before regular file members):
116
 "//              " - Long name table, System 5 R4 style.
117
 "ARFILENAMES/    " - Long name table, non-standard extended BSD (not BSD 4.4).
118
 
119
 Regular file members with short names:
120
 "filename.o/     " - Regular file, System 5 style (embedded spaces ok).
121
 "filename.o      " - Regular file, Berkeley style (no embedded spaces).
122
 
123
 Regular files with long names (or embedded spaces, for BSD variants):
124
 "/18             " - SVR4 style, name at offset 18 in name table.
125
 "#1/23           " - Long name (or embedded spaces) 23 characters long,
126
                      BSD 4.4 style, full name follows header.
127
 " 18             " - Long name 18 characters long, extended pseudo-BSD.
128
 */
129
 
130
#include "sysdep.h"
131
#include "bfd.h"
132
#include "libiberty.h"
133
#include "libbfd.h"
134
#include "aout/ar.h"
135
#include "aout/ranlib.h"
136
#include "safe-ctype.h"
137
#include "hashtab.h"
138
#include "filenames.h"
139
 
140
#ifndef errno
141
extern int errno;
142
#endif
143
 
144
/* We keep a cache of archive filepointers to archive elements to
145
   speed up searching the archive by filepos.  We only add an entry to
146
   the cache when we actually read one.  We also don't sort the cache;
147
   it's generally short enough to search linearly.
148
   Note that the pointers here point to the front of the ar_hdr, not
149
   to the front of the contents!  */
150
struct ar_cache {
151
  file_ptr ptr;
152
  bfd *arbfd;
153
};
154
 
155
#define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
156
#define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
157
 
158
#define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data))
159
#define arch_hdr(bfd) ((struct ar_hdr *) arch_eltdata (bfd)->arch_header)
160
 
161
/* True iff NAME designated a BSD 4.4 extended name.  */
162
 
163
#define is_bsd44_extended_name(NAME) \
164
  (NAME[0] == '#'  && NAME[1] == '1' && NAME[2] == '/' && ISDIGIT (NAME[3]))
165
 
166
void
167
_bfd_ar_spacepad (char *p, size_t n, const char *fmt, long val)
168
{
169
  static char buf[20];
170
  size_t len;
171
  snprintf (buf, sizeof (buf), fmt, val);
172
  len = strlen (buf);
173
  if (len < n)
174
    {
175
      memcpy (p, buf, len);
176
      memset (p + len, ' ', n - len);
177
    }
178
  else
179
    memcpy (p, buf, n);
180
}
181
 
182
bfd_boolean
183
_bfd_generic_mkarchive (bfd *abfd)
184
{
185
  bfd_size_type amt = sizeof (struct artdata);
186
 
187
  abfd->tdata.aout_ar_data = (struct artdata *) bfd_zalloc (abfd, amt);
188
  if (bfd_ardata (abfd) == NULL)
189
    return FALSE;
190
 
191
  /* Already cleared by bfd_zalloc above.
192
     bfd_ardata (abfd)->cache = NULL;
193
     bfd_ardata (abfd)->archive_head = NULL;
194
     bfd_ardata (abfd)->symdefs = NULL;
195
     bfd_ardata (abfd)->extended_names = NULL;
196
     bfd_ardata (abfd)->extended_names_size = 0;
197
     bfd_ardata (abfd)->tdata = NULL;  */
198
 
199
  return TRUE;
200
}
201
 
202
/*
203
FUNCTION
204
        bfd_get_next_mapent
205
 
206
SYNOPSIS
207
        symindex bfd_get_next_mapent
208
          (bfd *abfd, symindex previous, carsym **sym);
209
 
210
DESCRIPTION
211
        Step through archive @var{abfd}'s symbol table (if it
212
        has one).  Successively update @var{sym} with the next symbol's
213
        information, returning that symbol's (internal) index into the
214
        symbol table.
215
 
216
        Supply <<BFD_NO_MORE_SYMBOLS>> as the @var{previous} entry to get
217
        the first one; returns <<BFD_NO_MORE_SYMBOLS>> when you've already
218
        got the last one.
219
 
220
        A <<carsym>> is a canonical archive symbol.  The only
221
        user-visible element is its name, a null-terminated string.
222
*/
223
 
224
symindex
225
bfd_get_next_mapent (bfd *abfd, symindex prev, carsym **entry)
226
{
227
  if (!bfd_has_map (abfd))
228
    {
229
      bfd_set_error (bfd_error_invalid_operation);
230
      return BFD_NO_MORE_SYMBOLS;
231
    }
232
 
233
  if (prev == BFD_NO_MORE_SYMBOLS)
234
    prev = 0;
235
  else
236
    ++prev;
237
  if (prev >= bfd_ardata (abfd)->symdef_count)
238
    return BFD_NO_MORE_SYMBOLS;
239
 
240
  *entry = (bfd_ardata (abfd)->symdefs + prev);
241
  return prev;
242
}
243
 
244
/* To be called by backends only.  */
245
 
246
bfd *
247
_bfd_create_empty_archive_element_shell (bfd *obfd)
248
{
249
  return _bfd_new_bfd_contained_in (obfd);
250
}
251
 
252
/*
253
FUNCTION
254
        bfd_set_archive_head
255
 
256
SYNOPSIS
257
        bfd_boolean bfd_set_archive_head (bfd *output, bfd *new_head);
258
 
259
DESCRIPTION
260
        Set the head of the chain of
261
        BFDs contained in the archive @var{output} to @var{new_head}.
262
*/
263
 
264
bfd_boolean
265
bfd_set_archive_head (bfd *output_archive, bfd *new_head)
266
{
267
  output_archive->archive_head = new_head;
268
  return TRUE;
269
}
270
 
271
bfd *
272
_bfd_look_for_bfd_in_cache (bfd *arch_bfd, file_ptr filepos)
273
{
274
  htab_t hash_table = bfd_ardata (arch_bfd)->cache;
275
  struct ar_cache m;
276
  m.ptr = filepos;
277
 
278
  if (hash_table)
279
    {
280
      struct ar_cache *entry = (struct ar_cache *) htab_find (hash_table, &m);
281
      if (!entry)
282
        return NULL;
283
      else
284
        return entry->arbfd;
285
    }
286
  else
287
    return NULL;
288
}
289
 
290
static hashval_t
291
hash_file_ptr (const PTR p)
292
{
293
  return (hashval_t) (((struct ar_cache *) p)->ptr);
294
}
295
 
296
/* Returns non-zero if P1 and P2 are equal.  */
297
 
298
static int
299
eq_file_ptr (const PTR p1, const PTR p2)
300
{
301
  struct ar_cache *arc1 = (struct ar_cache *) p1;
302
  struct ar_cache *arc2 = (struct ar_cache *) p2;
303
  return arc1->ptr == arc2->ptr;
304
}
305
 
306
/* The calloc function doesn't always take size_t (e.g. on VMS)
307
   so wrap it to avoid a compile time warning.   */
308
 
309
static void *
310
_bfd_calloc_wrapper (size_t a, size_t b)
311
{
312
  return calloc (a, b);
313
}
314
 
315
/* Kind of stupid to call cons for each one, but we don't do too many.  */
316
 
317
bfd_boolean
318
_bfd_add_bfd_to_archive_cache (bfd *arch_bfd, file_ptr filepos, bfd *new_elt)
319
{
320
  struct ar_cache *cache;
321
  htab_t hash_table = bfd_ardata (arch_bfd)->cache;
322
 
323
  /* If the hash table hasn't been created, create it.  */
324
  if (hash_table == NULL)
325
    {
326
      hash_table = htab_create_alloc (16, hash_file_ptr, eq_file_ptr,
327
                                      NULL, _bfd_calloc_wrapper, free);
328
      if (hash_table == NULL)
329
        return FALSE;
330
      bfd_ardata (arch_bfd)->cache = hash_table;
331
    }
332
 
333
  /* Insert new_elt into the hash table by filepos.  */
334
  cache = (struct ar_cache *) bfd_zalloc (arch_bfd, sizeof (struct ar_cache));
335
  cache->ptr = filepos;
336
  cache->arbfd = new_elt;
337
  *htab_find_slot (hash_table, (const void *) cache, INSERT) = cache;
338
 
339
  return TRUE;
340
}
341
 
342
static bfd *
343
_bfd_find_nested_archive (bfd *arch_bfd, const char *filename)
344
{
345
  bfd *abfd;
346
 
347
  for (abfd = arch_bfd->nested_archives;
348
       abfd != NULL;
349
       abfd = abfd->archive_next)
350
    {
351
      if (filename_cmp (filename, abfd->filename) == 0)
352
        return abfd;
353
    }
354
  abfd = bfd_openr (filename, NULL);
355
  if (abfd)
356
    {
357
      abfd->archive_next = arch_bfd->nested_archives;
358
      arch_bfd->nested_archives = abfd;
359
    }
360
  return abfd;
361
}
362
 
363
/* The name begins with space.  Hence the rest of the name is an index into
364
   the string table.  */
365
 
366
static char *
367
get_extended_arelt_filename (bfd *arch, const char *name, file_ptr *originp)
368
{
369
  unsigned long table_index = 0;
370
  const char *endp;
371
 
372
  /* Should extract string so that I can guarantee not to overflow into
373
     the next region, but I'm too lazy.  */
374
  errno = 0;
375
  /* Skip first char, which is '/' in SVR4 or ' ' in some other variants.  */
376
  table_index = strtol (name + 1, (char **) &endp, 10);
377
  if (errno != 0 || table_index >= bfd_ardata (arch)->extended_names_size)
378
    {
379
      bfd_set_error (bfd_error_malformed_archive);
380
      return NULL;
381
    }
382
  /* In a thin archive, a member of an archive-within-an-archive
383
     will have the offset in the inner archive encoded here.  */
384
  if (bfd_is_thin_archive (arch) && endp != NULL && *endp == ':')
385
    {
386
      file_ptr origin = strtol (endp + 1, NULL, 10);
387
 
388
      if (errno != 0)
389
        {
390
          bfd_set_error (bfd_error_malformed_archive);
391
          return NULL;
392
        }
393
      *originp = origin;
394
    }
395
  else
396
    *originp = 0;
397
 
398
  return bfd_ardata (arch)->extended_names + table_index;
399
}
400
 
401
/* This functions reads an arch header and returns an areltdata pointer, or
402
   NULL on error.
403
 
404
   Presumes the file pointer is already in the right place (ie pointing
405
   to the ar_hdr in the file).   Moves the file pointer; on success it
406
   should be pointing to the front of the file contents; on failure it
407
   could have been moved arbitrarily.  */
408
 
409
void *
410
_bfd_generic_read_ar_hdr (bfd *abfd)
411
{
412
  return _bfd_generic_read_ar_hdr_mag (abfd, NULL);
413
}
414
 
415
/* Alpha ECOFF uses an optional different ARFMAG value, so we have a
416
   variant of _bfd_generic_read_ar_hdr which accepts a magic string.  */
417
 
418
void *
419
_bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag)
420
{
421
  struct ar_hdr hdr;
422
  char *hdrp = (char *) &hdr;
423
  size_t parsed_size;
424
  struct areltdata *ared;
425
  char *filename = NULL;
426
  bfd_size_type namelen = 0;
427
  bfd_size_type allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
428
  char *allocptr = 0;
429
  file_ptr origin = 0;
430
  unsigned int extra_size = 0;
431
 
432
  if (bfd_bread (hdrp, sizeof (struct ar_hdr), abfd) != sizeof (struct ar_hdr))
433
    {
434
      if (bfd_get_error () != bfd_error_system_call)
435
        bfd_set_error (bfd_error_no_more_archived_files);
436
      return NULL;
437
    }
438
  if (strncmp (hdr.ar_fmag, ARFMAG, 2) != 0
439
      && (mag == NULL
440
          || strncmp (hdr.ar_fmag, mag, 2) != 0))
441
    {
442
      bfd_set_error (bfd_error_malformed_archive);
443
      return NULL;
444
    }
445
 
446
  errno = 0;
447
  parsed_size = strtol (hdr.ar_size, NULL, 10);
448
  if (errno != 0)
449
    {
450
      bfd_set_error (bfd_error_malformed_archive);
451
      return NULL;
452
    }
453
 
454
  /* Extract the filename from the archive - there are two ways to
455
     specify an extended name table, either the first char of the
456
     name is a space, or it's a slash.  */
457
  if ((hdr.ar_name[0] == '/'
458
       || (hdr.ar_name[0] == ' '
459
           && memchr (hdr.ar_name, '/', ar_maxnamelen (abfd)) == NULL))
460
      && bfd_ardata (abfd)->extended_names != NULL)
461
    {
462
      filename = get_extended_arelt_filename (abfd, hdr.ar_name, &origin);
463
      if (filename == NULL)
464
        return NULL;
465
    }
466
  /* BSD4.4-style long filename.  */
467
  else if (is_bsd44_extended_name (hdr.ar_name))
468
    {
469
      /* BSD-4.4 extended name */
470
      namelen = atoi (&hdr.ar_name[3]);
471
      allocsize += namelen + 1;
472
      parsed_size -= namelen;
473
      extra_size = namelen;
474
 
475
      allocptr = (char *) bfd_zalloc (abfd, allocsize);
476
      if (allocptr == NULL)
477
        return NULL;
478
      filename = (allocptr
479
                  + sizeof (struct areltdata)
480
                  + sizeof (struct ar_hdr));
481
      if (bfd_bread (filename, namelen, abfd) != namelen)
482
        {
483
          if (bfd_get_error () != bfd_error_system_call)
484
            bfd_set_error (bfd_error_no_more_archived_files);
485
          return NULL;
486
        }
487
      filename[namelen] = '\0';
488
    }
489
  else
490
    {
491
      /* We judge the end of the name by looking for '/' or ' '.
492
         Note:  The SYSV format (terminated by '/') allows embedded
493
         spaces, so only look for ' ' if we don't find '/'.  */
494
 
495
      char *e;
496
      e = (char *) memchr (hdr.ar_name, '\0', ar_maxnamelen (abfd));
497
      if (e == NULL)
498
        {
499
          e = (char *) memchr (hdr.ar_name, '/', ar_maxnamelen (abfd));
500
          if (e == NULL)
501
            e = (char *) memchr (hdr.ar_name, ' ', ar_maxnamelen (abfd));
502
        }
503
 
504
      if (e != NULL)
505
        namelen = e - hdr.ar_name;
506
      else
507
        {
508
          /* If we didn't find a termination character, then the name
509
             must be the entire field.  */
510
          namelen = ar_maxnamelen (abfd);
511
        }
512
 
513
      allocsize += namelen + 1;
514
    }
515
 
516
  if (!allocptr)
517
    {
518
      allocptr = (char *) bfd_zalloc (abfd, allocsize);
519
      if (allocptr == NULL)
520
        return NULL;
521
    }
522
 
523
  ared = (struct areltdata *) allocptr;
524
 
525
  ared->arch_header = allocptr + sizeof (struct areltdata);
526
  memcpy (ared->arch_header, &hdr, sizeof (struct ar_hdr));
527
  ared->parsed_size = parsed_size;
528
  ared->extra_size = extra_size;
529
  ared->origin = origin;
530
 
531
  if (filename != NULL)
532
    ared->filename = filename;
533
  else
534
    {
535
      ared->filename = allocptr + (sizeof (struct areltdata) +
536
                                   sizeof (struct ar_hdr));
537
      if (namelen)
538
        memcpy (ared->filename, hdr.ar_name, namelen);
539
      ared->filename[namelen] = '\0';
540
    }
541
 
542
  return ared;
543
}
544
 
545
/* Append the relative pathname for a member of the thin archive
546
   to the pathname of the directory containing the archive.  */
547
 
548
char *
549
_bfd_append_relative_path (bfd *arch, char *elt_name)
550
{
551
  const char *arch_name = arch->filename;
552
  const char *base_name = lbasename (arch_name);
553
  size_t prefix_len;
554
  char *filename;
555
 
556
  if (base_name == arch_name)
557
    return elt_name;
558
 
559
  prefix_len = base_name - arch_name;
560
  filename = (char *) bfd_alloc (arch, prefix_len + strlen (elt_name) + 1);
561
  if (filename == NULL)
562
    return NULL;
563
 
564
  strncpy (filename, arch_name, prefix_len);
565
  strcpy (filename + prefix_len, elt_name);
566
  return filename;
567
}
568
 
569
/* This is an internal function; it's mainly used when indexing
570
   through the archive symbol table, but also used to get the next
571
   element, since it handles the bookkeeping so nicely for us.  */
572
 
573
bfd *
574
_bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos)
575
{
576
  struct areltdata *new_areldata;
577
  bfd *n_nfd;
578
  char *filename;
579
 
580
  if (archive->my_archive)
581
    {
582
      filepos += archive->origin;
583
      archive = archive->my_archive;
584
    }
585
 
586
  n_nfd = _bfd_look_for_bfd_in_cache (archive, filepos);
587
  if (n_nfd)
588
    return n_nfd;
589
 
590
  if (0 > bfd_seek (archive, filepos, SEEK_SET))
591
    return NULL;
592
 
593
  if ((new_areldata = (struct areltdata *) _bfd_read_ar_hdr (archive)) == NULL)
594
    return NULL;
595
 
596
  filename = new_areldata->filename;
597
 
598
  if (bfd_is_thin_archive (archive))
599
    {
600
      /* This is a proxy entry for an external file.  */
601
      if (! IS_ABSOLUTE_PATH (filename))
602
        {
603
          filename = _bfd_append_relative_path (archive, filename);
604
          if (filename == NULL)
605
            return NULL;
606
        }
607
 
608
      if (new_areldata->origin > 0)
609
        {
610
          /* This proxy entry refers to an element of a nested archive.
611
             Locate the member of that archive and return a bfd for it.  */
612
          bfd *ext_arch = _bfd_find_nested_archive (archive, filename);
613
 
614
          if (ext_arch == NULL
615
              || ! bfd_check_format (ext_arch, bfd_archive))
616
            {
617
              bfd_release (archive, new_areldata);
618
              return NULL;
619
            }
620
          n_nfd = _bfd_get_elt_at_filepos (ext_arch, new_areldata->origin);
621
          if (n_nfd == NULL)
622
            {
623
              bfd_release (archive, new_areldata);
624
              return NULL;
625
            }
626
          n_nfd->proxy_origin = bfd_tell (archive);
627
          return n_nfd;
628
        }
629
      /* It's not an element of a nested archive;
630
         open the external file as a bfd.  */
631
      n_nfd = bfd_openr (filename, NULL);
632
      if (n_nfd == NULL)
633
        bfd_set_error (bfd_error_malformed_archive);
634
    }
635
  else
636
    {
637
      n_nfd = _bfd_create_empty_archive_element_shell (archive);
638
    }
639
 
640
  if (n_nfd == NULL)
641
    {
642
      bfd_release (archive, new_areldata);
643
      return NULL;
644
    }
645
 
646
  n_nfd->proxy_origin = bfd_tell (archive);
647
 
648
  if (bfd_is_thin_archive (archive))
649
    {
650
      n_nfd->origin = 0;
651
    }
652
  else
653
    {
654
      n_nfd->origin = n_nfd->proxy_origin;
655
      n_nfd->filename = filename;
656
    }
657
 
658
  n_nfd->arelt_data = new_areldata;
659
 
660
  /* Copy BFD_COMPRESS and BFD_DECOMPRESS flags.  */
661
  n_nfd->flags |= archive->flags & (BFD_COMPRESS | BFD_DECOMPRESS);
662
 
663
  if (_bfd_add_bfd_to_archive_cache (archive, filepos, n_nfd))
664
    return n_nfd;
665
 
666
  bfd_release (archive, new_areldata);
667
  return NULL;
668
}
669
 
670
/* Return the BFD which is referenced by the symbol in ABFD indexed by
671
   SYM_INDEX.  SYM_INDEX should have been returned by bfd_get_next_mapent.  */
672
 
673
bfd *
674
_bfd_generic_get_elt_at_index (bfd *abfd, symindex sym_index)
675
{
676
  carsym *entry;
677
 
678
  entry = bfd_ardata (abfd)->symdefs + sym_index;
679
  return _bfd_get_elt_at_filepos (abfd, entry->file_offset);
680
}
681
 
682
/*
683
FUNCTION
684
        bfd_openr_next_archived_file
685
 
686
SYNOPSIS
687
        bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous);
688
 
689
DESCRIPTION
690
        Provided a BFD, @var{archive}, containing an archive and NULL, open
691
        an input BFD on the first contained element and returns that.
692
        Subsequent calls should pass
693
        the archive and the previous return value to return a created
694
        BFD to the next contained element. NULL is returned when there
695
        are no more.
696
*/
697
 
698
bfd *
699
bfd_openr_next_archived_file (bfd *archive, bfd *last_file)
700
{
701
  if ((bfd_get_format (archive) != bfd_archive)
702
      || (archive->direction == write_direction))
703
    {
704
      bfd_set_error (bfd_error_invalid_operation);
705
      return NULL;
706
    }
707
 
708
  return BFD_SEND (archive,
709
                   openr_next_archived_file, (archive, last_file));
710
}
711
 
712
bfd *
713
bfd_generic_openr_next_archived_file (bfd *archive, bfd *last_file)
714
{
715
  file_ptr filestart;
716
 
717
  if (!last_file)
718
    filestart = bfd_ardata (archive)->first_file_filepos;
719
  else
720
    {
721
      unsigned int size = arelt_size (last_file);
722
 
723
      filestart = last_file->proxy_origin;
724
      if (! bfd_is_thin_archive (archive))
725
        filestart += size;
726
      if (archive->my_archive)
727
        filestart -= archive->origin;
728
      /* Pad to an even boundary...
729
         Note that last_file->origin can be odd in the case of
730
         BSD-4.4-style element with a long odd size.  */
731
      filestart += filestart % 2;
732
    }
733
 
734
  return _bfd_get_elt_at_filepos (archive, filestart);
735
}
736
 
737
const bfd_target *
738
bfd_generic_archive_p (bfd *abfd)
739
{
740
  struct artdata *tdata_hold;
741
  char armag[SARMAG + 1];
742
  bfd_size_type amt;
743
 
744
  if (bfd_bread (armag, SARMAG, abfd) != SARMAG)
745
    {
746
      if (bfd_get_error () != bfd_error_system_call)
747
        bfd_set_error (bfd_error_wrong_format);
748
      return NULL;
749
    }
750
 
751
  bfd_is_thin_archive (abfd) = (strncmp (armag, ARMAGT, SARMAG) == 0);
752
 
753
  if (strncmp (armag, ARMAG, SARMAG) != 0
754
      && strncmp (armag, ARMAGB, SARMAG) != 0
755
      && ! bfd_is_thin_archive (abfd))
756
    return NULL;
757
 
758
  tdata_hold = bfd_ardata (abfd);
759
 
760
  amt = sizeof (struct artdata);
761
  bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
762
  if (bfd_ardata (abfd) == NULL)
763
    {
764
      bfd_ardata (abfd) = tdata_hold;
765
      return NULL;
766
    }
767
 
768
  bfd_ardata (abfd)->first_file_filepos = SARMAG;
769
  /* Cleared by bfd_zalloc above.
770
     bfd_ardata (abfd)->cache = NULL;
771
     bfd_ardata (abfd)->archive_head = NULL;
772
     bfd_ardata (abfd)->symdefs = NULL;
773
     bfd_ardata (abfd)->extended_names = NULL;
774
     bfd_ardata (abfd)->extended_names_size = 0;
775
     bfd_ardata (abfd)->tdata = NULL;  */
776
 
777
  if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))
778
      || !BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd)))
779
    {
780
      if (bfd_get_error () != bfd_error_system_call)
781
        bfd_set_error (bfd_error_wrong_format);
782
      bfd_release (abfd, bfd_ardata (abfd));
783
      bfd_ardata (abfd) = tdata_hold;
784
      return NULL;
785
    }
786
 
787
  if (bfd_has_map (abfd))
788
    {
789
      bfd *first;
790
 
791
      /* This archive has a map, so we may presume that the contents
792
         are object files.  Make sure that if the first file in the
793
         archive can be recognized as an object file, it is for this
794
         target.  If not, assume that this is the wrong format.  If
795
         the first file is not an object file, somebody is doing
796
         something weird, and we permit it so that ar -t will work.
797
 
798
         This is done because any normal format will recognize any
799
         normal archive, regardless of the format of the object files.
800
         We do accept an empty archive.  */
801
 
802
      first = bfd_openr_next_archived_file (abfd, NULL);
803
      if (first != NULL)
804
        {
805
          first->target_defaulted = FALSE;
806
          if (bfd_check_format (first, bfd_object)
807
              && first->xvec != abfd->xvec)
808
            {
809
              bfd_set_error (bfd_error_wrong_object_format);
810
              bfd_ardata (abfd) = tdata_hold;
811
              return NULL;
812
            }
813
          /* And we ought to close `first' here too.  */
814
        }
815
    }
816
 
817
  return abfd->xvec;
818
}
819
 
820
/* Some constants for a 32 bit BSD archive structure.  We do not
821
   support 64 bit archives presently; so far as I know, none actually
822
   exist.  Supporting them would require changing these constants, and
823
   changing some H_GET_32 to H_GET_64.  */
824
 
825
/* The size of an external symdef structure.  */
826
#define BSD_SYMDEF_SIZE 8
827
 
828
/* The offset from the start of a symdef structure to the file offset.  */
829
#define BSD_SYMDEF_OFFSET_SIZE 4
830
 
831
/* The size of the symdef count.  */
832
#define BSD_SYMDEF_COUNT_SIZE 4
833
 
834
/* The size of the string count.  */
835
#define BSD_STRING_COUNT_SIZE 4
836
 
837
/* Read a BSD-style archive symbol table.  Returns FALSE on error,
838
   TRUE otherwise.  */
839
 
840
static bfd_boolean
841
do_slurp_bsd_armap (bfd *abfd)
842
{
843
  struct areltdata *mapdata;
844
  unsigned int counter;
845
  bfd_byte *raw_armap, *rbase;
846
  struct artdata *ardata = bfd_ardata (abfd);
847
  char *stringbase;
848
  bfd_size_type parsed_size, amt;
849
  carsym *set;
850
 
851
  mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
852
  if (mapdata == NULL)
853
    return FALSE;
854
  parsed_size = mapdata->parsed_size;
855
  bfd_release (abfd, mapdata);  /* Don't need it any more.  */
856
 
857
  raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size);
858
  if (raw_armap == NULL)
859
    return FALSE;
860
 
861
  if (bfd_bread (raw_armap, parsed_size, abfd) != parsed_size)
862
    {
863
      if (bfd_get_error () != bfd_error_system_call)
864
        bfd_set_error (bfd_error_malformed_archive);
865
    byebye:
866
      bfd_release (abfd, raw_armap);
867
      return FALSE;
868
    }
869
 
870
  ardata->symdef_count = H_GET_32 (abfd, raw_armap) / BSD_SYMDEF_SIZE;
871
 
872
  if (ardata->symdef_count * BSD_SYMDEF_SIZE >
873
      parsed_size - BSD_SYMDEF_COUNT_SIZE)
874
    {
875
      /* Probably we're using the wrong byte ordering.  */
876
      bfd_set_error (bfd_error_wrong_format);
877
      goto byebye;
878
    }
879
 
880
  ardata->cache = 0;
881
  rbase = raw_armap + BSD_SYMDEF_COUNT_SIZE;
882
  stringbase = ((char *) rbase
883
                + ardata->symdef_count * BSD_SYMDEF_SIZE
884
                + BSD_STRING_COUNT_SIZE);
885
  amt = ardata->symdef_count * sizeof (carsym);
886
  ardata->symdefs = (struct carsym *) bfd_alloc (abfd, amt);
887
  if (!ardata->symdefs)
888
    return FALSE;
889
 
890
  for (counter = 0, set = ardata->symdefs;
891
       counter < ardata->symdef_count;
892
       counter++, set++, rbase += BSD_SYMDEF_SIZE)
893
    {
894
      set->name = H_GET_32 (abfd, rbase) + stringbase;
895
      set->file_offset = H_GET_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE);
896
    }
897
 
898
  ardata->first_file_filepos = bfd_tell (abfd);
899
  /* Pad to an even boundary if you have to.  */
900
  ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
901
  /* FIXME, we should provide some way to free raw_ardata when
902
     we are done using the strings from it.  For now, it seems
903
     to be allocated on an objalloc anyway...  */
904
  bfd_has_map (abfd) = TRUE;
905
  return TRUE;
906
}
907
 
908
/* Read a COFF archive symbol table.  Returns FALSE on error, TRUE
909
   otherwise.  */
910
 
911
static bfd_boolean
912
do_slurp_coff_armap (bfd *abfd)
913
{
914
  struct areltdata *mapdata;
915
  int *raw_armap, *rawptr;
916
  struct artdata *ardata = bfd_ardata (abfd);
917
  char *stringbase;
918
  bfd_size_type stringsize;
919
  unsigned int parsed_size;
920
  carsym *carsyms;
921
  bfd_size_type nsymz;          /* Number of symbols in armap.  */
922
  bfd_vma (*swap) (const void *);
923
  char int_buf[sizeof (long)];
924
  bfd_size_type carsym_size, ptrsize;
925
  unsigned int i;
926
 
927
  mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
928
  if (mapdata == NULL)
929
    return FALSE;
930
  parsed_size = mapdata->parsed_size;
931
  bfd_release (abfd, mapdata);  /* Don't need it any more.  */
932
 
933
  if (bfd_bread (int_buf, 4, abfd) != 4)
934
    {
935
      if (bfd_get_error () != bfd_error_system_call)
936
        bfd_set_error (bfd_error_malformed_archive);
937
      return FALSE;
938
    }
939
  /* It seems that all numeric information in a coff archive is always
940
     in big endian format, nomatter the host or target.  */
941
  swap = bfd_getb32;
942
  nsymz = bfd_getb32 (int_buf);
943
  stringsize = parsed_size - (4 * nsymz) - 4;
944
 
945
  /* ... except that some archive formats are broken, and it may be our
946
     fault - the i960 little endian coff sometimes has big and sometimes
947
     little, because our tools changed.  Here's a horrible hack to clean
948
     up the crap.  */
949
 
950
  if (stringsize > 0xfffff
951
      && bfd_get_arch (abfd) == bfd_arch_i960
952
      && bfd_get_flavour (abfd) == bfd_target_coff_flavour)
953
    {
954
      /* This looks dangerous, let's do it the other way around.  */
955
      nsymz = bfd_getl32 (int_buf);
956
      stringsize = parsed_size - (4 * nsymz) - 4;
957
      swap = bfd_getl32;
958
    }
959
 
960
  /* The coff armap must be read sequentially.  So we construct a
961
     bsd-style one in core all at once, for simplicity.  */
962
 
963
  if (nsymz > ~ (bfd_size_type) 0 / sizeof (carsym))
964
    return FALSE;
965
 
966
  carsym_size = (nsymz * sizeof (carsym));
967
  ptrsize = (4 * nsymz);
968
 
969
  if (carsym_size + stringsize + 1 <= carsym_size)
970
    return FALSE;
971
 
972
  ardata->symdefs = (struct carsym *) bfd_zalloc (abfd,
973
                                                  carsym_size + stringsize + 1);
974
  if (ardata->symdefs == NULL)
975
    return FALSE;
976
  carsyms = ardata->symdefs;
977
  stringbase = ((char *) ardata->symdefs) + carsym_size;
978
 
979
  /* Allocate and read in the raw offsets.  */
980
  raw_armap = (int *) bfd_alloc (abfd, ptrsize);
981
  if (raw_armap == NULL)
982
    goto release_symdefs;
983
  if (bfd_bread (raw_armap, ptrsize, abfd) != ptrsize
984
      || (bfd_bread (stringbase, stringsize, abfd) != stringsize))
985
    {
986
      if (bfd_get_error () != bfd_error_system_call)
987
        bfd_set_error (bfd_error_malformed_archive);
988
      goto release_raw_armap;
989
    }
990
 
991
  /* OK, build the carsyms.  */
992
  for (i = 0; i < nsymz; i++)
993
    {
994
      rawptr = raw_armap + i;
995
      carsyms->file_offset = swap ((bfd_byte *) rawptr);
996
      carsyms->name = stringbase;
997
      stringbase += strlen (stringbase) + 1;
998
      carsyms++;
999
    }
1000
  *stringbase = 0;
1001
 
1002
  ardata->symdef_count = nsymz;
1003
  ardata->first_file_filepos = bfd_tell (abfd);
1004
  /* Pad to an even boundary if you have to.  */
1005
  ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
1006
 
1007
  bfd_has_map (abfd) = TRUE;
1008
  bfd_release (abfd, raw_armap);
1009
 
1010
  /* Check for a second archive header (as used by PE).  */
1011
  {
1012
    struct areltdata *tmp;
1013
 
1014
    bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET);
1015
    tmp = (struct areltdata *) _bfd_read_ar_hdr (abfd);
1016
    if (tmp != NULL)
1017
      {
1018
        if (tmp->arch_header[0] == '/'
1019
            && tmp->arch_header[1] == ' ')
1020
          {
1021
            ardata->first_file_filepos +=
1022
              (tmp->parsed_size + sizeof (struct ar_hdr) + 1) & ~(unsigned) 1;
1023
          }
1024
        bfd_release (abfd, tmp);
1025
      }
1026
  }
1027
 
1028
  return TRUE;
1029
 
1030
release_raw_armap:
1031
  bfd_release (abfd, raw_armap);
1032
release_symdefs:
1033
  bfd_release (abfd, (ardata)->symdefs);
1034
  return FALSE;
1035
}
1036
 
1037
/* This routine can handle either coff-style or bsd-style armaps
1038
   (archive symbol table).  Returns FALSE on error, TRUE otherwise */
1039
 
1040
bfd_boolean
1041
bfd_slurp_armap (bfd *abfd)
1042
{
1043
  char nextname[17];
1044
  int i = bfd_bread (nextname, 16, abfd);
1045
 
1046
  if (i == 0)
1047
    return TRUE;
1048
  if (i != 16)
1049
    return FALSE;
1050
 
1051
  if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
1052
    return FALSE;
1053
 
1054
  if (CONST_STRNEQ (nextname, "__.SYMDEF       ")
1055
      || CONST_STRNEQ (nextname, "__.SYMDEF/      ")) /* Old Linux archives.  */
1056
    return do_slurp_bsd_armap (abfd);
1057
  else if (CONST_STRNEQ (nextname, "/               "))
1058
    return do_slurp_coff_armap (abfd);
1059
  else if (CONST_STRNEQ (nextname, "/SYM64/         "))
1060
    {
1061
      /* 64bit ELF (Irix 6) archive.  */
1062
#ifdef BFD64
1063
      extern bfd_boolean bfd_elf64_archive_slurp_armap (bfd *);
1064
      return bfd_elf64_archive_slurp_armap (abfd);
1065
#else
1066
      bfd_set_error (bfd_error_wrong_format);
1067
      return FALSE;
1068
#endif
1069
    }
1070
  else if (CONST_STRNEQ (nextname, "#1/20           "))
1071
    {
1072
      /* Mach-O has a special name for armap when the map is sorted by name.
1073
         However because this name has a space it is slightly more difficult
1074
         to check it.  */
1075
      struct ar_hdr hdr;
1076
      char extname[21];
1077
 
1078
      if (bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
1079
        return FALSE;
1080
      /* Read the extended name.  We know its length.  */
1081
      if (bfd_bread (extname, 20, abfd) != 20)
1082
        return FALSE;
1083
      if (bfd_seek (abfd, (file_ptr) -(sizeof (hdr) + 20), SEEK_CUR) != 0)
1084
        return FALSE;
1085
      if (CONST_STRNEQ (extname, "__.SYMDEF SORTED")
1086
          || CONST_STRNEQ (extname, "__.SYMDEF"))
1087
        return do_slurp_bsd_armap (abfd);
1088
    }
1089
 
1090
  bfd_has_map (abfd) = FALSE;
1091
  return TRUE;
1092
}
1093
 
1094
/* Returns FALSE on error, TRUE otherwise.  */
1095
/* Flavor 2 of a bsd armap, similar to bfd_slurp_bsd_armap except the
1096
   header is in a slightly different order and the map name is '/'.
1097
   This flavour is used by hp300hpux.  */
1098
 
1099
#define HPUX_SYMDEF_COUNT_SIZE 2
1100
 
1101
bfd_boolean
1102
bfd_slurp_bsd_armap_f2 (bfd *abfd)
1103
{
1104
  struct areltdata *mapdata;
1105
  char nextname[17];
1106
  unsigned int counter;
1107
  bfd_byte *raw_armap, *rbase;
1108
  struct artdata *ardata = bfd_ardata (abfd);
1109
  char *stringbase;
1110
  unsigned int stringsize;
1111
  unsigned int left;
1112
  bfd_size_type amt;
1113
  carsym *set;
1114
  int i = bfd_bread (nextname, 16, abfd);
1115
 
1116
  if (i == 0)
1117
    return TRUE;
1118
  if (i != 16)
1119
    return FALSE;
1120
 
1121
  /* The archive has at least 16 bytes in it.  */
1122
  if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
1123
    return FALSE;
1124
 
1125
  if (CONST_STRNEQ (nextname, "__.SYMDEF       ")
1126
      || CONST_STRNEQ (nextname, "__.SYMDEF/      ")) /* Old Linux archives.  */
1127
    return do_slurp_bsd_armap (abfd);
1128
 
1129
  if (! CONST_STRNEQ (nextname, "/               "))
1130
    {
1131
      bfd_has_map (abfd) = FALSE;
1132
      return TRUE;
1133
    }
1134
 
1135
  mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
1136
  if (mapdata == NULL)
1137
    return FALSE;
1138
 
1139
  if (mapdata->parsed_size < HPUX_SYMDEF_COUNT_SIZE + BSD_STRING_COUNT_SIZE)
1140
    {
1141
    wrong_format:
1142
      bfd_set_error (bfd_error_wrong_format);
1143
    byebye:
1144
      bfd_release (abfd, mapdata);
1145
      return FALSE;
1146
    }
1147
  left = mapdata->parsed_size - HPUX_SYMDEF_COUNT_SIZE - BSD_STRING_COUNT_SIZE;
1148
 
1149
  amt = mapdata->parsed_size;
1150
  raw_armap = (bfd_byte *) bfd_zalloc (abfd, amt);
1151
  if (raw_armap == NULL)
1152
    goto byebye;
1153
 
1154
  if (bfd_bread (raw_armap, amt, abfd) != amt)
1155
    {
1156
      if (bfd_get_error () != bfd_error_system_call)
1157
        bfd_set_error (bfd_error_malformed_archive);
1158
      goto byebye;
1159
    }
1160
 
1161
  ardata->symdef_count = H_GET_16 (abfd, raw_armap);
1162
 
1163
  ardata->cache = 0;
1164
 
1165
  stringsize = H_GET_32 (abfd, raw_armap + HPUX_SYMDEF_COUNT_SIZE);
1166
  if (stringsize > left)
1167
    goto wrong_format;
1168
  left -= stringsize;
1169
 
1170
  /* Skip sym count and string sz.  */
1171
  stringbase = ((char *) raw_armap
1172
                + HPUX_SYMDEF_COUNT_SIZE
1173
                + BSD_STRING_COUNT_SIZE);
1174
  rbase = (bfd_byte *) stringbase + stringsize;
1175
  amt = ardata->symdef_count * BSD_SYMDEF_SIZE;
1176
  if (amt > left)
1177
    goto wrong_format;
1178
 
1179
  ardata->symdefs = (struct carsym *) bfd_alloc (abfd, amt);
1180
  if (!ardata->symdefs)
1181
    return FALSE;
1182
 
1183
  for (counter = 0, set = ardata->symdefs;
1184
       counter < ardata->symdef_count;
1185
       counter++, set++, rbase += BSD_SYMDEF_SIZE)
1186
    {
1187
      set->name = H_GET_32 (abfd, rbase) + stringbase;
1188
      set->file_offset = H_GET_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE);
1189
    }
1190
 
1191
  ardata->first_file_filepos = bfd_tell (abfd);
1192
  /* Pad to an even boundary if you have to.  */
1193
  ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
1194
  /* FIXME, we should provide some way to free raw_ardata when
1195
     we are done using the strings from it.  For now, it seems
1196
     to be allocated on an objalloc anyway...  */
1197
  bfd_has_map (abfd) = TRUE;
1198
  return TRUE;
1199
}
1200
 
1201
/** Extended name table.
1202
 
1203
  Normally archives support only 14-character filenames.
1204
 
1205
  Intel has extended the format: longer names are stored in a special
1206
  element (the first in the archive, or second if there is an armap);
1207
  the name in the ar_hdr is replaced by <space><index into filename
1208
  element>.  Index is the P.R. of an int (decimal).  Data General have
1209
  extended the format by using the prefix // for the special element.  */
1210
 
1211
/* Returns FALSE on error, TRUE otherwise.  */
1212
 
1213
bfd_boolean
1214
_bfd_slurp_extended_name_table (bfd *abfd)
1215
{
1216
  char nextname[17];
1217
  struct areltdata *namedata;
1218
  bfd_size_type amt;
1219
 
1220
  /* FIXME:  Formatting sucks here, and in case of failure of BFD_READ,
1221
     we probably don't want to return TRUE.  */
1222
  if (bfd_seek (abfd, bfd_ardata (abfd)->first_file_filepos, SEEK_SET) != 0)
1223
    return FALSE;
1224
 
1225
  if (bfd_bread (nextname, 16, abfd) == 16)
1226
    {
1227
      if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
1228
        return FALSE;
1229
 
1230
      if (! CONST_STRNEQ (nextname, "ARFILENAMES/    ")
1231
          && ! CONST_STRNEQ (nextname, "//              "))
1232
        {
1233
          bfd_ardata (abfd)->extended_names = NULL;
1234
          bfd_ardata (abfd)->extended_names_size = 0;
1235
          return TRUE;
1236
        }
1237
 
1238
      namedata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
1239
      if (namedata == NULL)
1240
        return FALSE;
1241
 
1242
      amt = namedata->parsed_size;
1243
      if (amt + 1 == 0)
1244
        goto byebye;
1245
 
1246
      bfd_ardata (abfd)->extended_names_size = amt;
1247
      bfd_ardata (abfd)->extended_names = (char *) bfd_zalloc (abfd, amt + 1);
1248
      if (bfd_ardata (abfd)->extended_names == NULL)
1249
        {
1250
        byebye:
1251
          bfd_release (abfd, namedata);
1252
          return FALSE;
1253
        }
1254
 
1255
      if (bfd_bread (bfd_ardata (abfd)->extended_names, amt, abfd) != amt)
1256
        {
1257
          if (bfd_get_error () != bfd_error_system_call)
1258
            bfd_set_error (bfd_error_malformed_archive);
1259
          bfd_release (abfd, (bfd_ardata (abfd)->extended_names));
1260
          bfd_ardata (abfd)->extended_names = NULL;
1261
          goto byebye;
1262
        }
1263
 
1264
      /* Since the archive is supposed to be printable if it contains
1265
         text, the entries in the list are newline-padded, not null
1266
         padded. In SVR4-style archives, the names also have a
1267
         trailing '/'.  DOS/NT created archive often have \ in them
1268
         We'll fix all problems here..  */
1269
      {
1270
        char *ext_names = bfd_ardata (abfd)->extended_names;
1271
        char *temp = ext_names;
1272
        char *limit = temp + namedata->parsed_size;
1273
        for (; temp < limit; ++temp)
1274
          {
1275
            if (*temp == ARFMAG[1])
1276
              temp[temp > ext_names && temp[-1] == '/' ? -1 : 0] = '\0';
1277
            if (*temp == '\\')
1278
              *temp = '/';
1279
          }
1280
        *limit = '\0';
1281
      }
1282
 
1283
      /* Pad to an even boundary if you have to.  */
1284
      bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
1285
      bfd_ardata (abfd)->first_file_filepos +=
1286
        (bfd_ardata (abfd)->first_file_filepos) % 2;
1287
 
1288
      /* FIXME, we can't release namedata here because it was allocated
1289
         below extended_names on the objalloc...  */
1290
    }
1291
  return TRUE;
1292
}
1293
 
1294
#ifdef VMS
1295
 
1296
/* Return a copy of the stuff in the filename between any :]> and a
1297
   semicolon.  */
1298
 
1299
static const char *
1300
normalize (bfd *abfd, const char *file)
1301
{
1302
  const char *first;
1303
  const char *last;
1304
  char *copy;
1305
 
1306
  first = file + strlen (file) - 1;
1307
  last = first + 1;
1308
 
1309
  while (first != file)
1310
    {
1311
      if (*first == ';')
1312
        last = first;
1313
      if (*first == ':' || *first == ']' || *first == '>')
1314
        {
1315
          first++;
1316
          break;
1317
        }
1318
      first--;
1319
    }
1320
 
1321
  copy = bfd_alloc (abfd, last - first + 1);
1322
  if (copy == NULL)
1323
    return NULL;
1324
 
1325
  memcpy (copy, first, last - first);
1326
  copy[last - first] = 0;
1327
 
1328
  return copy;
1329
}
1330
 
1331
#else
1332
static const char *
1333
normalize (bfd *abfd ATTRIBUTE_UNUSED, const char *file)
1334
{
1335
  return lbasename (file);
1336
}
1337
#endif
1338
 
1339
/* Adjust a relative path name based on the reference path.
1340
   For example:
1341
 
1342
     Relative path  Reference path  Result
1343
     -------------  --------------  ------
1344
     bar.o          lib.a           bar.o
1345
     foo/bar.o      lib.a           foo/bar.o
1346
     bar.o          foo/lib.a       ../bar.o
1347
     foo/bar.o      baz/lib.a       ../foo/bar.o
1348
     bar.o          ../lib.a        <parent of current dir>/bar.o
1349
   ; ../bar.o       ../lib.a        bar.o
1350
   ; ../bar.o       lib.a           ../bar.o
1351
     foo/bar.o      ../lib.a        <parent of current dir>/foo/bar.o
1352
     bar.o          ../../lib.a     <grandparent>/<parent>/bar.o
1353
     bar.o          foo/baz/lib.a   ../../bar.o
1354
 
1355
   Note - the semicolons above are there to prevent the BFD chew
1356
   utility from interpreting those lines as prototypes to put into
1357
   the autogenerated bfd.h header...
1358
 
1359
   Note - the string is returned in a static buffer.  */
1360
 
1361
static const char *
1362
adjust_relative_path (const char * path, const char * ref_path)
1363
{
1364
  static char *pathbuf = NULL;
1365
  static unsigned int pathbuf_len = 0;
1366
  const char *pathp;
1367
  const char *refp;
1368
  char * lpath;
1369
  char * rpath;
1370
  unsigned int len;
1371
  unsigned int dir_up = 0;
1372
  unsigned int dir_down = 0;
1373
  char *newp;
1374
  char * pwd = getpwd ();
1375
  const char * down;
1376
 
1377
  /* Remove symlinks, '.' and '..' from the paths, if possible.  */
1378
  lpath = lrealpath (path);
1379
  pathp = lpath == NULL ? path : lpath;
1380
 
1381
  rpath = lrealpath (ref_path);
1382
  refp = rpath == NULL ? ref_path : rpath;
1383
 
1384
  /* Remove common leading path elements.  */
1385
  for (;;)
1386
    {
1387
      const char *e1 = pathp;
1388
      const char *e2 = refp;
1389
 
1390
      while (*e1 && ! IS_DIR_SEPARATOR (*e1))
1391
        ++e1;
1392
      while (*e2 && ! IS_DIR_SEPARATOR (*e2))
1393
        ++e2;
1394
      if (*e1 == '\0' || *e2 == '\0' || e1 - pathp != e2 - refp
1395
          || filename_ncmp (pathp, refp, e1 - pathp) != 0)
1396
        break;
1397
      pathp = e1 + 1;
1398
      refp = e2 + 1;
1399
    }
1400
 
1401
  len = strlen (pathp) + 1;
1402
  /* For each leading path element in the reference path,
1403
     insert "../" into the path.  */
1404
  for (; *refp; ++refp)
1405
    if (IS_DIR_SEPARATOR (*refp))
1406
      {
1407
        /* PR 12710:  If the path element is "../" then instead of
1408
           inserting "../" we need to insert the name of the directory
1409
           at the current level.  */
1410
        if (refp > ref_path + 1
1411
            && refp[-1] == '.'
1412
            && refp[-2] == '.')
1413
          dir_down ++;
1414
        else
1415
          dir_up ++;
1416
      }
1417
 
1418
  /* If the lrealpath calls above succeeded then we should never
1419
     see dir_up and dir_down both being non-zero.  */
1420
 
1421
  len += 3 * dir_up;
1422
 
1423
  if (dir_down)
1424
    {
1425
      down = pwd + strlen (pwd) - 1;
1426
 
1427
      while (dir_down && down > pwd)
1428
        {
1429
          if (IS_DIR_SEPARATOR (*down))
1430
            --dir_down;
1431
        }
1432
      BFD_ASSERT (dir_down == 0);
1433
      len += strlen (down) + 1;
1434
    }
1435
  else
1436
    down = NULL;
1437
 
1438
  if (len > pathbuf_len)
1439
    {
1440
      if (pathbuf != NULL)
1441
        free (pathbuf);
1442
      pathbuf_len = 0;
1443
      pathbuf = (char *) bfd_malloc (len);
1444
      if (pathbuf == NULL)
1445
        goto out;
1446
      pathbuf_len = len;
1447
    }
1448
 
1449
  newp = pathbuf;
1450
  while (dir_up-- > 0)
1451
    {
1452
      /* FIXME: Support Windows style path separators as well.  */
1453
      strcpy (newp, "../");
1454
      newp += 3;
1455
    }
1456
 
1457
  if (down)
1458
    sprintf (newp, "%s/%s", down, pathp);
1459
  else
1460
    strcpy (newp, pathp);
1461
 
1462
 out:
1463
  free (lpath);
1464
  free (rpath);
1465
  return pathbuf;
1466
}
1467
 
1468
/* Build a BFD style extended name table.  */
1469
 
1470
bfd_boolean
1471
_bfd_archive_bsd_construct_extended_name_table (bfd *abfd,
1472
                                                char **tabloc,
1473
                                                bfd_size_type *tablen,
1474
                                                const char **name)
1475
{
1476
  *name = "ARFILENAMES/";
1477
  return _bfd_construct_extended_name_table (abfd, FALSE, tabloc, tablen);
1478
}
1479
 
1480
/* Build an SVR4 style extended name table.  */
1481
 
1482
bfd_boolean
1483
_bfd_archive_coff_construct_extended_name_table (bfd *abfd,
1484
                                                 char **tabloc,
1485
                                                 bfd_size_type *tablen,
1486
                                                 const char **name)
1487
{
1488
  *name = "//";
1489
  return _bfd_construct_extended_name_table (abfd, TRUE, tabloc, tablen);
1490
}
1491
 
1492
/* Follows archive_head and produces an extended name table if
1493
   necessary.  Returns (in tabloc) a pointer to an extended name
1494
   table, and in tablen the length of the table.  If it makes an entry
1495
   it clobbers the filename so that the element may be written without
1496
   further massage.  Returns TRUE if it ran successfully, FALSE if
1497
   something went wrong.  A successful return may still involve a
1498
   zero-length tablen!  */
1499
 
1500
bfd_boolean
1501
_bfd_construct_extended_name_table (bfd *abfd,
1502
                                    bfd_boolean trailing_slash,
1503
                                    char **tabloc,
1504
                                    bfd_size_type *tablen)
1505
{
1506
  unsigned int maxname = abfd->xvec->ar_max_namelen;
1507
  bfd_size_type total_namelen = 0;
1508
  bfd *current;
1509
  char *strptr;
1510
  const char *last_filename;
1511
  long last_stroff;
1512
 
1513
  *tablen = 0;
1514
  last_filename = NULL;
1515
 
1516
  /* Figure out how long the table should be.  */
1517
  for (current = abfd->archive_head;
1518
       current != NULL;
1519
       current = current->archive_next)
1520
    {
1521
      const char *normal;
1522
      unsigned int thislen;
1523
 
1524
      if (bfd_is_thin_archive (abfd))
1525
        {
1526
          const char *filename = current->filename;
1527
 
1528
          /* If the element being added is a member of another archive
1529
             (i.e., we are flattening), use the containing archive's name.  */
1530
          if (current->my_archive
1531
              && ! bfd_is_thin_archive (current->my_archive))
1532
            filename = current->my_archive->filename;
1533
 
1534
          /* If the path is the same as the previous path seen,
1535
             reuse it.  This can happen when flattening a thin
1536
             archive that contains other archives.  */
1537
          if (last_filename && filename_cmp (last_filename, filename) == 0)
1538
            continue;
1539
 
1540
          last_filename = filename;
1541
 
1542
          /* If the path is relative, adjust it relative to
1543
             the containing archive. */
1544
          if (! IS_ABSOLUTE_PATH (filename)
1545
              && ! IS_ABSOLUTE_PATH (abfd->filename))
1546
            normal = adjust_relative_path (filename, abfd->filename);
1547
          else
1548
            normal = filename;
1549
 
1550
          /* In a thin archive, always store the full pathname
1551
             in the extended name table.  */
1552
          total_namelen += strlen (normal) + 1;
1553
          if (trailing_slash)
1554
            /* Leave room for trailing slash.  */
1555
            ++total_namelen;
1556
 
1557
          continue;
1558
        }
1559
 
1560
      normal = normalize (current, current->filename);
1561
      if (normal == NULL)
1562
        return FALSE;
1563
 
1564
      thislen = strlen (normal);
1565
 
1566
      if (thislen > maxname
1567
          && (bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0)
1568
        thislen = maxname;
1569
 
1570
      if (thislen > maxname)
1571
        {
1572
          /* Add one to leave room for \n.  */
1573
          total_namelen += thislen + 1;
1574
          if (trailing_slash)
1575
            {
1576
              /* Leave room for trailing slash.  */
1577
              ++total_namelen;
1578
            }
1579
        }
1580
      else
1581
        {
1582
          struct ar_hdr *hdr = arch_hdr (current);
1583
          if (filename_ncmp (normal, hdr->ar_name, thislen) != 0
1584
              || (thislen < sizeof hdr->ar_name
1585
                  && hdr->ar_name[thislen] != ar_padchar (current)))
1586
            {
1587
              /* Must have been using extended format even though it
1588
                 didn't need to.  Fix it to use normal format.  */
1589
              memcpy (hdr->ar_name, normal, thislen);
1590
              if (thislen < maxname
1591
                  || (thislen == maxname && thislen < sizeof hdr->ar_name))
1592
                hdr->ar_name[thislen] = ar_padchar (current);
1593
            }
1594
        }
1595
    }
1596
 
1597
  if (total_namelen == 0)
1598
    return TRUE;
1599
 
1600
  *tabloc = (char *) bfd_zalloc (abfd, total_namelen);
1601
  if (*tabloc == NULL)
1602
    return FALSE;
1603
 
1604
  *tablen = total_namelen;
1605
  strptr = *tabloc;
1606
 
1607
  last_filename = NULL;
1608
  last_stroff = 0;
1609
 
1610
  for (current = abfd->archive_head;
1611
       current != NULL;
1612
       current = current->archive_next)
1613
    {
1614
      const char *normal;
1615
      unsigned int thislen;
1616
      long stroff;
1617
      const char *filename = current->filename;
1618
 
1619
      if (bfd_is_thin_archive (abfd))
1620
        {
1621
          /* If the element being added is a member of another archive
1622
             (i.e., we are flattening), use the containing archive's name.  */
1623
          if (current->my_archive
1624
              && ! bfd_is_thin_archive (current->my_archive))
1625
            filename = current->my_archive->filename;
1626
          /* If the path is the same as the previous path seen,
1627
             reuse it.  This can happen when flattening a thin
1628
             archive that contains other archives.
1629
             If the path is relative, adjust it relative to
1630
             the containing archive.  */
1631
          if (last_filename && filename_cmp (last_filename, filename) == 0)
1632
            normal = last_filename;
1633
          else if (! IS_ABSOLUTE_PATH (filename)
1634
                   && ! IS_ABSOLUTE_PATH (abfd->filename))
1635
            normal = adjust_relative_path (filename, abfd->filename);
1636
          else
1637
            normal = filename;
1638
        }
1639
      else
1640
        {
1641
          normal = normalize (current, filename);
1642
          if (normal == NULL)
1643
            return FALSE;
1644
        }
1645
 
1646
      thislen = strlen (normal);
1647
      if (thislen > maxname || bfd_is_thin_archive (abfd))
1648
        {
1649
          /* Works for now; may need to be re-engineered if we
1650
             encounter an oddball archive format and want to
1651
             generalise this hack.  */
1652
          struct ar_hdr *hdr = arch_hdr (current);
1653
          if (normal == last_filename)
1654
            stroff = last_stroff;
1655
          else
1656
            {
1657
              strcpy (strptr, normal);
1658
              if (! trailing_slash)
1659
                strptr[thislen] = ARFMAG[1];
1660
              else
1661
                {
1662
                  strptr[thislen] = '/';
1663
                  strptr[thislen + 1] = ARFMAG[1];
1664
                }
1665
              stroff = strptr - *tabloc;
1666
              last_stroff = stroff;
1667
            }
1668
          hdr->ar_name[0] = ar_padchar (current);
1669
          if (bfd_is_thin_archive (abfd) && current->origin > 0)
1670
            {
1671
              int len = snprintf (hdr->ar_name + 1, maxname - 1, "%-ld:",
1672
                                  stroff);
1673
              _bfd_ar_spacepad (hdr->ar_name + 1 + len, maxname - 1 - len,
1674
                                "%-ld",
1675
                                current->origin - sizeof (struct ar_hdr));
1676
            }
1677
          else
1678
            _bfd_ar_spacepad (hdr->ar_name + 1, maxname - 1, "%-ld", stroff);
1679
          if (normal != last_filename)
1680
            {
1681
              strptr += thislen + 1;
1682
              if (trailing_slash)
1683
                ++strptr;
1684
              last_filename = filename;
1685
            }
1686
        }
1687
    }
1688
 
1689
  return TRUE;
1690
}
1691
 
1692
/* Do not construct an extended name table but transforms name field into
1693
   its extended form.  */
1694
 
1695
bfd_boolean
1696
_bfd_archive_bsd44_construct_extended_name_table (bfd *abfd,
1697
                                                  char **tabloc,
1698
                                                  bfd_size_type *tablen,
1699
                                                  const char **name)
1700
{
1701
  unsigned int maxname = abfd->xvec->ar_max_namelen;
1702
  bfd *current;
1703
 
1704
  *tablen = 0;
1705
  *tabloc = NULL;
1706
  *name = NULL;
1707
 
1708
  for (current = abfd->archive_head;
1709
       current != NULL;
1710
       current = current->archive_next)
1711
    {
1712
      const char *normal = normalize (current, current->filename);
1713
      int has_space = 0;
1714
      unsigned int len;
1715
 
1716
      if (normal == NULL)
1717
        return FALSE;
1718
 
1719
      for (len = 0; normal[len]; len++)
1720
        if (normal[len] == ' ')
1721
          has_space = 1;
1722
 
1723
      if (len > maxname || has_space)
1724
        {
1725
          struct ar_hdr *hdr = arch_hdr (current);
1726
 
1727
          len = (len + 3) & ~3;
1728
          arch_eltdata (current)->extra_size = len;
1729
          _bfd_ar_spacepad (hdr->ar_name, maxname, "#1/%lu", len);
1730
        }
1731
    }
1732
 
1733
  return TRUE;
1734
}
1735
 
1736
/* Write an archive header.  */
1737
 
1738
bfd_boolean
1739
_bfd_generic_write_ar_hdr (bfd *archive, bfd *abfd)
1740
{
1741
  struct ar_hdr *hdr = arch_hdr (abfd);
1742
 
1743
  if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr))
1744
    return FALSE;
1745
  return TRUE;
1746
}
1747
 
1748
/* Write an archive header using BSD4.4 convention.  */
1749
 
1750
bfd_boolean
1751
_bfd_bsd44_write_ar_hdr (bfd *archive, bfd *abfd)
1752
{
1753
  struct ar_hdr *hdr = arch_hdr (abfd);
1754
 
1755
  if (is_bsd44_extended_name (hdr->ar_name))
1756
    {
1757
      /* This is a BSD 4.4 extended name.  */
1758
      const char *fullname = normalize (abfd, abfd->filename);
1759
      unsigned int len = strlen (fullname);
1760
      unsigned int padded_len = (len + 3) & ~3;
1761
 
1762
      BFD_ASSERT (padded_len == arch_eltdata (abfd)->extra_size);
1763
 
1764
      _bfd_ar_spacepad (hdr->ar_size, sizeof (hdr->ar_size), "%-10ld",
1765
                        arch_eltdata (abfd)->parsed_size + padded_len);
1766
 
1767
      if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr))
1768
        return FALSE;
1769
 
1770
      if (bfd_bwrite (fullname, len, archive) != len)
1771
        return FALSE;
1772
      if (len & 3)
1773
        {
1774
          static const char pad[3] = { 0, 0, 0 };
1775
 
1776
          len = 4 - (len & 3);
1777
          if (bfd_bwrite (pad, len, archive) != len)
1778
            return FALSE;
1779
        }
1780
    }
1781
  else
1782
    {
1783
      if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr))
1784
        return FALSE;
1785
    }
1786
  return TRUE;
1787
}
1788
 
1789
/* A couple of functions for creating ar_hdrs.  */
1790
 
1791
#ifdef HPUX_LARGE_AR_IDS
1792
/* Function to encode large UID/GID values according to HP.  */
1793
 
1794
static void
1795
hpux_uid_gid_encode (char str[6], long int id)
1796
{
1797
  int cnt;
1798
 
1799
  str[5] = '@' + (id & 3);
1800
  id >>= 2;
1801
 
1802
  for (cnt = 4; cnt >= 0; --cnt, id >>= 6)
1803
    str[cnt] = ' ' + (id & 0x3f);
1804
}
1805
#endif  /* HPUX_LARGE_AR_IDS */
1806
 
1807
#ifndef HAVE_GETUID
1808
#define getuid() 0
1809
#endif
1810
 
1811
#ifndef HAVE_GETGID
1812
#define getgid() 0
1813
#endif
1814
 
1815
/* Takes a filename, returns an arelt_data for it, or NULL if it can't
1816
   make one.  The filename must refer to a filename in the filesystem.
1817
   The filename field of the ar_hdr will NOT be initialized.  If member
1818
   is set, and it's an in-memory bfd, we fake it.  */
1819
 
1820
static struct areltdata *
1821
bfd_ar_hdr_from_filesystem (bfd *abfd, const char *filename, bfd *member)
1822
{
1823
  struct stat status;
1824
  struct areltdata *ared;
1825
  struct ar_hdr *hdr;
1826
  bfd_size_type amt;
1827
 
1828
  if (member && (member->flags & BFD_IN_MEMORY) != 0)
1829
    {
1830
      /* Assume we just "made" the member, and fake it.  */
1831
      struct bfd_in_memory *bim = (struct bfd_in_memory *) member->iostream;
1832
      time (&status.st_mtime);
1833
      status.st_uid = getuid ();
1834
      status.st_gid = getgid ();
1835
      status.st_mode = 0644;
1836
      status.st_size = bim->size;
1837
    }
1838
  else if (stat (filename, &status) != 0)
1839
    {
1840
      bfd_set_error (bfd_error_system_call);
1841
      return NULL;
1842
    }
1843
 
1844
  /* If the caller requested that the BFD generate deterministic output,
1845
     fake values for modification time, UID, GID, and file mode.  */
1846
  if ((abfd->flags & BFD_DETERMINISTIC_OUTPUT) != 0)
1847
    {
1848
      status.st_mtime = 0;
1849
      status.st_uid = 0;
1850
      status.st_gid = 0;
1851
      status.st_mode = 0644;
1852
    }
1853
 
1854
  amt = sizeof (struct ar_hdr) + sizeof (struct areltdata);
1855
  ared = (struct areltdata *) bfd_zalloc (abfd, amt);
1856
  if (ared == NULL)
1857
    return NULL;
1858
  hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
1859
 
1860
  /* ar headers are space padded, not null padded!  */
1861
  memset (hdr, ' ', sizeof (struct ar_hdr));
1862
 
1863
  _bfd_ar_spacepad (hdr->ar_date, sizeof (hdr->ar_date), "%-12ld",
1864
                    status.st_mtime);
1865
#ifdef HPUX_LARGE_AR_IDS
1866
  /* HP has a very "special" way to handle UID/GID's with numeric values
1867
     > 99999.  */
1868
  if (status.st_uid > 99999)
1869
    hpux_uid_gid_encode (hdr->ar_uid, (long) status.st_uid);
1870
  else
1871
#endif
1872
    _bfd_ar_spacepad (hdr->ar_uid, sizeof (hdr->ar_uid), "%ld",
1873
                      status.st_uid);
1874
#ifdef HPUX_LARGE_AR_IDS
1875
  /* HP has a very "special" way to handle UID/GID's with numeric values
1876
     > 99999.  */
1877
  if (status.st_gid > 99999)
1878
    hpux_uid_gid_encode (hdr->ar_gid, (long) status.st_gid);
1879
  else
1880
#endif
1881
    _bfd_ar_spacepad (hdr->ar_gid, sizeof (hdr->ar_gid), "%ld",
1882
                      status.st_gid);
1883
  _bfd_ar_spacepad (hdr->ar_mode, sizeof (hdr->ar_mode), "%-8lo",
1884
                    status.st_mode);
1885
  _bfd_ar_spacepad (hdr->ar_size, sizeof (hdr->ar_size), "%-10ld",
1886
                    status.st_size);
1887
  memcpy (hdr->ar_fmag, ARFMAG, 2);
1888
  ared->parsed_size = status.st_size;
1889
  ared->arch_header = (char *) hdr;
1890
 
1891
  return ared;
1892
}
1893
 
1894
/* Analogous to stat call.  */
1895
 
1896
int
1897
bfd_generic_stat_arch_elt (bfd *abfd, struct stat *buf)
1898
{
1899
  struct ar_hdr *hdr;
1900
  char *aloser;
1901
 
1902
  if (abfd->arelt_data == NULL)
1903
    {
1904
      bfd_set_error (bfd_error_invalid_operation);
1905
      return -1;
1906
    }
1907
 
1908
  hdr = arch_hdr (abfd);
1909
 
1910
#define foo(arelt, stelt, size)                         \
1911
  buf->stelt = strtol (hdr->arelt, &aloser, size);      \
1912
  if (aloser == hdr->arelt)                             \
1913
    return -1;
1914
 
1915
  /* Some platforms support special notations for large IDs.  */
1916
#ifdef HPUX_LARGE_AR_IDS
1917
# define foo2(arelt, stelt, size)                                       \
1918
  if (hdr->arelt[5] == ' ')                                             \
1919
    {                                                                   \
1920
      foo (arelt, stelt, size);                                         \
1921
    }                                                                   \
1922
  else                                                                  \
1923
    {                                                                   \
1924
      int cnt;                                                          \
1925
      for (buf->stelt = cnt = 0; cnt < 5; ++cnt)                 \
1926
        {                                                               \
1927
          if (hdr->arelt[cnt] < ' ' || hdr->arelt[cnt] > ' ' + 0x3f)    \
1928
            return -1;                                                  \
1929
          buf->stelt <<= 6;                                             \
1930
          buf->stelt += hdr->arelt[cnt] - ' ';                          \
1931
        }                                                               \
1932
      if (hdr->arelt[5] < '@' || hdr->arelt[5] > '@' + 3)               \
1933
        return -1;                                                      \
1934
      buf->stelt <<= 2;                                                 \
1935
      buf->stelt += hdr->arelt[5] - '@';                                \
1936
    }
1937
#else
1938
# define foo2(arelt, stelt, size) foo (arelt, stelt, size)
1939
#endif
1940
 
1941
  foo (ar_date, st_mtime, 10);
1942
  foo2 (ar_uid, st_uid, 10);
1943
  foo2 (ar_gid, st_gid, 10);
1944
  foo (ar_mode, st_mode, 8);
1945
 
1946
  buf->st_size = arch_eltdata (abfd)->parsed_size;
1947
 
1948
  return 0;
1949
}
1950
 
1951
void
1952
bfd_dont_truncate_arname (bfd *abfd, const char *pathname, char *arhdr)
1953
{
1954
  /* FIXME: This interacts unpleasantly with ar's quick-append option.
1955
     Fortunately ic960 users will never use that option.  Fixing this
1956
     is very hard; fortunately I know how to do it and will do so once
1957
     intel's release is out the door.  */
1958
 
1959
  struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
1960
  size_t length;
1961
  const char *filename;
1962
  size_t maxlen = ar_maxnamelen (abfd);
1963
 
1964
  if ((bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0)
1965
    {
1966
      bfd_bsd_truncate_arname (abfd, pathname, arhdr);
1967
      return;
1968
    }
1969
 
1970
  filename = normalize (abfd, pathname);
1971
  if (filename == NULL)
1972
    {
1973
      /* FIXME */
1974
      abort ();
1975
    }
1976
 
1977
  length = strlen (filename);
1978
 
1979
  if (length <= maxlen)
1980
    memcpy (hdr->ar_name, filename, length);
1981
 
1982
  /* Add the padding character if there is room for it.  */
1983
  if (length < maxlen
1984
      || (length == maxlen && length < sizeof hdr->ar_name))
1985
    (hdr->ar_name)[length] = ar_padchar (abfd);
1986
}
1987
 
1988
void
1989
bfd_bsd_truncate_arname (bfd *abfd, const char *pathname, char *arhdr)
1990
{
1991
  struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
1992
  size_t length;
1993
  const char *filename = lbasename (pathname);
1994
  size_t maxlen = ar_maxnamelen (abfd);
1995
 
1996
  length = strlen (filename);
1997
 
1998
  if (length <= maxlen)
1999
    memcpy (hdr->ar_name, filename, length);
2000
  else
2001
    {
2002
      /* pathname: meet procrustes */
2003
      memcpy (hdr->ar_name, filename, maxlen);
2004
      length = maxlen;
2005
    }
2006
 
2007
  if (length < maxlen)
2008
    (hdr->ar_name)[length] = ar_padchar (abfd);
2009
}
2010
 
2011
/* Store name into ar header.  Truncates the name to fit.
2012
   1> strip pathname to be just the basename.
2013
   2> if it's short enuf to fit, stuff it in.
2014
   3> If it doesn't end with .o, truncate it to fit
2015
   4> truncate it before the .o, append .o, stuff THAT in.  */
2016
 
2017
/* This is what gnu ar does.  It's better but incompatible with the
2018
   bsd ar.  */
2019
 
2020
void
2021
bfd_gnu_truncate_arname (bfd *abfd, const char *pathname, char *arhdr)
2022
{
2023
  struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
2024
  size_t length;
2025
  const char *filename = lbasename (pathname);
2026
  size_t maxlen = ar_maxnamelen (abfd);
2027
 
2028
  length = strlen (filename);
2029
 
2030
  if (length <= maxlen)
2031
    memcpy (hdr->ar_name, filename, length);
2032
  else
2033
    {
2034
      /* pathname: meet procrustes.  */
2035
      memcpy (hdr->ar_name, filename, maxlen);
2036
      if ((filename[length - 2] == '.') && (filename[length - 1] == 'o'))
2037
        {
2038
          hdr->ar_name[maxlen - 2] = '.';
2039
          hdr->ar_name[maxlen - 1] = 'o';
2040
        }
2041
      length = maxlen;
2042
    }
2043
 
2044
  if (length < 16)
2045
    (hdr->ar_name)[length] = ar_padchar (abfd);
2046
}
2047
 
2048
/* The BFD is open for write and has its format set to bfd_archive.  */
2049
 
2050
bfd_boolean
2051
_bfd_write_archive_contents (bfd *arch)
2052
{
2053
  bfd *current;
2054
  char *etable = NULL;
2055
  bfd_size_type elength = 0;
2056
  const char *ename = NULL;
2057
  bfd_boolean makemap = bfd_has_map (arch);
2058
  /* If no .o's, don't bother to make a map.  */
2059
  bfd_boolean hasobjects = FALSE;
2060
  bfd_size_type wrote;
2061
  int tries;
2062
  char *armag;
2063
 
2064
  /* Verify the viability of all entries; if any of them live in the
2065
     filesystem (as opposed to living in an archive open for input)
2066
     then construct a fresh ar_hdr for them.  */
2067
  for (current = arch->archive_head;
2068
       current != NULL;
2069
       current = current->archive_next)
2070
    {
2071
      /* This check is checking the bfds for the objects we're reading
2072
         from (which are usually either an object file or archive on
2073
         disk), not the archive entries we're writing to.  We don't
2074
         actually create bfds for the archive members, we just copy
2075
         them byte-wise when we write out the archive.  */
2076
      if (bfd_write_p (current))
2077
        {
2078
          bfd_set_error (bfd_error_invalid_operation);
2079
          goto input_err;
2080
        }
2081
      if (!current->arelt_data)
2082
        {
2083
          current->arelt_data =
2084
            bfd_ar_hdr_from_filesystem (arch, current->filename, current);
2085
          if (!current->arelt_data)
2086
            goto input_err;
2087
 
2088
          /* Put in the file name.  */
2089
          BFD_SEND (arch, _bfd_truncate_arname,
2090
                    (arch, current->filename, (char *) arch_hdr (current)));
2091
        }
2092
 
2093
      if (makemap && ! hasobjects)
2094
        {                       /* Don't bother if we won't make a map!  */
2095
          if ((bfd_check_format (current, bfd_object)))
2096
            hasobjects = TRUE;
2097
        }
2098
    }
2099
 
2100
  if (!BFD_SEND (arch, _bfd_construct_extended_name_table,
2101
                 (arch, &etable, &elength, &ename)))
2102
    return FALSE;
2103
 
2104
  if (bfd_seek (arch, (file_ptr) 0, SEEK_SET) != 0)
2105
    return FALSE;
2106
  armag = ARMAG;
2107
  if (bfd_is_thin_archive (arch))
2108
    armag = ARMAGT;
2109
  wrote = bfd_bwrite (armag, SARMAG, arch);
2110
  if (wrote != SARMAG)
2111
    return FALSE;
2112
 
2113
  if (makemap && hasobjects)
2114
    {
2115
      if (! _bfd_compute_and_write_armap (arch, (unsigned int) elength))
2116
        return FALSE;
2117
    }
2118
 
2119
  if (elength != 0)
2120
    {
2121
      struct ar_hdr hdr;
2122
 
2123
      memset (&hdr, ' ', sizeof (struct ar_hdr));
2124
      memcpy (hdr.ar_name, ename, strlen (ename));
2125
      /* Round size up to even number in archive header.  */
2126
      _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld",
2127
                        (elength + 1) & ~(bfd_size_type) 1);
2128
      memcpy (hdr.ar_fmag, ARFMAG, 2);
2129
      if ((bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
2130
           != sizeof (struct ar_hdr))
2131
          || bfd_bwrite (etable, elength, arch) != elength)
2132
        return FALSE;
2133
      if ((elength % 2) == 1)
2134
        {
2135
          if (bfd_bwrite (&ARFMAG[1], 1, arch) != 1)
2136
            return FALSE;
2137
        }
2138
    }
2139
 
2140
  for (current = arch->archive_head;
2141
       current != NULL;
2142
       current = current->archive_next)
2143
    {
2144
      char buffer[DEFAULT_BUFFERSIZE];
2145
      unsigned int remaining = arelt_size (current);
2146
 
2147
      /* Write ar header.  */
2148
      if (!_bfd_write_ar_hdr (arch, current))
2149
        return FALSE;
2150
      if (bfd_is_thin_archive (arch))
2151
        continue;
2152
      if (bfd_seek (current, (file_ptr) 0, SEEK_SET) != 0)
2153
        goto input_err;
2154
 
2155
      while (remaining)
2156
        {
2157
          unsigned int amt = DEFAULT_BUFFERSIZE;
2158
 
2159
          if (amt > remaining)
2160
            amt = remaining;
2161
          errno = 0;
2162
          if (bfd_bread (buffer, amt, current) != amt)
2163
            {
2164
              if (bfd_get_error () != bfd_error_system_call)
2165
                bfd_set_error (bfd_error_file_truncated);
2166
              goto input_err;
2167
            }
2168
          if (bfd_bwrite (buffer, amt, arch) != amt)
2169
            return FALSE;
2170
          remaining -= amt;
2171
        }
2172
 
2173
      if ((arelt_size (current) % 2) == 1)
2174
        {
2175
          if (bfd_bwrite (&ARFMAG[1], 1, arch) != 1)
2176
            return FALSE;
2177
        }
2178
    }
2179
 
2180
  if (makemap && hasobjects)
2181
    {
2182
      /* Verify the timestamp in the archive file.  If it would not be
2183
         accepted by the linker, rewrite it until it would be.  If
2184
         anything odd happens, break out and just return.  (The
2185
         Berkeley linker checks the timestamp and refuses to read the
2186
         table-of-contents if it is >60 seconds less than the file's
2187
         modified-time.  That painful hack requires this painful hack.  */
2188
      tries = 1;
2189
      do
2190
        {
2191
          if (bfd_update_armap_timestamp (arch))
2192
            break;
2193
          (*_bfd_error_handler)
2194
            (_("Warning: writing archive was slow: rewriting timestamp\n"));
2195
        }
2196
      while (++tries < 6);
2197
    }
2198
 
2199
  return TRUE;
2200
 
2201
 input_err:
2202
  bfd_set_error (bfd_error_on_input, current, bfd_get_error ());
2203
  return FALSE;
2204
}
2205
 
2206
/* Note that the namidx for the first symbol is 0.  */
2207
 
2208
bfd_boolean
2209
_bfd_compute_and_write_armap (bfd *arch, unsigned int elength)
2210
{
2211
  char *first_name = NULL;
2212
  bfd *current;
2213
  file_ptr elt_no = 0;
2214
  struct orl *map = NULL;
2215
  unsigned int orl_max = 1024;          /* Fine initial default.  */
2216
  unsigned int orl_count = 0;
2217
  int stridx = 0;
2218
  asymbol **syms = NULL;
2219
  long syms_max = 0;
2220
  bfd_boolean ret;
2221
  bfd_size_type amt;
2222
 
2223
  /* Dunno if this is the best place for this info...  */
2224
  if (elength != 0)
2225
    elength += sizeof (struct ar_hdr);
2226
  elength += elength % 2;
2227
 
2228
  amt = orl_max * sizeof (struct orl);
2229
  map = (struct orl *) bfd_malloc (amt);
2230
  if (map == NULL)
2231
    goto error_return;
2232
 
2233
  /* We put the symbol names on the arch objalloc, and then discard
2234
     them when done.  */
2235
  first_name = (char *) bfd_alloc (arch, 1);
2236
  if (first_name == NULL)
2237
    goto error_return;
2238
 
2239
  /* Drop all the files called __.SYMDEF, we're going to make our own.  */
2240
  while (arch->archive_head
2241
         && strcmp (arch->archive_head->filename, "__.SYMDEF") == 0)
2242
    arch->archive_head = arch->archive_head->archive_next;
2243
 
2244
  /* Map over each element.  */
2245
  for (current = arch->archive_head;
2246
       current != NULL;
2247
       current = current->archive_next, elt_no++)
2248
    {
2249
      if (bfd_check_format (current, bfd_object)
2250
          && (bfd_get_file_flags (current) & HAS_SYMS) != 0)
2251
        {
2252
          long storage;
2253
          long symcount;
2254
          long src_count;
2255
 
2256
          storage = bfd_get_symtab_upper_bound (current);
2257
          if (storage < 0)
2258
            goto error_return;
2259
 
2260
          if (storage != 0)
2261
            {
2262
              if (storage > syms_max)
2263
                {
2264
                  if (syms_max > 0)
2265
                    free (syms);
2266
                  syms_max = storage;
2267
                  syms = (asymbol **) bfd_malloc (syms_max);
2268
                  if (syms == NULL)
2269
                    goto error_return;
2270
                }
2271
              symcount = bfd_canonicalize_symtab (current, syms);
2272
              if (symcount < 0)
2273
                goto error_return;
2274
 
2275
              /* Now map over all the symbols, picking out the ones we
2276
                 want.  */
2277
              for (src_count = 0; src_count < symcount; src_count++)
2278
                {
2279
                  flagword flags = (syms[src_count])->flags;
2280
                  asection *sec = syms[src_count]->section;
2281
 
2282
                  if ((flags & BSF_GLOBAL
2283
                       || flags & BSF_WEAK
2284
                       || flags & BSF_INDIRECT
2285
                       || flags & BSF_GNU_UNIQUE
2286
                       || bfd_is_com_section (sec))
2287
                      && ! bfd_is_und_section (sec))
2288
                    {
2289
                      bfd_size_type namelen;
2290
                      struct orl *new_map;
2291
 
2292
                      /* This symbol will go into the archive header.  */
2293
                      if (orl_count == orl_max)
2294
                        {
2295
                          orl_max *= 2;
2296
                          amt = orl_max * sizeof (struct orl);
2297
                          new_map = (struct orl *) bfd_realloc (map, amt);
2298
                          if (new_map == NULL)
2299
                            goto error_return;
2300
 
2301
                          map = new_map;
2302
                        }
2303
 
2304
                      namelen = strlen (syms[src_count]->name);
2305
                      amt = sizeof (char *);
2306
                      map[orl_count].name = (char **) bfd_alloc (arch, amt);
2307
                      if (map[orl_count].name == NULL)
2308
                        goto error_return;
2309
                      *(map[orl_count].name) = (char *) bfd_alloc (arch,
2310
                                                                   namelen + 1);
2311
                      if (*(map[orl_count].name) == NULL)
2312
                        goto error_return;
2313
                      strcpy (*(map[orl_count].name), syms[src_count]->name);
2314
                      map[orl_count].u.abfd = current;
2315
                      map[orl_count].namidx = stridx;
2316
 
2317
                      stridx += namelen + 1;
2318
                      ++orl_count;
2319
                    }
2320
                }
2321
            }
2322
 
2323
          /* Now ask the BFD to free up any cached information, so we
2324
             don't fill all of memory with symbol tables.  */
2325
          if (! bfd_free_cached_info (current))
2326
            goto error_return;
2327
        }
2328
    }
2329
 
2330
  /* OK, now we have collected all the data, let's write them out.  */
2331
  ret = BFD_SEND (arch, write_armap,
2332
                  (arch, elength, map, orl_count, stridx));
2333
 
2334
  if (syms_max > 0)
2335
    free (syms);
2336
  if (map != NULL)
2337
    free (map);
2338
  if (first_name != NULL)
2339
    bfd_release (arch, first_name);
2340
 
2341
  return ret;
2342
 
2343
 error_return:
2344
  if (syms_max > 0)
2345
    free (syms);
2346
  if (map != NULL)
2347
    free (map);
2348
  if (first_name != NULL)
2349
    bfd_release (arch, first_name);
2350
 
2351
  return FALSE;
2352
}
2353
 
2354
bfd_boolean
2355
bsd_write_armap (bfd *arch,
2356
                 unsigned int elength,
2357
                 struct orl *map,
2358
                 unsigned int orl_count,
2359
                 int stridx)
2360
{
2361
  int padit = stridx & 1;
2362
  unsigned int ranlibsize = orl_count * BSD_SYMDEF_SIZE;
2363
  unsigned int stringsize = stridx + padit;
2364
  /* Include 8 bytes to store ranlibsize and stringsize in output.  */
2365
  unsigned int mapsize = ranlibsize + stringsize + 8;
2366
  file_ptr firstreal;
2367
  bfd *current = arch->archive_head;
2368
  bfd *last_elt = current;      /* Last element arch seen.  */
2369
  bfd_byte temp[4];
2370
  unsigned int count;
2371
  struct ar_hdr hdr;
2372
  long uid, gid;
2373
 
2374
  firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
2375
 
2376
  /* If deterministic, we use 0 as the timestamp in the map.
2377
     Some linkers may require that the archive filesystem modification
2378
     time is less than (or near to) the archive map timestamp.  Those
2379
     linkers should not be used with deterministic mode.  (GNU ld and
2380
     Gold do not have this restriction.)  */
2381
  bfd_ardata (arch)->armap_timestamp = 0;
2382
  uid = 0;
2383
  gid = 0;
2384
  if ((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0)
2385
    {
2386
      struct stat statbuf;
2387
 
2388
      if (stat (arch->filename, &statbuf) == 0)
2389
        bfd_ardata (arch)->armap_timestamp = (statbuf.st_mtime
2390
                                              + ARMAP_TIME_OFFSET);
2391
      uid = getuid();
2392
      gid = getgid();
2393
    }
2394
 
2395
  memset (&hdr, ' ', sizeof (struct ar_hdr));
2396
  memcpy (hdr.ar_name, RANLIBMAG, strlen (RANLIBMAG));
2397
  bfd_ardata (arch)->armap_datepos = (SARMAG
2398
                                      + offsetof (struct ar_hdr, ar_date[0]));
2399
  _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
2400
                    bfd_ardata (arch)->armap_timestamp);
2401
  _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", uid);
2402
  _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", gid);
2403
  _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", mapsize);
2404
  memcpy (hdr.ar_fmag, ARFMAG, 2);
2405
  if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
2406
      != sizeof (struct ar_hdr))
2407
    return FALSE;
2408
  H_PUT_32 (arch, ranlibsize, temp);
2409
  if (bfd_bwrite (temp, sizeof (temp), arch) != sizeof (temp))
2410
    return FALSE;
2411
 
2412
  for (count = 0; count < orl_count; count++)
2413
    {
2414
      bfd_byte buf[BSD_SYMDEF_SIZE];
2415
 
2416
      if (map[count].u.abfd != last_elt)
2417
        {
2418
          do
2419
            {
2420
              struct areltdata *ared = arch_eltdata (current);
2421
 
2422
              firstreal += (ared->parsed_size + ared->extra_size
2423
                            + sizeof (struct ar_hdr));
2424
              firstreal += firstreal % 2;
2425
              current = current->archive_next;
2426
            }
2427
          while (current != map[count].u.abfd);
2428
        }
2429
 
2430
      last_elt = current;
2431
      H_PUT_32 (arch, map[count].namidx, buf);
2432
      H_PUT_32 (arch, firstreal, buf + BSD_SYMDEF_OFFSET_SIZE);
2433
      if (bfd_bwrite (buf, BSD_SYMDEF_SIZE, arch)
2434
          != BSD_SYMDEF_SIZE)
2435
        return FALSE;
2436
    }
2437
 
2438
  /* Now write the strings themselves.  */
2439
  H_PUT_32 (arch, stringsize, temp);
2440
  if (bfd_bwrite (temp, sizeof (temp), arch) != sizeof (temp))
2441
    return FALSE;
2442
  for (count = 0; count < orl_count; count++)
2443
    {
2444
      size_t len = strlen (*map[count].name) + 1;
2445
 
2446
      if (bfd_bwrite (*map[count].name, len, arch) != len)
2447
        return FALSE;
2448
    }
2449
 
2450
  /* The spec sez this should be a newline.  But in order to be
2451
     bug-compatible for sun's ar we use a null.  */
2452
  if (padit)
2453
    {
2454
      if (bfd_bwrite ("", 1, arch) != 1)
2455
        return FALSE;
2456
    }
2457
 
2458
  return TRUE;
2459
}
2460
 
2461
/* At the end of archive file handling, update the timestamp in the
2462
   file, so the linker will accept it.
2463
 
2464
   Return TRUE if the timestamp was OK, or an unusual problem happened.
2465
   Return FALSE if we updated the timestamp.  */
2466
 
2467
bfd_boolean
2468
_bfd_archive_bsd_update_armap_timestamp (bfd *arch)
2469
{
2470
  struct stat archstat;
2471
  struct ar_hdr hdr;
2472
 
2473
  /* If creating deterministic archives, just leave the timestamp as-is.  */
2474
  if ((arch->flags & BFD_DETERMINISTIC_OUTPUT) != 0)
2475
    return TRUE;
2476
 
2477
  /* Flush writes, get last-write timestamp from file, and compare it
2478
     to the timestamp IN the file.  */
2479
  bfd_flush (arch);
2480
  if (bfd_stat (arch, &archstat) == -1)
2481
    {
2482
      bfd_perror (_("Reading archive file mod timestamp"));
2483
 
2484
      /* Can't read mod time for some reason.  */
2485
      return TRUE;
2486
    }
2487
  if (((long) archstat.st_mtime) <= bfd_ardata (arch)->armap_timestamp)
2488
    /* OK by the linker's rules.  */
2489
    return TRUE;
2490
 
2491
  /* Update the timestamp.  */
2492
  bfd_ardata (arch)->armap_timestamp = archstat.st_mtime + ARMAP_TIME_OFFSET;
2493
 
2494
  /* Prepare an ASCII version suitable for writing.  */
2495
  memset (hdr.ar_date, ' ', sizeof (hdr.ar_date));
2496
  _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
2497
                    bfd_ardata (arch)->armap_timestamp);
2498
 
2499
  /* Write it into the file.  */
2500
  bfd_ardata (arch)->armap_datepos = (SARMAG
2501
                                      + offsetof (struct ar_hdr, ar_date[0]));
2502
  if (bfd_seek (arch, bfd_ardata (arch)->armap_datepos, SEEK_SET) != 0
2503
      || (bfd_bwrite (hdr.ar_date, sizeof (hdr.ar_date), arch)
2504
          != sizeof (hdr.ar_date)))
2505
    {
2506
      bfd_perror (_("Writing updated armap timestamp"));
2507
 
2508
      /* Some error while writing.  */
2509
      return TRUE;
2510
    }
2511
 
2512
  /* We updated the timestamp successfully.  */
2513
  return FALSE;
2514
}
2515
 
2516
/* A coff armap looks like :
2517
   lARMAG
2518
   struct ar_hdr with name = '/'
2519
   number of symbols
2520
   offset of file for symbol 0
2521
   offset of file for symbol 1
2522
 
2523
   offset of file for symbol n-1
2524
   symbol name 0
2525
   symbol name 1
2526
 
2527
   symbol name n-1  */
2528
 
2529
bfd_boolean
2530
coff_write_armap (bfd *arch,
2531
                  unsigned int elength,
2532
                  struct orl *map,
2533
                  unsigned int symbol_count,
2534
                  int stridx)
2535
{
2536
  /* The size of the ranlib is the number of exported symbols in the
2537
     archive * the number of bytes in an int, + an int for the count.  */
2538
  unsigned int ranlibsize = (symbol_count * 4) + 4;
2539
  unsigned int stringsize = stridx;
2540
  unsigned int mapsize = stringsize + ranlibsize;
2541
  unsigned int archive_member_file_ptr;
2542
  bfd *current = arch->archive_head;
2543
  unsigned int count;
2544
  struct ar_hdr hdr;
2545
  int padit = mapsize & 1;
2546
 
2547
  if (padit)
2548
    mapsize++;
2549
 
2550
  /* Work out where the first object file will go in the archive.  */
2551
  archive_member_file_ptr = (mapsize
2552
                             + elength
2553
                             + sizeof (struct ar_hdr)
2554
                             + SARMAG);
2555
 
2556
  memset (&hdr, ' ', sizeof (struct ar_hdr));
2557
  hdr.ar_name[0] = '/';
2558
  _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld",
2559
                    mapsize);
2560
  _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
2561
                    ((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0
2562
                     ? time (NULL) : 0));
2563
  /* This, at least, is what Intel coff sets the values to.  */
2564
  _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
2565
  _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0);
2566
  _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0);
2567
  memcpy (hdr.ar_fmag, ARFMAG, 2);
2568
 
2569
  /* Write the ar header for this item and the number of symbols.  */
2570
  if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
2571
      != sizeof (struct ar_hdr))
2572
    return FALSE;
2573
 
2574
  if (!bfd_write_bigendian_4byte_int (arch, symbol_count))
2575
    return FALSE;
2576
 
2577
  /* Two passes, first write the file offsets for each symbol -
2578
     remembering that each offset is on a two byte boundary.  */
2579
 
2580
  /* Write out the file offset for the file associated with each
2581
     symbol, and remember to keep the offsets padded out.  */
2582
 
2583
  current = arch->archive_head;
2584
  count = 0;
2585
  while (current != NULL && count < symbol_count)
2586
    {
2587
      /* For each symbol which is used defined in this object, write
2588
         out the object file's address in the archive.  */
2589
 
2590
      while (count < symbol_count && map[count].u.abfd == current)
2591
        {
2592
          if (!bfd_write_bigendian_4byte_int (arch, archive_member_file_ptr))
2593
            return FALSE;
2594
          count++;
2595
        }
2596
      archive_member_file_ptr += sizeof (struct ar_hdr);
2597
      if (! bfd_is_thin_archive (arch))
2598
        {
2599
          /* Add size of this archive entry.  */
2600
          archive_member_file_ptr += arelt_size (current);
2601
          /* Remember about the even alignment.  */
2602
          archive_member_file_ptr += archive_member_file_ptr % 2;
2603
        }
2604
      current = current->archive_next;
2605
    }
2606
 
2607
  /* Now write the strings themselves.  */
2608
  for (count = 0; count < symbol_count; count++)
2609
    {
2610
      size_t len = strlen (*map[count].name) + 1;
2611
 
2612
      if (bfd_bwrite (*map[count].name, len, arch) != len)
2613
        return FALSE;
2614
    }
2615
 
2616
  /* The spec sez this should be a newline.  But in order to be
2617
     bug-compatible for arc960 we use a null.  */
2618
  if (padit)
2619
    {
2620
      if (bfd_bwrite ("", 1, arch) != 1)
2621
        return FALSE;
2622
    }
2623
 
2624
  return TRUE;
2625
}

powered by: WebSVN 2.1.0

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