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