]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
PR gas/3810 gas/3800
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
64fd6348 2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
74013231 3 Free Software Foundation, Inc.
252b5132
RH
4
5 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 6 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
7
8 This file is part of GNU Binutils.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
b43b5d5f
NC
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
23 02110-1301, USA. */
252b5132 24\f
9eb20dd8 25/* The difference between readelf and objdump:
252b5132 26
74013231 27 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 28 so why does the binutils project have two file dumpers ?
0de14b54 29
9eb20dd8
NC
30 The reason is that objdump sees an ELF file through a BFD filter of the
31 world; if BFD has a bug where, say, it disagrees about a machine constant
32 in e_flags, then the odds are good that it will remain internally
33 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
34 GAS sees it the BFD way. There was need for a tool to go find out what
35 the file actually says.
36
37 This is why the readelf program does not link against the BFD library - it
38 exists as an independent program to help verify the correct working of BFD.
39
40 There is also the case that readelf can provide more information about an
41 ELF file than is provided by objdump. In particular it can display DWARF
42 debugging information which (at the moment) objdump cannot. */
43\f
252b5132 44#include <assert.h>
00ed88bd 45#include <sys/types.h>
252b5132
RH
46#include <sys/stat.h>
47#include <stdio.h>
48#include <time.h>
49
f8eae8b2
L
50/* for PATH_MAX */
51#ifdef HAVE_LIMITS_H
52#include <limits.h>
53#endif
54
55#ifndef PATH_MAX
56/* for MAXPATHLEN */
57# ifdef HAVE_SYS_PARAM_H
58# include <sys/param.h>
59# endif
60# ifndef PATH_MAX
61# ifdef MAXPATHLEN
62# define PATH_MAX MAXPATHLEN
63# else
64# define PATH_MAX 1024
65# endif
66# endif
67#endif
68
a952a375 69#if __GNUC__ >= 2
19936277 70/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 71 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 72 Only do this if we believe that the compiler can support a 64 bit
a952a375 73 data type. For now we only rely on GCC being able to do this. */
19936277 74#define BFD64
a952a375
NC
75#endif
76
19e6b90e 77#include "dwarf.h"
252b5132
RH
78
79#include "elf/common.h"
80#include "elf/external.h"
81#include "elf/internal.h"
252b5132
RH
82
83/* The following headers use the elf/reloc-macros.h file to
84 automatically generate relocation recognition functions
85 such as elf_mips_reloc_type() */
86
87#define RELOC_MACROS_GEN_FUNC
88
252b5132 89#include "elf/alpha.h"
3b16e843 90#include "elf/arc.h"
252b5132 91#include "elf/arm.h"
3b16e843 92#include "elf/avr.h"
1d65ded4 93#include "elf/bfin.h"
3b16e843 94#include "elf/cris.h"
1c0d3aa6 95#include "elf/crx.h"
252b5132
RH
96#include "elf/d10v.h"
97#include "elf/d30v.h"
d172d4ba 98#include "elf/dlx.h"
252b5132 99#include "elf/fr30.h"
5c70f934 100#include "elf/frv.h"
3b16e843
NC
101#include "elf/h8.h"
102#include "elf/hppa.h"
103#include "elf/i386.h"
35b1837e 104#include "elf/i370.h"
3b16e843
NC
105#include "elf/i860.h"
106#include "elf/i960.h"
107#include "elf/ia64.h"
1e4cf259 108#include "elf/ip2k.h"
1c0d3aa6 109#include "elf/iq2000.h"
49f58d10 110#include "elf/m32c.h"
3b16e843
NC
111#include "elf/m32r.h"
112#include "elf/m68k.h"
75751cd9 113#include "elf/m68hc11.h"
252b5132 114#include "elf/mcore.h"
15ab5209 115#include "elf/mep.h"
3b16e843 116#include "elf/mips.h"
3c3bdf30 117#include "elf/mmix.h"
3b16e843
NC
118#include "elf/mn10200.h"
119#include "elf/mn10300.h"
4970f871 120#include "elf/mt.h"
2469cfa2 121#include "elf/msp430.h"
3b16e843 122#include "elf/or32.h"
7d466069 123#include "elf/pj.h"
3b16e843 124#include "elf/ppc.h"
c833c019 125#include "elf/ppc64.h"
a85d7ed0 126#include "elf/s390.h"
1c0d3aa6 127#include "elf/score.h"
3b16e843
NC
128#include "elf/sh.h"
129#include "elf/sparc.h"
e9f53129 130#include "elf/spu.h"
3b16e843 131#include "elf/v850.h"
179d3252 132#include "elf/vax.h"
3b16e843 133#include "elf/x86-64.h"
93fbbb04 134#include "elf/xstormy16.h"
88da6820 135#include "elf/xtensa.h"
252b5132 136
fb52b2f4
NC
137#include "aout/ar.h"
138
252b5132
RH
139#include "bucomm.h"
140#include "getopt.h"
566b0d53 141#include "libiberty.h"
252b5132 142
b34976b6 143char *program_name = "readelf";
85b1c36d
BE
144static long archive_file_offset;
145static unsigned long archive_file_size;
146static unsigned long dynamic_addr;
147static bfd_size_type dynamic_size;
148static unsigned int dynamic_nent;
149static char *dynamic_strings;
150static unsigned long dynamic_strings_length;
151static char *string_table;
152static unsigned long string_table_length;
153static unsigned long num_dynamic_syms;
154static Elf_Internal_Sym *dynamic_symbols;
155static Elf_Internal_Syminfo *dynamic_syminfo;
156static unsigned long dynamic_syminfo_offset;
157static unsigned int dynamic_syminfo_nent;
f8eae8b2 158static char program_interpreter[PATH_MAX];
85b1c36d 159static bfd_vma dynamic_info[DT_JMPREL + 1];
fdc90cb4 160static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
161static bfd_vma version_info[16];
162static Elf_Internal_Ehdr elf_header;
163static Elf_Internal_Shdr *section_headers;
164static Elf_Internal_Phdr *program_headers;
165static Elf_Internal_Dyn *dynamic_section;
166static Elf_Internal_Shdr *symtab_shndx_hdr;
167static int show_name;
168static int do_dynamic;
169static int do_syms;
170static int do_reloc;
171static int do_sections;
172static int do_section_groups;
5477e8a0 173static int do_section_details;
85b1c36d
BE
174static int do_segments;
175static int do_unwind;
176static int do_using_dynamic;
177static int do_header;
178static int do_dump;
179static int do_version;
180static int do_wide;
181static int do_histogram;
182static int do_debugging;
85b1c36d
BE
183static int do_arch;
184static int do_notes;
185static int is_32bit_elf;
252b5132 186
e4b17d5c
L
187struct group_list
188{
189 struct group_list *next;
190 unsigned int section_index;
191};
192
193struct group
194{
195 struct group_list *root;
196 unsigned int group_index;
197};
198
85b1c36d
BE
199static size_t group_count;
200static struct group *section_groups;
201static struct group **section_headers_groups;
e4b17d5c 202
aef1f6d0
DJ
203/* A linked list of the section names for which dumps were requested
204 by name. */
205struct dump_list_entry
206{
207 char *name;
208 int type;
209 struct dump_list_entry *next;
210};
211static struct dump_list_entry *dump_sects_byname;
212
18bd398b
NC
213/* A dynamic array of flags indicating for which sections a hex dump
214 has been requested (via the -x switch) and/or a disassembly dump
215 (via the -i switch). */
216char *cmdline_dump_sects = NULL;
217unsigned num_cmdline_dump_sects = 0;
218
219/* A dynamic array of flags indicating for which sections a dump of
220 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
221 basis and then initialised from the cmdline_dump_sects array,
222 the results of interpreting the -w switch, and the
223 dump_sects_byname list. */
b34976b6
AM
224char *dump_sects = NULL;
225unsigned int num_dump_sects = 0;
252b5132
RH
226
227#define HEX_DUMP (1 << 0)
228#define DISASS_DUMP (1 << 1)
229#define DEBUG_DUMP (1 << 2)
230
c256ffe7 231/* How to print a vma value. */
843dd992
NC
232typedef enum print_mode
233{
234 HEX,
235 DEC,
236 DEC_5,
237 UNSIGNED,
238 PREFIX_HEX,
239 FULL_HEX,
240 LONG_HEX
241}
242print_mode;
243
d3ba0551 244static void (*byte_put) (unsigned char *, bfd_vma, int);
252b5132 245
9c19a809
NC
246#define UNKNOWN -1
247
0b49d371
NC
248#define SECTION_NAME(X) \
249 ((X) == NULL ? "<none>" \
250 : string_table == NULL ? "<no-name>" \
251 : ((X)->sh_name >= string_table_length ? "<corrupt>" \
252 : string_table + (X)->sh_name))
252b5132 253
9ad5cbcf
AM
254/* Given st_shndx I, map to section_headers index. */
255#define SECTION_HEADER_INDEX(I) \
256 ((I) < SHN_LORESERVE \
257 ? (I) \
258 : ((I) <= SHN_HIRESERVE \
259 ? 0 \
260 : (I) - (SHN_HIRESERVE + 1 - SHN_LORESERVE)))
261
262/* Reverse of the above. */
263#define SECTION_HEADER_NUM(N) \
264 ((N) < SHN_LORESERVE \
265 ? (N) \
266 : (N) + (SHN_HIRESERVE + 1 - SHN_LORESERVE))
267
268#define SECTION_HEADER(I) (section_headers + SECTION_HEADER_INDEX (I))
269
ee42cf8c 270#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 271
7036c0e1 272#define BYTE_GET(field) byte_get (field, sizeof (field))
a952a375 273
261a45ad 274#define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
252b5132 275
9ad5cbcf
AM
276#define GET_ELF_SYMBOLS(file, section) \
277 (is_32bit_elf ? get_32bit_elf_symbols (file, section) \
278 : get_64bit_elf_symbols (file, section))
9ea033b2 279
d79b3d50
NC
280#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
281/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
282 already been called and verified that the string exists. */
283#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b
NC
284
285/* This is just a bit of syntatic sugar. */
286#define streq(a,b) (strcmp ((a), (b)) == 0)
287#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
0112cd26 288#define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0)
d79b3d50 289\f
c256ffe7
JJ
290static void *
291get_data (void *var, FILE *file, long offset, size_t size, size_t nmemb,
292 const char *reason)
a6e9f9df 293{
d3ba0551 294 void *mvar;
a6e9f9df 295
c256ffe7 296 if (size == 0 || nmemb == 0)
a6e9f9df
AM
297 return NULL;
298
fb52b2f4 299 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 300 {
0fd3a477 301 error (_("Unable to seek to 0x%lx for %s\n"),
fb52b2f4 302 archive_file_offset + offset, reason);
a6e9f9df
AM
303 return NULL;
304 }
305
306 mvar = var;
307 if (mvar == NULL)
308 {
c256ffe7
JJ
309 /* Check for overflow. */
310 if (nmemb < (~(size_t) 0 - 1) / size)
311 /* + 1 so that we can '\0' terminate invalid string table sections. */
312 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
313
314 if (mvar == NULL)
315 {
0fd3a477
JW
316 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
317 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
318 return NULL;
319 }
c256ffe7
JJ
320
321 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
322 }
323
c256ffe7 324 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 325 {
0fd3a477
JW
326 error (_("Unable to read in 0x%lx bytes of %s\n"),
327 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
328 if (mvar != var)
329 free (mvar);
330 return NULL;
331 }
332
333 return mvar;
334}
335
adab8cdc 336static void
d3ba0551 337byte_put_little_endian (unsigned char *field, bfd_vma value, int size)
adab8cdc
AO
338{
339 switch (size)
340 {
341 case 8:
342 field[7] = (((value >> 24) >> 24) >> 8) & 0xff;
343 field[6] = ((value >> 24) >> 24) & 0xff;
344 field[5] = ((value >> 24) >> 16) & 0xff;
345 field[4] = ((value >> 24) >> 8) & 0xff;
346 /* Fall through. */
347 case 4:
348 field[3] = (value >> 24) & 0xff;
349 field[2] = (value >> 16) & 0xff;
350 /* Fall through. */
351 case 2:
352 field[1] = (value >> 8) & 0xff;
353 /* Fall through. */
354 case 1:
355 field[0] = value & 0xff;
356 break;
357
358 default:
359 error (_("Unhandled data length: %d\n"), size);
360 abort ();
361 }
362}
363
66543521
AM
364#if defined BFD64 && !BFD_HOST_64BIT_LONG
365static int
366print_dec_vma (bfd_vma vma, int is_signed)
367{
368 char buf[40];
369 char *bufp = buf;
370 int nc = 0;
371
372 if (is_signed && (bfd_signed_vma) vma < 0)
373 {
374 vma = -vma;
375 putchar ('-');
376 nc = 1;
377 }
378
379 do
380 {
381 *bufp++ = '0' + vma % 10;
382 vma /= 10;
383 }
384 while (vma != 0);
385 nc += bufp - buf;
386
387 while (bufp > buf)
388 putchar (*--bufp);
389 return nc;
390}
391
392static int
393print_hex_vma (bfd_vma vma)
394{
395 char buf[32];
396 char *bufp = buf;
397 int nc;
398
399 do
400 {
401 char digit = '0' + (vma & 0x0f);
402 if (digit > '9')
403 digit += 'a' - '0' - 10;
404 *bufp++ = digit;
405 vma >>= 4;
406 }
407 while (vma != 0);
408 nc = bufp - buf;
409
410 while (bufp > buf)
411 putchar (*--bufp);
412 return nc;
413}
414#endif
415
f7a99963 416/* Print a VMA value. */
66543521 417static int
d3ba0551 418print_vma (bfd_vma vma, print_mode mode)
f7a99963
NC
419{
420#ifdef BFD64
421 if (is_32bit_elf)
422#endif
423 {
424 switch (mode)
425 {
b19aac67 426 case FULL_HEX:
66543521
AM
427 return printf ("0x%8.8lx", (unsigned long) vma);
428
b19aac67 429 case LONG_HEX:
66543521 430 return printf ("%8.8lx", (unsigned long) vma);
b19aac67
NC
431
432 case DEC_5:
433 if (vma <= 99999)
66543521 434 return printf ("%5ld", (long) vma);
b19aac67 435 /* Drop through. */
66543521 436
b19aac67 437 case PREFIX_HEX:
66543521
AM
438 return printf ("0x%lx", (unsigned long) vma);
439
b19aac67 440 case HEX:
66543521 441 return printf ("%lx", (unsigned long) vma);
b19aac67
NC
442
443 case DEC:
66543521 444 return printf ("%ld", (unsigned long) vma);
b19aac67
NC
445
446 case UNSIGNED:
66543521 447 return printf ("%lu", (unsigned long) vma);
f7a99963
NC
448 }
449 }
450#ifdef BFD64
451 else
452 {
66543521
AM
453 int nc = 0;
454
f7a99963
NC
455 switch (mode)
456 {
457 case FULL_HEX:
66543521 458 nc = printf ("0x");
b19aac67 459 /* Drop through. */
76da6bbe 460
f7a99963
NC
461 case LONG_HEX:
462 printf_vma (vma);
66543521 463 return nc + 16;
76da6bbe 464
f7a99963 465 case PREFIX_HEX:
66543521 466 nc = printf ("0x");
b19aac67 467 /* Drop through. */
76da6bbe 468
f7a99963
NC
469 case HEX:
470#if BFD_HOST_64BIT_LONG
66543521 471 return nc + printf ("%lx", vma);
f7a99963 472#else
66543521 473 return nc + print_hex_vma (vma);
f7a99963 474#endif
f7a99963
NC
475
476 case DEC:
2f528887 477#if BFD_HOST_64BIT_LONG
66543521 478 return printf ("%ld", vma);
2f528887 479#else
66543521 480 return print_dec_vma (vma, 1);
76da6bbe 481#endif
f7a99963
NC
482
483 case DEC_5:
2f528887 484#if BFD_HOST_64BIT_LONG
b19aac67 485 if (vma <= 99999)
66543521 486 return printf ("%5ld", vma);
b19aac67 487 else
66543521 488 return printf ("%#lx", vma);
2f528887 489#else
66543521
AM
490 if (vma <= 99999)
491 return printf ("%5ld", _bfd_int64_low (vma));
b19aac67 492 else
66543521 493 return print_hex_vma (vma);
76da6bbe 494#endif
76da6bbe 495
f7a99963 496 case UNSIGNED:
2f528887 497#if BFD_HOST_64BIT_LONG
66543521 498 return printf ("%lu", vma);
76da6bbe 499#else
66543521 500 return print_dec_vma (vma, 0);
2f528887 501#endif
f7a99963
NC
502 }
503 }
504#endif
66543521 505 return 0;
f7a99963
NC
506}
507
31104126
NC
508/* Display a symbol on stdout. If do_wide is not true then
509 format the symbol to be at most WIDTH characters,
047b2264 510 truncating as necessary. If WIDTH is negative then
31104126
NC
511 format the string to be exactly - WIDTH characters,
512 truncating or padding as necessary. */
513
514static void
d3ba0551 515print_symbol (int width, const char *symbol)
31104126
NC
516{
517 if (do_wide)
f1ef08cb 518 printf ("%s", symbol);
31104126
NC
519 else if (width < 0)
520 printf ("%-*.*s", width, width, symbol);
53c7db4b 521 else
31104126
NC
522 printf ("%-.*s", width, symbol);
523}
524
adab8cdc 525static void
d3ba0551 526byte_put_big_endian (unsigned char *field, bfd_vma value, int size)
adab8cdc
AO
527{
528 switch (size)
529 {
530 case 8:
531 field[7] = value & 0xff;
532 field[6] = (value >> 8) & 0xff;
533 field[5] = (value >> 16) & 0xff;
534 field[4] = (value >> 24) & 0xff;
535 value >>= 16;
536 value >>= 16;
537 /* Fall through. */
538 case 4:
539 field[3] = value & 0xff;
540 field[2] = (value >> 8) & 0xff;
541 value >>= 16;
542 /* Fall through. */
543 case 2:
544 field[1] = value & 0xff;
545 value >>= 8;
546 /* Fall through. */
547 case 1:
548 field[0] = value & 0xff;
549 break;
550
551 default:
552 error (_("Unhandled data length: %d\n"), size);
553 abort ();
554 }
555}
556
89fac5e3
RS
557/* Return a pointer to section NAME, or NULL if no such section exists. */
558
559static Elf_Internal_Shdr *
560find_section (const char *name)
561{
562 unsigned int i;
563
564 for (i = 0; i < elf_header.e_shnum; i++)
565 if (streq (SECTION_NAME (section_headers + i), name))
566 return section_headers + i;
567
568 return NULL;
569}
570
bcedfee6 571/* Guess the relocation size commonly used by the specific machines. */
252b5132 572
252b5132 573static int
d3ba0551 574guess_is_rela (unsigned long e_machine)
252b5132 575{
9c19a809 576 switch (e_machine)
252b5132
RH
577 {
578 /* Targets that use REL relocations. */
252b5132
RH
579 case EM_386:
580 case EM_486:
63fcb9e9 581 case EM_960:
e9f53129 582 case EM_ARM:
2b0337b0 583 case EM_D10V:
252b5132 584 case EM_CYGNUS_D10V:
e9f53129 585 case EM_DLX:
252b5132 586 case EM_MIPS:
4fe85591 587 case EM_MIPS_RS3_LE:
e9f53129
AM
588 case EM_CYGNUS_M32R:
589 case EM_OPENRISC:
590 case EM_OR32:
1c0d3aa6 591 case EM_SCORE:
9c19a809 592 return FALSE;
103f02d3 593
252b5132
RH
594 /* Targets that use RELA relocations. */
595 case EM_68K:
e9f53129
AM
596 case EM_860:
597 case EM_ALPHA:
598 case EM_ALTERA_NIOS2:
599 case EM_AVR:
600 case EM_AVR_OLD:
601 case EM_BLACKFIN:
602 case EM_CRIS:
603 case EM_CRX:
2b0337b0 604 case EM_D30V:
252b5132 605 case EM_CYGNUS_D30V:
2b0337b0 606 case EM_FR30:
252b5132 607 case EM_CYGNUS_FR30:
5c70f934 608 case EM_CYGNUS_FRV:
e9f53129
AM
609 case EM_H8S:
610 case EM_H8_300:
611 case EM_H8_300H:
800eeca4 612 case EM_IA_64:
1e4cf259
NC
613 case EM_IP2K:
614 case EM_IP2K_OLD:
3b36097d 615 case EM_IQ2000:
49f58d10 616 case EM_M32C:
e9f53129
AM
617 case EM_M32R:
618 case EM_MCORE:
15ab5209 619 case EM_CYGNUS_MEP:
e9f53129
AM
620 case EM_MMIX:
621 case EM_MN10200:
622 case EM_CYGNUS_MN10200:
623 case EM_MN10300:
624 case EM_CYGNUS_MN10300:
625 case EM_MSP430:
626 case EM_MSP430_OLD:
d031aafb 627 case EM_MT:
64fd6348 628 case EM_NIOS32:
e9f53129
AM
629 case EM_PPC64:
630 case EM_PPC:
631 case EM_S390:
632 case EM_S390_OLD:
633 case EM_SH:
634 case EM_SPARC:
635 case EM_SPARC32PLUS:
636 case EM_SPARCV9:
637 case EM_SPU:
638 case EM_V850:
639 case EM_CYGNUS_V850:
640 case EM_VAX:
641 case EM_X86_64:
642 case EM_XSTORMY16:
643 case EM_XTENSA:
644 case EM_XTENSA_OLD:
9c19a809 645 return TRUE;
103f02d3 646
e9f53129
AM
647 case EM_68HC05:
648 case EM_68HC08:
649 case EM_68HC11:
650 case EM_68HC16:
651 case EM_FX66:
652 case EM_ME16:
d1133906 653 case EM_MMA:
d1133906
NC
654 case EM_NCPU:
655 case EM_NDR1:
e9f53129 656 case EM_PCP:
d1133906 657 case EM_ST100:
e9f53129 658 case EM_ST19:
d1133906 659 case EM_ST7:
e9f53129
AM
660 case EM_ST9PLUS:
661 case EM_STARCORE:
d1133906 662 case EM_SVX:
e9f53129 663 case EM_TINYJ:
9c19a809
NC
664 default:
665 warn (_("Don't know about relocations on this machine architecture\n"));
666 return FALSE;
667 }
668}
252b5132 669
9c19a809 670static int
d3ba0551
AM
671slurp_rela_relocs (FILE *file,
672 unsigned long rel_offset,
673 unsigned long rel_size,
674 Elf_Internal_Rela **relasp,
675 unsigned long *nrelasp)
9c19a809 676{
4d6ed7c8
NC
677 Elf_Internal_Rela *relas;
678 unsigned long nrelas;
679 unsigned int i;
252b5132 680
4d6ed7c8
NC
681 if (is_32bit_elf)
682 {
b34976b6 683 Elf32_External_Rela *erelas;
103f02d3 684
c256ffe7 685 erelas = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
a6e9f9df
AM
686 if (!erelas)
687 return 0;
252b5132 688
4d6ed7c8 689 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 690
c256ffe7 691 relas = cmalloc (nrelas, sizeof (Elf_Internal_Rela));
103f02d3 692
4d6ed7c8
NC
693 if (relas == NULL)
694 {
c256ffe7 695 free (erelas);
18bd398b 696 error (_("out of memory parsing relocs"));
4d6ed7c8
NC
697 return 0;
698 }
103f02d3 699
4d6ed7c8
NC
700 for (i = 0; i < nrelas; i++)
701 {
702 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
703 relas[i].r_info = BYTE_GET (erelas[i].r_info);
704 relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
705 }
103f02d3 706
4d6ed7c8
NC
707 free (erelas);
708 }
709 else
710 {
b34976b6 711 Elf64_External_Rela *erelas;
103f02d3 712
c256ffe7 713 erelas = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
a6e9f9df
AM
714 if (!erelas)
715 return 0;
4d6ed7c8
NC
716
717 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 718
c256ffe7 719 relas = cmalloc (nrelas, sizeof (Elf_Internal_Rela));
103f02d3 720
4d6ed7c8
NC
721 if (relas == NULL)
722 {
c256ffe7 723 free (erelas);
18bd398b 724 error (_("out of memory parsing relocs"));
4d6ed7c8 725 return 0;
9c19a809 726 }
4d6ed7c8
NC
727
728 for (i = 0; i < nrelas; i++)
9c19a809 729 {
66543521
AM
730 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
731 relas[i].r_info = BYTE_GET (erelas[i].r_info);
732 relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
4d6ed7c8 733 }
103f02d3 734
4d6ed7c8
NC
735 free (erelas);
736 }
737 *relasp = relas;
738 *nrelasp = nrelas;
739 return 1;
740}
103f02d3 741
4d6ed7c8 742static int
d3ba0551
AM
743slurp_rel_relocs (FILE *file,
744 unsigned long rel_offset,
745 unsigned long rel_size,
746 Elf_Internal_Rela **relsp,
747 unsigned long *nrelsp)
4d6ed7c8 748{
c8286bd1 749 Elf_Internal_Rela *rels;
4d6ed7c8
NC
750 unsigned long nrels;
751 unsigned int i;
103f02d3 752
4d6ed7c8
NC
753 if (is_32bit_elf)
754 {
b34976b6 755 Elf32_External_Rel *erels;
103f02d3 756
c256ffe7 757 erels = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
a6e9f9df
AM
758 if (!erels)
759 return 0;
103f02d3 760
4d6ed7c8 761 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 762
c256ffe7 763 rels = cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 764
4d6ed7c8
NC
765 if (rels == NULL)
766 {
c256ffe7 767 free (erels);
18bd398b 768 error (_("out of memory parsing relocs"));
4d6ed7c8
NC
769 return 0;
770 }
771
772 for (i = 0; i < nrels; i++)
773 {
774 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
775 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 776 rels[i].r_addend = 0;
9ea033b2 777 }
4d6ed7c8
NC
778
779 free (erels);
9c19a809
NC
780 }
781 else
782 {
b34976b6 783 Elf64_External_Rel *erels;
9ea033b2 784
c256ffe7 785 erels = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
a6e9f9df
AM
786 if (!erels)
787 return 0;
103f02d3 788
4d6ed7c8 789 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 790
c256ffe7 791 rels = cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 792
4d6ed7c8 793 if (rels == NULL)
9c19a809 794 {
c256ffe7 795 free (erels);
18bd398b 796 error (_("out of memory parsing relocs"));
4d6ed7c8
NC
797 return 0;
798 }
103f02d3 799
4d6ed7c8
NC
800 for (i = 0; i < nrels; i++)
801 {
66543521
AM
802 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
803 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 804 rels[i].r_addend = 0;
4d6ed7c8 805 }
103f02d3 806
4d6ed7c8
NC
807 free (erels);
808 }
809 *relsp = rels;
810 *nrelsp = nrels;
811 return 1;
812}
103f02d3 813
d3ba0551
AM
814/* Display the contents of the relocation data found at the specified
815 offset. */
ee42cf8c 816
4d6ed7c8 817static int
d3ba0551
AM
818dump_relocations (FILE *file,
819 unsigned long rel_offset,
820 unsigned long rel_size,
821 Elf_Internal_Sym *symtab,
822 unsigned long nsyms,
823 char *strtab,
d79b3d50 824 unsigned long strtablen,
d3ba0551 825 int is_rela)
4d6ed7c8 826{
b34976b6
AM
827 unsigned int i;
828 Elf_Internal_Rela *rels;
103f02d3 829
103f02d3 830
4d6ed7c8
NC
831 if (is_rela == UNKNOWN)
832 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 833
4d6ed7c8
NC
834 if (is_rela)
835 {
c8286bd1 836 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
4d6ed7c8
NC
837 return 0;
838 }
839 else
840 {
841 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
842 return 0;
252b5132
RH
843 }
844
410f7a12
L
845 if (is_32bit_elf)
846 {
847 if (is_rela)
2c71103e
NC
848 {
849 if (do_wide)
850 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
851 else
852 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
853 }
410f7a12 854 else
2c71103e
NC
855 {
856 if (do_wide)
857 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
858 else
859 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
860 }
410f7a12 861 }
252b5132 862 else
410f7a12
L
863 {
864 if (is_rela)
2c71103e
NC
865 {
866 if (do_wide)
8beeaeb7 867 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
868 else
869 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
870 }
410f7a12 871 else
2c71103e
NC
872 {
873 if (do_wide)
8beeaeb7 874 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
875 else
876 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
877 }
410f7a12 878 }
252b5132
RH
879
880 for (i = 0; i < rel_size; i++)
881 {
b34976b6
AM
882 const char *rtype;
883 const char *rtype2 = NULL;
884 const char *rtype3 = NULL;
885 bfd_vma offset;
886 bfd_vma info;
887 bfd_vma symtab_index;
888 bfd_vma type;
d3ba0551
AM
889 bfd_vma type2 = 0;
890 bfd_vma type3 = 0;
103f02d3 891
b34976b6
AM
892 offset = rels[i].r_offset;
893 info = rels[i].r_info;
103f02d3 894
9ea033b2
NC
895 if (is_32bit_elf)
896 {
897 type = ELF32_R_TYPE (info);
898 symtab_index = ELF32_R_SYM (info);
899 }
900 else
901 {
1a677ea8
RS
902 /* The #ifdef BFD64 below is to prevent a compile time warning.
903 We know that if we do not have a 64 bit data type that we
904 will never execute this code anyway. */
905#ifdef BFD64
53c7db4b 906 if (elf_header.e_machine == EM_MIPS)
2c71103e 907 {
1a677ea8
RS
908 /* In little-endian objects, r_info isn't really a 64-bit
909 little-endian value: it has a 32-bit little-endian
910 symbol index followed by four individual byte fields.
911 Reorder INFO accordingly. */
912 if (elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
913 info = (((info & 0xffffffff) << 32)
914 | ((info >> 56) & 0xff)
915 | ((info >> 40) & 0xff00)
916 | ((info >> 24) & 0xff0000)
917 | ((info >> 8) & 0xff000000));
2c71103e
NC
918 type = ELF64_MIPS_R_TYPE (info);
919 type2 = ELF64_MIPS_R_TYPE2 (info);
920 type3 = ELF64_MIPS_R_TYPE3 (info);
921 }
922 else if (elf_header.e_machine == EM_SPARCV9)
923 type = ELF64_R_TYPE_ID (info);
351b4b40 924 else
2c71103e 925 type = ELF64_R_TYPE (info);
1a677ea8 926
9ea033b2 927 symtab_index = ELF64_R_SYM (info);
a952a375 928#endif
9ea033b2 929 }
252b5132 930
410f7a12
L
931 if (is_32bit_elf)
932 {
933#ifdef _bfd_int64_low
934 printf ("%8.8lx %8.8lx ", _bfd_int64_low (offset), _bfd_int64_low (info));
935#else
936 printf ("%8.8lx %8.8lx ", offset, info);
937#endif
938 }
939 else
940 {
9ea033b2 941#ifdef _bfd_int64_low
2c71103e
NC
942 printf (do_wide
943 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
944 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
945 _bfd_int64_high (offset),
946 _bfd_int64_low (offset),
947 _bfd_int64_high (info),
948 _bfd_int64_low (info));
9ea033b2 949#else
2c71103e 950 printf (do_wide
25345be5 951 ? "%16.16lx %16.16lx "
2c71103e
NC
952 : "%12.12lx %12.12lx ",
953 offset, info);
9ea033b2 954#endif
410f7a12 955 }
103f02d3 956
252b5132
RH
957 switch (elf_header.e_machine)
958 {
959 default:
960 rtype = NULL;
961 break;
962
2b0337b0 963 case EM_M32R:
252b5132 964 case EM_CYGNUS_M32R:
9ea033b2 965 rtype = elf_m32r_reloc_type (type);
252b5132
RH
966 break;
967
968 case EM_386:
969 case EM_486:
9ea033b2 970 rtype = elf_i386_reloc_type (type);
252b5132
RH
971 break;
972
ba2685cc
AM
973 case EM_68HC11:
974 case EM_68HC12:
975 rtype = elf_m68hc11_reloc_type (type);
976 break;
75751cd9 977
252b5132 978 case EM_68K:
9ea033b2 979 rtype = elf_m68k_reloc_type (type);
252b5132
RH
980 break;
981
63fcb9e9 982 case EM_960:
9ea033b2 983 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
984 break;
985
adde6300 986 case EM_AVR:
2b0337b0 987 case EM_AVR_OLD:
adde6300
AM
988 rtype = elf_avr_reloc_type (type);
989 break;
990
9ea033b2
NC
991 case EM_OLD_SPARCV9:
992 case EM_SPARC32PLUS:
993 case EM_SPARCV9:
252b5132 994 case EM_SPARC:
9ea033b2 995 rtype = elf_sparc_reloc_type (type);
252b5132
RH
996 break;
997
e9f53129
AM
998 case EM_SPU:
999 rtype = elf_spu_reloc_type (type);
1000 break;
1001
2b0337b0 1002 case EM_V850:
252b5132 1003 case EM_CYGNUS_V850:
9ea033b2 1004 rtype = v850_reloc_type (type);
252b5132
RH
1005 break;
1006
2b0337b0 1007 case EM_D10V:
252b5132 1008 case EM_CYGNUS_D10V:
9ea033b2 1009 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1010 break;
1011
2b0337b0 1012 case EM_D30V:
252b5132 1013 case EM_CYGNUS_D30V:
9ea033b2 1014 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1015 break;
1016
d172d4ba
NC
1017 case EM_DLX:
1018 rtype = elf_dlx_reloc_type (type);
1019 break;
1020
252b5132 1021 case EM_SH:
9ea033b2 1022 rtype = elf_sh_reloc_type (type);
252b5132
RH
1023 break;
1024
2b0337b0 1025 case EM_MN10300:
252b5132 1026 case EM_CYGNUS_MN10300:
9ea033b2 1027 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1028 break;
1029
2b0337b0 1030 case EM_MN10200:
252b5132 1031 case EM_CYGNUS_MN10200:
9ea033b2 1032 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1033 break;
1034
2b0337b0 1035 case EM_FR30:
252b5132 1036 case EM_CYGNUS_FR30:
9ea033b2 1037 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1038 break;
1039
ba2685cc
AM
1040 case EM_CYGNUS_FRV:
1041 rtype = elf_frv_reloc_type (type);
1042 break;
5c70f934 1043
252b5132 1044 case EM_MCORE:
9ea033b2 1045 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1046 break;
1047
3c3bdf30
NC
1048 case EM_MMIX:
1049 rtype = elf_mmix_reloc_type (type);
1050 break;
1051
2469cfa2
NC
1052 case EM_MSP430:
1053 case EM_MSP430_OLD:
1054 rtype = elf_msp430_reloc_type (type);
1055 break;
1056
252b5132 1057 case EM_PPC:
9ea033b2 1058 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1059 break;
1060
c833c019
AM
1061 case EM_PPC64:
1062 rtype = elf_ppc64_reloc_type (type);
1063 break;
1064
252b5132 1065 case EM_MIPS:
4fe85591 1066 case EM_MIPS_RS3_LE:
9ea033b2 1067 rtype = elf_mips_reloc_type (type);
53c7db4b 1068 if (!is_32bit_elf)
2c71103e
NC
1069 {
1070 rtype2 = elf_mips_reloc_type (type2);
1071 rtype3 = elf_mips_reloc_type (type3);
1072 }
252b5132
RH
1073 break;
1074
1075 case EM_ALPHA:
9ea033b2 1076 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1077 break;
1078
1079 case EM_ARM:
9ea033b2 1080 rtype = elf_arm_reloc_type (type);
252b5132
RH
1081 break;
1082
584da044 1083 case EM_ARC:
9ea033b2 1084 rtype = elf_arc_reloc_type (type);
252b5132
RH
1085 break;
1086
1087 case EM_PARISC:
69e617ca 1088 rtype = elf_hppa_reloc_type (type);
252b5132 1089 break;
7d466069 1090
b8720f9d
JL
1091 case EM_H8_300:
1092 case EM_H8_300H:
1093 case EM_H8S:
1094 rtype = elf_h8_reloc_type (type);
1095 break;
1096
3b16e843
NC
1097 case EM_OPENRISC:
1098 case EM_OR32:
1099 rtype = elf_or32_reloc_type (type);
1100 break;
1101
7d466069 1102 case EM_PJ:
2b0337b0 1103 case EM_PJ_OLD:
7d466069
ILT
1104 rtype = elf_pj_reloc_type (type);
1105 break;
800eeca4
JW
1106 case EM_IA_64:
1107 rtype = elf_ia64_reloc_type (type);
1108 break;
1b61cf92
HPN
1109
1110 case EM_CRIS:
1111 rtype = elf_cris_reloc_type (type);
1112 break;
535c37ff
JE
1113
1114 case EM_860:
1115 rtype = elf_i860_reloc_type (type);
1116 break;
bcedfee6
NC
1117
1118 case EM_X86_64:
1119 rtype = elf_x86_64_reloc_type (type);
1120 break;
a85d7ed0 1121
35b1837e
AM
1122 case EM_S370:
1123 rtype = i370_reloc_type (type);
1124 break;
1125
53c7db4b
KH
1126 case EM_S390_OLD:
1127 case EM_S390:
1128 rtype = elf_s390_reloc_type (type);
1129 break;
93fbbb04 1130
1c0d3aa6
NC
1131 case EM_SCORE:
1132 rtype = elf_score_reloc_type (type);
1133 break;
1134
93fbbb04
GK
1135 case EM_XSTORMY16:
1136 rtype = elf_xstormy16_reloc_type (type);
1137 break;
179d3252 1138
1fe1f39c
NC
1139 case EM_CRX:
1140 rtype = elf_crx_reloc_type (type);
1141 break;
1142
179d3252
JT
1143 case EM_VAX:
1144 rtype = elf_vax_reloc_type (type);
1145 break;
1e4cf259
NC
1146
1147 case EM_IP2K:
1148 case EM_IP2K_OLD:
1149 rtype = elf_ip2k_reloc_type (type);
1150 break;
3b36097d
SC
1151
1152 case EM_IQ2000:
1153 rtype = elf_iq2000_reloc_type (type);
1154 break;
88da6820
NC
1155
1156 case EM_XTENSA_OLD:
1157 case EM_XTENSA:
1158 rtype = elf_xtensa_reloc_type (type);
1159 break;
a34e3ecb 1160
49f58d10
JB
1161 case EM_M32C:
1162 rtype = elf_m32c_reloc_type (type);
1163 break;
1164
d031aafb
NS
1165 case EM_MT:
1166 rtype = elf_mt_reloc_type (type);
a34e3ecb 1167 break;
1d65ded4
CM
1168
1169 case EM_BLACKFIN:
1170 rtype = elf_bfin_reloc_type (type);
1171 break;
15ab5209
DB
1172
1173 case EM_CYGNUS_MEP:
1174 rtype = elf_mep_reloc_type (type);
1175 break;
252b5132
RH
1176 }
1177
1178 if (rtype == NULL)
103f02d3 1179#ifdef _bfd_int64_low
2c71103e 1180 printf (_("unrecognized: %-7lx"), _bfd_int64_low (type));
9ea033b2 1181#else
2c71103e 1182 printf (_("unrecognized: %-7lx"), type);
9ea033b2 1183#endif
252b5132 1184 else
8beeaeb7 1185 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1186
7ace3541 1187 if (elf_header.e_machine == EM_ALPHA
157c2599 1188 && rtype != NULL
7ace3541
RH
1189 && streq (rtype, "R_ALPHA_LITUSE")
1190 && is_rela)
1191 {
1192 switch (rels[i].r_addend)
1193 {
1194 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1195 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1196 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1197 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1198 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1199 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1200 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1201 default: rtype = NULL;
1202 }
1203 if (rtype)
1204 printf (" (%s)", rtype);
1205 else
1206 {
1207 putchar (' ');
1208 printf (_("<unknown addend: %lx>"),
1209 (unsigned long) rels[i].r_addend);
1210 }
1211 }
1212 else if (symtab_index)
252b5132 1213 {
af3fc3bc
AM
1214 if (symtab == NULL || symtab_index >= nsyms)
1215 printf (" bad symbol index: %08lx", (unsigned long) symtab_index);
1216 else
19936277 1217 {
b34976b6 1218 Elf_Internal_Sym *psym;
19936277 1219
af3fc3bc 1220 psym = symtab + symtab_index;
103f02d3 1221
af3fc3bc
AM
1222 printf (" ");
1223 print_vma (psym->st_value, LONG_HEX);
2c71103e 1224 printf (is_32bit_elf ? " " : " ");
103f02d3 1225
af3fc3bc 1226 if (psym->st_name == 0)
f1ef08cb
AM
1227 {
1228 const char *sec_name = "<null>";
1229 char name_buf[40];
1230
1231 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1232 {
1233 bfd_vma sec_index = (bfd_vma) -1;
1234
1235 if (psym->st_shndx < SHN_LORESERVE)
1236 sec_index = psym->st_shndx;
efcb5b0e 1237 else if (psym->st_shndx > SHN_HIRESERVE)
f1ef08cb
AM
1238 sec_index = psym->st_shndx - (SHN_HIRESERVE + 1
1239 - SHN_LORESERVE);
1240
1241 if (sec_index != (bfd_vma) -1)
1242 sec_name = SECTION_NAME (section_headers + sec_index);
1243 else if (psym->st_shndx == SHN_ABS)
1244 sec_name = "ABS";
1245 else if (psym->st_shndx == SHN_COMMON)
1246 sec_name = "COMMON";
172553c7
TS
1247 else if (elf_header.e_machine == EM_MIPS
1248 && psym->st_shndx == SHN_MIPS_SCOMMON)
1249 sec_name = "SCOMMON";
1250 else if (elf_header.e_machine == EM_MIPS
1251 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1252 sec_name = "SUNDEF";
3b22753a
L
1253 else if (elf_header.e_machine == EM_X86_64
1254 && psym->st_shndx == SHN_X86_64_LCOMMON)
1255 sec_name = "LARGE_COMMON";
9ce701e2
L
1256 else if (elf_header.e_machine == EM_IA_64
1257 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1258 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1259 sec_name = "ANSI_COM";
f1ef08cb
AM
1260 else
1261 {
1262 sprintf (name_buf, "<section 0x%x>",
1263 (unsigned int) psym->st_shndx);
1264 sec_name = name_buf;
1265 }
1266 }
1267 print_symbol (22, sec_name);
1268 }
af3fc3bc 1269 else if (strtab == NULL)
d79b3d50 1270 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1271 else if (psym->st_name >= strtablen)
d79b3d50 1272 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1273 else
2c71103e 1274 print_symbol (22, strtab + psym->st_name);
103f02d3 1275
af3fc3bc 1276 if (is_rela)
b34976b6 1277 printf (" + %lx", (unsigned long) rels[i].r_addend);
19936277 1278 }
252b5132 1279 }
1b228002 1280 else if (is_rela)
f7a99963 1281 {
18bd398b
NC
1282 printf ("%*c", is_32bit_elf ?
1283 (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' ');
c8286bd1 1284 print_vma (rels[i].r_addend, LONG_HEX);
f7a99963 1285 }
252b5132 1286
157c2599
NC
1287 if (elf_header.e_machine == EM_SPARCV9
1288 && rtype != NULL
1289 && streq (rtype, "R_SPARC_OLO10"))
351b4b40
RH
1290 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (info));
1291
252b5132 1292 putchar ('\n');
2c71103e 1293
53c7db4b 1294 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e
NC
1295 {
1296 printf (" Type2: ");
1297
1298 if (rtype2 == NULL)
1299#ifdef _bfd_int64_low
1300 printf (_("unrecognized: %-7lx"), _bfd_int64_low (type2));
1301#else
1302 printf (_("unrecognized: %-7lx"), type2);
1303#endif
1304 else
1305 printf ("%-17.17s", rtype2);
1306
18bd398b 1307 printf ("\n Type3: ");
2c71103e
NC
1308
1309 if (rtype3 == NULL)
1310#ifdef _bfd_int64_low
1311 printf (_("unrecognized: %-7lx"), _bfd_int64_low (type3));
1312#else
1313 printf (_("unrecognized: %-7lx"), type3);
1314#endif
1315 else
1316 printf ("%-17.17s", rtype3);
1317
53c7db4b 1318 putchar ('\n');
2c71103e 1319 }
252b5132
RH
1320 }
1321
c8286bd1 1322 free (rels);
252b5132
RH
1323
1324 return 1;
1325}
1326
1327static const char *
d3ba0551 1328get_mips_dynamic_type (unsigned long type)
252b5132
RH
1329{
1330 switch (type)
1331 {
1332 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1333 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1334 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1335 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1336 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1337 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1338 case DT_MIPS_MSYM: return "MIPS_MSYM";
1339 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1340 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1341 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1342 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1343 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1344 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1345 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1346 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1347 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1348 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1349 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1350 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1351 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1352 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1353 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1354 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1355 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1356 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1357 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1358 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1359 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1360 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1361 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1362 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1363 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1364 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1365 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1366 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1367 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1368 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1369 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1370 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1371 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1372 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1373 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1374 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
1375 default:
1376 return NULL;
1377 }
1378}
1379
9a097730 1380static const char *
d3ba0551 1381get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1382{
1383 switch (type)
1384 {
1385 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1386 default:
1387 return NULL;
1388 }
103f02d3
UD
1389}
1390
7490d522
AM
1391static const char *
1392get_ppc_dynamic_type (unsigned long type)
1393{
1394 switch (type)
1395 {
1fe44d79 1396 case DT_PPC_GOT: return "PPC_GOT";
7490d522
AM
1397 default:
1398 return NULL;
1399 }
1400}
1401
f1cb7e17 1402static const char *
d3ba0551 1403get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1404{
1405 switch (type)
1406 {
1407 case DT_PPC64_GLINK: return "PPC64_GLINK";
19397422
AM
1408 case DT_PPC64_OPD: return "PPC64_OPD";
1409 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
f1cb7e17
AM
1410 default:
1411 return NULL;
1412 }
1413}
1414
103f02d3 1415static const char *
d3ba0551 1416get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1417{
1418 switch (type)
1419 {
1420 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1421 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1422 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1423 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1424 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1425 case DT_HP_PREINIT: return "HP_PREINIT";
1426 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1427 case DT_HP_NEEDED: return "HP_NEEDED";
1428 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1429 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1430 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1431 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1432 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1433 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1434 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1435 case DT_HP_FILTERED: return "HP_FILTERED";
1436 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1437 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1438 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1439 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1440 case DT_PLT: return "PLT";
1441 case DT_PLT_SIZE: return "PLT_SIZE";
1442 case DT_DLT: return "DLT";
1443 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1444 default:
1445 return NULL;
1446 }
1447}
9a097730 1448
ecc51f48 1449static const char *
d3ba0551 1450get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1451{
1452 switch (type)
1453 {
1454 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1455 default:
1456 return NULL;
1457 }
1458}
1459
fabcb361
RH
1460static const char *
1461get_alpha_dynamic_type (unsigned long type)
1462{
1463 switch (type)
1464 {
1465 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1466 default:
1467 return NULL;
1468 }
1469}
1470
1c0d3aa6
NC
1471static const char *
1472get_score_dynamic_type (unsigned long type)
1473{
1474 switch (type)
1475 {
1476 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1477 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1478 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1479 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1480 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1481 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1482 default:
1483 return NULL;
1484 }
1485}
1486
1487
252b5132 1488static const char *
d3ba0551 1489get_dynamic_type (unsigned long type)
252b5132 1490{
e9e44622 1491 static char buff[64];
252b5132
RH
1492
1493 switch (type)
1494 {
1495 case DT_NULL: return "NULL";
1496 case DT_NEEDED: return "NEEDED";
1497 case DT_PLTRELSZ: return "PLTRELSZ";
1498 case DT_PLTGOT: return "PLTGOT";
1499 case DT_HASH: return "HASH";
1500 case DT_STRTAB: return "STRTAB";
1501 case DT_SYMTAB: return "SYMTAB";
1502 case DT_RELA: return "RELA";
1503 case DT_RELASZ: return "RELASZ";
1504 case DT_RELAENT: return "RELAENT";
1505 case DT_STRSZ: return "STRSZ";
1506 case DT_SYMENT: return "SYMENT";
1507 case DT_INIT: return "INIT";
1508 case DT_FINI: return "FINI";
1509 case DT_SONAME: return "SONAME";
1510 case DT_RPATH: return "RPATH";
1511 case DT_SYMBOLIC: return "SYMBOLIC";
1512 case DT_REL: return "REL";
1513 case DT_RELSZ: return "RELSZ";
1514 case DT_RELENT: return "RELENT";
1515 case DT_PLTREL: return "PLTREL";
1516 case DT_DEBUG: return "DEBUG";
1517 case DT_TEXTREL: return "TEXTREL";
1518 case DT_JMPREL: return "JMPREL";
1519 case DT_BIND_NOW: return "BIND_NOW";
1520 case DT_INIT_ARRAY: return "INIT_ARRAY";
1521 case DT_FINI_ARRAY: return "FINI_ARRAY";
1522 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1523 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1524 case DT_RUNPATH: return "RUNPATH";
1525 case DT_FLAGS: return "FLAGS";
2d0e6f43 1526
d1133906
NC
1527 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1528 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1529
05107a46 1530 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1531 case DT_PLTPADSZ: return "PLTPADSZ";
1532 case DT_MOVEENT: return "MOVEENT";
1533 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1534 case DT_FEATURE: return "FEATURE";
252b5132
RH
1535 case DT_POSFLAG_1: return "POSFLAG_1";
1536 case DT_SYMINSZ: return "SYMINSZ";
1537 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1538
252b5132 1539 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1540 case DT_CONFIG: return "CONFIG";
1541 case DT_DEPAUDIT: return "DEPAUDIT";
1542 case DT_AUDIT: return "AUDIT";
1543 case DT_PLTPAD: return "PLTPAD";
1544 case DT_MOVETAB: return "MOVETAB";
252b5132 1545 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1546
252b5132 1547 case DT_VERSYM: return "VERSYM";
103f02d3 1548
67a4f2b7
AO
1549 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1550 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1551 case DT_RELACOUNT: return "RELACOUNT";
1552 case DT_RELCOUNT: return "RELCOUNT";
1553 case DT_FLAGS_1: return "FLAGS_1";
1554 case DT_VERDEF: return "VERDEF";
1555 case DT_VERDEFNUM: return "VERDEFNUM";
1556 case DT_VERNEED: return "VERNEED";
1557 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1558
019148e4 1559 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1560 case DT_USED: return "USED";
1561 case DT_FILTER: return "FILTER";
103f02d3 1562
047b2264
JJ
1563 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1564 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1565 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1566 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1567 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1568 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1569
252b5132
RH
1570 default:
1571 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1572 {
b34976b6 1573 const char *result;
103f02d3 1574
252b5132
RH
1575 switch (elf_header.e_machine)
1576 {
1577 case EM_MIPS:
4fe85591 1578 case EM_MIPS_RS3_LE:
252b5132
RH
1579 result = get_mips_dynamic_type (type);
1580 break;
9a097730
RH
1581 case EM_SPARCV9:
1582 result = get_sparc64_dynamic_type (type);
1583 break;
7490d522
AM
1584 case EM_PPC:
1585 result = get_ppc_dynamic_type (type);
1586 break;
f1cb7e17
AM
1587 case EM_PPC64:
1588 result = get_ppc64_dynamic_type (type);
1589 break;
ecc51f48
NC
1590 case EM_IA_64:
1591 result = get_ia64_dynamic_type (type);
1592 break;
fabcb361
RH
1593 case EM_ALPHA:
1594 result = get_alpha_dynamic_type (type);
1595 break;
1c0d3aa6
NC
1596 case EM_SCORE:
1597 result = get_score_dynamic_type (type);
1598 break;
252b5132
RH
1599 default:
1600 result = NULL;
1601 break;
1602 }
1603
1604 if (result != NULL)
1605 return result;
1606
e9e44622 1607 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1608 }
eec8f817
DA
1609 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1610 || (elf_header.e_machine == EM_PARISC
1611 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1612 {
b34976b6 1613 const char *result;
103f02d3
UD
1614
1615 switch (elf_header.e_machine)
1616 {
1617 case EM_PARISC:
1618 result = get_parisc_dynamic_type (type);
1619 break;
1620 default:
1621 result = NULL;
1622 break;
1623 }
1624
1625 if (result != NULL)
1626 return result;
1627
e9e44622
JJ
1628 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1629 type);
103f02d3 1630 }
252b5132 1631 else
e9e44622 1632 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1633
252b5132
RH
1634 return buff;
1635 }
1636}
1637
1638static char *
d3ba0551 1639get_file_type (unsigned e_type)
252b5132 1640{
b34976b6 1641 static char buff[32];
252b5132
RH
1642
1643 switch (e_type)
1644 {
1645 case ET_NONE: return _("NONE (None)");
1646 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1647 case ET_EXEC: return _("EXEC (Executable file)");
1648 case ET_DYN: return _("DYN (Shared object file)");
1649 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1650
1651 default:
1652 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1653 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1654 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1655 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1656 else
e9e44622 1657 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1658 return buff;
1659 }
1660}
1661
1662static char *
d3ba0551 1663get_machine_name (unsigned e_machine)
252b5132 1664{
b34976b6 1665 static char buff[64]; /* XXX */
252b5132
RH
1666
1667 switch (e_machine)
1668 {
c45021f2
NC
1669 case EM_NONE: return _("None");
1670 case EM_M32: return "WE32100";
1671 case EM_SPARC: return "Sparc";
e9f53129 1672 case EM_SPU: return "SPU";
c45021f2
NC
1673 case EM_386: return "Intel 80386";
1674 case EM_68K: return "MC68000";
1675 case EM_88K: return "MC88000";
1676 case EM_486: return "Intel 80486";
1677 case EM_860: return "Intel 80860";
1678 case EM_MIPS: return "MIPS R3000";
1679 case EM_S370: return "IBM System/370";
7036c0e1 1680 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1681 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1682 case EM_PARISC: return "HPPA";
252b5132 1683 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1684 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1685 case EM_960: return "Intel 90860";
1686 case EM_PPC: return "PowerPC";
285d1771 1687 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1688 case EM_V800: return "NEC V800";
1689 case EM_FR20: return "Fujitsu FR20";
1690 case EM_RH32: return "TRW RH32";
b34976b6 1691 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1692 case EM_ARM: return "ARM";
1693 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1694 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1695 case EM_SPARCV9: return "Sparc v9";
1696 case EM_TRICORE: return "Siemens Tricore";
584da044 1697 case EM_ARC: return "ARC";
c2dcd04e
NC
1698 case EM_H8_300: return "Renesas H8/300";
1699 case EM_H8_300H: return "Renesas H8/300H";
1700 case EM_H8S: return "Renesas H8S";
1701 case EM_H8_500: return "Renesas H8/500";
30800947 1702 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1703 case EM_MIPS_X: return "Stanford MIPS-X";
1704 case EM_COLDFIRE: return "Motorola Coldfire";
1705 case EM_68HC12: return "Motorola M68HC12";
c45021f2 1706 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1707 case EM_CYGNUS_D10V:
1708 case EM_D10V: return "d10v";
1709 case EM_CYGNUS_D30V:
b34976b6 1710 case EM_D30V: return "d30v";
2b0337b0 1711 case EM_CYGNUS_M32R:
26597c86 1712 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0
AO
1713 case EM_CYGNUS_V850:
1714 case EM_V850: return "NEC v850";
1715 case EM_CYGNUS_MN10300:
1716 case EM_MN10300: return "mn10300";
1717 case EM_CYGNUS_MN10200:
1718 case EM_MN10200: return "mn10200";
1719 case EM_CYGNUS_FR30:
1720 case EM_FR30: return "Fujitsu FR30";
b34976b6 1721 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1722 case EM_PJ_OLD:
b34976b6 1723 case EM_PJ: return "picoJava";
7036c0e1
AJ
1724 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1725 case EM_PCP: return "Siemens PCP";
1726 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1727 case EM_NDR1: return "Denso NDR1 microprocesspr";
1728 case EM_STARCORE: return "Motorola Star*Core processor";
1729 case EM_ME16: return "Toyota ME16 processor";
1730 case EM_ST100: return "STMicroelectronics ST100 processor";
1731 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
1732 case EM_FX66: return "Siemens FX66 microcontroller";
1733 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1734 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1735 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
1736 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1737 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1738 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1739 case EM_SVX: return "Silicon Graphics SVx";
1740 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1741 case EM_VAX: return "Digital VAX";
2b0337b0 1742 case EM_AVR_OLD:
b34976b6 1743 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1744 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1745 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1746 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1747 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1748 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1749 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1750 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1751 case EM_X86_64: return "Advanced Micro Devices X86-64";
b7498e0e 1752 case EM_S390_OLD:
b34976b6 1753 case EM_S390: return "IBM S/390";
1c0d3aa6 1754 case EM_SCORE: return "SUNPLUS S+Core";
93fbbb04 1755 case EM_XSTORMY16: return "Sanyo Xstormy16 CPU core";
3b16e843
NC
1756 case EM_OPENRISC:
1757 case EM_OR32: return "OpenRISC";
1fe1f39c 1758 case EM_CRX: return "National Semiconductor CRX microprocessor";
d172d4ba 1759 case EM_DLX: return "OpenDLX";
1e4cf259 1760 case EM_IP2K_OLD:
b34976b6 1761 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1762 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1763 case EM_XTENSA_OLD:
1764 case EM_XTENSA: return "Tensilica Xtensa Processor";
49f58d10 1765 case EM_M32C: return "Renesas M32c";
d031aafb 1766 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 1767 case EM_BLACKFIN: return "Analog Devices Blackfin";
64fd6348
NC
1768 case EM_NIOS32: return "Altera Nios";
1769 case EM_ALTERA_NIOS2: return "Altera Nios II";
d70c5fc7 1770 case EM_XC16X: return "Infineon Technologies xc16x";
15ab5209 1771 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
252b5132 1772 default:
e9e44622 1773 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_machine);
252b5132
RH
1774 return buff;
1775 }
1776}
1777
f3485b74 1778static void
d3ba0551 1779decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
1780{
1781 unsigned eabi;
1782 int unknown = 0;
1783
1784 eabi = EF_ARM_EABI_VERSION (e_flags);
1785 e_flags &= ~ EF_ARM_EABIMASK;
1786
1787 /* Handle "generic" ARM flags. */
1788 if (e_flags & EF_ARM_RELEXEC)
1789 {
1790 strcat (buf, ", relocatable executable");
1791 e_flags &= ~ EF_ARM_RELEXEC;
1792 }
76da6bbe 1793
f3485b74
NC
1794 if (e_flags & EF_ARM_HASENTRY)
1795 {
1796 strcat (buf, ", has entry point");
1797 e_flags &= ~ EF_ARM_HASENTRY;
1798 }
76da6bbe 1799
f3485b74
NC
1800 /* Now handle EABI specific flags. */
1801 switch (eabi)
1802 {
1803 default:
2c71103e 1804 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
1805 if (e_flags)
1806 unknown = 1;
1807 break;
1808
1809 case EF_ARM_EABI_VER1:
a5bcd848 1810 strcat (buf, ", Version1 EABI");
f3485b74
NC
1811 while (e_flags)
1812 {
1813 unsigned flag;
76da6bbe 1814
f3485b74
NC
1815 /* Process flags one bit at a time. */
1816 flag = e_flags & - e_flags;
1817 e_flags &= ~ flag;
76da6bbe 1818
f3485b74
NC
1819 switch (flag)
1820 {
a5bcd848 1821 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
1822 strcat (buf, ", sorted symbol tables");
1823 break;
76da6bbe 1824
f3485b74
NC
1825 default:
1826 unknown = 1;
1827 break;
1828 }
1829 }
1830 break;
76da6bbe 1831
a5bcd848
PB
1832 case EF_ARM_EABI_VER2:
1833 strcat (buf, ", Version2 EABI");
1834 while (e_flags)
1835 {
1836 unsigned flag;
1837
1838 /* Process flags one bit at a time. */
1839 flag = e_flags & - e_flags;
1840 e_flags &= ~ flag;
1841
1842 switch (flag)
1843 {
1844 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
1845 strcat (buf, ", sorted symbol tables");
1846 break;
1847
1848 case EF_ARM_DYNSYMSUSESEGIDX:
1849 strcat (buf, ", dynamic symbols use segment index");
1850 break;
1851
1852 case EF_ARM_MAPSYMSFIRST:
1853 strcat (buf, ", mapping symbols precede others");
1854 break;
1855
1856 default:
1857 unknown = 1;
1858 break;
1859 }
1860 }
1861 break;
1862
d507cf36
PB
1863 case EF_ARM_EABI_VER3:
1864 strcat (buf, ", Version3 EABI");
8cb51566
PB
1865 break;
1866
1867 case EF_ARM_EABI_VER4:
1868 strcat (buf, ", Version4 EABI");
3a4a14e9
PB
1869 goto eabi;
1870
1871 case EF_ARM_EABI_VER5:
1872 strcat (buf, ", Version5 EABI");
1873 eabi:
d507cf36
PB
1874 while (e_flags)
1875 {
1876 unsigned flag;
1877
1878 /* Process flags one bit at a time. */
1879 flag = e_flags & - e_flags;
1880 e_flags &= ~ flag;
1881
1882 switch (flag)
1883 {
1884 case EF_ARM_BE8:
1885 strcat (buf, ", BE8");
1886 break;
1887
1888 case EF_ARM_LE8:
1889 strcat (buf, ", LE8");
1890 break;
1891
1892 default:
1893 unknown = 1;
1894 break;
1895 }
1896 }
1897 break;
1898
f3485b74 1899 case EF_ARM_EABI_UNKNOWN:
a5bcd848 1900 strcat (buf, ", GNU EABI");
f3485b74
NC
1901 while (e_flags)
1902 {
1903 unsigned flag;
76da6bbe 1904
f3485b74
NC
1905 /* Process flags one bit at a time. */
1906 flag = e_flags & - e_flags;
1907 e_flags &= ~ flag;
76da6bbe 1908
f3485b74
NC
1909 switch (flag)
1910 {
a5bcd848 1911 case EF_ARM_INTERWORK:
f3485b74
NC
1912 strcat (buf, ", interworking enabled");
1913 break;
76da6bbe 1914
a5bcd848 1915 case EF_ARM_APCS_26:
f3485b74
NC
1916 strcat (buf, ", uses APCS/26");
1917 break;
76da6bbe 1918
a5bcd848 1919 case EF_ARM_APCS_FLOAT:
f3485b74
NC
1920 strcat (buf, ", uses APCS/float");
1921 break;
76da6bbe 1922
a5bcd848 1923 case EF_ARM_PIC:
f3485b74
NC
1924 strcat (buf, ", position independent");
1925 break;
76da6bbe 1926
a5bcd848 1927 case EF_ARM_ALIGN8:
f3485b74
NC
1928 strcat (buf, ", 8 bit structure alignment");
1929 break;
76da6bbe 1930
a5bcd848 1931 case EF_ARM_NEW_ABI:
f3485b74
NC
1932 strcat (buf, ", uses new ABI");
1933 break;
76da6bbe 1934
a5bcd848 1935 case EF_ARM_OLD_ABI:
f3485b74
NC
1936 strcat (buf, ", uses old ABI");
1937 break;
76da6bbe 1938
a5bcd848 1939 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
1940 strcat (buf, ", software FP");
1941 break;
76da6bbe 1942
90e01f86
ILT
1943 case EF_ARM_VFP_FLOAT:
1944 strcat (buf, ", VFP");
1945 break;
1946
fde78edd
NC
1947 case EF_ARM_MAVERICK_FLOAT:
1948 strcat (buf, ", Maverick FP");
1949 break;
1950
f3485b74
NC
1951 default:
1952 unknown = 1;
1953 break;
1954 }
1955 }
1956 }
f3485b74
NC
1957
1958 if (unknown)
1959 strcat (buf,", <unknown>");
1960}
1961
252b5132 1962static char *
d3ba0551 1963get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 1964{
b34976b6 1965 static char buf[1024];
252b5132
RH
1966
1967 buf[0] = '\0';
76da6bbe 1968
252b5132
RH
1969 if (e_flags)
1970 {
1971 switch (e_machine)
1972 {
1973 default:
1974 break;
1975
f3485b74
NC
1976 case EM_ARM:
1977 decode_ARM_machine_flags (e_flags, buf);
1978 break;
76da6bbe 1979
ec2dfb42
AO
1980 case EM_CYGNUS_FRV:
1981 switch (e_flags & EF_FRV_CPU_MASK)
1982 {
1983 case EF_FRV_CPU_GENERIC:
1984 break;
1985
1986 default:
1987 strcat (buf, ", fr???");
1988 break;
57346661 1989
ec2dfb42
AO
1990 case EF_FRV_CPU_FR300:
1991 strcat (buf, ", fr300");
1992 break;
1993
1994 case EF_FRV_CPU_FR400:
1995 strcat (buf, ", fr400");
1996 break;
1997 case EF_FRV_CPU_FR405:
1998 strcat (buf, ", fr405");
1999 break;
2000
2001 case EF_FRV_CPU_FR450:
2002 strcat (buf, ", fr450");
2003 break;
2004
2005 case EF_FRV_CPU_FR500:
2006 strcat (buf, ", fr500");
2007 break;
2008 case EF_FRV_CPU_FR550:
2009 strcat (buf, ", fr550");
2010 break;
2011
2012 case EF_FRV_CPU_SIMPLE:
2013 strcat (buf, ", simple");
2014 break;
2015 case EF_FRV_CPU_TOMCAT:
2016 strcat (buf, ", tomcat");
2017 break;
2018 }
1c877e87 2019 break;
ec2dfb42 2020
53c7db4b 2021 case EM_68K:
425c6cb0 2022 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2023 strcat (buf, ", m68000");
425c6cb0 2024 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2025 strcat (buf, ", cpu32");
2026 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2027 strcat (buf, ", fido_a");
425c6cb0 2028 else
266abb8f
NS
2029 {
2030 char const *isa = _("unknown");
2031 char const *mac = _("unknown mac");
0b2e31dc 2032 char const *additional = NULL;
0112cd26 2033
c694fd50 2034 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2035 {
c694fd50 2036 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2037 isa = "A";
2038 additional = ", nodiv";
2039 break;
c694fd50 2040 case EF_M68K_CF_ISA_A:
266abb8f
NS
2041 isa = "A";
2042 break;
c694fd50 2043 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2044 isa = "A+";
2045 break;
c694fd50 2046 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2047 isa = "B";
2048 additional = ", nousp";
2049 break;
c694fd50 2050 case EF_M68K_CF_ISA_B:
266abb8f
NS
2051 isa = "B";
2052 break;
2053 }
2054 strcat (buf, ", cf, isa ");
2055 strcat (buf, isa);
0b2e31dc
NS
2056 if (additional)
2057 strcat (buf, additional);
c694fd50 2058 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2059 strcat (buf, ", float");
c694fd50 2060 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2061 {
2062 case 0:
2063 mac = NULL;
2064 break;
c694fd50 2065 case EF_M68K_CF_MAC:
266abb8f
NS
2066 mac = "mac";
2067 break;
c694fd50 2068 case EF_M68K_CF_EMAC:
266abb8f
NS
2069 mac = "emac";
2070 break;
2071 }
2072 if (mac)
2073 {
2074 strcat (buf, ", ");
2075 strcat (buf, mac);
2076 }
266abb8f 2077 }
53c7db4b 2078 break;
33c63f9d 2079
252b5132
RH
2080 case EM_PPC:
2081 if (e_flags & EF_PPC_EMB)
2082 strcat (buf, ", emb");
2083
2084 if (e_flags & EF_PPC_RELOCATABLE)
2085 strcat (buf, ", relocatable");
2086
2087 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2088 strcat (buf, ", relocatable-lib");
2089 break;
2090
2b0337b0 2091 case EM_V850:
252b5132
RH
2092 case EM_CYGNUS_V850:
2093 switch (e_flags & EF_V850_ARCH)
2094 {
8ad30312
NC
2095 case E_V850E1_ARCH:
2096 strcat (buf, ", v850e1");
2097 break;
252b5132
RH
2098 case E_V850E_ARCH:
2099 strcat (buf, ", v850e");
2100 break;
252b5132
RH
2101 case E_V850_ARCH:
2102 strcat (buf, ", v850");
2103 break;
2104 default:
2105 strcat (buf, ", unknown v850 architecture variant");
2106 break;
2107 }
2108 break;
2109
2b0337b0 2110 case EM_M32R:
252b5132
RH
2111 case EM_CYGNUS_M32R:
2112 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2113 strcat (buf, ", m32r");
252b5132
RH
2114 break;
2115
2116 case EM_MIPS:
4fe85591 2117 case EM_MIPS_RS3_LE:
252b5132
RH
2118 if (e_flags & EF_MIPS_NOREORDER)
2119 strcat (buf, ", noreorder");
2120
2121 if (e_flags & EF_MIPS_PIC)
2122 strcat (buf, ", pic");
2123
2124 if (e_flags & EF_MIPS_CPIC)
2125 strcat (buf, ", cpic");
2126
d1bdd336
TS
2127 if (e_flags & EF_MIPS_UCODE)
2128 strcat (buf, ", ugen_reserved");
2129
252b5132
RH
2130 if (e_flags & EF_MIPS_ABI2)
2131 strcat (buf, ", abi2");
2132
43521d43
TS
2133 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2134 strcat (buf, ", odk first");
2135
a5d22d2a
TS
2136 if (e_flags & EF_MIPS_32BITMODE)
2137 strcat (buf, ", 32bitmode");
2138
156c2f8b
NC
2139 switch ((e_flags & EF_MIPS_MACH))
2140 {
2141 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2142 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2143 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2144 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2145 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2146 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2147 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2148 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2149 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2150 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
43521d43
TS
2151 case 0:
2152 /* We simply ignore the field in this case to avoid confusion:
2153 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2154 extension. */
2155 break;
2156 default: strcat (buf, ", unknown CPU"); break;
156c2f8b 2157 }
43521d43
TS
2158
2159 switch ((e_flags & EF_MIPS_ABI))
2160 {
2161 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2162 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2163 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2164 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2165 case 0:
2166 /* We simply ignore the field in this case to avoid confusion:
2167 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2168 This means it is likely to be an o32 file, but not for
2169 sure. */
2170 break;
2171 default: strcat (buf, ", unknown ABI"); break;
2172 }
2173
2174 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2175 strcat (buf, ", mdmx");
2176
2177 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2178 strcat (buf, ", mips16");
2179
2180 switch ((e_flags & EF_MIPS_ARCH))
2181 {
2182 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2183 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2184 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2185 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2186 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2187 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2188 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2189 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2190 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
43521d43
TS
2191 default: strcat (buf, ", unknown ISA"); break;
2192 }
2193
252b5132 2194 break;
351b4b40 2195
ccde1100
AO
2196 case EM_SH:
2197 switch ((e_flags & EF_SH_MACH_MASK))
2198 {
2199 case EF_SH1: strcat (buf, ", sh1"); break;
2200 case EF_SH2: strcat (buf, ", sh2"); break;
2201 case EF_SH3: strcat (buf, ", sh3"); break;
2202 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2203 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2204 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2205 case EF_SH3E: strcat (buf, ", sh3e"); break;
2206 case EF_SH4: strcat (buf, ", sh4"); break;
2207 case EF_SH5: strcat (buf, ", sh5"); break;
2208 case EF_SH2E: strcat (buf, ", sh2e"); break;
2209 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2210 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2211 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2212 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2213 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2214 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2215 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2216 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2217 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2218 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2219 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
dc85a459 2220 default: strcat (buf, ", unknown ISA"); break;
ccde1100
AO
2221 }
2222
2223 break;
57346661 2224
351b4b40
RH
2225 case EM_SPARCV9:
2226 if (e_flags & EF_SPARC_32PLUS)
2227 strcat (buf, ", v8+");
2228
2229 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2230 strcat (buf, ", ultrasparcI");
2231
2232 if (e_flags & EF_SPARC_SUN_US3)
2233 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2234
2235 if (e_flags & EF_SPARC_HAL_R1)
2236 strcat (buf, ", halr1");
2237
2238 if (e_flags & EF_SPARC_LEDATA)
2239 strcat (buf, ", ledata");
2240
2241 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2242 strcat (buf, ", tso");
2243
2244 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2245 strcat (buf, ", pso");
2246
2247 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2248 strcat (buf, ", rmo");
2249 break;
7d466069 2250
103f02d3
UD
2251 case EM_PARISC:
2252 switch (e_flags & EF_PARISC_ARCH)
2253 {
2254 case EFA_PARISC_1_0:
2255 strcpy (buf, ", PA-RISC 1.0");
2256 break;
2257 case EFA_PARISC_1_1:
2258 strcpy (buf, ", PA-RISC 1.1");
2259 break;
2260 case EFA_PARISC_2_0:
2261 strcpy (buf, ", PA-RISC 2.0");
2262 break;
2263 default:
2264 break;
2265 }
2266 if (e_flags & EF_PARISC_TRAPNIL)
2267 strcat (buf, ", trapnil");
2268 if (e_flags & EF_PARISC_EXT)
2269 strcat (buf, ", ext");
2270 if (e_flags & EF_PARISC_LSB)
2271 strcat (buf, ", lsb");
2272 if (e_flags & EF_PARISC_WIDE)
2273 strcat (buf, ", wide");
2274 if (e_flags & EF_PARISC_NO_KABP)
2275 strcat (buf, ", no kabp");
2276 if (e_flags & EF_PARISC_LAZYSWAP)
2277 strcat (buf, ", lazyswap");
30800947 2278 break;
76da6bbe 2279
7d466069 2280 case EM_PJ:
2b0337b0 2281 case EM_PJ_OLD:
7d466069
ILT
2282 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2283 strcat (buf, ", new calling convention");
2284
2285 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2286 strcat (buf, ", gnu calling convention");
2287 break;
4d6ed7c8
NC
2288
2289 case EM_IA_64:
2290 if ((e_flags & EF_IA_64_ABI64))
2291 strcat (buf, ", 64-bit");
2292 else
2293 strcat (buf, ", 32-bit");
2294 if ((e_flags & EF_IA_64_REDUCEDFP))
2295 strcat (buf, ", reduced fp model");
2296 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2297 strcat (buf, ", no function descriptors, constant gp");
2298 else if ((e_flags & EF_IA_64_CONS_GP))
2299 strcat (buf, ", constant gp");
2300 if ((e_flags & EF_IA_64_ABSOLUTE))
2301 strcat (buf, ", absolute");
2302 break;
179d3252
JT
2303
2304 case EM_VAX:
2305 if ((e_flags & EF_VAX_NONPIC))
2306 strcat (buf, ", non-PIC");
2307 if ((e_flags & EF_VAX_DFLOAT))
2308 strcat (buf, ", D-Float");
2309 if ((e_flags & EF_VAX_GFLOAT))
2310 strcat (buf, ", G-Float");
2311 break;
252b5132
RH
2312 }
2313 }
2314
2315 return buf;
2316}
2317
252b5132 2318static const char *
d3ba0551
AM
2319get_osabi_name (unsigned int osabi)
2320{
2321 static char buff[32];
2322
2323 switch (osabi)
2324 {
2325 case ELFOSABI_NONE: return "UNIX - System V";
2326 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2327 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
2328 case ELFOSABI_LINUX: return "UNIX - Linux";
2329 case ELFOSABI_HURD: return "GNU/Hurd";
2330 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2331 case ELFOSABI_AIX: return "UNIX - AIX";
2332 case ELFOSABI_IRIX: return "UNIX - IRIX";
2333 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2334 case ELFOSABI_TRU64: return "UNIX - TRU64";
2335 case ELFOSABI_MODESTO: return "Novell - Modesto";
2336 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2337 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2338 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
2339 case ELFOSABI_AROS: return "Amiga Research OS";
2340 case ELFOSABI_STANDALONE: return _("Standalone App");
2341 case ELFOSABI_ARM: return "ARM";
2342 default:
e9e44622 2343 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2344 return buff;
2345 }
2346}
2347
b294bdf8
MM
2348static const char *
2349get_arm_segment_type (unsigned long type)
2350{
2351 switch (type)
2352 {
2353 case PT_ARM_EXIDX:
2354 return "EXIDX";
2355 default:
2356 break;
2357 }
2358
2359 return NULL;
2360}
2361
d3ba0551
AM
2362static const char *
2363get_mips_segment_type (unsigned long type)
252b5132
RH
2364{
2365 switch (type)
2366 {
2367 case PT_MIPS_REGINFO:
2368 return "REGINFO";
2369 case PT_MIPS_RTPROC:
2370 return "RTPROC";
2371 case PT_MIPS_OPTIONS:
2372 return "OPTIONS";
2373 default:
2374 break;
2375 }
2376
2377 return NULL;
2378}
2379
103f02d3 2380static const char *
d3ba0551 2381get_parisc_segment_type (unsigned long type)
103f02d3
UD
2382{
2383 switch (type)
2384 {
2385 case PT_HP_TLS: return "HP_TLS";
2386 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2387 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2388 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2389 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2390 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2391 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2392 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2393 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2394 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2395 case PT_HP_PARALLEL: return "HP_PARALLEL";
2396 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2397 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2398 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2399 case PT_HP_STACK: return "HP_STACK";
2400 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2401 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2402 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2403 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2404 default:
2405 break;
2406 }
2407
2408 return NULL;
2409}
2410
4d6ed7c8 2411static const char *
d3ba0551 2412get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2413{
2414 switch (type)
2415 {
2416 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2417 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2418 case PT_HP_TLS: return "HP_TLS";
2419 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2420 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2421 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2422 default:
2423 break;
2424 }
2425
2426 return NULL;
2427}
2428
252b5132 2429static const char *
d3ba0551 2430get_segment_type (unsigned long p_type)
252b5132 2431{
b34976b6 2432 static char buff[32];
252b5132
RH
2433
2434 switch (p_type)
2435 {
b34976b6
AM
2436 case PT_NULL: return "NULL";
2437 case PT_LOAD: return "LOAD";
252b5132 2438 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2439 case PT_INTERP: return "INTERP";
2440 case PT_NOTE: return "NOTE";
2441 case PT_SHLIB: return "SHLIB";
2442 case PT_PHDR: return "PHDR";
13ae64f3 2443 case PT_TLS: return "TLS";
252b5132 2444
65765700
JJ
2445 case PT_GNU_EH_FRAME:
2446 return "GNU_EH_FRAME";
fb7b006e 2447 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2448 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2449
252b5132
RH
2450 default:
2451 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2452 {
b34976b6 2453 const char *result;
103f02d3 2454
252b5132
RH
2455 switch (elf_header.e_machine)
2456 {
b294bdf8
MM
2457 case EM_ARM:
2458 result = get_arm_segment_type (p_type);
2459 break;
252b5132 2460 case EM_MIPS:
4fe85591 2461 case EM_MIPS_RS3_LE:
252b5132
RH
2462 result = get_mips_segment_type (p_type);
2463 break;
103f02d3
UD
2464 case EM_PARISC:
2465 result = get_parisc_segment_type (p_type);
2466 break;
4d6ed7c8
NC
2467 case EM_IA_64:
2468 result = get_ia64_segment_type (p_type);
2469 break;
252b5132
RH
2470 default:
2471 result = NULL;
2472 break;
2473 }
103f02d3 2474
252b5132
RH
2475 if (result != NULL)
2476 return result;
103f02d3 2477
252b5132
RH
2478 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2479 }
2480 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2481 {
b34976b6 2482 const char *result;
103f02d3
UD
2483
2484 switch (elf_header.e_machine)
2485 {
2486 case EM_PARISC:
2487 result = get_parisc_segment_type (p_type);
2488 break;
00428cca
AM
2489 case EM_IA_64:
2490 result = get_ia64_segment_type (p_type);
2491 break;
103f02d3
UD
2492 default:
2493 result = NULL;
2494 break;
2495 }
2496
2497 if (result != NULL)
2498 return result;
2499
2500 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
2501 }
252b5132 2502 else
e9e44622 2503 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
2504
2505 return buff;
2506 }
2507}
2508
2509static const char *
d3ba0551 2510get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
2511{
2512 switch (sh_type)
2513 {
b34976b6
AM
2514 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2515 case SHT_MIPS_MSYM: return "MIPS_MSYM";
2516 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2517 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
2518 case SHT_MIPS_UCODE: return "MIPS_UCODE";
2519 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
2520 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
2521 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
2522 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
2523 case SHT_MIPS_RELD: return "MIPS_RELD";
2524 case SHT_MIPS_IFACE: return "MIPS_IFACE";
2525 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
2526 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2527 case SHT_MIPS_SHDR: return "MIPS_SHDR";
2528 case SHT_MIPS_FDESC: return "MIPS_FDESC";
2529 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
2530 case SHT_MIPS_DENSE: return "MIPS_DENSE";
2531 case SHT_MIPS_PDESC: return "MIPS_PDESC";
2532 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
2533 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
2534 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
2535 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
2536 case SHT_MIPS_LINE: return "MIPS_LINE";
2537 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
2538 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
2539 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
2540 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
2541 case SHT_MIPS_DWARF: return "MIPS_DWARF";
2542 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
2543 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2544 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
2545 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
2546 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
2547 case SHT_MIPS_XLATE: return "MIPS_XLATE";
2548 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
2549 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
2550 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
2551 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
2552 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
2553 default:
2554 break;
2555 }
2556 return NULL;
2557}
2558
103f02d3 2559static const char *
d3ba0551 2560get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
2561{
2562 switch (sh_type)
2563 {
2564 case SHT_PARISC_EXT: return "PARISC_EXT";
2565 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
2566 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
2567 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
2568 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
2569 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 2570 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
2571 default:
2572 break;
2573 }
2574 return NULL;
2575}
2576
4d6ed7c8 2577static const char *
d3ba0551 2578get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 2579{
18bd398b 2580 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
2581 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
2582 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 2583
4d6ed7c8
NC
2584 switch (sh_type)
2585 {
ecc51f48
NC
2586 case SHT_IA_64_EXT: return "IA_64_EXT";
2587 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
2588 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4d6ed7c8
NC
2589 default:
2590 break;
2591 }
2592 return NULL;
2593}
2594
d2b2c203
DJ
2595static const char *
2596get_x86_64_section_type_name (unsigned int sh_type)
2597{
2598 switch (sh_type)
2599 {
2600 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
2601 default:
2602 break;
2603 }
2604 return NULL;
2605}
2606
40a18ebd
NC
2607static const char *
2608get_arm_section_type_name (unsigned int sh_type)
2609{
2610 switch (sh_type)
2611 {
2612 case SHT_ARM_EXIDX:
2613 return "ARM_EXIDX";
ec1c4759
RE
2614 case SHT_ARM_PREEMPTMAP:
2615 return "ARM_PREEMPTMAP";
2616 case SHT_ARM_ATTRIBUTES:
2617 return "ARM_ATTRIBUTES";
40a18ebd
NC
2618 default:
2619 break;
2620 }
2621 return NULL;
2622}
2623
252b5132 2624static const char *
d3ba0551 2625get_section_type_name (unsigned int sh_type)
252b5132 2626{
b34976b6 2627 static char buff[32];
252b5132
RH
2628
2629 switch (sh_type)
2630 {
2631 case SHT_NULL: return "NULL";
2632 case SHT_PROGBITS: return "PROGBITS";
2633 case SHT_SYMTAB: return "SYMTAB";
2634 case SHT_STRTAB: return "STRTAB";
2635 case SHT_RELA: return "RELA";
2636 case SHT_HASH: return "HASH";
2637 case SHT_DYNAMIC: return "DYNAMIC";
2638 case SHT_NOTE: return "NOTE";
2639 case SHT_NOBITS: return "NOBITS";
2640 case SHT_REL: return "REL";
2641 case SHT_SHLIB: return "SHLIB";
2642 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
2643 case SHT_INIT_ARRAY: return "INIT_ARRAY";
2644 case SHT_FINI_ARRAY: return "FINI_ARRAY";
2645 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 2646 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
2647 case SHT_GROUP: return "GROUP";
2648 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
2649 case SHT_GNU_verdef: return "VERDEF";
2650 case SHT_GNU_verneed: return "VERNEED";
2651 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
2652 case 0x6ffffff0: return "VERSYM";
2653 case 0x6ffffffc: return "VERDEF";
252b5132
RH
2654 case 0x7ffffffd: return "AUXILIARY";
2655 case 0x7fffffff: return "FILTER";
047b2264 2656 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
2657
2658 default:
2659 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
2660 {
b34976b6 2661 const char *result;
252b5132
RH
2662
2663 switch (elf_header.e_machine)
2664 {
2665 case EM_MIPS:
4fe85591 2666 case EM_MIPS_RS3_LE:
252b5132
RH
2667 result = get_mips_section_type_name (sh_type);
2668 break;
103f02d3
UD
2669 case EM_PARISC:
2670 result = get_parisc_section_type_name (sh_type);
2671 break;
4d6ed7c8
NC
2672 case EM_IA_64:
2673 result = get_ia64_section_type_name (sh_type);
2674 break;
d2b2c203
DJ
2675 case EM_X86_64:
2676 result = get_x86_64_section_type_name (sh_type);
2677 break;
40a18ebd
NC
2678 case EM_ARM:
2679 result = get_arm_section_type_name (sh_type);
2680 break;
252b5132
RH
2681 default:
2682 result = NULL;
2683 break;
2684 }
2685
2686 if (result != NULL)
2687 return result;
2688
c91d0dfb 2689 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
2690 }
2691 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
c91d0dfb 2692 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
252b5132 2693 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 2694 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 2695 else
e9e44622 2696 snprintf (buff, sizeof (buff), _("<unknown>: %x"), sh_type);
103f02d3 2697
252b5132
RH
2698 return buff;
2699 }
2700}
2701
2979dc34
JJ
2702#define OPTION_DEBUG_DUMP 512
2703
85b1c36d 2704static struct option options[] =
252b5132 2705{
b34976b6 2706 {"all", no_argument, 0, 'a'},
252b5132
RH
2707 {"file-header", no_argument, 0, 'h'},
2708 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
2709 {"headers", no_argument, 0, 'e'},
2710 {"histogram", no_argument, 0, 'I'},
2711 {"segments", no_argument, 0, 'l'},
2712 {"sections", no_argument, 0, 'S'},
252b5132 2713 {"section-headers", no_argument, 0, 'S'},
f5842774 2714 {"section-groups", no_argument, 0, 'g'},
5477e8a0 2715 {"section-details", no_argument, 0, 't'},
595cf52e 2716 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
2717 {"symbols", no_argument, 0, 's'},
2718 {"syms", no_argument, 0, 's'},
2719 {"relocs", no_argument, 0, 'r'},
2720 {"notes", no_argument, 0, 'n'},
2721 {"dynamic", no_argument, 0, 'd'},
a952a375 2722 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
2723 {"version-info", no_argument, 0, 'V'},
2724 {"use-dynamic", no_argument, 0, 'D'},
b34976b6 2725 {"hex-dump", required_argument, 0, 'x'},
2979dc34 2726 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
4d6ed7c8 2727 {"unwind", no_argument, 0, 'u'},
252b5132
RH
2728#ifdef SUPPORT_DISASSEMBLY
2729 {"instruction-dump", required_argument, 0, 'i'},
2730#endif
2731
b34976b6
AM
2732 {"version", no_argument, 0, 'v'},
2733 {"wide", no_argument, 0, 'W'},
2734 {"help", no_argument, 0, 'H'},
2735 {0, no_argument, 0, 0}
252b5132
RH
2736};
2737
2738static void
d3ba0551 2739usage (void)
252b5132 2740{
8b53311e
NC
2741 fprintf (stdout, _("Usage: readelf <option(s)> elf-file(s)\n"));
2742 fprintf (stdout, _(" Display information about the contents of ELF format files\n"));
2743 fprintf (stdout, _(" Options are:\n\
2744 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
2745 -h --file-header Display the ELF file header\n\
2746 -l --program-headers Display the program headers\n\
2747 --segments An alias for --program-headers\n\
2748 -S --section-headers Display the sections' header\n\
2749 --sections An alias for --section-headers\n\
f5842774 2750 -g --section-groups Display the section groups\n\
5477e8a0 2751 -t --section-details Display the section details\n\
8b53311e
NC
2752 -e --headers Equivalent to: -h -l -S\n\
2753 -s --syms Display the symbol table\n\
2754 --symbols An alias for --syms\n\
2755 -n --notes Display the core notes (if present)\n\
2756 -r --relocs Display the relocations (if present)\n\
2757 -u --unwind Display the unwind info (if present)\n\
b2d38a17 2758 -d --dynamic Display the dynamic section (if present)\n\
8b53311e
NC
2759 -V --version-info Display the version sections (if present)\n\
2760 -A --arch-specific Display architecture specific information (if any).\n\
2761 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
2762 -x --hex-dump=<number> Dump the contents of section <number>\n\
18bd398b
NC
2763 -w[liaprmfFsoR] or\n\
2764 --debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]\n\
8b53311e 2765 Display the contents of DWARF2 debug sections\n"));
252b5132 2766#ifdef SUPPORT_DISASSEMBLY
8b53311e
NC
2767 fprintf (stdout, _("\
2768 -i --instruction-dump=<number>\n\
2769 Disassemble the contents of section <number>\n"));
252b5132 2770#endif
8b53311e
NC
2771 fprintf (stdout, _("\
2772 -I --histogram Display histogram of bucket list lengths\n\
2773 -W --wide Allow output width to exceed 80 characters\n\
07012eee 2774 @<file> Read options from <file>\n\
8b53311e
NC
2775 -H --help Display this information\n\
2776 -v --version Display the version number of readelf\n"));
8ad3436c 2777 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
2778
2779 exit (0);
2780}
2781
18bd398b
NC
2782/* Record the fact that the user wants the contents of section number
2783 SECTION to be displayed using the method(s) encoded as flags bits
2784 in TYPE. Note, TYPE can be zero if we are creating the array for
2785 the first time. */
2786
252b5132 2787static void
d3ba0551 2788request_dump (unsigned int section, int type)
252b5132
RH
2789{
2790 if (section >= num_dump_sects)
2791 {
b34976b6 2792 char *new_dump_sects;
252b5132 2793
d3ba0551 2794 new_dump_sects = calloc (section + 1, 1);
252b5132
RH
2795
2796 if (new_dump_sects == NULL)
2797 error (_("Out of memory allocating dump request table."));
2798 else
2799 {
2800 /* Copy current flag settings. */
2801 memcpy (new_dump_sects, dump_sects, num_dump_sects);
2802
2803 free (dump_sects);
2804
2805 dump_sects = new_dump_sects;
2806 num_dump_sects = section + 1;
2807 }
2808 }
2809
2810 if (dump_sects)
b34976b6 2811 dump_sects[section] |= type;
252b5132
RH
2812
2813 return;
2814}
2815
aef1f6d0
DJ
2816/* Request a dump by section name. */
2817
2818static void
2819request_dump_byname (const char *section, int type)
2820{
2821 struct dump_list_entry *new_request;
2822
2823 new_request = malloc (sizeof (struct dump_list_entry));
2824 if (!new_request)
2825 error (_("Out of memory allocating dump request table."));
2826
2827 new_request->name = strdup (section);
2828 if (!new_request->name)
2829 error (_("Out of memory allocating dump request table."));
2830
2831 new_request->type = type;
2832
2833 new_request->next = dump_sects_byname;
2834 dump_sects_byname = new_request;
2835}
2836
252b5132 2837static void
d3ba0551 2838parse_args (int argc, char **argv)
252b5132
RH
2839{
2840 int c;
2841
2842 if (argc < 2)
2843 usage ();
2844
2845 while ((c = getopt_long
5477e8a0 2846 (argc, argv, "ersuahnldSDAINtgw::x:i:vVWH", options, NULL)) != EOF)
252b5132 2847 {
b34976b6
AM
2848 char *cp;
2849 int section;
252b5132
RH
2850
2851 switch (c)
2852 {
2853 case 0:
2854 /* Long options. */
2855 break;
2856 case 'H':
2857 usage ();
2858 break;
2859
2860 case 'a':
b34976b6
AM
2861 do_syms++;
2862 do_reloc++;
2863 do_unwind++;
2864 do_dynamic++;
2865 do_header++;
2866 do_sections++;
f5842774 2867 do_section_groups++;
b34976b6
AM
2868 do_segments++;
2869 do_version++;
2870 do_histogram++;
2871 do_arch++;
2872 do_notes++;
252b5132 2873 break;
f5842774
L
2874 case 'g':
2875 do_section_groups++;
2876 break;
5477e8a0 2877 case 't':
595cf52e 2878 case 'N':
5477e8a0
L
2879 do_sections++;
2880 do_section_details++;
595cf52e 2881 break;
252b5132 2882 case 'e':
b34976b6
AM
2883 do_header++;
2884 do_sections++;
2885 do_segments++;
252b5132 2886 break;
a952a375 2887 case 'A':
b34976b6 2888 do_arch++;
a952a375 2889 break;
252b5132 2890 case 'D':
b34976b6 2891 do_using_dynamic++;
252b5132
RH
2892 break;
2893 case 'r':
b34976b6 2894 do_reloc++;
252b5132 2895 break;
4d6ed7c8 2896 case 'u':
b34976b6 2897 do_unwind++;
4d6ed7c8 2898 break;
252b5132 2899 case 'h':
b34976b6 2900 do_header++;
252b5132
RH
2901 break;
2902 case 'l':
b34976b6 2903 do_segments++;
252b5132
RH
2904 break;
2905 case 's':
b34976b6 2906 do_syms++;
252b5132
RH
2907 break;
2908 case 'S':
b34976b6 2909 do_sections++;
252b5132
RH
2910 break;
2911 case 'd':
b34976b6 2912 do_dynamic++;
252b5132 2913 break;
a952a375 2914 case 'I':
b34976b6 2915 do_histogram++;
a952a375 2916 break;
779fe533 2917 case 'n':
b34976b6 2918 do_notes++;
779fe533 2919 break;
252b5132 2920 case 'x':
b34976b6 2921 do_dump++;
252b5132 2922 section = strtoul (optarg, & cp, 0);
b34976b6 2923 if (! *cp && section >= 0)
aef1f6d0
DJ
2924 request_dump (section, HEX_DUMP);
2925 else
2926 request_dump_byname (optarg, HEX_DUMP);
2927 break;
252b5132 2928 case 'w':
b34976b6 2929 do_dump++;
252b5132
RH
2930 if (optarg == 0)
2931 do_debugging = 1;
2932 else
2933 {
f662939a 2934 unsigned int index = 0;
53c7db4b 2935
252b5132 2936 do_debugging = 0;
252b5132 2937
f662939a
NC
2938 while (optarg[index])
2939 switch (optarg[index++])
2940 {
2941 case 'i':
2942 case 'I':
2943 do_debug_info = 1;
2944 break;
2945
2946 case 'a':
2947 case 'A':
2948 do_debug_abbrevs = 1;
2949 break;
2950
2951 case 'l':
2952 case 'L':
2953 do_debug_lines = 1;
2954 break;
2955
2956 case 'p':
2957 case 'P':
2958 do_debug_pubnames = 1;
2959 break;
2960
2961 case 'r':
f662939a
NC
2962 do_debug_aranges = 1;
2963 break;
2964
18bd398b
NC
2965 case 'R':
2966 do_debug_ranges = 1;
2967 break;
2968
f662939a
NC
2969 case 'F':
2970 do_debug_frames_interp = 1;
2971 case 'f':
2972 do_debug_frames = 1;
2973 break;
2974
2975 case 'm':
2976 case 'M':
2977 do_debug_macinfo = 1;
2978 break;
2979
261a45ad
NC
2980 case 's':
2981 case 'S':
2982 do_debug_str = 1;
2983 break;
2984
a2f14207
DB
2985 case 'o':
2986 case 'O':
2987 do_debug_loc = 1;
2988 break;
53c7db4b 2989
f662939a 2990 default:
2c71103e 2991 warn (_("Unrecognized debug option '%s'\n"), optarg);
f662939a
NC
2992 break;
2993 }
252b5132
RH
2994 }
2995 break;
2979dc34 2996 case OPTION_DEBUG_DUMP:
b34976b6 2997 do_dump++;
2979dc34
JJ
2998 if (optarg == 0)
2999 do_debugging = 1;
3000 else
3001 {
18bd398b
NC
3002 typedef struct
3003 {
3004 const char * option;
3005 int * variable;
3006 }
3007 debug_dump_long_opts;
3008
3009 debug_dump_long_opts opts_table [] =
3010 {
3011 /* Please keep this table alpha- sorted. */
3012 { "Ranges", & do_debug_ranges },
3013 { "abbrev", & do_debug_abbrevs },
3014 { "aranges", & do_debug_aranges },
3015 { "frames", & do_debug_frames },
3016 { "frames-interp", & do_debug_frames_interp },
3017 { "info", & do_debug_info },
3018 { "line", & do_debug_lines },
3019 { "loc", & do_debug_loc },
3020 { "macro", & do_debug_macinfo },
3021 { "pubnames", & do_debug_pubnames },
3022 /* This entry is for compatability
3023 with earlier versions of readelf. */
3024 { "ranges", & do_debug_aranges },
3025 { "str", & do_debug_str },
3026 { NULL, NULL }
3027 };
3028
2979dc34
JJ
3029 const char *p;
3030
3031 do_debugging = 0;
3032
3033 p = optarg;
3034 while (*p)
3035 {
18bd398b
NC
3036 debug_dump_long_opts * entry;
3037
3038 for (entry = opts_table; entry->option; entry++)
2979dc34 3039 {
18bd398b 3040 size_t len = strlen (entry->option);
2979dc34 3041
18bd398b 3042 if (strneq (p, entry->option, len)
2979dc34
JJ
3043 && (p[len] == ',' || p[len] == '\0'))
3044 {
18bd398b
NC
3045 * entry->variable = 1;
3046
3047 /* The --debug-dump=frames-interp option also
3048 enables the --debug-dump=frames option. */
3049 if (do_debug_frames_interp)
3050 do_debug_frames = 1;
2979dc34
JJ
3051
3052 p += len;
3053 break;
3054 }
3055 }
3056
18bd398b 3057 if (entry->option == NULL)
2979dc34
JJ
3058 {
3059 warn (_("Unrecognized debug option '%s'\n"), p);
3060 p = strchr (p, ',');
3061 if (p == NULL)
3062 break;
3063 }
3064
3065 if (*p == ',')
3066 p++;
3067 }
3068 }
3069 break;
252b5132
RH
3070#ifdef SUPPORT_DISASSEMBLY
3071 case 'i':
b34976b6 3072 do_dump++;
252b5132 3073 section = strtoul (optarg, & cp, 0);
b34976b6 3074 if (! *cp && section >= 0)
252b5132
RH
3075 {
3076 request_dump (section, DISASS_DUMP);
3077 break;
3078 }
3079 goto oops;
3080#endif
3081 case 'v':
3082 print_version (program_name);
3083 break;
3084 case 'V':
b34976b6 3085 do_version++;
252b5132 3086 break;
d974e256 3087 case 'W':
b34976b6 3088 do_wide++;
d974e256 3089 break;
252b5132 3090 default:
aef1f6d0 3091#ifdef SUPPORT_DISASSEMBLY
252b5132 3092 oops:
aef1f6d0 3093#endif
252b5132
RH
3094 /* xgettext:c-format */
3095 error (_("Invalid option '-%c'\n"), c);
3096 /* Drop through. */
3097 case '?':
3098 usage ();
3099 }
3100 }
3101
4d6ed7c8 3102 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3103 && !do_segments && !do_header && !do_dump && !do_version
f5842774
L
3104 && !do_histogram && !do_debugging && !do_arch && !do_notes
3105 && !do_section_groups)
252b5132
RH
3106 usage ();
3107 else if (argc < 3)
3108 {
3109 warn (_("Nothing to do.\n"));
18bd398b 3110 usage ();
252b5132
RH
3111 }
3112}
3113
3114static const char *
d3ba0551 3115get_elf_class (unsigned int elf_class)
252b5132 3116{
b34976b6 3117 static char buff[32];
103f02d3 3118
252b5132
RH
3119 switch (elf_class)
3120 {
3121 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3122 case ELFCLASS32: return "ELF32";
3123 case ELFCLASS64: return "ELF64";
ab5e7794 3124 default:
e9e44622 3125 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3126 return buff;
252b5132
RH
3127 }
3128}
3129
3130static const char *
d3ba0551 3131get_data_encoding (unsigned int encoding)
252b5132 3132{
b34976b6 3133 static char buff[32];
103f02d3 3134
252b5132
RH
3135 switch (encoding)
3136 {
3137 case ELFDATANONE: return _("none");
33c63f9d
CM
3138 case ELFDATA2LSB: return _("2's complement, little endian");
3139 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3140 default:
e9e44622 3141 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3142 return buff;
252b5132
RH
3143 }
3144}
3145
252b5132 3146/* Decode the data held in 'elf_header'. */
ee42cf8c 3147
252b5132 3148static int
d3ba0551 3149process_file_header (void)
252b5132 3150{
b34976b6
AM
3151 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3152 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3153 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3154 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3155 {
3156 error
3157 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3158 return 0;
3159 }
3160
3161 if (do_header)
3162 {
3163 int i;
3164
3165 printf (_("ELF Header:\n"));
3166 printf (_(" Magic: "));
b34976b6
AM
3167 for (i = 0; i < EI_NIDENT; i++)
3168 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3169 printf ("\n");
3170 printf (_(" Class: %s\n"),
b34976b6 3171 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3172 printf (_(" Data: %s\n"),
b34976b6 3173 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3174 printf (_(" Version: %d %s\n"),
b34976b6
AM
3175 elf_header.e_ident[EI_VERSION],
3176 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3177 ? "(current)"
b34976b6 3178 : (elf_header.e_ident[EI_VERSION] != EV_NONE
789be9f7
ILT
3179 ? "<unknown: %lx>"
3180 : "")));
252b5132 3181 printf (_(" OS/ABI: %s\n"),
b34976b6 3182 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3183 printf (_(" ABI Version: %d\n"),
b34976b6 3184 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3185 printf (_(" Type: %s\n"),
3186 get_file_type (elf_header.e_type));
3187 printf (_(" Machine: %s\n"),
3188 get_machine_name (elf_header.e_machine));
3189 printf (_(" Version: 0x%lx\n"),
3190 (unsigned long) elf_header.e_version);
76da6bbe 3191
f7a99963
NC
3192 printf (_(" Entry point address: "));
3193 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3194 printf (_("\n Start of program headers: "));
3195 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3196 printf (_(" (bytes into file)\n Start of section headers: "));
3197 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3198 printf (_(" (bytes into file)\n"));
76da6bbe 3199
252b5132
RH
3200 printf (_(" Flags: 0x%lx%s\n"),
3201 (unsigned long) elf_header.e_flags,
3202 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3203 printf (_(" Size of this header: %ld (bytes)\n"),
3204 (long) elf_header.e_ehsize);
3205 printf (_(" Size of program headers: %ld (bytes)\n"),
3206 (long) elf_header.e_phentsize);
3207 printf (_(" Number of program headers: %ld\n"),
3208 (long) elf_header.e_phnum);
3209 printf (_(" Size of section headers: %ld (bytes)\n"),
3210 (long) elf_header.e_shentsize);
560f3c1c 3211 printf (_(" Number of section headers: %ld"),
252b5132 3212 (long) elf_header.e_shnum);
560f3c1c
AM
3213 if (section_headers != NULL && elf_header.e_shnum == 0)
3214 printf (" (%ld)", (long) section_headers[0].sh_size);
3215 putc ('\n', stdout);
3216 printf (_(" Section header string table index: %ld"),
252b5132 3217 (long) elf_header.e_shstrndx);
560f3c1c
AM
3218 if (section_headers != NULL && elf_header.e_shstrndx == SHN_XINDEX)
3219 printf (" (%ld)", (long) section_headers[0].sh_link);
0b49d371
NC
3220 else if (elf_header.e_shstrndx != SHN_UNDEF
3221 && (elf_header.e_shstrndx >= elf_header.e_shnum
3222 || (elf_header.e_shstrndx >= SHN_LORESERVE
3223 && elf_header.e_shstrndx <= SHN_HIRESERVE)))
3224 printf (" <corrupt: out of range>");
560f3c1c
AM
3225 putc ('\n', stdout);
3226 }
3227
3228 if (section_headers != NULL)
3229 {
3230 if (elf_header.e_shnum == 0)
3231 elf_header.e_shnum = section_headers[0].sh_size;
3232 if (elf_header.e_shstrndx == SHN_XINDEX)
3233 elf_header.e_shstrndx = section_headers[0].sh_link;
0b49d371
NC
3234 else if (elf_header.e_shstrndx != SHN_UNDEF
3235 && (elf_header.e_shstrndx >= elf_header.e_shnum
3236 || (elf_header.e_shstrndx >= SHN_LORESERVE
3237 && elf_header.e_shstrndx <= SHN_HIRESERVE)))
3238 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3239 free (section_headers);
3240 section_headers = NULL;
252b5132 3241 }
103f02d3 3242
9ea033b2
NC
3243 return 1;
3244}
3245
252b5132 3246
9ea033b2 3247static int
d3ba0551 3248get_32bit_program_headers (FILE *file, Elf_Internal_Phdr *program_headers)
9ea033b2 3249{
b34976b6
AM
3250 Elf32_External_Phdr *phdrs;
3251 Elf32_External_Phdr *external;
3252 Elf_Internal_Phdr *internal;
3253 unsigned int i;
103f02d3 3254
d3ba0551 3255 phdrs = get_data (NULL, file, elf_header.e_phoff,
c256ffe7 3256 elf_header.e_phentsize, elf_header.e_phnum,
d3ba0551 3257 _("program headers"));
a6e9f9df
AM
3258 if (!phdrs)
3259 return 0;
9ea033b2
NC
3260
3261 for (i = 0, internal = program_headers, external = phdrs;
3262 i < elf_header.e_phnum;
b34976b6 3263 i++, internal++, external++)
252b5132 3264 {
9ea033b2
NC
3265 internal->p_type = BYTE_GET (external->p_type);
3266 internal->p_offset = BYTE_GET (external->p_offset);
3267 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3268 internal->p_paddr = BYTE_GET (external->p_paddr);
3269 internal->p_filesz = BYTE_GET (external->p_filesz);
3270 internal->p_memsz = BYTE_GET (external->p_memsz);
3271 internal->p_flags = BYTE_GET (external->p_flags);
3272 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3273 }
3274
9ea033b2
NC
3275 free (phdrs);
3276
252b5132
RH
3277 return 1;
3278}
3279
9ea033b2 3280static int
d3ba0551 3281get_64bit_program_headers (FILE *file, Elf_Internal_Phdr *program_headers)
9ea033b2 3282{
b34976b6
AM
3283 Elf64_External_Phdr *phdrs;
3284 Elf64_External_Phdr *external;
3285 Elf_Internal_Phdr *internal;
3286 unsigned int i;
103f02d3 3287
d3ba0551 3288 phdrs = get_data (NULL, file, elf_header.e_phoff,
c256ffe7 3289 elf_header.e_phentsize, elf_header.e_phnum,
d3ba0551 3290 _("program headers"));
a6e9f9df
AM
3291 if (!phdrs)
3292 return 0;
9ea033b2
NC
3293
3294 for (i = 0, internal = program_headers, external = phdrs;
3295 i < elf_header.e_phnum;
b34976b6 3296 i++, internal++, external++)
9ea033b2
NC
3297 {
3298 internal->p_type = BYTE_GET (external->p_type);
3299 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3300 internal->p_offset = BYTE_GET (external->p_offset);
3301 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3302 internal->p_paddr = BYTE_GET (external->p_paddr);
3303 internal->p_filesz = BYTE_GET (external->p_filesz);
3304 internal->p_memsz = BYTE_GET (external->p_memsz);
3305 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3306 }
3307
3308 free (phdrs);
3309
3310 return 1;
3311}
252b5132 3312
d93f0186
NC
3313/* Returns 1 if the program headers were read into `program_headers'. */
3314
3315static int
d3ba0551 3316get_program_headers (FILE *file)
d93f0186
NC
3317{
3318 Elf_Internal_Phdr *phdrs;
3319
3320 /* Check cache of prior read. */
3321 if (program_headers != NULL)
3322 return 1;
3323
c256ffe7 3324 phdrs = cmalloc (elf_header.e_phnum, sizeof (Elf_Internal_Phdr));
d93f0186
NC
3325
3326 if (phdrs == NULL)
3327 {
3328 error (_("Out of memory\n"));
3329 return 0;
3330 }
3331
3332 if (is_32bit_elf
3333 ? get_32bit_program_headers (file, phdrs)
3334 : get_64bit_program_headers (file, phdrs))
3335 {
3336 program_headers = phdrs;
3337 return 1;
3338 }
3339
3340 free (phdrs);
3341 return 0;
3342}
3343
2f62977e
NC
3344/* Returns 1 if the program headers were loaded. */
3345
252b5132 3346static int
d3ba0551 3347process_program_headers (FILE *file)
252b5132 3348{
b34976b6
AM
3349 Elf_Internal_Phdr *segment;
3350 unsigned int i;
252b5132
RH
3351
3352 if (elf_header.e_phnum == 0)
3353 {
3354 if (do_segments)
3355 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3356 return 0;
252b5132
RH
3357 }
3358
3359 if (do_segments && !do_header)
3360 {
f7a99963
NC
3361 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3362 printf (_("Entry point "));
3363 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3364 printf (_("\nThere are %d program headers, starting at offset "),
3365 elf_header.e_phnum);
3366 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3367 printf ("\n");
252b5132
RH
3368 }
3369
d93f0186 3370 if (! get_program_headers (file))
252b5132 3371 return 0;
103f02d3 3372
252b5132
RH
3373 if (do_segments)
3374 {
3a1a2036
NC
3375 if (elf_header.e_phnum > 1)
3376 printf (_("\nProgram Headers:\n"));
3377 else
3378 printf (_("\nProgram Headers:\n"));
76da6bbe 3379
f7a99963
NC
3380 if (is_32bit_elf)
3381 printf
3382 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3383 else if (do_wide)
3384 printf
3385 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3386 else
3387 {
3388 printf
3389 (_(" Type Offset VirtAddr PhysAddr\n"));
3390 printf
3391 (_(" FileSiz MemSiz Flags Align\n"));
3392 }
252b5132
RH
3393 }
3394
252b5132 3395 dynamic_addr = 0;
1b228002 3396 dynamic_size = 0;
252b5132
RH
3397
3398 for (i = 0, segment = program_headers;
3399 i < elf_header.e_phnum;
b34976b6 3400 i++, segment++)
252b5132
RH
3401 {
3402 if (do_segments)
3403 {
103f02d3 3404 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3405
3406 if (is_32bit_elf)
3407 {
3408 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3409 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3410 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3411 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3412 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3413 printf ("%c%c%c ",
3414 (segment->p_flags & PF_R ? 'R' : ' '),
3415 (segment->p_flags & PF_W ? 'W' : ' '),
3416 (segment->p_flags & PF_X ? 'E' : ' '));
3417 printf ("%#lx", (unsigned long) segment->p_align);
3418 }
d974e256
JJ
3419 else if (do_wide)
3420 {
3421 if ((unsigned long) segment->p_offset == segment->p_offset)
3422 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3423 else
3424 {
3425 print_vma (segment->p_offset, FULL_HEX);
3426 putchar (' ');
3427 }
3428
3429 print_vma (segment->p_vaddr, FULL_HEX);
3430 putchar (' ');
3431 print_vma (segment->p_paddr, FULL_HEX);
3432 putchar (' ');
3433
3434 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3435 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3436 else
3437 {
3438 print_vma (segment->p_filesz, FULL_HEX);
3439 putchar (' ');
3440 }
3441
3442 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3443 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3444 else
3445 {
3446 print_vma (segment->p_offset, FULL_HEX);
3447 }
3448
3449 printf (" %c%c%c ",
3450 (segment->p_flags & PF_R ? 'R' : ' '),
3451 (segment->p_flags & PF_W ? 'W' : ' '),
3452 (segment->p_flags & PF_X ? 'E' : ' '));
3453
3454 if ((unsigned long) segment->p_align == segment->p_align)
3455 printf ("%#lx", (unsigned long) segment->p_align);
3456 else
3457 {
3458 print_vma (segment->p_align, PREFIX_HEX);
3459 }
3460 }
f7a99963
NC
3461 else
3462 {
3463 print_vma (segment->p_offset, FULL_HEX);
3464 putchar (' ');
3465 print_vma (segment->p_vaddr, FULL_HEX);
3466 putchar (' ');
3467 print_vma (segment->p_paddr, FULL_HEX);
3468 printf ("\n ");
3469 print_vma (segment->p_filesz, FULL_HEX);
3470 putchar (' ');
3471 print_vma (segment->p_memsz, FULL_HEX);
3472 printf (" %c%c%c ",
3473 (segment->p_flags & PF_R ? 'R' : ' '),
3474 (segment->p_flags & PF_W ? 'W' : ' '),
3475 (segment->p_flags & PF_X ? 'E' : ' '));
3476 print_vma (segment->p_align, HEX);
3477 }
252b5132
RH
3478 }
3479
3480 switch (segment->p_type)
3481 {
252b5132
RH
3482 case PT_DYNAMIC:
3483 if (dynamic_addr)
3484 error (_("more than one dynamic segment\n"));
3485
b2d38a17
NC
3486 /* Try to locate the .dynamic section. If there is
3487 a section header table, we can easily locate it. */
3488 if (section_headers != NULL)
3489 {
3490 Elf_Internal_Shdr *sec;
b2d38a17 3491
89fac5e3
RS
3492 sec = find_section (".dynamic");
3493 if (sec == NULL || sec->sh_size == 0)
b2d38a17
NC
3494 {
3495 error (_("no .dynamic section in the dynamic segment"));
3496 break;
3497 }
3498
3499 dynamic_addr = sec->sh_offset;
3500 dynamic_size = sec->sh_size;
3501
3502 if (dynamic_addr < segment->p_offset
3503 || dynamic_addr > segment->p_offset + segment->p_filesz)
3504 warn (_("the .dynamic section is not contained within the dynamic segment"));
3505 else if (dynamic_addr > segment->p_offset)
3506 warn (_("the .dynamic section is not the first section in the dynamic segment."));
3507 }
3508 else
3509 {
3510 /* Otherwise, we can only assume that the .dynamic
3511 section is the first section in the DYNAMIC segment. */
3512 dynamic_addr = segment->p_offset;
3513 dynamic_size = segment->p_filesz;
3514 }
252b5132
RH
3515 break;
3516
3517 case PT_INTERP:
fb52b2f4
NC
3518 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3519 SEEK_SET))
252b5132
RH
3520 error (_("Unable to find program interpreter name\n"));
3521 else
3522 {
f8eae8b2
L
3523 char fmt [32];
3524 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
3525
3526 if (ret >= (int) sizeof (fmt) || ret < 0)
3527 error (_("Internal error: failed to create format string to display program interpreter"));
3528
252b5132 3529 program_interpreter[0] = 0;
7bd7b3ef
AM
3530 if (fscanf (file, fmt, program_interpreter) <= 0)
3531 error (_("Unable to read program interpreter name\n"));
252b5132
RH
3532
3533 if (do_segments)
3534 printf (_("\n [Requesting program interpreter: %s]"),
3535 program_interpreter);
3536 }
3537 break;
3538 }
3539
3540 if (do_segments)
3541 putc ('\n', stdout);
3542 }
3543
c256ffe7 3544 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
3545 {
3546 printf (_("\n Section to Segment mapping:\n"));
3547 printf (_(" Segment Sections...\n"));
3548
252b5132
RH
3549 for (i = 0; i < elf_header.e_phnum; i++)
3550 {
9ad5cbcf 3551 unsigned int j;
b34976b6 3552 Elf_Internal_Shdr *section;
252b5132
RH
3553
3554 segment = program_headers + i;
3555 section = section_headers;
3556
3557 printf (" %2.2d ", i);
3558
b34976b6 3559 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 3560 {
84d1d650 3561 if (ELF_IS_SECTION_IN_SEGMENT_MEMORY(section, segment))
252b5132
RH
3562 printf ("%s ", SECTION_NAME (section));
3563 }
3564
3565 putc ('\n',stdout);
3566 }
3567 }
3568
252b5132
RH
3569 return 1;
3570}
3571
3572
d93f0186
NC
3573/* Find the file offset corresponding to VMA by using the program headers. */
3574
3575static long
d3ba0551 3576offset_from_vma (FILE *file, bfd_vma vma, bfd_size_type size)
d93f0186
NC
3577{
3578 Elf_Internal_Phdr *seg;
3579
3580 if (! get_program_headers (file))
3581 {
3582 warn (_("Cannot interpret virtual addresses without program headers.\n"));
3583 return (long) vma;
3584 }
3585
3586 for (seg = program_headers;
3587 seg < program_headers + elf_header.e_phnum;
3588 ++seg)
3589 {
3590 if (seg->p_type != PT_LOAD)
3591 continue;
3592
3593 if (vma >= (seg->p_vaddr & -seg->p_align)
3594 && vma + size <= seg->p_vaddr + seg->p_filesz)
3595 return vma - seg->p_vaddr + seg->p_offset;
3596 }
3597
3598 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
3599 (long) vma);
3600 return (long) vma;
3601}
3602
3603
252b5132 3604static int
d3ba0551 3605get_32bit_section_headers (FILE *file, unsigned int num)
252b5132 3606{
b34976b6
AM
3607 Elf32_External_Shdr *shdrs;
3608 Elf_Internal_Shdr *internal;
3609 unsigned int i;
252b5132 3610
d3ba0551 3611 shdrs = get_data (NULL, file, elf_header.e_shoff,
c256ffe7 3612 elf_header.e_shentsize, num, _("section headers"));
a6e9f9df
AM
3613 if (!shdrs)
3614 return 0;
252b5132 3615
c256ffe7 3616 section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
252b5132
RH
3617
3618 if (section_headers == NULL)
3619 {
3620 error (_("Out of memory\n"));
3621 return 0;
3622 }
3623
3624 for (i = 0, internal = section_headers;
560f3c1c 3625 i < num;
b34976b6 3626 i++, internal++)
252b5132
RH
3627 {
3628 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3629 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
3630 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3631 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3632 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3633 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3634 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3635 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3636 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3637 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
3638 }
3639
3640 free (shdrs);
3641
3642 return 1;
3643}
3644
9ea033b2 3645static int
d3ba0551 3646get_64bit_section_headers (FILE *file, unsigned int num)
9ea033b2 3647{
b34976b6
AM
3648 Elf64_External_Shdr *shdrs;
3649 Elf_Internal_Shdr *internal;
3650 unsigned int i;
9ea033b2 3651
d3ba0551 3652 shdrs = get_data (NULL, file, elf_header.e_shoff,
c256ffe7 3653 elf_header.e_shentsize, num, _("section headers"));
a6e9f9df
AM
3654 if (!shdrs)
3655 return 0;
9ea033b2 3656
c256ffe7 3657 section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
9ea033b2
NC
3658
3659 if (section_headers == NULL)
3660 {
3661 error (_("Out of memory\n"));
3662 return 0;
3663 }
3664
3665 for (i = 0, internal = section_headers;
560f3c1c 3666 i < num;
b34976b6 3667 i++, internal++)
9ea033b2
NC
3668 {
3669 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3670 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
3671 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3672 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3673 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3674 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
3675 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3676 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3677 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3678 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3679 }
3680
3681 free (shdrs);
3682
3683 return 1;
3684}
3685
252b5132 3686static Elf_Internal_Sym *
d3ba0551 3687get_32bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section)
252b5132 3688{
9ad5cbcf 3689 unsigned long number;
b34976b6 3690 Elf32_External_Sym *esyms;
9ad5cbcf 3691 Elf_External_Sym_Shndx *shndx;
b34976b6
AM
3692 Elf_Internal_Sym *isyms;
3693 Elf_Internal_Sym *psym;
3694 unsigned int j;
252b5132 3695
c256ffe7 3696 esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
d3ba0551 3697 _("symbols"));
a6e9f9df
AM
3698 if (!esyms)
3699 return NULL;
252b5132 3700
9ad5cbcf
AM
3701 shndx = NULL;
3702 if (symtab_shndx_hdr != NULL
3703 && (symtab_shndx_hdr->sh_link
3704 == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
3705 {
d3ba0551 3706 shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
c256ffe7 3707 1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
9ad5cbcf
AM
3708 if (!shndx)
3709 {
3710 free (esyms);
3711 return NULL;
3712 }
3713 }
3714
3715 number = section->sh_size / section->sh_entsize;
c256ffe7 3716 isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
3717
3718 if (isyms == NULL)
3719 {
3720 error (_("Out of memory\n"));
9ad5cbcf
AM
3721 if (shndx)
3722 free (shndx);
252b5132 3723 free (esyms);
252b5132
RH
3724 return NULL;
3725 }
3726
3727 for (j = 0, psym = isyms;
3728 j < number;
b34976b6 3729 j++, psym++)
252b5132
RH
3730 {
3731 psym->st_name = BYTE_GET (esyms[j].st_name);
3732 psym->st_value = BYTE_GET (esyms[j].st_value);
3733 psym->st_size = BYTE_GET (esyms[j].st_size);
3734 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
9ad5cbcf
AM
3735 if (psym->st_shndx == SHN_XINDEX && shndx != NULL)
3736 psym->st_shndx
3737 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
252b5132
RH
3738 psym->st_info = BYTE_GET (esyms[j].st_info);
3739 psym->st_other = BYTE_GET (esyms[j].st_other);
3740 }
3741
9ad5cbcf
AM
3742 if (shndx)
3743 free (shndx);
252b5132
RH
3744 free (esyms);
3745
3746 return isyms;
3747}
3748
9ea033b2 3749static Elf_Internal_Sym *
d3ba0551 3750get_64bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section)
9ea033b2 3751{
9ad5cbcf 3752 unsigned long number;
b34976b6 3753 Elf64_External_Sym *esyms;
9ad5cbcf 3754 Elf_External_Sym_Shndx *shndx;
b34976b6
AM
3755 Elf_Internal_Sym *isyms;
3756 Elf_Internal_Sym *psym;
3757 unsigned int j;
9ea033b2 3758
c256ffe7 3759 esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
d3ba0551 3760 _("symbols"));
a6e9f9df
AM
3761 if (!esyms)
3762 return NULL;
9ea033b2 3763
9ad5cbcf
AM
3764 shndx = NULL;
3765 if (symtab_shndx_hdr != NULL
3766 && (symtab_shndx_hdr->sh_link
3767 == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
3768 {
d3ba0551 3769 shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
c256ffe7 3770 1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
9ad5cbcf
AM
3771 if (!shndx)
3772 {
3773 free (esyms);
3774 return NULL;
3775 }
3776 }
3777
3778 number = section->sh_size / section->sh_entsize;
c256ffe7 3779 isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
3780
3781 if (isyms == NULL)
3782 {
3783 error (_("Out of memory\n"));
9ad5cbcf
AM
3784 if (shndx)
3785 free (shndx);
9ea033b2 3786 free (esyms);
9ea033b2
NC
3787 return NULL;
3788 }
3789
3790 for (j = 0, psym = isyms;
3791 j < number;
b34976b6 3792 j++, psym++)
9ea033b2
NC
3793 {
3794 psym->st_name = BYTE_GET (esyms[j].st_name);
3795 psym->st_info = BYTE_GET (esyms[j].st_info);
3796 psym->st_other = BYTE_GET (esyms[j].st_other);
3797 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
9ad5cbcf
AM
3798 if (psym->st_shndx == SHN_XINDEX && shndx != NULL)
3799 psym->st_shndx
3800 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
66543521
AM
3801 psym->st_value = BYTE_GET (esyms[j].st_value);
3802 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
3803 }
3804
9ad5cbcf
AM
3805 if (shndx)
3806 free (shndx);
9ea033b2
NC
3807 free (esyms);
3808
3809 return isyms;
3810}
3811
d1133906 3812static const char *
d3ba0551 3813get_elf_section_flags (bfd_vma sh_flags)
d1133906 3814{
5477e8a0 3815 static char buff[1024];
e9e44622 3816 char *p = buff;
8d5ff12c
L
3817 int field_size = is_32bit_elf ? 8 : 16;
3818 int index, size = sizeof (buff) - (field_size + 4 + 1);
3819 bfd_vma os_flags = 0;
3820 bfd_vma proc_flags = 0;
3821 bfd_vma unknown_flags = 0;
5477e8a0
L
3822 const struct
3823 {
3824 const char *str;
3825 int len;
3826 }
3827 flags [] =
3828 {
3829 { "WRITE", 5 },
3830 { "ALLOC", 5 },
3831 { "EXEC", 4 },
3832 { "MERGE", 5 },
3833 { "STRINGS", 7 },
3834 { "INFO LINK", 9 },
3835 { "LINK ORDER", 10 },
3836 { "OS NONCONF", 10 },
3837 { "GROUP", 5 },
3838 { "TLS", 3 }
3839 };
3840
3841 if (do_section_details)
3842 {
8d5ff12c
L
3843 sprintf (buff, "[%*.*lx]: ",
3844 field_size, field_size, (unsigned long) sh_flags);
3845 p += field_size + 4;
5477e8a0 3846 }
76da6bbe 3847
d1133906
NC
3848 while (sh_flags)
3849 {
3850 bfd_vma flag;
3851
3852 flag = sh_flags & - sh_flags;
3853 sh_flags &= ~ flag;
76da6bbe 3854
5477e8a0 3855 if (do_section_details)
d1133906 3856 {
5477e8a0
L
3857 switch (flag)
3858 {
3859 case SHF_WRITE: index = 0; break;
3860 case SHF_ALLOC: index = 1; break;
3861 case SHF_EXECINSTR: index = 2; break;
3862 case SHF_MERGE: index = 3; break;
3863 case SHF_STRINGS: index = 4; break;
3864 case SHF_INFO_LINK: index = 5; break;
3865 case SHF_LINK_ORDER: index = 6; break;
3866 case SHF_OS_NONCONFORMING: index = 7; break;
3867 case SHF_GROUP: index = 8; break;
3868 case SHF_TLS: index = 9; break;
76da6bbe 3869
5477e8a0
L
3870 default:
3871 index = -1;
3872 break;
3873 }
3874
5477e8a0
L
3875 if (index != -1)
3876 {
8d5ff12c
L
3877 if (p != buff + field_size + 4)
3878 {
3879 if (size < (10 + 2))
3880 abort ();
3881 size -= 2;
3882 *p++ = ',';
3883 *p++ = ' ';
3884 }
3885
5477e8a0
L
3886 size -= flags [index].len;
3887 p = stpcpy (p, flags [index].str);
3888 }
3b22753a 3889 else if (flag & SHF_MASKOS)
8d5ff12c 3890 os_flags |= flag;
d1133906 3891 else if (flag & SHF_MASKPROC)
8d5ff12c 3892 proc_flags |= flag;
d1133906 3893 else
8d5ff12c 3894 unknown_flags |= flag;
5477e8a0
L
3895 }
3896 else
3897 {
3898 switch (flag)
3899 {
3900 case SHF_WRITE: *p = 'W'; break;
3901 case SHF_ALLOC: *p = 'A'; break;
3902 case SHF_EXECINSTR: *p = 'X'; break;
3903 case SHF_MERGE: *p = 'M'; break;
3904 case SHF_STRINGS: *p = 'S'; break;
3905 case SHF_INFO_LINK: *p = 'I'; break;
3906 case SHF_LINK_ORDER: *p = 'L'; break;
3907 case SHF_OS_NONCONFORMING: *p = 'O'; break;
3908 case SHF_GROUP: *p = 'G'; break;
3909 case SHF_TLS: *p = 'T'; break;
3910
3911 default:
3912 if (elf_header.e_machine == EM_X86_64
3913 && flag == SHF_X86_64_LARGE)
3914 *p = 'l';
3915 else if (flag & SHF_MASKOS)
3916 {
3917 *p = 'o';
3918 sh_flags &= ~ SHF_MASKOS;
3919 }
3920 else if (flag & SHF_MASKPROC)
3921 {
3922 *p = 'p';
3923 sh_flags &= ~ SHF_MASKPROC;
3924 }
3925 else
3926 *p = 'x';
3927 break;
3928 }
3929 p++;
d1133906
NC
3930 }
3931 }
76da6bbe 3932
8d5ff12c
L
3933 if (do_section_details)
3934 {
3935 if (os_flags)
3936 {
3937 size -= 5 + field_size;
3938 if (p != buff + field_size + 4)
3939 {
3940 if (size < (2 + 1))
3941 abort ();
3942 size -= 2;
3943 *p++ = ',';
3944 *p++ = ' ';
3945 }
3946 sprintf (p, "OS (%*.*lx)", field_size, field_size,
3947 (unsigned long) os_flags);
3948 p += 5 + field_size;
3949 }
3950 if (proc_flags)
3951 {
3952 size -= 7 + field_size;
3953 if (p != buff + field_size + 4)
3954 {
3955 if (size < (2 + 1))
3956 abort ();
3957 size -= 2;
3958 *p++ = ',';
3959 *p++ = ' ';
3960 }
3961 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
3962 (unsigned long) proc_flags);
3963 p += 7 + field_size;
3964 }
3965 if (unknown_flags)
3966 {
3967 size -= 10 + field_size;
3968 if (p != buff + field_size + 4)
3969 {
3970 if (size < (2 + 1))
3971 abort ();
3972 size -= 2;
3973 *p++ = ',';
3974 *p++ = ' ';
3975 }
3976 sprintf (p, "UNKNOWN (%*.*lx)", field_size, field_size,
3977 (unsigned long) unknown_flags);
3978 p += 10 + field_size;
3979 }
3980 }
3981
e9e44622 3982 *p = '\0';
d1133906
NC
3983 return buff;
3984}
3985
252b5132 3986static int
d3ba0551 3987process_section_headers (FILE *file)
252b5132 3988{
b34976b6
AM
3989 Elf_Internal_Shdr *section;
3990 unsigned int i;
252b5132
RH
3991
3992 section_headers = NULL;
3993
3994 if (elf_header.e_shnum == 0)
3995 {
3996 if (do_sections)
3997 printf (_("\nThere are no sections in this file.\n"));
3998
3999 return 1;
4000 }
4001
4002 if (do_sections && !do_header)
9ea033b2 4003 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4004 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4005
9ea033b2
NC
4006 if (is_32bit_elf)
4007 {
560f3c1c 4008 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4009 return 0;
4010 }
560f3c1c 4011 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4012 return 0;
4013
4014 /* Read in the string table, so that we have names to display. */
0b49d371
NC
4015 if (elf_header.e_shstrndx != SHN_UNDEF
4016 && SECTION_HEADER_INDEX (elf_header.e_shstrndx) < elf_header.e_shnum)
252b5132 4017 {
c256ffe7 4018 section = SECTION_HEADER (elf_header.e_shstrndx);
d40ac9bd 4019
c256ffe7
JJ
4020 if (section->sh_size != 0)
4021 {
4022 string_table = get_data (NULL, file, section->sh_offset,
4023 1, section->sh_size, _("string table"));
0de14b54 4024
c256ffe7
JJ
4025 string_table_length = string_table != NULL ? section->sh_size : 0;
4026 }
252b5132
RH
4027 }
4028
4029 /* Scan the sections for the dynamic symbol table
e3c8793a 4030 and dynamic string table and debug sections. */
252b5132
RH
4031 dynamic_symbols = NULL;
4032 dynamic_strings = NULL;
4033 dynamic_syminfo = NULL;
f1ef08cb 4034 symtab_shndx_hdr = NULL;
103f02d3 4035
89fac5e3
RS
4036 eh_addr_size = is_32bit_elf ? 4 : 8;
4037 switch (elf_header.e_machine)
4038 {
4039 case EM_MIPS:
4040 case EM_MIPS_RS3_LE:
4041 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4042 FDE addresses. However, the ABI also has a semi-official ILP32
4043 variant for which the normal FDE address size rules apply.
4044
4045 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4046 section, where XX is the size of longs in bits. Unfortunately,
4047 earlier compilers provided no way of distinguishing ILP32 objects
4048 from LP64 objects, so if there's any doubt, we should assume that
4049 the official LP64 form is being used. */
4050 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4051 && find_section (".gcc_compiled_long32") == NULL)
4052 eh_addr_size = 8;
4053 break;
0f56a26a
DD
4054
4055 case EM_H8_300:
4056 case EM_H8_300H:
4057 switch (elf_header.e_flags & EF_H8_MACH)
4058 {
4059 case E_H8_MACH_H8300:
4060 case E_H8_MACH_H8300HN:
4061 case E_H8_MACH_H8300SN:
4062 case E_H8_MACH_H8300SXN:
4063 eh_addr_size = 2;
4064 break;
4065 case E_H8_MACH_H8300H:
4066 case E_H8_MACH_H8300S:
4067 case E_H8_MACH_H8300SX:
4068 eh_addr_size = 4;
4069 break;
4070 }
89fac5e3
RS
4071 }
4072
08d8fa11
JJ
4073#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4074 do \
4075 { \
4076 size_t expected_entsize \
4077 = is_32bit_elf ? size32 : size64; \
4078 if (section->sh_entsize != expected_entsize) \
4079 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4080 i, (unsigned long int) section->sh_entsize, \
4081 (unsigned long int) expected_entsize); \
4082 section->sh_entsize = expected_entsize; \
4083 } \
4084 while (0)
4085#define CHECK_ENTSIZE(section, i, type) \
4086 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4087 sizeof (Elf64_External_##type))
4088
252b5132
RH
4089 for (i = 0, section = section_headers;
4090 i < elf_header.e_shnum;
b34976b6 4091 i++, section++)
252b5132 4092 {
b34976b6 4093 char *name = SECTION_NAME (section);
252b5132
RH
4094
4095 if (section->sh_type == SHT_DYNSYM)
4096 {
4097 if (dynamic_symbols != NULL)
4098 {
4099 error (_("File contains multiple dynamic symbol tables\n"));
4100 continue;
4101 }
4102
08d8fa11 4103 CHECK_ENTSIZE (section, i, Sym);
19936277 4104 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 4105 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
4106 }
4107 else if (section->sh_type == SHT_STRTAB
18bd398b 4108 && streq (name, ".dynstr"))
252b5132
RH
4109 {
4110 if (dynamic_strings != NULL)
4111 {
4112 error (_("File contains multiple dynamic string tables\n"));
4113 continue;
4114 }
4115
d3ba0551 4116 dynamic_strings = get_data (NULL, file, section->sh_offset,
c256ffe7 4117 1, section->sh_size, _("dynamic strings"));
d79b3d50 4118 dynamic_strings_length = section->sh_size;
252b5132 4119 }
9ad5cbcf
AM
4120 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4121 {
4122 if (symtab_shndx_hdr != NULL)
4123 {
4124 error (_("File contains multiple symtab shndx tables\n"));
4125 continue;
4126 }
4127 symtab_shndx_hdr = section;
4128 }
08d8fa11
JJ
4129 else if (section->sh_type == SHT_SYMTAB)
4130 CHECK_ENTSIZE (section, i, Sym);
4131 else if (section->sh_type == SHT_GROUP)
4132 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4133 else if (section->sh_type == SHT_REL)
4134 CHECK_ENTSIZE (section, i, Rel);
4135 else if (section->sh_type == SHT_RELA)
4136 CHECK_ENTSIZE (section, i, Rela);
252b5132 4137 else if ((do_debugging || do_debug_info || do_debug_abbrevs
31b6fca6 4138 || do_debug_lines || do_debug_pubnames || do_debug_aranges
a2f14207 4139 || do_debug_frames || do_debug_macinfo || do_debug_str
18bd398b 4140 || do_debug_loc || do_debug_ranges)
0112cd26 4141 && const_strneq (name, ".debug_"))
252b5132
RH
4142 {
4143 name += 7;
4144
4145 if (do_debugging
18bd398b
NC
4146 || (do_debug_info && streq (name, "info"))
4147 || (do_debug_abbrevs && streq (name, "abbrev"))
4148 || (do_debug_lines && streq (name, "line"))
4149 || (do_debug_pubnames && streq (name, "pubnames"))
4150 || (do_debug_aranges && streq (name, "aranges"))
4151 || (do_debug_ranges && streq (name, "ranges"))
4152 || (do_debug_frames && streq (name, "frame"))
4153 || (do_debug_macinfo && streq (name, "macinfo"))
4154 || (do_debug_str && streq (name, "str"))
4155 || (do_debug_loc && streq (name, "loc"))
252b5132
RH
4156 )
4157 request_dump (i, DEBUG_DUMP);
4158 }
09fd7e38
JM
4159 /* linkonce section to be combined with .debug_info at link time. */
4160 else if ((do_debugging || do_debug_info)
0112cd26 4161 && const_strneq (name, ".gnu.linkonce.wi."))
09fd7e38 4162 request_dump (i, DEBUG_DUMP);
18bd398b 4163 else if (do_debug_frames && streq (name, ".eh_frame"))
c47d488e 4164 request_dump (i, DEBUG_DUMP);
252b5132
RH
4165 }
4166
4167 if (! do_sections)
4168 return 1;
4169
3a1a2036
NC
4170 if (elf_header.e_shnum > 1)
4171 printf (_("\nSection Headers:\n"));
4172 else
4173 printf (_("\nSection Header:\n"));
76da6bbe 4174
f7a99963 4175 if (is_32bit_elf)
595cf52e 4176 {
5477e8a0 4177 if (do_section_details)
595cf52e
L
4178 {
4179 printf (_(" [Nr] Name\n"));
5477e8a0 4180 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4181 }
4182 else
4183 printf
4184 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4185 }
d974e256 4186 else if (do_wide)
595cf52e 4187 {
5477e8a0 4188 if (do_section_details)
595cf52e
L
4189 {
4190 printf (_(" [Nr] Name\n"));
5477e8a0 4191 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4192 }
4193 else
4194 printf
4195 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4196 }
f7a99963
NC
4197 else
4198 {
5477e8a0 4199 if (do_section_details)
595cf52e
L
4200 {
4201 printf (_(" [Nr] Name\n"));
5477e8a0
L
4202 printf (_(" Type Address Offset Link\n"));
4203 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4204 }
4205 else
4206 {
4207 printf (_(" [Nr] Name Type Address Offset\n"));
4208 printf (_(" Size EntSize Flags Link Info Align\n"));
4209 }
f7a99963 4210 }
252b5132 4211
5477e8a0
L
4212 if (do_section_details)
4213 printf (_(" Flags\n"));
4214
252b5132
RH
4215 for (i = 0, section = section_headers;
4216 i < elf_header.e_shnum;
b34976b6 4217 i++, section++)
252b5132 4218 {
5477e8a0 4219 if (do_section_details)
595cf52e
L
4220 {
4221 printf (" [%2u] %s\n",
4222 SECTION_HEADER_NUM (i),
4223 SECTION_NAME (section));
4224 if (is_32bit_elf || do_wide)
4225 printf (" %-15.15s ",
4226 get_section_type_name (section->sh_type));
4227 }
4228 else
4229 printf (" [%2u] %-17.17s %-15.15s ",
4230 SECTION_HEADER_NUM (i),
4231 SECTION_NAME (section),
4232 get_section_type_name (section->sh_type));
252b5132 4233
f7a99963
NC
4234 if (is_32bit_elf)
4235 {
4236 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4237
f7a99963
NC
4238 printf ( " %6.6lx %6.6lx %2.2lx",
4239 (unsigned long) section->sh_offset,
4240 (unsigned long) section->sh_size,
4241 (unsigned long) section->sh_entsize);
d1133906 4242
5477e8a0
L
4243 if (do_section_details)
4244 fputs (" ", stdout);
4245 else
4246 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4247
f2da459f 4248 printf ("%2ld %3lu %2ld\n",
f7a99963
NC
4249 (unsigned long) section->sh_link,
4250 (unsigned long) section->sh_info,
4251 (unsigned long) section->sh_addralign);
4252 }
d974e256
JJ
4253 else if (do_wide)
4254 {
4255 print_vma (section->sh_addr, LONG_HEX);
4256
4257 if ((long) section->sh_offset == section->sh_offset)
4258 printf (" %6.6lx", (unsigned long) section->sh_offset);
4259 else
4260 {
4261 putchar (' ');
4262 print_vma (section->sh_offset, LONG_HEX);
4263 }
4264
4265 if ((unsigned long) section->sh_size == section->sh_size)
4266 printf (" %6.6lx", (unsigned long) section->sh_size);
4267 else
4268 {
4269 putchar (' ');
4270 print_vma (section->sh_size, LONG_HEX);
4271 }
4272
4273 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4274 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4275 else
4276 {
4277 putchar (' ');
4278 print_vma (section->sh_entsize, LONG_HEX);
4279 }
4280
5477e8a0
L
4281 if (do_section_details)
4282 fputs (" ", stdout);
4283 else
4284 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4285
f2da459f 4286 printf ("%2ld %3lu ",
d974e256
JJ
4287 (unsigned long) section->sh_link,
4288 (unsigned long) section->sh_info);
4289
4290 if ((unsigned long) section->sh_addralign == section->sh_addralign)
4291 printf ("%2ld\n", (unsigned long) section->sh_addralign);
4292 else
4293 {
4294 print_vma (section->sh_addralign, DEC);
4295 putchar ('\n');
4296 }
4297 }
5477e8a0 4298 else if (do_section_details)
595cf52e 4299 {
5477e8a0 4300 printf (" %-15.15s ",
595cf52e 4301 get_section_type_name (section->sh_type));
595cf52e
L
4302 print_vma (section->sh_addr, LONG_HEX);
4303 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4304 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4305 else
4306 {
4307 printf (" ");
4308 print_vma (section->sh_offset, LONG_HEX);
4309 }
5477e8a0 4310 printf (" %ld\n ", (unsigned long) section->sh_link);
595cf52e 4311 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4312 putchar (' ');
595cf52e
L
4313 print_vma (section->sh_entsize, LONG_HEX);
4314
5477e8a0 4315 printf (" %-16lu %ld\n",
595cf52e
L
4316 (unsigned long) section->sh_info,
4317 (unsigned long) section->sh_addralign);
4318 }
f7a99963
NC
4319 else
4320 {
4321 putchar (' ');
4322 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4323 if ((long) section->sh_offset == section->sh_offset)
4324 printf (" %8.8lx", (unsigned long) section->sh_offset);
4325 else
4326 {
4327 printf (" ");
4328 print_vma (section->sh_offset, LONG_HEX);
4329 }
f7a99963
NC
4330 printf ("\n ");
4331 print_vma (section->sh_size, LONG_HEX);
4332 printf (" ");
4333 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4334
d1133906 4335 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4336
f2da459f 4337 printf (" %2ld %3lu %ld\n",
f7a99963
NC
4338 (unsigned long) section->sh_link,
4339 (unsigned long) section->sh_info,
4340 (unsigned long) section->sh_addralign);
4341 }
5477e8a0
L
4342
4343 if (do_section_details)
4344 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4345 }
4346
5477e8a0
L
4347 if (!do_section_details)
4348 printf (_("Key to Flags:\n\
e3c8793a
NC
4349 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
4350 I (info), L (link order), G (group), x (unknown)\n\
4351 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
d1133906 4352
252b5132
RH
4353 return 1;
4354}
4355
f5842774
L
4356static const char *
4357get_group_flags (unsigned int flags)
4358{
4359 static char buff[32];
4360 switch (flags)
4361 {
4362 case GRP_COMDAT:
4363 return "COMDAT";
4364
4365 default:
e9e44622 4366 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x]"), flags);
f5842774
L
4367 break;
4368 }
4369 return buff;
4370}
4371
4372static int
4373process_section_groups (FILE *file)
4374{
4375 Elf_Internal_Shdr *section;
4376 unsigned int i;
e4b17d5c 4377 struct group *group;
d1f5c6e3
L
4378 Elf_Internal_Shdr *symtab_sec, *strtab_sec;
4379 Elf_Internal_Sym *symtab;
4380 char *strtab;
c256ffe7 4381 size_t strtab_size;
d1f5c6e3
L
4382
4383 /* Don't process section groups unless needed. */
4384 if (!do_unwind && !do_section_groups)
4385 return 1;
f5842774
L
4386
4387 if (elf_header.e_shnum == 0)
4388 {
4389 if (do_section_groups)
d1f5c6e3 4390 printf (_("\nThere are no sections in this file.\n"));
f5842774
L
4391
4392 return 1;
4393 }
4394
4395 if (section_headers == NULL)
4396 {
4397 error (_("Section headers are not available!\n"));
4398 abort ();
4399 }
4400
e4b17d5c
L
4401 section_headers_groups = calloc (elf_header.e_shnum,
4402 sizeof (struct group *));
4403
4404 if (section_headers_groups == NULL)
4405 {
4406 error (_("Out of memory\n"));
4407 return 0;
4408 }
4409
f5842774 4410 /* Scan the sections for the group section. */
d1f5c6e3 4411 group_count = 0;
f5842774
L
4412 for (i = 0, section = section_headers;
4413 i < elf_header.e_shnum;
4414 i++, section++)
e4b17d5c
L
4415 if (section->sh_type == SHT_GROUP)
4416 group_count++;
4417
d1f5c6e3
L
4418 if (group_count == 0)
4419 {
4420 if (do_section_groups)
4421 printf (_("\nThere are no section groups in this file.\n"));
4422
4423 return 1;
4424 }
4425
e4b17d5c
L
4426 section_groups = calloc (group_count, sizeof (struct group));
4427
4428 if (section_groups == NULL)
4429 {
4430 error (_("Out of memory\n"));
4431 return 0;
4432 }
4433
d1f5c6e3
L
4434 symtab_sec = NULL;
4435 strtab_sec = NULL;
4436 symtab = NULL;
4437 strtab = NULL;
c256ffe7 4438 strtab_size = 0;
e4b17d5c
L
4439 for (i = 0, section = section_headers, group = section_groups;
4440 i < elf_header.e_shnum;
4441 i++, section++)
f5842774
L
4442 {
4443 if (section->sh_type == SHT_GROUP)
4444 {
4445 char *name = SECTION_NAME (section);
dc3c06c2
AM
4446 char *group_name;
4447 unsigned char *start, *indices;
f5842774 4448 unsigned int entry, j, size;
d1f5c6e3 4449 Elf_Internal_Shdr *sec;
f5842774 4450 Elf_Internal_Sym *sym;
f5842774
L
4451
4452 /* Get the symbol table. */
c256ffe7
JJ
4453 if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum
4454 || ((sec = SECTION_HEADER (section->sh_link))->sh_type
4455 != SHT_SYMTAB))
f5842774
L
4456 {
4457 error (_("Bad sh_link in group section `%s'\n"), name);
4458 continue;
4459 }
d1f5c6e3
L
4460
4461 if (symtab_sec != sec)
4462 {
4463 symtab_sec = sec;
4464 if (symtab)
4465 free (symtab);
4466 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
4467 }
f5842774
L
4468
4469 sym = symtab + section->sh_info;
4470
4471 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4472 {
4473 bfd_vma sec_index = SECTION_HEADER_INDEX (sym->st_shndx);
4474 if (sec_index == 0)
4475 {
4476 error (_("Bad sh_info in group section `%s'\n"), name);
4477 continue;
4478 }
ba2685cc 4479
f5842774 4480 group_name = SECTION_NAME (section_headers + sec_index);
c256ffe7
JJ
4481 strtab_sec = NULL;
4482 if (strtab)
4483 free (strtab);
f5842774 4484 strtab = NULL;
c256ffe7 4485 strtab_size = 0;
f5842774
L
4486 }
4487 else
4488 {
4489 /* Get the string table. */
c256ffe7
JJ
4490 if (SECTION_HEADER_INDEX (symtab_sec->sh_link)
4491 >= elf_header.e_shnum)
4492 {
4493 strtab_sec = NULL;
4494 if (strtab)
4495 free (strtab);
4496 strtab = NULL;
4497 strtab_size = 0;
4498 }
4499 else if (strtab_sec
4500 != (sec = SECTION_HEADER (symtab_sec->sh_link)))
d1f5c6e3
L
4501 {
4502 strtab_sec = sec;
4503 if (strtab)
4504 free (strtab);
4505 strtab = get_data (NULL, file, strtab_sec->sh_offset,
c256ffe7 4506 1, strtab_sec->sh_size,
d1f5c6e3 4507 _("string table"));
c256ffe7 4508 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 4509 }
c256ffe7
JJ
4510 group_name = sym->st_name < strtab_size
4511 ? strtab + sym->st_name : "<corrupt>";
f5842774
L
4512 }
4513
4514 start = get_data (NULL, file, section->sh_offset,
c256ffe7 4515 1, section->sh_size, _("section data"));
f5842774
L
4516
4517 indices = start;
4518 size = (section->sh_size / section->sh_entsize) - 1;
4519 entry = byte_get (indices, 4);
4520 indices += 4;
e4b17d5c
L
4521
4522 if (do_section_groups)
4523 {
391cb864
L
4524 printf ("\n%s group section [%5u] `%s' [%s] contains %u sections:\n",
4525 get_group_flags (entry), i, name, group_name, size);
ba2685cc 4526
e4b17d5c
L
4527 printf (_(" [Index] Name\n"));
4528 }
4529
4530 group->group_index = i;
4531
f5842774
L
4532 for (j = 0; j < size; j++)
4533 {
e4b17d5c
L
4534 struct group_list *g;
4535
f5842774
L
4536 entry = byte_get (indices, 4);
4537 indices += 4;
4538
c256ffe7 4539 if (SECTION_HEADER_INDEX (entry) >= elf_header.e_shnum)
391cb864
L
4540 {
4541 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
4542 entry, i, elf_header.e_shnum - 1);
4543 continue;
4544 }
4545 else if (entry >= SHN_LORESERVE && entry <= SHN_HIRESERVE)
4546 {
4547 error (_("invalid section [%5u] in group section [%5u]\n"),
4548 entry, i);
4549 continue;
4550 }
4551
e4b17d5c
L
4552 if (section_headers_groups [SECTION_HEADER_INDEX (entry)]
4553 != NULL)
4554 {
d1f5c6e3
L
4555 if (entry)
4556 {
391cb864
L
4557 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
4558 entry, i,
d1f5c6e3
L
4559 section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
4560 continue;
4561 }
4562 else
4563 {
4564 /* Intel C/C++ compiler may put section 0 in a
4565 section group. We just warn it the first time
4566 and ignore it afterwards. */
4567 static int warned = 0;
4568 if (!warned)
4569 {
4570 error (_("section 0 in group section [%5u]\n"),
4571 section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
4572 warned++;
4573 }
4574 }
e4b17d5c
L
4575 }
4576
4577 section_headers_groups [SECTION_HEADER_INDEX (entry)]
4578 = group;
4579
4580 if (do_section_groups)
4581 {
4582 sec = SECTION_HEADER (entry);
c256ffe7 4583 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
4584 }
4585
e4b17d5c
L
4586 g = xmalloc (sizeof (struct group_list));
4587 g->section_index = entry;
4588 g->next = group->root;
4589 group->root = g;
f5842774
L
4590 }
4591
f5842774
L
4592 if (start)
4593 free (start);
e4b17d5c
L
4594
4595 group++;
f5842774
L
4596 }
4597 }
4598
d1f5c6e3
L
4599 if (symtab)
4600 free (symtab);
4601 if (strtab)
4602 free (strtab);
f5842774
L
4603 return 1;
4604}
4605
85b1c36d 4606static struct
566b0d53
L
4607{
4608 const char *name;
4609 int reloc;
4610 int size;
4611 int rela;
4612} dynamic_relocations [] =
4613{
4614 { "REL", DT_REL, DT_RELSZ, FALSE },
4615 { "RELA", DT_RELA, DT_RELASZ, TRUE },
4616 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
4617};
4618
252b5132 4619/* Process the reloc section. */
18bd398b 4620
252b5132 4621static int
d3ba0551 4622process_relocs (FILE *file)
252b5132 4623{
b34976b6
AM
4624 unsigned long rel_size;
4625 unsigned long rel_offset;
252b5132
RH
4626
4627
4628 if (!do_reloc)
4629 return 1;
4630
4631 if (do_using_dynamic)
4632 {
566b0d53
L
4633 int is_rela;
4634 const char *name;
4635 int has_dynamic_reloc;
4636 unsigned int i;
0de14b54 4637
566b0d53 4638 has_dynamic_reloc = 0;
252b5132 4639
566b0d53 4640 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 4641 {
566b0d53
L
4642 is_rela = dynamic_relocations [i].rela;
4643 name = dynamic_relocations [i].name;
4644 rel_size = dynamic_info [dynamic_relocations [i].size];
4645 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 4646
566b0d53
L
4647 has_dynamic_reloc |= rel_size;
4648
4649 if (is_rela == UNKNOWN)
aa903cfb 4650 {
566b0d53
L
4651 if (dynamic_relocations [i].reloc == DT_JMPREL)
4652 switch (dynamic_info[DT_PLTREL])
4653 {
4654 case DT_REL:
4655 is_rela = FALSE;
4656 break;
4657 case DT_RELA:
4658 is_rela = TRUE;
4659 break;
4660 }
aa903cfb 4661 }
252b5132 4662
566b0d53
L
4663 if (rel_size)
4664 {
4665 printf
4666 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
4667 name, rel_offset, rel_size);
252b5132 4668
d93f0186
NC
4669 dump_relocations (file,
4670 offset_from_vma (file, rel_offset, rel_size),
4671 rel_size,
566b0d53 4672 dynamic_symbols, num_dynamic_syms,
d79b3d50 4673 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 4674 }
252b5132 4675 }
566b0d53
L
4676
4677 if (! has_dynamic_reloc)
252b5132
RH
4678 printf (_("\nThere are no dynamic relocations in this file.\n"));
4679 }
4680 else
4681 {
b34976b6
AM
4682 Elf_Internal_Shdr *section;
4683 unsigned long i;
4684 int found = 0;
252b5132
RH
4685
4686 for (i = 0, section = section_headers;
4687 i < elf_header.e_shnum;
b34976b6 4688 i++, section++)
252b5132
RH
4689 {
4690 if ( section->sh_type != SHT_RELA
4691 && section->sh_type != SHT_REL)
4692 continue;
4693
4694 rel_offset = section->sh_offset;
4695 rel_size = section->sh_size;
4696
4697 if (rel_size)
4698 {
b34976b6 4699 Elf_Internal_Shdr *strsec;
b34976b6 4700 int is_rela;
103f02d3 4701
252b5132
RH
4702 printf (_("\nRelocation section "));
4703
4704 if (string_table == NULL)
19936277 4705 printf ("%d", section->sh_name);
252b5132 4706 else
3a1a2036 4707 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
4708
4709 printf (_(" at offset 0x%lx contains %lu entries:\n"),
4710 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
4711
d79b3d50
NC
4712 is_rela = section->sh_type == SHT_RELA;
4713
c256ffe7
JJ
4714 if (section->sh_link
4715 && SECTION_HEADER_INDEX (section->sh_link)
4716 < elf_header.e_shnum)
af3fc3bc 4717 {
b34976b6 4718 Elf_Internal_Shdr *symsec;
d79b3d50
NC
4719 Elf_Internal_Sym *symtab;
4720 unsigned long nsyms;
c256ffe7 4721 unsigned long strtablen = 0;
d79b3d50 4722 char *strtab = NULL;
57346661 4723
9ad5cbcf 4724 symsec = SECTION_HEADER (section->sh_link);
08d8fa11
JJ
4725 if (symsec->sh_type != SHT_SYMTAB
4726 && symsec->sh_type != SHT_DYNSYM)
4727 continue;
4728
af3fc3bc 4729 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 4730 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 4731
af3fc3bc
AM
4732 if (symtab == NULL)
4733 continue;
252b5132 4734
c256ffe7
JJ
4735 if (SECTION_HEADER_INDEX (symsec->sh_link)
4736 < elf_header.e_shnum)
4737 {
4738 strsec = SECTION_HEADER (symsec->sh_link);
103f02d3 4739
c256ffe7
JJ
4740 strtab = get_data (NULL, file, strsec->sh_offset,
4741 1, strsec->sh_size,
4742 _("string table"));
4743 strtablen = strtab == NULL ? 0 : strsec->sh_size;
4744 }
252b5132 4745
d79b3d50
NC
4746 dump_relocations (file, rel_offset, rel_size,
4747 symtab, nsyms, strtab, strtablen, is_rela);
4748 if (strtab)
4749 free (strtab);
4750 free (symtab);
4751 }
4752 else
4753 dump_relocations (file, rel_offset, rel_size,
4754 NULL, 0, NULL, 0, is_rela);
252b5132
RH
4755
4756 found = 1;
4757 }
4758 }
4759
4760 if (! found)
4761 printf (_("\nThere are no relocations in this file.\n"));
4762 }
4763
4764 return 1;
4765}
4766
57346661
AM
4767/* Process the unwind section. */
4768
4d6ed7c8
NC
4769#include "unwind-ia64.h"
4770
4771/* An absolute address consists of a section and an offset. If the
4772 section is NULL, the offset itself is the address, otherwise, the
4773 address equals to LOAD_ADDRESS(section) + offset. */
4774
4775struct absaddr
4776 {
4777 unsigned short section;
4778 bfd_vma offset;
4779 };
4780
1949de15
L
4781#define ABSADDR(a) \
4782 ((a).section \
4783 ? section_headers [(a).section].sh_addr + (a).offset \
4784 : (a).offset)
4785
57346661 4786struct ia64_unw_aux_info
4d6ed7c8 4787 {
57346661 4788 struct ia64_unw_table_entry
4d6ed7c8 4789 {
b34976b6
AM
4790 struct absaddr start;
4791 struct absaddr end;
4792 struct absaddr info;
4d6ed7c8 4793 }
b34976b6
AM
4794 *table; /* Unwind table. */
4795 unsigned long table_len; /* Length of unwind table. */
4796 unsigned char *info; /* Unwind info. */
4797 unsigned long info_size; /* Size of unwind info. */
4798 bfd_vma info_addr; /* starting address of unwind info. */
4799 bfd_vma seg_base; /* Starting address of segment. */
4800 Elf_Internal_Sym *symtab; /* The symbol table. */
4801 unsigned long nsyms; /* Number of symbols. */
4802 char *strtab; /* The string table. */
4803 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
4804 };
4805
4d6ed7c8 4806static void
57346661
AM
4807find_symbol_for_address (Elf_Internal_Sym *symtab,
4808 unsigned long nsyms,
4809 const char *strtab,
4810 unsigned long strtab_size,
d3ba0551
AM
4811 struct absaddr addr,
4812 const char **symname,
4813 bfd_vma *offset)
4d6ed7c8 4814{
d3ba0551 4815 bfd_vma dist = 0x100000;
4d6ed7c8
NC
4816 Elf_Internal_Sym *sym, *best = NULL;
4817 unsigned long i;
4818
57346661 4819 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8
NC
4820 {
4821 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
4822 && sym->st_name != 0
4823 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
4824 && addr.offset >= sym->st_value
4825 && addr.offset - sym->st_value < dist)
4826 {
4827 best = sym;
4828 dist = addr.offset - sym->st_value;
4829 if (!dist)
4830 break;
4831 }
4832 }
4833 if (best)
4834 {
57346661
AM
4835 *symname = (best->st_name >= strtab_size
4836 ? "<corrupt>" : strtab + best->st_name);
4d6ed7c8
NC
4837 *offset = dist;
4838 return;
4839 }
4840 *symname = NULL;
4841 *offset = addr.offset;
4842}
4843
4844static void
57346661 4845dump_ia64_unwind (struct ia64_unw_aux_info *aux)
4d6ed7c8 4846{
57346661 4847 struct ia64_unw_table_entry *tp;
4d6ed7c8 4848 int in_body;
7036c0e1 4849
4d6ed7c8
NC
4850 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
4851 {
4852 bfd_vma stamp;
4853 bfd_vma offset;
b34976b6
AM
4854 const unsigned char *dp;
4855 const unsigned char *head;
4856 const char *procname;
4d6ed7c8 4857
57346661
AM
4858 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
4859 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
4860
4861 fputs ("\n<", stdout);
4862
4863 if (procname)
4864 {
4865 fputs (procname, stdout);
4866
4867 if (offset)
4868 printf ("+%lx", (unsigned long) offset);
4869 }
4870
4871 fputs (">: [", stdout);
4872 print_vma (tp->start.offset, PREFIX_HEX);
4873 fputc ('-', stdout);
4874 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 4875 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
4876 (unsigned long) (tp->info.offset - aux->seg_base));
4877
1949de15 4878 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 4879 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 4880
86f55779 4881 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
4882 (unsigned) UNW_VER (stamp),
4883 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
4884 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
4885 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 4886 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
4887
4888 if (UNW_VER (stamp) != 1)
4889 {
4890 printf ("\tUnknown version.\n");
4891 continue;
4892 }
4893
4894 in_body = 0;
89fac5e3 4895 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
4896 dp = unw_decode (dp, in_body, & in_body);
4897 }
4898}
4899
4900static int
d3ba0551 4901slurp_ia64_unwind_table (FILE *file,
57346661 4902 struct ia64_unw_aux_info *aux,
d3ba0551 4903 Elf_Internal_Shdr *sec)
4d6ed7c8 4904{
89fac5e3 4905 unsigned long size, nrelas, i;
d93f0186 4906 Elf_Internal_Phdr *seg;
57346661 4907 struct ia64_unw_table_entry *tep;
c8286bd1 4908 Elf_Internal_Shdr *relsec;
4d6ed7c8
NC
4909 Elf_Internal_Rela *rela, *rp;
4910 unsigned char *table, *tp;
4911 Elf_Internal_Sym *sym;
4912 const char *relname;
4d6ed7c8 4913
4d6ed7c8
NC
4914 /* First, find the starting address of the segment that includes
4915 this section: */
4916
4917 if (elf_header.e_phnum)
4918 {
d93f0186 4919 if (! get_program_headers (file))
4d6ed7c8 4920 return 0;
4d6ed7c8 4921
d93f0186
NC
4922 for (seg = program_headers;
4923 seg < program_headers + elf_header.e_phnum;
4924 ++seg)
4d6ed7c8
NC
4925 {
4926 if (seg->p_type != PT_LOAD)
4927 continue;
4928
4929 if (sec->sh_addr >= seg->p_vaddr
4930 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
4931 {
4932 aux->seg_base = seg->p_vaddr;
4933 break;
4934 }
4935 }
4d6ed7c8
NC
4936 }
4937
4938 /* Second, build the unwind table from the contents of the unwind section: */
4939 size = sec->sh_size;
c256ffe7 4940 table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
a6e9f9df
AM
4941 if (!table)
4942 return 0;
4d6ed7c8 4943
c256ffe7 4944 aux->table = xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3
RS
4945 tep = aux->table;
4946 for (tp = table; tp < table + size; tp += 3 * eh_addr_size, ++tep)
4d6ed7c8
NC
4947 {
4948 tep->start.section = SHN_UNDEF;
4949 tep->end.section = SHN_UNDEF;
4950 tep->info.section = SHN_UNDEF;
4951 if (is_32bit_elf)
4952 {
4953 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
4954 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
4955 tep->info.offset = byte_get ((unsigned char *) tp + 8, 4);
4956 }
4957 else
4958 {
66543521
AM
4959 tep->start.offset = BYTE_GET ((unsigned char *) tp + 0);
4960 tep->end.offset = BYTE_GET ((unsigned char *) tp + 8);
4961 tep->info.offset = BYTE_GET ((unsigned char *) tp + 16);
4d6ed7c8
NC
4962 }
4963 tep->start.offset += aux->seg_base;
4964 tep->end.offset += aux->seg_base;
4965 tep->info.offset += aux->seg_base;
4966 }
4967 free (table);
4968
4969 /* Third, apply any relocations to the unwind table: */
4970
4971 for (relsec = section_headers;
4972 relsec < section_headers + elf_header.e_shnum;
4973 ++relsec)
4974 {
4975 if (relsec->sh_type != SHT_RELA
c256ffe7 4976 || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
9ad5cbcf 4977 || SECTION_HEADER (relsec->sh_info) != sec)
4d6ed7c8
NC
4978 continue;
4979
4980 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
4981 & rela, & nrelas))
4982 return 0;
4983
4984 for (rp = rela; rp < rela + nrelas; ++rp)
4985 {
4986 if (is_32bit_elf)
4987 {
4988 relname = elf_ia64_reloc_type (ELF32_R_TYPE (rp->r_info));
4989 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
4d6ed7c8
NC
4990 }
4991 else
4992 {
4993 relname = elf_ia64_reloc_type (ELF64_R_TYPE (rp->r_info));
4994 sym = aux->symtab + ELF64_R_SYM (rp->r_info);
4d6ed7c8
NC
4995 }
4996
0112cd26 4997 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 4998 {
e5fb9629 4999 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5000 continue;
5001 }
5002
89fac5e3 5003 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5004
89fac5e3 5005 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5006 {
5007 case 0:
5008 aux->table[i].start.section = sym->st_shndx;
1ffa9a18 5009 aux->table[i].start.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5010 break;
5011 case 1:
5012 aux->table[i].end.section = sym->st_shndx;
1ffa9a18 5013 aux->table[i].end.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5014 break;
5015 case 2:
5016 aux->table[i].info.section = sym->st_shndx;
1ffa9a18 5017 aux->table[i].info.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5018 break;
5019 default:
5020 break;
5021 }
5022 }
5023
5024 free (rela);
5025 }
5026
89fac5e3 5027 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5028 return 1;
5029}
5030
5031static int
57346661 5032ia64_process_unwind (FILE *file)
4d6ed7c8 5033{
c8286bd1 5034 Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
89fac5e3 5035 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5036 struct ia64_unw_aux_info aux;
f1467e33 5037
4d6ed7c8
NC
5038 memset (& aux, 0, sizeof (aux));
5039
4d6ed7c8
NC
5040 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5041 {
c256ffe7
JJ
5042 if (sec->sh_type == SHT_SYMTAB
5043 && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum)
4d6ed7c8
NC
5044 {
5045 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 5046 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 5047
9ad5cbcf 5048 strsec = SECTION_HEADER (sec->sh_link);
d3ba0551 5049 aux.strtab = get_data (NULL, file, strsec->sh_offset,
c256ffe7
JJ
5050 1, strsec->sh_size, _("string table"));
5051 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5052 }
5053 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5054 unwcount++;
5055 }
5056
5057 if (!unwcount)
5058 printf (_("\nThere are no unwind sections in this file.\n"));
5059
5060 while (unwcount-- > 0)
5061 {
5062 char *suffix;
5063 size_t len, len2;
5064
5065 for (i = unwstart, sec = section_headers + unwstart;
5066 i < elf_header.e_shnum; ++i, ++sec)
5067 if (sec->sh_type == SHT_IA_64_UNWIND)
5068 {
5069 unwsec = sec;
5070 break;
5071 }
5072
5073 unwstart = i + 1;
5074 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5075
e4b17d5c
L
5076 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5077 {
5078 /* We need to find which section group it is in. */
5079 struct group_list *g = section_headers_groups [i]->root;
5080
5081 for (; g != NULL; g = g->next)
5082 {
5083 sec = SECTION_HEADER (g->section_index);
18bd398b
NC
5084
5085 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5086 break;
e4b17d5c
L
5087 }
5088
5089 if (g == NULL)
5090 i = elf_header.e_shnum;
5091 }
18bd398b 5092 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5093 {
18bd398b 5094 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5095 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5096 suffix = SECTION_NAME (unwsec) + len;
5097 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5098 ++i, ++sec)
18bd398b
NC
5099 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5100 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5101 break;
5102 }
5103 else
5104 {
5105 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5106 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5107 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5108 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5109 suffix = "";
18bd398b 5110 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5111 suffix = SECTION_NAME (unwsec) + len;
5112 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5113 ++i, ++sec)
18bd398b
NC
5114 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5115 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5116 break;
5117 }
5118
5119 if (i == elf_header.e_shnum)
5120 {
5121 printf (_("\nCould not find unwind info section for "));
5122
5123 if (string_table == NULL)
5124 printf ("%d", unwsec->sh_name);
5125 else
3a1a2036 5126 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5127 }
5128 else
4d6ed7c8
NC
5129 {
5130 aux.info_size = sec->sh_size;
5131 aux.info_addr = sec->sh_addr;
c256ffe7 5132 aux.info = get_data (NULL, file, sec->sh_offset, 1, aux.info_size,
d3ba0551 5133 _("unwind info"));
4d6ed7c8 5134
579f31ac 5135 printf (_("\nUnwind section "));
4d6ed7c8 5136
579f31ac
JJ
5137 if (string_table == NULL)
5138 printf ("%d", unwsec->sh_name);
5139 else
3a1a2036 5140 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5141
579f31ac 5142 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5143 (unsigned long) unwsec->sh_offset,
89fac5e3 5144 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5145
579f31ac 5146 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5147
579f31ac
JJ
5148 if (aux.table_len > 0)
5149 dump_ia64_unwind (& aux);
5150
5151 if (aux.table)
5152 free ((char *) aux.table);
5153 if (aux.info)
5154 free ((char *) aux.info);
5155 aux.table = NULL;
5156 aux.info = NULL;
5157 }
4d6ed7c8 5158 }
4d6ed7c8 5159
4d6ed7c8
NC
5160 if (aux.symtab)
5161 free (aux.symtab);
5162 if (aux.strtab)
5163 free ((char *) aux.strtab);
5164
5165 return 1;
5166}
5167
57346661
AM
5168struct hppa_unw_aux_info
5169 {
5170 struct hppa_unw_table_entry
5171 {
5172 struct absaddr start;
5173 struct absaddr end;
5174 unsigned int Cannot_unwind:1; /* 0 */
5175 unsigned int Millicode:1; /* 1 */
5176 unsigned int Millicode_save_sr0:1; /* 2 */
5177 unsigned int Region_description:2; /* 3..4 */
5178 unsigned int reserved1:1; /* 5 */
5179 unsigned int Entry_SR:1; /* 6 */
5180 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
5181 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
5182 unsigned int Args_stored:1; /* 16 */
5183 unsigned int Variable_Frame:1; /* 17 */
5184 unsigned int Separate_Package_Body:1; /* 18 */
5185 unsigned int Frame_Extension_Millicode:1; /* 19 */
5186 unsigned int Stack_Overflow_Check:1; /* 20 */
5187 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
5188 unsigned int Ada_Region:1; /* 22 */
5189 unsigned int cxx_info:1; /* 23 */
5190 unsigned int cxx_try_catch:1; /* 24 */
5191 unsigned int sched_entry_seq:1; /* 25 */
5192 unsigned int reserved2:1; /* 26 */
5193 unsigned int Save_SP:1; /* 27 */
5194 unsigned int Save_RP:1; /* 28 */
5195 unsigned int Save_MRP_in_frame:1; /* 29 */
5196 unsigned int extn_ptr_defined:1; /* 30 */
5197 unsigned int Cleanup_defined:1; /* 31 */
5198
5199 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5200 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5201 unsigned int Large_frame:1; /* 2 */
5202 unsigned int Pseudo_SP_Set:1; /* 3 */
5203 unsigned int reserved4:1; /* 4 */
5204 unsigned int Total_frame_size:27; /* 5..31 */
5205 }
5206 *table; /* Unwind table. */
5207 unsigned long table_len; /* Length of unwind table. */
5208 bfd_vma seg_base; /* Starting address of segment. */
5209 Elf_Internal_Sym *symtab; /* The symbol table. */
5210 unsigned long nsyms; /* Number of symbols. */
5211 char *strtab; /* The string table. */
5212 unsigned long strtab_size; /* Size of string table. */
5213 };
5214
5215static void
5216dump_hppa_unwind (struct hppa_unw_aux_info *aux)
5217{
57346661
AM
5218 struct hppa_unw_table_entry *tp;
5219
57346661
AM
5220 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5221 {
5222 bfd_vma offset;
5223 const char *procname;
5224
5225 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5226 aux->strtab_size, tp->start, &procname,
5227 &offset);
5228
5229 fputs ("\n<", stdout);
5230
5231 if (procname)
5232 {
5233 fputs (procname, stdout);
5234
5235 if (offset)
5236 printf ("+%lx", (unsigned long) offset);
5237 }
5238
5239 fputs (">: [", stdout);
5240 print_vma (tp->start.offset, PREFIX_HEX);
5241 fputc ('-', stdout);
5242 print_vma (tp->end.offset, PREFIX_HEX);
5243 printf ("]\n\t");
5244
18bd398b
NC
5245#define PF(_m) if (tp->_m) printf (#_m " ");
5246#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5247 PF(Cannot_unwind);
5248 PF(Millicode);
5249 PF(Millicode_save_sr0);
18bd398b 5250 /* PV(Region_description); */
57346661
AM
5251 PF(Entry_SR);
5252 PV(Entry_FR);
5253 PV(Entry_GR);
5254 PF(Args_stored);
5255 PF(Variable_Frame);
5256 PF(Separate_Package_Body);
5257 PF(Frame_Extension_Millicode);
5258 PF(Stack_Overflow_Check);
5259 PF(Two_Instruction_SP_Increment);
5260 PF(Ada_Region);
5261 PF(cxx_info);
5262 PF(cxx_try_catch);
5263 PF(sched_entry_seq);
5264 PF(Save_SP);
5265 PF(Save_RP);
5266 PF(Save_MRP_in_frame);
5267 PF(extn_ptr_defined);
5268 PF(Cleanup_defined);
5269 PF(MPE_XL_interrupt_marker);
5270 PF(HP_UX_interrupt_marker);
5271 PF(Large_frame);
5272 PF(Pseudo_SP_Set);
5273 PV(Total_frame_size);
5274#undef PF
5275#undef PV
5276 }
5277
18bd398b 5278 printf ("\n");
57346661
AM
5279}
5280
5281static int
5282slurp_hppa_unwind_table (FILE *file,
5283 struct hppa_unw_aux_info *aux,
5284 Elf_Internal_Shdr *sec)
5285{
1c0751b2 5286 unsigned long size, unw_ent_size, nentries, nrelas, i;
57346661
AM
5287 Elf_Internal_Phdr *seg;
5288 struct hppa_unw_table_entry *tep;
5289 Elf_Internal_Shdr *relsec;
5290 Elf_Internal_Rela *rela, *rp;
5291 unsigned char *table, *tp;
5292 Elf_Internal_Sym *sym;
5293 const char *relname;
5294
57346661
AM
5295 /* First, find the starting address of the segment that includes
5296 this section. */
5297
5298 if (elf_header.e_phnum)
5299 {
5300 if (! get_program_headers (file))
5301 return 0;
5302
5303 for (seg = program_headers;
5304 seg < program_headers + elf_header.e_phnum;
5305 ++seg)
5306 {
5307 if (seg->p_type != PT_LOAD)
5308 continue;
5309
5310 if (sec->sh_addr >= seg->p_vaddr
5311 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5312 {
5313 aux->seg_base = seg->p_vaddr;
5314 break;
5315 }
5316 }
5317 }
5318
5319 /* Second, build the unwind table from the contents of the unwind
5320 section. */
5321 size = sec->sh_size;
c256ffe7 5322 table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
57346661
AM
5323 if (!table)
5324 return 0;
5325
1c0751b2
DA
5326 unw_ent_size = 16;
5327 nentries = size / unw_ent_size;
5328 size = unw_ent_size * nentries;
57346661 5329
1c0751b2 5330 tep = aux->table = xcmalloc (nentries, sizeof (aux->table[0]));
57346661 5331
1c0751b2 5332 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
5333 {
5334 unsigned int tmp1, tmp2;
5335
5336 tep->start.section = SHN_UNDEF;
5337 tep->end.section = SHN_UNDEF;
5338
1c0751b2
DA
5339 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
5340 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
5341 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
5342 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
5343
5344 tep->start.offset += aux->seg_base;
5345 tep->end.offset += aux->seg_base;
57346661
AM
5346
5347 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
5348 tep->Millicode = (tmp1 >> 30) & 0x1;
5349 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
5350 tep->Region_description = (tmp1 >> 27) & 0x3;
5351 tep->reserved1 = (tmp1 >> 26) & 0x1;
5352 tep->Entry_SR = (tmp1 >> 25) & 0x1;
5353 tep->Entry_FR = (tmp1 >> 21) & 0xf;
5354 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
5355 tep->Args_stored = (tmp1 >> 15) & 0x1;
5356 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
5357 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
5358 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
5359 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
5360 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
5361 tep->Ada_Region = (tmp1 >> 9) & 0x1;
5362 tep->cxx_info = (tmp1 >> 8) & 0x1;
5363 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
5364 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
5365 tep->reserved2 = (tmp1 >> 5) & 0x1;
5366 tep->Save_SP = (tmp1 >> 4) & 0x1;
5367 tep->Save_RP = (tmp1 >> 3) & 0x1;
5368 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
5369 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
5370 tep->Cleanup_defined = tmp1 & 0x1;
5371
5372 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
5373 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
5374 tep->Large_frame = (tmp2 >> 29) & 0x1;
5375 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
5376 tep->reserved4 = (tmp2 >> 27) & 0x1;
5377 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
5378 }
5379 free (table);
5380
5381 /* Third, apply any relocations to the unwind table. */
5382
5383 for (relsec = section_headers;
5384 relsec < section_headers + elf_header.e_shnum;
5385 ++relsec)
5386 {
5387 if (relsec->sh_type != SHT_RELA
c256ffe7 5388 || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
57346661
AM
5389 || SECTION_HEADER (relsec->sh_info) != sec)
5390 continue;
5391
5392 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5393 & rela, & nrelas))
5394 return 0;
5395
5396 for (rp = rela; rp < rela + nrelas; ++rp)
5397 {
5398 if (is_32bit_elf)
5399 {
5400 relname = elf_hppa_reloc_type (ELF32_R_TYPE (rp->r_info));
5401 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
5402 }
5403 else
5404 {
5405 relname = elf_hppa_reloc_type (ELF64_R_TYPE (rp->r_info));
5406 sym = aux->symtab + ELF64_R_SYM (rp->r_info);
5407 }
5408
5409 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 5410 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
5411 {
5412 warn (_("Skipping unexpected relocation type %s\n"), relname);
5413 continue;
5414 }
5415
5416 i = rp->r_offset / unw_ent_size;
5417
89fac5e3 5418 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
5419 {
5420 case 0:
5421 aux->table[i].start.section = sym->st_shndx;
5422 aux->table[i].start.offset += sym->st_value + rp->r_addend;
5423 break;
5424 case 1:
5425 aux->table[i].end.section = sym->st_shndx;
5426 aux->table[i].end.offset += sym->st_value + rp->r_addend;
5427 break;
5428 default:
5429 break;
5430 }
5431 }
5432
5433 free (rela);
5434 }
5435
1c0751b2 5436 aux->table_len = nentries;
57346661
AM
5437
5438 return 1;
5439}
5440
5441static int
5442hppa_process_unwind (FILE *file)
5443{
57346661 5444 struct hppa_unw_aux_info aux;
18bd398b
NC
5445 Elf_Internal_Shdr *unwsec = NULL;
5446 Elf_Internal_Shdr *strsec;
5447 Elf_Internal_Shdr *sec;
18bd398b 5448 unsigned long i;
57346661
AM
5449
5450 memset (& aux, 0, sizeof (aux));
5451
c256ffe7
JJ
5452 if (string_table == NULL)
5453 return 1;
57346661
AM
5454
5455 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5456 {
c256ffe7
JJ
5457 if (sec->sh_type == SHT_SYMTAB
5458 && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum)
57346661
AM
5459 {
5460 aux.nsyms = sec->sh_size / sec->sh_entsize;
5461 aux.symtab = GET_ELF_SYMBOLS (file, sec);
5462
5463 strsec = SECTION_HEADER (sec->sh_link);
57346661 5464 aux.strtab = get_data (NULL, file, strsec->sh_offset,
c256ffe7
JJ
5465 1, strsec->sh_size, _("string table"));
5466 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 5467 }
18bd398b 5468 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
5469 unwsec = sec;
5470 }
5471
5472 if (!unwsec)
5473 printf (_("\nThere are no unwind sections in this file.\n"));
5474
5475 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5476 {
18bd398b 5477 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 5478 {
57346661
AM
5479 printf (_("\nUnwind section "));
5480 printf (_("'%s'"), SECTION_NAME (sec));
5481
5482 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5483 (unsigned long) sec->sh_offset,
89fac5e3 5484 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
5485
5486 slurp_hppa_unwind_table (file, &aux, sec);
5487 if (aux.table_len > 0)
5488 dump_hppa_unwind (&aux);
5489
5490 if (aux.table)
5491 free ((char *) aux.table);
5492 aux.table = NULL;
5493 }
5494 }
5495
5496 if (aux.symtab)
5497 free (aux.symtab);
5498 if (aux.strtab)
5499 free ((char *) aux.strtab);
5500
5501 return 1;
5502}
5503
5504static int
5505process_unwind (FILE *file)
5506{
5507 struct unwind_handler {
5508 int machtype;
5509 int (*handler)(FILE *file);
5510 } handlers[] = {
5511 { EM_IA_64, ia64_process_unwind },
5512 { EM_PARISC, hppa_process_unwind },
5513 { 0, 0 }
5514 };
5515 int i;
5516
5517 if (!do_unwind)
5518 return 1;
5519
5520 for (i = 0; handlers[i].handler != NULL; i++)
5521 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 5522 return handlers[i].handler (file);
57346661
AM
5523
5524 printf (_("\nThere are no unwind sections in this file.\n"));
5525 return 1;
5526}
5527
252b5132 5528static void
b2d38a17 5529dynamic_section_mips_val (Elf_Internal_Dyn *entry)
252b5132
RH
5530{
5531 switch (entry->d_tag)
5532 {
5533 case DT_MIPS_FLAGS:
5534 if (entry->d_un.d_val == 0)
5535 printf ("NONE\n");
5536 else
5537 {
5538 static const char * opts[] =
5539 {
5540 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
5541 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
5542 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
5543 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
5544 "RLD_ORDER_SAFE"
5545 };
5546 unsigned int cnt;
5547 int first = 1;
b34976b6 5548 for (cnt = 0; cnt < NUM_ELEM (opts); ++cnt)
252b5132
RH
5549 if (entry->d_un.d_val & (1 << cnt))
5550 {
5551 printf ("%s%s", first ? "" : " ", opts[cnt]);
5552 first = 0;
5553 }
5554 puts ("");
5555 }
5556 break;
103f02d3 5557
252b5132 5558 case DT_MIPS_IVERSION:
d79b3d50
NC
5559 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
5560 printf ("Interface Version: %s\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 5561 else
d79b3d50 5562 printf ("<corrupt: %ld>\n", (long) entry->d_un.d_ptr);
252b5132 5563 break;
103f02d3 5564
252b5132
RH
5565 case DT_MIPS_TIME_STAMP:
5566 {
5567 char timebuf[20];
b34976b6 5568 struct tm *tmp;
50da7a9c 5569
252b5132 5570 time_t time = entry->d_un.d_val;
50da7a9c 5571 tmp = gmtime (&time);
e9e44622
JJ
5572 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
5573 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
5574 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
5575 printf ("Time Stamp: %s\n", timebuf);
5576 }
5577 break;
103f02d3 5578
252b5132
RH
5579 case DT_MIPS_RLD_VERSION:
5580 case DT_MIPS_LOCAL_GOTNO:
5581 case DT_MIPS_CONFLICTNO:
5582 case DT_MIPS_LIBLISTNO:
5583 case DT_MIPS_SYMTABNO:
5584 case DT_MIPS_UNREFEXTNO:
5585 case DT_MIPS_HIPAGENO:
5586 case DT_MIPS_DELTA_CLASS_NO:
5587 case DT_MIPS_DELTA_INSTANCE_NO:
5588 case DT_MIPS_DELTA_RELOC_NO:
5589 case DT_MIPS_DELTA_SYM_NO:
5590 case DT_MIPS_DELTA_CLASSSYM_NO:
5591 case DT_MIPS_COMPACT_SIZE:
5592 printf ("%ld\n", (long) entry->d_un.d_ptr);
5593 break;
103f02d3
UD
5594
5595 default:
5596 printf ("%#lx\n", (long) entry->d_un.d_ptr);
5597 }
5598}
5599
5600
5601static void
b2d38a17 5602dynamic_section_parisc_val (Elf_Internal_Dyn *entry)
103f02d3
UD
5603{
5604 switch (entry->d_tag)
5605 {
5606 case DT_HP_DLD_FLAGS:
5607 {
5608 static struct
5609 {
5610 long int bit;
b34976b6 5611 const char *str;
5e220199
NC
5612 }
5613 flags[] =
5614 {
5615 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
5616 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
5617 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
5618 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
5619 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
5620 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
5621 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
5622 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
5623 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
5624 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
5625 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
5626 { DT_HP_GST, "HP_GST" },
5627 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
5628 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
5629 { DT_HP_NODELETE, "HP_NODELETE" },
5630 { DT_HP_GROUP, "HP_GROUP" },
5631 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 5632 };
103f02d3 5633 int first = 1;
5e220199 5634 size_t cnt;
f7a99963 5635 bfd_vma val = entry->d_un.d_val;
103f02d3
UD
5636
5637 for (cnt = 0; cnt < sizeof (flags) / sizeof (flags[0]); ++cnt)
5638 if (val & flags[cnt].bit)
30800947
NC
5639 {
5640 if (! first)
5641 putchar (' ');
5642 fputs (flags[cnt].str, stdout);
5643 first = 0;
5644 val ^= flags[cnt].bit;
5645 }
76da6bbe 5646
103f02d3 5647 if (val != 0 || first)
f7a99963
NC
5648 {
5649 if (! first)
5650 putchar (' ');
5651 print_vma (val, HEX);
5652 }
103f02d3
UD
5653 }
5654 break;
76da6bbe 5655
252b5132 5656 default:
f7a99963
NC
5657 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5658 break;
252b5132 5659 }
35b1837e 5660 putchar ('\n');
252b5132
RH
5661}
5662
ecc51f48 5663static void
b2d38a17 5664dynamic_section_ia64_val (Elf_Internal_Dyn *entry)
ecc51f48
NC
5665{
5666 switch (entry->d_tag)
5667 {
0de14b54 5668 case DT_IA_64_PLT_RESERVE:
bdf4d63a 5669 /* First 3 slots reserved. */
ecc51f48
NC
5670 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5671 printf (" -- ");
5672 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
5673 break;
5674
5675 default:
5676 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5677 break;
ecc51f48 5678 }
bdf4d63a 5679 putchar ('\n');
ecc51f48
NC
5680}
5681
252b5132 5682static int
b2d38a17 5683get_32bit_dynamic_section (FILE *file)
252b5132 5684{
fb514b26 5685 Elf32_External_Dyn *edyn, *ext;
b34976b6 5686 Elf_Internal_Dyn *entry;
103f02d3 5687
c256ffe7 5688 edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
b2d38a17 5689 _("dynamic section"));
a6e9f9df
AM
5690 if (!edyn)
5691 return 0;
103f02d3 5692
ba2685cc
AM
5693/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5694 might not have the luxury of section headers. Look for the DT_NULL
5695 terminator to determine the number of entries. */
5696 for (ext = edyn, dynamic_nent = 0;
5697 (char *) ext < (char *) edyn + dynamic_size;
5698 ext++)
5699 {
5700 dynamic_nent++;
5701 if (BYTE_GET (ext->d_tag) == DT_NULL)
5702 break;
5703 }
252b5132 5704
c256ffe7 5705 dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
b2d38a17 5706 if (dynamic_section == NULL)
252b5132 5707 {
9ea033b2
NC
5708 error (_("Out of memory\n"));
5709 free (edyn);
5710 return 0;
5711 }
252b5132 5712
fb514b26 5713 for (ext = edyn, entry = dynamic_section;
ba2685cc 5714 entry < dynamic_section + dynamic_nent;
fb514b26 5715 ext++, entry++)
9ea033b2 5716 {
fb514b26
AM
5717 entry->d_tag = BYTE_GET (ext->d_tag);
5718 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
5719 }
5720
9ea033b2
NC
5721 free (edyn);
5722
5723 return 1;
5724}
5725
5726static int
b2d38a17 5727get_64bit_dynamic_section (FILE *file)
9ea033b2 5728{
fb514b26 5729 Elf64_External_Dyn *edyn, *ext;
b34976b6 5730 Elf_Internal_Dyn *entry;
103f02d3 5731
c256ffe7 5732 edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
b2d38a17 5733 _("dynamic section"));
a6e9f9df
AM
5734 if (!edyn)
5735 return 0;
103f02d3 5736
ba2685cc
AM
5737/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5738 might not have the luxury of section headers. Look for the DT_NULL
5739 terminator to determine the number of entries. */
5740 for (ext = edyn, dynamic_nent = 0;
5741 (char *) ext < (char *) edyn + dynamic_size;
5742 ext++)
5743 {
5744 dynamic_nent++;
66543521 5745 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
5746 break;
5747 }
252b5132 5748
c256ffe7 5749 dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
b2d38a17 5750 if (dynamic_section == NULL)
252b5132
RH
5751 {
5752 error (_("Out of memory\n"));
5753 free (edyn);
5754 return 0;
5755 }
5756
fb514b26 5757 for (ext = edyn, entry = dynamic_section;
ba2685cc 5758 entry < dynamic_section + dynamic_nent;
fb514b26 5759 ext++, entry++)
252b5132 5760 {
66543521
AM
5761 entry->d_tag = BYTE_GET (ext->d_tag);
5762 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
5763 }
5764
5765 free (edyn);
5766
9ea033b2
NC
5767 return 1;
5768}
5769
e9e44622
JJ
5770static void
5771print_dynamic_flags (bfd_vma flags)
d1133906 5772{
e9e44622 5773 int first = 1;
13ae64f3 5774
d1133906
NC
5775 while (flags)
5776 {
5777 bfd_vma flag;
5778
5779 flag = flags & - flags;
5780 flags &= ~ flag;
5781
e9e44622
JJ
5782 if (first)
5783 first = 0;
5784 else
5785 putc (' ', stdout);
13ae64f3 5786
d1133906
NC
5787 switch (flag)
5788 {
e9e44622
JJ
5789 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
5790 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
5791 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
5792 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
5793 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
5794 default: fputs ("unknown", stdout); break;
d1133906
NC
5795 }
5796 }
e9e44622 5797 puts ("");
d1133906
NC
5798}
5799
b2d38a17
NC
5800/* Parse and display the contents of the dynamic section. */
5801
9ea033b2 5802static int
b2d38a17 5803process_dynamic_section (FILE *file)
9ea033b2 5804{
b34976b6 5805 Elf_Internal_Dyn *entry;
9ea033b2
NC
5806
5807 if (dynamic_size == 0)
5808 {
5809 if (do_dynamic)
b2d38a17 5810 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
5811
5812 return 1;
5813 }
5814
5815 if (is_32bit_elf)
5816 {
b2d38a17 5817 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
5818 return 0;
5819 }
b2d38a17 5820 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
5821 return 0;
5822
252b5132
RH
5823 /* Find the appropriate symbol table. */
5824 if (dynamic_symbols == NULL)
5825 {
86dba8ee
AM
5826 for (entry = dynamic_section;
5827 entry < dynamic_section + dynamic_nent;
5828 ++entry)
252b5132 5829 {
c8286bd1 5830 Elf_Internal_Shdr section;
252b5132
RH
5831
5832 if (entry->d_tag != DT_SYMTAB)
5833 continue;
5834
5835 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
5836
5837 /* Since we do not know how big the symbol table is,
5838 we default to reading in the entire file (!) and
5839 processing that. This is overkill, I know, but it
e3c8793a 5840 should work. */
d93f0186 5841 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 5842
fb52b2f4
NC
5843 if (archive_file_offset != 0)
5844 section.sh_size = archive_file_size - section.sh_offset;
5845 else
5846 {
5847 if (fseek (file, 0, SEEK_END))
5848 error (_("Unable to seek to end of file!"));
5849
5850 section.sh_size = ftell (file) - section.sh_offset;
5851 }
252b5132 5852
9ea033b2 5853 if (is_32bit_elf)
9ad5cbcf 5854 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 5855 else
9ad5cbcf 5856 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 5857
9ad5cbcf 5858 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 5859 if (num_dynamic_syms < 1)
252b5132
RH
5860 {
5861 error (_("Unable to determine the number of symbols to load\n"));
5862 continue;
5863 }
5864
9ad5cbcf 5865 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
5866 }
5867 }
5868
5869 /* Similarly find a string table. */
5870 if (dynamic_strings == NULL)
5871 {
86dba8ee
AM
5872 for (entry = dynamic_section;
5873 entry < dynamic_section + dynamic_nent;
5874 ++entry)
252b5132
RH
5875 {
5876 unsigned long offset;
b34976b6 5877 long str_tab_len;
252b5132
RH
5878
5879 if (entry->d_tag != DT_STRTAB)
5880 continue;
5881
5882 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
5883
5884 /* Since we do not know how big the string table is,
5885 we default to reading in the entire file (!) and
5886 processing that. This is overkill, I know, but it
e3c8793a 5887 should work. */
252b5132 5888
d93f0186 5889 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
5890
5891 if (archive_file_offset != 0)
5892 str_tab_len = archive_file_size - offset;
5893 else
5894 {
5895 if (fseek (file, 0, SEEK_END))
5896 error (_("Unable to seek to end of file\n"));
5897 str_tab_len = ftell (file) - offset;
5898 }
252b5132
RH
5899
5900 if (str_tab_len < 1)
5901 {
5902 error
5903 (_("Unable to determine the length of the dynamic string table\n"));
5904 continue;
5905 }
5906
c256ffe7 5907 dynamic_strings = get_data (NULL, file, offset, 1, str_tab_len,
d3ba0551 5908 _("dynamic string table"));
d79b3d50 5909 dynamic_strings_length = str_tab_len;
252b5132
RH
5910 break;
5911 }
5912 }
5913
5914 /* And find the syminfo section if available. */
5915 if (dynamic_syminfo == NULL)
5916 {
3e8bba36 5917 unsigned long syminsz = 0;
252b5132 5918
86dba8ee
AM
5919 for (entry = dynamic_section;
5920 entry < dynamic_section + dynamic_nent;
5921 ++entry)
252b5132
RH
5922 {
5923 if (entry->d_tag == DT_SYMINENT)
5924 {
5925 /* Note: these braces are necessary to avoid a syntax
5926 error from the SunOS4 C compiler. */
5927 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
5928 }
5929 else if (entry->d_tag == DT_SYMINSZ)
5930 syminsz = entry->d_un.d_val;
5931 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
5932 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
5933 syminsz);
252b5132
RH
5934 }
5935
5936 if (dynamic_syminfo_offset != 0 && syminsz != 0)
5937 {
86dba8ee 5938 Elf_External_Syminfo *extsyminfo, *extsym;
b34976b6 5939 Elf_Internal_Syminfo *syminfo;
252b5132
RH
5940
5941 /* There is a syminfo section. Read the data. */
c256ffe7
JJ
5942 extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, 1,
5943 syminsz, _("symbol information"));
a6e9f9df
AM
5944 if (!extsyminfo)
5945 return 0;
252b5132 5946
d3ba0551 5947 dynamic_syminfo = malloc (syminsz);
252b5132
RH
5948 if (dynamic_syminfo == NULL)
5949 {
5950 error (_("Out of memory\n"));
5951 return 0;
5952 }
5953
5954 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
5955 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
5956 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
5957 ++syminfo, ++extsym)
252b5132 5958 {
86dba8ee
AM
5959 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
5960 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
5961 }
5962
5963 free (extsyminfo);
5964 }
5965 }
5966
5967 if (do_dynamic && dynamic_addr)
86dba8ee
AM
5968 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
5969 dynamic_addr, dynamic_nent);
252b5132
RH
5970 if (do_dynamic)
5971 printf (_(" Tag Type Name/Value\n"));
5972
86dba8ee
AM
5973 for (entry = dynamic_section;
5974 entry < dynamic_section + dynamic_nent;
5975 entry++)
252b5132
RH
5976 {
5977 if (do_dynamic)
f7a99963 5978 {
b34976b6 5979 const char *dtype;
e699b9ff 5980
f7a99963
NC
5981 putchar (' ');
5982 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
5983 dtype = get_dynamic_type (entry->d_tag);
5984 printf (" (%s)%*s", dtype,
5985 ((is_32bit_elf ? 27 : 19)
5986 - (int) strlen (dtype)),
f7a99963
NC
5987 " ");
5988 }
252b5132
RH
5989
5990 switch (entry->d_tag)
5991 {
d1133906
NC
5992 case DT_FLAGS:
5993 if (do_dynamic)
e9e44622 5994 print_dynamic_flags (entry->d_un.d_val);
d1133906 5995 break;
76da6bbe 5996
252b5132
RH
5997 case DT_AUXILIARY:
5998 case DT_FILTER:
019148e4
L
5999 case DT_CONFIG:
6000 case DT_DEPAUDIT:
6001 case DT_AUDIT:
252b5132
RH
6002 if (do_dynamic)
6003 {
019148e4 6004 switch (entry->d_tag)
b34976b6 6005 {
019148e4
L
6006 case DT_AUXILIARY:
6007 printf (_("Auxiliary library"));
6008 break;
6009
6010 case DT_FILTER:
6011 printf (_("Filter library"));
6012 break;
6013
b34976b6 6014 case DT_CONFIG:
019148e4
L
6015 printf (_("Configuration file"));
6016 break;
6017
6018 case DT_DEPAUDIT:
6019 printf (_("Dependency audit library"));
6020 break;
6021
6022 case DT_AUDIT:
6023 printf (_("Audit library"));
6024 break;
6025 }
252b5132 6026
d79b3d50
NC
6027 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
6028 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 6029 else
f7a99963
NC
6030 {
6031 printf (": ");
6032 print_vma (entry->d_un.d_val, PREFIX_HEX);
6033 putchar ('\n');
6034 }
252b5132
RH
6035 }
6036 break;
6037
dcefbbbd 6038 case DT_FEATURE:
252b5132
RH
6039 if (do_dynamic)
6040 {
6041 printf (_("Flags:"));
86f55779 6042
252b5132
RH
6043 if (entry->d_un.d_val == 0)
6044 printf (_(" None\n"));
6045 else
6046 {
6047 unsigned long int val = entry->d_un.d_val;
86f55779 6048
252b5132
RH
6049 if (val & DTF_1_PARINIT)
6050 {
6051 printf (" PARINIT");
6052 val ^= DTF_1_PARINIT;
6053 }
dcefbbbd
L
6054 if (val & DTF_1_CONFEXP)
6055 {
6056 printf (" CONFEXP");
6057 val ^= DTF_1_CONFEXP;
6058 }
252b5132
RH
6059 if (val != 0)
6060 printf (" %lx", val);
6061 puts ("");
6062 }
6063 }
6064 break;
6065
6066 case DT_POSFLAG_1:
6067 if (do_dynamic)
6068 {
6069 printf (_("Flags:"));
86f55779 6070
252b5132
RH
6071 if (entry->d_un.d_val == 0)
6072 printf (_(" None\n"));
6073 else
6074 {
6075 unsigned long int val = entry->d_un.d_val;
86f55779 6076
252b5132
RH
6077 if (val & DF_P1_LAZYLOAD)
6078 {
6079 printf (" LAZYLOAD");
6080 val ^= DF_P1_LAZYLOAD;
6081 }
6082 if (val & DF_P1_GROUPPERM)
6083 {
6084 printf (" GROUPPERM");
6085 val ^= DF_P1_GROUPPERM;
6086 }
6087 if (val != 0)
6088 printf (" %lx", val);
6089 puts ("");
6090 }
6091 }
6092 break;
6093
6094 case DT_FLAGS_1:
6095 if (do_dynamic)
6096 {
6097 printf (_("Flags:"));
6098 if (entry->d_un.d_val == 0)
6099 printf (_(" None\n"));
6100 else
6101 {
6102 unsigned long int val = entry->d_un.d_val;
86f55779 6103
252b5132
RH
6104 if (val & DF_1_NOW)
6105 {
6106 printf (" NOW");
6107 val ^= DF_1_NOW;
6108 }
6109 if (val & DF_1_GLOBAL)
6110 {
6111 printf (" GLOBAL");
6112 val ^= DF_1_GLOBAL;
6113 }
6114 if (val & DF_1_GROUP)
6115 {
6116 printf (" GROUP");
6117 val ^= DF_1_GROUP;
6118 }
6119 if (val & DF_1_NODELETE)
6120 {
6121 printf (" NODELETE");
6122 val ^= DF_1_NODELETE;
6123 }
6124 if (val & DF_1_LOADFLTR)
6125 {
6126 printf (" LOADFLTR");
6127 val ^= DF_1_LOADFLTR;
6128 }
6129 if (val & DF_1_INITFIRST)
6130 {
6131 printf (" INITFIRST");
6132 val ^= DF_1_INITFIRST;
6133 }
6134 if (val & DF_1_NOOPEN)
6135 {
6136 printf (" NOOPEN");
6137 val ^= DF_1_NOOPEN;
6138 }
6139 if (val & DF_1_ORIGIN)
6140 {
6141 printf (" ORIGIN");
6142 val ^= DF_1_ORIGIN;
6143 }
6144 if (val & DF_1_DIRECT)
6145 {
6146 printf (" DIRECT");
6147 val ^= DF_1_DIRECT;
6148 }
6149 if (val & DF_1_TRANS)
6150 {
6151 printf (" TRANS");
6152 val ^= DF_1_TRANS;
6153 }
6154 if (val & DF_1_INTERPOSE)
6155 {
6156 printf (" INTERPOSE");
6157 val ^= DF_1_INTERPOSE;
6158 }
f7db6139 6159 if (val & DF_1_NODEFLIB)
dcefbbbd 6160 {
f7db6139
L
6161 printf (" NODEFLIB");
6162 val ^= DF_1_NODEFLIB;
dcefbbbd
L
6163 }
6164 if (val & DF_1_NODUMP)
6165 {
6166 printf (" NODUMP");
6167 val ^= DF_1_NODUMP;
6168 }
6169 if (val & DF_1_CONLFAT)
6170 {
6171 printf (" CONLFAT");
6172 val ^= DF_1_CONLFAT;
6173 }
252b5132
RH
6174 if (val != 0)
6175 printf (" %lx", val);
6176 puts ("");
6177 }
6178 }
6179 break;
6180
6181 case DT_PLTREL:
566b0d53 6182 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
6183 if (do_dynamic)
6184 puts (get_dynamic_type (entry->d_un.d_val));
6185 break;
6186
6187 case DT_NULL :
6188 case DT_NEEDED :
6189 case DT_PLTGOT :
6190 case DT_HASH :
6191 case DT_STRTAB :
6192 case DT_SYMTAB :
6193 case DT_RELA :
6194 case DT_INIT :
6195 case DT_FINI :
6196 case DT_SONAME :
6197 case DT_RPATH :
6198 case DT_SYMBOLIC:
6199 case DT_REL :
6200 case DT_DEBUG :
6201 case DT_TEXTREL :
6202 case DT_JMPREL :
019148e4 6203 case DT_RUNPATH :
252b5132
RH
6204 dynamic_info[entry->d_tag] = entry->d_un.d_val;
6205
6206 if (do_dynamic)
6207 {
b34976b6 6208 char *name;
252b5132 6209
d79b3d50
NC
6210 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
6211 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 6212 else
d79b3d50 6213 name = NULL;
252b5132
RH
6214
6215 if (name)
6216 {
6217 switch (entry->d_tag)
6218 {
6219 case DT_NEEDED:
6220 printf (_("Shared library: [%s]"), name);
6221
18bd398b 6222 if (streq (name, program_interpreter))
f7a99963 6223 printf (_(" program interpreter"));
252b5132
RH
6224 break;
6225
6226 case DT_SONAME:
f7a99963 6227 printf (_("Library soname: [%s]"), name);
252b5132
RH
6228 break;
6229
6230 case DT_RPATH:
f7a99963 6231 printf (_("Library rpath: [%s]"), name);
252b5132
RH
6232 break;
6233
019148e4
L
6234 case DT_RUNPATH:
6235 printf (_("Library runpath: [%s]"), name);
6236 break;
6237
252b5132 6238 default:
f7a99963
NC
6239 print_vma (entry->d_un.d_val, PREFIX_HEX);
6240 break;
252b5132
RH
6241 }
6242 }
6243 else
f7a99963
NC
6244 print_vma (entry->d_un.d_val, PREFIX_HEX);
6245
6246 putchar ('\n');
252b5132
RH
6247 }
6248 break;
6249
6250 case DT_PLTRELSZ:
6251 case DT_RELASZ :
6252 case DT_STRSZ :
6253 case DT_RELSZ :
6254 case DT_RELAENT :
6255 case DT_SYMENT :
6256 case DT_RELENT :
566b0d53 6257 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
6258 case DT_PLTPADSZ:
6259 case DT_MOVEENT :
6260 case DT_MOVESZ :
6261 case DT_INIT_ARRAYSZ:
6262 case DT_FINI_ARRAYSZ:
047b2264
JJ
6263 case DT_GNU_CONFLICTSZ:
6264 case DT_GNU_LIBLISTSZ:
252b5132 6265 if (do_dynamic)
f7a99963
NC
6266 {
6267 print_vma (entry->d_un.d_val, UNSIGNED);
6268 printf (" (bytes)\n");
6269 }
252b5132
RH
6270 break;
6271
6272 case DT_VERDEFNUM:
6273 case DT_VERNEEDNUM:
6274 case DT_RELACOUNT:
6275 case DT_RELCOUNT:
6276 if (do_dynamic)
f7a99963
NC
6277 {
6278 print_vma (entry->d_un.d_val, UNSIGNED);
6279 putchar ('\n');
6280 }
252b5132
RH
6281 break;
6282
6283 case DT_SYMINSZ:
6284 case DT_SYMINENT:
6285 case DT_SYMINFO:
6286 case DT_USED:
6287 case DT_INIT_ARRAY:
6288 case DT_FINI_ARRAY:
6289 if (do_dynamic)
6290 {
d79b3d50
NC
6291 if (entry->d_tag == DT_USED
6292 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 6293 {
d79b3d50 6294 char *name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 6295
b34976b6 6296 if (*name)
252b5132
RH
6297 {
6298 printf (_("Not needed object: [%s]\n"), name);
6299 break;
6300 }
6301 }
103f02d3 6302
f7a99963
NC
6303 print_vma (entry->d_un.d_val, PREFIX_HEX);
6304 putchar ('\n');
252b5132
RH
6305 }
6306 break;
6307
6308 case DT_BIND_NOW:
6309 /* The value of this entry is ignored. */
35b1837e
AM
6310 if (do_dynamic)
6311 putchar ('\n');
252b5132 6312 break;
103f02d3 6313
047b2264
JJ
6314 case DT_GNU_PRELINKED:
6315 if (do_dynamic)
6316 {
b34976b6 6317 struct tm *tmp;
047b2264
JJ
6318 time_t time = entry->d_un.d_val;
6319
6320 tmp = gmtime (&time);
6321 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
6322 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
6323 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
6324
6325 }
6326 break;
6327
fdc90cb4
JJ
6328 case DT_GNU_HASH:
6329 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
6330 if (do_dynamic)
6331 {
6332 print_vma (entry->d_un.d_val, PREFIX_HEX);
6333 putchar ('\n');
6334 }
6335 break;
6336
252b5132
RH
6337 default:
6338 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 6339 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
6340 entry->d_un.d_val;
6341
6342 if (do_dynamic)
6343 {
6344 switch (elf_header.e_machine)
6345 {
6346 case EM_MIPS:
4fe85591 6347 case EM_MIPS_RS3_LE:
b2d38a17 6348 dynamic_section_mips_val (entry);
252b5132 6349 break;
103f02d3 6350 case EM_PARISC:
b2d38a17 6351 dynamic_section_parisc_val (entry);
103f02d3 6352 break;
ecc51f48 6353 case EM_IA_64:
b2d38a17 6354 dynamic_section_ia64_val (entry);
ecc51f48 6355 break;
252b5132 6356 default:
f7a99963
NC
6357 print_vma (entry->d_un.d_val, PREFIX_HEX);
6358 putchar ('\n');
252b5132
RH
6359 }
6360 }
6361 break;
6362 }
6363 }
6364
6365 return 1;
6366}
6367
6368static char *
d3ba0551 6369get_ver_flags (unsigned int flags)
252b5132 6370{
b34976b6 6371 static char buff[32];
252b5132
RH
6372
6373 buff[0] = 0;
6374
6375 if (flags == 0)
6376 return _("none");
6377
6378 if (flags & VER_FLG_BASE)
6379 strcat (buff, "BASE ");
6380
6381 if (flags & VER_FLG_WEAK)
6382 {
6383 if (flags & VER_FLG_BASE)
6384 strcat (buff, "| ");
6385
6386 strcat (buff, "WEAK ");
6387 }
6388
6389 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
6390 strcat (buff, "| <unknown>");
6391
6392 return buff;
6393}
6394
6395/* Display the contents of the version sections. */
6396static int
d3ba0551 6397process_version_sections (FILE *file)
252b5132 6398{
b34976b6
AM
6399 Elf_Internal_Shdr *section;
6400 unsigned i;
6401 int found = 0;
252b5132
RH
6402
6403 if (! do_version)
6404 return 1;
6405
6406 for (i = 0, section = section_headers;
6407 i < elf_header.e_shnum;
b34976b6 6408 i++, section++)
252b5132
RH
6409 {
6410 switch (section->sh_type)
6411 {
6412 case SHT_GNU_verdef:
6413 {
b34976b6
AM
6414 Elf_External_Verdef *edefs;
6415 unsigned int idx;
6416 unsigned int cnt;
252b5132
RH
6417
6418 found = 1;
6419
6420 printf
6421 (_("\nVersion definition section '%s' contains %ld entries:\n"),
6422 SECTION_NAME (section), section->sh_info);
6423
6424 printf (_(" Addr: 0x"));
6425 printf_vma (section->sh_addr);
6426 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 6427 (unsigned long) section->sh_offset, section->sh_link,
c256ffe7
JJ
6428 SECTION_HEADER_INDEX (section->sh_link)
6429 < elf_header.e_shnum
6430 ? SECTION_NAME (SECTION_HEADER (section->sh_link))
6431 : "<corrupt>");
252b5132 6432
c256ffe7
JJ
6433 edefs = get_data (NULL, file, section->sh_offset, 1,
6434 section->sh_size,
d3ba0551 6435 _("version definition section"));
a6e9f9df
AM
6436 if (!edefs)
6437 break;
252b5132 6438
b34976b6 6439 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 6440 {
b34976b6
AM
6441 char *vstart;
6442 Elf_External_Verdef *edef;
6443 Elf_Internal_Verdef ent;
6444 Elf_External_Verdaux *eaux;
6445 Elf_Internal_Verdaux aux;
6446 int j;
6447 int isum;
103f02d3 6448
252b5132
RH
6449 vstart = ((char *) edefs) + idx;
6450
6451 edef = (Elf_External_Verdef *) vstart;
6452
6453 ent.vd_version = BYTE_GET (edef->vd_version);
6454 ent.vd_flags = BYTE_GET (edef->vd_flags);
6455 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
6456 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
6457 ent.vd_hash = BYTE_GET (edef->vd_hash);
6458 ent.vd_aux = BYTE_GET (edef->vd_aux);
6459 ent.vd_next = BYTE_GET (edef->vd_next);
6460
6461 printf (_(" %#06x: Rev: %d Flags: %s"),
6462 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
6463
6464 printf (_(" Index: %d Cnt: %d "),
6465 ent.vd_ndx, ent.vd_cnt);
6466
6467 vstart += ent.vd_aux;
6468
6469 eaux = (Elf_External_Verdaux *) vstart;
6470
6471 aux.vda_name = BYTE_GET (eaux->vda_name);
6472 aux.vda_next = BYTE_GET (eaux->vda_next);
6473
d79b3d50
NC
6474 if (VALID_DYNAMIC_NAME (aux.vda_name))
6475 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
6476 else
6477 printf (_("Name index: %ld\n"), aux.vda_name);
6478
6479 isum = idx + ent.vd_aux;
6480
b34976b6 6481 for (j = 1; j < ent.vd_cnt; j++)
252b5132
RH
6482 {
6483 isum += aux.vda_next;
6484 vstart += aux.vda_next;
6485
6486 eaux = (Elf_External_Verdaux *) vstart;
6487
6488 aux.vda_name = BYTE_GET (eaux->vda_name);
6489 aux.vda_next = BYTE_GET (eaux->vda_next);
6490
d79b3d50 6491 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 6492 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 6493 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
6494 else
6495 printf (_(" %#06x: Parent %d, name index: %ld\n"),
6496 isum, j, aux.vda_name);
6497 }
6498
6499 idx += ent.vd_next;
6500 }
6501
6502 free (edefs);
6503 }
6504 break;
103f02d3 6505
252b5132
RH
6506 case SHT_GNU_verneed:
6507 {
b34976b6
AM
6508 Elf_External_Verneed *eneed;
6509 unsigned int idx;
6510 unsigned int cnt;
252b5132
RH
6511
6512 found = 1;
6513
6514 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
6515 SECTION_NAME (section), section->sh_info);
6516
6517 printf (_(" Addr: 0x"));
6518 printf_vma (section->sh_addr);
6519 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
1b228002 6520 (unsigned long) section->sh_offset, section->sh_link,
c256ffe7
JJ
6521 SECTION_HEADER_INDEX (section->sh_link)
6522 < elf_header.e_shnum
6523 ? SECTION_NAME (SECTION_HEADER (section->sh_link))
6524 : "<corrupt>");
252b5132 6525
c256ffe7
JJ
6526 eneed = get_data (NULL, file, section->sh_offset, 1,
6527 section->sh_size,
d3ba0551 6528 _("version need section"));
a6e9f9df
AM
6529 if (!eneed)
6530 break;
252b5132
RH
6531
6532 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
6533 {
b34976b6
AM
6534 Elf_External_Verneed *entry;
6535 Elf_Internal_Verneed ent;
6536 int j;
6537 int isum;
6538 char *vstart;
252b5132
RH
6539
6540 vstart = ((char *) eneed) + idx;
6541
6542 entry = (Elf_External_Verneed *) vstart;
6543
6544 ent.vn_version = BYTE_GET (entry->vn_version);
6545 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
6546 ent.vn_file = BYTE_GET (entry->vn_file);
6547 ent.vn_aux = BYTE_GET (entry->vn_aux);
6548 ent.vn_next = BYTE_GET (entry->vn_next);
6549
6550 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
6551
d79b3d50
NC
6552 if (VALID_DYNAMIC_NAME (ent.vn_file))
6553 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
6554 else
6555 printf (_(" File: %lx"), ent.vn_file);
6556
6557 printf (_(" Cnt: %d\n"), ent.vn_cnt);
6558
6559 vstart += ent.vn_aux;
6560
6561 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
6562 {
b34976b6
AM
6563 Elf_External_Vernaux *eaux;
6564 Elf_Internal_Vernaux aux;
252b5132
RH
6565
6566 eaux = (Elf_External_Vernaux *) vstart;
6567
6568 aux.vna_hash = BYTE_GET (eaux->vna_hash);
6569 aux.vna_flags = BYTE_GET (eaux->vna_flags);
6570 aux.vna_other = BYTE_GET (eaux->vna_other);
6571 aux.vna_name = BYTE_GET (eaux->vna_name);
6572 aux.vna_next = BYTE_GET (eaux->vna_next);
6573
d79b3d50 6574 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 6575 printf (_(" %#06x: Name: %s"),
d79b3d50 6576 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 6577 else
ecc2063b 6578 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
6579 isum, aux.vna_name);
6580
6581 printf (_(" Flags: %s Version: %d\n"),
6582 get_ver_flags (aux.vna_flags), aux.vna_other);
6583
6584 isum += aux.vna_next;
6585 vstart += aux.vna_next;
6586 }
6587
6588 idx += ent.vn_next;
6589 }
103f02d3 6590
252b5132
RH
6591 free (eneed);
6592 }
6593 break;
6594
6595 case SHT_GNU_versym:
6596 {
b34976b6
AM
6597 Elf_Internal_Shdr *link_section;
6598 int total;
6599 int cnt;
6600 unsigned char *edata;
6601 unsigned short *data;
6602 char *strtab;
6603 Elf_Internal_Sym *symbols;
6604 Elf_Internal_Shdr *string_sec;
d3ba0551 6605 long off;
252b5132 6606
c256ffe7
JJ
6607 if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum)
6608 break;
6609
9ad5cbcf 6610 link_section = SECTION_HEADER (section->sh_link);
08d8fa11 6611 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 6612
c256ffe7
JJ
6613 if (SECTION_HEADER_INDEX (link_section->sh_link)
6614 >= elf_header.e_shnum)
6615 break;
6616
252b5132
RH
6617 found = 1;
6618
9ad5cbcf 6619 symbols = GET_ELF_SYMBOLS (file, link_section);
252b5132 6620
9ad5cbcf 6621 string_sec = SECTION_HEADER (link_section->sh_link);
252b5132 6622
c256ffe7 6623 strtab = get_data (NULL, file, string_sec->sh_offset, 1,
d3ba0551 6624 string_sec->sh_size, _("version string table"));
a6e9f9df
AM
6625 if (!strtab)
6626 break;
252b5132
RH
6627
6628 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
6629 SECTION_NAME (section), total);
6630
6631 printf (_(" Addr: "));
6632 printf_vma (section->sh_addr);
6633 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 6634 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
6635 SECTION_NAME (link_section));
6636
d3ba0551
AM
6637 off = offset_from_vma (file,
6638 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
6639 total * sizeof (short));
c256ffe7 6640 edata = get_data (NULL, file, off, total, sizeof (short),
d3ba0551 6641 _("version symbol data"));
a6e9f9df
AM
6642 if (!edata)
6643 {
6644 free (strtab);
6645 break;
6646 }
252b5132 6647
c256ffe7 6648 data = cmalloc (total, sizeof (short));
252b5132
RH
6649
6650 for (cnt = total; cnt --;)
b34976b6
AM
6651 data[cnt] = byte_get (edata + cnt * sizeof (short),
6652 sizeof (short));
252b5132
RH
6653
6654 free (edata);
6655
6656 for (cnt = 0; cnt < total; cnt += 4)
6657 {
6658 int j, nn;
00d93f34 6659 int check_def, check_need;
b34976b6 6660 char *name;
252b5132
RH
6661
6662 printf (" %03x:", cnt);
6663
6664 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 6665 switch (data[cnt + j])
252b5132
RH
6666 {
6667 case 0:
6668 fputs (_(" 0 (*local*) "), stdout);
6669 break;
6670
6671 case 1:
6672 fputs (_(" 1 (*global*) "), stdout);
6673 break;
6674
6675 default:
b34976b6
AM
6676 nn = printf ("%4x%c", data[cnt + j] & 0x7fff,
6677 data[cnt + j] & 0x8000 ? 'h' : ' ');
252b5132 6678
00d93f34
JJ
6679 check_def = 1;
6680 check_need = 1;
c256ffe7
JJ
6681 if (SECTION_HEADER_INDEX (symbols[cnt + j].st_shndx)
6682 >= elf_header.e_shnum
6683 || SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
6684 != SHT_NOBITS)
252b5132 6685 {
b34976b6 6686 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
6687 check_def = 0;
6688 else
6689 check_need = 0;
252b5132 6690 }
00d93f34
JJ
6691
6692 if (check_need
b34976b6 6693 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 6694 {
b34976b6
AM
6695 Elf_Internal_Verneed ivn;
6696 unsigned long offset;
252b5132 6697
d93f0186
NC
6698 offset = offset_from_vma
6699 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
6700 sizeof (Elf_External_Verneed));
252b5132 6701
b34976b6 6702 do
252b5132 6703 {
b34976b6
AM
6704 Elf_Internal_Vernaux ivna;
6705 Elf_External_Verneed evn;
6706 Elf_External_Vernaux evna;
6707 unsigned long a_off;
252b5132 6708
c256ffe7 6709 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 6710 _("version need"));
252b5132
RH
6711
6712 ivn.vn_aux = BYTE_GET (evn.vn_aux);
6713 ivn.vn_next = BYTE_GET (evn.vn_next);
6714
6715 a_off = offset + ivn.vn_aux;
6716
6717 do
6718 {
a6e9f9df 6719 get_data (&evna, file, a_off, sizeof (evna),
c256ffe7 6720 1, _("version need aux (2)"));
252b5132
RH
6721
6722 ivna.vna_next = BYTE_GET (evna.vna_next);
6723 ivna.vna_other = BYTE_GET (evna.vna_other);
6724
6725 a_off += ivna.vna_next;
6726 }
b34976b6 6727 while (ivna.vna_other != data[cnt + j]
252b5132
RH
6728 && ivna.vna_next != 0);
6729
b34976b6 6730 if (ivna.vna_other == data[cnt + j])
252b5132
RH
6731 {
6732 ivna.vna_name = BYTE_GET (evna.vna_name);
6733
16062207 6734 name = strtab + ivna.vna_name;
252b5132 6735 nn += printf ("(%s%-*s",
16062207
ILT
6736 name,
6737 12 - (int) strlen (name),
252b5132 6738 ")");
00d93f34 6739 check_def = 0;
252b5132
RH
6740 break;
6741 }
6742
6743 offset += ivn.vn_next;
6744 }
6745 while (ivn.vn_next);
6746 }
00d93f34 6747
b34976b6
AM
6748 if (check_def && data[cnt + j] != 0x8001
6749 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 6750 {
b34976b6
AM
6751 Elf_Internal_Verdef ivd;
6752 Elf_External_Verdef evd;
6753 unsigned long offset;
252b5132 6754
d93f0186
NC
6755 offset = offset_from_vma
6756 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
6757 sizeof evd);
252b5132
RH
6758
6759 do
6760 {
c256ffe7 6761 get_data (&evd, file, offset, sizeof (evd), 1,
a6e9f9df 6762 _("version def"));
252b5132
RH
6763
6764 ivd.vd_next = BYTE_GET (evd.vd_next);
6765 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
6766
6767 offset += ivd.vd_next;
6768 }
b34976b6 6769 while (ivd.vd_ndx != (data[cnt + j] & 0x7fff)
252b5132
RH
6770 && ivd.vd_next != 0);
6771
b34976b6 6772 if (ivd.vd_ndx == (data[cnt + j] & 0x7fff))
252b5132 6773 {
b34976b6
AM
6774 Elf_External_Verdaux evda;
6775 Elf_Internal_Verdaux ivda;
252b5132
RH
6776
6777 ivd.vd_aux = BYTE_GET (evd.vd_aux);
6778
a6e9f9df
AM
6779 get_data (&evda, file,
6780 offset - ivd.vd_next + ivd.vd_aux,
c256ffe7
JJ
6781 sizeof (evda), 1,
6782 _("version def aux"));
252b5132
RH
6783
6784 ivda.vda_name = BYTE_GET (evda.vda_name);
6785
16062207 6786 name = strtab + ivda.vda_name;
252b5132 6787 nn += printf ("(%s%-*s",
16062207
ILT
6788 name,
6789 12 - (int) strlen (name),
252b5132
RH
6790 ")");
6791 }
6792 }
6793
6794 if (nn < 18)
6795 printf ("%*c", 18 - nn, ' ');
6796 }
6797
6798 putchar ('\n');
6799 }
6800
6801 free (data);
6802 free (strtab);
6803 free (symbols);
6804 }
6805 break;
103f02d3 6806
252b5132
RH
6807 default:
6808 break;
6809 }
6810 }
6811
6812 if (! found)
6813 printf (_("\nNo version information found in this file.\n"));
6814
6815 return 1;
6816}
6817
d1133906 6818static const char *
d3ba0551 6819get_symbol_binding (unsigned int binding)
252b5132 6820{
b34976b6 6821 static char buff[32];
252b5132
RH
6822
6823 switch (binding)
6824 {
b34976b6
AM
6825 case STB_LOCAL: return "LOCAL";
6826 case STB_GLOBAL: return "GLOBAL";
6827 case STB_WEAK: return "WEAK";
252b5132
RH
6828 default:
6829 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
6830 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
6831 binding);
252b5132 6832 else if (binding >= STB_LOOS && binding <= STB_HIOS)
e9e44622 6833 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
252b5132 6834 else
e9e44622 6835 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
6836 return buff;
6837 }
6838}
6839
d1133906 6840static const char *
d3ba0551 6841get_symbol_type (unsigned int type)
252b5132 6842{
b34976b6 6843 static char buff[32];
252b5132
RH
6844
6845 switch (type)
6846 {
b34976b6
AM
6847 case STT_NOTYPE: return "NOTYPE";
6848 case STT_OBJECT: return "OBJECT";
6849 case STT_FUNC: return "FUNC";
6850 case STT_SECTION: return "SECTION";
6851 case STT_FILE: return "FILE";
6852 case STT_COMMON: return "COMMON";
6853 case STT_TLS: return "TLS";
15ab5209
DB
6854 case STT_RELC: return "RELC";
6855 case STT_SRELC: return "SRELC";
252b5132
RH
6856 default:
6857 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
6858 {
6859 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
6860 return "THUMB_FUNC";
6861
351b4b40 6862 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
6863 return "REGISTER";
6864
6865 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
6866 return "PARISC_MILLI";
6867
e9e44622 6868 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 6869 }
252b5132 6870 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
6871 {
6872 if (elf_header.e_machine == EM_PARISC)
6873 {
6874 if (type == STT_HP_OPAQUE)
6875 return "HP_OPAQUE";
6876 if (type == STT_HP_STUB)
6877 return "HP_STUB";
6878 }
6879
e9e44622 6880 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 6881 }
252b5132 6882 else
e9e44622 6883 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
6884 return buff;
6885 }
6886}
6887
d1133906 6888static const char *
d3ba0551 6889get_symbol_visibility (unsigned int visibility)
d1133906
NC
6890{
6891 switch (visibility)
6892 {
b34976b6
AM
6893 case STV_DEFAULT: return "DEFAULT";
6894 case STV_INTERNAL: return "INTERNAL";
6895 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
6896 case STV_PROTECTED: return "PROTECTED";
6897 default: abort ();
6898 }
6899}
6900
5e2b0d47
NC
6901static const char *
6902get_mips_symbol_other (unsigned int other)
6903{
6904 switch (other)
6905 {
6906 case STO_OPTIONAL: return "OPTIONAL";
6907 case STO_MIPS16: return "MIPS16";
6908 default: return NULL;
6909 }
6910}
6911
6912static const char *
6913get_symbol_other (unsigned int other)
6914{
6915 const char * result = NULL;
6916 static char buff [32];
6917
6918 if (other == 0)
6919 return "";
6920
6921 switch (elf_header.e_machine)
6922 {
6923 case EM_MIPS:
6924 result = get_mips_symbol_other (other);
6925 default:
6926 break;
6927 }
6928
6929 if (result)
6930 return result;
6931
6932 snprintf (buff, sizeof buff, _("<other>: %x"), other);
6933 return buff;
6934}
6935
d1133906 6936static const char *
d3ba0551 6937get_symbol_index_type (unsigned int type)
252b5132 6938{
b34976b6 6939 static char buff[32];
5cf1065c 6940
252b5132
RH
6941 switch (type)
6942 {
b34976b6
AM
6943 case SHN_UNDEF: return "UND";
6944 case SHN_ABS: return "ABS";
6945 case SHN_COMMON: return "COM";
252b5132 6946 default:
9ce701e2
L
6947 if (type == SHN_IA_64_ANSI_COMMON
6948 && elf_header.e_machine == EM_IA_64
6949 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
6950 return "ANSI_COM";
3b22753a
L
6951 else if (elf_header.e_machine == EM_X86_64
6952 && type == SHN_X86_64_LCOMMON)
6953 return "LARGE_COM";
172553c7
TS
6954 else if (type == SHN_MIPS_SCOMMON
6955 && elf_header.e_machine == EM_MIPS)
6956 return "SCOM";
6957 else if (type == SHN_MIPS_SUNDEFINED
6958 && elf_header.e_machine == EM_MIPS)
6959 return "SUND";
9ce701e2 6960 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
5cf1065c 6961 sprintf (buff, "PRC[0x%04x]", type);
252b5132 6962 else if (type >= SHN_LOOS && type <= SHN_HIOS)
5cf1065c 6963 sprintf (buff, "OS [0x%04x]", type);
9ad5cbcf 6964 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
5cf1065c 6965 sprintf (buff, "RSV[0x%04x]", type);
252b5132 6966 else
232e7cb8 6967 sprintf (buff, "%3d", type);
5cf1065c 6968 break;
252b5132 6969 }
5cf1065c
NC
6970
6971 return buff;
252b5132
RH
6972}
6973
66543521
AM
6974static bfd_vma *
6975get_dynamic_data (FILE *file, unsigned int number, unsigned int ent_size)
252b5132 6976{
b34976b6 6977 unsigned char *e_data;
66543521 6978 bfd_vma *i_data;
252b5132 6979
c256ffe7 6980 e_data = cmalloc (number, ent_size);
252b5132
RH
6981
6982 if (e_data == NULL)
6983 {
6984 error (_("Out of memory\n"));
6985 return NULL;
6986 }
6987
66543521 6988 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
6989 {
6990 error (_("Unable to read in dynamic data\n"));
6991 return NULL;
6992 }
6993
c256ffe7 6994 i_data = cmalloc (number, sizeof (*i_data));
252b5132
RH
6995
6996 if (i_data == NULL)
6997 {
6998 error (_("Out of memory\n"));
6999 free (e_data);
7000 return NULL;
7001 }
7002
7003 while (number--)
66543521 7004 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
7005
7006 free (e_data);
7007
7008 return i_data;
7009}
7010
e3c8793a 7011/* Dump the symbol table. */
252b5132 7012static int
d3ba0551 7013process_symbol_table (FILE *file)
252b5132 7014{
b34976b6 7015 Elf_Internal_Shdr *section;
66543521
AM
7016 bfd_vma nbuckets = 0;
7017 bfd_vma nchains = 0;
7018 bfd_vma *buckets = NULL;
7019 bfd_vma *chains = NULL;
fdc90cb4
JJ
7020 bfd_vma ngnubuckets = 0;
7021 bfd_vma *gnubuckets = NULL;
7022 bfd_vma *gnuchains = NULL;
252b5132
RH
7023
7024 if (! do_syms && !do_histogram)
7025 return 1;
7026
7027 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
7028 || do_histogram))
7029 {
66543521
AM
7030 unsigned char nb[8];
7031 unsigned char nc[8];
7032 int hash_ent_size = 4;
7033
7034 if ((elf_header.e_machine == EM_ALPHA
7035 || elf_header.e_machine == EM_S390
7036 || elf_header.e_machine == EM_S390_OLD)
7037 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
7038 hash_ent_size = 8;
7039
fb52b2f4
NC
7040 if (fseek (file,
7041 (archive_file_offset
7042 + offset_from_vma (file, dynamic_info[DT_HASH],
7043 sizeof nb + sizeof nc)),
d93f0186 7044 SEEK_SET))
252b5132
RH
7045 {
7046 error (_("Unable to seek to start of dynamic information"));
7047 return 0;
7048 }
7049
66543521 7050 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
7051 {
7052 error (_("Failed to read in number of buckets\n"));
7053 return 0;
7054 }
7055
66543521 7056 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
7057 {
7058 error (_("Failed to read in number of chains\n"));
7059 return 0;
7060 }
7061
66543521
AM
7062 nbuckets = byte_get (nb, hash_ent_size);
7063 nchains = byte_get (nc, hash_ent_size);
252b5132 7064
66543521
AM
7065 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
7066 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132
RH
7067
7068 if (buckets == NULL || chains == NULL)
7069 return 0;
7070 }
7071
7072 if (do_syms
7073 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
7074 {
66543521
AM
7075 unsigned long hn;
7076 bfd_vma si;
252b5132
RH
7077
7078 printf (_("\nSymbol table for image:\n"));
f7a99963 7079 if (is_32bit_elf)
ca47b30c 7080 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 7081 else
ca47b30c 7082 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
252b5132
RH
7083
7084 for (hn = 0; hn < nbuckets; hn++)
7085 {
b34976b6 7086 if (! buckets[hn])
252b5132
RH
7087 continue;
7088
b34976b6 7089 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
252b5132 7090 {
b34976b6 7091 Elf_Internal_Sym *psym;
66543521 7092 int n;
252b5132
RH
7093
7094 psym = dynamic_symbols + si;
7095
66543521
AM
7096 n = print_vma (si, DEC_5);
7097 if (n < 5)
7098 fputs (" " + n, stdout);
7099 printf (" %3lu: ", hn);
f7a99963 7100 print_vma (psym->st_value, LONG_HEX);
66543521 7101 putchar (' ');
d1133906 7102 print_vma (psym->st_size, DEC_5);
76da6bbe 7103
d1133906
NC
7104 printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
7105 printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
7106 printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
7107 /* Check to see if any other bits in the st_other field are set.
7108 Note - displaying this information disrupts the layout of the
7109 table being generated, but for the moment this case is very rare. */
7110 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
7111 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 7112 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
d79b3d50
NC
7113 if (VALID_DYNAMIC_NAME (psym->st_name))
7114 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
7115 else
7116 printf (" <corrupt: %14ld>", psym->st_name);
31104126 7117 putchar ('\n');
252b5132
RH
7118 }
7119 }
7120 }
7121 else if (do_syms && !do_using_dynamic)
7122 {
b34976b6 7123 unsigned int i;
252b5132
RH
7124
7125 for (i = 0, section = section_headers;
7126 i < elf_header.e_shnum;
7127 i++, section++)
7128 {
b34976b6 7129 unsigned int si;
c256ffe7
JJ
7130 char *strtab = NULL;
7131 unsigned long int strtab_size = 0;
b34976b6
AM
7132 Elf_Internal_Sym *symtab;
7133 Elf_Internal_Sym *psym;
252b5132
RH
7134
7135
7136 if ( section->sh_type != SHT_SYMTAB
7137 && section->sh_type != SHT_DYNSYM)
7138 continue;
7139
7140 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
7141 SECTION_NAME (section),
7142 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 7143 if (is_32bit_elf)
ca47b30c 7144 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 7145 else
ca47b30c 7146 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 7147
9ad5cbcf 7148 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
7149 if (symtab == NULL)
7150 continue;
7151
7152 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
7153 {
7154 strtab = string_table;
7155 strtab_size = string_table_length;
7156 }
7157 else if (SECTION_HEADER_INDEX (section->sh_link) < elf_header.e_shnum)
252b5132 7158 {
b34976b6 7159 Elf_Internal_Shdr *string_sec;
252b5132 7160
9ad5cbcf 7161 string_sec = SECTION_HEADER (section->sh_link);
252b5132 7162
d3ba0551 7163 strtab = get_data (NULL, file, string_sec->sh_offset,
c256ffe7
JJ
7164 1, string_sec->sh_size, _("string table"));
7165 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
7166 }
7167
7168 for (si = 0, psym = symtab;
7169 si < section->sh_size / section->sh_entsize;
b34976b6 7170 si++, psym++)
252b5132 7171 {
5e220199 7172 printf ("%6d: ", si);
f7a99963
NC
7173 print_vma (psym->st_value, LONG_HEX);
7174 putchar (' ');
7175 print_vma (psym->st_size, DEC_5);
d1133906
NC
7176 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
7177 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
7178 printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
7179 /* Check to see if any other bits in the st_other field are set.
7180 Note - displaying this information disrupts the layout of the
7181 table being generated, but for the moment this case is very rare. */
7182 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
7183 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 7184 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7
JJ
7185 print_symbol (25, psym->st_name < strtab_size
7186 ? strtab + psym->st_name : "<corrupt>");
252b5132
RH
7187
7188 if (section->sh_type == SHT_DYNSYM &&
b34976b6 7189 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 7190 {
b34976b6
AM
7191 unsigned char data[2];
7192 unsigned short vers_data;
7193 unsigned long offset;
7194 int is_nobits;
7195 int check_def;
252b5132 7196
d93f0186
NC
7197 offset = offset_from_vma
7198 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
7199 sizeof data + si * sizeof (vers_data));
252b5132 7200
a6e9f9df 7201 get_data (&data, file, offset + si * sizeof (vers_data),
c256ffe7 7202 sizeof (data), 1, _("version data"));
252b5132
RH
7203
7204 vers_data = byte_get (data, 2);
7205
c256ffe7
JJ
7206 is_nobits = (SECTION_HEADER_INDEX (psym->st_shndx)
7207 < elf_header.e_shnum
7208 && SECTION_HEADER (psym->st_shndx)->sh_type
7209 == SHT_NOBITS);
252b5132
RH
7210
7211 check_def = (psym->st_shndx != SHN_UNDEF);
7212
7213 if ((vers_data & 0x8000) || vers_data > 1)
7214 {
b34976b6 7215 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 7216 && (is_nobits || ! check_def))
252b5132 7217 {
b34976b6
AM
7218 Elf_External_Verneed evn;
7219 Elf_Internal_Verneed ivn;
7220 Elf_Internal_Vernaux ivna;
252b5132
RH
7221
7222 /* We must test both. */
d93f0186
NC
7223 offset = offset_from_vma
7224 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
7225 sizeof evn);
252b5132 7226
252b5132
RH
7227 do
7228 {
b34976b6 7229 unsigned long vna_off;
252b5132 7230
c256ffe7 7231 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 7232 _("version need"));
dd27201e
L
7233
7234 ivn.vn_aux = BYTE_GET (evn.vn_aux);
7235 ivn.vn_next = BYTE_GET (evn.vn_next);
7236
252b5132
RH
7237 vna_off = offset + ivn.vn_aux;
7238
7239 do
7240 {
b34976b6 7241 Elf_External_Vernaux evna;
252b5132 7242
a6e9f9df 7243 get_data (&evna, file, vna_off,
c256ffe7 7244 sizeof (evna), 1,
a6e9f9df 7245 _("version need aux (3)"));
252b5132
RH
7246
7247 ivna.vna_other = BYTE_GET (evna.vna_other);
7248 ivna.vna_next = BYTE_GET (evna.vna_next);
7249 ivna.vna_name = BYTE_GET (evna.vna_name);
7250
7251 vna_off += ivna.vna_next;
7252 }
7253 while (ivna.vna_other != vers_data
7254 && ivna.vna_next != 0);
7255
7256 if (ivna.vna_other == vers_data)
7257 break;
7258
7259 offset += ivn.vn_next;
7260 }
7261 while (ivn.vn_next != 0);
7262
7263 if (ivna.vna_other == vers_data)
7264 {
7265 printf ("@%s (%d)",
c256ffe7
JJ
7266 ivna.vna_name < strtab_size
7267 ? strtab + ivna.vna_name : "<corrupt>",
7268 ivna.vna_other);
252b5132
RH
7269 check_def = 0;
7270 }
7271 else if (! is_nobits)
7272 error (_("bad dynamic symbol"));
7273 else
7274 check_def = 1;
7275 }
7276
7277 if (check_def)
7278 {
00d93f34 7279 if (vers_data != 0x8001
b34976b6 7280 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 7281 {
b34976b6
AM
7282 Elf_Internal_Verdef ivd;
7283 Elf_Internal_Verdaux ivda;
7284 Elf_External_Verdaux evda;
7285 unsigned long offset;
252b5132 7286
d93f0186
NC
7287 offset = offset_from_vma
7288 (file,
7289 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
7290 sizeof (Elf_External_Verdef));
252b5132
RH
7291
7292 do
7293 {
b34976b6 7294 Elf_External_Verdef evd;
252b5132 7295
a6e9f9df 7296 get_data (&evd, file, offset, sizeof (evd),
c256ffe7 7297 1, _("version def"));
252b5132 7298
b34976b6
AM
7299 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
7300 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
7301 ivd.vd_next = BYTE_GET (evd.vd_next);
7302
7303 offset += ivd.vd_next;
7304 }
7305 while (ivd.vd_ndx != (vers_data & 0x7fff)
7306 && ivd.vd_next != 0);
7307
7308 offset -= ivd.vd_next;
7309 offset += ivd.vd_aux;
7310
a6e9f9df 7311 get_data (&evda, file, offset, sizeof (evda),
c256ffe7 7312 1, _("version def aux"));
252b5132
RH
7313
7314 ivda.vda_name = BYTE_GET (evda.vda_name);
7315
7316 if (psym->st_name != ivda.vda_name)
7317 printf ((vers_data & 0x8000)
7318 ? "@%s" : "@@%s",
c256ffe7
JJ
7319 ivda.vda_name < strtab_size
7320 ? strtab + ivda.vda_name : "<corrupt>");
252b5132
RH
7321 }
7322 }
7323 }
7324 }
7325
7326 putchar ('\n');
7327 }
7328
7329 free (symtab);
7330 if (strtab != string_table)
7331 free (strtab);
7332 }
7333 }
7334 else if (do_syms)
7335 printf
7336 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
7337
7338 if (do_histogram && buckets != NULL)
7339 {
66543521
AM
7340 unsigned long *lengths;
7341 unsigned long *counts;
7342 unsigned long hn;
7343 bfd_vma si;
7344 unsigned long maxlength = 0;
7345 unsigned long nzero_counts = 0;
7346 unsigned long nsyms = 0;
252b5132 7347
66543521
AM
7348 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
7349 (unsigned long) nbuckets);
252b5132
RH
7350 printf (_(" Length Number %% of total Coverage\n"));
7351
66543521 7352 lengths = calloc (nbuckets, sizeof (*lengths));
252b5132
RH
7353 if (lengths == NULL)
7354 {
7355 error (_("Out of memory"));
7356 return 0;
7357 }
7358 for (hn = 0; hn < nbuckets; ++hn)
7359 {
f7a99963 7360 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 7361 {
b34976b6 7362 ++nsyms;
252b5132 7363 if (maxlength < ++lengths[hn])
b34976b6 7364 ++maxlength;
252b5132
RH
7365 }
7366 }
7367
66543521 7368 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
7369 if (counts == NULL)
7370 {
7371 error (_("Out of memory"));
7372 return 0;
7373 }
7374
7375 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 7376 ++counts[lengths[hn]];
252b5132 7377
103f02d3 7378 if (nbuckets > 0)
252b5132 7379 {
66543521
AM
7380 unsigned long i;
7381 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 7382 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 7383 for (i = 1; i <= maxlength; ++i)
103f02d3 7384 {
66543521
AM
7385 nzero_counts += counts[i] * i;
7386 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
7387 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
7388 (nzero_counts * 100.0) / nsyms);
7389 }
252b5132
RH
7390 }
7391
7392 free (counts);
7393 free (lengths);
7394 }
7395
7396 if (buckets != NULL)
7397 {
7398 free (buckets);
7399 free (chains);
7400 }
7401
fdc90cb4
JJ
7402 if (do_histogram && dynamic_info_DT_GNU_HASH)
7403 {
7404 unsigned char nb[16];
7405 bfd_vma i, maxchain = 0xffffffff, symidx, bitmaskwords;
7406 unsigned long *lengths;
7407 unsigned long *counts;
7408 unsigned long hn;
7409 unsigned long maxlength = 0;
7410 unsigned long nzero_counts = 0;
7411 unsigned long nsyms = 0;
7412 bfd_vma buckets_vma;
7413
7414 if (fseek (file,
7415 (archive_file_offset
7416 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
7417 sizeof nb)),
7418 SEEK_SET))
7419 {
7420 error (_("Unable to seek to start of dynamic information"));
7421 return 0;
7422 }
7423
7424 if (fread (nb, 16, 1, file) != 1)
7425 {
7426 error (_("Failed to read in number of buckets\n"));
7427 return 0;
7428 }
7429
7430 ngnubuckets = byte_get (nb, 4);
7431 symidx = byte_get (nb + 4, 4);
7432 bitmaskwords = byte_get (nb + 8, 4);
7433 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
7434 if (is_32bit_elf)
7435 buckets_vma += bitmaskwords * 4;
7436 else
7437 buckets_vma += bitmaskwords * 8;
7438
7439 if (fseek (file,
7440 (archive_file_offset
7441 + offset_from_vma (file, buckets_vma, 4)),
7442 SEEK_SET))
7443 {
7444 error (_("Unable to seek to start of dynamic information"));
7445 return 0;
7446 }
7447
7448 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
7449
7450 if (gnubuckets == NULL)
7451 return 0;
7452
7453 for (i = 0; i < ngnubuckets; i++)
7454 if (gnubuckets[i] != 0)
7455 {
7456 if (gnubuckets[i] < symidx)
7457 return 0;
7458
7459 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
7460 maxchain = gnubuckets[i];
7461 }
7462
7463 if (maxchain == 0xffffffff)
7464 return 0;
7465
7466 maxchain -= symidx;
7467
7468 if (fseek (file,
7469 (archive_file_offset
7470 + offset_from_vma (file, buckets_vma
7471 + 4 * (ngnubuckets + maxchain), 4)),
7472 SEEK_SET))
7473 {
7474 error (_("Unable to seek to start of dynamic information"));
7475 return 0;
7476 }
7477
7478 do
7479 {
7480 if (fread (nb, 4, 1, file) != 1)
7481 {
7482 error (_("Failed to determine last chain length\n"));
7483 return 0;
7484 }
7485
7486 if (maxchain + 1 == 0)
7487 return 0;
7488
7489 ++maxchain;
7490 }
7491 while ((byte_get (nb, 4) & 1) == 0);
7492
7493 if (fseek (file,
7494 (archive_file_offset
7495 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
7496 SEEK_SET))
7497 {
7498 error (_("Unable to seek to start of dynamic information"));
7499 return 0;
7500 }
7501
7502 gnuchains = get_dynamic_data (file, maxchain, 4);
7503
7504 if (gnuchains == NULL)
7505 return 0;
7506
7507 lengths = calloc (ngnubuckets, sizeof (*lengths));
7508 if (lengths == NULL)
7509 {
7510 error (_("Out of memory"));
7511 return 0;
7512 }
7513
7514 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
7515 (unsigned long) ngnubuckets);
7516 printf (_(" Length Number %% of total Coverage\n"));
7517
7518 for (hn = 0; hn < ngnubuckets; ++hn)
7519 if (gnubuckets[hn] != 0)
7520 {
7521 bfd_vma off, length = 1;
7522
7523 for (off = gnubuckets[hn] - symidx;
7524 (gnuchains[off] & 1) == 0; ++off)
7525 ++length;
7526 lengths[hn] = length;
7527 if (length > maxlength)
7528 maxlength = length;
7529 nsyms += length;
7530 }
7531
7532 counts = calloc (maxlength + 1, sizeof (*counts));
7533 if (counts == NULL)
7534 {
7535 error (_("Out of memory"));
7536 return 0;
7537 }
7538
7539 for (hn = 0; hn < ngnubuckets; ++hn)
7540 ++counts[lengths[hn]];
7541
7542 if (ngnubuckets > 0)
7543 {
7544 unsigned long j;
7545 printf (" 0 %-10lu (%5.1f%%)\n",
7546 counts[0], (counts[0] * 100.0) / ngnubuckets);
7547 for (j = 1; j <= maxlength; ++j)
7548 {
7549 nzero_counts += counts[j] * j;
7550 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
7551 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
7552 (nzero_counts * 100.0) / nsyms);
7553 }
7554 }
7555
7556 free (counts);
7557 free (lengths);
7558 free (gnubuckets);
7559 free (gnuchains);
7560 }
7561
252b5132
RH
7562 return 1;
7563}
7564
7565static int
d3ba0551 7566process_syminfo (FILE *file ATTRIBUTE_UNUSED)
252b5132 7567{
b4c96d0d 7568 unsigned int i;
252b5132
RH
7569
7570 if (dynamic_syminfo == NULL
7571 || !do_dynamic)
7572 /* No syminfo, this is ok. */
7573 return 1;
7574
7575 /* There better should be a dynamic symbol section. */
7576 if (dynamic_symbols == NULL || dynamic_strings == NULL)
7577 return 0;
7578
7579 if (dynamic_addr)
7580 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
7581 dynamic_syminfo_offset, dynamic_syminfo_nent);
7582
7583 printf (_(" Num: Name BoundTo Flags\n"));
7584 for (i = 0; i < dynamic_syminfo_nent; ++i)
7585 {
7586 unsigned short int flags = dynamic_syminfo[i].si_flags;
7587
31104126 7588 printf ("%4d: ", i);
d79b3d50
NC
7589 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
7590 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
7591 else
7592 printf ("<corrupt: %19ld>", dynamic_symbols[i].st_name);
31104126 7593 putchar (' ');
252b5132
RH
7594
7595 switch (dynamic_syminfo[i].si_boundto)
7596 {
7597 case SYMINFO_BT_SELF:
7598 fputs ("SELF ", stdout);
7599 break;
7600 case SYMINFO_BT_PARENT:
7601 fputs ("PARENT ", stdout);
7602 break;
7603 default:
7604 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
7605 && dynamic_syminfo[i].si_boundto < dynamic_nent
7606 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 7607 {
d79b3d50 7608 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
7609 putchar (' ' );
7610 }
252b5132
RH
7611 else
7612 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
7613 break;
7614 }
7615
7616 if (flags & SYMINFO_FLG_DIRECT)
7617 printf (" DIRECT");
7618 if (flags & SYMINFO_FLG_PASSTHRU)
7619 printf (" PASSTHRU");
7620 if (flags & SYMINFO_FLG_COPY)
7621 printf (" COPY");
7622 if (flags & SYMINFO_FLG_LAZYLOAD)
7623 printf (" LAZYLOAD");
7624
7625 puts ("");
7626 }
7627
7628 return 1;
7629}
7630
7631#ifdef SUPPORT_DISASSEMBLY
18bd398b 7632static int
d3ba0551 7633disassemble_section (Elf_Internal_Shdr *section, FILE *file)
252b5132
RH
7634{
7635 printf (_("\nAssembly dump of section %s\n"),
7636 SECTION_NAME (section));
7637
7638 /* XXX -- to be done --- XXX */
7639
7640 return 1;
7641}
7642#endif
7643
7644static int
d3ba0551 7645dump_section (Elf_Internal_Shdr *section, FILE *file)
252b5132 7646{
b34976b6
AM
7647 bfd_size_type bytes;
7648 bfd_vma addr;
7649 unsigned char *data;
7650 unsigned char *start;
252b5132
RH
7651
7652 bytes = section->sh_size;
7653
e69f2d21 7654 if (bytes == 0 || section->sh_type == SHT_NOBITS)
252b5132
RH
7655 {
7656 printf (_("\nSection '%s' has no data to dump.\n"),
7657 SECTION_NAME (section));
7658 return 0;
7659 }
7660 else
7661 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
7662
7663 addr = section->sh_addr;
7664
c256ffe7
JJ
7665 start = get_data (NULL, file, section->sh_offset, 1, bytes,
7666 _("section data"));
a6e9f9df
AM
7667 if (!start)
7668 return 0;
252b5132
RH
7669
7670 data = start;
7671
7672 while (bytes)
7673 {
7674 int j;
7675 int k;
7676 int lbytes;
7677
7678 lbytes = (bytes > 16 ? 16 : bytes);
7679
148d3c43 7680 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132 7681
20414cab 7682 for (j = 0; j < 16; j++)
252b5132 7683 {
20414cab
AM
7684 if (j < lbytes)
7685 printf ("%2.2x", data[j]);
7686 else
7687 printf (" ");
252b5132 7688
20414cab
AM
7689 if ((j & 3) == 3)
7690 printf (" ");
252b5132
RH
7691 }
7692
7693 for (j = 0; j < lbytes; j++)
7694 {
b34976b6 7695 k = data[j];
9376f0c7 7696 if (k >= ' ' && k < 0x7f)
252b5132
RH
7697 printf ("%c", k);
7698 else
7699 printf (".");
7700 }
7701
7702 putchar ('\n');
7703
7704 data += lbytes;
7705 addr += lbytes;
7706 bytes -= lbytes;
7707 }
7708
7709 free (start);
7710
7711 return 1;
7712}
7713
1007acb3 7714/* Apply addends of RELA relocations. */
d9296b18 7715
1007acb3
L
7716static int
7717debug_apply_rela_addends (void *file,
7718 Elf_Internal_Shdr *section,
7719 unsigned char *start)
d9296b18 7720{
1007acb3
L
7721 Elf_Internal_Shdr *relsec;
7722 unsigned char *end = start + section->sh_size;
7723 /* FIXME: The relocation field size is relocation type dependent. */
7724 unsigned int reloc_size = 4;
18bd398b 7725
1007acb3
L
7726 if (!is_relocatable)
7727 return 1;
d9296b18 7728
1007acb3
L
7729 if (section->sh_size < reloc_size)
7730 return 1;
d9296b18 7731
5b18a4bc
NC
7732 for (relsec = section_headers;
7733 relsec < section_headers + elf_header.e_shnum;
7734 ++relsec)
252b5132 7735 {
5b18a4bc
NC
7736 unsigned long nrelas;
7737 Elf_Internal_Rela *rela, *rp;
7738 Elf_Internal_Shdr *symsec;
7739 Elf_Internal_Sym *symtab;
7740 Elf_Internal_Sym *sym;
252b5132 7741
5b18a4bc 7742 if (relsec->sh_type != SHT_RELA
c256ffe7 7743 || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
5b18a4bc 7744 || SECTION_HEADER (relsec->sh_info) != section
c256ffe7
JJ
7745 || relsec->sh_size == 0
7746 || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum)
5b18a4bc 7747 continue;
428409d5 7748
5b18a4bc
NC
7749 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7750 &rela, &nrelas))
7751 return 0;
428409d5 7752
5b18a4bc
NC
7753 symsec = SECTION_HEADER (relsec->sh_link);
7754 symtab = GET_ELF_SYMBOLS (file, symsec);
103f02d3 7755
5b18a4bc 7756 for (rp = rela; rp < rela + nrelas; ++rp)
252b5132 7757 {
5b18a4bc 7758 unsigned char *loc;
103f02d3 7759
700dd8b7
L
7760 loc = start + rp->r_offset;
7761 if ((loc + reloc_size) > end)
7762 {
7763 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
7764 (unsigned long) rp->r_offset,
7765 SECTION_NAME (section));
7766 continue;
7767 }
103f02d3 7768
5b18a4bc
NC
7769 if (is_32bit_elf)
7770 {
7771 sym = symtab + ELF32_R_SYM (rp->r_info);
103f02d3 7772
5b18a4bc
NC
7773 if (ELF32_R_SYM (rp->r_info) != 0
7774 && ELF32_ST_TYPE (sym->st_info) != STT_SECTION
3b578682
L
7775 /* Relocations against symbols without type can happen.
7776 Gcc -feliminate-dwarf2-dups may generate symbols
7777 without type for debug info. */
7778 && ELF32_ST_TYPE (sym->st_info) != STT_NOTYPE
5b18a4bc
NC
7779 /* Relocations against object symbols can happen,
7780 eg when referencing a global array. For an
7781 example of this see the _clz.o binary in libgcc.a. */
7782 && ELF32_ST_TYPE (sym->st_info) != STT_OBJECT)
7783 {
520494b6 7784 warn (_("skipping unexpected symbol type %s in relocation in section .rela%s\n"),
5b18a4bc
NC
7785 get_symbol_type (ELF32_ST_TYPE (sym->st_info)),
7786 SECTION_NAME (section));
7787 continue;
7788 }
7789 }
7790 else
7791 {
a8b683fc
MR
7792 /* In MIPS little-endian objects, r_info isn't really a
7793 64-bit little-endian value: it has a 32-bit little-endian
7794 symbol index followed by four individual byte fields.
7795 Reorder INFO accordingly. */
7796 if (elf_header.e_machine == EM_MIPS
7797 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
7798 rp->r_info = (((rp->r_info & 0xffffffff) << 32)
7799 | ((rp->r_info >> 56) & 0xff)
7800 | ((rp->r_info >> 40) & 0xff00)
7801 | ((rp->r_info >> 24) & 0xff0000)
7802 | ((rp->r_info >> 8) & 0xff000000));
7803
5b18a4bc 7804 sym = symtab + ELF64_R_SYM (rp->r_info);
0e0c4098 7805
5b18a4bc
NC
7806 if (ELF64_R_SYM (rp->r_info) != 0
7807 && ELF64_ST_TYPE (sym->st_info) != STT_SECTION
3b578682 7808 && ELF64_ST_TYPE (sym->st_info) != STT_NOTYPE
5b18a4bc
NC
7809 && ELF64_ST_TYPE (sym->st_info) != STT_OBJECT)
7810 {
7811 warn (_("skipping unexpected symbol type %s in relocation in section .rela.%s\n"),
7812 get_symbol_type (ELF64_ST_TYPE (sym->st_info)),
7813 SECTION_NAME (section));
7814 continue;
7815 }
7816 }
252b5132 7817
5b18a4bc
NC
7818 byte_put (loc, rp->r_addend, reloc_size);
7819 }
252b5132 7820
5b18a4bc
NC
7821 free (symtab);
7822 free (rela);
7823 break;
7824 }
7825 return 1;
7826}
103f02d3 7827
19e6b90e
L
7828int
7829load_debug_section (enum dwarf_section_display_enum debug, void *file)
1007acb3 7830{
19e6b90e
L
7831 struct dwarf_section *section = &debug_displays [debug].section;
7832 Elf_Internal_Shdr *sec;
7833 char buf [64];
1007acb3 7834
19e6b90e
L
7835 /* If it is already loaded, do nothing. */
7836 if (section->start != NULL)
7837 return 1;
1007acb3 7838
19e6b90e
L
7839 /* Locate the debug section. */
7840 sec = find_section (section->name);
7841 if (sec == NULL)
7842 return 0;
1007acb3 7843
19e6b90e
L
7844 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
7845 section->address = sec->sh_addr;
7846 section->size = sec->sh_size;
7847 section->start = get_data (NULL, file, sec->sh_offset, 1,
7848 sec->sh_size, buf);
1007acb3 7849
19e6b90e
L
7850 if (debug_displays [debug].relocate)
7851 debug_apply_rela_addends (file, sec, section->start);
1007acb3 7852
19e6b90e 7853 return section->start != NULL;
1007acb3
L
7854}
7855
19e6b90e
L
7856void
7857free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 7858{
19e6b90e 7859 struct dwarf_section *section = &debug_displays [debug].section;
1007acb3 7860
19e6b90e
L
7861 if (section->start == NULL)
7862 return;
1007acb3 7863
19e6b90e
L
7864 free ((char *) section->start);
7865 section->start = NULL;
7866 section->address = 0;
7867 section->size = 0;
1007acb3
L
7868}
7869
1007acb3 7870static int
19e6b90e 7871display_debug_section (Elf_Internal_Shdr *section, FILE *file)
1007acb3 7872{
19e6b90e
L
7873 char *name = SECTION_NAME (section);
7874 bfd_size_type length;
7875 int result = 1;
7876 enum dwarf_section_display_enum i;
1007acb3 7877
19e6b90e
L
7878 length = section->sh_size;
7879 if (length == 0)
1007acb3 7880 {
19e6b90e
L
7881 printf (_("\nSection '%s' has no debugging data.\n"), name);
7882 return 0;
1007acb3
L
7883 }
7884
0112cd26 7885 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 7886 name = ".debug_info";
1007acb3 7887
19e6b90e
L
7888 /* See if we know how to display the contents of this section. */
7889 for (i = 0; i < max; i++)
7890 if (streq (debug_displays[i].section.name, name))
7891 {
7892 struct dwarf_section *sec = &debug_displays [i].section;
1007acb3 7893
19e6b90e
L
7894 if (load_debug_section (i, file))
7895 {
7896 result &= debug_displays[i].display (sec, file);
1007acb3 7897
19e6b90e
L
7898 if (i != info && i != abbrev)
7899 free_debug_section (i);
7900 }
1007acb3 7901
19e6b90e
L
7902 break;
7903 }
1007acb3 7904
19e6b90e 7905 if (i == max)
1007acb3 7906 {
19e6b90e
L
7907 printf (_("Unrecognized debug section: %s\n"), name);
7908 result = 0;
1007acb3
L
7909 }
7910
19e6b90e 7911 return result;
5b18a4bc 7912}
103f02d3 7913
aef1f6d0
DJ
7914/* Set DUMP_SECTS for all sections where dumps were requested
7915 based on section name. */
7916
7917static void
7918initialise_dumps_byname (void)
7919{
7920 struct dump_list_entry *cur;
7921
7922 for (cur = dump_sects_byname; cur; cur = cur->next)
7923 {
7924 unsigned int i;
7925 int any;
7926
7927 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
7928 if (streq (SECTION_NAME (section_headers + i), cur->name))
7929 {
7930 request_dump (i, cur->type);
7931 any = 1;
7932 }
7933
7934 if (!any)
7935 warn (_("Section '%s' was not dumped because it does not exist!\n"),
7936 cur->name);
7937 }
7938}
7939
5b18a4bc 7940static void
19e6b90e 7941process_section_contents (FILE *file)
5b18a4bc 7942{
19e6b90e
L
7943 Elf_Internal_Shdr *section;
7944 unsigned int i;
103f02d3 7945
19e6b90e
L
7946 if (! do_dump)
7947 return;
103f02d3 7948
aef1f6d0
DJ
7949 initialise_dumps_byname ();
7950
19e6b90e
L
7951 for (i = 0, section = section_headers;
7952 i < elf_header.e_shnum && i < num_dump_sects;
7953 i++, section++)
7954 {
7955#ifdef SUPPORT_DISASSEMBLY
7956 if (dump_sects[i] & DISASS_DUMP)
7957 disassemble_section (section, file);
7958#endif
7959 if (dump_sects[i] & HEX_DUMP)
7960 dump_section (section, file);
103f02d3 7961
19e6b90e
L
7962 if (dump_sects[i] & DEBUG_DUMP)
7963 display_debug_section (section, file);
5b18a4bc 7964 }
103f02d3 7965
19e6b90e
L
7966 /* Check to see if the user requested a
7967 dump of a section that does not exist. */
7968 while (i++ < num_dump_sects)
7969 if (dump_sects[i])
7970 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 7971}
103f02d3 7972
5b18a4bc 7973static void
19e6b90e 7974process_mips_fpe_exception (int mask)
5b18a4bc 7975{
19e6b90e
L
7976 if (mask)
7977 {
7978 int first = 1;
7979 if (mask & OEX_FPU_INEX)
7980 fputs ("INEX", stdout), first = 0;
7981 if (mask & OEX_FPU_UFLO)
7982 printf ("%sUFLO", first ? "" : "|"), first = 0;
7983 if (mask & OEX_FPU_OFLO)
7984 printf ("%sOFLO", first ? "" : "|"), first = 0;
7985 if (mask & OEX_FPU_DIV0)
7986 printf ("%sDIV0", first ? "" : "|"), first = 0;
7987 if (mask & OEX_FPU_INVAL)
7988 printf ("%sINVAL", first ? "" : "|");
7989 }
5b18a4bc 7990 else
19e6b90e 7991 fputs ("0", stdout);
5b18a4bc 7992}
103f02d3 7993
11c1ff18
PB
7994/* ARM EABI attributes section. */
7995typedef struct
7996{
7997 int tag;
7998 const char *name;
7999 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
8000 int type;
8001 const char **table;
8002} arm_attr_public_tag;
8003
8004static const char *arm_attr_tag_CPU_arch[] =
8005 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
8006 "v6K", "v7"};
8007static const char *arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
8008static const char *arm_attr_tag_THUMB_ISA_use[] =
8009 {"No", "Thumb-1", "Thumb-2"};
14c28b74
JB
8010/* FIXME: VFPv3 encoding was extrapolated! */
8011static const char *arm_attr_tag_VFP_arch[] = {"No", "VFPv1", "VFPv2", "VFPv3"};
11c1ff18
PB
8012static const char *arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1"};
8013static const char *arm_attr_tag_NEON_arch[] = {"No", "NEONv1"};
8014static const char *arm_attr_tag_ABI_PCS_config[] =
8015 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
8016 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
8017static const char *arm_attr_tag_ABI_PCS_R9_use[] =
8018 {"V6", "SB", "TLS", "Unused"};
8019static const char *arm_attr_tag_ABI_PCS_RW_data[] =
8020 {"Absolute", "PC-relative", "SB-relative", "None"};
8021static const char *arm_attr_tag_ABI_PCS_RO_DATA[] =
8022 {"Absolute", "PC-relative", "None"};
8023static const char *arm_attr_tag_ABI_PCS_GOT_use[] =
8024 {"None", "direct", "GOT-indirect"};
8025static const char *arm_attr_tag_ABI_PCS_wchar_t[] =
8026 {"None", "??? 1", "2", "??? 3", "4"};
8027static const char *arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
8028static const char *arm_attr_tag_ABI_FP_denormal[] = {"Unused", "Needed"};
8029static const char *arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
8030static const char *arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
8031static const char *arm_attr_tag_ABI_FP_number_model[] =
8032 {"Unused", "Finite", "RTABI", "IEEE 754"};
8033static const char *arm_attr_tag_ABI_align8_needed[] = {"No", "Yes", "4-byte"};
8034static const char *arm_attr_tag_ABI_align8_preserved[] =
8035 {"No", "Yes, except leaf SP", "Yes"};
8036static const char *arm_attr_tag_ABI_enum_size[] =
8037 {"Unused", "small", "int", "forced to int"};
8038static const char *arm_attr_tag_ABI_HardFP_use[] =
8039 {"As Tag_VFP_arch", "SP only", "DP only", "SP and DP"};
8040static const char *arm_attr_tag_ABI_VFP_args[] =
8041 {"AAPCS", "VFP registers", "custom"};
8042static const char *arm_attr_tag_ABI_WMMX_args[] =
8043 {"AAPCS", "WMMX registers", "custom"};
8044static const char *arm_attr_tag_ABI_optimization_goals[] =
8045 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
8046 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
8047static const char *arm_attr_tag_ABI_FP_optimization_goals[] =
8048 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
8049 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
8050
8051#define LOOKUP(id, name) \
8052 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 8053static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
8054{
8055 {4, "CPU_raw_name", 1, NULL},
8056 {5, "CPU_name", 1, NULL},
8057 LOOKUP(6, CPU_arch),
8058 {7, "CPU_arch_profile", 0, NULL},
8059 LOOKUP(8, ARM_ISA_use),
8060 LOOKUP(9, THUMB_ISA_use),
8061 LOOKUP(10, VFP_arch),
8062 LOOKUP(11, WMMX_arch),
8063 LOOKUP(12, NEON_arch),
8064 LOOKUP(13, ABI_PCS_config),
8065 LOOKUP(14, ABI_PCS_R9_use),
8066 LOOKUP(15, ABI_PCS_RW_data),
8067 LOOKUP(16, ABI_PCS_RO_DATA),
8068 LOOKUP(17, ABI_PCS_GOT_use),
8069 LOOKUP(18, ABI_PCS_wchar_t),
8070 LOOKUP(19, ABI_FP_rounding),
8071 LOOKUP(20, ABI_FP_denormal),
8072 LOOKUP(21, ABI_FP_exceptions),
8073 LOOKUP(22, ABI_FP_user_exceptions),
8074 LOOKUP(23, ABI_FP_number_model),
8075 LOOKUP(24, ABI_align8_needed),
8076 LOOKUP(25, ABI_align8_preserved),
8077 LOOKUP(26, ABI_enum_size),
8078 LOOKUP(27, ABI_HardFP_use),
8079 LOOKUP(28, ABI_VFP_args),
8080 LOOKUP(29, ABI_WMMX_args),
8081 LOOKUP(30, ABI_optimization_goals),
8082 LOOKUP(31, ABI_FP_optimization_goals),
8083 {32, "compatibility", 0, NULL}
8084};
8085#undef LOOKUP
8086
8087/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
8088 bytes read. */
8089static unsigned int
8090read_uleb128 (unsigned char *p, unsigned int *plen)
8091{
8092 unsigned char c;
8093 unsigned int val;
8094 int shift;
8095 int len;
8096
8097 val = 0;
8098 shift = 0;
8099 len = 0;
8100 do
8101 {
8102 c = *(p++);
8103 len++;
8104 val |= ((unsigned int)c & 0x7f) << shift;
8105 shift += 7;
8106 }
8107 while (c & 0x80);
8108
8109 *plen = len;
8110 return val;
8111}
8112
8113static unsigned char *
8114display_arm_attribute (unsigned char *p)
8115{
8116 int tag;
8117 unsigned int len;
8118 int val;
8119 arm_attr_public_tag *attr;
8120 unsigned i;
8121 int type;
8122
8123 tag = read_uleb128 (p, &len);
8124 p += len;
8125 attr = NULL;
8126 for (i = 0; i < ARRAY_SIZE(arm_attr_public_tags); i++)
8127 {
8128 if (arm_attr_public_tags[i].tag == tag)
8129 {
8130 attr = &arm_attr_public_tags[i];
8131 break;
8132 }
8133 }
8134
8135 if (attr)
8136 {
8137 printf (" Tag_%s: ", attr->name);
8138 switch (attr->type)
8139 {
8140 case 0:
8141 switch (tag)
8142 {
8143 case 7: /* Tag_CPU_arch_profile. */
8144 val = read_uleb128 (p, &len);
8145 p += len;
8146 switch (val)
8147 {
8148 case 0: printf ("None\n"); break;
8149 case 'A': printf ("Application\n"); break;
8150 case 'R': printf ("Realtime\n"); break;
8151 case 'M': printf ("Microcontroller\n"); break;
8152 default: printf ("??? (%d)\n", val); break;
8153 }
8154 break;
8155
8156 case 32: /* Tag_compatibility. */
8157 val = read_uleb128 (p, &len);
8158 p += len;
8159 printf ("flag = %d, vendor = %s\n", val, p);
8160 p += strlen((char *)p) + 1;
8161 break;
8162
8163 default:
8164 abort();
8165 }
8166 return p;
8167
8168 case 1:
8169 case 2:
8170 type = attr->type;
8171 break;
8172
8173 default:
8174 assert (attr->type & 0x80);
8175 val = read_uleb128 (p, &len);
8176 p += len;
8177 type = attr->type & 0x7f;
8178 if (val >= type)
8179 printf ("??? (%d)\n", val);
8180 else
8181 printf ("%s\n", attr->table[val]);
8182 return p;
8183 }
8184 }
8185 else
8186 {
8187 if (tag & 1)
8188 type = 1; /* String. */
8189 else
8190 type = 2; /* uleb128. */
8191 printf (" Tag_unknown_%d: ", tag);
8192 }
8193
8194 if (type == 1)
8195 {
8196 printf ("\"%s\"\n", p);
8197 p += strlen((char *)p) + 1;
8198 }
8199 else
8200 {
8201 val = read_uleb128 (p, &len);
8202 p += len;
8203 printf ("%d (0x%x)\n", val, val);
8204 }
8205
8206 return p;
8207}
8208
8209static int
8210process_arm_specific (FILE *file)
8211{
8212 Elf_Internal_Shdr *sect;
8213 unsigned char *contents;
8214 unsigned char *p;
8215 unsigned char *end;
8216 bfd_vma section_len;
8217 bfd_vma len;
8218 unsigned i;
8219
8220 /* Find the section header so that we get the size. */
8221 for (i = 0, sect = section_headers;
8222 i < elf_header.e_shnum;
8223 i++, sect++)
8224 {
8225 if (sect->sh_type != SHT_ARM_ATTRIBUTES)
8226 continue;
8227
8228 contents = get_data (NULL, file, sect->sh_offset, 1, sect->sh_size,
8229 _("attributes"));
d70c5fc7 8230
11c1ff18
PB
8231 if (!contents)
8232 continue;
8233 p = contents;
8234 if (*p == 'A')
8235 {
8236 len = sect->sh_size - 1;
8237 p++;
8238 while (len > 0)
8239 {
8240 int namelen;
8241 bfd_boolean public_section;
8242
8243 section_len = byte_get (p, 4);
8244 p += 4;
8245 if (section_len > len)
8246 {
8247 printf (_("ERROR: Bad section length (%d > %d)\n"),
8248 (int)section_len, (int)len);
8249 section_len = len;
8250 }
8251 len -= section_len;
8252 printf ("Attribute Section: %s\n", p);
8253 if (strcmp ((char *)p, "aeabi") == 0)
8254 public_section = TRUE;
8255 else
8256 public_section = FALSE;
8257 namelen = strlen ((char *)p) + 1;
8258 p += namelen;
8259 section_len -= namelen + 4;
8260 while (section_len > 0)
8261 {
8262 int tag = *(p++);
8263 int val;
8264 bfd_vma size;
8265 size = byte_get (p, 4);
8266 if (size > section_len)
8267 {
8268 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
8269 (int)size, (int)section_len);
8270 size = section_len;
8271 }
8272 section_len -= size;
8273 end = p + size - 1;
8274 p += 4;
8275 switch (tag)
8276 {
8277 case 1:
8278 printf ("File Attributes\n");
8279 break;
8280 case 2:
8281 printf ("Section Attributes:");
8282 goto do_numlist;
8283 case 3:
8284 printf ("Symbol Attributes:");
8285 do_numlist:
8286 for (;;)
8287 {
8288 unsigned int i;
8289 val = read_uleb128 (p, &i);
8290 p += i;
8291 if (val == 0)
8292 break;
8293 printf (" %d", val);
8294 }
8295 printf ("\n");
8296 break;
8297 default:
8298 printf ("Unknown tag: %d\n", tag);
8299 public_section = FALSE;
8300 break;
8301 }
8302 if (public_section)
8303 {
8304 while (p < end)
8305 p = display_arm_attribute(p);
8306 }
8307 else
8308 {
8309 /* ??? Do something sensible, like dump hex. */
8310 printf (" Unknown section contexts\n");
8311 p = end;
8312 }
8313 }
8314 }
8315 }
8316 else
8317 {
8318 printf (_("Unknown format '%c'\n"), *p);
8319 }
d70c5fc7 8320
11c1ff18
PB
8321 free(contents);
8322 }
8323 return 1;
8324}
8325
19e6b90e
L
8326static int
8327process_mips_specific (FILE *file)
5b18a4bc 8328{
19e6b90e
L
8329 Elf_Internal_Dyn *entry;
8330 size_t liblist_offset = 0;
8331 size_t liblistno = 0;
8332 size_t conflictsno = 0;
8333 size_t options_offset = 0;
8334 size_t conflicts_offset = 0;
103f02d3 8335
19e6b90e
L
8336 /* We have a lot of special sections. Thanks SGI! */
8337 if (dynamic_section == NULL)
8338 /* No information available. */
8339 return 0;
252b5132 8340
b2d38a17 8341 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
8342 switch (entry->d_tag)
8343 {
8344 case DT_MIPS_LIBLIST:
d93f0186
NC
8345 liblist_offset
8346 = offset_from_vma (file, entry->d_un.d_val,
8347 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
8348 break;
8349 case DT_MIPS_LIBLISTNO:
8350 liblistno = entry->d_un.d_val;
8351 break;
8352 case DT_MIPS_OPTIONS:
d93f0186 8353 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
8354 break;
8355 case DT_MIPS_CONFLICT:
d93f0186
NC
8356 conflicts_offset
8357 = offset_from_vma (file, entry->d_un.d_val,
8358 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
8359 break;
8360 case DT_MIPS_CONFLICTNO:
8361 conflictsno = entry->d_un.d_val;
8362 break;
8363 default:
8364 break;
8365 }
8366
8367 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
8368 {
b34976b6 8369 Elf32_External_Lib *elib;
252b5132
RH
8370 size_t cnt;
8371
d3ba0551 8372 elib = get_data (NULL, file, liblist_offset,
c256ffe7 8373 liblistno, sizeof (Elf32_External_Lib),
d3ba0551 8374 _("liblist"));
a6e9f9df 8375 if (elib)
252b5132 8376 {
a6e9f9df
AM
8377 printf ("\nSection '.liblist' contains %lu entries:\n",
8378 (unsigned long) liblistno);
8379 fputs (" Library Time Stamp Checksum Version Flags\n",
8380 stdout);
8381
8382 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 8383 {
a6e9f9df
AM
8384 Elf32_Lib liblist;
8385 time_t time;
8386 char timebuf[20];
b34976b6 8387 struct tm *tmp;
a6e9f9df
AM
8388
8389 liblist.l_name = BYTE_GET (elib[cnt].l_name);
8390 time = BYTE_GET (elib[cnt].l_time_stamp);
8391 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
8392 liblist.l_version = BYTE_GET (elib[cnt].l_version);
8393 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
8394
8395 tmp = gmtime (&time);
e9e44622
JJ
8396 snprintf (timebuf, sizeof (timebuf),
8397 "%04u-%02u-%02uT%02u:%02u:%02u",
8398 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8399 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 8400
31104126 8401 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
8402 if (VALID_DYNAMIC_NAME (liblist.l_name))
8403 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
8404 else
8405 printf ("<corrupt: %9ld>", liblist.l_name);
31104126
NC
8406 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
8407 liblist.l_version);
a6e9f9df
AM
8408
8409 if (liblist.l_flags == 0)
8410 puts (" NONE");
8411 else
8412 {
8413 static const struct
252b5132 8414 {
b34976b6 8415 const char *name;
a6e9f9df 8416 int bit;
252b5132 8417 }
a6e9f9df
AM
8418 l_flags_vals[] =
8419 {
8420 { " EXACT_MATCH", LL_EXACT_MATCH },
8421 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
8422 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
8423 { " EXPORTS", LL_EXPORTS },
8424 { " DELAY_LOAD", LL_DELAY_LOAD },
8425 { " DELTA", LL_DELTA }
8426 };
8427 int flags = liblist.l_flags;
8428 size_t fcnt;
8429
8430 for (fcnt = 0;
8431 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
8432 ++fcnt)
8433 if ((flags & l_flags_vals[fcnt].bit) != 0)
8434 {
8435 fputs (l_flags_vals[fcnt].name, stdout);
8436 flags ^= l_flags_vals[fcnt].bit;
8437 }
8438 if (flags != 0)
8439 printf (" %#x", (unsigned int) flags);
252b5132 8440
a6e9f9df
AM
8441 puts ("");
8442 }
252b5132 8443 }
252b5132 8444
a6e9f9df
AM
8445 free (elib);
8446 }
252b5132
RH
8447 }
8448
8449 if (options_offset != 0)
8450 {
b34976b6
AM
8451 Elf_External_Options *eopt;
8452 Elf_Internal_Shdr *sect = section_headers;
8453 Elf_Internal_Options *iopt;
8454 Elf_Internal_Options *option;
252b5132
RH
8455 size_t offset;
8456 int cnt;
8457
8458 /* Find the section header so that we get the size. */
8459 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 8460 ++sect;
252b5132 8461
c256ffe7 8462 eopt = get_data (NULL, file, options_offset, 1, sect->sh_size,
d3ba0551 8463 _("options"));
a6e9f9df 8464 if (eopt)
252b5132 8465 {
c256ffe7 8466 iopt = cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (*iopt));
a6e9f9df
AM
8467 if (iopt == NULL)
8468 {
8469 error (_("Out of memory"));
8470 return 0;
8471 }
76da6bbe 8472
a6e9f9df
AM
8473 offset = cnt = 0;
8474 option = iopt;
252b5132 8475
a6e9f9df
AM
8476 while (offset < sect->sh_size)
8477 {
b34976b6 8478 Elf_External_Options *eoption;
252b5132 8479
a6e9f9df 8480 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 8481
a6e9f9df
AM
8482 option->kind = BYTE_GET (eoption->kind);
8483 option->size = BYTE_GET (eoption->size);
8484 option->section = BYTE_GET (eoption->section);
8485 option->info = BYTE_GET (eoption->info);
76da6bbe 8486
a6e9f9df 8487 offset += option->size;
252b5132 8488
a6e9f9df
AM
8489 ++option;
8490 ++cnt;
8491 }
252b5132 8492
a6e9f9df
AM
8493 printf (_("\nSection '%s' contains %d entries:\n"),
8494 SECTION_NAME (sect), cnt);
76da6bbe 8495
a6e9f9df 8496 option = iopt;
252b5132 8497
a6e9f9df 8498 while (cnt-- > 0)
252b5132 8499 {
a6e9f9df
AM
8500 size_t len;
8501
8502 switch (option->kind)
252b5132 8503 {
a6e9f9df
AM
8504 case ODK_NULL:
8505 /* This shouldn't happen. */
8506 printf (" NULL %d %lx", option->section, option->info);
8507 break;
8508 case ODK_REGINFO:
8509 printf (" REGINFO ");
8510 if (elf_header.e_machine == EM_MIPS)
8511 {
8512 /* 32bit form. */
b34976b6
AM
8513 Elf32_External_RegInfo *ereg;
8514 Elf32_RegInfo reginfo;
a6e9f9df
AM
8515
8516 ereg = (Elf32_External_RegInfo *) (option + 1);
8517 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8518 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8519 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8520 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8521 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8522 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
8523
8524 printf ("GPR %08lx GP 0x%lx\n",
8525 reginfo.ri_gprmask,
8526 (unsigned long) reginfo.ri_gp_value);
8527 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
8528 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8529 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8530 }
8531 else
8532 {
8533 /* 64 bit form. */
b34976b6 8534 Elf64_External_RegInfo *ereg;
a6e9f9df
AM
8535 Elf64_Internal_RegInfo reginfo;
8536
8537 ereg = (Elf64_External_RegInfo *) (option + 1);
8538 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8539 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8540 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8541 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8542 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 8543 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
8544
8545 printf ("GPR %08lx GP 0x",
8546 reginfo.ri_gprmask);
8547 printf_vma (reginfo.ri_gp_value);
8548 printf ("\n");
8549
8550 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
8551 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8552 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8553 }
8554 ++option;
8555 continue;
8556 case ODK_EXCEPTIONS:
8557 fputs (" EXCEPTIONS fpe_min(", stdout);
8558 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
8559 fputs (") fpe_max(", stdout);
8560 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
8561 fputs (")", stdout);
8562
8563 if (option->info & OEX_PAGE0)
8564 fputs (" PAGE0", stdout);
8565 if (option->info & OEX_SMM)
8566 fputs (" SMM", stdout);
8567 if (option->info & OEX_FPDBUG)
8568 fputs (" FPDBUG", stdout);
8569 if (option->info & OEX_DISMISS)
8570 fputs (" DISMISS", stdout);
8571 break;
8572 case ODK_PAD:
8573 fputs (" PAD ", stdout);
8574 if (option->info & OPAD_PREFIX)
8575 fputs (" PREFIX", stdout);
8576 if (option->info & OPAD_POSTFIX)
8577 fputs (" POSTFIX", stdout);
8578 if (option->info & OPAD_SYMBOL)
8579 fputs (" SYMBOL", stdout);
8580 break;
8581 case ODK_HWPATCH:
8582 fputs (" HWPATCH ", stdout);
8583 if (option->info & OHW_R4KEOP)
8584 fputs (" R4KEOP", stdout);
8585 if (option->info & OHW_R8KPFETCH)
8586 fputs (" R8KPFETCH", stdout);
8587 if (option->info & OHW_R5KEOP)
8588 fputs (" R5KEOP", stdout);
8589 if (option->info & OHW_R5KCVTL)
8590 fputs (" R5KCVTL", stdout);
8591 break;
8592 case ODK_FILL:
8593 fputs (" FILL ", stdout);
8594 /* XXX Print content of info word? */
8595 break;
8596 case ODK_TAGS:
8597 fputs (" TAGS ", stdout);
8598 /* XXX Print content of info word? */
8599 break;
8600 case ODK_HWAND:
8601 fputs (" HWAND ", stdout);
8602 if (option->info & OHWA0_R4KEOP_CHECKED)
8603 fputs (" R4KEOP_CHECKED", stdout);
8604 if (option->info & OHWA0_R4KEOP_CLEAN)
8605 fputs (" R4KEOP_CLEAN", stdout);
8606 break;
8607 case ODK_HWOR:
8608 fputs (" HWOR ", stdout);
8609 if (option->info & OHWA0_R4KEOP_CHECKED)
8610 fputs (" R4KEOP_CHECKED", stdout);
8611 if (option->info & OHWA0_R4KEOP_CLEAN)
8612 fputs (" R4KEOP_CLEAN", stdout);
8613 break;
8614 case ODK_GP_GROUP:
8615 printf (" GP_GROUP %#06lx self-contained %#06lx",
8616 option->info & OGP_GROUP,
8617 (option->info & OGP_SELF) >> 16);
8618 break;
8619 case ODK_IDENT:
8620 printf (" IDENT %#06lx self-contained %#06lx",
8621 option->info & OGP_GROUP,
8622 (option->info & OGP_SELF) >> 16);
8623 break;
8624 default:
8625 /* This shouldn't happen. */
8626 printf (" %3d ??? %d %lx",
8627 option->kind, option->section, option->info);
8628 break;
252b5132 8629 }
a6e9f9df 8630
b34976b6 8631 len = sizeof (*eopt);
a6e9f9df
AM
8632 while (len < option->size)
8633 if (((char *) option)[len] >= ' '
8634 && ((char *) option)[len] < 0x7f)
8635 printf ("%c", ((char *) option)[len++]);
8636 else
8637 printf ("\\%03o", ((char *) option)[len++]);
8638
8639 fputs ("\n", stdout);
252b5132 8640 ++option;
252b5132
RH
8641 }
8642
a6e9f9df 8643 free (eopt);
252b5132 8644 }
252b5132
RH
8645 }
8646
8647 if (conflicts_offset != 0 && conflictsno != 0)
8648 {
b34976b6 8649 Elf32_Conflict *iconf;
252b5132
RH
8650 size_t cnt;
8651
8652 if (dynamic_symbols == NULL)
8653 {
3a1a2036 8654 error (_("conflict list found without a dynamic symbol table"));
252b5132
RH
8655 return 0;
8656 }
8657
c256ffe7 8658 iconf = cmalloc (conflictsno, sizeof (*iconf));
252b5132
RH
8659 if (iconf == NULL)
8660 {
8661 error (_("Out of memory"));
8662 return 0;
8663 }
8664
9ea033b2 8665 if (is_32bit_elf)
252b5132 8666 {
b34976b6 8667 Elf32_External_Conflict *econf32;
a6e9f9df 8668
d3ba0551 8669 econf32 = get_data (NULL, file, conflicts_offset,
c256ffe7 8670 conflictsno, sizeof (*econf32), _("conflict"));
a6e9f9df
AM
8671 if (!econf32)
8672 return 0;
252b5132
RH
8673
8674 for (cnt = 0; cnt < conflictsno; ++cnt)
8675 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
8676
8677 free (econf32);
252b5132
RH
8678 }
8679 else
8680 {
b34976b6 8681 Elf64_External_Conflict *econf64;
a6e9f9df 8682
d3ba0551 8683 econf64 = get_data (NULL, file, conflicts_offset,
c256ffe7 8684 conflictsno, sizeof (*econf64), _("conflict"));
a6e9f9df
AM
8685 if (!econf64)
8686 return 0;
252b5132
RH
8687
8688 for (cnt = 0; cnt < conflictsno; ++cnt)
8689 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
8690
8691 free (econf64);
252b5132
RH
8692 }
8693
c7e7ca54
NC
8694 printf (_("\nSection '.conflict' contains %lu entries:\n"),
8695 (unsigned long) conflictsno);
252b5132
RH
8696 puts (_(" Num: Index Value Name"));
8697
8698 for (cnt = 0; cnt < conflictsno; ++cnt)
8699 {
b34976b6 8700 Elf_Internal_Sym *psym = & dynamic_symbols[iconf[cnt]];
252b5132 8701
b34976b6 8702 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 8703 print_vma (psym->st_value, FULL_HEX);
31104126 8704 putchar (' ');
d79b3d50
NC
8705 if (VALID_DYNAMIC_NAME (psym->st_name))
8706 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
8707 else
8708 printf ("<corrupt: %14ld>", psym->st_name);
31104126 8709 putchar ('\n');
252b5132
RH
8710 }
8711
252b5132
RH
8712 free (iconf);
8713 }
8714
8715 return 1;
8716}
8717
047b2264 8718static int
d3ba0551 8719process_gnu_liblist (FILE *file)
047b2264 8720{
b34976b6
AM
8721 Elf_Internal_Shdr *section, *string_sec;
8722 Elf32_External_Lib *elib;
8723 char *strtab;
c256ffe7 8724 size_t strtab_size;
047b2264
JJ
8725 size_t cnt;
8726 unsigned i;
8727
8728 if (! do_arch)
8729 return 0;
8730
8731 for (i = 0, section = section_headers;
8732 i < elf_header.e_shnum;
b34976b6 8733 i++, section++)
047b2264
JJ
8734 {
8735 switch (section->sh_type)
8736 {
8737 case SHT_GNU_LIBLIST:
c256ffe7
JJ
8738 if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum)
8739 break;
8740
8741 elib = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
d3ba0551 8742 _("liblist"));
047b2264
JJ
8743
8744 if (elib == NULL)
8745 break;
8746 string_sec = SECTION_HEADER (section->sh_link);
8747
c256ffe7 8748 strtab = get_data (NULL, file, string_sec->sh_offset, 1,
d3ba0551 8749 string_sec->sh_size, _("liblist string table"));
c256ffe7 8750 strtab_size = string_sec->sh_size;
047b2264
JJ
8751
8752 if (strtab == NULL
8753 || section->sh_entsize != sizeof (Elf32_External_Lib))
8754 {
8755 free (elib);
8756 break;
8757 }
8758
8759 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
8760 SECTION_NAME (section),
8761 (long) (section->sh_size / sizeof (Elf32_External_Lib)));
8762
8763 puts (" Library Time Stamp Checksum Version Flags");
8764
8765 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
8766 ++cnt)
8767 {
8768 Elf32_Lib liblist;
8769 time_t time;
8770 char timebuf[20];
b34976b6 8771 struct tm *tmp;
047b2264
JJ
8772
8773 liblist.l_name = BYTE_GET (elib[cnt].l_name);
8774 time = BYTE_GET (elib[cnt].l_time_stamp);
8775 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
8776 liblist.l_version = BYTE_GET (elib[cnt].l_version);
8777 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
8778
8779 tmp = gmtime (&time);
e9e44622
JJ
8780 snprintf (timebuf, sizeof (timebuf),
8781 "%04u-%02u-%02uT%02u:%02u:%02u",
8782 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8783 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
8784
8785 printf ("%3lu: ", (unsigned long) cnt);
8786 if (do_wide)
c256ffe7
JJ
8787 printf ("%-20s", liblist.l_name < strtab_size
8788 ? strtab + liblist.l_name : "<corrupt>");
047b2264 8789 else
c256ffe7
JJ
8790 printf ("%-20.20s", liblist.l_name < strtab_size
8791 ? strtab + liblist.l_name : "<corrupt>");
047b2264
JJ
8792 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
8793 liblist.l_version, liblist.l_flags);
8794 }
8795
8796 free (elib);
8797 }
8798 }
8799
8800 return 1;
8801}
8802
9437c45b 8803static const char *
d3ba0551 8804get_note_type (unsigned e_type)
779fe533
NC
8805{
8806 static char buff[64];
103f02d3 8807
1ec5cd37
NC
8808 if (elf_header.e_type == ET_CORE)
8809 switch (e_type)
8810 {
57346661 8811 case NT_AUXV:
1ec5cd37 8812 return _("NT_AUXV (auxiliary vector)");
57346661 8813 case NT_PRSTATUS:
1ec5cd37 8814 return _("NT_PRSTATUS (prstatus structure)");
57346661 8815 case NT_FPREGSET:
1ec5cd37 8816 return _("NT_FPREGSET (floating point registers)");
57346661 8817 case NT_PRPSINFO:
1ec5cd37 8818 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 8819 case NT_TASKSTRUCT:
1ec5cd37 8820 return _("NT_TASKSTRUCT (task structure)");
57346661 8821 case NT_PRXFPREG:
1ec5cd37 8822 return _("NT_PRXFPREG (user_xfpregs structure)");
57346661 8823 case NT_PSTATUS:
1ec5cd37 8824 return _("NT_PSTATUS (pstatus structure)");
57346661 8825 case NT_FPREGS:
1ec5cd37 8826 return _("NT_FPREGS (floating point registers)");
57346661 8827 case NT_PSINFO:
1ec5cd37 8828 return _("NT_PSINFO (psinfo structure)");
57346661 8829 case NT_LWPSTATUS:
1ec5cd37 8830 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 8831 case NT_LWPSINFO:
1ec5cd37 8832 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 8833 case NT_WIN32PSTATUS:
1ec5cd37
NC
8834 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
8835 default:
8836 break;
8837 }
8838 else
8839 switch (e_type)
8840 {
8841 case NT_VERSION:
8842 return _("NT_VERSION (version)");
8843 case NT_ARCH:
8844 return _("NT_ARCH (architecture)");
8845 default:
8846 break;
8847 }
8848
e9e44622 8849 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 8850 return buff;
779fe533
NC
8851}
8852
9437c45b 8853static const char *
d3ba0551 8854get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
8855{
8856 static char buff[64];
8857
b4db1224 8858 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
8859 {
8860 /* NetBSD core "procinfo" structure. */
8861 return _("NetBSD procinfo structure");
8862 }
8863
8864 /* As of Jan 2002 there are no other machine-independent notes
8865 defined for NetBSD core files. If the note type is less
8866 than the start of the machine-dependent note types, we don't
8867 understand it. */
8868
b4db1224 8869 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 8870 {
e9e44622 8871 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
8872 return buff;
8873 }
8874
8875 switch (elf_header.e_machine)
8876 {
8877 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
8878 and PT_GETFPREGS == mach+2. */
8879
8880 case EM_OLD_ALPHA:
8881 case EM_ALPHA:
8882 case EM_SPARC:
8883 case EM_SPARC32PLUS:
8884 case EM_SPARCV9:
8885 switch (e_type)
8886 {
b4db1224
JT
8887 case NT_NETBSDCORE_FIRSTMACH+0:
8888 return _("PT_GETREGS (reg structure)");
8889 case NT_NETBSDCORE_FIRSTMACH+2:
8890 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
8891 default:
8892 break;
8893 }
8894 break;
8895
8896 /* On all other arch's, PT_GETREGS == mach+1 and
8897 PT_GETFPREGS == mach+3. */
8898 default:
8899 switch (e_type)
8900 {
b4db1224
JT
8901 case NT_NETBSDCORE_FIRSTMACH+1:
8902 return _("PT_GETREGS (reg structure)");
8903 case NT_NETBSDCORE_FIRSTMACH+3:
8904 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
8905 default:
8906 break;
8907 }
8908 }
8909
e9e44622
JJ
8910 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
8911 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
8912 return buff;
8913}
8914
6d118b09
NC
8915/* Note that by the ELF standard, the name field is already null byte
8916 terminated, and namesz includes the terminating null byte.
8917 I.E. the value of namesz for the name "FSF" is 4.
8918
e3c8793a 8919 If the value of namesz is zero, there is no name present. */
779fe533 8920static int
d3ba0551 8921process_note (Elf_Internal_Note *pnote)
779fe533 8922{
9437c45b
JT
8923 const char *nt;
8924
8925 if (pnote->namesz == 0)
1ec5cd37
NC
8926 /* If there is no note name, then use the default set of
8927 note type strings. */
8928 nt = get_note_type (pnote->type);
8929
0112cd26 8930 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
8931 /* NetBSD-specific core file notes. */
8932 nt = get_netbsd_elfcore_note_type (pnote->type);
8933
9437c45b 8934 else
1ec5cd37
NC
8935 /* Don't recognize this note name; just use the default set of
8936 note type strings. */
9437c45b 8937 nt = get_note_type (pnote->type);
9437c45b 8938
103f02d3 8939 printf (" %s\t\t0x%08lx\t%s\n",
6d118b09 8940 pnote->namesz ? pnote->namedata : "(NONE)",
9437c45b 8941 pnote->descsz, nt);
779fe533
NC
8942 return 1;
8943}
8944
6d118b09 8945
779fe533 8946static int
d3ba0551 8947process_corefile_note_segment (FILE *file, bfd_vma offset, bfd_vma length)
779fe533 8948{
b34976b6
AM
8949 Elf_External_Note *pnotes;
8950 Elf_External_Note *external;
8951 int res = 1;
103f02d3 8952
779fe533
NC
8953 if (length <= 0)
8954 return 0;
103f02d3 8955
c256ffe7 8956 pnotes = get_data (NULL, file, offset, 1, length, _("notes"));
a6e9f9df
AM
8957 if (!pnotes)
8958 return 0;
779fe533 8959
103f02d3 8960 external = pnotes;
103f02d3 8961
305c7206 8962 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 8963 (unsigned long) offset, (unsigned long) length);
779fe533 8964 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 8965
6d118b09 8966 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 8967 {
b34976b6
AM
8968 Elf_External_Note *next;
8969 Elf_Internal_Note inote;
8970 char *temp = NULL;
6d118b09
NC
8971
8972 inote.type = BYTE_GET (external->type);
8973 inote.namesz = BYTE_GET (external->namesz);
8974 inote.namedata = external->name;
8975 inote.descsz = BYTE_GET (external->descsz);
8976 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
8977 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 8978
3e55a963
NC
8979 next = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
8980
8981 if (((char *) next) > (((char *) pnotes) + length))
8982 {
0fd3a477
JW
8983 warn (_("corrupt note found at offset %lx into core notes\n"),
8984 (long)((char *)external - (char *)pnotes));
8985 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
8986 inote.type, inote.namesz, inote.descsz);
8987 break;
8988 }
8989
8990 external = next;
6d118b09
NC
8991
8992 /* Verify that name is null terminated. It appears that at least
8993 one version of Linux (RedHat 6.0) generates corefiles that don't
8994 comply with the ELF spec by failing to include the null byte in
8995 namesz. */
8996 if (inote.namedata[inote.namesz] != '\0')
8997 {
8998 temp = malloc (inote.namesz + 1);
76da6bbe 8999
6d118b09
NC
9000 if (temp == NULL)
9001 {
9002 error (_("Out of memory\n"));
9003 res = 0;
9004 break;
9005 }
76da6bbe 9006
6d118b09
NC
9007 strncpy (temp, inote.namedata, inote.namesz);
9008 temp[inote.namesz] = 0;
76da6bbe 9009
6d118b09
NC
9010 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
9011 inote.namedata = temp;
9012 }
9013
9014 res &= process_note (& inote);
103f02d3 9015
6d118b09
NC
9016 if (temp != NULL)
9017 {
9018 free (temp);
9019 temp = NULL;
9020 }
779fe533
NC
9021 }
9022
9023 free (pnotes);
103f02d3 9024
779fe533
NC
9025 return res;
9026}
9027
9028static int
d3ba0551 9029process_corefile_note_segments (FILE *file)
779fe533 9030{
b34976b6
AM
9031 Elf_Internal_Phdr *segment;
9032 unsigned int i;
9033 int res = 1;
103f02d3 9034
d93f0186 9035 if (! get_program_headers (file))
779fe533 9036 return 0;
103f02d3 9037
779fe533
NC
9038 for (i = 0, segment = program_headers;
9039 i < elf_header.e_phnum;
b34976b6 9040 i++, segment++)
779fe533
NC
9041 {
9042 if (segment->p_type == PT_NOTE)
103f02d3 9043 res &= process_corefile_note_segment (file,
30800947
NC
9044 (bfd_vma) segment->p_offset,
9045 (bfd_vma) segment->p_filesz);
779fe533 9046 }
103f02d3 9047
779fe533
NC
9048 return res;
9049}
9050
9051static int
1ec5cd37
NC
9052process_note_sections (FILE *file)
9053{
9054 Elf_Internal_Shdr *section;
9055 unsigned long i;
9056 int res = 1;
9057
9058 for (i = 0, section = section_headers;
9059 i < elf_header.e_shnum;
9060 i++, section++)
9061 if (section->sh_type == SHT_NOTE)
9062 res &= process_corefile_note_segment (file,
9063 (bfd_vma) section->sh_offset,
9064 (bfd_vma) section->sh_size);
9065
9066 return res;
9067}
9068
9069static int
9070process_notes (FILE *file)
779fe533
NC
9071{
9072 /* If we have not been asked to display the notes then do nothing. */
9073 if (! do_notes)
9074 return 1;
103f02d3 9075
779fe533 9076 if (elf_header.e_type != ET_CORE)
1ec5cd37 9077 return process_note_sections (file);
103f02d3 9078
779fe533 9079 /* No program headers means no NOTE segment. */
1ec5cd37
NC
9080 if (elf_header.e_phnum > 0)
9081 return process_corefile_note_segments (file);
779fe533 9082
1ec5cd37
NC
9083 printf (_("No note segments present in the core file.\n"));
9084 return 1;
779fe533
NC
9085}
9086
252b5132 9087static int
d3ba0551 9088process_arch_specific (FILE *file)
252b5132 9089{
a952a375
NC
9090 if (! do_arch)
9091 return 1;
9092
252b5132
RH
9093 switch (elf_header.e_machine)
9094 {
11c1ff18
PB
9095 case EM_ARM:
9096 return process_arm_specific (file);
252b5132 9097 case EM_MIPS:
4fe85591 9098 case EM_MIPS_RS3_LE:
252b5132
RH
9099 return process_mips_specific (file);
9100 break;
9101 default:
9102 break;
9103 }
9104 return 1;
9105}
9106
9107static int
d3ba0551 9108get_file_header (FILE *file)
252b5132 9109{
9ea033b2
NC
9110 /* Read in the identity array. */
9111 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
9112 return 0;
9113
9ea033b2 9114 /* Determine how to read the rest of the header. */
b34976b6 9115 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
9116 {
9117 default: /* fall through */
9118 case ELFDATANONE: /* fall through */
adab8cdc
AO
9119 case ELFDATA2LSB:
9120 byte_get = byte_get_little_endian;
9121 byte_put = byte_put_little_endian;
9122 break;
9123 case ELFDATA2MSB:
9124 byte_get = byte_get_big_endian;
9125 byte_put = byte_put_big_endian;
9126 break;
9ea033b2
NC
9127 }
9128
9129 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 9130 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
9131
9132 /* Read in the rest of the header. */
9133 if (is_32bit_elf)
9134 {
9135 Elf32_External_Ehdr ehdr32;
252b5132 9136
9ea033b2
NC
9137 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
9138 return 0;
103f02d3 9139
9ea033b2
NC
9140 elf_header.e_type = BYTE_GET (ehdr32.e_type);
9141 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
9142 elf_header.e_version = BYTE_GET (ehdr32.e_version);
9143 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
9144 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
9145 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
9146 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
9147 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
9148 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
9149 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
9150 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
9151 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
9152 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9153 }
252b5132 9154 else
9ea033b2
NC
9155 {
9156 Elf64_External_Ehdr ehdr64;
a952a375
NC
9157
9158 /* If we have been compiled with sizeof (bfd_vma) == 4, then
9159 we will not be able to cope with the 64bit data found in
9160 64 ELF files. Detect this now and abort before we start
50c2245b 9161 overwriting things. */
a952a375
NC
9162 if (sizeof (bfd_vma) < 8)
9163 {
e3c8793a
NC
9164 error (_("This instance of readelf has been built without support for a\n\
916564 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
9166 return 0;
9167 }
103f02d3 9168
9ea033b2
NC
9169 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
9170 return 0;
103f02d3 9171
9ea033b2
NC
9172 elf_header.e_type = BYTE_GET (ehdr64.e_type);
9173 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
9174 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
9175 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
9176 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
9177 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
9178 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
9179 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
9180 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
9181 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
9182 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
9183 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
9184 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9185 }
252b5132 9186
7ece0d85
JJ
9187 if (elf_header.e_shoff)
9188 {
9189 /* There may be some extensions in the first section header. Don't
9190 bomb if we can't read it. */
9191 if (is_32bit_elf)
9192 get_32bit_section_headers (file, 1);
9193 else
9194 get_64bit_section_headers (file, 1);
9195 }
560f3c1c 9196
1007acb3
L
9197 is_relocatable = elf_header.e_type == ET_REL;
9198
252b5132
RH
9199 return 1;
9200}
9201
fb52b2f4
NC
9202/* Process one ELF object file according to the command line options.
9203 This file may actually be stored in an archive. The file is
9204 positioned at the start of the ELF object. */
9205
ff78d6d6 9206static int
fb52b2f4 9207process_object (char *file_name, FILE *file)
252b5132 9208{
252b5132
RH
9209 unsigned int i;
9210
252b5132
RH
9211 if (! get_file_header (file))
9212 {
9213 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 9214 return 1;
252b5132
RH
9215 }
9216
9217 /* Initialise per file variables. */
9218 for (i = NUM_ELEM (version_info); i--;)
9219 version_info[i] = 0;
9220
9221 for (i = NUM_ELEM (dynamic_info); i--;)
9222 dynamic_info[i] = 0;
9223
9224 /* Process the file. */
9225 if (show_name)
9226 printf (_("\nFile: %s\n"), file_name);
9227
18bd398b
NC
9228 /* Initialise the dump_sects array from the cmdline_dump_sects array.
9229 Note we do this even if cmdline_dump_sects is empty because we
9230 must make sure that the dump_sets array is zeroed out before each
9231 object file is processed. */
9232 if (num_dump_sects > num_cmdline_dump_sects)
9233 memset (dump_sects, 0, num_dump_sects);
9234
9235 if (num_cmdline_dump_sects > 0)
9236 {
9237 if (num_dump_sects == 0)
9238 /* A sneaky way of allocating the dump_sects array. */
9239 request_dump (num_cmdline_dump_sects, 0);
9240
9241 assert (num_dump_sects >= num_cmdline_dump_sects);
9242 memcpy (dump_sects, cmdline_dump_sects, num_cmdline_dump_sects);
9243 }
d70c5fc7 9244
252b5132 9245 if (! process_file_header ())
fb52b2f4 9246 return 1;
252b5132 9247
d1f5c6e3 9248 if (! process_section_headers (file))
2f62977e 9249 {
d1f5c6e3
L
9250 /* Without loaded section headers we cannot process lots of
9251 things. */
2f62977e 9252 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 9253
2f62977e
NC
9254 if (! do_using_dynamic)
9255 do_syms = do_reloc = 0;
9256 }
252b5132 9257
d1f5c6e3
L
9258 if (! process_section_groups (file))
9259 {
9260 /* Without loaded section groups we cannot process unwind. */
9261 do_unwind = 0;
9262 }
9263
2f62977e 9264 if (process_program_headers (file))
b2d38a17 9265 process_dynamic_section (file);
252b5132
RH
9266
9267 process_relocs (file);
9268
4d6ed7c8
NC
9269 process_unwind (file);
9270
252b5132
RH
9271 process_symbol_table (file);
9272
9273 process_syminfo (file);
9274
9275 process_version_sections (file);
9276
9277 process_section_contents (file);
f5842774 9278
1ec5cd37 9279 process_notes (file);
103f02d3 9280
047b2264
JJ
9281 process_gnu_liblist (file);
9282
252b5132
RH
9283 process_arch_specific (file);
9284
d93f0186
NC
9285 if (program_headers)
9286 {
9287 free (program_headers);
9288 program_headers = NULL;
9289 }
9290
252b5132
RH
9291 if (section_headers)
9292 {
9293 free (section_headers);
9294 section_headers = NULL;
9295 }
9296
9297 if (string_table)
9298 {
9299 free (string_table);
9300 string_table = NULL;
d40ac9bd 9301 string_table_length = 0;
252b5132
RH
9302 }
9303
9304 if (dynamic_strings)
9305 {
9306 free (dynamic_strings);
9307 dynamic_strings = NULL;
d79b3d50 9308 dynamic_strings_length = 0;
252b5132
RH
9309 }
9310
9311 if (dynamic_symbols)
9312 {
9313 free (dynamic_symbols);
9314 dynamic_symbols = NULL;
19936277 9315 num_dynamic_syms = 0;
252b5132
RH
9316 }
9317
9318 if (dynamic_syminfo)
9319 {
9320 free (dynamic_syminfo);
9321 dynamic_syminfo = NULL;
9322 }
ff78d6d6 9323
e4b17d5c
L
9324 if (section_headers_groups)
9325 {
9326 free (section_headers_groups);
9327 section_headers_groups = NULL;
9328 }
9329
9330 if (section_groups)
9331 {
9332 struct group_list *g, *next;
9333
9334 for (i = 0; i < group_count; i++)
9335 {
9336 for (g = section_groups [i].root; g != NULL; g = next)
9337 {
9338 next = g->next;
9339 free (g);
9340 }
9341 }
9342
9343 free (section_groups);
9344 section_groups = NULL;
9345 }
9346
19e6b90e 9347 free_debug_memory ();
18bd398b 9348
ff78d6d6 9349 return 0;
252b5132
RH
9350}
9351
fb52b2f4
NC
9352/* Process an ELF archive. The file is positioned just after the
9353 ARMAG string. */
9354
9355static int
9356process_archive (char *file_name, FILE *file)
9357{
9358 struct ar_hdr arhdr;
9359 size_t got;
9360 unsigned long size;
9361 char *longnames = NULL;
9362 unsigned long longnames_size = 0;
9363 size_t file_name_size;
d989285c 9364 int ret;
fb52b2f4
NC
9365
9366 show_name = 1;
9367
9368 got = fread (&arhdr, 1, sizeof arhdr, file);
9369 if (got != sizeof arhdr)
9370 {
9371 if (got == 0)
9372 return 0;
9373
9374 error (_("%s: failed to read archive header\n"), file_name);
9375 return 1;
9376 }
9377
0112cd26 9378 if (const_strneq (arhdr.ar_name, "/ "))
fb52b2f4
NC
9379 {
9380 /* This is the archive symbol table. Skip it.
9381 FIXME: We should have an option to dump it. */
9382 size = strtoul (arhdr.ar_size, NULL, 10);
9383 if (fseek (file, size + (size & 1), SEEK_CUR) != 0)
9384 {
9385 error (_("%s: failed to skip archive symbol table\n"), file_name);
9386 return 1;
9387 }
9388
9389 got = fread (&arhdr, 1, sizeof arhdr, file);
9390 if (got != sizeof arhdr)
9391 {
9392 if (got == 0)
9393 return 0;
9394
9395 error (_("%s: failed to read archive header\n"), file_name);
9396 return 1;
9397 }
9398 }
9399
0112cd26 9400 if (const_strneq (arhdr.ar_name, "// "))
fb52b2f4
NC
9401 {
9402 /* This is the archive string table holding long member
9403 names. */
9404
9405 longnames_size = strtoul (arhdr.ar_size, NULL, 10);
9406
9407 longnames = malloc (longnames_size);
9408 if (longnames == NULL)
9409 {
9410 error (_("Out of memory\n"));
9411 return 1;
9412 }
9413
9414 if (fread (longnames, longnames_size, 1, file) != 1)
9415 {
d989285c 9416 free (longnames);
18bd398b 9417 error (_("%s: failed to read string table\n"), file_name);
fb52b2f4
NC
9418 return 1;
9419 }
9420
9421 if ((longnames_size & 1) != 0)
9422 getc (file);
9423
9424 got = fread (&arhdr, 1, sizeof arhdr, file);
9425 if (got != sizeof arhdr)
9426 {
d989285c
ILT
9427 free (longnames);
9428
fb52b2f4
NC
9429 if (got == 0)
9430 return 0;
9431
9432 error (_("%s: failed to read archive header\n"), file_name);
9433 return 1;
9434 }
9435 }
9436
9437 file_name_size = strlen (file_name);
d989285c 9438 ret = 0;
fb52b2f4
NC
9439
9440 while (1)
9441 {
9442 char *name;
9443 char *nameend;
9444 char *namealc;
9445
9446 if (arhdr.ar_name[0] == '/')
9447 {
9448 unsigned long off;
9449
9450 off = strtoul (arhdr.ar_name + 1, NULL, 10);
9451 if (off >= longnames_size)
9452 {
0fd3a477 9453 error (_("%s: invalid archive string table offset %lu\n"), file_name, off);
d989285c
ILT
9454 ret = 1;
9455 break;
fb52b2f4
NC
9456 }
9457
9458 name = longnames + off;
9459 nameend = memchr (name, '/', longnames_size - off);
9460 }
9461 else
9462 {
9463 name = arhdr.ar_name;
9464 nameend = memchr (name, '/', 16);
9465 }
9466
9467 if (nameend == NULL)
9468 {
0fd3a477 9469 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
9470 ret = 1;
9471 break;
fb52b2f4
NC
9472 }
9473
9474 namealc = malloc (file_name_size + (nameend - name) + 3);
9475 if (namealc == NULL)
9476 {
9477 error (_("Out of memory\n"));
d989285c
ILT
9478 ret = 1;
9479 break;
fb52b2f4
NC
9480 }
9481
9482 memcpy (namealc, file_name, file_name_size);
9483 namealc[file_name_size] = '(';
9484 memcpy (namealc + file_name_size + 1, name, nameend - name);
9485 namealc[file_name_size + 1 + (nameend - name)] = ')';
9486 namealc[file_name_size + 2 + (nameend - name)] = '\0';
9487
9488 archive_file_offset = ftell (file);
9489 archive_file_size = strtoul (arhdr.ar_size, NULL, 10);
d70c5fc7 9490
d989285c 9491 ret |= process_object (namealc, file);
fb52b2f4
NC
9492
9493 free (namealc);
9494
9495 if (fseek (file,
9496 (archive_file_offset
9497 + archive_file_size
9498 + (archive_file_size & 1)),
9499 SEEK_SET) != 0)
9500 {
9501 error (_("%s: failed to seek to next archive header\n"), file_name);
d989285c
ILT
9502 ret = 1;
9503 break;
fb52b2f4
NC
9504 }
9505
9506 got = fread (&arhdr, 1, sizeof arhdr, file);
9507 if (got != sizeof arhdr)
9508 {
9509 if (got == 0)
d989285c 9510 break;
fb52b2f4
NC
9511
9512 error (_("%s: failed to read archive header\n"), file_name);
d989285c
ILT
9513 ret = 1;
9514 break;
fb52b2f4
NC
9515 }
9516 }
9517
9518 if (longnames != 0)
9519 free (longnames);
9520
d989285c 9521 return ret;
fb52b2f4
NC
9522}
9523
9524static int
9525process_file (char *file_name)
9526{
9527 FILE *file;
9528 struct stat statbuf;
9529 char armag[SARMAG];
9530 int ret;
9531
9532 if (stat (file_name, &statbuf) < 0)
9533 {
f24ddbdd
NC
9534 if (errno == ENOENT)
9535 error (_("'%s': No such file\n"), file_name);
9536 else
9537 error (_("Could not locate '%s'. System error message: %s\n"),
9538 file_name, strerror (errno));
9539 return 1;
9540 }
9541
9542 if (! S_ISREG (statbuf.st_mode))
9543 {
9544 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
9545 return 1;
9546 }
9547
9548 file = fopen (file_name, "rb");
9549 if (file == NULL)
9550 {
f24ddbdd 9551 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
9552 return 1;
9553 }
9554
9555 if (fread (armag, SARMAG, 1, file) != 1)
9556 {
9557 error (_("%s: Failed to read file header\n"), file_name);
9558 fclose (file);
9559 return 1;
9560 }
9561
9562 if (memcmp (armag, ARMAG, SARMAG) == 0)
9563 ret = process_archive (file_name, file);
9564 else
9565 {
9566 rewind (file);
9567 archive_file_size = archive_file_offset = 0;
9568 ret = process_object (file_name, file);
9569 }
9570
9571 fclose (file);
9572
9573 return ret;
9574}
9575
252b5132
RH
9576#ifdef SUPPORT_DISASSEMBLY
9577/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 9578 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 9579 symbols. */
252b5132
RH
9580
9581void
b34976b6 9582print_address (unsigned int addr, FILE *outfile)
252b5132
RH
9583{
9584 fprintf (outfile,"0x%8.8x", addr);
9585}
9586
e3c8793a 9587/* Needed by the i386 disassembler. */
252b5132
RH
9588void
9589db_task_printsym (unsigned int addr)
9590{
9591 print_address (addr, stderr);
9592}
9593#endif
9594
9595int
d3ba0551 9596main (int argc, char **argv)
252b5132 9597{
ff78d6d6
L
9598 int err;
9599
252b5132
RH
9600#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
9601 setlocale (LC_MESSAGES, "");
3882b010
L
9602#endif
9603#if defined (HAVE_SETLOCALE)
9604 setlocale (LC_CTYPE, "");
252b5132
RH
9605#endif
9606 bindtextdomain (PACKAGE, LOCALEDIR);
9607 textdomain (PACKAGE);
9608
869b9d07
MM
9609 expandargv (&argc, &argv);
9610
252b5132
RH
9611 parse_args (argc, argv);
9612
18bd398b 9613 if (num_dump_sects > 0)
59f14fc0 9614 {
18bd398b 9615 /* Make a copy of the dump_sects array. */
59f14fc0
AS
9616 cmdline_dump_sects = malloc (num_dump_sects);
9617 if (cmdline_dump_sects == NULL)
9618 error (_("Out of memory allocating dump request table."));
9619 else
9620 {
9621 memcpy (cmdline_dump_sects, dump_sects, num_dump_sects);
9622 num_cmdline_dump_sects = num_dump_sects;
9623 }
9624 }
9625
18bd398b
NC
9626 if (optind < (argc - 1))
9627 show_name = 1;
9628
ff78d6d6 9629 err = 0;
252b5132 9630 while (optind < argc)
18bd398b 9631 err |= process_file (argv[optind++]);
252b5132
RH
9632
9633 if (dump_sects != NULL)
9634 free (dump_sects);
59f14fc0
AS
9635 if (cmdline_dump_sects != NULL)
9636 free (cmdline_dump_sects);
252b5132 9637
ff78d6d6 9638 return err;
252b5132 9639}