1ed0d50c3Schristos /* elfcomm.c -- common code for ELF format file.
2*b88e3e88Schristos Copyright (C) 2010-2020 Free Software Foundation, Inc.
3ed0d50c3Schristos
4ed0d50c3Schristos Originally developed by Eric Youngdale <eric@andante.jic.com>
5ed0d50c3Schristos Modifications by Nick Clifton <nickc@redhat.com>
6ed0d50c3Schristos
7ed0d50c3Schristos This file is part of GNU Binutils.
8ed0d50c3Schristos
9ed0d50c3Schristos This program is free software; you can redistribute it and/or modify
10ed0d50c3Schristos it under the terms of the GNU General Public License as published by
11ed0d50c3Schristos the Free Software Foundation; either version 3 of the License, or
12ed0d50c3Schristos (at your option) any later version.
13ed0d50c3Schristos
14ed0d50c3Schristos This program is distributed in the hope that it will be useful,
15ed0d50c3Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
16ed0d50c3Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17ed0d50c3Schristos GNU General Public License for more details.
18ed0d50c3Schristos
19ed0d50c3Schristos You should have received a copy of the GNU General Public License
20ed0d50c3Schristos along with this program; if not, write to the Free Software
21ed0d50c3Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22ed0d50c3Schristos 02110-1301, USA. */
23ed0d50c3Schristos
24ed0d50c3Schristos #include "sysdep.h"
25ed0d50c3Schristos #include "libiberty.h"
26ed0d50c3Schristos #include "filenames.h"
27ed0d50c3Schristos #include "bfd.h"
28ed0d50c3Schristos #include "aout/ar.h"
29ed0d50c3Schristos #include "bucomm.h"
30ed0d50c3Schristos #include "elfcomm.h"
31ed0d50c3Schristos #include <assert.h>
32ed0d50c3Schristos
33ed0d50c3Schristos void
error(const char * message,...)34ed0d50c3Schristos error (const char *message, ...)
35ed0d50c3Schristos {
36ed0d50c3Schristos va_list args;
37ed0d50c3Schristos
38ed0d50c3Schristos /* Try to keep error messages in sync with the program's normal output. */
39ed0d50c3Schristos fflush (stdout);
40ed0d50c3Schristos
41ed0d50c3Schristos va_start (args, message);
42ed0d50c3Schristos fprintf (stderr, _("%s: Error: "), program_name);
43ed0d50c3Schristos vfprintf (stderr, message, args);
44ed0d50c3Schristos va_end (args);
45ed0d50c3Schristos }
46ed0d50c3Schristos
47ed0d50c3Schristos void
warn(const char * message,...)48ed0d50c3Schristos warn (const char *message, ...)
49ed0d50c3Schristos {
50ed0d50c3Schristos va_list args;
51ed0d50c3Schristos
52ed0d50c3Schristos /* Try to keep warning messages in sync with the program's normal output. */
53ed0d50c3Schristos fflush (stdout);
54ed0d50c3Schristos
55ed0d50c3Schristos va_start (args, message);
56ed0d50c3Schristos fprintf (stderr, _("%s: Warning: "), program_name);
57ed0d50c3Schristos vfprintf (stderr, message, args);
58ed0d50c3Schristos va_end (args);
59ed0d50c3Schristos }
60ed0d50c3Schristos
61ed0d50c3Schristos void (*byte_put) (unsigned char *, elf_vma, int);
62ed0d50c3Schristos
63ed0d50c3Schristos void
byte_put_little_endian(unsigned char * field,elf_vma value,int size)64ed0d50c3Schristos byte_put_little_endian (unsigned char * field, elf_vma value, int size)
65ed0d50c3Schristos {
66ed0d50c3Schristos switch (size)
67ed0d50c3Schristos {
68ed0d50c3Schristos case 8:
69ed0d50c3Schristos field[7] = (((value >> 24) >> 24) >> 8) & 0xff;
70ed0d50c3Schristos field[6] = ((value >> 24) >> 24) & 0xff;
71ed0d50c3Schristos field[5] = ((value >> 24) >> 16) & 0xff;
72ed0d50c3Schristos field[4] = ((value >> 24) >> 8) & 0xff;
73ed0d50c3Schristos /* Fall through. */
74ed0d50c3Schristos case 4:
75ed0d50c3Schristos field[3] = (value >> 24) & 0xff;
76ed0d50c3Schristos /* Fall through. */
77ed0d50c3Schristos case 3:
78ed0d50c3Schristos field[2] = (value >> 16) & 0xff;
79ed0d50c3Schristos /* Fall through. */
80ed0d50c3Schristos case 2:
81ed0d50c3Schristos field[1] = (value >> 8) & 0xff;
82ed0d50c3Schristos /* Fall through. */
83ed0d50c3Schristos case 1:
84ed0d50c3Schristos field[0] = value & 0xff;
85ed0d50c3Schristos break;
86ed0d50c3Schristos
87ed0d50c3Schristos default:
88ed0d50c3Schristos error (_("Unhandled data length: %d\n"), size);
89ed0d50c3Schristos abort ();
90ed0d50c3Schristos }
91ed0d50c3Schristos }
92ed0d50c3Schristos
93ed0d50c3Schristos void
byte_put_big_endian(unsigned char * field,elf_vma value,int size)94ed0d50c3Schristos byte_put_big_endian (unsigned char * field, elf_vma value, int size)
95ed0d50c3Schristos {
96ed0d50c3Schristos switch (size)
97ed0d50c3Schristos {
98ed0d50c3Schristos case 8:
99ed0d50c3Schristos field[7] = value & 0xff;
100ed0d50c3Schristos field[6] = (value >> 8) & 0xff;
101ed0d50c3Schristos field[5] = (value >> 16) & 0xff;
102ed0d50c3Schristos field[4] = (value >> 24) & 0xff;
103ed0d50c3Schristos value >>= 16;
104ed0d50c3Schristos value >>= 16;
105ed0d50c3Schristos /* Fall through. */
106ed0d50c3Schristos case 4:
107ed0d50c3Schristos field[3] = value & 0xff;
108ed0d50c3Schristos value >>= 8;
109ed0d50c3Schristos /* Fall through. */
110ed0d50c3Schristos case 3:
111ed0d50c3Schristos field[2] = value & 0xff;
112ed0d50c3Schristos value >>= 8;
113ed0d50c3Schristos /* Fall through. */
114ed0d50c3Schristos case 2:
115ed0d50c3Schristos field[1] = value & 0xff;
116ed0d50c3Schristos value >>= 8;
117ed0d50c3Schristos /* Fall through. */
118ed0d50c3Schristos case 1:
119ed0d50c3Schristos field[0] = value & 0xff;
120ed0d50c3Schristos break;
121ed0d50c3Schristos
122ed0d50c3Schristos default:
123ed0d50c3Schristos error (_("Unhandled data length: %d\n"), size);
124ed0d50c3Schristos abort ();
125ed0d50c3Schristos }
126ed0d50c3Schristos }
127ed0d50c3Schristos
12806324dcfSchristos elf_vma (*byte_get) (const unsigned char *, int);
129ed0d50c3Schristos
130ed0d50c3Schristos elf_vma
byte_get_little_endian(const unsigned char * field,int size)13106324dcfSchristos byte_get_little_endian (const unsigned char *field, int size)
132ed0d50c3Schristos {
133ed0d50c3Schristos switch (size)
134ed0d50c3Schristos {
135ed0d50c3Schristos case 1:
136ed0d50c3Schristos return *field;
137ed0d50c3Schristos
138ed0d50c3Schristos case 2:
139ed0d50c3Schristos return ((unsigned int) (field[0]))
140ed0d50c3Schristos | (((unsigned int) (field[1])) << 8);
141ed0d50c3Schristos
142ed0d50c3Schristos case 3:
143ed0d50c3Schristos return ((unsigned long) (field[0]))
144ed0d50c3Schristos | (((unsigned long) (field[1])) << 8)
145ed0d50c3Schristos | (((unsigned long) (field[2])) << 16);
146ed0d50c3Schristos
147ed0d50c3Schristos case 4:
148ed0d50c3Schristos return ((unsigned long) (field[0]))
149ed0d50c3Schristos | (((unsigned long) (field[1])) << 8)
150ed0d50c3Schristos | (((unsigned long) (field[2])) << 16)
151ed0d50c3Schristos | (((unsigned long) (field[3])) << 24);
152ed0d50c3Schristos
153ed0d50c3Schristos case 5:
154ed0d50c3Schristos if (sizeof (elf_vma) == 8)
155ed0d50c3Schristos return ((elf_vma) (field[0]))
156ed0d50c3Schristos | (((elf_vma) (field[1])) << 8)
157ed0d50c3Schristos | (((elf_vma) (field[2])) << 16)
158ed0d50c3Schristos | (((elf_vma) (field[3])) << 24)
159ed0d50c3Schristos | (((elf_vma) (field[4])) << 32);
160ed0d50c3Schristos else if (sizeof (elf_vma) == 4)
161ed0d50c3Schristos /* We want to extract data from an 8 byte wide field and
162ed0d50c3Schristos place it into a 4 byte wide field. Since this is a little
163ed0d50c3Schristos endian source we can just use the 4 byte extraction code. */
164ed0d50c3Schristos return ((unsigned long) (field[0]))
165ed0d50c3Schristos | (((unsigned long) (field[1])) << 8)
166ed0d50c3Schristos | (((unsigned long) (field[2])) << 16)
167ed0d50c3Schristos | (((unsigned long) (field[3])) << 24);
16806324dcfSchristos /* Fall through. */
169ed0d50c3Schristos
170ed0d50c3Schristos case 6:
171ed0d50c3Schristos if (sizeof (elf_vma) == 8)
172ed0d50c3Schristos return ((elf_vma) (field[0]))
173ed0d50c3Schristos | (((elf_vma) (field[1])) << 8)
174ed0d50c3Schristos | (((elf_vma) (field[2])) << 16)
175ed0d50c3Schristos | (((elf_vma) (field[3])) << 24)
176ed0d50c3Schristos | (((elf_vma) (field[4])) << 32)
177ed0d50c3Schristos | (((elf_vma) (field[5])) << 40);
178ed0d50c3Schristos else if (sizeof (elf_vma) == 4)
179ed0d50c3Schristos /* We want to extract data from an 8 byte wide field and
180ed0d50c3Schristos place it into a 4 byte wide field. Since this is a little
181ed0d50c3Schristos endian source we can just use the 4 byte extraction code. */
182ed0d50c3Schristos return ((unsigned long) (field[0]))
183ed0d50c3Schristos | (((unsigned long) (field[1])) << 8)
184ed0d50c3Schristos | (((unsigned long) (field[2])) << 16)
185ed0d50c3Schristos | (((unsigned long) (field[3])) << 24);
18606324dcfSchristos /* Fall through. */
187ed0d50c3Schristos
188ed0d50c3Schristos case 7:
189ed0d50c3Schristos if (sizeof (elf_vma) == 8)
190ed0d50c3Schristos return ((elf_vma) (field[0]))
191ed0d50c3Schristos | (((elf_vma) (field[1])) << 8)
192ed0d50c3Schristos | (((elf_vma) (field[2])) << 16)
193ed0d50c3Schristos | (((elf_vma) (field[3])) << 24)
194ed0d50c3Schristos | (((elf_vma) (field[4])) << 32)
195ed0d50c3Schristos | (((elf_vma) (field[5])) << 40)
196ed0d50c3Schristos | (((elf_vma) (field[6])) << 48);
197ed0d50c3Schristos else if (sizeof (elf_vma) == 4)
198ed0d50c3Schristos /* We want to extract data from an 8 byte wide field and
199ed0d50c3Schristos place it into a 4 byte wide field. Since this is a little
200ed0d50c3Schristos endian source we can just use the 4 byte extraction code. */
201ed0d50c3Schristos return ((unsigned long) (field[0]))
202ed0d50c3Schristos | (((unsigned long) (field[1])) << 8)
203ed0d50c3Schristos | (((unsigned long) (field[2])) << 16)
204ed0d50c3Schristos | (((unsigned long) (field[3])) << 24);
20506324dcfSchristos /* Fall through. */
206ed0d50c3Schristos
207ed0d50c3Schristos case 8:
208ed0d50c3Schristos if (sizeof (elf_vma) == 8)
209ed0d50c3Schristos return ((elf_vma) (field[0]))
210ed0d50c3Schristos | (((elf_vma) (field[1])) << 8)
211ed0d50c3Schristos | (((elf_vma) (field[2])) << 16)
212ed0d50c3Schristos | (((elf_vma) (field[3])) << 24)
213ed0d50c3Schristos | (((elf_vma) (field[4])) << 32)
214ed0d50c3Schristos | (((elf_vma) (field[5])) << 40)
215ed0d50c3Schristos | (((elf_vma) (field[6])) << 48)
216ed0d50c3Schristos | (((elf_vma) (field[7])) << 56);
217ed0d50c3Schristos else if (sizeof (elf_vma) == 4)
218ed0d50c3Schristos /* We want to extract data from an 8 byte wide field and
219ed0d50c3Schristos place it into a 4 byte wide field. Since this is a little
220ed0d50c3Schristos endian source we can just use the 4 byte extraction code. */
221ed0d50c3Schristos return ((unsigned long) (field[0]))
222ed0d50c3Schristos | (((unsigned long) (field[1])) << 8)
223ed0d50c3Schristos | (((unsigned long) (field[2])) << 16)
224ed0d50c3Schristos | (((unsigned long) (field[3])) << 24);
22506324dcfSchristos /* Fall through. */
226ed0d50c3Schristos
227ed0d50c3Schristos default:
228ed0d50c3Schristos error (_("Unhandled data length: %d\n"), size);
229ed0d50c3Schristos abort ();
230ed0d50c3Schristos }
231ed0d50c3Schristos }
232ed0d50c3Schristos
233ed0d50c3Schristos elf_vma
byte_get_big_endian(const unsigned char * field,int size)23406324dcfSchristos byte_get_big_endian (const unsigned char *field, int size)
235ed0d50c3Schristos {
236ed0d50c3Schristos switch (size)
237ed0d50c3Schristos {
238ed0d50c3Schristos case 1:
239ed0d50c3Schristos return *field;
240ed0d50c3Schristos
241ed0d50c3Schristos case 2:
242ed0d50c3Schristos return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);
243ed0d50c3Schristos
244ed0d50c3Schristos case 3:
245ed0d50c3Schristos return ((unsigned long) (field[2]))
246ed0d50c3Schristos | (((unsigned long) (field[1])) << 8)
247ed0d50c3Schristos | (((unsigned long) (field[0])) << 16);
248ed0d50c3Schristos
249ed0d50c3Schristos case 4:
250ed0d50c3Schristos return ((unsigned long) (field[3]))
251ed0d50c3Schristos | (((unsigned long) (field[2])) << 8)
252ed0d50c3Schristos | (((unsigned long) (field[1])) << 16)
253ed0d50c3Schristos | (((unsigned long) (field[0])) << 24);
254ed0d50c3Schristos
255ed0d50c3Schristos case 5:
256ed0d50c3Schristos if (sizeof (elf_vma) == 8)
257ed0d50c3Schristos return ((elf_vma) (field[4]))
258ed0d50c3Schristos | (((elf_vma) (field[3])) << 8)
259ed0d50c3Schristos | (((elf_vma) (field[2])) << 16)
260ed0d50c3Schristos | (((elf_vma) (field[1])) << 24)
261ed0d50c3Schristos | (((elf_vma) (field[0])) << 32);
262ed0d50c3Schristos else if (sizeof (elf_vma) == 4)
263ed0d50c3Schristos {
264ed0d50c3Schristos /* Although we are extracting data from an 8 byte wide field,
265ed0d50c3Schristos we are returning only 4 bytes of data. */
266ed0d50c3Schristos field += 1;
267ed0d50c3Schristos return ((unsigned long) (field[3]))
268ed0d50c3Schristos | (((unsigned long) (field[2])) << 8)
269ed0d50c3Schristos | (((unsigned long) (field[1])) << 16)
270ed0d50c3Schristos | (((unsigned long) (field[0])) << 24);
271ed0d50c3Schristos }
27206324dcfSchristos /* Fall through. */
273ed0d50c3Schristos
274ed0d50c3Schristos case 6:
275ed0d50c3Schristos if (sizeof (elf_vma) == 8)
276ed0d50c3Schristos return ((elf_vma) (field[5]))
277ed0d50c3Schristos | (((elf_vma) (field[4])) << 8)
278ed0d50c3Schristos | (((elf_vma) (field[3])) << 16)
279ed0d50c3Schristos | (((elf_vma) (field[2])) << 24)
280ed0d50c3Schristos | (((elf_vma) (field[1])) << 32)
281ed0d50c3Schristos | (((elf_vma) (field[0])) << 40);
282ed0d50c3Schristos else if (sizeof (elf_vma) == 4)
283ed0d50c3Schristos {
284ed0d50c3Schristos /* Although we are extracting data from an 8 byte wide field,
285ed0d50c3Schristos we are returning only 4 bytes of data. */
286ed0d50c3Schristos field += 2;
287ed0d50c3Schristos return ((unsigned long) (field[3]))
288ed0d50c3Schristos | (((unsigned long) (field[2])) << 8)
289ed0d50c3Schristos | (((unsigned long) (field[1])) << 16)
290ed0d50c3Schristos | (((unsigned long) (field[0])) << 24);
291ed0d50c3Schristos }
29206324dcfSchristos /* Fall through. */
293ed0d50c3Schristos
294ed0d50c3Schristos case 7:
295ed0d50c3Schristos if (sizeof (elf_vma) == 8)
296ed0d50c3Schristos return ((elf_vma) (field[6]))
297ed0d50c3Schristos | (((elf_vma) (field[5])) << 8)
298ed0d50c3Schristos | (((elf_vma) (field[4])) << 16)
299ed0d50c3Schristos | (((elf_vma) (field[3])) << 24)
300ed0d50c3Schristos | (((elf_vma) (field[2])) << 32)
301ed0d50c3Schristos | (((elf_vma) (field[1])) << 40)
302ed0d50c3Schristos | (((elf_vma) (field[0])) << 48);
303ed0d50c3Schristos else if (sizeof (elf_vma) == 4)
304ed0d50c3Schristos {
305ed0d50c3Schristos /* Although we are extracting data from an 8 byte wide field,
306ed0d50c3Schristos we are returning only 4 bytes of data. */
307ed0d50c3Schristos field += 3;
308ed0d50c3Schristos return ((unsigned long) (field[3]))
309ed0d50c3Schristos | (((unsigned long) (field[2])) << 8)
310ed0d50c3Schristos | (((unsigned long) (field[1])) << 16)
311ed0d50c3Schristos | (((unsigned long) (field[0])) << 24);
312ed0d50c3Schristos }
31306324dcfSchristos /* Fall through. */
314ed0d50c3Schristos
315ed0d50c3Schristos case 8:
316ed0d50c3Schristos if (sizeof (elf_vma) == 8)
317ed0d50c3Schristos return ((elf_vma) (field[7]))
318ed0d50c3Schristos | (((elf_vma) (field[6])) << 8)
319ed0d50c3Schristos | (((elf_vma) (field[5])) << 16)
320ed0d50c3Schristos | (((elf_vma) (field[4])) << 24)
321ed0d50c3Schristos | (((elf_vma) (field[3])) << 32)
322ed0d50c3Schristos | (((elf_vma) (field[2])) << 40)
323ed0d50c3Schristos | (((elf_vma) (field[1])) << 48)
324ed0d50c3Schristos | (((elf_vma) (field[0])) << 56);
325ed0d50c3Schristos else if (sizeof (elf_vma) == 4)
326ed0d50c3Schristos {
327ed0d50c3Schristos /* Although we are extracting data from an 8 byte wide field,
328ed0d50c3Schristos we are returning only 4 bytes of data. */
329ed0d50c3Schristos field += 4;
330ed0d50c3Schristos return ((unsigned long) (field[3]))
331ed0d50c3Schristos | (((unsigned long) (field[2])) << 8)
332ed0d50c3Schristos | (((unsigned long) (field[1])) << 16)
333ed0d50c3Schristos | (((unsigned long) (field[0])) << 24);
334ed0d50c3Schristos }
33506324dcfSchristos /* Fall through. */
336ed0d50c3Schristos
337ed0d50c3Schristos default:
338ed0d50c3Schristos error (_("Unhandled data length: %d\n"), size);
339ed0d50c3Schristos abort ();
340ed0d50c3Schristos }
341ed0d50c3Schristos }
342ed0d50c3Schristos
343ed0d50c3Schristos elf_vma
byte_get_signed(const unsigned char * field,int size)34406324dcfSchristos byte_get_signed (const unsigned char *field, int size)
345ed0d50c3Schristos {
346ed0d50c3Schristos elf_vma x = byte_get (field, size);
347ed0d50c3Schristos
348ed0d50c3Schristos switch (size)
349ed0d50c3Schristos {
350ed0d50c3Schristos case 1:
351ed0d50c3Schristos return (x ^ 0x80) - 0x80;
352ed0d50c3Schristos case 2:
353ed0d50c3Schristos return (x ^ 0x8000) - 0x8000;
354ed0d50c3Schristos case 3:
355ed0d50c3Schristos return (x ^ 0x800000) - 0x800000;
356ed0d50c3Schristos case 4:
357ed0d50c3Schristos return (x ^ 0x80000000) - 0x80000000;
358ed0d50c3Schristos case 5:
359ed0d50c3Schristos case 6:
360ed0d50c3Schristos case 7:
361ed0d50c3Schristos case 8:
362ed0d50c3Schristos /* Reads of 5-, 6-, and 7-byte numbers are the result of
363ed0d50c3Schristos trying to read past the end of a buffer, and will therefore
364ed0d50c3Schristos not have meaningful values, so we don't try to deal with
365ed0d50c3Schristos the sign in these cases. */
366ed0d50c3Schristos return x;
367ed0d50c3Schristos default:
368ed0d50c3Schristos abort ();
369ed0d50c3Schristos }
370ed0d50c3Schristos }
371ed0d50c3Schristos
372ed0d50c3Schristos /* Return the high-order 32-bits and the low-order 32-bits
373ed0d50c3Schristos of an 8-byte value separately. */
374ed0d50c3Schristos
375ed0d50c3Schristos void
byte_get_64(const unsigned char * field,elf_vma * high,elf_vma * low)37606324dcfSchristos byte_get_64 (const unsigned char *field, elf_vma *high, elf_vma *low)
377ed0d50c3Schristos {
378ed0d50c3Schristos if (byte_get == byte_get_big_endian)
379ed0d50c3Schristos {
380ed0d50c3Schristos *high = byte_get_big_endian (field, 4);
381ed0d50c3Schristos *low = byte_get_big_endian (field + 4, 4);
382ed0d50c3Schristos }
383ed0d50c3Schristos else
384ed0d50c3Schristos {
385ed0d50c3Schristos *high = byte_get_little_endian (field + 4, 4);
386ed0d50c3Schristos *low = byte_get_little_endian (field, 4);
387ed0d50c3Schristos }
388ed0d50c3Schristos return;
389ed0d50c3Schristos }
390ed0d50c3Schristos
391ed0d50c3Schristos /* Return the path name for a proxy entry in a thin archive, adjusted
392ed0d50c3Schristos relative to the path name of the thin archive itself if necessary.
393ed0d50c3Schristos Always returns a pointer to malloc'ed memory. */
394ed0d50c3Schristos
395ed0d50c3Schristos char *
adjust_relative_path(const char * file_name,const char * name,unsigned long name_len)396ed0d50c3Schristos adjust_relative_path (const char *file_name, const char *name,
397ed0d50c3Schristos unsigned long name_len)
398ed0d50c3Schristos {
399ed0d50c3Schristos char * member_file_name;
400ed0d50c3Schristos const char * base_name = lbasename (file_name);
401ed0d50c3Schristos size_t amt;
402ed0d50c3Schristos
403ed0d50c3Schristos /* This is a proxy entry for a thin archive member.
404ed0d50c3Schristos If the extended name table contains an absolute path
405ed0d50c3Schristos name, or if the archive is in the current directory,
406ed0d50c3Schristos use the path name as given. Otherwise, we need to
407ed0d50c3Schristos find the member relative to the directory where the
408ed0d50c3Schristos archive is located. */
409ed0d50c3Schristos if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
410ed0d50c3Schristos {
411ed0d50c3Schristos amt = name_len + 1;
412ed0d50c3Schristos if (amt == 0)
413ed0d50c3Schristos return NULL;
414ed0d50c3Schristos member_file_name = (char *) malloc (amt);
415ed0d50c3Schristos if (member_file_name == NULL)
416ed0d50c3Schristos {
417ed0d50c3Schristos error (_("Out of memory\n"));
418ed0d50c3Schristos return NULL;
419ed0d50c3Schristos }
420ed0d50c3Schristos memcpy (member_file_name, name, name_len);
421ed0d50c3Schristos member_file_name[name_len] = '\0';
422ed0d50c3Schristos }
423ed0d50c3Schristos else
424ed0d50c3Schristos {
425ed0d50c3Schristos /* Concatenate the path components of the archive file name
426ed0d50c3Schristos to the relative path name from the extended name table. */
427ed0d50c3Schristos size_t prefix_len = base_name - file_name;
428ed0d50c3Schristos
429ed0d50c3Schristos amt = prefix_len + name_len + 1;
430ed0d50c3Schristos /* PR 17531: file: 2896dc8b
431ed0d50c3Schristos Catch wraparound. */
432ed0d50c3Schristos if (amt < prefix_len || amt < name_len)
433ed0d50c3Schristos {
434ed0d50c3Schristos error (_("Abnormal length of thin archive member name: %lx\n"),
435ed0d50c3Schristos name_len);
436ed0d50c3Schristos return NULL;
437ed0d50c3Schristos }
438ed0d50c3Schristos
439ed0d50c3Schristos member_file_name = (char *) malloc (amt);
440ed0d50c3Schristos if (member_file_name == NULL)
441ed0d50c3Schristos {
442ed0d50c3Schristos error (_("Out of memory\n"));
443ed0d50c3Schristos return NULL;
444ed0d50c3Schristos }
445ed0d50c3Schristos memcpy (member_file_name, file_name, prefix_len);
446ed0d50c3Schristos memcpy (member_file_name + prefix_len, name, name_len);
447ed0d50c3Schristos member_file_name[prefix_len + name_len] = '\0';
448ed0d50c3Schristos }
449ed0d50c3Schristos return member_file_name;
450ed0d50c3Schristos }
451ed0d50c3Schristos
452ed0d50c3Schristos /* Processes the archive index table and symbol table in ARCH.
453ed0d50c3Schristos Entries in the index table are SIZEOF_AR_INDEX bytes long.
454ed0d50c3Schristos Fills in ARCH->next_arhdr_offset and ARCH->arhdr.
455ed0d50c3Schristos If READ_SYMBOLS is true then fills in ARCH->index_num, ARCH->index_array,
456ed0d50c3Schristos ARCH->sym_size and ARCH->sym_table.
457ed0d50c3Schristos It is the caller's responsibility to free ARCH->index_array and
458ed0d50c3Schristos ARCH->sym_table.
459ed0d50c3Schristos Returns TRUE upon success, FALSE otherwise.
460ed0d50c3Schristos If failure occurs an error message is printed. */
461ed0d50c3Schristos
462ed0d50c3Schristos static bfd_boolean
process_archive_index_and_symbols(struct archive_info * arch,unsigned int sizeof_ar_index,bfd_boolean read_symbols)463ed0d50c3Schristos process_archive_index_and_symbols (struct archive_info * arch,
464ed0d50c3Schristos unsigned int sizeof_ar_index,
465ed0d50c3Schristos bfd_boolean read_symbols)
466ed0d50c3Schristos {
467ed0d50c3Schristos size_t got;
468ed0d50c3Schristos unsigned long size;
46906324dcfSchristos char fmag_save;
470ed0d50c3Schristos
47106324dcfSchristos fmag_save = arch->arhdr.ar_fmag[0];
47206324dcfSchristos arch->arhdr.ar_fmag[0] = 0;
473ed0d50c3Schristos size = strtoul (arch->arhdr.ar_size, NULL, 10);
47406324dcfSchristos arch->arhdr.ar_fmag[0] = fmag_save;
475ed0d50c3Schristos /* PR 17531: file: 912bd7de. */
476ed0d50c3Schristos if ((signed long) size < 0)
477ed0d50c3Schristos {
478ed0d50c3Schristos error (_("%s: invalid archive header size: %ld\n"),
479ed0d50c3Schristos arch->file_name, size);
480ed0d50c3Schristos return FALSE;
481ed0d50c3Schristos }
482ed0d50c3Schristos
483ed0d50c3Schristos size = size + (size & 1);
484ed0d50c3Schristos
485ed0d50c3Schristos arch->next_arhdr_offset += sizeof arch->arhdr + size;
486ed0d50c3Schristos
487ed0d50c3Schristos if (! read_symbols)
488ed0d50c3Schristos {
489ed0d50c3Schristos if (fseek (arch->file, size, SEEK_CUR) != 0)
490ed0d50c3Schristos {
491ed0d50c3Schristos error (_("%s: failed to skip archive symbol table\n"),
492ed0d50c3Schristos arch->file_name);
493ed0d50c3Schristos return FALSE;
494ed0d50c3Schristos }
495ed0d50c3Schristos }
496ed0d50c3Schristos else
497ed0d50c3Schristos {
498ed0d50c3Schristos unsigned long i;
499ed0d50c3Schristos /* A buffer used to hold numbers read in from an archive index.
500ed0d50c3Schristos These are always SIZEOF_AR_INDEX bytes long and stored in
501ed0d50c3Schristos big-endian format. */
502ed0d50c3Schristos unsigned char integer_buffer[sizeof arch->index_num];
503ed0d50c3Schristos unsigned char * index_buffer;
504ed0d50c3Schristos
505ed0d50c3Schristos assert (sizeof_ar_index <= sizeof integer_buffer);
506ed0d50c3Schristos
507ed0d50c3Schristos /* Check the size of the archive index. */
508ed0d50c3Schristos if (size < sizeof_ar_index)
509ed0d50c3Schristos {
510ed0d50c3Schristos error (_("%s: the archive index is empty\n"), arch->file_name);
511ed0d50c3Schristos return FALSE;
512ed0d50c3Schristos }
513ed0d50c3Schristos
514ed0d50c3Schristos /* Read the number of entries in the archive index. */
515ed0d50c3Schristos got = fread (integer_buffer, 1, sizeof_ar_index, arch->file);
516ed0d50c3Schristos if (got != sizeof_ar_index)
517ed0d50c3Schristos {
518ed0d50c3Schristos error (_("%s: failed to read archive index\n"), arch->file_name);
519ed0d50c3Schristos return FALSE;
520ed0d50c3Schristos }
521ed0d50c3Schristos
522ed0d50c3Schristos arch->index_num = byte_get_big_endian (integer_buffer, sizeof_ar_index);
523ed0d50c3Schristos size -= sizeof_ar_index;
524ed0d50c3Schristos
525ed0d50c3Schristos if (size < arch->index_num * sizeof_ar_index
526ed0d50c3Schristos /* PR 17531: file: 585515d1. */
527ed0d50c3Schristos || size < arch->index_num)
528ed0d50c3Schristos {
529ed0d50c3Schristos error (_("%s: the archive index is supposed to have 0x%lx entries of %d bytes, but the size is only 0x%lx\n"),
530ed0d50c3Schristos arch->file_name, (long) arch->index_num, sizeof_ar_index, size);
531ed0d50c3Schristos return FALSE;
532ed0d50c3Schristos }
533ed0d50c3Schristos
534ed0d50c3Schristos /* Read in the archive index. */
535ed0d50c3Schristos index_buffer = (unsigned char *)
536ed0d50c3Schristos malloc (arch->index_num * sizeof_ar_index);
537ed0d50c3Schristos if (index_buffer == NULL)
538ed0d50c3Schristos {
539ed0d50c3Schristos error (_("Out of memory whilst trying to read archive symbol index\n"));
540ed0d50c3Schristos return FALSE;
541ed0d50c3Schristos }
542ed0d50c3Schristos
543ed0d50c3Schristos got = fread (index_buffer, sizeof_ar_index, arch->index_num, arch->file);
544ed0d50c3Schristos if (got != arch->index_num)
545ed0d50c3Schristos {
546ed0d50c3Schristos free (index_buffer);
547ed0d50c3Schristos error (_("%s: failed to read archive index\n"), arch->file_name);
548ed0d50c3Schristos return FALSE;
549ed0d50c3Schristos }
550ed0d50c3Schristos
551ed0d50c3Schristos size -= arch->index_num * sizeof_ar_index;
552ed0d50c3Schristos
553ed0d50c3Schristos /* Convert the index numbers into the host's numeric format. */
554ed0d50c3Schristos arch->index_array = (elf_vma *)
555ed0d50c3Schristos malloc (arch->index_num * sizeof (* arch->index_array));
556ed0d50c3Schristos if (arch->index_array == NULL)
557ed0d50c3Schristos {
558ed0d50c3Schristos free (index_buffer);
559ed0d50c3Schristos error (_("Out of memory whilst trying to convert the archive symbol index\n"));
560ed0d50c3Schristos return FALSE;
561ed0d50c3Schristos }
562ed0d50c3Schristos
563ed0d50c3Schristos for (i = 0; i < arch->index_num; i++)
564ed0d50c3Schristos arch->index_array[i] =
565ed0d50c3Schristos byte_get_big_endian ((unsigned char *) (index_buffer + (i * sizeof_ar_index)),
566ed0d50c3Schristos sizeof_ar_index);
567ed0d50c3Schristos free (index_buffer);
568ed0d50c3Schristos
569ed0d50c3Schristos /* The remaining space in the header is taken up by the symbol table. */
570ed0d50c3Schristos if (size < 1)
571ed0d50c3Schristos {
572ed0d50c3Schristos error (_("%s: the archive has an index but no symbols\n"),
573ed0d50c3Schristos arch->file_name);
574ed0d50c3Schristos return FALSE;
575ed0d50c3Schristos }
576ed0d50c3Schristos
577ed0d50c3Schristos arch->sym_table = (char *) malloc (size);
578ed0d50c3Schristos if (arch->sym_table == NULL)
579ed0d50c3Schristos {
580ed0d50c3Schristos error (_("Out of memory whilst trying to read archive index symbol table\n"));
581ed0d50c3Schristos return FALSE;
582ed0d50c3Schristos }
583ed0d50c3Schristos
584ed0d50c3Schristos arch->sym_size = size;
585ed0d50c3Schristos got = fread (arch->sym_table, 1, size, arch->file);
586ed0d50c3Schristos if (got != size)
587ed0d50c3Schristos {
588ed0d50c3Schristos error (_("%s: failed to read archive index symbol table\n"),
589ed0d50c3Schristos arch->file_name);
590ed0d50c3Schristos return FALSE;
591ed0d50c3Schristos }
592ed0d50c3Schristos }
593ed0d50c3Schristos
594ed0d50c3Schristos /* Read the next archive header. */
595ed0d50c3Schristos got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
596ed0d50c3Schristos if (got != sizeof arch->arhdr && got != 0)
597ed0d50c3Schristos {
598ed0d50c3Schristos error (_("%s: failed to read archive header following archive index\n"),
599ed0d50c3Schristos arch->file_name);
600ed0d50c3Schristos return FALSE;
601ed0d50c3Schristos }
602ed0d50c3Schristos
603ed0d50c3Schristos return TRUE;
604ed0d50c3Schristos }
605ed0d50c3Schristos
606ed0d50c3Schristos /* Read the symbol table and long-name table from an archive. */
607ed0d50c3Schristos
608ed0d50c3Schristos int
setup_archive(struct archive_info * arch,const char * file_name,FILE * file,bfd_boolean is_thin_archive,bfd_boolean read_symbols)609ed0d50c3Schristos setup_archive (struct archive_info *arch, const char *file_name,
610ed0d50c3Schristos FILE *file, bfd_boolean is_thin_archive,
611ed0d50c3Schristos bfd_boolean read_symbols)
612ed0d50c3Schristos {
613ed0d50c3Schristos size_t got;
614ed0d50c3Schristos
615ed0d50c3Schristos arch->file_name = strdup (file_name);
616ed0d50c3Schristos arch->file = file;
617ed0d50c3Schristos arch->index_num = 0;
618ed0d50c3Schristos arch->index_array = NULL;
619ed0d50c3Schristos arch->sym_table = NULL;
620ed0d50c3Schristos arch->sym_size = 0;
621ed0d50c3Schristos arch->longnames = NULL;
622ed0d50c3Schristos arch->longnames_size = 0;
623ed0d50c3Schristos arch->nested_member_origin = 0;
624ed0d50c3Schristos arch->is_thin_archive = is_thin_archive;
625*b88e3e88Schristos arch->uses_64bit_indices = FALSE;
626ed0d50c3Schristos arch->next_arhdr_offset = SARMAG;
627ed0d50c3Schristos
628ed0d50c3Schristos /* Read the first archive member header. */
629ed0d50c3Schristos if (fseek (file, SARMAG, SEEK_SET) != 0)
630ed0d50c3Schristos {
631ed0d50c3Schristos error (_("%s: failed to seek to first archive header\n"), file_name);
632ed0d50c3Schristos return 1;
633ed0d50c3Schristos }
634ed0d50c3Schristos got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
635ed0d50c3Schristos if (got != sizeof arch->arhdr)
636ed0d50c3Schristos {
637ed0d50c3Schristos if (got == 0)
638ed0d50c3Schristos return 0;
639ed0d50c3Schristos
640ed0d50c3Schristos error (_("%s: failed to read archive header\n"), file_name);
641ed0d50c3Schristos return 1;
642ed0d50c3Schristos }
643ed0d50c3Schristos
644ed0d50c3Schristos /* See if this is the archive symbol table. */
645ed0d50c3Schristos if (const_strneq (arch->arhdr.ar_name, "/ "))
646ed0d50c3Schristos {
647ed0d50c3Schristos if (! process_archive_index_and_symbols (arch, 4, read_symbols))
648ed0d50c3Schristos return 1;
649ed0d50c3Schristos }
650ed0d50c3Schristos else if (const_strneq (arch->arhdr.ar_name, "/SYM64/ "))
651ed0d50c3Schristos {
652*b88e3e88Schristos arch->uses_64bit_indices = TRUE;
653ed0d50c3Schristos if (! process_archive_index_and_symbols (arch, 8, read_symbols))
654ed0d50c3Schristos return 1;
655ed0d50c3Schristos }
656ed0d50c3Schristos else if (read_symbols)
657ed0d50c3Schristos printf (_("%s has no archive index\n"), file_name);
658ed0d50c3Schristos
659ed0d50c3Schristos if (const_strneq (arch->arhdr.ar_name, "// "))
660ed0d50c3Schristos {
661ed0d50c3Schristos /* This is the archive string table holding long member names. */
66206324dcfSchristos char fmag_save = arch->arhdr.ar_fmag[0];
66306324dcfSchristos arch->arhdr.ar_fmag[0] = 0;
664ed0d50c3Schristos arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
66506324dcfSchristos arch->arhdr.ar_fmag[0] = fmag_save;
666ed0d50c3Schristos /* PR 17531: file: 01068045. */
667ed0d50c3Schristos if (arch->longnames_size < 8)
668ed0d50c3Schristos {
669ed0d50c3Schristos error (_("%s: long name table is too small, (size = %ld)\n"),
670ed0d50c3Schristos file_name, arch->longnames_size);
671ed0d50c3Schristos return 1;
672ed0d50c3Schristos }
673ed0d50c3Schristos /* PR 17531: file: 639d6a26. */
674ed0d50c3Schristos if ((signed long) arch->longnames_size < 0)
675ed0d50c3Schristos {
676ed0d50c3Schristos error (_("%s: long name table is too big, (size = 0x%lx)\n"),
677ed0d50c3Schristos file_name, arch->longnames_size);
678ed0d50c3Schristos return 1;
679ed0d50c3Schristos }
680ed0d50c3Schristos
681ed0d50c3Schristos arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
682ed0d50c3Schristos
683ed0d50c3Schristos /* Plus one to allow for a string terminator. */
684ed0d50c3Schristos arch->longnames = (char *) malloc (arch->longnames_size + 1);
685ed0d50c3Schristos if (arch->longnames == NULL)
686ed0d50c3Schristos {
687ed0d50c3Schristos error (_("Out of memory reading long symbol names in archive\n"));
688ed0d50c3Schristos return 1;
689ed0d50c3Schristos }
690ed0d50c3Schristos
691ed0d50c3Schristos if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
692ed0d50c3Schristos {
693ed0d50c3Schristos free (arch->longnames);
694ed0d50c3Schristos arch->longnames = NULL;
695ed0d50c3Schristos error (_("%s: failed to read long symbol name string table\n"),
696ed0d50c3Schristos file_name);
697ed0d50c3Schristos return 1;
698ed0d50c3Schristos }
699ed0d50c3Schristos
700ed0d50c3Schristos if ((arch->longnames_size & 1) != 0)
701ed0d50c3Schristos getc (file);
702ed0d50c3Schristos
703ed0d50c3Schristos arch->longnames[arch->longnames_size] = 0;
704ed0d50c3Schristos }
705ed0d50c3Schristos
706ed0d50c3Schristos return 0;
707ed0d50c3Schristos }
708ed0d50c3Schristos
709ed0d50c3Schristos /* Open and setup a nested archive, if not already open. */
710ed0d50c3Schristos
711ed0d50c3Schristos int
setup_nested_archive(struct archive_info * nested_arch,const char * member_file_name)712ed0d50c3Schristos setup_nested_archive (struct archive_info *nested_arch,
713ed0d50c3Schristos const char *member_file_name)
714ed0d50c3Schristos {
715ed0d50c3Schristos FILE * member_file;
716ed0d50c3Schristos
717ed0d50c3Schristos /* Have we already setup this archive? */
718ed0d50c3Schristos if (nested_arch->file_name != NULL
719ed0d50c3Schristos && streq (nested_arch->file_name, member_file_name))
720ed0d50c3Schristos return 0;
721ed0d50c3Schristos
722ed0d50c3Schristos /* Close previous file and discard cached information. */
723ed0d50c3Schristos if (nested_arch->file != NULL)
724ed0d50c3Schristos fclose (nested_arch->file);
725ed0d50c3Schristos release_archive (nested_arch);
726ed0d50c3Schristos
727ed0d50c3Schristos member_file = fopen (member_file_name, "rb");
728ed0d50c3Schristos if (member_file == NULL)
729ed0d50c3Schristos return 1;
730ed0d50c3Schristos return setup_archive (nested_arch, member_file_name, member_file,
731ed0d50c3Schristos FALSE, FALSE);
732ed0d50c3Schristos }
733ed0d50c3Schristos
734ed0d50c3Schristos /* Release the memory used for the archive information. */
735ed0d50c3Schristos
736ed0d50c3Schristos void
release_archive(struct archive_info * arch)737ed0d50c3Schristos release_archive (struct archive_info * arch)
738ed0d50c3Schristos {
739ed0d50c3Schristos if (arch->file_name != NULL)
740ed0d50c3Schristos free (arch->file_name);
741ed0d50c3Schristos if (arch->index_array != NULL)
742ed0d50c3Schristos free (arch->index_array);
743ed0d50c3Schristos if (arch->sym_table != NULL)
744ed0d50c3Schristos free (arch->sym_table);
745ed0d50c3Schristos if (arch->longnames != NULL)
746ed0d50c3Schristos free (arch->longnames);
747ed0d50c3Schristos }
748ed0d50c3Schristos
749ed0d50c3Schristos /* Get the name of an archive member from the current archive header.
750ed0d50c3Schristos For simple names, this will modify the ar_name field of the current
751ed0d50c3Schristos archive header. For long names, it will return a pointer to the
752ed0d50c3Schristos longnames table. For nested archives, it will open the nested archive
753ed0d50c3Schristos and get the name recursively. NESTED_ARCH is a single-entry cache so
754ed0d50c3Schristos we don't keep rereading the same information from a nested archive. */
755ed0d50c3Schristos
756ed0d50c3Schristos char *
get_archive_member_name(struct archive_info * arch,struct archive_info * nested_arch)757ed0d50c3Schristos get_archive_member_name (struct archive_info *arch,
758ed0d50c3Schristos struct archive_info *nested_arch)
759ed0d50c3Schristos {
760ed0d50c3Schristos unsigned long j, k;
761ed0d50c3Schristos
762ed0d50c3Schristos if (arch->arhdr.ar_name[0] == '/')
763ed0d50c3Schristos {
764ed0d50c3Schristos /* We have a long name. */
765ed0d50c3Schristos char *endp;
766ed0d50c3Schristos char *member_file_name;
767ed0d50c3Schristos char *member_name;
76806324dcfSchristos char fmag_save;
769ed0d50c3Schristos
770ed0d50c3Schristos if (arch->longnames == NULL || arch->longnames_size == 0)
771ed0d50c3Schristos {
772ed0d50c3Schristos error (_("Archive member uses long names, but no longname table found\n"));
773ed0d50c3Schristos return NULL;
774ed0d50c3Schristos }
775ed0d50c3Schristos
776ed0d50c3Schristos arch->nested_member_origin = 0;
77706324dcfSchristos fmag_save = arch->arhdr.ar_fmag[0];
77806324dcfSchristos arch->arhdr.ar_fmag[0] = 0;
779ed0d50c3Schristos k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
780ed0d50c3Schristos if (arch->is_thin_archive && endp != NULL && * endp == ':')
781ed0d50c3Schristos arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
78206324dcfSchristos arch->arhdr.ar_fmag[0] = fmag_save;
783ed0d50c3Schristos
784ed0d50c3Schristos if (j > arch->longnames_size)
785ed0d50c3Schristos {
786ed0d50c3Schristos error (_("Found long name index (%ld) beyond end of long name table\n"),j);
787ed0d50c3Schristos return NULL;
788ed0d50c3Schristos }
789ed0d50c3Schristos while ((j < arch->longnames_size)
790ed0d50c3Schristos && (arch->longnames[j] != '\n')
791ed0d50c3Schristos && (arch->longnames[j] != '\0'))
792ed0d50c3Schristos j++;
793ed0d50c3Schristos if (j > 0 && arch->longnames[j-1] == '/')
794ed0d50c3Schristos j--;
795ed0d50c3Schristos if (j > arch->longnames_size)
796ed0d50c3Schristos j = arch->longnames_size;
797ed0d50c3Schristos arch->longnames[j] = '\0';
798ed0d50c3Schristos
799ed0d50c3Schristos if (!arch->is_thin_archive || arch->nested_member_origin == 0)
800ed0d50c3Schristos return arch->longnames + k;
801ed0d50c3Schristos
802ed0d50c3Schristos /* PR 17531: file: 2896dc8b. */
803ed0d50c3Schristos if (k >= j)
804ed0d50c3Schristos {
805ed0d50c3Schristos error (_("Invalid Thin archive member name\n"));
806ed0d50c3Schristos return NULL;
807ed0d50c3Schristos }
808ed0d50c3Schristos
809ed0d50c3Schristos /* This is a proxy for a member of a nested archive.
810ed0d50c3Schristos Find the name of the member in that archive. */
811ed0d50c3Schristos member_file_name = adjust_relative_path (arch->file_name,
812ed0d50c3Schristos arch->longnames + k, j - k);
813ed0d50c3Schristos if (member_file_name != NULL
814ed0d50c3Schristos && setup_nested_archive (nested_arch, member_file_name) == 0)
815ed0d50c3Schristos {
816ed0d50c3Schristos member_name = get_archive_member_name_at (nested_arch,
817ed0d50c3Schristos arch->nested_member_origin,
818ed0d50c3Schristos NULL);
819ed0d50c3Schristos if (member_name != NULL)
820ed0d50c3Schristos {
821ed0d50c3Schristos free (member_file_name);
822ed0d50c3Schristos return member_name;
823ed0d50c3Schristos }
824ed0d50c3Schristos }
825ed0d50c3Schristos free (member_file_name);
826ed0d50c3Schristos
827ed0d50c3Schristos /* Last resort: just return the name of the nested archive. */
828ed0d50c3Schristos return arch->longnames + k;
829ed0d50c3Schristos }
830ed0d50c3Schristos
831ed0d50c3Schristos /* We have a normal (short) name. */
832ed0d50c3Schristos for (j = 0; j < sizeof (arch->arhdr.ar_name); j++)
833ed0d50c3Schristos if (arch->arhdr.ar_name[j] == '/')
834ed0d50c3Schristos {
835ed0d50c3Schristos arch->arhdr.ar_name[j] = '\0';
836ed0d50c3Schristos return arch->arhdr.ar_name;
837ed0d50c3Schristos }
838ed0d50c3Schristos
839ed0d50c3Schristos /* The full ar_name field is used. Don't rely on ar_date starting
840ed0d50c3Schristos with a zero byte. */
841ed0d50c3Schristos {
842ed0d50c3Schristos char *name = xmalloc (sizeof (arch->arhdr.ar_name) + 1);
843ed0d50c3Schristos memcpy (name, arch->arhdr.ar_name, sizeof (arch->arhdr.ar_name));
844ed0d50c3Schristos name[sizeof (arch->arhdr.ar_name)] = '\0';
845ed0d50c3Schristos return name;
846ed0d50c3Schristos }
847ed0d50c3Schristos }
848ed0d50c3Schristos
849ed0d50c3Schristos /* Get the name of an archive member at a given OFFSET within an archive
850ed0d50c3Schristos ARCH. */
851ed0d50c3Schristos
852ed0d50c3Schristos char *
get_archive_member_name_at(struct archive_info * arch,unsigned long offset,struct archive_info * nested_arch)853ed0d50c3Schristos get_archive_member_name_at (struct archive_info *arch,
854ed0d50c3Schristos unsigned long offset,
855ed0d50c3Schristos struct archive_info *nested_arch)
856ed0d50c3Schristos {
857ed0d50c3Schristos size_t got;
858ed0d50c3Schristos
859ed0d50c3Schristos if (fseek (arch->file, offset, SEEK_SET) != 0)
860ed0d50c3Schristos {
861ed0d50c3Schristos error (_("%s: failed to seek to next file name\n"), arch->file_name);
862ed0d50c3Schristos return NULL;
863ed0d50c3Schristos }
864ed0d50c3Schristos got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
865ed0d50c3Schristos if (got != sizeof arch->arhdr)
866ed0d50c3Schristos {
867ed0d50c3Schristos error (_("%s: failed to read archive header\n"), arch->file_name);
868ed0d50c3Schristos return NULL;
869ed0d50c3Schristos }
870ed0d50c3Schristos if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
871ed0d50c3Schristos {
872ed0d50c3Schristos error (_("%s: did not find a valid archive header\n"),
873ed0d50c3Schristos arch->file_name);
874ed0d50c3Schristos return NULL;
875ed0d50c3Schristos }
876ed0d50c3Schristos
877ed0d50c3Schristos return get_archive_member_name (arch, nested_arch);
878ed0d50c3Schristos }
879ed0d50c3Schristos
880ed0d50c3Schristos /* Construct a string showing the name of the archive member, qualified
881ed0d50c3Schristos with the name of the containing archive file. For thin archives, we
882ed0d50c3Schristos use square brackets to denote the indirection. For nested archives,
883ed0d50c3Schristos we show the qualified name of the external member inside the square
884ed0d50c3Schristos brackets (e.g., "thin.a[normal.a(foo.o)]"). */
885ed0d50c3Schristos
886ed0d50c3Schristos char *
make_qualified_name(struct archive_info * arch,struct archive_info * nested_arch,const char * member_name)887ed0d50c3Schristos make_qualified_name (struct archive_info * arch,
888ed0d50c3Schristos struct archive_info * nested_arch,
889ed0d50c3Schristos const char *member_name)
890ed0d50c3Schristos {
891ed0d50c3Schristos const char * error_name = _("<corrupt>");
892ed0d50c3Schristos size_t len;
893ed0d50c3Schristos char * name;
894ed0d50c3Schristos
895ed0d50c3Schristos len = strlen (arch->file_name) + strlen (member_name) + 3;
896ed0d50c3Schristos if (arch->is_thin_archive
897ed0d50c3Schristos && arch->nested_member_origin != 0)
898ed0d50c3Schristos {
899ed0d50c3Schristos /* PR 15140: Allow for corrupt thin archives. */
900ed0d50c3Schristos if (nested_arch->file_name)
901ed0d50c3Schristos len += strlen (nested_arch->file_name) + 2;
902ed0d50c3Schristos else
903ed0d50c3Schristos len += strlen (error_name) + 2;
904ed0d50c3Schristos }
905ed0d50c3Schristos
906ed0d50c3Schristos name = (char *) malloc (len);
907ed0d50c3Schristos if (name == NULL)
908ed0d50c3Schristos {
909ed0d50c3Schristos error (_("Out of memory\n"));
910ed0d50c3Schristos return NULL;
911ed0d50c3Schristos }
912ed0d50c3Schristos
913ed0d50c3Schristos if (arch->is_thin_archive
914ed0d50c3Schristos && arch->nested_member_origin != 0)
915ed0d50c3Schristos {
916ed0d50c3Schristos if (nested_arch->file_name)
917ed0d50c3Schristos snprintf (name, len, "%s[%s(%s)]", arch->file_name,
918ed0d50c3Schristos nested_arch->file_name, member_name);
919ed0d50c3Schristos else
920ed0d50c3Schristos snprintf (name, len, "%s[%s(%s)]", arch->file_name,
921ed0d50c3Schristos error_name, member_name);
922ed0d50c3Schristos }
923ed0d50c3Schristos else if (arch->is_thin_archive)
924ed0d50c3Schristos snprintf (name, len, "%s[%s]", arch->file_name, member_name);
925ed0d50c3Schristos else
926ed0d50c3Schristos snprintf (name, len, "%s(%s)", arch->file_name, member_name);
927ed0d50c3Schristos
928ed0d50c3Schristos return name;
929ed0d50c3Schristos }
930