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