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