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