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