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