[BACK]Return to archive64.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils.old / dist / bfd

Annotation of src/external/gpl3/binutils.old/dist/bfd/archive64.c, Revision 1.6

1.5       christos    1: /* Support for 64-bit archives.
1.6     ! christos    2:    Copyright (C) 1996-2018 Free Software Foundation, Inc.
1.1       christos    3:    Ian Lance Taylor, Cygnus Support
                      4:    Linker support added by Mark Mitchell, CodeSourcery, LLC.
                      5:    <mark@codesourcery.com>
                      6:
                      7:    This file is part of BFD, the Binary File Descriptor library.
                      8:
                      9:    This program is free software; you can redistribute it and/or modify
                     10:    it under the terms of the GNU General Public License as published by
                     11:    the Free Software Foundation; either version 3 of the License, or
                     12:    (at your option) any later version.
                     13:
                     14:    This program is distributed in the hope that it will be useful,
                     15:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     16:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     17:    GNU General Public License for more details.
                     18:
                     19:    You should have received a copy of the GNU General Public License
                     20:    along with this program; if not, write to the Free Software
                     21:    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
                     22:    MA 02110-1301, USA.  */
                     23:
1.5       christos   24: /* This file supports the 64-bit archives.  We use the same format as
                     25:    the 64-bit (MIPS) ELF archives.  */
1.1       christos   26:
                     27: #include "sysdep.h"
                     28: #include "bfd.h"
                     29: #include "libbfd.h"
                     30: #include "aout/ar.h"
                     31:
                     32: /* Irix 6 defines a 64bit archive map format, so that they can
                     33:    have archives more than 4 GB in size.  */
                     34:
                     35: /* Read an Irix 6 armap.  */
                     36:
                     37: bfd_boolean
1.5       christos   38: _bfd_archive_64_bit_slurp_armap (bfd *abfd)
1.1       christos   39: {
                     40:   struct artdata *ardata = bfd_ardata (abfd);
                     41:   char nextname[17];
                     42:   bfd_size_type i, parsed_size, nsymz, stringsize, carsym_size, ptrsize;
                     43:   struct areltdata *mapdata;
                     44:   bfd_byte int_buf[8];
                     45:   char *stringbase;
1.3       christos   46:   char *stringend;
1.1       christos   47:   bfd_byte *raw_armap = NULL;
                     48:   carsym *carsyms;
                     49:   bfd_size_type amt;
                     50:
                     51:   ardata->symdefs = NULL;
                     52:
                     53:   /* Get the name of the first element.  */
                     54:   i = bfd_bread (nextname, 16, abfd);
                     55:   if (i == 0)
                     56:     return TRUE;
                     57:   if (i != 16)
                     58:     return FALSE;
                     59:
                     60:   if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)
                     61:     return FALSE;
                     62:
                     63:   /* Archives with traditional armaps are still permitted.  */
                     64:   if (CONST_STRNEQ (nextname, "/               "))
                     65:     return bfd_slurp_armap (abfd);
                     66:
                     67:   if (! CONST_STRNEQ (nextname, "/SYM64/         "))
                     68:     {
                     69:       bfd_has_map (abfd) = FALSE;
                     70:       return TRUE;
                     71:     }
                     72:
                     73:   mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
                     74:   if (mapdata == NULL)
                     75:     return FALSE;
                     76:   parsed_size = mapdata->parsed_size;
1.3       christos   77:   free (mapdata);
1.1       christos   78:
                     79:   if (bfd_bread (int_buf, 8, abfd) != 8)
                     80:     {
                     81:       if (bfd_get_error () != bfd_error_system_call)
                     82:        bfd_set_error (bfd_error_malformed_archive);
                     83:       return FALSE;
                     84:     }
                     85:
                     86:   nsymz = bfd_getb64 (int_buf);
                     87:   stringsize = parsed_size - 8 * nsymz - 8;
                     88:
                     89:   carsym_size = nsymz * sizeof (carsym);
                     90:   ptrsize = 8 * nsymz;
                     91:
                     92:   amt = carsym_size + stringsize + 1;
1.3       christos   93:   if (carsym_size < nsymz || ptrsize < nsymz || amt < nsymz)
                     94:     {
                     95:       bfd_set_error (bfd_error_malformed_archive);
                     96:       return FALSE;
                     97:     }
1.1       christos   98:   ardata->symdefs = (struct carsym *) bfd_zalloc (abfd, amt);
                     99:   if (ardata->symdefs == NULL)
                    100:     return FALSE;
                    101:   carsyms = ardata->symdefs;
                    102:   stringbase = ((char *) ardata->symdefs) + carsym_size;
1.3       christos  103:   stringbase[stringsize] = 0;
                    104:   stringend = stringbase + stringsize;
1.1       christos  105:
                    106:   raw_armap = (bfd_byte *) bfd_alloc (abfd, ptrsize);
                    107:   if (raw_armap == NULL)
                    108:     goto release_symdefs;
                    109:
                    110:   if (bfd_bread (raw_armap, ptrsize, abfd) != ptrsize
                    111:       || bfd_bread (stringbase, stringsize, abfd) != stringsize)
                    112:     {
                    113:       if (bfd_get_error () != bfd_error_system_call)
                    114:        bfd_set_error (bfd_error_malformed_archive);
                    115:       goto release_raw_armap;
                    116:     }
                    117:
                    118:   for (i = 0; i < nsymz; i++)
                    119:     {
                    120:       carsyms->file_offset = bfd_getb64 (raw_armap + i * 8);
                    121:       carsyms->name = stringbase;
1.3       christos  122:       if (stringbase < stringend)
                    123:        stringbase += strlen (stringbase) + 1;
1.1       christos  124:       ++carsyms;
                    125:     }
                    126:   *stringbase = '\0';
                    127:
                    128:   ardata->symdef_count = nsymz;
                    129:   ardata->first_file_filepos = bfd_tell (abfd);
                    130:   /* Pad to an even boundary if you have to.  */
                    131:   ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
                    132:
                    133:   bfd_has_map (abfd) = TRUE;
                    134:   bfd_release (abfd, raw_armap);
                    135:
                    136:   return TRUE;
                    137:
                    138: release_raw_armap:
                    139:   bfd_release (abfd, raw_armap);
                    140: release_symdefs:
                    141:   bfd_release (abfd, ardata->symdefs);
                    142:   return FALSE;
                    143: }
                    144:
                    145: /* Write out an Irix 6 armap.  The Irix 6 tools are supposed to be
                    146:    able to handle ordinary ELF armaps, but at least on Irix 6.2 the
                    147:    linker crashes.  */
                    148:
                    149: bfd_boolean
1.5       christos  150: _bfd_archive_64_bit_write_armap (bfd *arch,
                    151:                                 unsigned int elength,
                    152:                                 struct orl *map,
                    153:                                 unsigned int symbol_count,
                    154:                                 int stridx)
1.1       christos  155: {
                    156:   unsigned int ranlibsize = (symbol_count * 8) + 8;
                    157:   unsigned int stringsize = stridx;
                    158:   unsigned int mapsize = stringsize + ranlibsize;
                    159:   file_ptr archive_member_file_ptr;
                    160:   bfd *current = arch->archive_head;
                    161:   unsigned int count;
                    162:   struct ar_hdr hdr;
                    163:   int padding;
                    164:   bfd_byte buf[8];
                    165:
                    166:   padding = BFD_ALIGN (mapsize, 8) - mapsize;
                    167:   mapsize += padding;
                    168:
                    169:   /* work out where the first object file will go in the archive */
                    170:   archive_member_file_ptr = (mapsize
                    171:                             + elength
                    172:                             + sizeof (struct ar_hdr)
                    173:                             + SARMAG);
                    174:
                    175:   memset (&hdr, ' ', sizeof (struct ar_hdr));
                    176:   memcpy (hdr.ar_name, "/SYM64/", strlen ("/SYM64/"));
                    177:   if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
                    178:     return FALSE;
                    179:   _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
1.6     ! christos  180:                    time (NULL));
1.1       christos  181:   /* This, at least, is what Intel coff sets the values to.: */
                    182:   _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
                    183:   _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0);
                    184:   _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0);
                    185:   memcpy (hdr.ar_fmag, ARFMAG, 2);
                    186:
                    187:   /* Write the ar header for this item and the number of symbols */
                    188:
                    189:   if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
                    190:       != sizeof (struct ar_hdr))
                    191:     return FALSE;
                    192:
                    193:   bfd_putb64 ((bfd_vma) symbol_count, buf);
                    194:   if (bfd_bwrite (buf, 8, arch) != 8)
                    195:     return FALSE;
                    196:
                    197:   /* Two passes, first write the file offsets for each symbol -
                    198:      remembering that each offset is on a two byte boundary.  */
                    199:
                    200:   /* Write out the file offset for the file associated with each
                    201:      symbol, and remember to keep the offsets padded out.  */
                    202:   count = 0;
                    203:   for (current = arch->archive_head;
                    204:        current != NULL && count < symbol_count;
                    205:        current = current->archive_next)
                    206:     {
                    207:       /* For each symbol which is used defined in this object, write out
1.3       christos  208:         the object file's address in the archive.  */
1.1       christos  209:
                    210:       for (;
                    211:           count < symbol_count && map[count].u.abfd == current;
                    212:           count++)
                    213:        {
                    214:          bfd_putb64 ((bfd_vma) archive_member_file_ptr, buf);
                    215:          if (bfd_bwrite (buf, 8, arch) != 8)
                    216:            return FALSE;
                    217:        }
1.3       christos  218:
1.1       christos  219:       /* Add size of this archive entry */
1.3       christos  220:       archive_member_file_ptr += sizeof (struct ar_hdr);
                    221:       if (! bfd_is_thin_archive (arch))
                    222:        archive_member_file_ptr += arelt_size (current);
1.1       christos  223:       /* remember about the even alignment */
                    224:       archive_member_file_ptr += archive_member_file_ptr % 2;
                    225:     }
                    226:
                    227:   /* now write the strings themselves */
                    228:   for (count = 0; count < symbol_count; count++)
                    229:     {
                    230:       size_t len = strlen (*map[count].name) + 1;
                    231:
                    232:       if (bfd_bwrite (*map[count].name, len, arch) != len)
                    233:        return FALSE;
                    234:     }
                    235:
                    236:   /* The spec says that this should be padded to an 8 byte boundary.
                    237:      However, the Irix 6.2 tools do not appear to do this.  */
                    238:   while (padding != 0)
                    239:     {
                    240:       if (bfd_bwrite ("", 1, arch) != 1)
                    241:        return FALSE;
                    242:       --padding;
                    243:     }
                    244:
                    245:   return TRUE;
                    246: }

CVSweb <webmaster@jp.NetBSD.org>