OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [archive.c] - Blame information for rev 285

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

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

powered by: WebSVN 2.1.0

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