]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/archive64.c
Fix Common symbol override test fails
[thirdparty/binutils-gdb.git] / bfd / archive64.c
CommitLineData
e6cc316a 1/* Support for 64-bit archives.
2571583a 2 Copyright (C) 1996-2017 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 {
b34976b6
AM
69 bfd_has_map (abfd) = FALSE;
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;
f64e188b
NC
93 if (carsym_size < nsymz || ptrsize < nsymz || amt < nsymz)
94 {
95 bfd_set_error (bfd_error_malformed_archive);
96 return FALSE;
97 }
a50b1753 98 ardata->symdefs = (struct carsym *) bfd_zalloc (abfd, amt);
36b45482 99 if (ardata->symdefs == NULL)
b34976b6 100 return FALSE;
36b45482
TS
101 carsyms = ardata->symdefs;
102 stringbase = ((char *) ardata->symdefs) + carsym_size;
f64e188b
NC
103 stringbase[stringsize] = 0;
104 stringend = stringbase + stringsize;
36b45482 105
a50b1753 106 raw_armap = (bfd_byte *) bfd_alloc (abfd, ptrsize);
36b45482
TS
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;
f64e188b
NC
122 if (stringbase < stringend)
123 stringbase += strlen (stringbase) + 1;
36b45482
TS
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
b34976b6 133 bfd_has_map (abfd) = TRUE;
36b45482
TS
134 bfd_release (abfd, raw_armap);
135
b34976b6 136 return TRUE;
36b45482
TS
137
138release_raw_armap:
139 bfd_release (abfd, raw_armap);
140release_symdefs:
141 bfd_release (abfd, ardata->symdefs);
b34976b6 142 return FALSE;
36b45482
TS
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
b34976b6 149bfd_boolean
e6cc316a
L
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)
36b45482
TS
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;
36b45482
TS
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
390c0e42
JJ
175 memset (&hdr, ' ', sizeof (struct ar_hdr));
176 memcpy (hdr.ar_name, "/SYM64/", strlen ("/SYM64/"));
f1bb16f8
NC
177 if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
178 return FALSE;
390c0e42
JJ
179 _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
180 time (NULL));
36b45482 181 /* This, at least, is what Intel coff sets the values to.: */
390c0e42
JJ
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);
36b45482
TS
186
187 /* Write the ar header for this item and the number of symbols */
188
c58b9523 189 if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
36b45482 190 != sizeof (struct ar_hdr))
b34976b6 191 return FALSE;
36b45482
TS
192
193 bfd_putb64 ((bfd_vma) symbol_count, buf);
c58b9523 194 if (bfd_bwrite (buf, 8, arch) != 8)
b34976b6 195 return FALSE;
36b45482
TS
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. */
36b45482 202 count = 0;
61e8a5ea
NS
203 for (current = arch->archive_head;
204 current != NULL && count < symbol_count;
205 current = current->archive_next)
36b45482
TS
206 {
207 /* For each symbol which is used defined in this object, write out
17e3916e 208 the object file's address in the archive. */
36b45482 209
61e8a5ea
NS
210 for (;
211 count < symbol_count && map[count].u.abfd == current;
212 count++)
36b45482
TS
213 {
214 bfd_putb64 ((bfd_vma) archive_member_file_ptr, buf);
c58b9523 215 if (bfd_bwrite (buf, 8, arch) != 8)
b34976b6 216 return FALSE;
36b45482 217 }
17e3916e 218
36b45482 219 /* Add size of this archive entry */
17e3916e
NC
220 archive_member_file_ptr += sizeof (struct ar_hdr);
221 if (! bfd_is_thin_archive (arch))
222 archive_member_file_ptr += arelt_size (current);
36b45482
TS
223 /* remember about the even alignment */
224 archive_member_file_ptr += archive_member_file_ptr % 2;
36b45482
TS
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
c58b9523 232 if (bfd_bwrite (*map[count].name, len, arch) != len)
b34976b6 233 return FALSE;
36b45482
TS
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 {
c58b9523 240 if (bfd_bwrite ("", 1, arch) != 1)
b34976b6 241 return FALSE;
36b45482
TS
242 --padding;
243 }
244
b34976b6 245 return TRUE;
36b45482 246}