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>