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