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