Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / archive64.c
CommitLineData
e6cc316a 1/* Support for 64-bit archives.
b3adc24a 2 Copyright (C) 1996-2020 Free Software Foundation, Inc.
36b45482
TS
3 Ian Lance Taylor, Cygnus Support
4 Linker support added by Mark Mitchell, CodeSourcery, LLC.
5 <mark@codesourcery.com>
6
0112cd26 7 This file is part of BFD, the Binary File Descriptor library.
36b45482 8
0112cd26
NC
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
cd123cb7 11 the Free Software Foundation; either version 3 of the License, or
0112cd26 12 (at your option) any later version.
36b45482 13
0112cd26
NC
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.
36b45482 18
0112cd26
NC
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
cd123cb7
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
36b45482 23
e6cc316a
L
24/* This file supports the 64-bit archives. We use the same format as
25 the 64-bit (MIPS) ELF archives. */
36b45482 26
36b45482 27#include "sysdep.h"
3db64b00 28#include "bfd.h"
36b45482
TS
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
36b45482
TS
35/* Read an Irix 6 armap. */
36
b34976b6 37bfd_boolean
e6cc316a 38_bfd_archive_64_bit_slurp_armap (bfd *abfd)
36b45482
TS
39{
40 struct artdata *ardata = bfd_ardata (abfd);
41 char nextname[17];
36b45482
TS
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;
f64e188b 46 char *stringend;
36b45482
TS
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. */
c58b9523 54 i = bfd_bread (nextname, 16, abfd);
36b45482 55 if (i == 0)
b34976b6 56 return TRUE;
36b45482 57 if (i != 16)
b34976b6 58 return FALSE;
36b45482
TS
59
60 if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)
b34976b6 61 return FALSE;
36b45482
TS
62
63 /* Archives with traditional armaps are still permitted. */
0112cd26 64 if (CONST_STRNEQ (nextname, "/ "))
36b45482
TS
65 return bfd_slurp_armap (abfd);
66
0112cd26 67 if (! CONST_STRNEQ (nextname, "/SYM64/ "))
36b45482 68 {
ed48ec2e 69 abfd->has_armap = FALSE;
b34976b6 70 return TRUE;
36b45482
TS
71 }
72
73 mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
74 if (mapdata == NULL)
b34976b6 75 return FALSE;
36b45482 76 parsed_size = mapdata->parsed_size;
06e7acd7 77 free (mapdata);
36b45482 78
c58b9523 79 if (bfd_bread (int_buf, 8, abfd) != 8)
36b45482
TS
80 {
81 if (bfd_get_error () != bfd_error_system_call)
82 bfd_set_error (bfd_error_malformed_archive);
b34976b6 83 return FALSE;
36b45482
TS
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;
97b031c5
AM
93 if (/* Catch overflow in stringsize (and ptrsize) expression. */
94 nsymz >= (bfd_size_type) -1 / 8
95 || stringsize > parsed_size
96 /* Catch overflow in carsym_size expression. */
97 || nsymz > (bfd_size_type) -1 / sizeof (carsym)
98 /* Catch overflow in amt expression. */
99 || amt <= carsym_size
100 || amt <= stringsize)
f64e188b
NC
101 {
102 bfd_set_error (bfd_error_malformed_archive);
103 return FALSE;
104 }
a50b1753 105 ardata->symdefs = (struct carsym *) bfd_zalloc (abfd, amt);
36b45482 106 if (ardata->symdefs == NULL)
b34976b6 107 return FALSE;
36b45482
TS
108 carsyms = ardata->symdefs;
109 stringbase = ((char *) ardata->symdefs) + carsym_size;
110
2bb3687b
AM
111 raw_armap = (bfd_byte *) _bfd_alloc_and_read (abfd, ptrsize, ptrsize);
112 if (raw_armap == NULL
36b45482
TS
113 || bfd_bread (stringbase, stringsize, abfd) != stringsize)
114 {
115 if (bfd_get_error () != bfd_error_system_call)
116 bfd_set_error (bfd_error_malformed_archive);
806470a2 117 goto release_symdefs;
36b45482
TS
118 }
119
8abac803
AM
120 stringend = stringbase + stringsize;
121 *stringend = 0;
36b45482
TS
122 for (i = 0; i < nsymz; i++)
123 {
124 carsyms->file_offset = bfd_getb64 (raw_armap + i * 8);
125 carsyms->name = stringbase;
8abac803
AM
126 stringbase += strlen (stringbase);
127 if (stringbase != stringend)
128 ++stringbase;
36b45482
TS
129 ++carsyms;
130 }
36b45482
TS
131
132 ardata->symdef_count = nsymz;
133 ardata->first_file_filepos = bfd_tell (abfd);
134 /* Pad to an even boundary if you have to. */
135 ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
136
ed48ec2e 137 abfd->has_armap = TRUE;
36b45482
TS
138 bfd_release (abfd, raw_armap);
139
b34976b6 140 return TRUE;
36b45482 141
dc1e8a47 142 release_symdefs:
36b45482 143 bfd_release (abfd, ardata->symdefs);
b34976b6 144 return FALSE;
36b45482
TS
145}
146
147/* Write out an Irix 6 armap. The Irix 6 tools are supposed to be
148 able to handle ordinary ELF armaps, but at least on Irix 6.2 the
149 linker crashes. */
150
b34976b6 151bfd_boolean
e6cc316a
L
152_bfd_archive_64_bit_write_armap (bfd *arch,
153 unsigned int elength,
154 struct orl *map,
155 unsigned int symbol_count,
156 int stridx)
36b45482
TS
157{
158 unsigned int ranlibsize = (symbol_count * 8) + 8;
159 unsigned int stringsize = stridx;
160 unsigned int mapsize = stringsize + ranlibsize;
161 file_ptr archive_member_file_ptr;
162 bfd *current = arch->archive_head;
163 unsigned int count;
164 struct ar_hdr hdr;
36b45482
TS
165 int padding;
166 bfd_byte buf[8];
167
168 padding = BFD_ALIGN (mapsize, 8) - mapsize;
169 mapsize += padding;
170
171 /* work out where the first object file will go in the archive */
172 archive_member_file_ptr = (mapsize
173 + elength
174 + sizeof (struct ar_hdr)
175 + SARMAG);
176
390c0e42
JJ
177 memset (&hdr, ' ', sizeof (struct ar_hdr));
178 memcpy (hdr.ar_name, "/SYM64/", strlen ("/SYM64/"));
f1bb16f8
NC
179 if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
180 return FALSE;
390c0e42 181 _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
07d6d2b8 182 time (NULL));
36b45482 183 /* This, at least, is what Intel coff sets the values to.: */
390c0e42
JJ
184 _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
185 _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0);
186 _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0);
187 memcpy (hdr.ar_fmag, ARFMAG, 2);
36b45482
TS
188
189 /* Write the ar header for this item and the number of symbols */
190
c58b9523 191 if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
36b45482 192 != sizeof (struct ar_hdr))
b34976b6 193 return FALSE;
36b45482
TS
194
195 bfd_putb64 ((bfd_vma) symbol_count, buf);
c58b9523 196 if (bfd_bwrite (buf, 8, arch) != 8)
b34976b6 197 return FALSE;
36b45482
TS
198
199 /* Two passes, first write the file offsets for each symbol -
200 remembering that each offset is on a two byte boundary. */
201
202 /* Write out the file offset for the file associated with each
203 symbol, and remember to keep the offsets padded out. */
36b45482 204 count = 0;
61e8a5ea
NS
205 for (current = arch->archive_head;
206 current != NULL && count < symbol_count;
207 current = current->archive_next)
36b45482
TS
208 {
209 /* For each symbol which is used defined in this object, write out
17e3916e 210 the object file's address in the archive. */
36b45482 211
61e8a5ea
NS
212 for (;
213 count < symbol_count && map[count].u.abfd == current;
214 count++)
36b45482
TS
215 {
216 bfd_putb64 ((bfd_vma) archive_member_file_ptr, buf);
c58b9523 217 if (bfd_bwrite (buf, 8, arch) != 8)
b34976b6 218 return FALSE;
36b45482 219 }
17e3916e 220
36b45482 221 /* Add size of this archive entry */
17e3916e
NC
222 archive_member_file_ptr += sizeof (struct ar_hdr);
223 if (! bfd_is_thin_archive (arch))
224 archive_member_file_ptr += arelt_size (current);
36b45482
TS
225 /* remember about the even alignment */
226 archive_member_file_ptr += archive_member_file_ptr % 2;
36b45482
TS
227 }
228
229 /* now write the strings themselves */
230 for (count = 0; count < symbol_count; count++)
231 {
232 size_t len = strlen (*map[count].name) + 1;
233
c58b9523 234 if (bfd_bwrite (*map[count].name, len, arch) != len)
b34976b6 235 return FALSE;
36b45482
TS
236 }
237
238 /* The spec says that this should be padded to an 8 byte boundary.
239 However, the Irix 6.2 tools do not appear to do this. */
240 while (padding != 0)
241 {
c58b9523 242 if (bfd_bwrite ("", 1, arch) != 1)
b34976b6 243 return FALSE;
36b45482
TS
244 --padding;
245 }
246
b34976b6 247 return TRUE;
36b45482 248}
This page took 1.139986 seconds and 4 git commands to generate.