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