Back to index

cell-binutils  2.17cvs20070401
archive.c
Go to the documentation of this file.
00001 /* BFD back-end for archive files (libraries).
00002    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
00003    2000, 2001, 2002, 2003, 2004, 2005, 2006
00004    Free Software Foundation, Inc.
00005    Written by Cygnus Support.  Mostly Gumby Henkel-Wallace's fault.
00006 
00007    This file is part of BFD, the Binary File Descriptor library.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00022 
00023 /*
00024 @setfilename archive-info
00025 SECTION
00026        Archives
00027 
00028 DESCRIPTION
00029        An archive (or library) is just another BFD.  It has a symbol
00030        table, although there's not much a user program will do with it.
00031 
00032        The big difference between an archive BFD and an ordinary BFD
00033        is that the archive doesn't have sections.  Instead it has a
00034        chain of BFDs that are considered its contents.  These BFDs can
00035        be manipulated like any other.  The BFDs contained in an
00036        archive opened for reading will all be opened for reading.  You
00037        may put either input or output BFDs into an archive opened for
00038        output; they will be handled correctly when the archive is closed.
00039 
00040        Use <<bfd_openr_next_archived_file>> to step through
00041        the contents of an archive opened for input.  You don't
00042        have to read the entire archive if you don't want
00043        to!  Read it until you find what you want.
00044 
00045        Archive contents of output BFDs are chained through the
00046        <<next>> pointer in a BFD.  The first one is findable through
00047        the <<archive_head>> slot of the archive.  Set it with
00048        <<bfd_set_archive_head>> (q.v.).  A given BFD may be in only one
00049        open output archive at a time.
00050 
00051        As expected, the BFD archive code is more general than the
00052        archive code of any given environment.  BFD archives may
00053        contain files of different formats (e.g., a.out and coff) and
00054        even different architectures.  You may even place archives
00055        recursively into archives!
00056 
00057        This can cause unexpected confusion, since some archive
00058        formats are more expressive than others.  For instance, Intel
00059        COFF archives can preserve long filenames; SunOS a.out archives
00060        cannot.  If you move a file from the first to the second
00061        format and back again, the filename may be truncated.
00062        Likewise, different a.out environments have different
00063        conventions as to how they truncate filenames, whether they
00064        preserve directory names in filenames, etc.  When
00065        interoperating with native tools, be sure your files are
00066        homogeneous.
00067 
00068        Beware: most of these formats do not react well to the
00069        presence of spaces in filenames.  We do the best we can, but
00070        can't always handle this case due to restrictions in the format of
00071        archives.  Many Unix utilities are braindead in regards to
00072        spaces and such in filenames anyway, so this shouldn't be much
00073        of a restriction.
00074 
00075        Archives are supported in BFD in <<archive.c>>.
00076 
00077 SUBSECTION
00078        Archive functions
00079 */
00080 
00081 /* Assumes:
00082    o - all archive elements start on an even boundary, newline padded;
00083    o - all arch headers are char *;
00084    o - all arch headers are the same size (across architectures).
00085 */
00086 
00087 /* Some formats provide a way to cram a long filename into the short
00088    (16 chars) space provided by a BSD archive.  The trick is: make a
00089    special "file" in the front of the archive, sort of like the SYMDEF
00090    entry.  If the filename is too long to fit, put it in the extended
00091    name table, and use its index as the filename.  To prevent
00092    confusion prepend the index with a space.  This means you can't
00093    have filenames that start with a space, but then again, many Unix
00094    utilities can't handle that anyway.
00095 
00096    This scheme unfortunately requires that you stand on your head in
00097    order to write an archive since you need to put a magic file at the
00098    front, and need to touch every entry to do so.  C'est la vie.
00099 
00100    We support two variants of this idea:
00101    The SVR4 format (extended name table is named "//"),
00102    and an extended pseudo-BSD variant (extended name table is named
00103    "ARFILENAMES/").  The origin of the latter format is uncertain.
00104 
00105    BSD 4.4 uses a third scheme:  It writes a long filename
00106    directly after the header.  This allows 'ar q' to work.
00107    We currently can read BSD 4.4 archives, but not write them.
00108 */
00109 
00110 /* Summary of archive member names:
00111 
00112  Symbol table (must be first):
00113  "__.SYMDEF       " - Symbol table, Berkeley style, produced by ranlib.
00114  "/               " - Symbol table, system 5 style.
00115 
00116  Long name table (must be before regular file members):
00117  "//              " - Long name table, System 5 R4 style.
00118  "ARFILENAMES/    " - Long name table, non-standard extended BSD (not BSD 4.4).
00119 
00120  Regular file members with short names:
00121  "filename.o/     " - Regular file, System 5 style (embedded spaces ok).
00122  "filename.o      " - Regular file, Berkeley style (no embedded spaces).
00123 
00124  Regular files with long names (or embedded spaces, for BSD variants):
00125  "/18             " - SVR4 style, name at offset 18 in name table.
00126  "#1/23           " - Long name (or embedded spaces) 23 characters long,
00127                     BSD 4.4 style, full name follows header.
00128                     Implemented for reading, not writing.
00129  " 18             " - Long name 18 characters long, extended pseudo-BSD.
00130  */
00131 
00132 #include "bfd.h"
00133 #include "sysdep.h"
00134 #include "libiberty.h"
00135 #include "libbfd.h"
00136 #include "aout/ar.h"
00137 #include "aout/ranlib.h"
00138 #include "safe-ctype.h"
00139 #include "hashtab.h"
00140 
00141 #ifndef errno
00142 extern int errno;
00143 #endif
00144 
00145 /* We keep a cache of archive filepointers to archive elements to
00146    speed up searching the archive by filepos.  We only add an entry to
00147    the cache when we actually read one.  We also don't sort the cache;
00148    it's generally short enough to search linearly.
00149    Note that the pointers here point to the front of the ar_hdr, not
00150    to the front of the contents!  */
00151 struct ar_cache {
00152   file_ptr ptr;
00153   bfd *arbfd;
00154 };
00155 
00156 #define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
00157 #define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
00158 
00159 #define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data))
00160 #define arch_hdr(bfd) ((struct ar_hdr *) arch_eltdata(bfd)->arch_header)
00161 
00162 void
00163 _bfd_ar_spacepad (char *p, size_t n, const char *fmt, long val)
00164 {
00165   static char buf[20];
00166   size_t len;
00167   snprintf (buf, sizeof (buf), fmt, val);
00168   len = strlen (buf);
00169   if (len < n)
00170     {
00171       memcpy (p, buf, len);
00172       memset (p + len, ' ', n - len);
00173     }
00174   else
00175     memcpy (p, buf, n);
00176 }
00177 
00178 bfd_boolean
00179 _bfd_generic_mkarchive (bfd *abfd)
00180 {
00181   bfd_size_type amt = sizeof (struct artdata);
00182 
00183   abfd->tdata.aout_ar_data = bfd_zalloc (abfd, amt);
00184   if (bfd_ardata (abfd) == NULL)
00185     return FALSE;
00186 
00187   /* Already cleared by bfd_zalloc above.
00188      bfd_ardata (abfd)->cache = NULL;
00189      bfd_ardata (abfd)->archive_head = NULL;
00190      bfd_ardata (abfd)->symdefs = NULL;
00191      bfd_ardata (abfd)->extended_names = NULL;
00192      bfd_ardata (abfd)->extended_names_size = 0;
00193      bfd_ardata (abfd)->tdata = NULL;  */
00194 
00195   return TRUE;
00196 }
00197 
00198 /*
00199 FUNCTION
00200        bfd_get_next_mapent
00201 
00202 SYNOPSIS
00203        symindex bfd_get_next_mapent
00204          (bfd *abfd, symindex previous, carsym **sym);
00205 
00206 DESCRIPTION
00207        Step through archive @var{abfd}'s symbol table (if it
00208        has one).  Successively update @var{sym} with the next symbol's
00209        information, returning that symbol's (internal) index into the
00210        symbol table.
00211 
00212        Supply <<BFD_NO_MORE_SYMBOLS>> as the @var{previous} entry to get
00213        the first one; returns <<BFD_NO_MORE_SYMBOLS>> when you've already
00214        got the last one.
00215 
00216        A <<carsym>> is a canonical archive symbol.  The only
00217        user-visible element is its name, a null-terminated string.
00218 */
00219 
00220 symindex
00221 bfd_get_next_mapent (bfd *abfd, symindex prev, carsym **entry)
00222 {
00223   if (!bfd_has_map (abfd))
00224     {
00225       bfd_set_error (bfd_error_invalid_operation);
00226       return BFD_NO_MORE_SYMBOLS;
00227     }
00228 
00229   if (prev == BFD_NO_MORE_SYMBOLS)
00230     prev = 0;
00231   else
00232     ++prev;
00233   if (prev >= bfd_ardata (abfd)->symdef_count)
00234     return BFD_NO_MORE_SYMBOLS;
00235 
00236   *entry = (bfd_ardata (abfd)->symdefs + prev);
00237   return prev;
00238 }
00239 
00240 /* To be called by backends only.  */
00241 
00242 bfd *
00243 _bfd_create_empty_archive_element_shell (bfd *obfd)
00244 {
00245   return _bfd_new_bfd_contained_in (obfd);
00246 }
00247 
00248 /*
00249 FUNCTION
00250        bfd_set_archive_head
00251 
00252 SYNOPSIS
00253        bfd_boolean bfd_set_archive_head (bfd *output, bfd *new_head);
00254 
00255 DESCRIPTION
00256        Set the head of the chain of
00257        BFDs contained in the archive @var{output} to @var{new_head}.
00258 */
00259 
00260 bfd_boolean
00261 bfd_set_archive_head (bfd *output_archive, bfd *new_head)
00262 {
00263   output_archive->archive_head = new_head;
00264   return TRUE;
00265 }
00266 
00267 bfd *
00268 _bfd_look_for_bfd_in_cache (bfd *arch_bfd, file_ptr filepos)
00269 {
00270   htab_t hash_table = bfd_ardata (arch_bfd)->cache;
00271   struct ar_cache m;
00272   m.ptr = filepos;
00273 
00274   if (hash_table)
00275     {
00276       struct ar_cache *entry = (struct ar_cache *) htab_find (hash_table, &m);
00277       if (!entry)
00278        return NULL;
00279       else
00280        return entry->arbfd;
00281     }
00282   else
00283     return NULL;
00284 }
00285 
00286 static hashval_t
00287 hash_file_ptr (const PTR p)
00288 {
00289   return (hashval_t) (((struct ar_cache *) p)->ptr);
00290 }
00291 
00292 /* Returns non-zero if P1 and P2 are equal.  */
00293 
00294 static int
00295 eq_file_ptr (const PTR p1, const PTR p2)
00296 {
00297   struct ar_cache *arc1 = (struct ar_cache *) p1;
00298   struct ar_cache *arc2 = (struct ar_cache *) p2;
00299   return arc1->ptr == arc2->ptr;
00300 }
00301 
00302 /* Kind of stupid to call cons for each one, but we don't do too many.  */
00303 
00304 bfd_boolean
00305 _bfd_add_bfd_to_archive_cache (bfd *arch_bfd, file_ptr filepos, bfd *new_elt)
00306 {
00307   struct ar_cache *cache;
00308   htab_t hash_table = bfd_ardata (arch_bfd)->cache;
00309 
00310   /* If the hash table hasn't been created, create it.  */
00311   if (hash_table == NULL)
00312     {
00313       hash_table = htab_create_alloc (16, hash_file_ptr, eq_file_ptr,
00314                                   NULL, calloc, free);
00315       if (hash_table == NULL)
00316        return FALSE;
00317       bfd_ardata (arch_bfd)->cache = hash_table;
00318     }
00319 
00320   /* Insert new_elt into the hash table by filepos.  */
00321   cache = bfd_zalloc (arch_bfd, sizeof (struct ar_cache));
00322   cache->ptr = filepos;
00323   cache->arbfd = new_elt;
00324   *htab_find_slot (hash_table, (const void *) cache, INSERT) = cache;
00325 
00326   return TRUE;
00327 }
00328 
00329 /* The name begins with space.  Hence the rest of the name is an index into
00330    the string table.  */
00331 
00332 static char *
00333 get_extended_arelt_filename (bfd *arch, const char *name)
00334 {
00335   unsigned long index = 0;
00336 
00337   /* Should extract string so that I can guarantee not to overflow into
00338      the next region, but I'm too lazy.  */
00339   errno = 0;
00340   /* Skip first char, which is '/' in SVR4 or ' ' in some other variants.  */
00341   index = strtol (name + 1, NULL, 10);
00342   if (errno != 0 || index >= bfd_ardata (arch)->extended_names_size)
00343     {
00344       bfd_set_error (bfd_error_malformed_archive);
00345       return NULL;
00346     }
00347 
00348   return bfd_ardata (arch)->extended_names + index;
00349 }
00350 
00351 /* This functions reads an arch header and returns an areltdata pointer, or
00352    NULL on error.
00353 
00354    Presumes the file pointer is already in the right place (ie pointing
00355    to the ar_hdr in the file).   Moves the file pointer; on success it
00356    should be pointing to the front of the file contents; on failure it
00357    could have been moved arbitrarily.  */
00358 
00359 void *
00360 _bfd_generic_read_ar_hdr (bfd *abfd)
00361 {
00362   return _bfd_generic_read_ar_hdr_mag (abfd, NULL);
00363 }
00364 
00365 /* Alpha ECOFF uses an optional different ARFMAG value, so we have a
00366    variant of _bfd_generic_read_ar_hdr which accepts a magic string.  */
00367 
00368 void *
00369 _bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag)
00370 {
00371   struct ar_hdr hdr;
00372   char *hdrp = (char *) &hdr;
00373   size_t parsed_size;
00374   struct areltdata *ared;
00375   char *filename = NULL;
00376   bfd_size_type namelen = 0;
00377   bfd_size_type allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
00378   char *allocptr = 0;
00379 
00380   if (bfd_bread (hdrp, sizeof (struct ar_hdr), abfd) != sizeof (struct ar_hdr))
00381     {
00382       if (bfd_get_error () != bfd_error_system_call)
00383        bfd_set_error (bfd_error_no_more_archived_files);
00384       return NULL;
00385     }
00386   if (strncmp (hdr.ar_fmag, ARFMAG, 2) != 0
00387       && (mag == NULL
00388          || strncmp (hdr.ar_fmag, mag, 2) != 0))
00389     {
00390       bfd_set_error (bfd_error_malformed_archive);
00391       return NULL;
00392     }
00393 
00394   errno = 0;
00395   parsed_size = strtol (hdr.ar_size, NULL, 10);
00396   if (errno != 0)
00397     {
00398       bfd_set_error (bfd_error_malformed_archive);
00399       return NULL;
00400     }
00401 
00402   /* Extract the filename from the archive - there are two ways to
00403      specify an extended name table, either the first char of the
00404      name is a space, or it's a slash.  */
00405   if ((hdr.ar_name[0] == '/'
00406        || (hdr.ar_name[0] == ' '
00407           && memchr (hdr.ar_name, '/', ar_maxnamelen (abfd)) == NULL))
00408       && bfd_ardata (abfd)->extended_names != NULL)
00409     {
00410       filename = get_extended_arelt_filename (abfd, hdr.ar_name);
00411       if (filename == NULL)
00412        return NULL;
00413     }
00414   /* BSD4.4-style long filename.
00415      Only implemented for reading, so far!  */
00416   else if (hdr.ar_name[0] == '#'
00417           && hdr.ar_name[1] == '1'
00418           && hdr.ar_name[2] == '/'
00419           && ISDIGIT (hdr.ar_name[3]))
00420     {
00421       /* BSD-4.4 extended name */
00422       namelen = atoi (&hdr.ar_name[3]);
00423       allocsize += namelen + 1;
00424       parsed_size -= namelen;
00425 
00426       allocptr = bfd_zalloc (abfd, allocsize);
00427       if (allocptr == NULL)
00428        return NULL;
00429       filename = (allocptr
00430                 + sizeof (struct areltdata)
00431                 + sizeof (struct ar_hdr));
00432       if (bfd_bread (filename, namelen, abfd) != namelen)
00433        {
00434          if (bfd_get_error () != bfd_error_system_call)
00435            bfd_set_error (bfd_error_no_more_archived_files);
00436          return NULL;
00437        }
00438       filename[namelen] = '\0';
00439     }
00440   else
00441     {
00442       /* We judge the end of the name by looking for '/' or ' '.
00443         Note:  The SYSV format (terminated by '/') allows embedded
00444         spaces, so only look for ' ' if we don't find '/'.  */
00445 
00446       char *e;
00447       e = memchr (hdr.ar_name, '\0', ar_maxnamelen (abfd));
00448       if (e == NULL)
00449        {
00450          e = memchr (hdr.ar_name, '/', ar_maxnamelen (abfd));
00451          if (e == NULL)
00452            e = memchr (hdr.ar_name, ' ', ar_maxnamelen (abfd));
00453        }
00454 
00455       if (e != NULL)
00456        namelen = e - hdr.ar_name;
00457       else
00458        {
00459          /* If we didn't find a termination character, then the name
00460             must be the entire field.  */
00461          namelen = ar_maxnamelen (abfd);
00462        }
00463 
00464       allocsize += namelen + 1;
00465     }
00466 
00467   if (!allocptr)
00468     {
00469       allocptr = bfd_zalloc (abfd, allocsize);
00470       if (allocptr == NULL)
00471        return NULL;
00472     }
00473 
00474   ared = (struct areltdata *) allocptr;
00475 
00476   ared->arch_header = allocptr + sizeof (struct areltdata);
00477   memcpy (ared->arch_header, &hdr, sizeof (struct ar_hdr));
00478   ared->parsed_size = parsed_size;
00479 
00480   if (filename != NULL)
00481     ared->filename = filename;
00482   else
00483     {
00484       ared->filename = allocptr + (sizeof (struct areltdata) +
00485                                sizeof (struct ar_hdr));
00486       if (namelen)
00487        memcpy (ared->filename, hdr.ar_name, namelen);
00488       ared->filename[namelen] = '\0';
00489     }
00490 
00491   return ared;
00492 }
00493 
00494 /* This is an internal function; it's mainly used when indexing
00495    through the archive symbol table, but also used to get the next
00496    element, since it handles the bookkeeping so nicely for us.  */
00497 
00498 bfd *
00499 _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos)
00500 {
00501   struct areltdata *new_areldata;
00502   bfd *n_nfd;
00503 
00504   if (archive->my_archive)
00505     {
00506       filepos += archive->origin;
00507       archive = archive->my_archive;
00508     }
00509 
00510   n_nfd = _bfd_look_for_bfd_in_cache (archive, filepos);
00511   if (n_nfd)
00512     return n_nfd;
00513 
00514   if (0 > bfd_seek (archive, filepos, SEEK_SET))
00515     return NULL;
00516 
00517   if ((new_areldata = _bfd_read_ar_hdr (archive)) == NULL)
00518     return NULL;
00519 
00520   n_nfd = _bfd_create_empty_archive_element_shell (archive);
00521   if (n_nfd == NULL)
00522     {
00523       bfd_release (archive, new_areldata);
00524       return NULL;
00525     }
00526 
00527   n_nfd->origin = bfd_tell (archive);
00528   n_nfd->arelt_data = new_areldata;
00529   n_nfd->filename = new_areldata->filename;
00530 
00531   if (_bfd_add_bfd_to_archive_cache (archive, filepos, n_nfd))
00532     return n_nfd;
00533 
00534   /* Huh?  */
00535   bfd_release (archive, n_nfd);
00536   bfd_release (archive, new_areldata);
00537   return NULL;
00538 }
00539 
00540 /* Return the BFD which is referenced by the symbol in ABFD indexed by
00541    INDEX.  INDEX should have been returned by bfd_get_next_mapent.  */
00542 
00543 bfd *
00544 _bfd_generic_get_elt_at_index (bfd *abfd, symindex index)
00545 {
00546   carsym *entry;
00547 
00548   entry = bfd_ardata (abfd)->symdefs + index;
00549   return _bfd_get_elt_at_filepos (abfd, entry->file_offset);
00550 }
00551 
00552 /*
00553 FUNCTION
00554        bfd_openr_next_archived_file
00555 
00556 SYNOPSIS
00557        bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous);
00558 
00559 DESCRIPTION
00560        Provided a BFD, @var{archive}, containing an archive and NULL, open
00561        an input BFD on the first contained element and returns that.
00562        Subsequent calls should pass
00563        the archive and the previous return value to return a created
00564        BFD to the next contained element. NULL is returned when there
00565        are no more.
00566 */
00567 
00568 bfd *
00569 bfd_openr_next_archived_file (bfd *archive, bfd *last_file)
00570 {
00571   if ((bfd_get_format (archive) != bfd_archive) ||
00572       (archive->direction == write_direction))
00573     {
00574       bfd_set_error (bfd_error_invalid_operation);
00575       return NULL;
00576     }
00577 
00578   return BFD_SEND (archive,
00579                  openr_next_archived_file, (archive, last_file));
00580 }
00581 
00582 bfd *
00583 bfd_generic_openr_next_archived_file (bfd *archive, bfd *last_file)
00584 {
00585   file_ptr filestart;
00586 
00587   if (!last_file)
00588     filestart = bfd_ardata (archive)->first_file_filepos;
00589   else
00590     {
00591       unsigned int size = arelt_size (last_file);
00592       filestart = last_file->origin + size;
00593       if (archive->my_archive)
00594        filestart -= archive->origin;
00595       /* Pad to an even boundary...
00596         Note that last_file->origin can be odd in the case of
00597         BSD-4.4-style element with a long odd size.  */
00598       filestart += filestart % 2;
00599     }
00600 
00601   return _bfd_get_elt_at_filepos (archive, filestart);
00602 }
00603 
00604 const bfd_target *
00605 bfd_generic_archive_p (bfd *abfd)
00606 {
00607   struct artdata *tdata_hold;
00608   char armag[SARMAG + 1];
00609   bfd_size_type amt;
00610 
00611   if (bfd_bread (armag, SARMAG, abfd) != SARMAG)
00612     {
00613       if (bfd_get_error () != bfd_error_system_call)
00614        bfd_set_error (bfd_error_wrong_format);
00615       return NULL;
00616     }
00617 
00618   if (strncmp (armag, ARMAG, SARMAG) != 0 &&
00619       strncmp (armag, ARMAGB, SARMAG) != 0)
00620     return 0;
00621 
00622   tdata_hold = bfd_ardata (abfd);
00623 
00624   amt = sizeof (struct artdata);
00625   bfd_ardata (abfd) = bfd_zalloc (abfd, amt);
00626   if (bfd_ardata (abfd) == NULL)
00627     {
00628       bfd_ardata (abfd) = tdata_hold;
00629       return NULL;
00630     }
00631 
00632   bfd_ardata (abfd)->first_file_filepos = SARMAG;
00633   /* Cleared by bfd_zalloc above.
00634      bfd_ardata (abfd)->cache = NULL;
00635      bfd_ardata (abfd)->archive_head = NULL;
00636      bfd_ardata (abfd)->symdefs = NULL;
00637      bfd_ardata (abfd)->extended_names = NULL;
00638      bfd_ardata (abfd)->extended_names_size = 0;
00639      bfd_ardata (abfd)->tdata = NULL;  */
00640 
00641   if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))
00642       || !BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd)))
00643     {
00644       if (bfd_get_error () != bfd_error_system_call)
00645        bfd_set_error (bfd_error_wrong_format);
00646       bfd_release (abfd, bfd_ardata (abfd));
00647       bfd_ardata (abfd) = tdata_hold;
00648       return NULL;
00649     }
00650 
00651   if (bfd_has_map (abfd))
00652     {
00653       bfd *first;
00654 
00655       /* This archive has a map, so we may presume that the contents
00656         are object files.  Make sure that if the first file in the
00657         archive can be recognized as an object file, it is for this
00658         target.  If not, assume that this is the wrong format.  If
00659         the first file is not an object file, somebody is doing
00660         something weird, and we permit it so that ar -t will work.
00661 
00662         This is done because any normal format will recognize any
00663         normal archive, regardless of the format of the object files.
00664         We do accept an empty archive.  */
00665 
00666       first = bfd_openr_next_archived_file (abfd, NULL);
00667       if (first != NULL)
00668        {
00669          first->target_defaulted = FALSE;
00670          if (bfd_check_format (first, bfd_object)
00671              && first->xvec != abfd->xvec)
00672            {
00673              bfd_set_error (bfd_error_wrong_object_format);
00674              bfd_ardata (abfd) = tdata_hold;
00675              return NULL;
00676            }
00677          /* And we ought to close `first' here too.  */
00678        }
00679     }
00680 
00681   return abfd->xvec;
00682 }
00683 
00684 /* Some constants for a 32 bit BSD archive structure.  We do not
00685    support 64 bit archives presently; so far as I know, none actually
00686    exist.  Supporting them would require changing these constants, and
00687    changing some H_GET_32 to H_GET_64.  */
00688 
00689 /* The size of an external symdef structure.  */
00690 #define BSD_SYMDEF_SIZE 8
00691 
00692 /* The offset from the start of a symdef structure to the file offset.  */
00693 #define BSD_SYMDEF_OFFSET_SIZE 4
00694 
00695 /* The size of the symdef count.  */
00696 #define BSD_SYMDEF_COUNT_SIZE 4
00697 
00698 /* The size of the string count.  */
00699 #define BSD_STRING_COUNT_SIZE 4
00700 
00701 /* Returns FALSE on error, TRUE otherwise.  */
00702 
00703 static bfd_boolean
00704 do_slurp_bsd_armap (bfd *abfd)
00705 {
00706   struct areltdata *mapdata;
00707   unsigned int counter;
00708   bfd_byte *raw_armap, *rbase;
00709   struct artdata *ardata = bfd_ardata (abfd);
00710   char *stringbase;
00711   bfd_size_type parsed_size, amt;
00712   carsym *set;
00713 
00714   mapdata = _bfd_read_ar_hdr (abfd);
00715   if (mapdata == NULL)
00716     return FALSE;
00717   parsed_size = mapdata->parsed_size;
00718   bfd_release (abfd, mapdata);     /* Don't need it any more.  */
00719 
00720   raw_armap = bfd_zalloc (abfd, parsed_size);
00721   if (raw_armap == NULL)
00722     return FALSE;
00723 
00724   if (bfd_bread (raw_armap, parsed_size, abfd) != parsed_size)
00725     {
00726       if (bfd_get_error () != bfd_error_system_call)
00727        bfd_set_error (bfd_error_malformed_archive);
00728     byebye:
00729       bfd_release (abfd, raw_armap);
00730       return FALSE;
00731     }
00732 
00733   ardata->symdef_count = H_GET_32 (abfd, raw_armap) / BSD_SYMDEF_SIZE;
00734 
00735   if (ardata->symdef_count * BSD_SYMDEF_SIZE >
00736       parsed_size - BSD_SYMDEF_COUNT_SIZE)
00737     {
00738       /* Probably we're using the wrong byte ordering.  */
00739       bfd_set_error (bfd_error_wrong_format);
00740       goto byebye;
00741     }
00742 
00743   ardata->cache = 0;
00744   rbase = raw_armap + BSD_SYMDEF_COUNT_SIZE;
00745   stringbase = ((char *) rbase
00746               + ardata->symdef_count * BSD_SYMDEF_SIZE
00747               + BSD_STRING_COUNT_SIZE);
00748   amt = ardata->symdef_count * sizeof (carsym);
00749   ardata->symdefs = bfd_alloc (abfd, amt);
00750   if (!ardata->symdefs)
00751     return FALSE;
00752 
00753   for (counter = 0, set = ardata->symdefs;
00754        counter < ardata->symdef_count;
00755        counter++, set++, rbase += BSD_SYMDEF_SIZE)
00756     {
00757       set->name = H_GET_32 (abfd, rbase) + stringbase;
00758       set->file_offset = H_GET_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE);
00759     }
00760 
00761   ardata->first_file_filepos = bfd_tell (abfd);
00762   /* Pad to an even boundary if you have to.  */
00763   ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
00764   /* FIXME, we should provide some way to free raw_ardata when
00765      we are done using the strings from it.  For now, it seems
00766      to be allocated on an objalloc anyway...  */
00767   bfd_has_map (abfd) = TRUE;
00768   return TRUE;
00769 }
00770 
00771 /* Returns FALSE on error, TRUE otherwise.  */
00772 
00773 static bfd_boolean
00774 do_slurp_coff_armap (bfd *abfd)
00775 {
00776   struct areltdata *mapdata;
00777   int *raw_armap, *rawptr;
00778   struct artdata *ardata = bfd_ardata (abfd);
00779   char *stringbase;
00780   bfd_size_type stringsize;
00781   unsigned int parsed_size;
00782   carsym *carsyms;
00783   bfd_size_type nsymz;             /* Number of symbols in armap.  */
00784   bfd_vma (*swap) (const void *);
00785   char int_buf[sizeof (long)];
00786   bfd_size_type carsym_size, ptrsize;
00787   unsigned int i;
00788 
00789   mapdata = _bfd_read_ar_hdr (abfd);
00790   if (mapdata == NULL)
00791     return FALSE;
00792   parsed_size = mapdata->parsed_size;
00793   bfd_release (abfd, mapdata);     /* Don't need it any more.  */
00794 
00795   if (bfd_bread (int_buf, 4, abfd) != 4)
00796     {
00797       if (bfd_get_error () != bfd_error_system_call)
00798        bfd_set_error (bfd_error_malformed_archive);
00799       return FALSE;
00800     }
00801   /* It seems that all numeric information in a coff archive is always
00802      in big endian format, nomatter the host or target.  */
00803   swap = bfd_getb32;
00804   nsymz = bfd_getb32 (int_buf);
00805   stringsize = parsed_size - (4 * nsymz) - 4;
00806 
00807   /* ... except that some archive formats are broken, and it may be our
00808      fault - the i960 little endian coff sometimes has big and sometimes
00809      little, because our tools changed.  Here's a horrible hack to clean
00810      up the crap.  */
00811 
00812   if (stringsize > 0xfffff
00813       && bfd_get_arch (abfd) == bfd_arch_i960
00814       && bfd_get_flavour (abfd) == bfd_target_coff_flavour)
00815     {
00816       /* This looks dangerous, let's do it the other way around.  */
00817       nsymz = bfd_getl32 (int_buf);
00818       stringsize = parsed_size - (4 * nsymz) - 4;
00819       swap = bfd_getl32;
00820     }
00821 
00822   /* The coff armap must be read sequentially.  So we construct a
00823      bsd-style one in core all at once, for simplicity.  */
00824 
00825   if (nsymz > ~ (bfd_size_type) 0 / sizeof (carsym))
00826     return FALSE;
00827 
00828   carsym_size = (nsymz * sizeof (carsym));
00829   ptrsize = (4 * nsymz);
00830 
00831   if (carsym_size + stringsize + 1 <= carsym_size)
00832     return FALSE;
00833 
00834   ardata->symdefs = bfd_zalloc (abfd, carsym_size + stringsize + 1);
00835   if (ardata->symdefs == NULL)
00836     return FALSE;
00837   carsyms = ardata->symdefs;
00838   stringbase = ((char *) ardata->symdefs) + carsym_size;
00839 
00840   /* Allocate and read in the raw offsets.  */
00841   raw_armap = bfd_alloc (abfd, ptrsize);
00842   if (raw_armap == NULL)
00843     goto release_symdefs;
00844   if (bfd_bread (raw_armap, ptrsize, abfd) != ptrsize
00845       || (bfd_bread (stringbase, stringsize, abfd) != stringsize))
00846     {
00847       if (bfd_get_error () != bfd_error_system_call)
00848        bfd_set_error (bfd_error_malformed_archive);
00849       goto release_raw_armap;
00850     }
00851 
00852   /* OK, build the carsyms.  */
00853   for (i = 0; i < nsymz; i++)
00854     {
00855       rawptr = raw_armap + i;
00856       carsyms->file_offset = swap ((bfd_byte *) rawptr);
00857       carsyms->name = stringbase;
00858       stringbase += strlen (stringbase) + 1;
00859       carsyms++;
00860     }
00861   *stringbase = 0;
00862 
00863   ardata->symdef_count = nsymz;
00864   ardata->first_file_filepos = bfd_tell (abfd);
00865   /* Pad to an even boundary if you have to.  */
00866   ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
00867 
00868   bfd_has_map (abfd) = TRUE;
00869   bfd_release (abfd, raw_armap);
00870 
00871   /* Check for a second archive header (as used by PE).  */
00872   {
00873     struct areltdata *tmp;
00874 
00875     bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET);
00876     tmp = _bfd_read_ar_hdr (abfd);
00877     if (tmp != NULL)
00878       {
00879        if (tmp->arch_header[0] == '/'
00880            && tmp->arch_header[1] == ' ')
00881          {
00882            ardata->first_file_filepos +=
00883              (tmp->parsed_size + sizeof (struct ar_hdr) + 1) & ~(unsigned) 1;
00884          }
00885        bfd_release (abfd, tmp);
00886       }
00887   }
00888 
00889   return TRUE;
00890 
00891 release_raw_armap:
00892   bfd_release (abfd, raw_armap);
00893 release_symdefs:
00894   bfd_release (abfd, (ardata)->symdefs);
00895   return FALSE;
00896 }
00897 
00898 /* This routine can handle either coff-style or bsd-style armaps.
00899    Returns FALSE on error, TRUE otherwise */
00900 
00901 bfd_boolean
00902 bfd_slurp_armap (bfd *abfd)
00903 {
00904   char nextname[17];
00905   int i = bfd_bread (nextname, 16, abfd);
00906 
00907   if (i == 0)
00908     return TRUE;
00909   if (i != 16)
00910     return FALSE;
00911 
00912   if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
00913     return FALSE;
00914 
00915   if (CONST_STRNEQ (nextname, "__.SYMDEF       ")
00916       || CONST_STRNEQ (nextname, "__.SYMDEF/      ")) /* Old Linux archives.  */
00917     return do_slurp_bsd_armap (abfd);
00918   else if (CONST_STRNEQ (nextname, "/               "))
00919     return do_slurp_coff_armap (abfd);
00920   else if (CONST_STRNEQ (nextname, "/SYM64/         "))
00921     {
00922       /* 64bit ELF (Irix 6) archive.  */
00923 #ifdef BFD64
00924       extern bfd_boolean bfd_elf64_archive_slurp_armap (bfd *);
00925       return bfd_elf64_archive_slurp_armap (abfd);
00926 #else
00927       bfd_set_error (bfd_error_wrong_format);
00928       return FALSE;
00929 #endif
00930     }
00931 
00932   bfd_has_map (abfd) = FALSE;
00933   return TRUE;
00934 }
00935 
00936 /* Returns FALSE on error, TRUE otherwise.  */
00937 /* Flavor 2 of a bsd armap, similar to bfd_slurp_bsd_armap except the
00938    header is in a slightly different order and the map name is '/'.
00939    This flavour is used by hp300hpux.  */
00940 
00941 #define HPUX_SYMDEF_COUNT_SIZE 2
00942 
00943 bfd_boolean
00944 bfd_slurp_bsd_armap_f2 (bfd *abfd)
00945 {
00946   struct areltdata *mapdata;
00947   char nextname[17];
00948   unsigned int counter;
00949   bfd_byte *raw_armap, *rbase;
00950   struct artdata *ardata = bfd_ardata (abfd);
00951   char *stringbase;
00952   unsigned int stringsize;
00953   bfd_size_type amt;
00954   carsym *set;
00955   int i = bfd_bread (nextname, 16, abfd);
00956 
00957   if (i == 0)
00958     return TRUE;
00959   if (i != 16)
00960     return FALSE;
00961 
00962   /* The archive has at least 16 bytes in it.  */
00963   if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
00964     return FALSE;
00965 
00966   if (CONST_STRNEQ (nextname, "__.SYMDEF       ")
00967       || CONST_STRNEQ (nextname, "__.SYMDEF/      ")) /* Old Linux archives.  */
00968     return do_slurp_bsd_armap (abfd);
00969 
00970   if (! CONST_STRNEQ (nextname, "/               "))
00971     {
00972       bfd_has_map (abfd) = FALSE;
00973       return TRUE;
00974     }
00975 
00976   mapdata = _bfd_read_ar_hdr (abfd);
00977   if (mapdata == NULL)
00978     return FALSE;
00979 
00980   amt = mapdata->parsed_size;
00981   raw_armap = bfd_zalloc (abfd, amt);
00982   if (raw_armap == NULL)
00983     {
00984     byebye:
00985       bfd_release (abfd, mapdata);
00986       return FALSE;
00987     }
00988 
00989   if (bfd_bread (raw_armap, amt, abfd) != amt)
00990     {
00991       if (bfd_get_error () != bfd_error_system_call)
00992        bfd_set_error (bfd_error_malformed_archive);
00993     byebyebye:
00994       bfd_release (abfd, raw_armap);
00995       goto byebye;
00996     }
00997 
00998   ardata->symdef_count = H_GET_16 (abfd, raw_armap);
00999 
01000   if (ardata->symdef_count * BSD_SYMDEF_SIZE
01001       > mapdata->parsed_size - HPUX_SYMDEF_COUNT_SIZE)
01002     {
01003       /* Probably we're using the wrong byte ordering.  */
01004       bfd_set_error (bfd_error_wrong_format);
01005       goto byebyebye;
01006     }
01007 
01008   ardata->cache = 0;
01009 
01010   stringsize = H_GET_32 (abfd, raw_armap + HPUX_SYMDEF_COUNT_SIZE);
01011   /* Skip sym count and string sz.  */
01012   stringbase = ((char *) raw_armap
01013               + HPUX_SYMDEF_COUNT_SIZE
01014               + BSD_STRING_COUNT_SIZE);
01015   rbase = (bfd_byte *) stringbase + stringsize;
01016   amt = ardata->symdef_count * BSD_SYMDEF_SIZE;
01017   ardata->symdefs = bfd_alloc (abfd, amt);
01018   if (!ardata->symdefs)
01019     return FALSE;
01020 
01021   for (counter = 0, set = ardata->symdefs;
01022        counter < ardata->symdef_count;
01023        counter++, set++, rbase += BSD_SYMDEF_SIZE)
01024     {
01025       set->name = H_GET_32 (abfd, rbase) + stringbase;
01026       set->file_offset = H_GET_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE);
01027     }
01028 
01029   ardata->first_file_filepos = bfd_tell (abfd);
01030   /* Pad to an even boundary if you have to.  */
01031   ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
01032   /* FIXME, we should provide some way to free raw_ardata when
01033      we are done using the strings from it.  For now, it seems
01034      to be allocated on an objalloc anyway...  */
01035   bfd_has_map (abfd) = TRUE;
01036   return TRUE;
01037 }
01038 
01049 /* Returns FALSE on error, TRUE otherwise.  */
01050 
01051 bfd_boolean
01052 _bfd_slurp_extended_name_table (bfd *abfd)
01053 {
01054   char nextname[17];
01055   struct areltdata *namedata;
01056   bfd_size_type amt;
01057 
01058   /* FIXME:  Formatting sucks here, and in case of failure of BFD_READ,
01059      we probably don't want to return TRUE.  */
01060   bfd_seek (abfd, bfd_ardata (abfd)->first_file_filepos, SEEK_SET);
01061   if (bfd_bread (nextname, 16, abfd) == 16)
01062     {
01063       if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
01064        return FALSE;
01065 
01066       if (! CONST_STRNEQ (nextname, "ARFILENAMES/    ")
01067          && ! CONST_STRNEQ (nextname, "//              "))
01068        {
01069          bfd_ardata (abfd)->extended_names = NULL;
01070          bfd_ardata (abfd)->extended_names_size = 0;
01071          return TRUE;
01072        }
01073 
01074       namedata = _bfd_read_ar_hdr (abfd);
01075       if (namedata == NULL)
01076        return FALSE;
01077 
01078       amt = namedata->parsed_size;
01079       if (amt + 1 == 0)
01080         goto byebye;
01081 
01082       bfd_ardata (abfd)->extended_names_size = amt;
01083       bfd_ardata (abfd)->extended_names = bfd_zalloc (abfd, amt + 1);
01084       if (bfd_ardata (abfd)->extended_names == NULL)
01085        {
01086        byebye:
01087          bfd_release (abfd, namedata);
01088          return FALSE;
01089        }
01090 
01091       if (bfd_bread (bfd_ardata (abfd)->extended_names, amt, abfd) != amt)
01092        {
01093          if (bfd_get_error () != bfd_error_system_call)
01094            bfd_set_error (bfd_error_malformed_archive);
01095          bfd_release (abfd, (bfd_ardata (abfd)->extended_names));
01096          bfd_ardata (abfd)->extended_names = NULL;
01097          goto byebye;
01098        }
01099 
01100       /* Since the archive is supposed to be printable if it contains
01101         text, the entries in the list are newline-padded, not null
01102         padded. In SVR4-style archives, the names also have a
01103         trailing '/'.  DOS/NT created archive often have \ in them
01104         We'll fix all problems here..  */
01105       {
01106         char *ext_names = bfd_ardata (abfd)->extended_names;
01107        char *temp = ext_names;
01108        char *limit = temp + namedata->parsed_size;
01109        for (; temp < limit; ++temp)
01110          {
01111            if (*temp == '\012')
01112              temp[temp > ext_names && temp[-1] == '/' ? -1 : 0] = '\0';
01113            if (*temp == '\\')
01114              *temp = '/';
01115          }
01116        *limit = '\0';
01117       }
01118 
01119       /* Pad to an even boundary if you have to.  */
01120       bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
01121       bfd_ardata (abfd)->first_file_filepos +=
01122        (bfd_ardata (abfd)->first_file_filepos) % 2;
01123 
01124       /* FIXME, we can't release namedata here because it was allocated
01125         below extended_names on the objalloc...  */
01126     }
01127   return TRUE;
01128 }
01129 
01130 #ifdef VMS
01131 
01132 /* Return a copy of the stuff in the filename between any :]> and a
01133    semicolon.  */
01134 
01135 static const char *
01136 normalize (bfd *abfd, const char *file)
01137 {
01138   const char *first;
01139   const char *last;
01140   char *copy;
01141 
01142   first = file + strlen (file) - 1;
01143   last = first + 1;
01144 
01145   while (first != file)
01146     {
01147       if (*first == ';')
01148        last = first;
01149       if (*first == ':' || *first == ']' || *first == '>')
01150        {
01151          first++;
01152          break;
01153        }
01154       first--;
01155     }
01156 
01157   copy = bfd_alloc (abfd, last - first + 1);
01158   if (copy == NULL)
01159     return NULL;
01160 
01161   memcpy (copy, first, last - first);
01162   copy[last - first] = 0;
01163 
01164   return copy;
01165 }
01166 
01167 #else
01168 static const char *
01169 normalize (bfd *abfd ATTRIBUTE_UNUSED, const char *file)
01170 {
01171   const char *filename = strrchr (file, '/');
01172 
01173 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
01174   {
01175     /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
01176     char *bslash = strrchr (file, '\\');
01177     if (filename == NULL || (bslash != NULL && bslash > filename))
01178       filename = bslash;
01179     if (filename == NULL && file[0] != '\0' && file[1] == ':')
01180       filename = file + 1;
01181   }
01182 #endif
01183   if (filename != NULL)
01184     filename++;
01185   else
01186     filename = file;
01187   return filename;
01188 }
01189 #endif
01190 
01191 /* Build a BFD style extended name table.  */
01192 
01193 bfd_boolean
01194 _bfd_archive_bsd_construct_extended_name_table (bfd *abfd,
01195                                           char **tabloc,
01196                                           bfd_size_type *tablen,
01197                                           const char **name)
01198 {
01199   *name = "ARFILENAMES/";
01200   return _bfd_construct_extended_name_table (abfd, FALSE, tabloc, tablen);
01201 }
01202 
01203 /* Build an SVR4 style extended name table.  */
01204 
01205 bfd_boolean
01206 _bfd_archive_coff_construct_extended_name_table (bfd *abfd,
01207                                            char **tabloc,
01208                                            bfd_size_type *tablen,
01209                                            const char **name)
01210 {
01211   *name = "//";
01212   return _bfd_construct_extended_name_table (abfd, TRUE, tabloc, tablen);
01213 }
01214 
01215 /* Follows archive_head and produces an extended name table if
01216    necessary.  Returns (in tabloc) a pointer to an extended name
01217    table, and in tablen the length of the table.  If it makes an entry
01218    it clobbers the filename so that the element may be written without
01219    further massage.  Returns TRUE if it ran successfully, FALSE if
01220    something went wrong.  A successful return may still involve a
01221    zero-length tablen!  */
01222 
01223 bfd_boolean
01224 _bfd_construct_extended_name_table (bfd *abfd,
01225                                 bfd_boolean trailing_slash,
01226                                 char **tabloc,
01227                                 bfd_size_type *tablen)
01228 {
01229   unsigned int maxname = abfd->xvec->ar_max_namelen;
01230   bfd_size_type total_namelen = 0;
01231   bfd *current;
01232   char *strptr;
01233 
01234   *tablen = 0;
01235 
01236   /* Figure out how long the table should be.  */
01237   for (current = abfd->archive_head; current != NULL; current = current->next)
01238     {
01239       const char *normal;
01240       unsigned int thislen;
01241 
01242       normal = normalize (current, current->filename);
01243       if (normal == NULL)
01244        return FALSE;
01245 
01246       thislen = strlen (normal);
01247 
01248       if (thislen > maxname
01249          && (bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0)
01250        thislen = maxname;
01251 
01252       if (thislen > maxname)
01253        {
01254          /* Add one to leave room for \n.  */
01255          total_namelen += thislen + 1;
01256          if (trailing_slash)
01257            {
01258              /* Leave room for trailing slash.  */
01259              ++total_namelen;
01260            }
01261        }
01262       else
01263        {
01264          struct ar_hdr *hdr = arch_hdr (current);
01265          if (strncmp (normal, hdr->ar_name, thislen) != 0
01266              || (thislen < sizeof hdr->ar_name
01267                 && hdr->ar_name[thislen] != ar_padchar (current)))
01268            {
01269              /* Must have been using extended format even though it
01270                 didn't need to.  Fix it to use normal format.  */
01271              memcpy (hdr->ar_name, normal, thislen);
01272              if (thislen < maxname
01273                 || (thislen == maxname && thislen < sizeof hdr->ar_name))
01274               hdr->ar_name[thislen] = ar_padchar (current);
01275            }
01276        }
01277     }
01278 
01279   if (total_namelen == 0)
01280     return TRUE;
01281 
01282   *tabloc = bfd_zalloc (abfd, total_namelen);
01283   if (*tabloc == NULL)
01284     return FALSE;
01285 
01286   *tablen = total_namelen;
01287   strptr = *tabloc;
01288 
01289   for (current = abfd->archive_head; current != NULL; current =
01290        current->next)
01291     {
01292       const char *normal;
01293       unsigned int thislen;
01294 
01295       normal = normalize (current, current->filename);
01296       if (normal == NULL)
01297        return FALSE;
01298 
01299       thislen = strlen (normal);
01300       if (thislen > maxname)
01301        {
01302          /* Works for now; may need to be re-engineered if we
01303             encounter an oddball archive format and want to
01304             generalise this hack.  */
01305          struct ar_hdr *hdr = arch_hdr (current);
01306          strcpy (strptr, normal);
01307          if (! trailing_slash)
01308            strptr[thislen] = '\012';
01309          else
01310            {
01311              strptr[thislen] = '/';
01312              strptr[thislen + 1] = '\012';
01313            }
01314          hdr->ar_name[0] = ar_padchar (current);
01315           _bfd_ar_spacepad (hdr->ar_name + 1, maxname - 1, "%-ld",
01316                             strptr - *tabloc);
01317          strptr += thislen + 1;
01318          if (trailing_slash)
01319            ++strptr;
01320        }
01321     }
01322 
01323   return TRUE;
01324 }
01325 
01326 /* A couple of functions for creating ar_hdrs.  */
01327 
01328 #ifdef HPUX_LARGE_AR_IDS
01329 /* Function to encode large UID/GID values according to HP.  */
01330 
01331 static void
01332 hpux_uid_gid_encode (char str[6], long int id)
01333 {
01334   int cnt;
01335 
01336   str[5] = '@' + (id & 3);
01337   id >>= 2;
01338 
01339   for (cnt = 4; cnt >= 0; --cnt, id >>= 6)
01340     str[cnt] = ' ' + (id & 0x3f);
01341 }
01342 #endif /* HPUX_LARGE_AR_IDS */
01343 
01344 #ifndef HAVE_GETUID
01345 #define getuid() 0
01346 #endif
01347 
01348 #ifndef HAVE_GETGID
01349 #define getgid() 0
01350 #endif
01351 
01352 /* Takes a filename, returns an arelt_data for it, or NULL if it can't
01353    make one.  The filename must refer to a filename in the filesystem.
01354    The filename field of the ar_hdr will NOT be initialized.  If member
01355    is set, and it's an in-memory bfd, we fake it.  */
01356 
01357 static struct areltdata *
01358 bfd_ar_hdr_from_filesystem (bfd *abfd, const char *filename, bfd *member)
01359 {
01360   struct stat status;
01361   struct areltdata *ared;
01362   struct ar_hdr *hdr;
01363   bfd_size_type amt;
01364 
01365   if (member && (member->flags & BFD_IN_MEMORY) != 0)
01366     {
01367       /* Assume we just "made" the member, and fake it.  */
01368       struct bfd_in_memory *bim = member->iostream;
01369       time (&status.st_mtime);
01370       status.st_uid = getuid ();
01371       status.st_gid = getgid ();
01372       status.st_mode = 0644;
01373       status.st_size = bim->size;
01374     }
01375   else if (stat (filename, &status) != 0)
01376     {
01377       bfd_set_error (bfd_error_system_call);
01378       return NULL;
01379     }
01380 
01381   amt = sizeof (struct ar_hdr) + sizeof (struct areltdata);
01382   ared = bfd_zalloc (abfd, amt);
01383   if (ared == NULL)
01384     return NULL;
01385   hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
01386 
01387   /* ar headers are space padded, not null padded!  */
01388   memset (hdr, ' ', sizeof (struct ar_hdr));
01389 
01390   _bfd_ar_spacepad (hdr->ar_date, sizeof (hdr->ar_date), "%-12ld",
01391                     status.st_mtime);
01392 #ifdef HPUX_LARGE_AR_IDS
01393   /* HP has a very "special" way to handle UID/GID's with numeric values
01394      > 99999.  */
01395   if (status.st_uid > 99999)
01396     hpux_uid_gid_encode (hdr->ar_uid, (long) status.st_uid);
01397   else
01398 #endif
01399     _bfd_ar_spacepad (hdr->ar_uid, sizeof (hdr->ar_uid), "%ld",
01400                       status.st_uid);
01401 #ifdef HPUX_LARGE_AR_IDS
01402   /* HP has a very "special" way to handle UID/GID's with numeric values
01403      > 99999.  */
01404   if (status.st_gid > 99999)
01405     hpux_uid_gid_encode (hdr->ar_gid, (long) status.st_gid);
01406   else
01407 #endif
01408     _bfd_ar_spacepad (hdr->ar_gid, sizeof (hdr->ar_gid), "%ld",
01409                       status.st_gid);
01410   _bfd_ar_spacepad (hdr->ar_mode, sizeof (hdr->ar_mode), "%-8lo",
01411                     status.st_mode);
01412   _bfd_ar_spacepad (hdr->ar_size, sizeof (hdr->ar_size), "%-10ld",
01413                     status.st_size);
01414   memcpy (hdr->ar_fmag, ARFMAG, 2);
01415   ared->parsed_size = status.st_size;
01416   ared->arch_header = (char *) hdr;
01417 
01418   return ared;
01419 }
01420 
01421 /* This is magic required by the "ar" program.  Since it's
01422    undocumented, it's undocumented.  You may think that it would take
01423    a strong stomach to write this, and it does, but it takes even a
01424    stronger stomach to try to code around such a thing!  */
01425 
01426 struct ar_hdr *bfd_special_undocumented_glue (bfd *, const char *);
01427 
01428 struct ar_hdr *
01429 bfd_special_undocumented_glue (bfd *abfd, const char *filename)
01430 {
01431   struct areltdata *ar_elt = bfd_ar_hdr_from_filesystem (abfd, filename, 0);
01432   if (ar_elt == NULL)
01433     return NULL;
01434   return (struct ar_hdr *) ar_elt->arch_header;
01435 }
01436 
01437 /* Analogous to stat call.  */
01438 
01439 int
01440 bfd_generic_stat_arch_elt (bfd *abfd, struct stat *buf)
01441 {
01442   struct ar_hdr *hdr;
01443   char *aloser;
01444 
01445   if (abfd->arelt_data == NULL)
01446     {
01447       bfd_set_error (bfd_error_invalid_operation);
01448       return -1;
01449     }
01450 
01451   hdr = arch_hdr (abfd);
01452 
01453 #define foo(arelt, stelt, size)                         \
01454   buf->stelt = strtol (hdr->arelt, &aloser, size);      \
01455   if (aloser == hdr->arelt)                      \
01456     return -1;
01457 
01458   /* Some platforms support special notations for large IDs.  */
01459 #ifdef HPUX_LARGE_AR_IDS
01460 # define foo2(arelt, stelt, size)                              \
01461   if (hdr->arelt[5] == ' ')                                    \
01462     {                                                          \
01463       foo (arelt, stelt, size);                                       \
01464     }                                                          \
01465   else                                                         \
01466     {                                                          \
01467       int cnt;                                                        \
01468       for (buf->stelt = cnt = 0; cnt < 5; ++cnt)               \
01469        {                                                       \
01470          if (hdr->arelt[cnt] < ' ' || hdr->arelt[cnt] > ' ' + 0x3f)   \
01471            return -1;                                                 \
01472          buf->stelt <<= 6;                                     \
01473          buf->stelt += hdr->arelt[cnt] - ' ';                         \
01474        }                                                       \
01475       if (hdr->arelt[5] < '@' || hdr->arelt[5] > '@' + 3)             \
01476        return -1;                                              \
01477       buf->stelt <<= 2;                                               \
01478       buf->stelt += hdr->arelt[5] - '@';                       \
01479     }
01480 #else
01481 # define foo2(arelt, stelt, size) foo (arelt, stelt, size)
01482 #endif
01483 
01484   foo (ar_date, st_mtime, 10);
01485   foo2 (ar_uid, st_uid, 10);
01486   foo2 (ar_gid, st_gid, 10);
01487   foo (ar_mode, st_mode, 8);
01488 
01489   buf->st_size = arch_eltdata (abfd)->parsed_size;
01490 
01491   return 0;
01492 }
01493 
01494 void
01495 bfd_dont_truncate_arname (bfd *abfd, const char *pathname, char *arhdr)
01496 {
01497   /* FIXME: This interacts unpleasantly with ar's quick-append option.
01498      Fortunately ic960 users will never use that option.  Fixing this
01499      is very hard; fortunately I know how to do it and will do so once
01500      intel's release is out the door.  */
01501 
01502   struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
01503   size_t length;
01504   const char *filename;
01505   size_t maxlen = ar_maxnamelen (abfd);
01506 
01507   if ((bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0)
01508     {
01509       bfd_bsd_truncate_arname (abfd, pathname, arhdr);
01510       return;
01511     }
01512 
01513   filename = normalize (abfd, pathname);
01514   if (filename == NULL)
01515     {
01516       /* FIXME */
01517       abort ();
01518     }
01519 
01520   length = strlen (filename);
01521 
01522   if (length <= maxlen)
01523     memcpy (hdr->ar_name, filename, length);
01524 
01525   /* Add the padding character if there is room for it.  */
01526   if (length < maxlen
01527       || (length == maxlen && length < sizeof hdr->ar_name))
01528     (hdr->ar_name)[length] = ar_padchar (abfd);
01529 }
01530 
01531 void
01532 bfd_bsd_truncate_arname (bfd *abfd, const char *pathname, char *arhdr)
01533 {
01534   struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
01535   size_t length;
01536   const char *filename = strrchr (pathname, '/');
01537   size_t maxlen = ar_maxnamelen (abfd);
01538 
01539 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
01540   {
01541     /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
01542     char *bslash = strrchr (pathname, '\\');
01543     if (filename == NULL || (bslash != NULL && bslash > filename))
01544       filename = bslash;
01545     if (filename == NULL && pathname[0] != '\0' && pathname[1] == ':')
01546       filename = pathname + 1;
01547   }
01548 #endif
01549 
01550   if (filename == NULL)
01551     filename = pathname;
01552   else
01553     ++filename;
01554 
01555   length = strlen (filename);
01556 
01557   if (length <= maxlen)
01558     memcpy (hdr->ar_name, filename, length);
01559   else
01560     {
01561       /* pathname: meet procrustes */
01562       memcpy (hdr->ar_name, filename, maxlen);
01563       length = maxlen;
01564     }
01565 
01566   if (length < maxlen)
01567     (hdr->ar_name)[length] = ar_padchar (abfd);
01568 }
01569 
01570 /* Store name into ar header.  Truncates the name to fit.
01571    1> strip pathname to be just the basename.
01572    2> if it's short enuf to fit, stuff it in.
01573    3> If it doesn't end with .o, truncate it to fit
01574    4> truncate it before the .o, append .o, stuff THAT in.  */
01575 
01576 /* This is what gnu ar does.  It's better but incompatible with the
01577    bsd ar.  */
01578 
01579 void
01580 bfd_gnu_truncate_arname (bfd *abfd, const char *pathname, char *arhdr)
01581 {
01582   struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
01583   size_t length;
01584   const char *filename = strrchr (pathname, '/');
01585   size_t maxlen = ar_maxnamelen (abfd);
01586 
01587 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
01588   {
01589     /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
01590     char *bslash = strrchr (pathname, '\\');
01591     if (filename == NULL || (bslash != NULL && bslash > filename))
01592       filename = bslash;
01593     if (filename == NULL && pathname[0] != '\0' && pathname[1] == ':')
01594       filename = pathname + 1;
01595   }
01596 #endif
01597 
01598   if (filename == NULL)
01599     filename = pathname;
01600   else
01601     ++filename;
01602 
01603   length = strlen (filename);
01604 
01605   if (length <= maxlen)
01606     memcpy (hdr->ar_name, filename, length);
01607   else
01608     {                       /* pathname: meet procrustes */
01609       memcpy (hdr->ar_name, filename, maxlen);
01610       if ((filename[length - 2] == '.') && (filename[length - 1] == 'o'))
01611        {
01612          hdr->ar_name[maxlen - 2] = '.';
01613          hdr->ar_name[maxlen - 1] = 'o';
01614        }
01615       length = maxlen;
01616     }
01617 
01618   if (length < 16)
01619     (hdr->ar_name)[length] = ar_padchar (abfd);
01620 }
01621 
01622 /* The BFD is open for write and has its format set to bfd_archive.  */
01623 
01624 bfd_boolean
01625 _bfd_write_archive_contents (bfd *arch)
01626 {
01627   bfd *current;
01628   char *etable = NULL;
01629   bfd_size_type elength = 0;
01630   const char *ename = NULL;
01631   bfd_boolean makemap = bfd_has_map (arch);
01632   /* If no .o's, don't bother to make a map.  */
01633   bfd_boolean hasobjects = FALSE;
01634   bfd_size_type wrote;
01635   int tries;
01636 
01637   /* Verify the viability of all entries; if any of them live in the
01638      filesystem (as opposed to living in an archive open for input)
01639      then construct a fresh ar_hdr for them.  */
01640   for (current = arch->archive_head; current; current = current->next)
01641     {
01642       /* This check is checking the bfds for the objects we're reading
01643         from (which are usually either an object file or archive on
01644         disk), not the archive entries we're writing to.  We don't
01645         actually create bfds for the archive members, we just copy
01646         them byte-wise when we write out the archive.  */
01647       if (bfd_write_p (current))
01648        {
01649          bfd_set_error (bfd_error_invalid_operation);
01650          goto input_err;
01651        }
01652       if (!current->arelt_data)
01653        {
01654          current->arelt_data =
01655            bfd_ar_hdr_from_filesystem (arch, current->filename, current);
01656          if (!current->arelt_data)
01657            goto input_err;
01658 
01659          /* Put in the file name.  */
01660          BFD_SEND (arch, _bfd_truncate_arname,
01661                   (arch, current->filename, (char *) arch_hdr (current)));
01662        }
01663 
01664       if (makemap && ! hasobjects)
01665        {                    /* Don't bother if we won't make a map!  */
01666          if ((bfd_check_format (current, bfd_object)))
01667            hasobjects = TRUE;
01668        }
01669     }
01670 
01671   if (!BFD_SEND (arch, _bfd_construct_extended_name_table,
01672                (arch, &etable, &elength, &ename)))
01673     return FALSE;
01674 
01675   if (bfd_seek (arch, (file_ptr) 0, SEEK_SET) != 0)
01676     return FALSE;
01677   wrote = bfd_bwrite (ARMAG, SARMAG, arch);
01678   if (wrote != SARMAG)
01679     return FALSE;
01680 
01681   if (makemap && hasobjects)
01682     {
01683       if (! _bfd_compute_and_write_armap (arch, (unsigned int) elength))
01684        return FALSE;
01685     }
01686 
01687   if (elength != 0)
01688     {
01689       struct ar_hdr hdr;
01690 
01691       memset (&hdr, ' ', sizeof (struct ar_hdr));
01692       memcpy (hdr.ar_name, ename, strlen (ename));
01693       /* Round size up to even number in archive header.  */
01694       _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld",
01695                         (elength + 1) & ~(bfd_size_type) 1);
01696       memcpy (hdr.ar_fmag, ARFMAG, 2);
01697       if ((bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
01698           != sizeof (struct ar_hdr))
01699          || bfd_bwrite (etable, elength, arch) != elength)
01700        return FALSE;
01701       if ((elength % 2) == 1)
01702        {
01703          if (bfd_bwrite ("\012", 1, arch) != 1)
01704            return FALSE;
01705        }
01706     }
01707 
01708   for (current = arch->archive_head; current; current = current->next)
01709     {
01710       char buffer[DEFAULT_BUFFERSIZE];
01711       unsigned int remaining = arelt_size (current);
01712       struct ar_hdr *hdr = arch_hdr (current);
01713 
01714       /* Write ar header.  */
01715       if (bfd_bwrite (hdr, sizeof (*hdr), arch)
01716          != sizeof (*hdr))
01717        return FALSE;
01718       if (bfd_seek (current, (file_ptr) 0, SEEK_SET) != 0)
01719        goto input_err;
01720       while (remaining)
01721        {
01722          unsigned int amt = DEFAULT_BUFFERSIZE;
01723          if (amt > remaining)
01724            amt = remaining;
01725          errno = 0;
01726          if (bfd_bread (buffer, amt, current) != amt)
01727            {
01728              if (bfd_get_error () != bfd_error_system_call)
01729               bfd_set_error (bfd_error_file_truncated);
01730              goto input_err;
01731            }
01732          if (bfd_bwrite (buffer, amt, arch) != amt)
01733            return FALSE;
01734          remaining -= amt;
01735        }
01736       if ((arelt_size (current) % 2) == 1)
01737        {
01738          if (bfd_bwrite ("\012", 1, arch) != 1)
01739            return FALSE;
01740        }
01741     }
01742 
01743   if (makemap && hasobjects)
01744     {
01745       /* Verify the timestamp in the archive file.  If it would not be
01746         accepted by the linker, rewrite it until it would be.  If
01747         anything odd happens, break out and just return.  (The
01748         Berkeley linker checks the timestamp and refuses to read the
01749         table-of-contents if it is >60 seconds less than the file's
01750         modified-time.  That painful hack requires this painful hack.  */
01751       tries = 1;
01752       do
01753        {
01754          if (bfd_update_armap_timestamp (arch))
01755            break;
01756          (*_bfd_error_handler)
01757            (_("Warning: writing archive was slow: rewriting timestamp\n"));
01758        }
01759       while (++tries < 6);
01760     }
01761 
01762   return TRUE;
01763 
01764  input_err:
01765   bfd_set_error (bfd_error_on_input, current, bfd_get_error ());
01766   return FALSE;
01767 }
01768 
01769 /* Note that the namidx for the first symbol is 0.  */
01770 
01771 bfd_boolean
01772 _bfd_compute_and_write_armap (bfd *arch, unsigned int elength)
01773 {
01774   char *first_name = NULL;
01775   bfd *current;
01776   file_ptr elt_no = 0;
01777   struct orl *map = NULL;
01778   unsigned int orl_max = 1024;            /* Fine initial default.  */
01779   unsigned int orl_count = 0;
01780   int stridx = 0;
01781   asymbol **syms = NULL;
01782   long syms_max = 0;
01783   bfd_boolean ret;
01784   bfd_size_type amt;
01785 
01786   /* Dunno if this is the best place for this info...  */
01787   if (elength != 0)
01788     elength += sizeof (struct ar_hdr);
01789   elength += elength % 2;
01790 
01791   amt = orl_max * sizeof (struct orl);
01792   map = bfd_malloc (amt);
01793   if (map == NULL)
01794     goto error_return;
01795 
01796   /* We put the symbol names on the arch objalloc, and then discard
01797      them when done.  */
01798   first_name = bfd_alloc (arch, 1);
01799   if (first_name == NULL)
01800     goto error_return;
01801 
01802   /* Drop all the files called __.SYMDEF, we're going to make our own.  */
01803   while (arch->archive_head &&
01804         strcmp (arch->archive_head->filename, "__.SYMDEF") == 0)
01805     arch->archive_head = arch->archive_head->next;
01806 
01807   /* Map over each element.  */
01808   for (current = arch->archive_head;
01809        current != NULL;
01810        current = current->next, elt_no++)
01811     {
01812       if (bfd_check_format (current, bfd_object)
01813          && (bfd_get_file_flags (current) & HAS_SYMS) != 0)
01814        {
01815          long storage;
01816          long symcount;
01817          long src_count;
01818 
01819          storage = bfd_get_symtab_upper_bound (current);
01820          if (storage < 0)
01821            goto error_return;
01822 
01823          if (storage != 0)
01824            {
01825              if (storage > syms_max)
01826               {
01827                 if (syms_max > 0)
01828                   free (syms);
01829                 syms_max = storage;
01830                 syms = bfd_malloc (syms_max);
01831                 if (syms == NULL)
01832                   goto error_return;
01833               }
01834              symcount = bfd_canonicalize_symtab (current, syms);
01835              if (symcount < 0)
01836               goto error_return;
01837 
01838              /* Now map over all the symbols, picking out the ones we
01839                  want.  */
01840              for (src_count = 0; src_count < symcount; src_count++)
01841               {
01842                 flagword flags = (syms[src_count])->flags;
01843                 asection *sec = syms[src_count]->section;
01844 
01845                 if ((flags & BSF_GLOBAL ||
01846                      flags & BSF_WEAK ||
01847                      flags & BSF_INDIRECT ||
01848                      bfd_is_com_section (sec))
01849                     && ! bfd_is_und_section (sec))
01850                   {
01851                     bfd_size_type namelen;
01852                     struct orl *new_map;
01853 
01854                     /* This symbol will go into the archive header.  */
01855                     if (orl_count == orl_max)
01856                      {
01857                        orl_max *= 2;
01858                        amt = orl_max * sizeof (struct orl);
01859                        new_map = bfd_realloc (map, amt);
01860                        if (new_map == NULL)
01861                          goto error_return;
01862 
01863                        map = new_map;
01864                      }
01865 
01866                     namelen = strlen (syms[src_count]->name);
01867                     amt = sizeof (char *);
01868                     map[orl_count].name = bfd_alloc (arch, amt);
01869                     if (map[orl_count].name == NULL)
01870                      goto error_return;
01871                     *(map[orl_count].name) = bfd_alloc (arch, namelen + 1);
01872                     if (*(map[orl_count].name) == NULL)
01873                      goto error_return;
01874                     strcpy (*(map[orl_count].name), syms[src_count]->name);
01875                     map[orl_count].u.abfd = current;
01876                     map[orl_count].namidx = stridx;
01877 
01878                     stridx += namelen + 1;
01879                     ++orl_count;
01880                   }
01881               }
01882            }
01883 
01884          /* Now ask the BFD to free up any cached information, so we
01885             don't fill all of memory with symbol tables.  */
01886          if (! bfd_free_cached_info (current))
01887            goto error_return;
01888        }
01889     }
01890 
01891   /* OK, now we have collected all the data, let's write them out.  */
01892   ret = BFD_SEND (arch, write_armap,
01893                 (arch, elength, map, orl_count, stridx));
01894 
01895   if (syms_max > 0)
01896     free (syms);
01897   if (map != NULL)
01898     free (map);
01899   if (first_name != NULL)
01900     bfd_release (arch, first_name);
01901 
01902   return ret;
01903 
01904  error_return:
01905   if (syms_max > 0)
01906     free (syms);
01907   if (map != NULL)
01908     free (map);
01909   if (first_name != NULL)
01910     bfd_release (arch, first_name);
01911 
01912   return FALSE;
01913 }
01914 
01915 bfd_boolean
01916 bsd_write_armap (bfd *arch,
01917                unsigned int elength,
01918                struct orl *map,
01919                unsigned int orl_count,
01920                int stridx)
01921 {
01922   int padit = stridx & 1;
01923   unsigned int ranlibsize = orl_count * BSD_SYMDEF_SIZE;
01924   unsigned int stringsize = stridx + padit;
01925   /* Include 8 bytes to store ranlibsize and stringsize in output.  */
01926   unsigned int mapsize = ranlibsize + stringsize + 8;
01927   file_ptr firstreal;
01928   bfd *current = arch->archive_head;
01929   bfd *last_elt = current;  /* Last element arch seen.  */
01930   bfd_byte temp[4];
01931   unsigned int count;
01932   struct ar_hdr hdr;
01933   struct stat statbuf;
01934 
01935   firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
01936 
01937   stat (arch->filename, &statbuf);
01938   memset (&hdr, ' ', sizeof (struct ar_hdr));
01939   memcpy (hdr.ar_name, RANLIBMAG, strlen (RANLIBMAG));
01940   /* Remember the timestamp, to keep it holy.  But fudge it a little.  */
01941   bfd_ardata (arch)->armap_timestamp = statbuf.st_mtime + ARMAP_TIME_OFFSET;
01942   bfd_ardata (arch)->armap_datepos = (SARMAG
01943                                   + offsetof (struct ar_hdr, ar_date[0]));
01944   _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
01945                     bfd_ardata (arch)->armap_timestamp);
01946   _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", getuid ());
01947   _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", getgid ());
01948   _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", mapsize);
01949   memcpy (hdr.ar_fmag, ARFMAG, 2);
01950   if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
01951       != sizeof (struct ar_hdr))
01952     return FALSE;
01953   H_PUT_32 (arch, ranlibsize, temp);
01954   if (bfd_bwrite (temp, sizeof (temp), arch) != sizeof (temp))
01955     return FALSE;
01956 
01957   for (count = 0; count < orl_count; count++)
01958     {
01959       bfd_byte buf[BSD_SYMDEF_SIZE];
01960 
01961       if (map[count].u.abfd != last_elt)
01962        {
01963          do
01964            {
01965              firstreal += arelt_size (current) + sizeof (struct ar_hdr);
01966              firstreal += firstreal % 2;
01967              current = current->next;
01968            }
01969          while (current != map[count].u.abfd);
01970        }
01971 
01972       last_elt = current;
01973       H_PUT_32 (arch, map[count].namidx, buf);
01974       H_PUT_32 (arch, firstreal, buf + BSD_SYMDEF_OFFSET_SIZE);
01975       if (bfd_bwrite (buf, BSD_SYMDEF_SIZE, arch)
01976          != BSD_SYMDEF_SIZE)
01977        return FALSE;
01978     }
01979 
01980   /* Now write the strings themselves.  */
01981   H_PUT_32 (arch, stringsize, temp);
01982   if (bfd_bwrite (temp, sizeof (temp), arch) != sizeof (temp))
01983     return FALSE;
01984   for (count = 0; count < orl_count; count++)
01985     {
01986       size_t len = strlen (*map[count].name) + 1;
01987 
01988       if (bfd_bwrite (*map[count].name, len, arch) != len)
01989        return FALSE;
01990     }
01991 
01992   /* The spec sez this should be a newline.  But in order to be
01993      bug-compatible for sun's ar we use a null.  */
01994   if (padit)
01995     {
01996       if (bfd_bwrite ("", 1, arch) != 1)
01997        return FALSE;
01998     }
01999 
02000   return TRUE;
02001 }
02002 
02003 /* At the end of archive file handling, update the timestamp in the
02004    file, so the linker will accept it.
02005 
02006    Return TRUE if the timestamp was OK, or an unusual problem happened.
02007    Return FALSE if we updated the timestamp.  */
02008 
02009 bfd_boolean
02010 _bfd_archive_bsd_update_armap_timestamp (bfd *arch)
02011 {
02012   struct stat archstat;
02013   struct ar_hdr hdr;
02014 
02015   /* Flush writes, get last-write timestamp from file, and compare it
02016      to the timestamp IN the file.  */
02017   bfd_flush (arch);
02018   if (bfd_stat (arch, &archstat) == -1)
02019     {
02020       bfd_perror (_("Reading archive file mod timestamp"));
02021 
02022       /* Can't read mod time for some reason.  */
02023       return TRUE;
02024     }
02025   if (archstat.st_mtime <= bfd_ardata (arch)->armap_timestamp)
02026     /* OK by the linker's rules.  */
02027     return TRUE;
02028 
02029   /* Update the timestamp.  */
02030   bfd_ardata (arch)->armap_timestamp = archstat.st_mtime + ARMAP_TIME_OFFSET;
02031 
02032   /* Prepare an ASCII version suitable for writing.  */
02033   memset (hdr.ar_date, ' ', sizeof (hdr.ar_date));
02034   _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
02035                     bfd_ardata (arch)->armap_timestamp);
02036 
02037   /* Write it into the file.  */
02038   bfd_ardata (arch)->armap_datepos = (SARMAG
02039                                   + offsetof (struct ar_hdr, ar_date[0]));
02040   if (bfd_seek (arch, bfd_ardata (arch)->armap_datepos, SEEK_SET) != 0
02041       || (bfd_bwrite (hdr.ar_date, sizeof (hdr.ar_date), arch)
02042          != sizeof (hdr.ar_date)))
02043     {
02044       bfd_perror (_("Writing updated armap timestamp"));
02045 
02046       /* Some error while writing.  */
02047       return TRUE;
02048     }
02049 
02050   /* We updated the timestamp successfully.  */
02051   return FALSE;
02052 }
02053 
02054 /* A coff armap looks like :
02055    lARMAG
02056    struct ar_hdr with name = '/'
02057    number of symbols
02058    offset of file for symbol 0
02059    offset of file for symbol 1
02060 
02061    offset of file for symbol n-1
02062    symbol name 0
02063    symbol name 1
02064 
02065    symbol name n-1  */
02066 
02067 bfd_boolean
02068 coff_write_armap (bfd *arch,
02069                 unsigned int elength,
02070                 struct orl *map,
02071                 unsigned int symbol_count,
02072                 int stridx)
02073 {
02074   /* The size of the ranlib is the number of exported symbols in the
02075      archive * the number of bytes in an int, + an int for the count.  */
02076   unsigned int ranlibsize = (symbol_count * 4) + 4;
02077   unsigned int stringsize = stridx;
02078   unsigned int mapsize = stringsize + ranlibsize;
02079   unsigned int archive_member_file_ptr;
02080   bfd *current = arch->archive_head;
02081   unsigned int count;
02082   struct ar_hdr hdr;
02083   int padit = mapsize & 1;
02084 
02085   if (padit)
02086     mapsize++;
02087 
02088   /* Work out where the first object file will go in the archive.  */
02089   archive_member_file_ptr = (mapsize
02090                           + elength
02091                           + sizeof (struct ar_hdr)
02092                           + SARMAG);
02093 
02094   memset (&hdr, ' ', sizeof (struct ar_hdr));
02095   hdr.ar_name[0] = '/';
02096   _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld",
02097                     mapsize);
02098   _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
02099                     time (NULL));
02100   /* This, at least, is what Intel coff sets the values to.  */
02101   _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
02102   _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0);
02103   _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0);
02104   memcpy (hdr.ar_fmag, ARFMAG, 2);
02105 
02106   /* Write the ar header for this item and the number of symbols.  */
02107   if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
02108       != sizeof (struct ar_hdr))
02109     return FALSE;
02110 
02111   if (!bfd_write_bigendian_4byte_int (arch, symbol_count))
02112     return FALSE;
02113 
02114   /* Two passes, first write the file offsets for each symbol -
02115      remembering that each offset is on a two byte boundary.  */
02116 
02117   /* Write out the file offset for the file associated with each
02118      symbol, and remember to keep the offsets padded out.  */
02119 
02120   current = arch->archive_head;
02121   count = 0;
02122   while (current != NULL && count < symbol_count)
02123     {
02124       /* For each symbol which is used defined in this object, write
02125         out the object file's address in the archive.  */
02126 
02127       while (count < symbol_count && map[count].u.abfd == current)
02128        {
02129          if (!bfd_write_bigendian_4byte_int (arch, archive_member_file_ptr))
02130            return FALSE;
02131          count++;
02132        }
02133       /* Add size of this archive entry.  */
02134       archive_member_file_ptr += arelt_size (current) + sizeof (struct ar_hdr);
02135       /* Remember aboout the even alignment.  */
02136       archive_member_file_ptr += archive_member_file_ptr % 2;
02137       current = current->next;
02138     }
02139 
02140   /* Now write the strings themselves.  */
02141   for (count = 0; count < symbol_count; count++)
02142     {
02143       size_t len = strlen (*map[count].name) + 1;
02144 
02145       if (bfd_bwrite (*map[count].name, len, arch) != len)
02146        return FALSE;
02147     }
02148 
02149   /* The spec sez this should be a newline.  But in order to be
02150      bug-compatible for arc960 we use a null.  */
02151   if (padit)
02152     {
02153       if (bfd_bwrite ("", 1, arch) != 1)
02154        return FALSE;
02155     }
02156 
02157   return TRUE;
02158 }