15796c8dcSSimon Schubert /* BFD back-end for archive files (libraries). 25796c8dcSSimon Schubert Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3*cf7f2e2dSJohn Marino 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 45796c8dcSSimon Schubert Free Software Foundation, Inc. 55796c8dcSSimon Schubert Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault. 65796c8dcSSimon Schubert 75796c8dcSSimon Schubert This file is part of BFD, the Binary File Descriptor library. 85796c8dcSSimon Schubert 95796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify 105796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by 115796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or 125796c8dcSSimon Schubert (at your option) any later version. 135796c8dcSSimon Schubert 145796c8dcSSimon Schubert This program is distributed in the hope that it will be useful, 155796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of 165796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 175796c8dcSSimon Schubert GNU General Public License for more details. 185796c8dcSSimon Schubert 195796c8dcSSimon Schubert You should have received a copy of the GNU General Public License 205796c8dcSSimon Schubert along with this program; if not, write to the Free Software 215796c8dcSSimon Schubert Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 225796c8dcSSimon Schubert 235796c8dcSSimon Schubert /* 245796c8dcSSimon Schubert @setfilename archive-info 255796c8dcSSimon Schubert SECTION 265796c8dcSSimon Schubert Archives 275796c8dcSSimon Schubert 285796c8dcSSimon Schubert DESCRIPTION 295796c8dcSSimon Schubert An archive (or library) is just another BFD. It has a symbol 305796c8dcSSimon Schubert table, although there's not much a user program will do with it. 315796c8dcSSimon Schubert 325796c8dcSSimon Schubert The big difference between an archive BFD and an ordinary BFD 335796c8dcSSimon Schubert is that the archive doesn't have sections. Instead it has a 345796c8dcSSimon Schubert chain of BFDs that are considered its contents. These BFDs can 355796c8dcSSimon Schubert be manipulated like any other. The BFDs contained in an 365796c8dcSSimon Schubert archive opened for reading will all be opened for reading. You 375796c8dcSSimon Schubert may put either input or output BFDs into an archive opened for 385796c8dcSSimon Schubert output; they will be handled correctly when the archive is closed. 395796c8dcSSimon Schubert 405796c8dcSSimon Schubert Use <<bfd_openr_next_archived_file>> to step through 415796c8dcSSimon Schubert the contents of an archive opened for input. You don't 425796c8dcSSimon Schubert have to read the entire archive if you don't want 435796c8dcSSimon Schubert to! Read it until you find what you want. 445796c8dcSSimon Schubert 455796c8dcSSimon Schubert Archive contents of output BFDs are chained through the 465796c8dcSSimon Schubert <<next>> pointer in a BFD. The first one is findable through 475796c8dcSSimon Schubert the <<archive_head>> slot of the archive. Set it with 485796c8dcSSimon Schubert <<bfd_set_archive_head>> (q.v.). A given BFD may be in only one 495796c8dcSSimon Schubert open output archive at a time. 505796c8dcSSimon Schubert 515796c8dcSSimon Schubert As expected, the BFD archive code is more general than the 525796c8dcSSimon Schubert archive code of any given environment. BFD archives may 535796c8dcSSimon Schubert contain files of different formats (e.g., a.out and coff) and 545796c8dcSSimon Schubert even different architectures. You may even place archives 555796c8dcSSimon Schubert recursively into archives! 565796c8dcSSimon Schubert 575796c8dcSSimon Schubert This can cause unexpected confusion, since some archive 585796c8dcSSimon Schubert formats are more expressive than others. For instance, Intel 595796c8dcSSimon Schubert COFF archives can preserve long filenames; SunOS a.out archives 605796c8dcSSimon Schubert cannot. If you move a file from the first to the second 615796c8dcSSimon Schubert format and back again, the filename may be truncated. 625796c8dcSSimon Schubert Likewise, different a.out environments have different 635796c8dcSSimon Schubert conventions as to how they truncate filenames, whether they 645796c8dcSSimon Schubert preserve directory names in filenames, etc. When 655796c8dcSSimon Schubert interoperating with native tools, be sure your files are 665796c8dcSSimon Schubert homogeneous. 675796c8dcSSimon Schubert 685796c8dcSSimon Schubert Beware: most of these formats do not react well to the 695796c8dcSSimon Schubert presence of spaces in filenames. We do the best we can, but 705796c8dcSSimon Schubert can't always handle this case due to restrictions in the format of 715796c8dcSSimon Schubert archives. Many Unix utilities are braindead in regards to 725796c8dcSSimon Schubert spaces and such in filenames anyway, so this shouldn't be much 735796c8dcSSimon Schubert of a restriction. 745796c8dcSSimon Schubert 755796c8dcSSimon Schubert Archives are supported in BFD in <<archive.c>>. 765796c8dcSSimon Schubert 775796c8dcSSimon Schubert SUBSECTION 785796c8dcSSimon Schubert Archive functions 795796c8dcSSimon Schubert */ 805796c8dcSSimon Schubert 815796c8dcSSimon Schubert /* Assumes: 825796c8dcSSimon Schubert o - all archive elements start on an even boundary, newline padded; 835796c8dcSSimon Schubert o - all arch headers are char *; 845796c8dcSSimon Schubert o - all arch headers are the same size (across architectures). 855796c8dcSSimon Schubert */ 865796c8dcSSimon Schubert 875796c8dcSSimon Schubert /* Some formats provide a way to cram a long filename into the short 885796c8dcSSimon Schubert (16 chars) space provided by a BSD archive. The trick is: make a 895796c8dcSSimon Schubert special "file" in the front of the archive, sort of like the SYMDEF 905796c8dcSSimon Schubert entry. If the filename is too long to fit, put it in the extended 915796c8dcSSimon Schubert name table, and use its index as the filename. To prevent 925796c8dcSSimon Schubert confusion prepend the index with a space. This means you can't 935796c8dcSSimon Schubert have filenames that start with a space, but then again, many Unix 945796c8dcSSimon Schubert utilities can't handle that anyway. 955796c8dcSSimon Schubert 965796c8dcSSimon Schubert This scheme unfortunately requires that you stand on your head in 975796c8dcSSimon Schubert order to write an archive since you need to put a magic file at the 985796c8dcSSimon Schubert front, and need to touch every entry to do so. C'est la vie. 995796c8dcSSimon Schubert 1005796c8dcSSimon Schubert We support two variants of this idea: 1015796c8dcSSimon Schubert The SVR4 format (extended name table is named "//"), 1025796c8dcSSimon Schubert and an extended pseudo-BSD variant (extended name table is named 1035796c8dcSSimon Schubert "ARFILENAMES/"). The origin of the latter format is uncertain. 1045796c8dcSSimon Schubert 1055796c8dcSSimon Schubert BSD 4.4 uses a third scheme: It writes a long filename 1065796c8dcSSimon Schubert directly after the header. This allows 'ar q' to work. 1075796c8dcSSimon Schubert */ 1085796c8dcSSimon Schubert 1095796c8dcSSimon Schubert /* Summary of archive member names: 1105796c8dcSSimon Schubert 1115796c8dcSSimon Schubert Symbol table (must be first): 1125796c8dcSSimon Schubert "__.SYMDEF " - Symbol table, Berkeley style, produced by ranlib. 1135796c8dcSSimon Schubert "/ " - Symbol table, system 5 style. 1145796c8dcSSimon Schubert 1155796c8dcSSimon Schubert Long name table (must be before regular file members): 1165796c8dcSSimon Schubert "// " - Long name table, System 5 R4 style. 1175796c8dcSSimon Schubert "ARFILENAMES/ " - Long name table, non-standard extended BSD (not BSD 4.4). 1185796c8dcSSimon Schubert 1195796c8dcSSimon Schubert Regular file members with short names: 1205796c8dcSSimon Schubert "filename.o/ " - Regular file, System 5 style (embedded spaces ok). 1215796c8dcSSimon Schubert "filename.o " - Regular file, Berkeley style (no embedded spaces). 1225796c8dcSSimon Schubert 1235796c8dcSSimon Schubert Regular files with long names (or embedded spaces, for BSD variants): 1245796c8dcSSimon Schubert "/18 " - SVR4 style, name at offset 18 in name table. 1255796c8dcSSimon Schubert "#1/23 " - Long name (or embedded spaces) 23 characters long, 1265796c8dcSSimon Schubert BSD 4.4 style, full name follows header. 1275796c8dcSSimon Schubert " 18 " - Long name 18 characters long, extended pseudo-BSD. 1285796c8dcSSimon Schubert */ 1295796c8dcSSimon Schubert 1305796c8dcSSimon Schubert #include "sysdep.h" 1315796c8dcSSimon Schubert #include "bfd.h" 1325796c8dcSSimon Schubert #include "libiberty.h" 1335796c8dcSSimon Schubert #include "libbfd.h" 1345796c8dcSSimon Schubert #include "aout/ar.h" 1355796c8dcSSimon Schubert #include "aout/ranlib.h" 1365796c8dcSSimon Schubert #include "safe-ctype.h" 1375796c8dcSSimon Schubert #include "hashtab.h" 1385796c8dcSSimon Schubert #include "filenames.h" 1395796c8dcSSimon Schubert 1405796c8dcSSimon Schubert #ifndef errno 1415796c8dcSSimon Schubert extern int errno; 1425796c8dcSSimon Schubert #endif 1435796c8dcSSimon Schubert 1445796c8dcSSimon Schubert /* We keep a cache of archive filepointers to archive elements to 1455796c8dcSSimon Schubert speed up searching the archive by filepos. We only add an entry to 1465796c8dcSSimon Schubert the cache when we actually read one. We also don't sort the cache; 1475796c8dcSSimon Schubert it's generally short enough to search linearly. 1485796c8dcSSimon Schubert Note that the pointers here point to the front of the ar_hdr, not 1495796c8dcSSimon Schubert to the front of the contents! */ 1505796c8dcSSimon Schubert struct ar_cache { 1515796c8dcSSimon Schubert file_ptr ptr; 1525796c8dcSSimon Schubert bfd *arbfd; 1535796c8dcSSimon Schubert }; 1545796c8dcSSimon Schubert 1555796c8dcSSimon Schubert #define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char) 1565796c8dcSSimon Schubert #define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen) 1575796c8dcSSimon Schubert 1585796c8dcSSimon Schubert #define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data)) 1595796c8dcSSimon Schubert #define arch_hdr(bfd) ((struct ar_hdr *) arch_eltdata (bfd)->arch_header) 160*cf7f2e2dSJohn Marino 161*cf7f2e2dSJohn Marino /* True iff NAME designated a BSD 4.4 extended name. */ 162*cf7f2e2dSJohn Marino 163*cf7f2e2dSJohn Marino #define is_bsd44_extended_name(NAME) \ 164*cf7f2e2dSJohn Marino (NAME[0] == '#' && NAME[1] == '1' && NAME[2] == '/' && ISDIGIT (NAME[3])) 1655796c8dcSSimon Schubert 1665796c8dcSSimon Schubert void 1675796c8dcSSimon Schubert _bfd_ar_spacepad (char *p, size_t n, const char *fmt, long val) 1685796c8dcSSimon Schubert { 1695796c8dcSSimon Schubert static char buf[20]; 1705796c8dcSSimon Schubert size_t len; 1715796c8dcSSimon Schubert snprintf (buf, sizeof (buf), fmt, val); 1725796c8dcSSimon Schubert len = strlen (buf); 1735796c8dcSSimon Schubert if (len < n) 1745796c8dcSSimon Schubert { 1755796c8dcSSimon Schubert memcpy (p, buf, len); 1765796c8dcSSimon Schubert memset (p + len, ' ', n - len); 1775796c8dcSSimon Schubert } 1785796c8dcSSimon Schubert else 1795796c8dcSSimon Schubert memcpy (p, buf, n); 1805796c8dcSSimon Schubert } 1815796c8dcSSimon Schubert 1825796c8dcSSimon Schubert bfd_boolean 1835796c8dcSSimon Schubert _bfd_generic_mkarchive (bfd *abfd) 1845796c8dcSSimon Schubert { 1855796c8dcSSimon Schubert bfd_size_type amt = sizeof (struct artdata); 1865796c8dcSSimon Schubert 1875796c8dcSSimon Schubert abfd->tdata.aout_ar_data = (struct artdata *) bfd_zalloc (abfd, amt); 1885796c8dcSSimon Schubert if (bfd_ardata (abfd) == NULL) 1895796c8dcSSimon Schubert return FALSE; 1905796c8dcSSimon Schubert 1915796c8dcSSimon Schubert /* Already cleared by bfd_zalloc above. 1925796c8dcSSimon Schubert bfd_ardata (abfd)->cache = NULL; 1935796c8dcSSimon Schubert bfd_ardata (abfd)->archive_head = NULL; 1945796c8dcSSimon Schubert bfd_ardata (abfd)->symdefs = NULL; 1955796c8dcSSimon Schubert bfd_ardata (abfd)->extended_names = NULL; 1965796c8dcSSimon Schubert bfd_ardata (abfd)->extended_names_size = 0; 1975796c8dcSSimon Schubert bfd_ardata (abfd)->tdata = NULL; */ 1985796c8dcSSimon Schubert 1995796c8dcSSimon Schubert return TRUE; 2005796c8dcSSimon Schubert } 2015796c8dcSSimon Schubert 2025796c8dcSSimon Schubert /* 2035796c8dcSSimon Schubert FUNCTION 2045796c8dcSSimon Schubert bfd_get_next_mapent 2055796c8dcSSimon Schubert 2065796c8dcSSimon Schubert SYNOPSIS 2075796c8dcSSimon Schubert symindex bfd_get_next_mapent 2085796c8dcSSimon Schubert (bfd *abfd, symindex previous, carsym **sym); 2095796c8dcSSimon Schubert 2105796c8dcSSimon Schubert DESCRIPTION 2115796c8dcSSimon Schubert Step through archive @var{abfd}'s symbol table (if it 2125796c8dcSSimon Schubert has one). Successively update @var{sym} with the next symbol's 2135796c8dcSSimon Schubert information, returning that symbol's (internal) index into the 2145796c8dcSSimon Schubert symbol table. 2155796c8dcSSimon Schubert 2165796c8dcSSimon Schubert Supply <<BFD_NO_MORE_SYMBOLS>> as the @var{previous} entry to get 2175796c8dcSSimon Schubert the first one; returns <<BFD_NO_MORE_SYMBOLS>> when you've already 2185796c8dcSSimon Schubert got the last one. 2195796c8dcSSimon Schubert 2205796c8dcSSimon Schubert A <<carsym>> is a canonical archive symbol. The only 2215796c8dcSSimon Schubert user-visible element is its name, a null-terminated string. 2225796c8dcSSimon Schubert */ 2235796c8dcSSimon Schubert 2245796c8dcSSimon Schubert symindex 2255796c8dcSSimon Schubert bfd_get_next_mapent (bfd *abfd, symindex prev, carsym **entry) 2265796c8dcSSimon Schubert { 2275796c8dcSSimon Schubert if (!bfd_has_map (abfd)) 2285796c8dcSSimon Schubert { 2295796c8dcSSimon Schubert bfd_set_error (bfd_error_invalid_operation); 2305796c8dcSSimon Schubert return BFD_NO_MORE_SYMBOLS; 2315796c8dcSSimon Schubert } 2325796c8dcSSimon Schubert 2335796c8dcSSimon Schubert if (prev == BFD_NO_MORE_SYMBOLS) 2345796c8dcSSimon Schubert prev = 0; 2355796c8dcSSimon Schubert else 2365796c8dcSSimon Schubert ++prev; 2375796c8dcSSimon Schubert if (prev >= bfd_ardata (abfd)->symdef_count) 2385796c8dcSSimon Schubert return BFD_NO_MORE_SYMBOLS; 2395796c8dcSSimon Schubert 2405796c8dcSSimon Schubert *entry = (bfd_ardata (abfd)->symdefs + prev); 2415796c8dcSSimon Schubert return prev; 2425796c8dcSSimon Schubert } 2435796c8dcSSimon Schubert 2445796c8dcSSimon Schubert /* To be called by backends only. */ 2455796c8dcSSimon Schubert 2465796c8dcSSimon Schubert bfd * 2475796c8dcSSimon Schubert _bfd_create_empty_archive_element_shell (bfd *obfd) 2485796c8dcSSimon Schubert { 2495796c8dcSSimon Schubert return _bfd_new_bfd_contained_in (obfd); 2505796c8dcSSimon Schubert } 2515796c8dcSSimon Schubert 2525796c8dcSSimon Schubert /* 2535796c8dcSSimon Schubert FUNCTION 2545796c8dcSSimon Schubert bfd_set_archive_head 2555796c8dcSSimon Schubert 2565796c8dcSSimon Schubert SYNOPSIS 2575796c8dcSSimon Schubert bfd_boolean bfd_set_archive_head (bfd *output, bfd *new_head); 2585796c8dcSSimon Schubert 2595796c8dcSSimon Schubert DESCRIPTION 2605796c8dcSSimon Schubert Set the head of the chain of 2615796c8dcSSimon Schubert BFDs contained in the archive @var{output} to @var{new_head}. 2625796c8dcSSimon Schubert */ 2635796c8dcSSimon Schubert 2645796c8dcSSimon Schubert bfd_boolean 2655796c8dcSSimon Schubert bfd_set_archive_head (bfd *output_archive, bfd *new_head) 2665796c8dcSSimon Schubert { 2675796c8dcSSimon Schubert output_archive->archive_head = new_head; 2685796c8dcSSimon Schubert return TRUE; 2695796c8dcSSimon Schubert } 2705796c8dcSSimon Schubert 2715796c8dcSSimon Schubert bfd * 2725796c8dcSSimon Schubert _bfd_look_for_bfd_in_cache (bfd *arch_bfd, file_ptr filepos) 2735796c8dcSSimon Schubert { 2745796c8dcSSimon Schubert htab_t hash_table = bfd_ardata (arch_bfd)->cache; 2755796c8dcSSimon Schubert struct ar_cache m; 2765796c8dcSSimon Schubert m.ptr = filepos; 2775796c8dcSSimon Schubert 2785796c8dcSSimon Schubert if (hash_table) 2795796c8dcSSimon Schubert { 2805796c8dcSSimon Schubert struct ar_cache *entry = (struct ar_cache *) htab_find (hash_table, &m); 2815796c8dcSSimon Schubert if (!entry) 2825796c8dcSSimon Schubert return NULL; 2835796c8dcSSimon Schubert else 2845796c8dcSSimon Schubert return entry->arbfd; 2855796c8dcSSimon Schubert } 2865796c8dcSSimon Schubert else 2875796c8dcSSimon Schubert return NULL; 2885796c8dcSSimon Schubert } 2895796c8dcSSimon Schubert 2905796c8dcSSimon Schubert static hashval_t 2915796c8dcSSimon Schubert hash_file_ptr (const PTR p) 2925796c8dcSSimon Schubert { 2935796c8dcSSimon Schubert return (hashval_t) (((struct ar_cache *) p)->ptr); 2945796c8dcSSimon Schubert } 2955796c8dcSSimon Schubert 2965796c8dcSSimon Schubert /* Returns non-zero if P1 and P2 are equal. */ 2975796c8dcSSimon Schubert 2985796c8dcSSimon Schubert static int 2995796c8dcSSimon Schubert eq_file_ptr (const PTR p1, const PTR p2) 3005796c8dcSSimon Schubert { 3015796c8dcSSimon Schubert struct ar_cache *arc1 = (struct ar_cache *) p1; 3025796c8dcSSimon Schubert struct ar_cache *arc2 = (struct ar_cache *) p2; 3035796c8dcSSimon Schubert return arc1->ptr == arc2->ptr; 3045796c8dcSSimon Schubert } 3055796c8dcSSimon Schubert 306*cf7f2e2dSJohn Marino /* The calloc function doesn't always take size_t (e.g. on VMS) 307*cf7f2e2dSJohn Marino so wrap it to avoid a compile time warning. */ 308*cf7f2e2dSJohn Marino 309*cf7f2e2dSJohn Marino static void * 310*cf7f2e2dSJohn Marino _bfd_calloc_wrapper (size_t a, size_t b) 311*cf7f2e2dSJohn Marino { 312*cf7f2e2dSJohn Marino return calloc (a, b); 313*cf7f2e2dSJohn Marino } 314*cf7f2e2dSJohn Marino 3155796c8dcSSimon Schubert /* Kind of stupid to call cons for each one, but we don't do too many. */ 3165796c8dcSSimon Schubert 3175796c8dcSSimon Schubert bfd_boolean 3185796c8dcSSimon Schubert _bfd_add_bfd_to_archive_cache (bfd *arch_bfd, file_ptr filepos, bfd *new_elt) 3195796c8dcSSimon Schubert { 3205796c8dcSSimon Schubert struct ar_cache *cache; 3215796c8dcSSimon Schubert htab_t hash_table = bfd_ardata (arch_bfd)->cache; 3225796c8dcSSimon Schubert 3235796c8dcSSimon Schubert /* If the hash table hasn't been created, create it. */ 3245796c8dcSSimon Schubert if (hash_table == NULL) 3255796c8dcSSimon Schubert { 3265796c8dcSSimon Schubert hash_table = htab_create_alloc (16, hash_file_ptr, eq_file_ptr, 327*cf7f2e2dSJohn Marino NULL, _bfd_calloc_wrapper, free); 3285796c8dcSSimon Schubert if (hash_table == NULL) 3295796c8dcSSimon Schubert return FALSE; 3305796c8dcSSimon Schubert bfd_ardata (arch_bfd)->cache = hash_table; 3315796c8dcSSimon Schubert } 3325796c8dcSSimon Schubert 3335796c8dcSSimon Schubert /* Insert new_elt into the hash table by filepos. */ 3345796c8dcSSimon Schubert cache = (struct ar_cache *) bfd_zalloc (arch_bfd, sizeof (struct ar_cache)); 3355796c8dcSSimon Schubert cache->ptr = filepos; 3365796c8dcSSimon Schubert cache->arbfd = new_elt; 3375796c8dcSSimon Schubert *htab_find_slot (hash_table, (const void *) cache, INSERT) = cache; 3385796c8dcSSimon Schubert 3395796c8dcSSimon Schubert return TRUE; 3405796c8dcSSimon Schubert } 3415796c8dcSSimon Schubert 3425796c8dcSSimon Schubert static bfd * 3435796c8dcSSimon Schubert _bfd_find_nested_archive (bfd *arch_bfd, const char *filename) 3445796c8dcSSimon Schubert { 3455796c8dcSSimon Schubert bfd *abfd; 3465796c8dcSSimon Schubert 3475796c8dcSSimon Schubert for (abfd = arch_bfd->nested_archives; 3485796c8dcSSimon Schubert abfd != NULL; 3495796c8dcSSimon Schubert abfd = abfd->archive_next) 3505796c8dcSSimon Schubert { 3515796c8dcSSimon Schubert if (strcmp (filename, abfd->filename) == 0) 3525796c8dcSSimon Schubert return abfd; 3535796c8dcSSimon Schubert } 3545796c8dcSSimon Schubert abfd = bfd_openr (filename, NULL); 3555796c8dcSSimon Schubert if (abfd) 3565796c8dcSSimon Schubert { 3575796c8dcSSimon Schubert abfd->archive_next = arch_bfd->nested_archives; 3585796c8dcSSimon Schubert arch_bfd->nested_archives = abfd; 3595796c8dcSSimon Schubert } 3605796c8dcSSimon Schubert return abfd; 3615796c8dcSSimon Schubert } 3625796c8dcSSimon Schubert 3635796c8dcSSimon Schubert /* The name begins with space. Hence the rest of the name is an index into 3645796c8dcSSimon Schubert the string table. */ 3655796c8dcSSimon Schubert 3665796c8dcSSimon Schubert static char * 3675796c8dcSSimon Schubert get_extended_arelt_filename (bfd *arch, const char *name, file_ptr *originp) 3685796c8dcSSimon Schubert { 369*cf7f2e2dSJohn Marino unsigned long table_index = 0; 3705796c8dcSSimon Schubert const char *endp; 3715796c8dcSSimon Schubert 3725796c8dcSSimon Schubert /* Should extract string so that I can guarantee not to overflow into 3735796c8dcSSimon Schubert the next region, but I'm too lazy. */ 3745796c8dcSSimon Schubert errno = 0; 3755796c8dcSSimon Schubert /* Skip first char, which is '/' in SVR4 or ' ' in some other variants. */ 376*cf7f2e2dSJohn Marino table_index = strtol (name + 1, (char **) &endp, 10); 377*cf7f2e2dSJohn Marino if (errno != 0 || table_index >= bfd_ardata (arch)->extended_names_size) 3785796c8dcSSimon Schubert { 3795796c8dcSSimon Schubert bfd_set_error (bfd_error_malformed_archive); 3805796c8dcSSimon Schubert return NULL; 3815796c8dcSSimon Schubert } 3825796c8dcSSimon Schubert /* In a thin archive, a member of an archive-within-an-archive 3835796c8dcSSimon Schubert will have the offset in the inner archive encoded here. */ 3845796c8dcSSimon Schubert if (bfd_is_thin_archive (arch) && endp != NULL && *endp == ':') 3855796c8dcSSimon Schubert { 3865796c8dcSSimon Schubert file_ptr origin = strtol (endp + 1, NULL, 10); 3875796c8dcSSimon Schubert 3885796c8dcSSimon Schubert if (errno != 0) 3895796c8dcSSimon Schubert { 3905796c8dcSSimon Schubert bfd_set_error (bfd_error_malformed_archive); 3915796c8dcSSimon Schubert return NULL; 3925796c8dcSSimon Schubert } 3935796c8dcSSimon Schubert *originp = origin; 3945796c8dcSSimon Schubert } 3955796c8dcSSimon Schubert else 3965796c8dcSSimon Schubert *originp = 0; 3975796c8dcSSimon Schubert 398*cf7f2e2dSJohn Marino return bfd_ardata (arch)->extended_names + table_index; 3995796c8dcSSimon Schubert } 4005796c8dcSSimon Schubert 4015796c8dcSSimon Schubert /* This functions reads an arch header and returns an areltdata pointer, or 4025796c8dcSSimon Schubert NULL on error. 4035796c8dcSSimon Schubert 4045796c8dcSSimon Schubert Presumes the file pointer is already in the right place (ie pointing 4055796c8dcSSimon Schubert to the ar_hdr in the file). Moves the file pointer; on success it 4065796c8dcSSimon Schubert should be pointing to the front of the file contents; on failure it 4075796c8dcSSimon Schubert could have been moved arbitrarily. */ 4085796c8dcSSimon Schubert 4095796c8dcSSimon Schubert void * 4105796c8dcSSimon Schubert _bfd_generic_read_ar_hdr (bfd *abfd) 4115796c8dcSSimon Schubert { 4125796c8dcSSimon Schubert return _bfd_generic_read_ar_hdr_mag (abfd, NULL); 4135796c8dcSSimon Schubert } 4145796c8dcSSimon Schubert 4155796c8dcSSimon Schubert /* Alpha ECOFF uses an optional different ARFMAG value, so we have a 4165796c8dcSSimon Schubert variant of _bfd_generic_read_ar_hdr which accepts a magic string. */ 4175796c8dcSSimon Schubert 4185796c8dcSSimon Schubert void * 4195796c8dcSSimon Schubert _bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag) 4205796c8dcSSimon Schubert { 4215796c8dcSSimon Schubert struct ar_hdr hdr; 4225796c8dcSSimon Schubert char *hdrp = (char *) &hdr; 4235796c8dcSSimon Schubert size_t parsed_size; 4245796c8dcSSimon Schubert struct areltdata *ared; 4255796c8dcSSimon Schubert char *filename = NULL; 4265796c8dcSSimon Schubert bfd_size_type namelen = 0; 4275796c8dcSSimon Schubert bfd_size_type allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr); 4285796c8dcSSimon Schubert char *allocptr = 0; 4295796c8dcSSimon Schubert file_ptr origin = 0; 430*cf7f2e2dSJohn Marino unsigned int extra_size = 0; 4315796c8dcSSimon Schubert 4325796c8dcSSimon Schubert if (bfd_bread (hdrp, sizeof (struct ar_hdr), abfd) != sizeof (struct ar_hdr)) 4335796c8dcSSimon Schubert { 4345796c8dcSSimon Schubert if (bfd_get_error () != bfd_error_system_call) 4355796c8dcSSimon Schubert bfd_set_error (bfd_error_no_more_archived_files); 4365796c8dcSSimon Schubert return NULL; 4375796c8dcSSimon Schubert } 4385796c8dcSSimon Schubert if (strncmp (hdr.ar_fmag, ARFMAG, 2) != 0 4395796c8dcSSimon Schubert && (mag == NULL 4405796c8dcSSimon Schubert || strncmp (hdr.ar_fmag, mag, 2) != 0)) 4415796c8dcSSimon Schubert { 4425796c8dcSSimon Schubert bfd_set_error (bfd_error_malformed_archive); 4435796c8dcSSimon Schubert return NULL; 4445796c8dcSSimon Schubert } 4455796c8dcSSimon Schubert 4465796c8dcSSimon Schubert errno = 0; 4475796c8dcSSimon Schubert parsed_size = strtol (hdr.ar_size, NULL, 10); 4485796c8dcSSimon Schubert if (errno != 0) 4495796c8dcSSimon Schubert { 4505796c8dcSSimon Schubert bfd_set_error (bfd_error_malformed_archive); 4515796c8dcSSimon Schubert return NULL; 4525796c8dcSSimon Schubert } 4535796c8dcSSimon Schubert 4545796c8dcSSimon Schubert /* Extract the filename from the archive - there are two ways to 4555796c8dcSSimon Schubert specify an extended name table, either the first char of the 4565796c8dcSSimon Schubert name is a space, or it's a slash. */ 4575796c8dcSSimon Schubert if ((hdr.ar_name[0] == '/' 4585796c8dcSSimon Schubert || (hdr.ar_name[0] == ' ' 4595796c8dcSSimon Schubert && memchr (hdr.ar_name, '/', ar_maxnamelen (abfd)) == NULL)) 4605796c8dcSSimon Schubert && bfd_ardata (abfd)->extended_names != NULL) 4615796c8dcSSimon Schubert { 4625796c8dcSSimon Schubert filename = get_extended_arelt_filename (abfd, hdr.ar_name, &origin); 4635796c8dcSSimon Schubert if (filename == NULL) 4645796c8dcSSimon Schubert return NULL; 4655796c8dcSSimon Schubert } 466*cf7f2e2dSJohn Marino /* BSD4.4-style long filename. */ 467*cf7f2e2dSJohn Marino else if (is_bsd44_extended_name (hdr.ar_name)) 4685796c8dcSSimon Schubert { 4695796c8dcSSimon Schubert /* BSD-4.4 extended name */ 4705796c8dcSSimon Schubert namelen = atoi (&hdr.ar_name[3]); 4715796c8dcSSimon Schubert allocsize += namelen + 1; 4725796c8dcSSimon Schubert parsed_size -= namelen; 473*cf7f2e2dSJohn Marino extra_size = namelen; 4745796c8dcSSimon Schubert 4755796c8dcSSimon Schubert allocptr = (char *) bfd_zalloc (abfd, allocsize); 4765796c8dcSSimon Schubert if (allocptr == NULL) 4775796c8dcSSimon Schubert return NULL; 4785796c8dcSSimon Schubert filename = (allocptr 4795796c8dcSSimon Schubert + sizeof (struct areltdata) 4805796c8dcSSimon Schubert + sizeof (struct ar_hdr)); 4815796c8dcSSimon Schubert if (bfd_bread (filename, namelen, abfd) != namelen) 4825796c8dcSSimon Schubert { 4835796c8dcSSimon Schubert if (bfd_get_error () != bfd_error_system_call) 4845796c8dcSSimon Schubert bfd_set_error (bfd_error_no_more_archived_files); 4855796c8dcSSimon Schubert return NULL; 4865796c8dcSSimon Schubert } 4875796c8dcSSimon Schubert filename[namelen] = '\0'; 4885796c8dcSSimon Schubert } 4895796c8dcSSimon Schubert else 4905796c8dcSSimon Schubert { 4915796c8dcSSimon Schubert /* We judge the end of the name by looking for '/' or ' '. 4925796c8dcSSimon Schubert Note: The SYSV format (terminated by '/') allows embedded 4935796c8dcSSimon Schubert spaces, so only look for ' ' if we don't find '/'. */ 4945796c8dcSSimon Schubert 4955796c8dcSSimon Schubert char *e; 4965796c8dcSSimon Schubert e = (char *) memchr (hdr.ar_name, '\0', ar_maxnamelen (abfd)); 4975796c8dcSSimon Schubert if (e == NULL) 4985796c8dcSSimon Schubert { 4995796c8dcSSimon Schubert e = (char *) memchr (hdr.ar_name, '/', ar_maxnamelen (abfd)); 5005796c8dcSSimon Schubert if (e == NULL) 5015796c8dcSSimon Schubert e = (char *) memchr (hdr.ar_name, ' ', ar_maxnamelen (abfd)); 5025796c8dcSSimon Schubert } 5035796c8dcSSimon Schubert 5045796c8dcSSimon Schubert if (e != NULL) 5055796c8dcSSimon Schubert namelen = e - hdr.ar_name; 5065796c8dcSSimon Schubert else 5075796c8dcSSimon Schubert { 5085796c8dcSSimon Schubert /* If we didn't find a termination character, then the name 5095796c8dcSSimon Schubert must be the entire field. */ 5105796c8dcSSimon Schubert namelen = ar_maxnamelen (abfd); 5115796c8dcSSimon Schubert } 5125796c8dcSSimon Schubert 5135796c8dcSSimon Schubert allocsize += namelen + 1; 5145796c8dcSSimon Schubert } 5155796c8dcSSimon Schubert 5165796c8dcSSimon Schubert if (!allocptr) 5175796c8dcSSimon Schubert { 5185796c8dcSSimon Schubert allocptr = (char *) bfd_zalloc (abfd, allocsize); 5195796c8dcSSimon Schubert if (allocptr == NULL) 5205796c8dcSSimon Schubert return NULL; 5215796c8dcSSimon Schubert } 5225796c8dcSSimon Schubert 5235796c8dcSSimon Schubert ared = (struct areltdata *) allocptr; 5245796c8dcSSimon Schubert 5255796c8dcSSimon Schubert ared->arch_header = allocptr + sizeof (struct areltdata); 5265796c8dcSSimon Schubert memcpy (ared->arch_header, &hdr, sizeof (struct ar_hdr)); 5275796c8dcSSimon Schubert ared->parsed_size = parsed_size; 528*cf7f2e2dSJohn Marino ared->extra_size = extra_size; 5295796c8dcSSimon Schubert ared->origin = origin; 5305796c8dcSSimon Schubert 5315796c8dcSSimon Schubert if (filename != NULL) 5325796c8dcSSimon Schubert ared->filename = filename; 5335796c8dcSSimon Schubert else 5345796c8dcSSimon Schubert { 5355796c8dcSSimon Schubert ared->filename = allocptr + (sizeof (struct areltdata) + 5365796c8dcSSimon Schubert sizeof (struct ar_hdr)); 5375796c8dcSSimon Schubert if (namelen) 5385796c8dcSSimon Schubert memcpy (ared->filename, hdr.ar_name, namelen); 5395796c8dcSSimon Schubert ared->filename[namelen] = '\0'; 5405796c8dcSSimon Schubert } 5415796c8dcSSimon Schubert 5425796c8dcSSimon Schubert return ared; 5435796c8dcSSimon Schubert } 5445796c8dcSSimon Schubert 5455796c8dcSSimon Schubert /* Append the relative pathname for a member of the thin archive 5465796c8dcSSimon Schubert to the pathname of the directory containing the archive. */ 5475796c8dcSSimon Schubert 548*cf7f2e2dSJohn Marino char * 549*cf7f2e2dSJohn Marino _bfd_append_relative_path (bfd *arch, char *elt_name) 5505796c8dcSSimon Schubert { 5515796c8dcSSimon Schubert const char *arch_name = arch->filename; 5525796c8dcSSimon Schubert const char *base_name = lbasename (arch_name); 5535796c8dcSSimon Schubert size_t prefix_len; 5545796c8dcSSimon Schubert char *filename; 5555796c8dcSSimon Schubert 5565796c8dcSSimon Schubert if (base_name == arch_name) 5575796c8dcSSimon Schubert return elt_name; 5585796c8dcSSimon Schubert 5595796c8dcSSimon Schubert prefix_len = base_name - arch_name; 5605796c8dcSSimon Schubert filename = (char *) bfd_alloc (arch, prefix_len + strlen (elt_name) + 1); 5615796c8dcSSimon Schubert if (filename == NULL) 5625796c8dcSSimon Schubert return NULL; 5635796c8dcSSimon Schubert 5645796c8dcSSimon Schubert strncpy (filename, arch_name, prefix_len); 5655796c8dcSSimon Schubert strcpy (filename + prefix_len, elt_name); 5665796c8dcSSimon Schubert return filename; 5675796c8dcSSimon Schubert } 5685796c8dcSSimon Schubert 5695796c8dcSSimon Schubert /* This is an internal function; it's mainly used when indexing 5705796c8dcSSimon Schubert through the archive symbol table, but also used to get the next 5715796c8dcSSimon Schubert element, since it handles the bookkeeping so nicely for us. */ 5725796c8dcSSimon Schubert 5735796c8dcSSimon Schubert bfd * 5745796c8dcSSimon Schubert _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos) 5755796c8dcSSimon Schubert { 5765796c8dcSSimon Schubert struct areltdata *new_areldata; 5775796c8dcSSimon Schubert bfd *n_nfd; 5785796c8dcSSimon Schubert char *filename; 5795796c8dcSSimon Schubert 5805796c8dcSSimon Schubert if (archive->my_archive) 5815796c8dcSSimon Schubert { 5825796c8dcSSimon Schubert filepos += archive->origin; 5835796c8dcSSimon Schubert archive = archive->my_archive; 5845796c8dcSSimon Schubert } 5855796c8dcSSimon Schubert 5865796c8dcSSimon Schubert n_nfd = _bfd_look_for_bfd_in_cache (archive, filepos); 5875796c8dcSSimon Schubert if (n_nfd) 5885796c8dcSSimon Schubert return n_nfd; 5895796c8dcSSimon Schubert 5905796c8dcSSimon Schubert if (0 > bfd_seek (archive, filepos, SEEK_SET)) 5915796c8dcSSimon Schubert return NULL; 5925796c8dcSSimon Schubert 5935796c8dcSSimon Schubert if ((new_areldata = (struct areltdata *) _bfd_read_ar_hdr (archive)) == NULL) 5945796c8dcSSimon Schubert return NULL; 5955796c8dcSSimon Schubert 5965796c8dcSSimon Schubert filename = new_areldata->filename; 5975796c8dcSSimon Schubert 5985796c8dcSSimon Schubert if (bfd_is_thin_archive (archive)) 5995796c8dcSSimon Schubert { 6005796c8dcSSimon Schubert /* This is a proxy entry for an external file. */ 6015796c8dcSSimon Schubert if (! IS_ABSOLUTE_PATH (filename)) 6025796c8dcSSimon Schubert { 603*cf7f2e2dSJohn Marino filename = _bfd_append_relative_path (archive, filename); 6045796c8dcSSimon Schubert if (filename == NULL) 6055796c8dcSSimon Schubert return NULL; 6065796c8dcSSimon Schubert } 6075796c8dcSSimon Schubert 6085796c8dcSSimon Schubert if (new_areldata->origin > 0) 6095796c8dcSSimon Schubert { 6105796c8dcSSimon Schubert /* This proxy entry refers to an element of a nested archive. 6115796c8dcSSimon Schubert Locate the member of that archive and return a bfd for it. */ 6125796c8dcSSimon Schubert bfd *ext_arch = _bfd_find_nested_archive (archive, filename); 6135796c8dcSSimon Schubert 6145796c8dcSSimon Schubert if (ext_arch == NULL 6155796c8dcSSimon Schubert || ! bfd_check_format (ext_arch, bfd_archive)) 6165796c8dcSSimon Schubert { 6175796c8dcSSimon Schubert bfd_release (archive, new_areldata); 6185796c8dcSSimon Schubert return NULL; 6195796c8dcSSimon Schubert } 6205796c8dcSSimon Schubert n_nfd = _bfd_get_elt_at_filepos (ext_arch, new_areldata->origin); 6215796c8dcSSimon Schubert if (n_nfd == NULL) 6225796c8dcSSimon Schubert { 6235796c8dcSSimon Schubert bfd_release (archive, new_areldata); 6245796c8dcSSimon Schubert return NULL; 6255796c8dcSSimon Schubert } 6265796c8dcSSimon Schubert n_nfd->proxy_origin = bfd_tell (archive); 6275796c8dcSSimon Schubert return n_nfd; 6285796c8dcSSimon Schubert } 6295796c8dcSSimon Schubert /* It's not an element of a nested archive; 6305796c8dcSSimon Schubert open the external file as a bfd. */ 6315796c8dcSSimon Schubert n_nfd = bfd_openr (filename, NULL); 6325796c8dcSSimon Schubert } 6335796c8dcSSimon Schubert else 6345796c8dcSSimon Schubert { 6355796c8dcSSimon Schubert n_nfd = _bfd_create_empty_archive_element_shell (archive); 6365796c8dcSSimon Schubert } 6375796c8dcSSimon Schubert 6385796c8dcSSimon Schubert if (n_nfd == NULL) 6395796c8dcSSimon Schubert { 6405796c8dcSSimon Schubert bfd_release (archive, new_areldata); 6415796c8dcSSimon Schubert return NULL; 6425796c8dcSSimon Schubert } 6435796c8dcSSimon Schubert 6445796c8dcSSimon Schubert n_nfd->proxy_origin = bfd_tell (archive); 6455796c8dcSSimon Schubert 6465796c8dcSSimon Schubert if (bfd_is_thin_archive (archive)) 6475796c8dcSSimon Schubert { 6485796c8dcSSimon Schubert n_nfd->origin = 0; 6495796c8dcSSimon Schubert } 6505796c8dcSSimon Schubert else 6515796c8dcSSimon Schubert { 6525796c8dcSSimon Schubert n_nfd->origin = n_nfd->proxy_origin; 6535796c8dcSSimon Schubert n_nfd->filename = filename; 6545796c8dcSSimon Schubert } 6555796c8dcSSimon Schubert 6565796c8dcSSimon Schubert n_nfd->arelt_data = new_areldata; 6575796c8dcSSimon Schubert 6585796c8dcSSimon Schubert if (_bfd_add_bfd_to_archive_cache (archive, filepos, n_nfd)) 6595796c8dcSSimon Schubert return n_nfd; 6605796c8dcSSimon Schubert 6615796c8dcSSimon Schubert /* Huh? */ 6625796c8dcSSimon Schubert /* FIXME: n_nfd isn't allocated in the archive's memory pool. 6635796c8dcSSimon Schubert If we reach this point, I think bfd_release will abort. */ 6645796c8dcSSimon Schubert bfd_release (archive, n_nfd); 6655796c8dcSSimon Schubert bfd_release (archive, new_areldata); 6665796c8dcSSimon Schubert return NULL; 6675796c8dcSSimon Schubert } 6685796c8dcSSimon Schubert 6695796c8dcSSimon Schubert /* Return the BFD which is referenced by the symbol in ABFD indexed by 670*cf7f2e2dSJohn Marino SYM_INDEX. SYM_INDEX should have been returned by bfd_get_next_mapent. */ 6715796c8dcSSimon Schubert 6725796c8dcSSimon Schubert bfd * 673*cf7f2e2dSJohn Marino _bfd_generic_get_elt_at_index (bfd *abfd, symindex sym_index) 6745796c8dcSSimon Schubert { 6755796c8dcSSimon Schubert carsym *entry; 6765796c8dcSSimon Schubert 677*cf7f2e2dSJohn Marino entry = bfd_ardata (abfd)->symdefs + sym_index; 6785796c8dcSSimon Schubert return _bfd_get_elt_at_filepos (abfd, entry->file_offset); 6795796c8dcSSimon Schubert } 6805796c8dcSSimon Schubert 6815796c8dcSSimon Schubert /* 6825796c8dcSSimon Schubert FUNCTION 6835796c8dcSSimon Schubert bfd_openr_next_archived_file 6845796c8dcSSimon Schubert 6855796c8dcSSimon Schubert SYNOPSIS 6865796c8dcSSimon Schubert bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous); 6875796c8dcSSimon Schubert 6885796c8dcSSimon Schubert DESCRIPTION 6895796c8dcSSimon Schubert Provided a BFD, @var{archive}, containing an archive and NULL, open 6905796c8dcSSimon Schubert an input BFD on the first contained element and returns that. 6915796c8dcSSimon Schubert Subsequent calls should pass 6925796c8dcSSimon Schubert the archive and the previous return value to return a created 6935796c8dcSSimon Schubert BFD to the next contained element. NULL is returned when there 6945796c8dcSSimon Schubert are no more. 6955796c8dcSSimon Schubert */ 6965796c8dcSSimon Schubert 6975796c8dcSSimon Schubert bfd * 6985796c8dcSSimon Schubert bfd_openr_next_archived_file (bfd *archive, bfd *last_file) 6995796c8dcSSimon Schubert { 7005796c8dcSSimon Schubert if ((bfd_get_format (archive) != bfd_archive) 7015796c8dcSSimon Schubert || (archive->direction == write_direction)) 7025796c8dcSSimon Schubert { 7035796c8dcSSimon Schubert bfd_set_error (bfd_error_invalid_operation); 7045796c8dcSSimon Schubert return NULL; 7055796c8dcSSimon Schubert } 7065796c8dcSSimon Schubert 7075796c8dcSSimon Schubert return BFD_SEND (archive, 7085796c8dcSSimon Schubert openr_next_archived_file, (archive, last_file)); 7095796c8dcSSimon Schubert } 7105796c8dcSSimon Schubert 7115796c8dcSSimon Schubert bfd * 7125796c8dcSSimon Schubert bfd_generic_openr_next_archived_file (bfd *archive, bfd *last_file) 7135796c8dcSSimon Schubert { 7145796c8dcSSimon Schubert file_ptr filestart; 7155796c8dcSSimon Schubert 7165796c8dcSSimon Schubert if (!last_file) 7175796c8dcSSimon Schubert filestart = bfd_ardata (archive)->first_file_filepos; 7185796c8dcSSimon Schubert else 7195796c8dcSSimon Schubert { 7205796c8dcSSimon Schubert unsigned int size = arelt_size (last_file); 7215796c8dcSSimon Schubert filestart = last_file->proxy_origin; 7225796c8dcSSimon Schubert if (! bfd_is_thin_archive (archive)) 7235796c8dcSSimon Schubert filestart += size; 7245796c8dcSSimon Schubert if (archive->my_archive) 7255796c8dcSSimon Schubert filestart -= archive->origin; 7265796c8dcSSimon Schubert /* Pad to an even boundary... 7275796c8dcSSimon Schubert Note that last_file->origin can be odd in the case of 7285796c8dcSSimon Schubert BSD-4.4-style element with a long odd size. */ 7295796c8dcSSimon Schubert filestart += filestart % 2; 7305796c8dcSSimon Schubert } 7315796c8dcSSimon Schubert 7325796c8dcSSimon Schubert return _bfd_get_elt_at_filepos (archive, filestart); 7335796c8dcSSimon Schubert } 7345796c8dcSSimon Schubert 7355796c8dcSSimon Schubert const bfd_target * 7365796c8dcSSimon Schubert bfd_generic_archive_p (bfd *abfd) 7375796c8dcSSimon Schubert { 7385796c8dcSSimon Schubert struct artdata *tdata_hold; 7395796c8dcSSimon Schubert char armag[SARMAG + 1]; 7405796c8dcSSimon Schubert bfd_size_type amt; 7415796c8dcSSimon Schubert 7425796c8dcSSimon Schubert if (bfd_bread (armag, SARMAG, abfd) != SARMAG) 7435796c8dcSSimon Schubert { 7445796c8dcSSimon Schubert if (bfd_get_error () != bfd_error_system_call) 7455796c8dcSSimon Schubert bfd_set_error (bfd_error_wrong_format); 7465796c8dcSSimon Schubert return NULL; 7475796c8dcSSimon Schubert } 7485796c8dcSSimon Schubert 7495796c8dcSSimon Schubert bfd_is_thin_archive (abfd) = (strncmp (armag, ARMAGT, SARMAG) == 0); 7505796c8dcSSimon Schubert 7515796c8dcSSimon Schubert if (strncmp (armag, ARMAG, SARMAG) != 0 7525796c8dcSSimon Schubert && strncmp (armag, ARMAGB, SARMAG) != 0 7535796c8dcSSimon Schubert && ! bfd_is_thin_archive (abfd)) 7545796c8dcSSimon Schubert return 0; 7555796c8dcSSimon Schubert 7565796c8dcSSimon Schubert tdata_hold = bfd_ardata (abfd); 7575796c8dcSSimon Schubert 7585796c8dcSSimon Schubert amt = sizeof (struct artdata); 7595796c8dcSSimon Schubert bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt); 7605796c8dcSSimon Schubert if (bfd_ardata (abfd) == NULL) 7615796c8dcSSimon Schubert { 7625796c8dcSSimon Schubert bfd_ardata (abfd) = tdata_hold; 7635796c8dcSSimon Schubert return NULL; 7645796c8dcSSimon Schubert } 7655796c8dcSSimon Schubert 7665796c8dcSSimon Schubert bfd_ardata (abfd)->first_file_filepos = SARMAG; 7675796c8dcSSimon Schubert /* Cleared by bfd_zalloc above. 7685796c8dcSSimon Schubert bfd_ardata (abfd)->cache = NULL; 7695796c8dcSSimon Schubert bfd_ardata (abfd)->archive_head = NULL; 7705796c8dcSSimon Schubert bfd_ardata (abfd)->symdefs = NULL; 7715796c8dcSSimon Schubert bfd_ardata (abfd)->extended_names = NULL; 7725796c8dcSSimon Schubert bfd_ardata (abfd)->extended_names_size = 0; 7735796c8dcSSimon Schubert bfd_ardata (abfd)->tdata = NULL; */ 7745796c8dcSSimon Schubert 7755796c8dcSSimon Schubert if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd)) 7765796c8dcSSimon Schubert || !BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd))) 7775796c8dcSSimon Schubert { 7785796c8dcSSimon Schubert if (bfd_get_error () != bfd_error_system_call) 7795796c8dcSSimon Schubert bfd_set_error (bfd_error_wrong_format); 7805796c8dcSSimon Schubert bfd_release (abfd, bfd_ardata (abfd)); 7815796c8dcSSimon Schubert bfd_ardata (abfd) = tdata_hold; 7825796c8dcSSimon Schubert return NULL; 7835796c8dcSSimon Schubert } 7845796c8dcSSimon Schubert 7855796c8dcSSimon Schubert if (bfd_has_map (abfd)) 7865796c8dcSSimon Schubert { 7875796c8dcSSimon Schubert bfd *first; 7885796c8dcSSimon Schubert 7895796c8dcSSimon Schubert /* This archive has a map, so we may presume that the contents 7905796c8dcSSimon Schubert are object files. Make sure that if the first file in the 7915796c8dcSSimon Schubert archive can be recognized as an object file, it is for this 7925796c8dcSSimon Schubert target. If not, assume that this is the wrong format. If 7935796c8dcSSimon Schubert the first file is not an object file, somebody is doing 7945796c8dcSSimon Schubert something weird, and we permit it so that ar -t will work. 7955796c8dcSSimon Schubert 7965796c8dcSSimon Schubert This is done because any normal format will recognize any 7975796c8dcSSimon Schubert normal archive, regardless of the format of the object files. 7985796c8dcSSimon Schubert We do accept an empty archive. */ 7995796c8dcSSimon Schubert 8005796c8dcSSimon Schubert first = bfd_openr_next_archived_file (abfd, NULL); 8015796c8dcSSimon Schubert if (first != NULL) 8025796c8dcSSimon Schubert { 8035796c8dcSSimon Schubert first->target_defaulted = FALSE; 8045796c8dcSSimon Schubert if (bfd_check_format (first, bfd_object) 8055796c8dcSSimon Schubert && first->xvec != abfd->xvec) 8065796c8dcSSimon Schubert { 8075796c8dcSSimon Schubert bfd_set_error (bfd_error_wrong_object_format); 8085796c8dcSSimon Schubert bfd_ardata (abfd) = tdata_hold; 8095796c8dcSSimon Schubert return NULL; 8105796c8dcSSimon Schubert } 8115796c8dcSSimon Schubert /* And we ought to close `first' here too. */ 8125796c8dcSSimon Schubert } 8135796c8dcSSimon Schubert } 8145796c8dcSSimon Schubert 8155796c8dcSSimon Schubert return abfd->xvec; 8165796c8dcSSimon Schubert } 8175796c8dcSSimon Schubert 8185796c8dcSSimon Schubert /* Some constants for a 32 bit BSD archive structure. We do not 8195796c8dcSSimon Schubert support 64 bit archives presently; so far as I know, none actually 8205796c8dcSSimon Schubert exist. Supporting them would require changing these constants, and 8215796c8dcSSimon Schubert changing some H_GET_32 to H_GET_64. */ 8225796c8dcSSimon Schubert 8235796c8dcSSimon Schubert /* The size of an external symdef structure. */ 8245796c8dcSSimon Schubert #define BSD_SYMDEF_SIZE 8 8255796c8dcSSimon Schubert 8265796c8dcSSimon Schubert /* The offset from the start of a symdef structure to the file offset. */ 8275796c8dcSSimon Schubert #define BSD_SYMDEF_OFFSET_SIZE 4 8285796c8dcSSimon Schubert 8295796c8dcSSimon Schubert /* The size of the symdef count. */ 8305796c8dcSSimon Schubert #define BSD_SYMDEF_COUNT_SIZE 4 8315796c8dcSSimon Schubert 8325796c8dcSSimon Schubert /* The size of the string count. */ 8335796c8dcSSimon Schubert #define BSD_STRING_COUNT_SIZE 4 8345796c8dcSSimon Schubert 8355796c8dcSSimon Schubert /* Read a BSD-style archive symbol table. Returns FALSE on error, 8365796c8dcSSimon Schubert TRUE otherwise. */ 8375796c8dcSSimon Schubert 8385796c8dcSSimon Schubert static bfd_boolean 8395796c8dcSSimon Schubert do_slurp_bsd_armap (bfd *abfd) 8405796c8dcSSimon Schubert { 8415796c8dcSSimon Schubert struct areltdata *mapdata; 8425796c8dcSSimon Schubert unsigned int counter; 8435796c8dcSSimon Schubert bfd_byte *raw_armap, *rbase; 8445796c8dcSSimon Schubert struct artdata *ardata = bfd_ardata (abfd); 8455796c8dcSSimon Schubert char *stringbase; 8465796c8dcSSimon Schubert bfd_size_type parsed_size, amt; 8475796c8dcSSimon Schubert carsym *set; 8485796c8dcSSimon Schubert 8495796c8dcSSimon Schubert mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); 8505796c8dcSSimon Schubert if (mapdata == NULL) 8515796c8dcSSimon Schubert return FALSE; 8525796c8dcSSimon Schubert parsed_size = mapdata->parsed_size; 8535796c8dcSSimon Schubert bfd_release (abfd, mapdata); /* Don't need it any more. */ 8545796c8dcSSimon Schubert 8555796c8dcSSimon Schubert raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size); 8565796c8dcSSimon Schubert if (raw_armap == NULL) 8575796c8dcSSimon Schubert return FALSE; 8585796c8dcSSimon Schubert 8595796c8dcSSimon Schubert if (bfd_bread (raw_armap, parsed_size, abfd) != parsed_size) 8605796c8dcSSimon Schubert { 8615796c8dcSSimon Schubert if (bfd_get_error () != bfd_error_system_call) 8625796c8dcSSimon Schubert bfd_set_error (bfd_error_malformed_archive); 8635796c8dcSSimon Schubert byebye: 8645796c8dcSSimon Schubert bfd_release (abfd, raw_armap); 8655796c8dcSSimon Schubert return FALSE; 8665796c8dcSSimon Schubert } 8675796c8dcSSimon Schubert 8685796c8dcSSimon Schubert ardata->symdef_count = H_GET_32 (abfd, raw_armap) / BSD_SYMDEF_SIZE; 8695796c8dcSSimon Schubert 8705796c8dcSSimon Schubert if (ardata->symdef_count * BSD_SYMDEF_SIZE > 8715796c8dcSSimon Schubert parsed_size - BSD_SYMDEF_COUNT_SIZE) 8725796c8dcSSimon Schubert { 8735796c8dcSSimon Schubert /* Probably we're using the wrong byte ordering. */ 8745796c8dcSSimon Schubert bfd_set_error (bfd_error_wrong_format); 8755796c8dcSSimon Schubert goto byebye; 8765796c8dcSSimon Schubert } 8775796c8dcSSimon Schubert 8785796c8dcSSimon Schubert ardata->cache = 0; 8795796c8dcSSimon Schubert rbase = raw_armap + BSD_SYMDEF_COUNT_SIZE; 8805796c8dcSSimon Schubert stringbase = ((char *) rbase 8815796c8dcSSimon Schubert + ardata->symdef_count * BSD_SYMDEF_SIZE 8825796c8dcSSimon Schubert + BSD_STRING_COUNT_SIZE); 8835796c8dcSSimon Schubert amt = ardata->symdef_count * sizeof (carsym); 8845796c8dcSSimon Schubert ardata->symdefs = (struct carsym *) bfd_alloc (abfd, amt); 8855796c8dcSSimon Schubert if (!ardata->symdefs) 8865796c8dcSSimon Schubert return FALSE; 8875796c8dcSSimon Schubert 8885796c8dcSSimon Schubert for (counter = 0, set = ardata->symdefs; 8895796c8dcSSimon Schubert counter < ardata->symdef_count; 8905796c8dcSSimon Schubert counter++, set++, rbase += BSD_SYMDEF_SIZE) 8915796c8dcSSimon Schubert { 8925796c8dcSSimon Schubert set->name = H_GET_32 (abfd, rbase) + stringbase; 8935796c8dcSSimon Schubert set->file_offset = H_GET_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE); 8945796c8dcSSimon Schubert } 8955796c8dcSSimon Schubert 8965796c8dcSSimon Schubert ardata->first_file_filepos = bfd_tell (abfd); 8975796c8dcSSimon Schubert /* Pad to an even boundary if you have to. */ 8985796c8dcSSimon Schubert ardata->first_file_filepos += (ardata->first_file_filepos) % 2; 8995796c8dcSSimon Schubert /* FIXME, we should provide some way to free raw_ardata when 9005796c8dcSSimon Schubert we are done using the strings from it. For now, it seems 9015796c8dcSSimon Schubert to be allocated on an objalloc anyway... */ 9025796c8dcSSimon Schubert bfd_has_map (abfd) = TRUE; 9035796c8dcSSimon Schubert return TRUE; 9045796c8dcSSimon Schubert } 9055796c8dcSSimon Schubert 9065796c8dcSSimon Schubert /* Read a COFF archive symbol table. Returns FALSE on error, TRUE 9075796c8dcSSimon Schubert otherwise. */ 9085796c8dcSSimon Schubert 9095796c8dcSSimon Schubert static bfd_boolean 9105796c8dcSSimon Schubert do_slurp_coff_armap (bfd *abfd) 9115796c8dcSSimon Schubert { 9125796c8dcSSimon Schubert struct areltdata *mapdata; 9135796c8dcSSimon Schubert int *raw_armap, *rawptr; 9145796c8dcSSimon Schubert struct artdata *ardata = bfd_ardata (abfd); 9155796c8dcSSimon Schubert char *stringbase; 9165796c8dcSSimon Schubert bfd_size_type stringsize; 9175796c8dcSSimon Schubert unsigned int parsed_size; 9185796c8dcSSimon Schubert carsym *carsyms; 9195796c8dcSSimon Schubert bfd_size_type nsymz; /* Number of symbols in armap. */ 9205796c8dcSSimon Schubert bfd_vma (*swap) (const void *); 9215796c8dcSSimon Schubert char int_buf[sizeof (long)]; 9225796c8dcSSimon Schubert bfd_size_type carsym_size, ptrsize; 9235796c8dcSSimon Schubert unsigned int i; 9245796c8dcSSimon Schubert 9255796c8dcSSimon Schubert mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); 9265796c8dcSSimon Schubert if (mapdata == NULL) 9275796c8dcSSimon Schubert return FALSE; 9285796c8dcSSimon Schubert parsed_size = mapdata->parsed_size; 9295796c8dcSSimon Schubert bfd_release (abfd, mapdata); /* Don't need it any more. */ 9305796c8dcSSimon Schubert 9315796c8dcSSimon Schubert if (bfd_bread (int_buf, 4, abfd) != 4) 9325796c8dcSSimon Schubert { 9335796c8dcSSimon Schubert if (bfd_get_error () != bfd_error_system_call) 9345796c8dcSSimon Schubert bfd_set_error (bfd_error_malformed_archive); 9355796c8dcSSimon Schubert return FALSE; 9365796c8dcSSimon Schubert } 9375796c8dcSSimon Schubert /* It seems that all numeric information in a coff archive is always 9385796c8dcSSimon Schubert in big endian format, nomatter the host or target. */ 9395796c8dcSSimon Schubert swap = bfd_getb32; 9405796c8dcSSimon Schubert nsymz = bfd_getb32 (int_buf); 9415796c8dcSSimon Schubert stringsize = parsed_size - (4 * nsymz) - 4; 9425796c8dcSSimon Schubert 9435796c8dcSSimon Schubert /* ... except that some archive formats are broken, and it may be our 9445796c8dcSSimon Schubert fault - the i960 little endian coff sometimes has big and sometimes 9455796c8dcSSimon Schubert little, because our tools changed. Here's a horrible hack to clean 9465796c8dcSSimon Schubert up the crap. */ 9475796c8dcSSimon Schubert 9485796c8dcSSimon Schubert if (stringsize > 0xfffff 9495796c8dcSSimon Schubert && bfd_get_arch (abfd) == bfd_arch_i960 9505796c8dcSSimon Schubert && bfd_get_flavour (abfd) == bfd_target_coff_flavour) 9515796c8dcSSimon Schubert { 9525796c8dcSSimon Schubert /* This looks dangerous, let's do it the other way around. */ 9535796c8dcSSimon Schubert nsymz = bfd_getl32 (int_buf); 9545796c8dcSSimon Schubert stringsize = parsed_size - (4 * nsymz) - 4; 9555796c8dcSSimon Schubert swap = bfd_getl32; 9565796c8dcSSimon Schubert } 9575796c8dcSSimon Schubert 9585796c8dcSSimon Schubert /* The coff armap must be read sequentially. So we construct a 9595796c8dcSSimon Schubert bsd-style one in core all at once, for simplicity. */ 9605796c8dcSSimon Schubert 9615796c8dcSSimon Schubert if (nsymz > ~ (bfd_size_type) 0 / sizeof (carsym)) 9625796c8dcSSimon Schubert return FALSE; 9635796c8dcSSimon Schubert 9645796c8dcSSimon Schubert carsym_size = (nsymz * sizeof (carsym)); 9655796c8dcSSimon Schubert ptrsize = (4 * nsymz); 9665796c8dcSSimon Schubert 9675796c8dcSSimon Schubert if (carsym_size + stringsize + 1 <= carsym_size) 9685796c8dcSSimon Schubert return FALSE; 9695796c8dcSSimon Schubert 9705796c8dcSSimon Schubert ardata->symdefs = (struct carsym *) bfd_zalloc (abfd, 9715796c8dcSSimon Schubert carsym_size + stringsize + 1); 9725796c8dcSSimon Schubert if (ardata->symdefs == NULL) 9735796c8dcSSimon Schubert return FALSE; 9745796c8dcSSimon Schubert carsyms = ardata->symdefs; 9755796c8dcSSimon Schubert stringbase = ((char *) ardata->symdefs) + carsym_size; 9765796c8dcSSimon Schubert 9775796c8dcSSimon Schubert /* Allocate and read in the raw offsets. */ 9785796c8dcSSimon Schubert raw_armap = (int *) bfd_alloc (abfd, ptrsize); 9795796c8dcSSimon Schubert if (raw_armap == NULL) 9805796c8dcSSimon Schubert goto release_symdefs; 9815796c8dcSSimon Schubert if (bfd_bread (raw_armap, ptrsize, abfd) != ptrsize 9825796c8dcSSimon Schubert || (bfd_bread (stringbase, stringsize, abfd) != stringsize)) 9835796c8dcSSimon Schubert { 9845796c8dcSSimon Schubert if (bfd_get_error () != bfd_error_system_call) 9855796c8dcSSimon Schubert bfd_set_error (bfd_error_malformed_archive); 9865796c8dcSSimon Schubert goto release_raw_armap; 9875796c8dcSSimon Schubert } 9885796c8dcSSimon Schubert 9895796c8dcSSimon Schubert /* OK, build the carsyms. */ 9905796c8dcSSimon Schubert for (i = 0; i < nsymz; i++) 9915796c8dcSSimon Schubert { 9925796c8dcSSimon Schubert rawptr = raw_armap + i; 9935796c8dcSSimon Schubert carsyms->file_offset = swap ((bfd_byte *) rawptr); 9945796c8dcSSimon Schubert carsyms->name = stringbase; 9955796c8dcSSimon Schubert stringbase += strlen (stringbase) + 1; 9965796c8dcSSimon Schubert carsyms++; 9975796c8dcSSimon Schubert } 9985796c8dcSSimon Schubert *stringbase = 0; 9995796c8dcSSimon Schubert 10005796c8dcSSimon Schubert ardata->symdef_count = nsymz; 10015796c8dcSSimon Schubert ardata->first_file_filepos = bfd_tell (abfd); 10025796c8dcSSimon Schubert /* Pad to an even boundary if you have to. */ 10035796c8dcSSimon Schubert ardata->first_file_filepos += (ardata->first_file_filepos) % 2; 10045796c8dcSSimon Schubert 10055796c8dcSSimon Schubert bfd_has_map (abfd) = TRUE; 10065796c8dcSSimon Schubert bfd_release (abfd, raw_armap); 10075796c8dcSSimon Schubert 10085796c8dcSSimon Schubert /* Check for a second archive header (as used by PE). */ 10095796c8dcSSimon Schubert { 10105796c8dcSSimon Schubert struct areltdata *tmp; 10115796c8dcSSimon Schubert 10125796c8dcSSimon Schubert bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET); 10135796c8dcSSimon Schubert tmp = (struct areltdata *) _bfd_read_ar_hdr (abfd); 10145796c8dcSSimon Schubert if (tmp != NULL) 10155796c8dcSSimon Schubert { 10165796c8dcSSimon Schubert if (tmp->arch_header[0] == '/' 10175796c8dcSSimon Schubert && tmp->arch_header[1] == ' ') 10185796c8dcSSimon Schubert { 10195796c8dcSSimon Schubert ardata->first_file_filepos += 10205796c8dcSSimon Schubert (tmp->parsed_size + sizeof (struct ar_hdr) + 1) & ~(unsigned) 1; 10215796c8dcSSimon Schubert } 10225796c8dcSSimon Schubert bfd_release (abfd, tmp); 10235796c8dcSSimon Schubert } 10245796c8dcSSimon Schubert } 10255796c8dcSSimon Schubert 10265796c8dcSSimon Schubert return TRUE; 10275796c8dcSSimon Schubert 10285796c8dcSSimon Schubert release_raw_armap: 10295796c8dcSSimon Schubert bfd_release (abfd, raw_armap); 10305796c8dcSSimon Schubert release_symdefs: 10315796c8dcSSimon Schubert bfd_release (abfd, (ardata)->symdefs); 10325796c8dcSSimon Schubert return FALSE; 10335796c8dcSSimon Schubert } 10345796c8dcSSimon Schubert 10355796c8dcSSimon Schubert /* This routine can handle either coff-style or bsd-style armaps 10365796c8dcSSimon Schubert (archive symbol table). Returns FALSE on error, TRUE otherwise */ 10375796c8dcSSimon Schubert 10385796c8dcSSimon Schubert bfd_boolean 10395796c8dcSSimon Schubert bfd_slurp_armap (bfd *abfd) 10405796c8dcSSimon Schubert { 10415796c8dcSSimon Schubert char nextname[17]; 10425796c8dcSSimon Schubert int i = bfd_bread (nextname, 16, abfd); 10435796c8dcSSimon Schubert 10445796c8dcSSimon Schubert if (i == 0) 10455796c8dcSSimon Schubert return TRUE; 10465796c8dcSSimon Schubert if (i != 16) 10475796c8dcSSimon Schubert return FALSE; 10485796c8dcSSimon Schubert 10495796c8dcSSimon Schubert if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0) 10505796c8dcSSimon Schubert return FALSE; 10515796c8dcSSimon Schubert 10525796c8dcSSimon Schubert if (CONST_STRNEQ (nextname, "__.SYMDEF ") 10535796c8dcSSimon Schubert || CONST_STRNEQ (nextname, "__.SYMDEF/ ")) /* Old Linux archives. */ 10545796c8dcSSimon Schubert return do_slurp_bsd_armap (abfd); 10555796c8dcSSimon Schubert else if (CONST_STRNEQ (nextname, "/ ")) 10565796c8dcSSimon Schubert return do_slurp_coff_armap (abfd); 10575796c8dcSSimon Schubert else if (CONST_STRNEQ (nextname, "/SYM64/ ")) 10585796c8dcSSimon Schubert { 10595796c8dcSSimon Schubert /* 64bit ELF (Irix 6) archive. */ 10605796c8dcSSimon Schubert #ifdef BFD64 10615796c8dcSSimon Schubert extern bfd_boolean bfd_elf64_archive_slurp_armap (bfd *); 10625796c8dcSSimon Schubert return bfd_elf64_archive_slurp_armap (abfd); 10635796c8dcSSimon Schubert #else 10645796c8dcSSimon Schubert bfd_set_error (bfd_error_wrong_format); 10655796c8dcSSimon Schubert return FALSE; 10665796c8dcSSimon Schubert #endif 10675796c8dcSSimon Schubert } 1068*cf7f2e2dSJohn Marino else if (CONST_STRNEQ (nextname, "#1/20 ")) 1069*cf7f2e2dSJohn Marino { 1070*cf7f2e2dSJohn Marino /* Mach-O has a special name for armap when the map is sorted by name. 1071*cf7f2e2dSJohn Marino However because this name has a space it is slightly more difficult 1072*cf7f2e2dSJohn Marino to check it. */ 1073*cf7f2e2dSJohn Marino struct ar_hdr hdr; 1074*cf7f2e2dSJohn Marino char extname[21]; 1075*cf7f2e2dSJohn Marino 1076*cf7f2e2dSJohn Marino if (bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr)) 1077*cf7f2e2dSJohn Marino return FALSE; 1078*cf7f2e2dSJohn Marino /* Read the extended name. We know its length. */ 1079*cf7f2e2dSJohn Marino if (bfd_bread (extname, 20, abfd) != 20) 1080*cf7f2e2dSJohn Marino return FALSE; 1081*cf7f2e2dSJohn Marino if (bfd_seek (abfd, (file_ptr) -(sizeof (hdr) + 20), SEEK_CUR) != 0) 1082*cf7f2e2dSJohn Marino return FALSE; 1083*cf7f2e2dSJohn Marino if (CONST_STRNEQ (extname, "__.SYMDEF SORTED") 1084*cf7f2e2dSJohn Marino || CONST_STRNEQ (extname, "__.SYMDEF")) 1085*cf7f2e2dSJohn Marino return do_slurp_bsd_armap (abfd); 1086*cf7f2e2dSJohn Marino } 10875796c8dcSSimon Schubert 10885796c8dcSSimon Schubert bfd_has_map (abfd) = FALSE; 10895796c8dcSSimon Schubert return TRUE; 10905796c8dcSSimon Schubert } 10915796c8dcSSimon Schubert 10925796c8dcSSimon Schubert /* Returns FALSE on error, TRUE otherwise. */ 10935796c8dcSSimon Schubert /* Flavor 2 of a bsd armap, similar to bfd_slurp_bsd_armap except the 10945796c8dcSSimon Schubert header is in a slightly different order and the map name is '/'. 10955796c8dcSSimon Schubert This flavour is used by hp300hpux. */ 10965796c8dcSSimon Schubert 10975796c8dcSSimon Schubert #define HPUX_SYMDEF_COUNT_SIZE 2 10985796c8dcSSimon Schubert 10995796c8dcSSimon Schubert bfd_boolean 11005796c8dcSSimon Schubert bfd_slurp_bsd_armap_f2 (bfd *abfd) 11015796c8dcSSimon Schubert { 11025796c8dcSSimon Schubert struct areltdata *mapdata; 11035796c8dcSSimon Schubert char nextname[17]; 11045796c8dcSSimon Schubert unsigned int counter; 11055796c8dcSSimon Schubert bfd_byte *raw_armap, *rbase; 11065796c8dcSSimon Schubert struct artdata *ardata = bfd_ardata (abfd); 11075796c8dcSSimon Schubert char *stringbase; 11085796c8dcSSimon Schubert unsigned int stringsize; 11095796c8dcSSimon Schubert bfd_size_type amt; 11105796c8dcSSimon Schubert carsym *set; 11115796c8dcSSimon Schubert int i = bfd_bread (nextname, 16, abfd); 11125796c8dcSSimon Schubert 11135796c8dcSSimon Schubert if (i == 0) 11145796c8dcSSimon Schubert return TRUE; 11155796c8dcSSimon Schubert if (i != 16) 11165796c8dcSSimon Schubert return FALSE; 11175796c8dcSSimon Schubert 11185796c8dcSSimon Schubert /* The archive has at least 16 bytes in it. */ 11195796c8dcSSimon Schubert if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0) 11205796c8dcSSimon Schubert return FALSE; 11215796c8dcSSimon Schubert 11225796c8dcSSimon Schubert if (CONST_STRNEQ (nextname, "__.SYMDEF ") 11235796c8dcSSimon Schubert || CONST_STRNEQ (nextname, "__.SYMDEF/ ")) /* Old Linux archives. */ 11245796c8dcSSimon Schubert return do_slurp_bsd_armap (abfd); 11255796c8dcSSimon Schubert 11265796c8dcSSimon Schubert if (! CONST_STRNEQ (nextname, "/ ")) 11275796c8dcSSimon Schubert { 11285796c8dcSSimon Schubert bfd_has_map (abfd) = FALSE; 11295796c8dcSSimon Schubert return TRUE; 11305796c8dcSSimon Schubert } 11315796c8dcSSimon Schubert 11325796c8dcSSimon Schubert mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); 11335796c8dcSSimon Schubert if (mapdata == NULL) 11345796c8dcSSimon Schubert return FALSE; 11355796c8dcSSimon Schubert 11365796c8dcSSimon Schubert amt = mapdata->parsed_size; 11375796c8dcSSimon Schubert raw_armap = (bfd_byte *) bfd_zalloc (abfd, amt); 11385796c8dcSSimon Schubert if (raw_armap == NULL) 11395796c8dcSSimon Schubert { 11405796c8dcSSimon Schubert byebye: 11415796c8dcSSimon Schubert bfd_release (abfd, mapdata); 11425796c8dcSSimon Schubert return FALSE; 11435796c8dcSSimon Schubert } 11445796c8dcSSimon Schubert 11455796c8dcSSimon Schubert if (bfd_bread (raw_armap, amt, abfd) != amt) 11465796c8dcSSimon Schubert { 11475796c8dcSSimon Schubert if (bfd_get_error () != bfd_error_system_call) 11485796c8dcSSimon Schubert bfd_set_error (bfd_error_malformed_archive); 11495796c8dcSSimon Schubert byebyebye: 11505796c8dcSSimon Schubert bfd_release (abfd, raw_armap); 11515796c8dcSSimon Schubert goto byebye; 11525796c8dcSSimon Schubert } 11535796c8dcSSimon Schubert 11545796c8dcSSimon Schubert ardata->symdef_count = H_GET_16 (abfd, raw_armap); 11555796c8dcSSimon Schubert 11565796c8dcSSimon Schubert if (ardata->symdef_count * BSD_SYMDEF_SIZE 11575796c8dcSSimon Schubert > mapdata->parsed_size - HPUX_SYMDEF_COUNT_SIZE) 11585796c8dcSSimon Schubert { 11595796c8dcSSimon Schubert /* Probably we're using the wrong byte ordering. */ 11605796c8dcSSimon Schubert bfd_set_error (bfd_error_wrong_format); 11615796c8dcSSimon Schubert goto byebyebye; 11625796c8dcSSimon Schubert } 11635796c8dcSSimon Schubert 11645796c8dcSSimon Schubert ardata->cache = 0; 11655796c8dcSSimon Schubert 11665796c8dcSSimon Schubert stringsize = H_GET_32 (abfd, raw_armap + HPUX_SYMDEF_COUNT_SIZE); 11675796c8dcSSimon Schubert /* Skip sym count and string sz. */ 11685796c8dcSSimon Schubert stringbase = ((char *) raw_armap 11695796c8dcSSimon Schubert + HPUX_SYMDEF_COUNT_SIZE 11705796c8dcSSimon Schubert + BSD_STRING_COUNT_SIZE); 11715796c8dcSSimon Schubert rbase = (bfd_byte *) stringbase + stringsize; 11725796c8dcSSimon Schubert amt = ardata->symdef_count * BSD_SYMDEF_SIZE; 11735796c8dcSSimon Schubert ardata->symdefs = (struct carsym *) bfd_alloc (abfd, amt); 11745796c8dcSSimon Schubert if (!ardata->symdefs) 11755796c8dcSSimon Schubert return FALSE; 11765796c8dcSSimon Schubert 11775796c8dcSSimon Schubert for (counter = 0, set = ardata->symdefs; 11785796c8dcSSimon Schubert counter < ardata->symdef_count; 11795796c8dcSSimon Schubert counter++, set++, rbase += BSD_SYMDEF_SIZE) 11805796c8dcSSimon Schubert { 11815796c8dcSSimon Schubert set->name = H_GET_32 (abfd, rbase) + stringbase; 11825796c8dcSSimon Schubert set->file_offset = H_GET_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE); 11835796c8dcSSimon Schubert } 11845796c8dcSSimon Schubert 11855796c8dcSSimon Schubert ardata->first_file_filepos = bfd_tell (abfd); 11865796c8dcSSimon Schubert /* Pad to an even boundary if you have to. */ 11875796c8dcSSimon Schubert ardata->first_file_filepos += (ardata->first_file_filepos) % 2; 11885796c8dcSSimon Schubert /* FIXME, we should provide some way to free raw_ardata when 11895796c8dcSSimon Schubert we are done using the strings from it. For now, it seems 11905796c8dcSSimon Schubert to be allocated on an objalloc anyway... */ 11915796c8dcSSimon Schubert bfd_has_map (abfd) = TRUE; 11925796c8dcSSimon Schubert return TRUE; 11935796c8dcSSimon Schubert } 11945796c8dcSSimon Schubert 11955796c8dcSSimon Schubert /** Extended name table. 11965796c8dcSSimon Schubert 11975796c8dcSSimon Schubert Normally archives support only 14-character filenames. 11985796c8dcSSimon Schubert 11995796c8dcSSimon Schubert Intel has extended the format: longer names are stored in a special 12005796c8dcSSimon Schubert element (the first in the archive, or second if there is an armap); 12015796c8dcSSimon Schubert the name in the ar_hdr is replaced by <space><index into filename 12025796c8dcSSimon Schubert element>. Index is the P.R. of an int (decimal). Data General have 12035796c8dcSSimon Schubert extended the format by using the prefix // for the special element. */ 12045796c8dcSSimon Schubert 12055796c8dcSSimon Schubert /* Returns FALSE on error, TRUE otherwise. */ 12065796c8dcSSimon Schubert 12075796c8dcSSimon Schubert bfd_boolean 12085796c8dcSSimon Schubert _bfd_slurp_extended_name_table (bfd *abfd) 12095796c8dcSSimon Schubert { 12105796c8dcSSimon Schubert char nextname[17]; 12115796c8dcSSimon Schubert struct areltdata *namedata; 12125796c8dcSSimon Schubert bfd_size_type amt; 12135796c8dcSSimon Schubert 12145796c8dcSSimon Schubert /* FIXME: Formatting sucks here, and in case of failure of BFD_READ, 12155796c8dcSSimon Schubert we probably don't want to return TRUE. */ 12165796c8dcSSimon Schubert bfd_seek (abfd, bfd_ardata (abfd)->first_file_filepos, SEEK_SET); 12175796c8dcSSimon Schubert if (bfd_bread (nextname, 16, abfd) == 16) 12185796c8dcSSimon Schubert { 12195796c8dcSSimon Schubert if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0) 12205796c8dcSSimon Schubert return FALSE; 12215796c8dcSSimon Schubert 12225796c8dcSSimon Schubert if (! CONST_STRNEQ (nextname, "ARFILENAMES/ ") 12235796c8dcSSimon Schubert && ! CONST_STRNEQ (nextname, "// ")) 12245796c8dcSSimon Schubert { 12255796c8dcSSimon Schubert bfd_ardata (abfd)->extended_names = NULL; 12265796c8dcSSimon Schubert bfd_ardata (abfd)->extended_names_size = 0; 12275796c8dcSSimon Schubert return TRUE; 12285796c8dcSSimon Schubert } 12295796c8dcSSimon Schubert 12305796c8dcSSimon Schubert namedata = (struct areltdata *) _bfd_read_ar_hdr (abfd); 12315796c8dcSSimon Schubert if (namedata == NULL) 12325796c8dcSSimon Schubert return FALSE; 12335796c8dcSSimon Schubert 12345796c8dcSSimon Schubert amt = namedata->parsed_size; 12355796c8dcSSimon Schubert if (amt + 1 == 0) 12365796c8dcSSimon Schubert goto byebye; 12375796c8dcSSimon Schubert 12385796c8dcSSimon Schubert bfd_ardata (abfd)->extended_names_size = amt; 12395796c8dcSSimon Schubert bfd_ardata (abfd)->extended_names = (char *) bfd_zalloc (abfd, amt + 1); 12405796c8dcSSimon Schubert if (bfd_ardata (abfd)->extended_names == NULL) 12415796c8dcSSimon Schubert { 12425796c8dcSSimon Schubert byebye: 12435796c8dcSSimon Schubert bfd_release (abfd, namedata); 12445796c8dcSSimon Schubert return FALSE; 12455796c8dcSSimon Schubert } 12465796c8dcSSimon Schubert 12475796c8dcSSimon Schubert if (bfd_bread (bfd_ardata (abfd)->extended_names, amt, abfd) != amt) 12485796c8dcSSimon Schubert { 12495796c8dcSSimon Schubert if (bfd_get_error () != bfd_error_system_call) 12505796c8dcSSimon Schubert bfd_set_error (bfd_error_malformed_archive); 12515796c8dcSSimon Schubert bfd_release (abfd, (bfd_ardata (abfd)->extended_names)); 12525796c8dcSSimon Schubert bfd_ardata (abfd)->extended_names = NULL; 12535796c8dcSSimon Schubert goto byebye; 12545796c8dcSSimon Schubert } 12555796c8dcSSimon Schubert 12565796c8dcSSimon Schubert /* Since the archive is supposed to be printable if it contains 12575796c8dcSSimon Schubert text, the entries in the list are newline-padded, not null 12585796c8dcSSimon Schubert padded. In SVR4-style archives, the names also have a 12595796c8dcSSimon Schubert trailing '/'. DOS/NT created archive often have \ in them 12605796c8dcSSimon Schubert We'll fix all problems here.. */ 12615796c8dcSSimon Schubert { 12625796c8dcSSimon Schubert char *ext_names = bfd_ardata (abfd)->extended_names; 12635796c8dcSSimon Schubert char *temp = ext_names; 12645796c8dcSSimon Schubert char *limit = temp + namedata->parsed_size; 12655796c8dcSSimon Schubert for (; temp < limit; ++temp) 12665796c8dcSSimon Schubert { 12675796c8dcSSimon Schubert if (*temp == ARFMAG[1]) 12685796c8dcSSimon Schubert temp[temp > ext_names && temp[-1] == '/' ? -1 : 0] = '\0'; 12695796c8dcSSimon Schubert if (*temp == '\\') 12705796c8dcSSimon Schubert *temp = '/'; 12715796c8dcSSimon Schubert } 12725796c8dcSSimon Schubert *limit = '\0'; 12735796c8dcSSimon Schubert } 12745796c8dcSSimon Schubert 12755796c8dcSSimon Schubert /* Pad to an even boundary if you have to. */ 12765796c8dcSSimon Schubert bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd); 12775796c8dcSSimon Schubert bfd_ardata (abfd)->first_file_filepos += 12785796c8dcSSimon Schubert (bfd_ardata (abfd)->first_file_filepos) % 2; 12795796c8dcSSimon Schubert 12805796c8dcSSimon Schubert /* FIXME, we can't release namedata here because it was allocated 12815796c8dcSSimon Schubert below extended_names on the objalloc... */ 12825796c8dcSSimon Schubert } 12835796c8dcSSimon Schubert return TRUE; 12845796c8dcSSimon Schubert } 12855796c8dcSSimon Schubert 12865796c8dcSSimon Schubert #ifdef VMS 12875796c8dcSSimon Schubert 12885796c8dcSSimon Schubert /* Return a copy of the stuff in the filename between any :]> and a 12895796c8dcSSimon Schubert semicolon. */ 12905796c8dcSSimon Schubert 12915796c8dcSSimon Schubert static const char * 12925796c8dcSSimon Schubert normalize (bfd *abfd, const char *file) 12935796c8dcSSimon Schubert { 12945796c8dcSSimon Schubert const char *first; 12955796c8dcSSimon Schubert const char *last; 12965796c8dcSSimon Schubert char *copy; 12975796c8dcSSimon Schubert 12985796c8dcSSimon Schubert first = file + strlen (file) - 1; 12995796c8dcSSimon Schubert last = first + 1; 13005796c8dcSSimon Schubert 13015796c8dcSSimon Schubert while (first != file) 13025796c8dcSSimon Schubert { 13035796c8dcSSimon Schubert if (*first == ';') 13045796c8dcSSimon Schubert last = first; 13055796c8dcSSimon Schubert if (*first == ':' || *first == ']' || *first == '>') 13065796c8dcSSimon Schubert { 13075796c8dcSSimon Schubert first++; 13085796c8dcSSimon Schubert break; 13095796c8dcSSimon Schubert } 13105796c8dcSSimon Schubert first--; 13115796c8dcSSimon Schubert } 13125796c8dcSSimon Schubert 13135796c8dcSSimon Schubert copy = bfd_alloc (abfd, last - first + 1); 13145796c8dcSSimon Schubert if (copy == NULL) 13155796c8dcSSimon Schubert return NULL; 13165796c8dcSSimon Schubert 13175796c8dcSSimon Schubert memcpy (copy, first, last - first); 13185796c8dcSSimon Schubert copy[last - first] = 0; 13195796c8dcSSimon Schubert 13205796c8dcSSimon Schubert return copy; 13215796c8dcSSimon Schubert } 13225796c8dcSSimon Schubert 13235796c8dcSSimon Schubert #else 13245796c8dcSSimon Schubert static const char * 13255796c8dcSSimon Schubert normalize (bfd *abfd ATTRIBUTE_UNUSED, const char *file) 13265796c8dcSSimon Schubert { 1327*cf7f2e2dSJohn Marino return lbasename (file); 13285796c8dcSSimon Schubert } 13295796c8dcSSimon Schubert #endif 13305796c8dcSSimon Schubert 13315796c8dcSSimon Schubert /* Adjust a relative path name based on the reference path. */ 13325796c8dcSSimon Schubert 13335796c8dcSSimon Schubert static const char * 13345796c8dcSSimon Schubert adjust_relative_path (const char * path, const char * ref_path) 13355796c8dcSSimon Schubert { 13365796c8dcSSimon Schubert static char *pathbuf = NULL; 13375796c8dcSSimon Schubert static int pathbuf_len = 0; 13385796c8dcSSimon Schubert const char *pathp = path; 13395796c8dcSSimon Schubert const char *refp = ref_path; 13405796c8dcSSimon Schubert int element_count = 0; 13415796c8dcSSimon Schubert int len; 13425796c8dcSSimon Schubert char *newp; 13435796c8dcSSimon Schubert 13445796c8dcSSimon Schubert /* Remove common leading path elements. */ 13455796c8dcSSimon Schubert for (;;) 13465796c8dcSSimon Schubert { 13475796c8dcSSimon Schubert const char *e1 = pathp; 13485796c8dcSSimon Schubert const char *e2 = refp; 13495796c8dcSSimon Schubert 13505796c8dcSSimon Schubert while (*e1 && ! IS_DIR_SEPARATOR (*e1)) 13515796c8dcSSimon Schubert ++e1; 13525796c8dcSSimon Schubert while (*e2 && ! IS_DIR_SEPARATOR (*e2)) 13535796c8dcSSimon Schubert ++e2; 13545796c8dcSSimon Schubert if (*e1 == '\0' || *e2 == '\0' || e1 - pathp != e2 - refp 13555796c8dcSSimon Schubert || strncmp (pathp, refp, e1 - pathp) != 0) 13565796c8dcSSimon Schubert break; 13575796c8dcSSimon Schubert pathp = e1 + 1; 13585796c8dcSSimon Schubert refp = e2 + 1; 13595796c8dcSSimon Schubert } 13605796c8dcSSimon Schubert 13615796c8dcSSimon Schubert /* For each leading path element in the reference path, 13625796c8dcSSimon Schubert insert "../" into the path. */ 13635796c8dcSSimon Schubert for (; *refp; ++refp) 13645796c8dcSSimon Schubert if (IS_DIR_SEPARATOR (*refp)) 13655796c8dcSSimon Schubert ++element_count; 13665796c8dcSSimon Schubert len = 3 * element_count + strlen (path) + 1; 13675796c8dcSSimon Schubert 13685796c8dcSSimon Schubert if (len > pathbuf_len) 13695796c8dcSSimon Schubert { 13705796c8dcSSimon Schubert if (pathbuf != NULL) 13715796c8dcSSimon Schubert free (pathbuf); 13725796c8dcSSimon Schubert pathbuf_len = 0; 13735796c8dcSSimon Schubert pathbuf = (char *) bfd_malloc (len); 13745796c8dcSSimon Schubert if (pathbuf == NULL) 13755796c8dcSSimon Schubert return path; 13765796c8dcSSimon Schubert pathbuf_len = len; 13775796c8dcSSimon Schubert } 13785796c8dcSSimon Schubert 13795796c8dcSSimon Schubert newp = pathbuf; 13805796c8dcSSimon Schubert while (element_count-- > 0) 13815796c8dcSSimon Schubert { 13825796c8dcSSimon Schubert /* FIXME: Support Windows style path separators as well. */ 13835796c8dcSSimon Schubert strcpy (newp, "../"); 13845796c8dcSSimon Schubert newp += 3; 13855796c8dcSSimon Schubert } 13865796c8dcSSimon Schubert strcpy (newp, pathp); 13875796c8dcSSimon Schubert 13885796c8dcSSimon Schubert return pathbuf; 13895796c8dcSSimon Schubert } 13905796c8dcSSimon Schubert 13915796c8dcSSimon Schubert /* Build a BFD style extended name table. */ 13925796c8dcSSimon Schubert 13935796c8dcSSimon Schubert bfd_boolean 13945796c8dcSSimon Schubert _bfd_archive_bsd_construct_extended_name_table (bfd *abfd, 13955796c8dcSSimon Schubert char **tabloc, 13965796c8dcSSimon Schubert bfd_size_type *tablen, 13975796c8dcSSimon Schubert const char **name) 13985796c8dcSSimon Schubert { 13995796c8dcSSimon Schubert *name = "ARFILENAMES/"; 14005796c8dcSSimon Schubert return _bfd_construct_extended_name_table (abfd, FALSE, tabloc, tablen); 14015796c8dcSSimon Schubert } 14025796c8dcSSimon Schubert 14035796c8dcSSimon Schubert /* Build an SVR4 style extended name table. */ 14045796c8dcSSimon Schubert 14055796c8dcSSimon Schubert bfd_boolean 14065796c8dcSSimon Schubert _bfd_archive_coff_construct_extended_name_table (bfd *abfd, 14075796c8dcSSimon Schubert char **tabloc, 14085796c8dcSSimon Schubert bfd_size_type *tablen, 14095796c8dcSSimon Schubert const char **name) 14105796c8dcSSimon Schubert { 14115796c8dcSSimon Schubert *name = "//"; 14125796c8dcSSimon Schubert return _bfd_construct_extended_name_table (abfd, TRUE, tabloc, tablen); 14135796c8dcSSimon Schubert } 14145796c8dcSSimon Schubert 14155796c8dcSSimon Schubert /* Follows archive_head and produces an extended name table if 14165796c8dcSSimon Schubert necessary. Returns (in tabloc) a pointer to an extended name 14175796c8dcSSimon Schubert table, and in tablen the length of the table. If it makes an entry 14185796c8dcSSimon Schubert it clobbers the filename so that the element may be written without 14195796c8dcSSimon Schubert further massage. Returns TRUE if it ran successfully, FALSE if 14205796c8dcSSimon Schubert something went wrong. A successful return may still involve a 14215796c8dcSSimon Schubert zero-length tablen! */ 14225796c8dcSSimon Schubert 14235796c8dcSSimon Schubert bfd_boolean 14245796c8dcSSimon Schubert _bfd_construct_extended_name_table (bfd *abfd, 14255796c8dcSSimon Schubert bfd_boolean trailing_slash, 14265796c8dcSSimon Schubert char **tabloc, 14275796c8dcSSimon Schubert bfd_size_type *tablen) 14285796c8dcSSimon Schubert { 14295796c8dcSSimon Schubert unsigned int maxname = abfd->xvec->ar_max_namelen; 14305796c8dcSSimon Schubert bfd_size_type total_namelen = 0; 14315796c8dcSSimon Schubert bfd *current; 14325796c8dcSSimon Schubert char *strptr; 14335796c8dcSSimon Schubert const char *last_filename; 14345796c8dcSSimon Schubert long last_stroff; 14355796c8dcSSimon Schubert 14365796c8dcSSimon Schubert *tablen = 0; 14375796c8dcSSimon Schubert last_filename = NULL; 14385796c8dcSSimon Schubert 14395796c8dcSSimon Schubert /* Figure out how long the table should be. */ 14405796c8dcSSimon Schubert for (current = abfd->archive_head; 14415796c8dcSSimon Schubert current != NULL; 14425796c8dcSSimon Schubert current = current->archive_next) 14435796c8dcSSimon Schubert { 14445796c8dcSSimon Schubert const char *normal; 14455796c8dcSSimon Schubert unsigned int thislen; 14465796c8dcSSimon Schubert 14475796c8dcSSimon Schubert if (bfd_is_thin_archive (abfd)) 14485796c8dcSSimon Schubert { 14495796c8dcSSimon Schubert const char *filename = current->filename; 14505796c8dcSSimon Schubert 14515796c8dcSSimon Schubert /* If the element being added is a member of another archive 14525796c8dcSSimon Schubert (i.e., we are flattening), use the containing archive's name. */ 14535796c8dcSSimon Schubert if (current->my_archive 14545796c8dcSSimon Schubert && ! bfd_is_thin_archive (current->my_archive)) 14555796c8dcSSimon Schubert filename = current->my_archive->filename; 14565796c8dcSSimon Schubert 14575796c8dcSSimon Schubert /* If the path is the same as the previous path seen, 14585796c8dcSSimon Schubert reuse it. This can happen when flattening a thin 14595796c8dcSSimon Schubert archive that contains other archives. */ 14605796c8dcSSimon Schubert if (last_filename && strcmp (last_filename, filename) == 0) 14615796c8dcSSimon Schubert continue; 14625796c8dcSSimon Schubert 14635796c8dcSSimon Schubert last_filename = filename; 14645796c8dcSSimon Schubert 14655796c8dcSSimon Schubert /* If the path is relative, adjust it relative to 14665796c8dcSSimon Schubert the containing archive. */ 14675796c8dcSSimon Schubert if (! IS_ABSOLUTE_PATH (filename) 14685796c8dcSSimon Schubert && ! IS_ABSOLUTE_PATH (abfd->filename)) 14695796c8dcSSimon Schubert normal = adjust_relative_path (filename, abfd->filename); 14705796c8dcSSimon Schubert else 14715796c8dcSSimon Schubert normal = filename; 14725796c8dcSSimon Schubert 14735796c8dcSSimon Schubert /* In a thin archive, always store the full pathname 14745796c8dcSSimon Schubert in the extended name table. */ 14755796c8dcSSimon Schubert total_namelen += strlen (normal) + 1; 14765796c8dcSSimon Schubert if (trailing_slash) 14775796c8dcSSimon Schubert /* Leave room for trailing slash. */ 14785796c8dcSSimon Schubert ++total_namelen; 14795796c8dcSSimon Schubert 14805796c8dcSSimon Schubert continue; 14815796c8dcSSimon Schubert } 14825796c8dcSSimon Schubert 14835796c8dcSSimon Schubert normal = normalize (current, current->filename); 14845796c8dcSSimon Schubert if (normal == NULL) 14855796c8dcSSimon Schubert return FALSE; 14865796c8dcSSimon Schubert 14875796c8dcSSimon Schubert thislen = strlen (normal); 14885796c8dcSSimon Schubert 14895796c8dcSSimon Schubert if (thislen > maxname 14905796c8dcSSimon Schubert && (bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0) 14915796c8dcSSimon Schubert thislen = maxname; 14925796c8dcSSimon Schubert 14935796c8dcSSimon Schubert if (thislen > maxname) 14945796c8dcSSimon Schubert { 14955796c8dcSSimon Schubert /* Add one to leave room for \n. */ 14965796c8dcSSimon Schubert total_namelen += thislen + 1; 14975796c8dcSSimon Schubert if (trailing_slash) 14985796c8dcSSimon Schubert { 14995796c8dcSSimon Schubert /* Leave room for trailing slash. */ 15005796c8dcSSimon Schubert ++total_namelen; 15015796c8dcSSimon Schubert } 15025796c8dcSSimon Schubert } 15035796c8dcSSimon Schubert else 15045796c8dcSSimon Schubert { 15055796c8dcSSimon Schubert struct ar_hdr *hdr = arch_hdr (current); 15065796c8dcSSimon Schubert if (strncmp (normal, hdr->ar_name, thislen) != 0 15075796c8dcSSimon Schubert || (thislen < sizeof hdr->ar_name 15085796c8dcSSimon Schubert && hdr->ar_name[thislen] != ar_padchar (current))) 15095796c8dcSSimon Schubert { 15105796c8dcSSimon Schubert /* Must have been using extended format even though it 15115796c8dcSSimon Schubert didn't need to. Fix it to use normal format. */ 15125796c8dcSSimon Schubert memcpy (hdr->ar_name, normal, thislen); 15135796c8dcSSimon Schubert if (thislen < maxname 15145796c8dcSSimon Schubert || (thislen == maxname && thislen < sizeof hdr->ar_name)) 15155796c8dcSSimon Schubert hdr->ar_name[thislen] = ar_padchar (current); 15165796c8dcSSimon Schubert } 15175796c8dcSSimon Schubert } 15185796c8dcSSimon Schubert } 15195796c8dcSSimon Schubert 15205796c8dcSSimon Schubert if (total_namelen == 0) 15215796c8dcSSimon Schubert return TRUE; 15225796c8dcSSimon Schubert 15235796c8dcSSimon Schubert *tabloc = (char *) bfd_zalloc (abfd, total_namelen); 15245796c8dcSSimon Schubert if (*tabloc == NULL) 15255796c8dcSSimon Schubert return FALSE; 15265796c8dcSSimon Schubert 15275796c8dcSSimon Schubert *tablen = total_namelen; 15285796c8dcSSimon Schubert strptr = *tabloc; 15295796c8dcSSimon Schubert 15305796c8dcSSimon Schubert last_filename = NULL; 15315796c8dcSSimon Schubert last_stroff = 0; 15325796c8dcSSimon Schubert 15335796c8dcSSimon Schubert for (current = abfd->archive_head; 15345796c8dcSSimon Schubert current != NULL; 15355796c8dcSSimon Schubert current = current->archive_next) 15365796c8dcSSimon Schubert { 15375796c8dcSSimon Schubert const char *normal; 15385796c8dcSSimon Schubert unsigned int thislen; 15395796c8dcSSimon Schubert long stroff; 15405796c8dcSSimon Schubert const char *filename = current->filename; 15415796c8dcSSimon Schubert 15425796c8dcSSimon Schubert if (bfd_is_thin_archive (abfd)) 15435796c8dcSSimon Schubert { 15445796c8dcSSimon Schubert /* If the element being added is a member of another archive 15455796c8dcSSimon Schubert (i.e., we are flattening), use the containing archive's name. */ 15465796c8dcSSimon Schubert if (current->my_archive 15475796c8dcSSimon Schubert && ! bfd_is_thin_archive (current->my_archive)) 15485796c8dcSSimon Schubert filename = current->my_archive->filename; 15495796c8dcSSimon Schubert /* If the path is the same as the previous path seen, 15505796c8dcSSimon Schubert reuse it. This can happen when flattening a thin 15515796c8dcSSimon Schubert archive that contains other archives. 15525796c8dcSSimon Schubert If the path is relative, adjust it relative to 15535796c8dcSSimon Schubert the containing archive. */ 15545796c8dcSSimon Schubert if (last_filename && strcmp (last_filename, filename) == 0) 15555796c8dcSSimon Schubert normal = last_filename; 15565796c8dcSSimon Schubert else if (! IS_ABSOLUTE_PATH (filename) 15575796c8dcSSimon Schubert && ! IS_ABSOLUTE_PATH (abfd->filename)) 15585796c8dcSSimon Schubert normal = adjust_relative_path (filename, abfd->filename); 15595796c8dcSSimon Schubert else 15605796c8dcSSimon Schubert normal = filename; 15615796c8dcSSimon Schubert } 15625796c8dcSSimon Schubert else 15635796c8dcSSimon Schubert { 15645796c8dcSSimon Schubert normal = normalize (current, filename); 15655796c8dcSSimon Schubert if (normal == NULL) 15665796c8dcSSimon Schubert return FALSE; 15675796c8dcSSimon Schubert } 15685796c8dcSSimon Schubert 15695796c8dcSSimon Schubert thislen = strlen (normal); 15705796c8dcSSimon Schubert if (thislen > maxname || bfd_is_thin_archive (abfd)) 15715796c8dcSSimon Schubert { 15725796c8dcSSimon Schubert /* Works for now; may need to be re-engineered if we 15735796c8dcSSimon Schubert encounter an oddball archive format and want to 15745796c8dcSSimon Schubert generalise this hack. */ 15755796c8dcSSimon Schubert struct ar_hdr *hdr = arch_hdr (current); 15765796c8dcSSimon Schubert if (normal == last_filename) 15775796c8dcSSimon Schubert stroff = last_stroff; 15785796c8dcSSimon Schubert else 15795796c8dcSSimon Schubert { 15805796c8dcSSimon Schubert strcpy (strptr, normal); 15815796c8dcSSimon Schubert if (! trailing_slash) 15825796c8dcSSimon Schubert strptr[thislen] = ARFMAG[1]; 15835796c8dcSSimon Schubert else 15845796c8dcSSimon Schubert { 15855796c8dcSSimon Schubert strptr[thislen] = '/'; 15865796c8dcSSimon Schubert strptr[thislen + 1] = ARFMAG[1]; 15875796c8dcSSimon Schubert } 15885796c8dcSSimon Schubert stroff = strptr - *tabloc; 15895796c8dcSSimon Schubert last_stroff = stroff; 15905796c8dcSSimon Schubert } 15915796c8dcSSimon Schubert hdr->ar_name[0] = ar_padchar (current); 15925796c8dcSSimon Schubert if (bfd_is_thin_archive (abfd) && current->origin > 0) 15935796c8dcSSimon Schubert { 15945796c8dcSSimon Schubert int len = snprintf (hdr->ar_name + 1, maxname - 1, "%-ld:", 15955796c8dcSSimon Schubert stroff); 15965796c8dcSSimon Schubert _bfd_ar_spacepad (hdr->ar_name + 1 + len, maxname - 1 - len, 15975796c8dcSSimon Schubert "%-ld", 15985796c8dcSSimon Schubert current->origin - sizeof (struct ar_hdr)); 15995796c8dcSSimon Schubert } 16005796c8dcSSimon Schubert else 16015796c8dcSSimon Schubert _bfd_ar_spacepad (hdr->ar_name + 1, maxname - 1, "%-ld", stroff); 16025796c8dcSSimon Schubert if (normal != last_filename) 16035796c8dcSSimon Schubert { 16045796c8dcSSimon Schubert strptr += thislen + 1; 16055796c8dcSSimon Schubert if (trailing_slash) 16065796c8dcSSimon Schubert ++strptr; 16075796c8dcSSimon Schubert last_filename = filename; 16085796c8dcSSimon Schubert } 16095796c8dcSSimon Schubert } 16105796c8dcSSimon Schubert } 16115796c8dcSSimon Schubert 16125796c8dcSSimon Schubert return TRUE; 16135796c8dcSSimon Schubert } 1614*cf7f2e2dSJohn Marino 1615*cf7f2e2dSJohn Marino /* Do not construct an extended name table but transforms name field into 1616*cf7f2e2dSJohn Marino its extended form. */ 1617*cf7f2e2dSJohn Marino 1618*cf7f2e2dSJohn Marino bfd_boolean 1619*cf7f2e2dSJohn Marino _bfd_archive_bsd44_construct_extended_name_table (bfd *abfd, 1620*cf7f2e2dSJohn Marino char **tabloc, 1621*cf7f2e2dSJohn Marino bfd_size_type *tablen, 1622*cf7f2e2dSJohn Marino const char **name) 1623*cf7f2e2dSJohn Marino { 1624*cf7f2e2dSJohn Marino unsigned int maxname = abfd->xvec->ar_max_namelen; 1625*cf7f2e2dSJohn Marino bfd *current; 1626*cf7f2e2dSJohn Marino 1627*cf7f2e2dSJohn Marino *tablen = 0; 1628*cf7f2e2dSJohn Marino *tabloc = NULL; 1629*cf7f2e2dSJohn Marino *name = NULL; 1630*cf7f2e2dSJohn Marino 1631*cf7f2e2dSJohn Marino for (current = abfd->archive_head; 1632*cf7f2e2dSJohn Marino current != NULL; 1633*cf7f2e2dSJohn Marino current = current->archive_next) 1634*cf7f2e2dSJohn Marino { 1635*cf7f2e2dSJohn Marino const char *normal = normalize (current, current->filename); 1636*cf7f2e2dSJohn Marino int has_space = 0; 1637*cf7f2e2dSJohn Marino unsigned int len; 1638*cf7f2e2dSJohn Marino 1639*cf7f2e2dSJohn Marino if (normal == NULL) 1640*cf7f2e2dSJohn Marino return FALSE; 1641*cf7f2e2dSJohn Marino 1642*cf7f2e2dSJohn Marino for (len = 0; normal[len]; len++) 1643*cf7f2e2dSJohn Marino if (normal[len] == ' ') 1644*cf7f2e2dSJohn Marino has_space = 1; 1645*cf7f2e2dSJohn Marino 1646*cf7f2e2dSJohn Marino if (len > maxname || has_space) 1647*cf7f2e2dSJohn Marino { 1648*cf7f2e2dSJohn Marino struct ar_hdr *hdr = arch_hdr (current); 1649*cf7f2e2dSJohn Marino 1650*cf7f2e2dSJohn Marino len = (len + 3) & ~3; 1651*cf7f2e2dSJohn Marino arch_eltdata (current)->extra_size = len; 1652*cf7f2e2dSJohn Marino _bfd_ar_spacepad (hdr->ar_name, maxname, "#1/%u", len); 1653*cf7f2e2dSJohn Marino } 1654*cf7f2e2dSJohn Marino } 1655*cf7f2e2dSJohn Marino 1656*cf7f2e2dSJohn Marino return TRUE; 1657*cf7f2e2dSJohn Marino } 1658*cf7f2e2dSJohn Marino 1659*cf7f2e2dSJohn Marino /* Write an archive header. */ 1660*cf7f2e2dSJohn Marino 1661*cf7f2e2dSJohn Marino bfd_boolean 1662*cf7f2e2dSJohn Marino _bfd_generic_write_ar_hdr (bfd *archive, bfd *abfd) 1663*cf7f2e2dSJohn Marino { 1664*cf7f2e2dSJohn Marino struct ar_hdr *hdr = arch_hdr (abfd); 1665*cf7f2e2dSJohn Marino 1666*cf7f2e2dSJohn Marino if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr)) 1667*cf7f2e2dSJohn Marino return FALSE; 1668*cf7f2e2dSJohn Marino return TRUE; 1669*cf7f2e2dSJohn Marino } 1670*cf7f2e2dSJohn Marino 1671*cf7f2e2dSJohn Marino /* Write an archive header using BSD4.4 convention. */ 1672*cf7f2e2dSJohn Marino 1673*cf7f2e2dSJohn Marino bfd_boolean 1674*cf7f2e2dSJohn Marino _bfd_bsd44_write_ar_hdr (bfd *archive, bfd *abfd) 1675*cf7f2e2dSJohn Marino { 1676*cf7f2e2dSJohn Marino struct ar_hdr *hdr = arch_hdr (abfd); 1677*cf7f2e2dSJohn Marino 1678*cf7f2e2dSJohn Marino if (is_bsd44_extended_name (hdr->ar_name)) 1679*cf7f2e2dSJohn Marino { 1680*cf7f2e2dSJohn Marino /* This is a BSD 4.4 extended name. */ 1681*cf7f2e2dSJohn Marino const char *fullname = normalize (abfd, abfd->filename); 1682*cf7f2e2dSJohn Marino unsigned int len = strlen (fullname); 1683*cf7f2e2dSJohn Marino unsigned int padded_len = (len + 3) & ~3; 1684*cf7f2e2dSJohn Marino 1685*cf7f2e2dSJohn Marino BFD_ASSERT (padded_len == arch_eltdata (abfd)->extra_size); 1686*cf7f2e2dSJohn Marino 1687*cf7f2e2dSJohn Marino _bfd_ar_spacepad (hdr->ar_size, sizeof (hdr->ar_size), "%-10ld", 1688*cf7f2e2dSJohn Marino arch_eltdata (abfd)->parsed_size + padded_len); 1689*cf7f2e2dSJohn Marino 1690*cf7f2e2dSJohn Marino if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr)) 1691*cf7f2e2dSJohn Marino return FALSE; 1692*cf7f2e2dSJohn Marino 1693*cf7f2e2dSJohn Marino if (bfd_bwrite (fullname, len, archive) != len) 1694*cf7f2e2dSJohn Marino return FALSE; 1695*cf7f2e2dSJohn Marino if (len & 3) 1696*cf7f2e2dSJohn Marino { 1697*cf7f2e2dSJohn Marino static const char pad[3] = { 0, 0, 0 }; 1698*cf7f2e2dSJohn Marino 1699*cf7f2e2dSJohn Marino len = 4 - (len & 3); 1700*cf7f2e2dSJohn Marino if (bfd_bwrite (pad, len, archive) != len) 1701*cf7f2e2dSJohn Marino return FALSE; 1702*cf7f2e2dSJohn Marino } 1703*cf7f2e2dSJohn Marino } 1704*cf7f2e2dSJohn Marino else 1705*cf7f2e2dSJohn Marino { 1706*cf7f2e2dSJohn Marino if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr)) 1707*cf7f2e2dSJohn Marino return FALSE; 1708*cf7f2e2dSJohn Marino } 1709*cf7f2e2dSJohn Marino return TRUE; 1710*cf7f2e2dSJohn Marino } 17115796c8dcSSimon Schubert 17125796c8dcSSimon Schubert /* A couple of functions for creating ar_hdrs. */ 17135796c8dcSSimon Schubert 17145796c8dcSSimon Schubert #ifdef HPUX_LARGE_AR_IDS 17155796c8dcSSimon Schubert /* Function to encode large UID/GID values according to HP. */ 17165796c8dcSSimon Schubert 17175796c8dcSSimon Schubert static void 17185796c8dcSSimon Schubert hpux_uid_gid_encode (char str[6], long int id) 17195796c8dcSSimon Schubert { 17205796c8dcSSimon Schubert int cnt; 17215796c8dcSSimon Schubert 17225796c8dcSSimon Schubert str[5] = '@' + (id & 3); 17235796c8dcSSimon Schubert id >>= 2; 17245796c8dcSSimon Schubert 17255796c8dcSSimon Schubert for (cnt = 4; cnt >= 0; --cnt, id >>= 6) 17265796c8dcSSimon Schubert str[cnt] = ' ' + (id & 0x3f); 17275796c8dcSSimon Schubert } 17285796c8dcSSimon Schubert #endif /* HPUX_LARGE_AR_IDS */ 17295796c8dcSSimon Schubert 17305796c8dcSSimon Schubert #ifndef HAVE_GETUID 17315796c8dcSSimon Schubert #define getuid() 0 17325796c8dcSSimon Schubert #endif 17335796c8dcSSimon Schubert 17345796c8dcSSimon Schubert #ifndef HAVE_GETGID 17355796c8dcSSimon Schubert #define getgid() 0 17365796c8dcSSimon Schubert #endif 17375796c8dcSSimon Schubert 17385796c8dcSSimon Schubert /* Takes a filename, returns an arelt_data for it, or NULL if it can't 17395796c8dcSSimon Schubert make one. The filename must refer to a filename in the filesystem. 17405796c8dcSSimon Schubert The filename field of the ar_hdr will NOT be initialized. If member 17415796c8dcSSimon Schubert is set, and it's an in-memory bfd, we fake it. */ 17425796c8dcSSimon Schubert 17435796c8dcSSimon Schubert static struct areltdata * 17445796c8dcSSimon Schubert bfd_ar_hdr_from_filesystem (bfd *abfd, const char *filename, bfd *member) 17455796c8dcSSimon Schubert { 17465796c8dcSSimon Schubert struct stat status; 17475796c8dcSSimon Schubert struct areltdata *ared; 17485796c8dcSSimon Schubert struct ar_hdr *hdr; 17495796c8dcSSimon Schubert bfd_size_type amt; 17505796c8dcSSimon Schubert 17515796c8dcSSimon Schubert if (member && (member->flags & BFD_IN_MEMORY) != 0) 17525796c8dcSSimon Schubert { 17535796c8dcSSimon Schubert /* Assume we just "made" the member, and fake it. */ 17545796c8dcSSimon Schubert struct bfd_in_memory *bim = (struct bfd_in_memory *) member->iostream; 17555796c8dcSSimon Schubert time (&status.st_mtime); 17565796c8dcSSimon Schubert status.st_uid = getuid (); 17575796c8dcSSimon Schubert status.st_gid = getgid (); 17585796c8dcSSimon Schubert status.st_mode = 0644; 17595796c8dcSSimon Schubert status.st_size = bim->size; 17605796c8dcSSimon Schubert } 17615796c8dcSSimon Schubert else if (stat (filename, &status) != 0) 17625796c8dcSSimon Schubert { 17635796c8dcSSimon Schubert bfd_set_error (bfd_error_system_call); 17645796c8dcSSimon Schubert return NULL; 17655796c8dcSSimon Schubert } 17665796c8dcSSimon Schubert 17675796c8dcSSimon Schubert /* If the caller requested that the BFD generate deterministic output, 17685796c8dcSSimon Schubert fake values for modification time, UID, GID, and file mode. */ 17695796c8dcSSimon Schubert if ((abfd->flags & BFD_DETERMINISTIC_OUTPUT) != 0) 17705796c8dcSSimon Schubert { 17715796c8dcSSimon Schubert status.st_mtime = 0; 17725796c8dcSSimon Schubert status.st_uid = 0; 17735796c8dcSSimon Schubert status.st_gid = 0; 17745796c8dcSSimon Schubert status.st_mode = 0644; 17755796c8dcSSimon Schubert } 17765796c8dcSSimon Schubert 17775796c8dcSSimon Schubert amt = sizeof (struct ar_hdr) + sizeof (struct areltdata); 17785796c8dcSSimon Schubert ared = (struct areltdata *) bfd_zalloc (abfd, amt); 17795796c8dcSSimon Schubert if (ared == NULL) 17805796c8dcSSimon Schubert return NULL; 17815796c8dcSSimon Schubert hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata)); 17825796c8dcSSimon Schubert 17835796c8dcSSimon Schubert /* ar headers are space padded, not null padded! */ 17845796c8dcSSimon Schubert memset (hdr, ' ', sizeof (struct ar_hdr)); 17855796c8dcSSimon Schubert 17865796c8dcSSimon Schubert _bfd_ar_spacepad (hdr->ar_date, sizeof (hdr->ar_date), "%-12ld", 17875796c8dcSSimon Schubert status.st_mtime); 17885796c8dcSSimon Schubert #ifdef HPUX_LARGE_AR_IDS 17895796c8dcSSimon Schubert /* HP has a very "special" way to handle UID/GID's with numeric values 17905796c8dcSSimon Schubert > 99999. */ 17915796c8dcSSimon Schubert if (status.st_uid > 99999) 17925796c8dcSSimon Schubert hpux_uid_gid_encode (hdr->ar_uid, (long) status.st_uid); 17935796c8dcSSimon Schubert else 17945796c8dcSSimon Schubert #endif 17955796c8dcSSimon Schubert _bfd_ar_spacepad (hdr->ar_uid, sizeof (hdr->ar_uid), "%ld", 17965796c8dcSSimon Schubert status.st_uid); 17975796c8dcSSimon Schubert #ifdef HPUX_LARGE_AR_IDS 17985796c8dcSSimon Schubert /* HP has a very "special" way to handle UID/GID's with numeric values 17995796c8dcSSimon Schubert > 99999. */ 18005796c8dcSSimon Schubert if (status.st_gid > 99999) 18015796c8dcSSimon Schubert hpux_uid_gid_encode (hdr->ar_gid, (long) status.st_gid); 18025796c8dcSSimon Schubert else 18035796c8dcSSimon Schubert #endif 18045796c8dcSSimon Schubert _bfd_ar_spacepad (hdr->ar_gid, sizeof (hdr->ar_gid), "%ld", 18055796c8dcSSimon Schubert status.st_gid); 18065796c8dcSSimon Schubert _bfd_ar_spacepad (hdr->ar_mode, sizeof (hdr->ar_mode), "%-8lo", 18075796c8dcSSimon Schubert status.st_mode); 18085796c8dcSSimon Schubert _bfd_ar_spacepad (hdr->ar_size, sizeof (hdr->ar_size), "%-10ld", 18095796c8dcSSimon Schubert status.st_size); 18105796c8dcSSimon Schubert memcpy (hdr->ar_fmag, ARFMAG, 2); 18115796c8dcSSimon Schubert ared->parsed_size = status.st_size; 18125796c8dcSSimon Schubert ared->arch_header = (char *) hdr; 18135796c8dcSSimon Schubert 18145796c8dcSSimon Schubert return ared; 18155796c8dcSSimon Schubert } 18165796c8dcSSimon Schubert 18175796c8dcSSimon Schubert /* Analogous to stat call. */ 18185796c8dcSSimon Schubert 18195796c8dcSSimon Schubert int 18205796c8dcSSimon Schubert bfd_generic_stat_arch_elt (bfd *abfd, struct stat *buf) 18215796c8dcSSimon Schubert { 18225796c8dcSSimon Schubert struct ar_hdr *hdr; 18235796c8dcSSimon Schubert char *aloser; 18245796c8dcSSimon Schubert 18255796c8dcSSimon Schubert if (abfd->arelt_data == NULL) 18265796c8dcSSimon Schubert { 18275796c8dcSSimon Schubert bfd_set_error (bfd_error_invalid_operation); 18285796c8dcSSimon Schubert return -1; 18295796c8dcSSimon Schubert } 18305796c8dcSSimon Schubert 18315796c8dcSSimon Schubert hdr = arch_hdr (abfd); 18325796c8dcSSimon Schubert 18335796c8dcSSimon Schubert #define foo(arelt, stelt, size) \ 18345796c8dcSSimon Schubert buf->stelt = strtol (hdr->arelt, &aloser, size); \ 18355796c8dcSSimon Schubert if (aloser == hdr->arelt) \ 18365796c8dcSSimon Schubert return -1; 18375796c8dcSSimon Schubert 18385796c8dcSSimon Schubert /* Some platforms support special notations for large IDs. */ 18395796c8dcSSimon Schubert #ifdef HPUX_LARGE_AR_IDS 18405796c8dcSSimon Schubert # define foo2(arelt, stelt, size) \ 18415796c8dcSSimon Schubert if (hdr->arelt[5] == ' ') \ 18425796c8dcSSimon Schubert { \ 18435796c8dcSSimon Schubert foo (arelt, stelt, size); \ 18445796c8dcSSimon Schubert } \ 18455796c8dcSSimon Schubert else \ 18465796c8dcSSimon Schubert { \ 18475796c8dcSSimon Schubert int cnt; \ 18485796c8dcSSimon Schubert for (buf->stelt = cnt = 0; cnt < 5; ++cnt) \ 18495796c8dcSSimon Schubert { \ 18505796c8dcSSimon Schubert if (hdr->arelt[cnt] < ' ' || hdr->arelt[cnt] > ' ' + 0x3f) \ 18515796c8dcSSimon Schubert return -1; \ 18525796c8dcSSimon Schubert buf->stelt <<= 6; \ 18535796c8dcSSimon Schubert buf->stelt += hdr->arelt[cnt] - ' '; \ 18545796c8dcSSimon Schubert } \ 18555796c8dcSSimon Schubert if (hdr->arelt[5] < '@' || hdr->arelt[5] > '@' + 3) \ 18565796c8dcSSimon Schubert return -1; \ 18575796c8dcSSimon Schubert buf->stelt <<= 2; \ 18585796c8dcSSimon Schubert buf->stelt += hdr->arelt[5] - '@'; \ 18595796c8dcSSimon Schubert } 18605796c8dcSSimon Schubert #else 18615796c8dcSSimon Schubert # define foo2(arelt, stelt, size) foo (arelt, stelt, size) 18625796c8dcSSimon Schubert #endif 18635796c8dcSSimon Schubert 18645796c8dcSSimon Schubert foo (ar_date, st_mtime, 10); 18655796c8dcSSimon Schubert foo2 (ar_uid, st_uid, 10); 18665796c8dcSSimon Schubert foo2 (ar_gid, st_gid, 10); 18675796c8dcSSimon Schubert foo (ar_mode, st_mode, 8); 18685796c8dcSSimon Schubert 18695796c8dcSSimon Schubert buf->st_size = arch_eltdata (abfd)->parsed_size; 18705796c8dcSSimon Schubert 18715796c8dcSSimon Schubert return 0; 18725796c8dcSSimon Schubert } 18735796c8dcSSimon Schubert 18745796c8dcSSimon Schubert void 18755796c8dcSSimon Schubert bfd_dont_truncate_arname (bfd *abfd, const char *pathname, char *arhdr) 18765796c8dcSSimon Schubert { 18775796c8dcSSimon Schubert /* FIXME: This interacts unpleasantly with ar's quick-append option. 18785796c8dcSSimon Schubert Fortunately ic960 users will never use that option. Fixing this 18795796c8dcSSimon Schubert is very hard; fortunately I know how to do it and will do so once 18805796c8dcSSimon Schubert intel's release is out the door. */ 18815796c8dcSSimon Schubert 18825796c8dcSSimon Schubert struct ar_hdr *hdr = (struct ar_hdr *) arhdr; 18835796c8dcSSimon Schubert size_t length; 18845796c8dcSSimon Schubert const char *filename; 18855796c8dcSSimon Schubert size_t maxlen = ar_maxnamelen (abfd); 18865796c8dcSSimon Schubert 18875796c8dcSSimon Schubert if ((bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0) 18885796c8dcSSimon Schubert { 18895796c8dcSSimon Schubert bfd_bsd_truncate_arname (abfd, pathname, arhdr); 18905796c8dcSSimon Schubert return; 18915796c8dcSSimon Schubert } 18925796c8dcSSimon Schubert 18935796c8dcSSimon Schubert filename = normalize (abfd, pathname); 18945796c8dcSSimon Schubert if (filename == NULL) 18955796c8dcSSimon Schubert { 18965796c8dcSSimon Schubert /* FIXME */ 18975796c8dcSSimon Schubert abort (); 18985796c8dcSSimon Schubert } 18995796c8dcSSimon Schubert 19005796c8dcSSimon Schubert length = strlen (filename); 19015796c8dcSSimon Schubert 19025796c8dcSSimon Schubert if (length <= maxlen) 19035796c8dcSSimon Schubert memcpy (hdr->ar_name, filename, length); 19045796c8dcSSimon Schubert 19055796c8dcSSimon Schubert /* Add the padding character if there is room for it. */ 19065796c8dcSSimon Schubert if (length < maxlen 19075796c8dcSSimon Schubert || (length == maxlen && length < sizeof hdr->ar_name)) 19085796c8dcSSimon Schubert (hdr->ar_name)[length] = ar_padchar (abfd); 19095796c8dcSSimon Schubert } 19105796c8dcSSimon Schubert 19115796c8dcSSimon Schubert void 19125796c8dcSSimon Schubert bfd_bsd_truncate_arname (bfd *abfd, const char *pathname, char *arhdr) 19135796c8dcSSimon Schubert { 19145796c8dcSSimon Schubert struct ar_hdr *hdr = (struct ar_hdr *) arhdr; 19155796c8dcSSimon Schubert size_t length; 1916*cf7f2e2dSJohn Marino const char *filename = lbasename (pathname); 19175796c8dcSSimon Schubert size_t maxlen = ar_maxnamelen (abfd); 19185796c8dcSSimon Schubert 19195796c8dcSSimon Schubert length = strlen (filename); 19205796c8dcSSimon Schubert 19215796c8dcSSimon Schubert if (length <= maxlen) 19225796c8dcSSimon Schubert memcpy (hdr->ar_name, filename, length); 19235796c8dcSSimon Schubert else 19245796c8dcSSimon Schubert { 19255796c8dcSSimon Schubert /* pathname: meet procrustes */ 19265796c8dcSSimon Schubert memcpy (hdr->ar_name, filename, maxlen); 19275796c8dcSSimon Schubert length = maxlen; 19285796c8dcSSimon Schubert } 19295796c8dcSSimon Schubert 19305796c8dcSSimon Schubert if (length < maxlen) 19315796c8dcSSimon Schubert (hdr->ar_name)[length] = ar_padchar (abfd); 19325796c8dcSSimon Schubert } 19335796c8dcSSimon Schubert 19345796c8dcSSimon Schubert /* Store name into ar header. Truncates the name to fit. 19355796c8dcSSimon Schubert 1> strip pathname to be just the basename. 19365796c8dcSSimon Schubert 2> if it's short enuf to fit, stuff it in. 19375796c8dcSSimon Schubert 3> If it doesn't end with .o, truncate it to fit 19385796c8dcSSimon Schubert 4> truncate it before the .o, append .o, stuff THAT in. */ 19395796c8dcSSimon Schubert 19405796c8dcSSimon Schubert /* This is what gnu ar does. It's better but incompatible with the 19415796c8dcSSimon Schubert bsd ar. */ 19425796c8dcSSimon Schubert 19435796c8dcSSimon Schubert void 19445796c8dcSSimon Schubert bfd_gnu_truncate_arname (bfd *abfd, const char *pathname, char *arhdr) 19455796c8dcSSimon Schubert { 19465796c8dcSSimon Schubert struct ar_hdr *hdr = (struct ar_hdr *) arhdr; 19475796c8dcSSimon Schubert size_t length; 1948*cf7f2e2dSJohn Marino const char *filename = lbasename (pathname); 19495796c8dcSSimon Schubert size_t maxlen = ar_maxnamelen (abfd); 19505796c8dcSSimon Schubert 19515796c8dcSSimon Schubert length = strlen (filename); 19525796c8dcSSimon Schubert 19535796c8dcSSimon Schubert if (length <= maxlen) 19545796c8dcSSimon Schubert memcpy (hdr->ar_name, filename, length); 19555796c8dcSSimon Schubert else 19565796c8dcSSimon Schubert { 19575796c8dcSSimon Schubert /* pathname: meet procrustes. */ 19585796c8dcSSimon Schubert memcpy (hdr->ar_name, filename, maxlen); 19595796c8dcSSimon Schubert if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) 19605796c8dcSSimon Schubert { 19615796c8dcSSimon Schubert hdr->ar_name[maxlen - 2] = '.'; 19625796c8dcSSimon Schubert hdr->ar_name[maxlen - 1] = 'o'; 19635796c8dcSSimon Schubert } 19645796c8dcSSimon Schubert length = maxlen; 19655796c8dcSSimon Schubert } 19665796c8dcSSimon Schubert 19675796c8dcSSimon Schubert if (length < 16) 19685796c8dcSSimon Schubert (hdr->ar_name)[length] = ar_padchar (abfd); 19695796c8dcSSimon Schubert } 19705796c8dcSSimon Schubert 19715796c8dcSSimon Schubert /* The BFD is open for write and has its format set to bfd_archive. */ 19725796c8dcSSimon Schubert 19735796c8dcSSimon Schubert bfd_boolean 19745796c8dcSSimon Schubert _bfd_write_archive_contents (bfd *arch) 19755796c8dcSSimon Schubert { 19765796c8dcSSimon Schubert bfd *current; 19775796c8dcSSimon Schubert char *etable = NULL; 19785796c8dcSSimon Schubert bfd_size_type elength = 0; 19795796c8dcSSimon Schubert const char *ename = NULL; 19805796c8dcSSimon Schubert bfd_boolean makemap = bfd_has_map (arch); 19815796c8dcSSimon Schubert /* If no .o's, don't bother to make a map. */ 19825796c8dcSSimon Schubert bfd_boolean hasobjects = FALSE; 19835796c8dcSSimon Schubert bfd_size_type wrote; 19845796c8dcSSimon Schubert int tries; 19855796c8dcSSimon Schubert char *armag; 19865796c8dcSSimon Schubert 19875796c8dcSSimon Schubert /* Verify the viability of all entries; if any of them live in the 19885796c8dcSSimon Schubert filesystem (as opposed to living in an archive open for input) 19895796c8dcSSimon Schubert then construct a fresh ar_hdr for them. */ 19905796c8dcSSimon Schubert for (current = arch->archive_head; 19915796c8dcSSimon Schubert current != NULL; 19925796c8dcSSimon Schubert current = current->archive_next) 19935796c8dcSSimon Schubert { 19945796c8dcSSimon Schubert /* This check is checking the bfds for the objects we're reading 19955796c8dcSSimon Schubert from (which are usually either an object file or archive on 19965796c8dcSSimon Schubert disk), not the archive entries we're writing to. We don't 19975796c8dcSSimon Schubert actually create bfds for the archive members, we just copy 19985796c8dcSSimon Schubert them byte-wise when we write out the archive. */ 19995796c8dcSSimon Schubert if (bfd_write_p (current)) 20005796c8dcSSimon Schubert { 20015796c8dcSSimon Schubert bfd_set_error (bfd_error_invalid_operation); 20025796c8dcSSimon Schubert goto input_err; 20035796c8dcSSimon Schubert } 20045796c8dcSSimon Schubert if (!current->arelt_data) 20055796c8dcSSimon Schubert { 20065796c8dcSSimon Schubert current->arelt_data = 20075796c8dcSSimon Schubert bfd_ar_hdr_from_filesystem (arch, current->filename, current); 20085796c8dcSSimon Schubert if (!current->arelt_data) 20095796c8dcSSimon Schubert goto input_err; 20105796c8dcSSimon Schubert 20115796c8dcSSimon Schubert /* Put in the file name. */ 20125796c8dcSSimon Schubert BFD_SEND (arch, _bfd_truncate_arname, 20135796c8dcSSimon Schubert (arch, current->filename, (char *) arch_hdr (current))); 20145796c8dcSSimon Schubert } 20155796c8dcSSimon Schubert 20165796c8dcSSimon Schubert if (makemap && ! hasobjects) 20175796c8dcSSimon Schubert { /* Don't bother if we won't make a map! */ 20185796c8dcSSimon Schubert if ((bfd_check_format (current, bfd_object))) 20195796c8dcSSimon Schubert hasobjects = TRUE; 20205796c8dcSSimon Schubert } 20215796c8dcSSimon Schubert } 20225796c8dcSSimon Schubert 20235796c8dcSSimon Schubert if (!BFD_SEND (arch, _bfd_construct_extended_name_table, 20245796c8dcSSimon Schubert (arch, &etable, &elength, &ename))) 20255796c8dcSSimon Schubert return FALSE; 20265796c8dcSSimon Schubert 20275796c8dcSSimon Schubert if (bfd_seek (arch, (file_ptr) 0, SEEK_SET) != 0) 20285796c8dcSSimon Schubert return FALSE; 20295796c8dcSSimon Schubert armag = ARMAG; 20305796c8dcSSimon Schubert if (bfd_is_thin_archive (arch)) 20315796c8dcSSimon Schubert armag = ARMAGT; 20325796c8dcSSimon Schubert wrote = bfd_bwrite (armag, SARMAG, arch); 20335796c8dcSSimon Schubert if (wrote != SARMAG) 20345796c8dcSSimon Schubert return FALSE; 20355796c8dcSSimon Schubert 20365796c8dcSSimon Schubert if (makemap && hasobjects) 20375796c8dcSSimon Schubert { 20385796c8dcSSimon Schubert if (! _bfd_compute_and_write_armap (arch, (unsigned int) elength)) 20395796c8dcSSimon Schubert return FALSE; 20405796c8dcSSimon Schubert } 20415796c8dcSSimon Schubert 20425796c8dcSSimon Schubert if (elength != 0) 20435796c8dcSSimon Schubert { 20445796c8dcSSimon Schubert struct ar_hdr hdr; 20455796c8dcSSimon Schubert 20465796c8dcSSimon Schubert memset (&hdr, ' ', sizeof (struct ar_hdr)); 20475796c8dcSSimon Schubert memcpy (hdr.ar_name, ename, strlen (ename)); 20485796c8dcSSimon Schubert /* Round size up to even number in archive header. */ 20495796c8dcSSimon Schubert _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", 20505796c8dcSSimon Schubert (elength + 1) & ~(bfd_size_type) 1); 20515796c8dcSSimon Schubert memcpy (hdr.ar_fmag, ARFMAG, 2); 20525796c8dcSSimon Schubert if ((bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch) 20535796c8dcSSimon Schubert != sizeof (struct ar_hdr)) 20545796c8dcSSimon Schubert || bfd_bwrite (etable, elength, arch) != elength) 20555796c8dcSSimon Schubert return FALSE; 20565796c8dcSSimon Schubert if ((elength % 2) == 1) 20575796c8dcSSimon Schubert { 20585796c8dcSSimon Schubert if (bfd_bwrite (&ARFMAG[1], 1, arch) != 1) 20595796c8dcSSimon Schubert return FALSE; 20605796c8dcSSimon Schubert } 20615796c8dcSSimon Schubert } 20625796c8dcSSimon Schubert 20635796c8dcSSimon Schubert for (current = arch->archive_head; 20645796c8dcSSimon Schubert current != NULL; 20655796c8dcSSimon Schubert current = current->archive_next) 20665796c8dcSSimon Schubert { 20675796c8dcSSimon Schubert char buffer[DEFAULT_BUFFERSIZE]; 20685796c8dcSSimon Schubert unsigned int remaining = arelt_size (current); 20695796c8dcSSimon Schubert 20705796c8dcSSimon Schubert /* Write ar header. */ 2071*cf7f2e2dSJohn Marino if (!_bfd_write_ar_hdr (arch, current)) 20725796c8dcSSimon Schubert return FALSE; 20735796c8dcSSimon Schubert if (bfd_is_thin_archive (arch)) 20745796c8dcSSimon Schubert continue; 20755796c8dcSSimon Schubert if (bfd_seek (current, (file_ptr) 0, SEEK_SET) != 0) 20765796c8dcSSimon Schubert goto input_err; 20775796c8dcSSimon Schubert 20785796c8dcSSimon Schubert while (remaining) 20795796c8dcSSimon Schubert { 20805796c8dcSSimon Schubert unsigned int amt = DEFAULT_BUFFERSIZE; 20815796c8dcSSimon Schubert 20825796c8dcSSimon Schubert if (amt > remaining) 20835796c8dcSSimon Schubert amt = remaining; 20845796c8dcSSimon Schubert errno = 0; 20855796c8dcSSimon Schubert if (bfd_bread (buffer, amt, current) != amt) 20865796c8dcSSimon Schubert { 20875796c8dcSSimon Schubert if (bfd_get_error () != bfd_error_system_call) 20885796c8dcSSimon Schubert bfd_set_error (bfd_error_file_truncated); 20895796c8dcSSimon Schubert goto input_err; 20905796c8dcSSimon Schubert } 20915796c8dcSSimon Schubert if (bfd_bwrite (buffer, amt, arch) != amt) 20925796c8dcSSimon Schubert return FALSE; 20935796c8dcSSimon Schubert remaining -= amt; 20945796c8dcSSimon Schubert } 20955796c8dcSSimon Schubert 20965796c8dcSSimon Schubert if ((arelt_size (current) % 2) == 1) 20975796c8dcSSimon Schubert { 20985796c8dcSSimon Schubert if (bfd_bwrite (&ARFMAG[1], 1, arch) != 1) 20995796c8dcSSimon Schubert return FALSE; 21005796c8dcSSimon Schubert } 21015796c8dcSSimon Schubert } 21025796c8dcSSimon Schubert 21035796c8dcSSimon Schubert if (makemap && hasobjects) 21045796c8dcSSimon Schubert { 21055796c8dcSSimon Schubert /* Verify the timestamp in the archive file. If it would not be 21065796c8dcSSimon Schubert accepted by the linker, rewrite it until it would be. If 21075796c8dcSSimon Schubert anything odd happens, break out and just return. (The 21085796c8dcSSimon Schubert Berkeley linker checks the timestamp and refuses to read the 21095796c8dcSSimon Schubert table-of-contents if it is >60 seconds less than the file's 21105796c8dcSSimon Schubert modified-time. That painful hack requires this painful hack. */ 21115796c8dcSSimon Schubert tries = 1; 21125796c8dcSSimon Schubert do 21135796c8dcSSimon Schubert { 21145796c8dcSSimon Schubert if (bfd_update_armap_timestamp (arch)) 21155796c8dcSSimon Schubert break; 21165796c8dcSSimon Schubert (*_bfd_error_handler) 21175796c8dcSSimon Schubert (_("Warning: writing archive was slow: rewriting timestamp\n")); 21185796c8dcSSimon Schubert } 21195796c8dcSSimon Schubert while (++tries < 6); 21205796c8dcSSimon Schubert } 21215796c8dcSSimon Schubert 21225796c8dcSSimon Schubert return TRUE; 21235796c8dcSSimon Schubert 21245796c8dcSSimon Schubert input_err: 21255796c8dcSSimon Schubert bfd_set_error (bfd_error_on_input, current, bfd_get_error ()); 21265796c8dcSSimon Schubert return FALSE; 21275796c8dcSSimon Schubert } 21285796c8dcSSimon Schubert 21295796c8dcSSimon Schubert /* Note that the namidx for the first symbol is 0. */ 21305796c8dcSSimon Schubert 21315796c8dcSSimon Schubert bfd_boolean 21325796c8dcSSimon Schubert _bfd_compute_and_write_armap (bfd *arch, unsigned int elength) 21335796c8dcSSimon Schubert { 21345796c8dcSSimon Schubert char *first_name = NULL; 21355796c8dcSSimon Schubert bfd *current; 21365796c8dcSSimon Schubert file_ptr elt_no = 0; 21375796c8dcSSimon Schubert struct orl *map = NULL; 21385796c8dcSSimon Schubert unsigned int orl_max = 1024; /* Fine initial default. */ 21395796c8dcSSimon Schubert unsigned int orl_count = 0; 21405796c8dcSSimon Schubert int stridx = 0; 21415796c8dcSSimon Schubert asymbol **syms = NULL; 21425796c8dcSSimon Schubert long syms_max = 0; 21435796c8dcSSimon Schubert bfd_boolean ret; 21445796c8dcSSimon Schubert bfd_size_type amt; 21455796c8dcSSimon Schubert 21465796c8dcSSimon Schubert /* Dunno if this is the best place for this info... */ 21475796c8dcSSimon Schubert if (elength != 0) 21485796c8dcSSimon Schubert elength += sizeof (struct ar_hdr); 21495796c8dcSSimon Schubert elength += elength % 2; 21505796c8dcSSimon Schubert 21515796c8dcSSimon Schubert amt = orl_max * sizeof (struct orl); 21525796c8dcSSimon Schubert map = (struct orl *) bfd_malloc (amt); 21535796c8dcSSimon Schubert if (map == NULL) 21545796c8dcSSimon Schubert goto error_return; 21555796c8dcSSimon Schubert 21565796c8dcSSimon Schubert /* We put the symbol names on the arch objalloc, and then discard 21575796c8dcSSimon Schubert them when done. */ 21585796c8dcSSimon Schubert first_name = (char *) bfd_alloc (arch, 1); 21595796c8dcSSimon Schubert if (first_name == NULL) 21605796c8dcSSimon Schubert goto error_return; 21615796c8dcSSimon Schubert 21625796c8dcSSimon Schubert /* Drop all the files called __.SYMDEF, we're going to make our own. */ 21635796c8dcSSimon Schubert while (arch->archive_head 21645796c8dcSSimon Schubert && strcmp (arch->archive_head->filename, "__.SYMDEF") == 0) 21655796c8dcSSimon Schubert arch->archive_head = arch->archive_head->archive_next; 21665796c8dcSSimon Schubert 21675796c8dcSSimon Schubert /* Map over each element. */ 21685796c8dcSSimon Schubert for (current = arch->archive_head; 21695796c8dcSSimon Schubert current != NULL; 21705796c8dcSSimon Schubert current = current->archive_next, elt_no++) 21715796c8dcSSimon Schubert { 21725796c8dcSSimon Schubert if (bfd_check_format (current, bfd_object) 21735796c8dcSSimon Schubert && (bfd_get_file_flags (current) & HAS_SYMS) != 0) 21745796c8dcSSimon Schubert { 21755796c8dcSSimon Schubert long storage; 21765796c8dcSSimon Schubert long symcount; 21775796c8dcSSimon Schubert long src_count; 21785796c8dcSSimon Schubert 21795796c8dcSSimon Schubert storage = bfd_get_symtab_upper_bound (current); 21805796c8dcSSimon Schubert if (storage < 0) 21815796c8dcSSimon Schubert goto error_return; 21825796c8dcSSimon Schubert 21835796c8dcSSimon Schubert if (storage != 0) 21845796c8dcSSimon Schubert { 21855796c8dcSSimon Schubert if (storage > syms_max) 21865796c8dcSSimon Schubert { 21875796c8dcSSimon Schubert if (syms_max > 0) 21885796c8dcSSimon Schubert free (syms); 21895796c8dcSSimon Schubert syms_max = storage; 21905796c8dcSSimon Schubert syms = (asymbol **) bfd_malloc (syms_max); 21915796c8dcSSimon Schubert if (syms == NULL) 21925796c8dcSSimon Schubert goto error_return; 21935796c8dcSSimon Schubert } 21945796c8dcSSimon Schubert symcount = bfd_canonicalize_symtab (current, syms); 21955796c8dcSSimon Schubert if (symcount < 0) 21965796c8dcSSimon Schubert goto error_return; 21975796c8dcSSimon Schubert 21985796c8dcSSimon Schubert /* Now map over all the symbols, picking out the ones we 21995796c8dcSSimon Schubert want. */ 22005796c8dcSSimon Schubert for (src_count = 0; src_count < symcount; src_count++) 22015796c8dcSSimon Schubert { 22025796c8dcSSimon Schubert flagword flags = (syms[src_count])->flags; 22035796c8dcSSimon Schubert asection *sec = syms[src_count]->section; 22045796c8dcSSimon Schubert 22055796c8dcSSimon Schubert if ((flags & BSF_GLOBAL 22065796c8dcSSimon Schubert || flags & BSF_WEAK 22075796c8dcSSimon Schubert || flags & BSF_INDIRECT 2208*cf7f2e2dSJohn Marino || flags & BSF_GNU_UNIQUE 22095796c8dcSSimon Schubert || bfd_is_com_section (sec)) 22105796c8dcSSimon Schubert && ! bfd_is_und_section (sec)) 22115796c8dcSSimon Schubert { 22125796c8dcSSimon Schubert bfd_size_type namelen; 22135796c8dcSSimon Schubert struct orl *new_map; 22145796c8dcSSimon Schubert 22155796c8dcSSimon Schubert /* This symbol will go into the archive header. */ 22165796c8dcSSimon Schubert if (orl_count == orl_max) 22175796c8dcSSimon Schubert { 22185796c8dcSSimon Schubert orl_max *= 2; 22195796c8dcSSimon Schubert amt = orl_max * sizeof (struct orl); 22205796c8dcSSimon Schubert new_map = (struct orl *) bfd_realloc (map, amt); 22215796c8dcSSimon Schubert if (new_map == NULL) 22225796c8dcSSimon Schubert goto error_return; 22235796c8dcSSimon Schubert 22245796c8dcSSimon Schubert map = new_map; 22255796c8dcSSimon Schubert } 22265796c8dcSSimon Schubert 22275796c8dcSSimon Schubert namelen = strlen (syms[src_count]->name); 22285796c8dcSSimon Schubert amt = sizeof (char *); 22295796c8dcSSimon Schubert map[orl_count].name = (char **) bfd_alloc (arch, amt); 22305796c8dcSSimon Schubert if (map[orl_count].name == NULL) 22315796c8dcSSimon Schubert goto error_return; 22325796c8dcSSimon Schubert *(map[orl_count].name) = (char *) bfd_alloc (arch, 22335796c8dcSSimon Schubert namelen + 1); 22345796c8dcSSimon Schubert if (*(map[orl_count].name) == NULL) 22355796c8dcSSimon Schubert goto error_return; 22365796c8dcSSimon Schubert strcpy (*(map[orl_count].name), syms[src_count]->name); 22375796c8dcSSimon Schubert map[orl_count].u.abfd = current; 22385796c8dcSSimon Schubert map[orl_count].namidx = stridx; 22395796c8dcSSimon Schubert 22405796c8dcSSimon Schubert stridx += namelen + 1; 22415796c8dcSSimon Schubert ++orl_count; 22425796c8dcSSimon Schubert } 22435796c8dcSSimon Schubert } 22445796c8dcSSimon Schubert } 22455796c8dcSSimon Schubert 22465796c8dcSSimon Schubert /* Now ask the BFD to free up any cached information, so we 22475796c8dcSSimon Schubert don't fill all of memory with symbol tables. */ 22485796c8dcSSimon Schubert if (! bfd_free_cached_info (current)) 22495796c8dcSSimon Schubert goto error_return; 22505796c8dcSSimon Schubert } 22515796c8dcSSimon Schubert } 22525796c8dcSSimon Schubert 22535796c8dcSSimon Schubert /* OK, now we have collected all the data, let's write them out. */ 22545796c8dcSSimon Schubert ret = BFD_SEND (arch, write_armap, 22555796c8dcSSimon Schubert (arch, elength, map, orl_count, stridx)); 22565796c8dcSSimon Schubert 22575796c8dcSSimon Schubert if (syms_max > 0) 22585796c8dcSSimon Schubert free (syms); 22595796c8dcSSimon Schubert if (map != NULL) 22605796c8dcSSimon Schubert free (map); 22615796c8dcSSimon Schubert if (first_name != NULL) 22625796c8dcSSimon Schubert bfd_release (arch, first_name); 22635796c8dcSSimon Schubert 22645796c8dcSSimon Schubert return ret; 22655796c8dcSSimon Schubert 22665796c8dcSSimon Schubert error_return: 22675796c8dcSSimon Schubert if (syms_max > 0) 22685796c8dcSSimon Schubert free (syms); 22695796c8dcSSimon Schubert if (map != NULL) 22705796c8dcSSimon Schubert free (map); 22715796c8dcSSimon Schubert if (first_name != NULL) 22725796c8dcSSimon Schubert bfd_release (arch, first_name); 22735796c8dcSSimon Schubert 22745796c8dcSSimon Schubert return FALSE; 22755796c8dcSSimon Schubert } 22765796c8dcSSimon Schubert 22775796c8dcSSimon Schubert bfd_boolean 22785796c8dcSSimon Schubert bsd_write_armap (bfd *arch, 22795796c8dcSSimon Schubert unsigned int elength, 22805796c8dcSSimon Schubert struct orl *map, 22815796c8dcSSimon Schubert unsigned int orl_count, 22825796c8dcSSimon Schubert int stridx) 22835796c8dcSSimon Schubert { 22845796c8dcSSimon Schubert int padit = stridx & 1; 22855796c8dcSSimon Schubert unsigned int ranlibsize = orl_count * BSD_SYMDEF_SIZE; 22865796c8dcSSimon Schubert unsigned int stringsize = stridx + padit; 22875796c8dcSSimon Schubert /* Include 8 bytes to store ranlibsize and stringsize in output. */ 22885796c8dcSSimon Schubert unsigned int mapsize = ranlibsize + stringsize + 8; 22895796c8dcSSimon Schubert file_ptr firstreal; 22905796c8dcSSimon Schubert bfd *current = arch->archive_head; 22915796c8dcSSimon Schubert bfd *last_elt = current; /* Last element arch seen. */ 22925796c8dcSSimon Schubert bfd_byte temp[4]; 22935796c8dcSSimon Schubert unsigned int count; 22945796c8dcSSimon Schubert struct ar_hdr hdr; 22955796c8dcSSimon Schubert struct stat statbuf; 22965796c8dcSSimon Schubert long uid, gid; 22975796c8dcSSimon Schubert 22985796c8dcSSimon Schubert firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG; 22995796c8dcSSimon Schubert 23005796c8dcSSimon Schubert stat (arch->filename, &statbuf); 23015796c8dcSSimon Schubert if ((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0) 23025796c8dcSSimon Schubert { 23035796c8dcSSimon Schubert /* Remember the timestamp, to keep it holy. But fudge it a little. */ 23045796c8dcSSimon Schubert bfd_ardata (arch)->armap_timestamp = (statbuf.st_mtime 23055796c8dcSSimon Schubert + ARMAP_TIME_OFFSET); 23065796c8dcSSimon Schubert uid = getuid(); 23075796c8dcSSimon Schubert gid = getgid(); 23085796c8dcSSimon Schubert } 23095796c8dcSSimon Schubert else 23105796c8dcSSimon Schubert { 23115796c8dcSSimon Schubert /* If deterministic, we use 0 as the timestamp in the map. 23125796c8dcSSimon Schubert Some linkers may require that the archive filesystem modification 23135796c8dcSSimon Schubert time is less than (or near to) the archive map timestamp. Those 23145796c8dcSSimon Schubert linkers should not be used with deterministic mode. (GNU ld and 23155796c8dcSSimon Schubert Gold do not have this restriction.) */ 23165796c8dcSSimon Schubert bfd_ardata (arch)->armap_timestamp = 0; 23175796c8dcSSimon Schubert uid = 0; 23185796c8dcSSimon Schubert gid = 0; 23195796c8dcSSimon Schubert } 23205796c8dcSSimon Schubert 23215796c8dcSSimon Schubert memset (&hdr, ' ', sizeof (struct ar_hdr)); 23225796c8dcSSimon Schubert memcpy (hdr.ar_name, RANLIBMAG, strlen (RANLIBMAG)); 23235796c8dcSSimon Schubert bfd_ardata (arch)->armap_datepos = (SARMAG 23245796c8dcSSimon Schubert + offsetof (struct ar_hdr, ar_date[0])); 23255796c8dcSSimon Schubert _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", 23265796c8dcSSimon Schubert bfd_ardata (arch)->armap_timestamp); 23275796c8dcSSimon Schubert _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", uid); 23285796c8dcSSimon Schubert _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", gid); 23295796c8dcSSimon Schubert _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", mapsize); 23305796c8dcSSimon Schubert memcpy (hdr.ar_fmag, ARFMAG, 2); 23315796c8dcSSimon Schubert if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch) 23325796c8dcSSimon Schubert != sizeof (struct ar_hdr)) 23335796c8dcSSimon Schubert return FALSE; 23345796c8dcSSimon Schubert H_PUT_32 (arch, ranlibsize, temp); 23355796c8dcSSimon Schubert if (bfd_bwrite (temp, sizeof (temp), arch) != sizeof (temp)) 23365796c8dcSSimon Schubert return FALSE; 23375796c8dcSSimon Schubert 23385796c8dcSSimon Schubert for (count = 0; count < orl_count; count++) 23395796c8dcSSimon Schubert { 23405796c8dcSSimon Schubert bfd_byte buf[BSD_SYMDEF_SIZE]; 23415796c8dcSSimon Schubert 23425796c8dcSSimon Schubert if (map[count].u.abfd != last_elt) 23435796c8dcSSimon Schubert { 23445796c8dcSSimon Schubert do 23455796c8dcSSimon Schubert { 2346*cf7f2e2dSJohn Marino struct areltdata *ared = arch_eltdata (current); 2347*cf7f2e2dSJohn Marino 2348*cf7f2e2dSJohn Marino firstreal += (ared->parsed_size + ared->extra_size 2349*cf7f2e2dSJohn Marino + sizeof (struct ar_hdr)); 23505796c8dcSSimon Schubert firstreal += firstreal % 2; 23515796c8dcSSimon Schubert current = current->archive_next; 23525796c8dcSSimon Schubert } 23535796c8dcSSimon Schubert while (current != map[count].u.abfd); 23545796c8dcSSimon Schubert } 23555796c8dcSSimon Schubert 23565796c8dcSSimon Schubert last_elt = current; 23575796c8dcSSimon Schubert H_PUT_32 (arch, map[count].namidx, buf); 23585796c8dcSSimon Schubert H_PUT_32 (arch, firstreal, buf + BSD_SYMDEF_OFFSET_SIZE); 23595796c8dcSSimon Schubert if (bfd_bwrite (buf, BSD_SYMDEF_SIZE, arch) 23605796c8dcSSimon Schubert != BSD_SYMDEF_SIZE) 23615796c8dcSSimon Schubert return FALSE; 23625796c8dcSSimon Schubert } 23635796c8dcSSimon Schubert 23645796c8dcSSimon Schubert /* Now write the strings themselves. */ 23655796c8dcSSimon Schubert H_PUT_32 (arch, stringsize, temp); 23665796c8dcSSimon Schubert if (bfd_bwrite (temp, sizeof (temp), arch) != sizeof (temp)) 23675796c8dcSSimon Schubert return FALSE; 23685796c8dcSSimon Schubert for (count = 0; count < orl_count; count++) 23695796c8dcSSimon Schubert { 23705796c8dcSSimon Schubert size_t len = strlen (*map[count].name) + 1; 23715796c8dcSSimon Schubert 23725796c8dcSSimon Schubert if (bfd_bwrite (*map[count].name, len, arch) != len) 23735796c8dcSSimon Schubert return FALSE; 23745796c8dcSSimon Schubert } 23755796c8dcSSimon Schubert 23765796c8dcSSimon Schubert /* The spec sez this should be a newline. But in order to be 23775796c8dcSSimon Schubert bug-compatible for sun's ar we use a null. */ 23785796c8dcSSimon Schubert if (padit) 23795796c8dcSSimon Schubert { 23805796c8dcSSimon Schubert if (bfd_bwrite ("", 1, arch) != 1) 23815796c8dcSSimon Schubert return FALSE; 23825796c8dcSSimon Schubert } 23835796c8dcSSimon Schubert 23845796c8dcSSimon Schubert return TRUE; 23855796c8dcSSimon Schubert } 23865796c8dcSSimon Schubert 23875796c8dcSSimon Schubert /* At the end of archive file handling, update the timestamp in the 23885796c8dcSSimon Schubert file, so the linker will accept it. 23895796c8dcSSimon Schubert 23905796c8dcSSimon Schubert Return TRUE if the timestamp was OK, or an unusual problem happened. 23915796c8dcSSimon Schubert Return FALSE if we updated the timestamp. */ 23925796c8dcSSimon Schubert 23935796c8dcSSimon Schubert bfd_boolean 23945796c8dcSSimon Schubert _bfd_archive_bsd_update_armap_timestamp (bfd *arch) 23955796c8dcSSimon Schubert { 23965796c8dcSSimon Schubert struct stat archstat; 23975796c8dcSSimon Schubert struct ar_hdr hdr; 23985796c8dcSSimon Schubert 23995796c8dcSSimon Schubert /* If creating deterministic archives, just leave the timestamp as-is. */ 24005796c8dcSSimon Schubert if ((arch->flags & BFD_DETERMINISTIC_OUTPUT) != 0) 24015796c8dcSSimon Schubert return TRUE; 24025796c8dcSSimon Schubert 24035796c8dcSSimon Schubert /* Flush writes, get last-write timestamp from file, and compare it 24045796c8dcSSimon Schubert to the timestamp IN the file. */ 24055796c8dcSSimon Schubert bfd_flush (arch); 24065796c8dcSSimon Schubert if (bfd_stat (arch, &archstat) == -1) 24075796c8dcSSimon Schubert { 24085796c8dcSSimon Schubert bfd_perror (_("Reading archive file mod timestamp")); 24095796c8dcSSimon Schubert 24105796c8dcSSimon Schubert /* Can't read mod time for some reason. */ 24115796c8dcSSimon Schubert return TRUE; 24125796c8dcSSimon Schubert } 24135796c8dcSSimon Schubert if (((long) archstat.st_mtime) <= bfd_ardata (arch)->armap_timestamp) 24145796c8dcSSimon Schubert /* OK by the linker's rules. */ 24155796c8dcSSimon Schubert return TRUE; 24165796c8dcSSimon Schubert 24175796c8dcSSimon Schubert /* Update the timestamp. */ 24185796c8dcSSimon Schubert bfd_ardata (arch)->armap_timestamp = archstat.st_mtime + ARMAP_TIME_OFFSET; 24195796c8dcSSimon Schubert 24205796c8dcSSimon Schubert /* Prepare an ASCII version suitable for writing. */ 24215796c8dcSSimon Schubert memset (hdr.ar_date, ' ', sizeof (hdr.ar_date)); 24225796c8dcSSimon Schubert _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", 24235796c8dcSSimon Schubert bfd_ardata (arch)->armap_timestamp); 24245796c8dcSSimon Schubert 24255796c8dcSSimon Schubert /* Write it into the file. */ 24265796c8dcSSimon Schubert bfd_ardata (arch)->armap_datepos = (SARMAG 24275796c8dcSSimon Schubert + offsetof (struct ar_hdr, ar_date[0])); 24285796c8dcSSimon Schubert if (bfd_seek (arch, bfd_ardata (arch)->armap_datepos, SEEK_SET) != 0 24295796c8dcSSimon Schubert || (bfd_bwrite (hdr.ar_date, sizeof (hdr.ar_date), arch) 24305796c8dcSSimon Schubert != sizeof (hdr.ar_date))) 24315796c8dcSSimon Schubert { 24325796c8dcSSimon Schubert bfd_perror (_("Writing updated armap timestamp")); 24335796c8dcSSimon Schubert 24345796c8dcSSimon Schubert /* Some error while writing. */ 24355796c8dcSSimon Schubert return TRUE; 24365796c8dcSSimon Schubert } 24375796c8dcSSimon Schubert 24385796c8dcSSimon Schubert /* We updated the timestamp successfully. */ 24395796c8dcSSimon Schubert return FALSE; 24405796c8dcSSimon Schubert } 24415796c8dcSSimon Schubert 24425796c8dcSSimon Schubert /* A coff armap looks like : 24435796c8dcSSimon Schubert lARMAG 24445796c8dcSSimon Schubert struct ar_hdr with name = '/' 24455796c8dcSSimon Schubert number of symbols 24465796c8dcSSimon Schubert offset of file for symbol 0 24475796c8dcSSimon Schubert offset of file for symbol 1 24485796c8dcSSimon Schubert 24495796c8dcSSimon Schubert offset of file for symbol n-1 24505796c8dcSSimon Schubert symbol name 0 24515796c8dcSSimon Schubert symbol name 1 24525796c8dcSSimon Schubert 24535796c8dcSSimon Schubert symbol name n-1 */ 24545796c8dcSSimon Schubert 24555796c8dcSSimon Schubert bfd_boolean 24565796c8dcSSimon Schubert coff_write_armap (bfd *arch, 24575796c8dcSSimon Schubert unsigned int elength, 24585796c8dcSSimon Schubert struct orl *map, 24595796c8dcSSimon Schubert unsigned int symbol_count, 24605796c8dcSSimon Schubert int stridx) 24615796c8dcSSimon Schubert { 24625796c8dcSSimon Schubert /* The size of the ranlib is the number of exported symbols in the 24635796c8dcSSimon Schubert archive * the number of bytes in an int, + an int for the count. */ 24645796c8dcSSimon Schubert unsigned int ranlibsize = (symbol_count * 4) + 4; 24655796c8dcSSimon Schubert unsigned int stringsize = stridx; 24665796c8dcSSimon Schubert unsigned int mapsize = stringsize + ranlibsize; 24675796c8dcSSimon Schubert unsigned int archive_member_file_ptr; 24685796c8dcSSimon Schubert bfd *current = arch->archive_head; 24695796c8dcSSimon Schubert unsigned int count; 24705796c8dcSSimon Schubert struct ar_hdr hdr; 24715796c8dcSSimon Schubert int padit = mapsize & 1; 24725796c8dcSSimon Schubert 24735796c8dcSSimon Schubert if (padit) 24745796c8dcSSimon Schubert mapsize++; 24755796c8dcSSimon Schubert 24765796c8dcSSimon Schubert /* Work out where the first object file will go in the archive. */ 24775796c8dcSSimon Schubert archive_member_file_ptr = (mapsize 24785796c8dcSSimon Schubert + elength 24795796c8dcSSimon Schubert + sizeof (struct ar_hdr) 24805796c8dcSSimon Schubert + SARMAG); 24815796c8dcSSimon Schubert 24825796c8dcSSimon Schubert memset (&hdr, ' ', sizeof (struct ar_hdr)); 24835796c8dcSSimon Schubert hdr.ar_name[0] = '/'; 24845796c8dcSSimon Schubert _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", 24855796c8dcSSimon Schubert mapsize); 24865796c8dcSSimon Schubert _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", 24875796c8dcSSimon Schubert ((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0 24885796c8dcSSimon Schubert ? time (NULL) : 0)); 24895796c8dcSSimon Schubert /* This, at least, is what Intel coff sets the values to. */ 24905796c8dcSSimon Schubert _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0); 24915796c8dcSSimon Schubert _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0); 24925796c8dcSSimon Schubert _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0); 24935796c8dcSSimon Schubert memcpy (hdr.ar_fmag, ARFMAG, 2); 24945796c8dcSSimon Schubert 24955796c8dcSSimon Schubert /* Write the ar header for this item and the number of symbols. */ 24965796c8dcSSimon Schubert if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch) 24975796c8dcSSimon Schubert != sizeof (struct ar_hdr)) 24985796c8dcSSimon Schubert return FALSE; 24995796c8dcSSimon Schubert 25005796c8dcSSimon Schubert if (!bfd_write_bigendian_4byte_int (arch, symbol_count)) 25015796c8dcSSimon Schubert return FALSE; 25025796c8dcSSimon Schubert 25035796c8dcSSimon Schubert /* Two passes, first write the file offsets for each symbol - 25045796c8dcSSimon Schubert remembering that each offset is on a two byte boundary. */ 25055796c8dcSSimon Schubert 25065796c8dcSSimon Schubert /* Write out the file offset for the file associated with each 25075796c8dcSSimon Schubert symbol, and remember to keep the offsets padded out. */ 25085796c8dcSSimon Schubert 25095796c8dcSSimon Schubert current = arch->archive_head; 25105796c8dcSSimon Schubert count = 0; 25115796c8dcSSimon Schubert while (current != NULL && count < symbol_count) 25125796c8dcSSimon Schubert { 25135796c8dcSSimon Schubert /* For each symbol which is used defined in this object, write 25145796c8dcSSimon Schubert out the object file's address in the archive. */ 25155796c8dcSSimon Schubert 25165796c8dcSSimon Schubert while (count < symbol_count && map[count].u.abfd == current) 25175796c8dcSSimon Schubert { 25185796c8dcSSimon Schubert if (!bfd_write_bigendian_4byte_int (arch, archive_member_file_ptr)) 25195796c8dcSSimon Schubert return FALSE; 25205796c8dcSSimon Schubert count++; 25215796c8dcSSimon Schubert } 25225796c8dcSSimon Schubert archive_member_file_ptr += sizeof (struct ar_hdr); 25235796c8dcSSimon Schubert if (! bfd_is_thin_archive (arch)) 25245796c8dcSSimon Schubert { 25255796c8dcSSimon Schubert /* Add size of this archive entry. */ 25265796c8dcSSimon Schubert archive_member_file_ptr += arelt_size (current); 25275796c8dcSSimon Schubert /* Remember about the even alignment. */ 25285796c8dcSSimon Schubert archive_member_file_ptr += archive_member_file_ptr % 2; 25295796c8dcSSimon Schubert } 25305796c8dcSSimon Schubert current = current->archive_next; 25315796c8dcSSimon Schubert } 25325796c8dcSSimon Schubert 25335796c8dcSSimon Schubert /* Now write the strings themselves. */ 25345796c8dcSSimon Schubert for (count = 0; count < symbol_count; count++) 25355796c8dcSSimon Schubert { 25365796c8dcSSimon Schubert size_t len = strlen (*map[count].name) + 1; 25375796c8dcSSimon Schubert 25385796c8dcSSimon Schubert if (bfd_bwrite (*map[count].name, len, arch) != len) 25395796c8dcSSimon Schubert return FALSE; 25405796c8dcSSimon Schubert } 25415796c8dcSSimon Schubert 25425796c8dcSSimon Schubert /* The spec sez this should be a newline. But in order to be 25435796c8dcSSimon Schubert bug-compatible for arc960 we use a null. */ 25445796c8dcSSimon Schubert if (padit) 25455796c8dcSSimon Schubert { 25465796c8dcSSimon Schubert if (bfd_bwrite ("", 1, arch) != 1) 25475796c8dcSSimon Schubert return FALSE; 25485796c8dcSSimon Schubert } 25495796c8dcSSimon Schubert 25505796c8dcSSimon Schubert return TRUE; 25515796c8dcSSimon Schubert } 2552