Miscellaneous memory alloc related fixes
[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
a50b1753 111 raw_armap = (bfd_byte *) bfd_alloc (abfd, ptrsize);
36b45482
TS
112 if (raw_armap == NULL)
113 goto release_symdefs;
114
115 if (bfd_bread (raw_armap, ptrsize, abfd) != ptrsize
116 || bfd_bread (stringbase, stringsize, abfd) != stringsize)
117 {
118 if (bfd_get_error () != bfd_error_system_call)
119 bfd_set_error (bfd_error_malformed_archive);
806470a2 120 goto release_symdefs;
36b45482
TS
121 }
122
8abac803
AM
123 stringend = stringbase + stringsize;
124 *stringend = 0;
36b45482
TS
125 for (i = 0; i < nsymz; i++)
126 {
127 carsyms->file_offset = bfd_getb64 (raw_armap + i * 8);
128 carsyms->name = stringbase;
8abac803
AM
129 stringbase += strlen (stringbase);
130 if (stringbase != stringend)
131 ++stringbase;
36b45482
TS
132 ++carsyms;
133 }
36b45482
TS
134
135 ardata->symdef_count = nsymz;
136 ardata->first_file_filepos = bfd_tell (abfd);
137 /* Pad to an even boundary if you have to. */
138 ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
139
ed48ec2e 140 abfd->has_armap = TRUE;
36b45482
TS
141 bfd_release (abfd, raw_armap);
142
b34976b6 143 return TRUE;
36b45482 144
36b45482
TS
145release_symdefs:
146 bfd_release (abfd, ardata->symdefs);
b34976b6 147 return FALSE;
36b45482
TS
148}
149
150/* Write out an Irix 6 armap. The Irix 6 tools are supposed to be
151 able to handle ordinary ELF armaps, but at least on Irix 6.2 the
152 linker crashes. */
153
b34976b6 154bfd_boolean
e6cc316a
L
155_bfd_archive_64_bit_write_armap (bfd *arch,
156 unsigned int elength,
157 struct orl *map,
158 unsigned int symbol_count,
159 int stridx)
36b45482
TS
160{
161 unsigned int ranlibsize = (symbol_count * 8) + 8;
162 unsigned int stringsize = stridx;
163 unsigned int mapsize = stringsize + ranlibsize;
164 file_ptr archive_member_file_ptr;
165 bfd *current = arch->archive_head;
166 unsigned int count;
167 struct ar_hdr hdr;
36b45482
TS
168 int padding;
169 bfd_byte buf[8];
170
171 padding = BFD_ALIGN (mapsize, 8) - mapsize;
172 mapsize += padding;
173
174 /* work out where the first object file will go in the archive */
175 archive_member_file_ptr = (mapsize
176 + elength
177 + sizeof (struct ar_hdr)
178 + SARMAG);
179
390c0e42
JJ
180 memset (&hdr, ' ', sizeof (struct ar_hdr));
181 memcpy (hdr.ar_name, "/SYM64/", strlen ("/SYM64/"));
f1bb16f8
NC
182 if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
183 return FALSE;
390c0e42 184 _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
07d6d2b8 185 time (NULL));
36b45482 186 /* This, at least, is what Intel coff sets the values to.: */
390c0e42
JJ
187 _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
188 _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0);
189 _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0);
190 memcpy (hdr.ar_fmag, ARFMAG, 2);
36b45482
TS
191
192 /* Write the ar header for this item and the number of symbols */
193
c58b9523 194 if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
36b45482 195 != sizeof (struct ar_hdr))
b34976b6 196 return FALSE;
36b45482
TS
197
198 bfd_putb64 ((bfd_vma) symbol_count, buf);
c58b9523 199 if (bfd_bwrite (buf, 8, arch) != 8)
b34976b6 200 return FALSE;
36b45482
TS
201
202 /* Two passes, first write the file offsets for each symbol -
203 remembering that each offset is on a two byte boundary. */
204
205 /* Write out the file offset for the file associated with each
206 symbol, and remember to keep the offsets padded out. */
36b45482 207 count = 0;
61e8a5ea
NS
208 for (current = arch->archive_head;
209 current != NULL && count < symbol_count;
210 current = current->archive_next)
36b45482
TS
211 {
212 /* For each symbol which is used defined in this object, write out
17e3916e 213 the object file's address in the archive. */
36b45482 214
61e8a5ea
NS
215 for (;
216 count < symbol_count && map[count].u.abfd == current;
217 count++)
36b45482
TS
218 {
219 bfd_putb64 ((bfd_vma) archive_member_file_ptr, buf);
c58b9523 220 if (bfd_bwrite (buf, 8, arch) != 8)
b34976b6 221 return FALSE;
36b45482 222 }
17e3916e 223
36b45482 224 /* Add size of this archive entry */
17e3916e
NC
225 archive_member_file_ptr += sizeof (struct ar_hdr);
226 if (! bfd_is_thin_archive (arch))
227 archive_member_file_ptr += arelt_size (current);
36b45482
TS
228 /* remember about the even alignment */
229 archive_member_file_ptr += archive_member_file_ptr % 2;
36b45482
TS
230 }
231
232 /* now write the strings themselves */
233 for (count = 0; count < symbol_count; count++)
234 {
235 size_t len = strlen (*map[count].name) + 1;
236
c58b9523 237 if (bfd_bwrite (*map[count].name, len, arch) != len)
b34976b6 238 return FALSE;
36b45482
TS
239 }
240
241 /* The spec says that this should be padded to an 8 byte boundary.
242 However, the Irix 6.2 tools do not appear to do this. */
243 while (padding != 0)
244 {
c58b9523 245 if (bfd_bwrite ("", 1, arch) != 1)
b34976b6 246 return FALSE;
36b45482
TS
247 --padding;
248 }
249
b34976b6 250 return TRUE;
36b45482 251}
This page took 0.768235 seconds and 4 git commands to generate.