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