]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
merge from gcc
[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
3b578682
L
7750 /* Relocations against symbols without type can happen.
7751 Gcc -feliminate-dwarf2-dups may generate symbols
7752 without type for debug info. */
7753 && ELF32_ST_TYPE (sym->st_info) != STT_NOTYPE
5b18a4bc
NC
7754 /* Relocations against object symbols can happen,
7755 eg when referencing a global array. For an
7756 example of this see the _clz.o binary in libgcc.a. */
7757 && ELF32_ST_TYPE (sym->st_info) != STT_OBJECT)
7758 {
520494b6 7759 warn (_("skipping unexpected symbol type %s in relocation in section .rela%s\n"),
5b18a4bc
NC
7760 get_symbol_type (ELF32_ST_TYPE (sym->st_info)),
7761 SECTION_NAME (section));
7762 continue;
7763 }
7764 }
7765 else
7766 {
a8b683fc
MR
7767 /* In MIPS little-endian objects, r_info isn't really a
7768 64-bit little-endian value: it has a 32-bit little-endian
7769 symbol index followed by four individual byte fields.
7770 Reorder INFO accordingly. */
7771 if (elf_header.e_machine == EM_MIPS
7772 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
7773 rp->r_info = (((rp->r_info & 0xffffffff) << 32)
7774 | ((rp->r_info >> 56) & 0xff)
7775 | ((rp->r_info >> 40) & 0xff00)
7776 | ((rp->r_info >> 24) & 0xff0000)
7777 | ((rp->r_info >> 8) & 0xff000000));
7778
5b18a4bc 7779 sym = symtab + ELF64_R_SYM (rp->r_info);
0e0c4098 7780
5b18a4bc
NC
7781 if (ELF64_R_SYM (rp->r_info) != 0
7782 && ELF64_ST_TYPE (sym->st_info) != STT_SECTION
3b578682 7783 && ELF64_ST_TYPE (sym->st_info) != STT_NOTYPE
5b18a4bc
NC
7784 && ELF64_ST_TYPE (sym->st_info) != STT_OBJECT)
7785 {
7786 warn (_("skipping unexpected symbol type %s in relocation in section .rela.%s\n"),
7787 get_symbol_type (ELF64_ST_TYPE (sym->st_info)),
7788 SECTION_NAME (section));
7789 continue;
7790 }
7791 }
252b5132 7792
5b18a4bc
NC
7793 byte_put (loc, rp->r_addend, reloc_size);
7794 }
252b5132 7795
5b18a4bc
NC
7796 free (symtab);
7797 free (rela);
7798 break;
7799 }
7800 return 1;
7801}
103f02d3 7802
19e6b90e
L
7803int
7804load_debug_section (enum dwarf_section_display_enum debug, void *file)
1007acb3 7805{
19e6b90e
L
7806 struct dwarf_section *section = &debug_displays [debug].section;
7807 Elf_Internal_Shdr *sec;
7808 char buf [64];
1007acb3 7809
19e6b90e
L
7810 /* If it is already loaded, do nothing. */
7811 if (section->start != NULL)
7812 return 1;
1007acb3 7813
19e6b90e
L
7814 /* Locate the debug section. */
7815 sec = find_section (section->name);
7816 if (sec == NULL)
7817 return 0;
1007acb3 7818
19e6b90e
L
7819 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
7820 section->address = sec->sh_addr;
7821 section->size = sec->sh_size;
7822 section->start = get_data (NULL, file, sec->sh_offset, 1,
7823 sec->sh_size, buf);
1007acb3 7824
19e6b90e
L
7825 if (debug_displays [debug].relocate)
7826 debug_apply_rela_addends (file, sec, section->start);
1007acb3 7827
19e6b90e 7828 return section->start != NULL;
1007acb3
L
7829}
7830
19e6b90e
L
7831void
7832free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 7833{
19e6b90e 7834 struct dwarf_section *section = &debug_displays [debug].section;
1007acb3 7835
19e6b90e
L
7836 if (section->start == NULL)
7837 return;
1007acb3 7838
19e6b90e
L
7839 free ((char *) section->start);
7840 section->start = NULL;
7841 section->address = 0;
7842 section->size = 0;
1007acb3
L
7843}
7844
1007acb3 7845static int
19e6b90e 7846display_debug_section (Elf_Internal_Shdr *section, FILE *file)
1007acb3 7847{
19e6b90e
L
7848 char *name = SECTION_NAME (section);
7849 bfd_size_type length;
7850 int result = 1;
7851 enum dwarf_section_display_enum i;
1007acb3 7852
19e6b90e
L
7853 length = section->sh_size;
7854 if (length == 0)
1007acb3 7855 {
19e6b90e
L
7856 printf (_("\nSection '%s' has no debugging data.\n"), name);
7857 return 0;
1007acb3
L
7858 }
7859
0112cd26 7860 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 7861 name = ".debug_info";
1007acb3 7862
19e6b90e
L
7863 /* See if we know how to display the contents of this section. */
7864 for (i = 0; i < max; i++)
7865 if (streq (debug_displays[i].section.name, name))
7866 {
7867 struct dwarf_section *sec = &debug_displays [i].section;
1007acb3 7868
19e6b90e
L
7869 if (load_debug_section (i, file))
7870 {
7871 result &= debug_displays[i].display (sec, file);
1007acb3 7872
19e6b90e
L
7873 if (i != info && i != abbrev)
7874 free_debug_section (i);
7875 }
1007acb3 7876
19e6b90e
L
7877 break;
7878 }
1007acb3 7879
19e6b90e 7880 if (i == max)
1007acb3 7881 {
19e6b90e
L
7882 printf (_("Unrecognized debug section: %s\n"), name);
7883 result = 0;
1007acb3
L
7884 }
7885
19e6b90e 7886 return result;
5b18a4bc 7887}
103f02d3 7888
aef1f6d0
DJ
7889/* Set DUMP_SECTS for all sections where dumps were requested
7890 based on section name. */
7891
7892static void
7893initialise_dumps_byname (void)
7894{
7895 struct dump_list_entry *cur;
7896
7897 for (cur = dump_sects_byname; cur; cur = cur->next)
7898 {
7899 unsigned int i;
7900 int any;
7901
7902 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
7903 if (streq (SECTION_NAME (section_headers + i), cur->name))
7904 {
7905 request_dump (i, cur->type);
7906 any = 1;
7907 }
7908
7909 if (!any)
7910 warn (_("Section '%s' was not dumped because it does not exist!\n"),
7911 cur->name);
7912 }
7913}
7914
5b18a4bc 7915static void
19e6b90e 7916process_section_contents (FILE *file)
5b18a4bc 7917{
19e6b90e
L
7918 Elf_Internal_Shdr *section;
7919 unsigned int i;
103f02d3 7920
19e6b90e
L
7921 if (! do_dump)
7922 return;
103f02d3 7923
aef1f6d0
DJ
7924 initialise_dumps_byname ();
7925
19e6b90e
L
7926 for (i = 0, section = section_headers;
7927 i < elf_header.e_shnum && i < num_dump_sects;
7928 i++, section++)
7929 {
7930#ifdef SUPPORT_DISASSEMBLY
7931 if (dump_sects[i] & DISASS_DUMP)
7932 disassemble_section (section, file);
7933#endif
7934 if (dump_sects[i] & HEX_DUMP)
7935 dump_section (section, file);
103f02d3 7936
19e6b90e
L
7937 if (dump_sects[i] & DEBUG_DUMP)
7938 display_debug_section (section, file);
5b18a4bc 7939 }
103f02d3 7940
19e6b90e
L
7941 /* Check to see if the user requested a
7942 dump of a section that does not exist. */
7943 while (i++ < num_dump_sects)
7944 if (dump_sects[i])
7945 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 7946}
103f02d3 7947
5b18a4bc 7948static void
19e6b90e 7949process_mips_fpe_exception (int mask)
5b18a4bc 7950{
19e6b90e
L
7951 if (mask)
7952 {
7953 int first = 1;
7954 if (mask & OEX_FPU_INEX)
7955 fputs ("INEX", stdout), first = 0;
7956 if (mask & OEX_FPU_UFLO)
7957 printf ("%sUFLO", first ? "" : "|"), first = 0;
7958 if (mask & OEX_FPU_OFLO)
7959 printf ("%sOFLO", first ? "" : "|"), first = 0;
7960 if (mask & OEX_FPU_DIV0)
7961 printf ("%sDIV0", first ? "" : "|"), first = 0;
7962 if (mask & OEX_FPU_INVAL)
7963 printf ("%sINVAL", first ? "" : "|");
7964 }
5b18a4bc 7965 else
19e6b90e 7966 fputs ("0", stdout);
5b18a4bc 7967}
103f02d3 7968
11c1ff18
PB
7969/* ARM EABI attributes section. */
7970typedef struct
7971{
7972 int tag;
7973 const char *name;
7974 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
7975 int type;
7976 const char **table;
7977} arm_attr_public_tag;
7978
7979static const char *arm_attr_tag_CPU_arch[] =
7980 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
7981 "v6K", "v7"};
7982static const char *arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
7983static const char *arm_attr_tag_THUMB_ISA_use[] =
7984 {"No", "Thumb-1", "Thumb-2"};
14c28b74
JB
7985/* FIXME: VFPv3 encoding was extrapolated! */
7986static const char *arm_attr_tag_VFP_arch[] = {"No", "VFPv1", "VFPv2", "VFPv3"};
11c1ff18
PB
7987static const char *arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1"};
7988static const char *arm_attr_tag_NEON_arch[] = {"No", "NEONv1"};
7989static const char *arm_attr_tag_ABI_PCS_config[] =
7990 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
7991 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
7992static const char *arm_attr_tag_ABI_PCS_R9_use[] =
7993 {"V6", "SB", "TLS", "Unused"};
7994static const char *arm_attr_tag_ABI_PCS_RW_data[] =
7995 {"Absolute", "PC-relative", "SB-relative", "None"};
7996static const char *arm_attr_tag_ABI_PCS_RO_DATA[] =
7997 {"Absolute", "PC-relative", "None"};
7998static const char *arm_attr_tag_ABI_PCS_GOT_use[] =
7999 {"None", "direct", "GOT-indirect"};
8000static const char *arm_attr_tag_ABI_PCS_wchar_t[] =
8001 {"None", "??? 1", "2", "??? 3", "4"};
8002static const char *arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
8003static const char *arm_attr_tag_ABI_FP_denormal[] = {"Unused", "Needed"};
8004static const char *arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
8005static const char *arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
8006static const char *arm_attr_tag_ABI_FP_number_model[] =
8007 {"Unused", "Finite", "RTABI", "IEEE 754"};
8008static const char *arm_attr_tag_ABI_align8_needed[] = {"No", "Yes", "4-byte"};
8009static const char *arm_attr_tag_ABI_align8_preserved[] =
8010 {"No", "Yes, except leaf SP", "Yes"};
8011static const char *arm_attr_tag_ABI_enum_size[] =
8012 {"Unused", "small", "int", "forced to int"};
8013static const char *arm_attr_tag_ABI_HardFP_use[] =
8014 {"As Tag_VFP_arch", "SP only", "DP only", "SP and DP"};
8015static const char *arm_attr_tag_ABI_VFP_args[] =
8016 {"AAPCS", "VFP registers", "custom"};
8017static const char *arm_attr_tag_ABI_WMMX_args[] =
8018 {"AAPCS", "WMMX registers", "custom"};
8019static const char *arm_attr_tag_ABI_optimization_goals[] =
8020 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
8021 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
8022static const char *arm_attr_tag_ABI_FP_optimization_goals[] =
8023 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
8024 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
8025
8026#define LOOKUP(id, name) \
8027 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 8028static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
8029{
8030 {4, "CPU_raw_name", 1, NULL},
8031 {5, "CPU_name", 1, NULL},
8032 LOOKUP(6, CPU_arch),
8033 {7, "CPU_arch_profile", 0, NULL},
8034 LOOKUP(8, ARM_ISA_use),
8035 LOOKUP(9, THUMB_ISA_use),
8036 LOOKUP(10, VFP_arch),
8037 LOOKUP(11, WMMX_arch),
8038 LOOKUP(12, NEON_arch),
8039 LOOKUP(13, ABI_PCS_config),
8040 LOOKUP(14, ABI_PCS_R9_use),
8041 LOOKUP(15, ABI_PCS_RW_data),
8042 LOOKUP(16, ABI_PCS_RO_DATA),
8043 LOOKUP(17, ABI_PCS_GOT_use),
8044 LOOKUP(18, ABI_PCS_wchar_t),
8045 LOOKUP(19, ABI_FP_rounding),
8046 LOOKUP(20, ABI_FP_denormal),
8047 LOOKUP(21, ABI_FP_exceptions),
8048 LOOKUP(22, ABI_FP_user_exceptions),
8049 LOOKUP(23, ABI_FP_number_model),
8050 LOOKUP(24, ABI_align8_needed),
8051 LOOKUP(25, ABI_align8_preserved),
8052 LOOKUP(26, ABI_enum_size),
8053 LOOKUP(27, ABI_HardFP_use),
8054 LOOKUP(28, ABI_VFP_args),
8055 LOOKUP(29, ABI_WMMX_args),
8056 LOOKUP(30, ABI_optimization_goals),
8057 LOOKUP(31, ABI_FP_optimization_goals),
8058 {32, "compatibility", 0, NULL}
8059};
8060#undef LOOKUP
8061
8062/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
8063 bytes read. */
8064static unsigned int
8065read_uleb128 (unsigned char *p, unsigned int *plen)
8066{
8067 unsigned char c;
8068 unsigned int val;
8069 int shift;
8070 int len;
8071
8072 val = 0;
8073 shift = 0;
8074 len = 0;
8075 do
8076 {
8077 c = *(p++);
8078 len++;
8079 val |= ((unsigned int)c & 0x7f) << shift;
8080 shift += 7;
8081 }
8082 while (c & 0x80);
8083
8084 *plen = len;
8085 return val;
8086}
8087
8088static unsigned char *
8089display_arm_attribute (unsigned char *p)
8090{
8091 int tag;
8092 unsigned int len;
8093 int val;
8094 arm_attr_public_tag *attr;
8095 unsigned i;
8096 int type;
8097
8098 tag = read_uleb128 (p, &len);
8099 p += len;
8100 attr = NULL;
8101 for (i = 0; i < ARRAY_SIZE(arm_attr_public_tags); i++)
8102 {
8103 if (arm_attr_public_tags[i].tag == tag)
8104 {
8105 attr = &arm_attr_public_tags[i];
8106 break;
8107 }
8108 }
8109
8110 if (attr)
8111 {
8112 printf (" Tag_%s: ", attr->name);
8113 switch (attr->type)
8114 {
8115 case 0:
8116 switch (tag)
8117 {
8118 case 7: /* Tag_CPU_arch_profile. */
8119 val = read_uleb128 (p, &len);
8120 p += len;
8121 switch (val)
8122 {
8123 case 0: printf ("None\n"); break;
8124 case 'A': printf ("Application\n"); break;
8125 case 'R': printf ("Realtime\n"); break;
8126 case 'M': printf ("Microcontroller\n"); break;
8127 default: printf ("??? (%d)\n", val); break;
8128 }
8129 break;
8130
8131 case 32: /* Tag_compatibility. */
8132 val = read_uleb128 (p, &len);
8133 p += len;
8134 printf ("flag = %d, vendor = %s\n", val, p);
8135 p += strlen((char *)p) + 1;
8136 break;
8137
8138 default:
8139 abort();
8140 }
8141 return p;
8142
8143 case 1:
8144 case 2:
8145 type = attr->type;
8146 break;
8147
8148 default:
8149 assert (attr->type & 0x80);
8150 val = read_uleb128 (p, &len);
8151 p += len;
8152 type = attr->type & 0x7f;
8153 if (val >= type)
8154 printf ("??? (%d)\n", val);
8155 else
8156 printf ("%s\n", attr->table[val]);
8157 return p;
8158 }
8159 }
8160 else
8161 {
8162 if (tag & 1)
8163 type = 1; /* String. */
8164 else
8165 type = 2; /* uleb128. */
8166 printf (" Tag_unknown_%d: ", tag);
8167 }
8168
8169 if (type == 1)
8170 {
8171 printf ("\"%s\"\n", p);
8172 p += strlen((char *)p) + 1;
8173 }
8174 else
8175 {
8176 val = read_uleb128 (p, &len);
8177 p += len;
8178 printf ("%d (0x%x)\n", val, val);
8179 }
8180
8181 return p;
8182}
8183
8184static int
8185process_arm_specific (FILE *file)
8186{
8187 Elf_Internal_Shdr *sect;
8188 unsigned char *contents;
8189 unsigned char *p;
8190 unsigned char *end;
8191 bfd_vma section_len;
8192 bfd_vma len;
8193 unsigned i;
8194
8195 /* Find the section header so that we get the size. */
8196 for (i = 0, sect = section_headers;
8197 i < elf_header.e_shnum;
8198 i++, sect++)
8199 {
8200 if (sect->sh_type != SHT_ARM_ATTRIBUTES)
8201 continue;
8202
8203 contents = get_data (NULL, file, sect->sh_offset, 1, sect->sh_size,
8204 _("attributes"));
d70c5fc7 8205
11c1ff18
PB
8206 if (!contents)
8207 continue;
8208 p = contents;
8209 if (*p == 'A')
8210 {
8211 len = sect->sh_size - 1;
8212 p++;
8213 while (len > 0)
8214 {
8215 int namelen;
8216 bfd_boolean public_section;
8217
8218 section_len = byte_get (p, 4);
8219 p += 4;
8220 if (section_len > len)
8221 {
8222 printf (_("ERROR: Bad section length (%d > %d)\n"),
8223 (int)section_len, (int)len);
8224 section_len = len;
8225 }
8226 len -= section_len;
8227 printf ("Attribute Section: %s\n", p);
8228 if (strcmp ((char *)p, "aeabi") == 0)
8229 public_section = TRUE;
8230 else
8231 public_section = FALSE;
8232 namelen = strlen ((char *)p) + 1;
8233 p += namelen;
8234 section_len -= namelen + 4;
8235 while (section_len > 0)
8236 {
8237 int tag = *(p++);
8238 int val;
8239 bfd_vma size;
8240 size = byte_get (p, 4);
8241 if (size > section_len)
8242 {
8243 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
8244 (int)size, (int)section_len);
8245 size = section_len;
8246 }
8247 section_len -= size;
8248 end = p + size - 1;
8249 p += 4;
8250 switch (tag)
8251 {
8252 case 1:
8253 printf ("File Attributes\n");
8254 break;
8255 case 2:
8256 printf ("Section Attributes:");
8257 goto do_numlist;
8258 case 3:
8259 printf ("Symbol Attributes:");
8260 do_numlist:
8261 for (;;)
8262 {
8263 unsigned int i;
8264 val = read_uleb128 (p, &i);
8265 p += i;
8266 if (val == 0)
8267 break;
8268 printf (" %d", val);
8269 }
8270 printf ("\n");
8271 break;
8272 default:
8273 printf ("Unknown tag: %d\n", tag);
8274 public_section = FALSE;
8275 break;
8276 }
8277 if (public_section)
8278 {
8279 while (p < end)
8280 p = display_arm_attribute(p);
8281 }
8282 else
8283 {
8284 /* ??? Do something sensible, like dump hex. */
8285 printf (" Unknown section contexts\n");
8286 p = end;
8287 }
8288 }
8289 }
8290 }
8291 else
8292 {
8293 printf (_("Unknown format '%c'\n"), *p);
8294 }
d70c5fc7 8295
11c1ff18
PB
8296 free(contents);
8297 }
8298 return 1;
8299}
8300
19e6b90e
L
8301static int
8302process_mips_specific (FILE *file)
5b18a4bc 8303{
19e6b90e
L
8304 Elf_Internal_Dyn *entry;
8305 size_t liblist_offset = 0;
8306 size_t liblistno = 0;
8307 size_t conflictsno = 0;
8308 size_t options_offset = 0;
8309 size_t conflicts_offset = 0;
103f02d3 8310
19e6b90e
L
8311 /* We have a lot of special sections. Thanks SGI! */
8312 if (dynamic_section == NULL)
8313 /* No information available. */
8314 return 0;
252b5132 8315
b2d38a17 8316 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
8317 switch (entry->d_tag)
8318 {
8319 case DT_MIPS_LIBLIST:
d93f0186
NC
8320 liblist_offset
8321 = offset_from_vma (file, entry->d_un.d_val,
8322 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
8323 break;
8324 case DT_MIPS_LIBLISTNO:
8325 liblistno = entry->d_un.d_val;
8326 break;
8327 case DT_MIPS_OPTIONS:
d93f0186 8328 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
8329 break;
8330 case DT_MIPS_CONFLICT:
d93f0186
NC
8331 conflicts_offset
8332 = offset_from_vma (file, entry->d_un.d_val,
8333 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
8334 break;
8335 case DT_MIPS_CONFLICTNO:
8336 conflictsno = entry->d_un.d_val;
8337 break;
8338 default:
8339 break;
8340 }
8341
8342 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
8343 {
b34976b6 8344 Elf32_External_Lib *elib;
252b5132
RH
8345 size_t cnt;
8346
d3ba0551 8347 elib = get_data (NULL, file, liblist_offset,
c256ffe7 8348 liblistno, sizeof (Elf32_External_Lib),
d3ba0551 8349 _("liblist"));
a6e9f9df 8350 if (elib)
252b5132 8351 {
a6e9f9df
AM
8352 printf ("\nSection '.liblist' contains %lu entries:\n",
8353 (unsigned long) liblistno);
8354 fputs (" Library Time Stamp Checksum Version Flags\n",
8355 stdout);
8356
8357 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 8358 {
a6e9f9df
AM
8359 Elf32_Lib liblist;
8360 time_t time;
8361 char timebuf[20];
b34976b6 8362 struct tm *tmp;
a6e9f9df
AM
8363
8364 liblist.l_name = BYTE_GET (elib[cnt].l_name);
8365 time = BYTE_GET (elib[cnt].l_time_stamp);
8366 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
8367 liblist.l_version = BYTE_GET (elib[cnt].l_version);
8368 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
8369
8370 tmp = gmtime (&time);
e9e44622
JJ
8371 snprintf (timebuf, sizeof (timebuf),
8372 "%04u-%02u-%02uT%02u:%02u:%02u",
8373 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8374 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 8375
31104126 8376 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
8377 if (VALID_DYNAMIC_NAME (liblist.l_name))
8378 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
8379 else
8380 printf ("<corrupt: %9ld>", liblist.l_name);
31104126
NC
8381 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
8382 liblist.l_version);
a6e9f9df
AM
8383
8384 if (liblist.l_flags == 0)
8385 puts (" NONE");
8386 else
8387 {
8388 static const struct
252b5132 8389 {
b34976b6 8390 const char *name;
a6e9f9df 8391 int bit;
252b5132 8392 }
a6e9f9df
AM
8393 l_flags_vals[] =
8394 {
8395 { " EXACT_MATCH", LL_EXACT_MATCH },
8396 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
8397 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
8398 { " EXPORTS", LL_EXPORTS },
8399 { " DELAY_LOAD", LL_DELAY_LOAD },
8400 { " DELTA", LL_DELTA }
8401 };
8402 int flags = liblist.l_flags;
8403 size_t fcnt;
8404
8405 for (fcnt = 0;
8406 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
8407 ++fcnt)
8408 if ((flags & l_flags_vals[fcnt].bit) != 0)
8409 {
8410 fputs (l_flags_vals[fcnt].name, stdout);
8411 flags ^= l_flags_vals[fcnt].bit;
8412 }
8413 if (flags != 0)
8414 printf (" %#x", (unsigned int) flags);
252b5132 8415
a6e9f9df
AM
8416 puts ("");
8417 }
252b5132 8418 }
252b5132 8419
a6e9f9df
AM
8420 free (elib);
8421 }
252b5132
RH
8422 }
8423
8424 if (options_offset != 0)
8425 {
b34976b6
AM
8426 Elf_External_Options *eopt;
8427 Elf_Internal_Shdr *sect = section_headers;
8428 Elf_Internal_Options *iopt;
8429 Elf_Internal_Options *option;
252b5132
RH
8430 size_t offset;
8431 int cnt;
8432
8433 /* Find the section header so that we get the size. */
8434 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 8435 ++sect;
252b5132 8436
c256ffe7 8437 eopt = get_data (NULL, file, options_offset, 1, sect->sh_size,
d3ba0551 8438 _("options"));
a6e9f9df 8439 if (eopt)
252b5132 8440 {
c256ffe7 8441 iopt = cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (*iopt));
a6e9f9df
AM
8442 if (iopt == NULL)
8443 {
8444 error (_("Out of memory"));
8445 return 0;
8446 }
76da6bbe 8447
a6e9f9df
AM
8448 offset = cnt = 0;
8449 option = iopt;
252b5132 8450
a6e9f9df
AM
8451 while (offset < sect->sh_size)
8452 {
b34976b6 8453 Elf_External_Options *eoption;
252b5132 8454
a6e9f9df 8455 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 8456
a6e9f9df
AM
8457 option->kind = BYTE_GET (eoption->kind);
8458 option->size = BYTE_GET (eoption->size);
8459 option->section = BYTE_GET (eoption->section);
8460 option->info = BYTE_GET (eoption->info);
76da6bbe 8461
a6e9f9df 8462 offset += option->size;
252b5132 8463
a6e9f9df
AM
8464 ++option;
8465 ++cnt;
8466 }
252b5132 8467
a6e9f9df
AM
8468 printf (_("\nSection '%s' contains %d entries:\n"),
8469 SECTION_NAME (sect), cnt);
76da6bbe 8470
a6e9f9df 8471 option = iopt;
252b5132 8472
a6e9f9df 8473 while (cnt-- > 0)
252b5132 8474 {
a6e9f9df
AM
8475 size_t len;
8476
8477 switch (option->kind)
252b5132 8478 {
a6e9f9df
AM
8479 case ODK_NULL:
8480 /* This shouldn't happen. */
8481 printf (" NULL %d %lx", option->section, option->info);
8482 break;
8483 case ODK_REGINFO:
8484 printf (" REGINFO ");
8485 if (elf_header.e_machine == EM_MIPS)
8486 {
8487 /* 32bit form. */
b34976b6
AM
8488 Elf32_External_RegInfo *ereg;
8489 Elf32_RegInfo reginfo;
a6e9f9df
AM
8490
8491 ereg = (Elf32_External_RegInfo *) (option + 1);
8492 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8493 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8494 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8495 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8496 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8497 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
8498
8499 printf ("GPR %08lx GP 0x%lx\n",
8500 reginfo.ri_gprmask,
8501 (unsigned long) reginfo.ri_gp_value);
8502 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
8503 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8504 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8505 }
8506 else
8507 {
8508 /* 64 bit form. */
b34976b6 8509 Elf64_External_RegInfo *ereg;
a6e9f9df
AM
8510 Elf64_Internal_RegInfo reginfo;
8511
8512 ereg = (Elf64_External_RegInfo *) (option + 1);
8513 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8514 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8515 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8516 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8517 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 8518 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
8519
8520 printf ("GPR %08lx GP 0x",
8521 reginfo.ri_gprmask);
8522 printf_vma (reginfo.ri_gp_value);
8523 printf ("\n");
8524
8525 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
8526 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8527 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8528 }
8529 ++option;
8530 continue;
8531 case ODK_EXCEPTIONS:
8532 fputs (" EXCEPTIONS fpe_min(", stdout);
8533 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
8534 fputs (") fpe_max(", stdout);
8535 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
8536 fputs (")", stdout);
8537
8538 if (option->info & OEX_PAGE0)
8539 fputs (" PAGE0", stdout);
8540 if (option->info & OEX_SMM)
8541 fputs (" SMM", stdout);
8542 if (option->info & OEX_FPDBUG)
8543 fputs (" FPDBUG", stdout);
8544 if (option->info & OEX_DISMISS)
8545 fputs (" DISMISS", stdout);
8546 break;
8547 case ODK_PAD:
8548 fputs (" PAD ", stdout);
8549 if (option->info & OPAD_PREFIX)
8550 fputs (" PREFIX", stdout);
8551 if (option->info & OPAD_POSTFIX)
8552 fputs (" POSTFIX", stdout);
8553 if (option->info & OPAD_SYMBOL)
8554 fputs (" SYMBOL", stdout);
8555 break;
8556 case ODK_HWPATCH:
8557 fputs (" HWPATCH ", stdout);
8558 if (option->info & OHW_R4KEOP)
8559 fputs (" R4KEOP", stdout);
8560 if (option->info & OHW_R8KPFETCH)
8561 fputs (" R8KPFETCH", stdout);
8562 if (option->info & OHW_R5KEOP)
8563 fputs (" R5KEOP", stdout);
8564 if (option->info & OHW_R5KCVTL)
8565 fputs (" R5KCVTL", stdout);
8566 break;
8567 case ODK_FILL:
8568 fputs (" FILL ", stdout);
8569 /* XXX Print content of info word? */
8570 break;
8571 case ODK_TAGS:
8572 fputs (" TAGS ", stdout);
8573 /* XXX Print content of info word? */
8574 break;
8575 case ODK_HWAND:
8576 fputs (" HWAND ", stdout);
8577 if (option->info & OHWA0_R4KEOP_CHECKED)
8578 fputs (" R4KEOP_CHECKED", stdout);
8579 if (option->info & OHWA0_R4KEOP_CLEAN)
8580 fputs (" R4KEOP_CLEAN", stdout);
8581 break;
8582 case ODK_HWOR:
8583 fputs (" HWOR ", stdout);
8584 if (option->info & OHWA0_R4KEOP_CHECKED)
8585 fputs (" R4KEOP_CHECKED", stdout);
8586 if (option->info & OHWA0_R4KEOP_CLEAN)
8587 fputs (" R4KEOP_CLEAN", stdout);
8588 break;
8589 case ODK_GP_GROUP:
8590 printf (" GP_GROUP %#06lx self-contained %#06lx",
8591 option->info & OGP_GROUP,
8592 (option->info & OGP_SELF) >> 16);
8593 break;
8594 case ODK_IDENT:
8595 printf (" IDENT %#06lx self-contained %#06lx",
8596 option->info & OGP_GROUP,
8597 (option->info & OGP_SELF) >> 16);
8598 break;
8599 default:
8600 /* This shouldn't happen. */
8601 printf (" %3d ??? %d %lx",
8602 option->kind, option->section, option->info);
8603 break;
252b5132 8604 }
a6e9f9df 8605
b34976b6 8606 len = sizeof (*eopt);
a6e9f9df
AM
8607 while (len < option->size)
8608 if (((char *) option)[len] >= ' '
8609 && ((char *) option)[len] < 0x7f)
8610 printf ("%c", ((char *) option)[len++]);
8611 else
8612 printf ("\\%03o", ((char *) option)[len++]);
8613
8614 fputs ("\n", stdout);
252b5132 8615 ++option;
252b5132
RH
8616 }
8617
a6e9f9df 8618 free (eopt);
252b5132 8619 }
252b5132
RH
8620 }
8621
8622 if (conflicts_offset != 0 && conflictsno != 0)
8623 {
b34976b6 8624 Elf32_Conflict *iconf;
252b5132
RH
8625 size_t cnt;
8626
8627 if (dynamic_symbols == NULL)
8628 {
3a1a2036 8629 error (_("conflict list found without a dynamic symbol table"));
252b5132
RH
8630 return 0;
8631 }
8632
c256ffe7 8633 iconf = cmalloc (conflictsno, sizeof (*iconf));
252b5132
RH
8634 if (iconf == NULL)
8635 {
8636 error (_("Out of memory"));
8637 return 0;
8638 }
8639
9ea033b2 8640 if (is_32bit_elf)
252b5132 8641 {
b34976b6 8642 Elf32_External_Conflict *econf32;
a6e9f9df 8643
d3ba0551 8644 econf32 = get_data (NULL, file, conflicts_offset,
c256ffe7 8645 conflictsno, sizeof (*econf32), _("conflict"));
a6e9f9df
AM
8646 if (!econf32)
8647 return 0;
252b5132
RH
8648
8649 for (cnt = 0; cnt < conflictsno; ++cnt)
8650 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
8651
8652 free (econf32);
252b5132
RH
8653 }
8654 else
8655 {
b34976b6 8656 Elf64_External_Conflict *econf64;
a6e9f9df 8657
d3ba0551 8658 econf64 = get_data (NULL, file, conflicts_offset,
c256ffe7 8659 conflictsno, sizeof (*econf64), _("conflict"));
a6e9f9df
AM
8660 if (!econf64)
8661 return 0;
252b5132
RH
8662
8663 for (cnt = 0; cnt < conflictsno; ++cnt)
8664 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
8665
8666 free (econf64);
252b5132
RH
8667 }
8668
c7e7ca54
NC
8669 printf (_("\nSection '.conflict' contains %lu entries:\n"),
8670 (unsigned long) conflictsno);
252b5132
RH
8671 puts (_(" Num: Index Value Name"));
8672
8673 for (cnt = 0; cnt < conflictsno; ++cnt)
8674 {
b34976b6 8675 Elf_Internal_Sym *psym = & dynamic_symbols[iconf[cnt]];
252b5132 8676
b34976b6 8677 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 8678 print_vma (psym->st_value, FULL_HEX);
31104126 8679 putchar (' ');
d79b3d50
NC
8680 if (VALID_DYNAMIC_NAME (psym->st_name))
8681 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
8682 else
8683 printf ("<corrupt: %14ld>", psym->st_name);
31104126 8684 putchar ('\n');
252b5132
RH
8685 }
8686
252b5132
RH
8687 free (iconf);
8688 }
8689
8690 return 1;
8691}
8692
047b2264 8693static int
d3ba0551 8694process_gnu_liblist (FILE *file)
047b2264 8695{
b34976b6
AM
8696 Elf_Internal_Shdr *section, *string_sec;
8697 Elf32_External_Lib *elib;
8698 char *strtab;
c256ffe7 8699 size_t strtab_size;
047b2264
JJ
8700 size_t cnt;
8701 unsigned i;
8702
8703 if (! do_arch)
8704 return 0;
8705
8706 for (i = 0, section = section_headers;
8707 i < elf_header.e_shnum;
b34976b6 8708 i++, section++)
047b2264
JJ
8709 {
8710 switch (section->sh_type)
8711 {
8712 case SHT_GNU_LIBLIST:
c256ffe7
JJ
8713 if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum)
8714 break;
8715
8716 elib = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
d3ba0551 8717 _("liblist"));
047b2264
JJ
8718
8719 if (elib == NULL)
8720 break;
8721 string_sec = SECTION_HEADER (section->sh_link);
8722
c256ffe7 8723 strtab = get_data (NULL, file, string_sec->sh_offset, 1,
d3ba0551 8724 string_sec->sh_size, _("liblist string table"));
c256ffe7 8725 strtab_size = string_sec->sh_size;
047b2264
JJ
8726
8727 if (strtab == NULL
8728 || section->sh_entsize != sizeof (Elf32_External_Lib))
8729 {
8730 free (elib);
8731 break;
8732 }
8733
8734 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
8735 SECTION_NAME (section),
8736 (long) (section->sh_size / sizeof (Elf32_External_Lib)));
8737
8738 puts (" Library Time Stamp Checksum Version Flags");
8739
8740 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
8741 ++cnt)
8742 {
8743 Elf32_Lib liblist;
8744 time_t time;
8745 char timebuf[20];
b34976b6 8746 struct tm *tmp;
047b2264
JJ
8747
8748 liblist.l_name = BYTE_GET (elib[cnt].l_name);
8749 time = BYTE_GET (elib[cnt].l_time_stamp);
8750 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
8751 liblist.l_version = BYTE_GET (elib[cnt].l_version);
8752 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
8753
8754 tmp = gmtime (&time);
e9e44622
JJ
8755 snprintf (timebuf, sizeof (timebuf),
8756 "%04u-%02u-%02uT%02u:%02u:%02u",
8757 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8758 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
8759
8760 printf ("%3lu: ", (unsigned long) cnt);
8761 if (do_wide)
c256ffe7
JJ
8762 printf ("%-20s", liblist.l_name < strtab_size
8763 ? strtab + liblist.l_name : "<corrupt>");
047b2264 8764 else
c256ffe7
JJ
8765 printf ("%-20.20s", liblist.l_name < strtab_size
8766 ? strtab + liblist.l_name : "<corrupt>");
047b2264
JJ
8767 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
8768 liblist.l_version, liblist.l_flags);
8769 }
8770
8771 free (elib);
8772 }
8773 }
8774
8775 return 1;
8776}
8777
9437c45b 8778static const char *
d3ba0551 8779get_note_type (unsigned e_type)
779fe533
NC
8780{
8781 static char buff[64];
103f02d3 8782
1ec5cd37
NC
8783 if (elf_header.e_type == ET_CORE)
8784 switch (e_type)
8785 {
57346661 8786 case NT_AUXV:
1ec5cd37 8787 return _("NT_AUXV (auxiliary vector)");
57346661 8788 case NT_PRSTATUS:
1ec5cd37 8789 return _("NT_PRSTATUS (prstatus structure)");
57346661 8790 case NT_FPREGSET:
1ec5cd37 8791 return _("NT_FPREGSET (floating point registers)");
57346661 8792 case NT_PRPSINFO:
1ec5cd37 8793 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 8794 case NT_TASKSTRUCT:
1ec5cd37 8795 return _("NT_TASKSTRUCT (task structure)");
57346661 8796 case NT_PRXFPREG:
1ec5cd37 8797 return _("NT_PRXFPREG (user_xfpregs structure)");
57346661 8798 case NT_PSTATUS:
1ec5cd37 8799 return _("NT_PSTATUS (pstatus structure)");
57346661 8800 case NT_FPREGS:
1ec5cd37 8801 return _("NT_FPREGS (floating point registers)");
57346661 8802 case NT_PSINFO:
1ec5cd37 8803 return _("NT_PSINFO (psinfo structure)");
57346661 8804 case NT_LWPSTATUS:
1ec5cd37 8805 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 8806 case NT_LWPSINFO:
1ec5cd37 8807 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 8808 case NT_WIN32PSTATUS:
1ec5cd37
NC
8809 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
8810 default:
8811 break;
8812 }
8813 else
8814 switch (e_type)
8815 {
8816 case NT_VERSION:
8817 return _("NT_VERSION (version)");
8818 case NT_ARCH:
8819 return _("NT_ARCH (architecture)");
8820 default:
8821 break;
8822 }
8823
e9e44622 8824 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 8825 return buff;
779fe533
NC
8826}
8827
9437c45b 8828static const char *
d3ba0551 8829get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
8830{
8831 static char buff[64];
8832
b4db1224 8833 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
8834 {
8835 /* NetBSD core "procinfo" structure. */
8836 return _("NetBSD procinfo structure");
8837 }
8838
8839 /* As of Jan 2002 there are no other machine-independent notes
8840 defined for NetBSD core files. If the note type is less
8841 than the start of the machine-dependent note types, we don't
8842 understand it. */
8843
b4db1224 8844 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 8845 {
e9e44622 8846 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
8847 return buff;
8848 }
8849
8850 switch (elf_header.e_machine)
8851 {
8852 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
8853 and PT_GETFPREGS == mach+2. */
8854
8855 case EM_OLD_ALPHA:
8856 case EM_ALPHA:
8857 case EM_SPARC:
8858 case EM_SPARC32PLUS:
8859 case EM_SPARCV9:
8860 switch (e_type)
8861 {
b4db1224
JT
8862 case NT_NETBSDCORE_FIRSTMACH+0:
8863 return _("PT_GETREGS (reg structure)");
8864 case NT_NETBSDCORE_FIRSTMACH+2:
8865 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
8866 default:
8867 break;
8868 }
8869 break;
8870
8871 /* On all other arch's, PT_GETREGS == mach+1 and
8872 PT_GETFPREGS == mach+3. */
8873 default:
8874 switch (e_type)
8875 {
b4db1224
JT
8876 case NT_NETBSDCORE_FIRSTMACH+1:
8877 return _("PT_GETREGS (reg structure)");
8878 case NT_NETBSDCORE_FIRSTMACH+3:
8879 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
8880 default:
8881 break;
8882 }
8883 }
8884
e9e44622
JJ
8885 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
8886 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
8887 return buff;
8888}
8889
6d118b09
NC
8890/* Note that by the ELF standard, the name field is already null byte
8891 terminated, and namesz includes the terminating null byte.
8892 I.E. the value of namesz for the name "FSF" is 4.
8893
e3c8793a 8894 If the value of namesz is zero, there is no name present. */
779fe533 8895static int
d3ba0551 8896process_note (Elf_Internal_Note *pnote)
779fe533 8897{
9437c45b
JT
8898 const char *nt;
8899
8900 if (pnote->namesz == 0)
1ec5cd37
NC
8901 /* If there is no note name, then use the default set of
8902 note type strings. */
8903 nt = get_note_type (pnote->type);
8904
0112cd26 8905 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
8906 /* NetBSD-specific core file notes. */
8907 nt = get_netbsd_elfcore_note_type (pnote->type);
8908
9437c45b 8909 else
1ec5cd37
NC
8910 /* Don't recognize this note name; just use the default set of
8911 note type strings. */
9437c45b 8912 nt = get_note_type (pnote->type);
9437c45b 8913
103f02d3 8914 printf (" %s\t\t0x%08lx\t%s\n",
6d118b09 8915 pnote->namesz ? pnote->namedata : "(NONE)",
9437c45b 8916 pnote->descsz, nt);
779fe533
NC
8917 return 1;
8918}
8919
6d118b09 8920
779fe533 8921static int
d3ba0551 8922process_corefile_note_segment (FILE *file, bfd_vma offset, bfd_vma length)
779fe533 8923{
b34976b6
AM
8924 Elf_External_Note *pnotes;
8925 Elf_External_Note *external;
8926 int res = 1;
103f02d3 8927
779fe533
NC
8928 if (length <= 0)
8929 return 0;
103f02d3 8930
c256ffe7 8931 pnotes = get_data (NULL, file, offset, 1, length, _("notes"));
a6e9f9df
AM
8932 if (!pnotes)
8933 return 0;
779fe533 8934
103f02d3 8935 external = pnotes;
103f02d3 8936
305c7206 8937 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 8938 (unsigned long) offset, (unsigned long) length);
779fe533 8939 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 8940
6d118b09 8941 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 8942 {
b34976b6
AM
8943 Elf_External_Note *next;
8944 Elf_Internal_Note inote;
8945 char *temp = NULL;
6d118b09
NC
8946
8947 inote.type = BYTE_GET (external->type);
8948 inote.namesz = BYTE_GET (external->namesz);
8949 inote.namedata = external->name;
8950 inote.descsz = BYTE_GET (external->descsz);
8951 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
8952 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 8953
3e55a963
NC
8954 next = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
8955
8956 if (((char *) next) > (((char *) pnotes) + length))
8957 {
0fd3a477
JW
8958 warn (_("corrupt note found at offset %lx into core notes\n"),
8959 (long)((char *)external - (char *)pnotes));
8960 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
8961 inote.type, inote.namesz, inote.descsz);
8962 break;
8963 }
8964
8965 external = next;
6d118b09
NC
8966
8967 /* Verify that name is null terminated. It appears that at least
8968 one version of Linux (RedHat 6.0) generates corefiles that don't
8969 comply with the ELF spec by failing to include the null byte in
8970 namesz. */
8971 if (inote.namedata[inote.namesz] != '\0')
8972 {
8973 temp = malloc (inote.namesz + 1);
76da6bbe 8974
6d118b09
NC
8975 if (temp == NULL)
8976 {
8977 error (_("Out of memory\n"));
8978 res = 0;
8979 break;
8980 }
76da6bbe 8981
6d118b09
NC
8982 strncpy (temp, inote.namedata, inote.namesz);
8983 temp[inote.namesz] = 0;
76da6bbe 8984
6d118b09
NC
8985 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
8986 inote.namedata = temp;
8987 }
8988
8989 res &= process_note (& inote);
103f02d3 8990
6d118b09
NC
8991 if (temp != NULL)
8992 {
8993 free (temp);
8994 temp = NULL;
8995 }
779fe533
NC
8996 }
8997
8998 free (pnotes);
103f02d3 8999
779fe533
NC
9000 return res;
9001}
9002
9003static int
d3ba0551 9004process_corefile_note_segments (FILE *file)
779fe533 9005{
b34976b6
AM
9006 Elf_Internal_Phdr *segment;
9007 unsigned int i;
9008 int res = 1;
103f02d3 9009
d93f0186 9010 if (! get_program_headers (file))
779fe533 9011 return 0;
103f02d3 9012
779fe533
NC
9013 for (i = 0, segment = program_headers;
9014 i < elf_header.e_phnum;
b34976b6 9015 i++, segment++)
779fe533
NC
9016 {
9017 if (segment->p_type == PT_NOTE)
103f02d3 9018 res &= process_corefile_note_segment (file,
30800947
NC
9019 (bfd_vma) segment->p_offset,
9020 (bfd_vma) segment->p_filesz);
779fe533 9021 }
103f02d3 9022
779fe533
NC
9023 return res;
9024}
9025
9026static int
1ec5cd37
NC
9027process_note_sections (FILE *file)
9028{
9029 Elf_Internal_Shdr *section;
9030 unsigned long i;
9031 int res = 1;
9032
9033 for (i = 0, section = section_headers;
9034 i < elf_header.e_shnum;
9035 i++, section++)
9036 if (section->sh_type == SHT_NOTE)
9037 res &= process_corefile_note_segment (file,
9038 (bfd_vma) section->sh_offset,
9039 (bfd_vma) section->sh_size);
9040
9041 return res;
9042}
9043
9044static int
9045process_notes (FILE *file)
779fe533
NC
9046{
9047 /* If we have not been asked to display the notes then do nothing. */
9048 if (! do_notes)
9049 return 1;
103f02d3 9050
779fe533 9051 if (elf_header.e_type != ET_CORE)
1ec5cd37 9052 return process_note_sections (file);
103f02d3 9053
779fe533 9054 /* No program headers means no NOTE segment. */
1ec5cd37
NC
9055 if (elf_header.e_phnum > 0)
9056 return process_corefile_note_segments (file);
779fe533 9057
1ec5cd37
NC
9058 printf (_("No note segments present in the core file.\n"));
9059 return 1;
779fe533
NC
9060}
9061
252b5132 9062static int
d3ba0551 9063process_arch_specific (FILE *file)
252b5132 9064{
a952a375
NC
9065 if (! do_arch)
9066 return 1;
9067
252b5132
RH
9068 switch (elf_header.e_machine)
9069 {
11c1ff18
PB
9070 case EM_ARM:
9071 return process_arm_specific (file);
252b5132 9072 case EM_MIPS:
4fe85591 9073 case EM_MIPS_RS3_LE:
252b5132
RH
9074 return process_mips_specific (file);
9075 break;
9076 default:
9077 break;
9078 }
9079 return 1;
9080}
9081
9082static int
d3ba0551 9083get_file_header (FILE *file)
252b5132 9084{
9ea033b2
NC
9085 /* Read in the identity array. */
9086 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
9087 return 0;
9088
9ea033b2 9089 /* Determine how to read the rest of the header. */
b34976b6 9090 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
9091 {
9092 default: /* fall through */
9093 case ELFDATANONE: /* fall through */
adab8cdc
AO
9094 case ELFDATA2LSB:
9095 byte_get = byte_get_little_endian;
9096 byte_put = byte_put_little_endian;
9097 break;
9098 case ELFDATA2MSB:
9099 byte_get = byte_get_big_endian;
9100 byte_put = byte_put_big_endian;
9101 break;
9ea033b2
NC
9102 }
9103
9104 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 9105 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
9106
9107 /* Read in the rest of the header. */
9108 if (is_32bit_elf)
9109 {
9110 Elf32_External_Ehdr ehdr32;
252b5132 9111
9ea033b2
NC
9112 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
9113 return 0;
103f02d3 9114
9ea033b2
NC
9115 elf_header.e_type = BYTE_GET (ehdr32.e_type);
9116 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
9117 elf_header.e_version = BYTE_GET (ehdr32.e_version);
9118 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
9119 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
9120 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
9121 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
9122 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
9123 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
9124 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
9125 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
9126 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
9127 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9128 }
252b5132 9129 else
9ea033b2
NC
9130 {
9131 Elf64_External_Ehdr ehdr64;
a952a375
NC
9132
9133 /* If we have been compiled with sizeof (bfd_vma) == 4, then
9134 we will not be able to cope with the 64bit data found in
9135 64 ELF files. Detect this now and abort before we start
50c2245b 9136 overwriting things. */
a952a375
NC
9137 if (sizeof (bfd_vma) < 8)
9138 {
e3c8793a
NC
9139 error (_("This instance of readelf has been built without support for a\n\
914064 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
9141 return 0;
9142 }
103f02d3 9143
9ea033b2
NC
9144 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
9145 return 0;
103f02d3 9146
9ea033b2
NC
9147 elf_header.e_type = BYTE_GET (ehdr64.e_type);
9148 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
9149 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
9150 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
9151 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
9152 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
9153 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
9154 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
9155 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
9156 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
9157 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
9158 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
9159 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9160 }
252b5132 9161
7ece0d85
JJ
9162 if (elf_header.e_shoff)
9163 {
9164 /* There may be some extensions in the first section header. Don't
9165 bomb if we can't read it. */
9166 if (is_32bit_elf)
9167 get_32bit_section_headers (file, 1);
9168 else
9169 get_64bit_section_headers (file, 1);
9170 }
560f3c1c 9171
1007acb3
L
9172 is_relocatable = elf_header.e_type == ET_REL;
9173
252b5132
RH
9174 return 1;
9175}
9176
fb52b2f4
NC
9177/* Process one ELF object file according to the command line options.
9178 This file may actually be stored in an archive. The file is
9179 positioned at the start of the ELF object. */
9180
ff78d6d6 9181static int
fb52b2f4 9182process_object (char *file_name, FILE *file)
252b5132 9183{
252b5132
RH
9184 unsigned int i;
9185
252b5132
RH
9186 if (! get_file_header (file))
9187 {
9188 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 9189 return 1;
252b5132
RH
9190 }
9191
9192 /* Initialise per file variables. */
9193 for (i = NUM_ELEM (version_info); i--;)
9194 version_info[i] = 0;
9195
9196 for (i = NUM_ELEM (dynamic_info); i--;)
9197 dynamic_info[i] = 0;
9198
9199 /* Process the file. */
9200 if (show_name)
9201 printf (_("\nFile: %s\n"), file_name);
9202
18bd398b
NC
9203 /* Initialise the dump_sects array from the cmdline_dump_sects array.
9204 Note we do this even if cmdline_dump_sects is empty because we
9205 must make sure that the dump_sets array is zeroed out before each
9206 object file is processed. */
9207 if (num_dump_sects > num_cmdline_dump_sects)
9208 memset (dump_sects, 0, num_dump_sects);
9209
9210 if (num_cmdline_dump_sects > 0)
9211 {
9212 if (num_dump_sects == 0)
9213 /* A sneaky way of allocating the dump_sects array. */
9214 request_dump (num_cmdline_dump_sects, 0);
9215
9216 assert (num_dump_sects >= num_cmdline_dump_sects);
9217 memcpy (dump_sects, cmdline_dump_sects, num_cmdline_dump_sects);
9218 }
d70c5fc7 9219
252b5132 9220 if (! process_file_header ())
fb52b2f4 9221 return 1;
252b5132 9222
d1f5c6e3 9223 if (! process_section_headers (file))
2f62977e 9224 {
d1f5c6e3
L
9225 /* Without loaded section headers we cannot process lots of
9226 things. */
2f62977e 9227 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 9228
2f62977e
NC
9229 if (! do_using_dynamic)
9230 do_syms = do_reloc = 0;
9231 }
252b5132 9232
d1f5c6e3
L
9233 if (! process_section_groups (file))
9234 {
9235 /* Without loaded section groups we cannot process unwind. */
9236 do_unwind = 0;
9237 }
9238
2f62977e 9239 if (process_program_headers (file))
b2d38a17 9240 process_dynamic_section (file);
252b5132
RH
9241
9242 process_relocs (file);
9243
4d6ed7c8
NC
9244 process_unwind (file);
9245
252b5132
RH
9246 process_symbol_table (file);
9247
9248 process_syminfo (file);
9249
9250 process_version_sections (file);
9251
9252 process_section_contents (file);
f5842774 9253
1ec5cd37 9254 process_notes (file);
103f02d3 9255
047b2264
JJ
9256 process_gnu_liblist (file);
9257
252b5132
RH
9258 process_arch_specific (file);
9259
d93f0186
NC
9260 if (program_headers)
9261 {
9262 free (program_headers);
9263 program_headers = NULL;
9264 }
9265
252b5132
RH
9266 if (section_headers)
9267 {
9268 free (section_headers);
9269 section_headers = NULL;
9270 }
9271
9272 if (string_table)
9273 {
9274 free (string_table);
9275 string_table = NULL;
d40ac9bd 9276 string_table_length = 0;
252b5132
RH
9277 }
9278
9279 if (dynamic_strings)
9280 {
9281 free (dynamic_strings);
9282 dynamic_strings = NULL;
d79b3d50 9283 dynamic_strings_length = 0;
252b5132
RH
9284 }
9285
9286 if (dynamic_symbols)
9287 {
9288 free (dynamic_symbols);
9289 dynamic_symbols = NULL;
19936277 9290 num_dynamic_syms = 0;
252b5132
RH
9291 }
9292
9293 if (dynamic_syminfo)
9294 {
9295 free (dynamic_syminfo);
9296 dynamic_syminfo = NULL;
9297 }
ff78d6d6 9298
e4b17d5c
L
9299 if (section_headers_groups)
9300 {
9301 free (section_headers_groups);
9302 section_headers_groups = NULL;
9303 }
9304
9305 if (section_groups)
9306 {
9307 struct group_list *g, *next;
9308
9309 for (i = 0; i < group_count; i++)
9310 {
9311 for (g = section_groups [i].root; g != NULL; g = next)
9312 {
9313 next = g->next;
9314 free (g);
9315 }
9316 }
9317
9318 free (section_groups);
9319 section_groups = NULL;
9320 }
9321
19e6b90e 9322 free_debug_memory ();
18bd398b 9323
ff78d6d6 9324 return 0;
252b5132
RH
9325}
9326
fb52b2f4
NC
9327/* Process an ELF archive. The file is positioned just after the
9328 ARMAG string. */
9329
9330static int
9331process_archive (char *file_name, FILE *file)
9332{
9333 struct ar_hdr arhdr;
9334 size_t got;
9335 unsigned long size;
9336 char *longnames = NULL;
9337 unsigned long longnames_size = 0;
9338 size_t file_name_size;
d989285c 9339 int ret;
fb52b2f4
NC
9340
9341 show_name = 1;
9342
9343 got = fread (&arhdr, 1, sizeof arhdr, file);
9344 if (got != sizeof arhdr)
9345 {
9346 if (got == 0)
9347 return 0;
9348
9349 error (_("%s: failed to read archive header\n"), file_name);
9350 return 1;
9351 }
9352
0112cd26 9353 if (const_strneq (arhdr.ar_name, "/ "))
fb52b2f4
NC
9354 {
9355 /* This is the archive symbol table. Skip it.
9356 FIXME: We should have an option to dump it. */
9357 size = strtoul (arhdr.ar_size, NULL, 10);
9358 if (fseek (file, size + (size & 1), SEEK_CUR) != 0)
9359 {
9360 error (_("%s: failed to skip archive symbol table\n"), file_name);
9361 return 1;
9362 }
9363
9364 got = fread (&arhdr, 1, sizeof arhdr, file);
9365 if (got != sizeof arhdr)
9366 {
9367 if (got == 0)
9368 return 0;
9369
9370 error (_("%s: failed to read archive header\n"), file_name);
9371 return 1;
9372 }
9373 }
9374
0112cd26 9375 if (const_strneq (arhdr.ar_name, "// "))
fb52b2f4
NC
9376 {
9377 /* This is the archive string table holding long member
9378 names. */
9379
9380 longnames_size = strtoul (arhdr.ar_size, NULL, 10);
9381
9382 longnames = malloc (longnames_size);
9383 if (longnames == NULL)
9384 {
9385 error (_("Out of memory\n"));
9386 return 1;
9387 }
9388
9389 if (fread (longnames, longnames_size, 1, file) != 1)
9390 {
d989285c 9391 free (longnames);
18bd398b 9392 error (_("%s: failed to read string table\n"), file_name);
fb52b2f4
NC
9393 return 1;
9394 }
9395
9396 if ((longnames_size & 1) != 0)
9397 getc (file);
9398
9399 got = fread (&arhdr, 1, sizeof arhdr, file);
9400 if (got != sizeof arhdr)
9401 {
d989285c
ILT
9402 free (longnames);
9403
fb52b2f4
NC
9404 if (got == 0)
9405 return 0;
9406
9407 error (_("%s: failed to read archive header\n"), file_name);
9408 return 1;
9409 }
9410 }
9411
9412 file_name_size = strlen (file_name);
d989285c 9413 ret = 0;
fb52b2f4
NC
9414
9415 while (1)
9416 {
9417 char *name;
9418 char *nameend;
9419 char *namealc;
9420
9421 if (arhdr.ar_name[0] == '/')
9422 {
9423 unsigned long off;
9424
9425 off = strtoul (arhdr.ar_name + 1, NULL, 10);
9426 if (off >= longnames_size)
9427 {
0fd3a477 9428 error (_("%s: invalid archive string table offset %lu\n"), file_name, off);
d989285c
ILT
9429 ret = 1;
9430 break;
fb52b2f4
NC
9431 }
9432
9433 name = longnames + off;
9434 nameend = memchr (name, '/', longnames_size - off);
9435 }
9436 else
9437 {
9438 name = arhdr.ar_name;
9439 nameend = memchr (name, '/', 16);
9440 }
9441
9442 if (nameend == NULL)
9443 {
0fd3a477 9444 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
9445 ret = 1;
9446 break;
fb52b2f4
NC
9447 }
9448
9449 namealc = malloc (file_name_size + (nameend - name) + 3);
9450 if (namealc == NULL)
9451 {
9452 error (_("Out of memory\n"));
d989285c
ILT
9453 ret = 1;
9454 break;
fb52b2f4
NC
9455 }
9456
9457 memcpy (namealc, file_name, file_name_size);
9458 namealc[file_name_size] = '(';
9459 memcpy (namealc + file_name_size + 1, name, nameend - name);
9460 namealc[file_name_size + 1 + (nameend - name)] = ')';
9461 namealc[file_name_size + 2 + (nameend - name)] = '\0';
9462
9463 archive_file_offset = ftell (file);
9464 archive_file_size = strtoul (arhdr.ar_size, NULL, 10);
d70c5fc7 9465
d989285c 9466 ret |= process_object (namealc, file);
fb52b2f4
NC
9467
9468 free (namealc);
9469
9470 if (fseek (file,
9471 (archive_file_offset
9472 + archive_file_size
9473 + (archive_file_size & 1)),
9474 SEEK_SET) != 0)
9475 {
9476 error (_("%s: failed to seek to next archive header\n"), file_name);
d989285c
ILT
9477 ret = 1;
9478 break;
fb52b2f4
NC
9479 }
9480
9481 got = fread (&arhdr, 1, sizeof arhdr, file);
9482 if (got != sizeof arhdr)
9483 {
9484 if (got == 0)
d989285c 9485 break;
fb52b2f4
NC
9486
9487 error (_("%s: failed to read archive header\n"), file_name);
d989285c
ILT
9488 ret = 1;
9489 break;
fb52b2f4
NC
9490 }
9491 }
9492
9493 if (longnames != 0)
9494 free (longnames);
9495
d989285c 9496 return ret;
fb52b2f4
NC
9497}
9498
9499static int
9500process_file (char *file_name)
9501{
9502 FILE *file;
9503 struct stat statbuf;
9504 char armag[SARMAG];
9505 int ret;
9506
9507 if (stat (file_name, &statbuf) < 0)
9508 {
f24ddbdd
NC
9509 if (errno == ENOENT)
9510 error (_("'%s': No such file\n"), file_name);
9511 else
9512 error (_("Could not locate '%s'. System error message: %s\n"),
9513 file_name, strerror (errno));
9514 return 1;
9515 }
9516
9517 if (! S_ISREG (statbuf.st_mode))
9518 {
9519 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
9520 return 1;
9521 }
9522
9523 file = fopen (file_name, "rb");
9524 if (file == NULL)
9525 {
f24ddbdd 9526 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
9527 return 1;
9528 }
9529
9530 if (fread (armag, SARMAG, 1, file) != 1)
9531 {
9532 error (_("%s: Failed to read file header\n"), file_name);
9533 fclose (file);
9534 return 1;
9535 }
9536
9537 if (memcmp (armag, ARMAG, SARMAG) == 0)
9538 ret = process_archive (file_name, file);
9539 else
9540 {
9541 rewind (file);
9542 archive_file_size = archive_file_offset = 0;
9543 ret = process_object (file_name, file);
9544 }
9545
9546 fclose (file);
9547
9548 return ret;
9549}
9550
252b5132
RH
9551#ifdef SUPPORT_DISASSEMBLY
9552/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 9553 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 9554 symbols. */
252b5132
RH
9555
9556void
b34976b6 9557print_address (unsigned int addr, FILE *outfile)
252b5132
RH
9558{
9559 fprintf (outfile,"0x%8.8x", addr);
9560}
9561
e3c8793a 9562/* Needed by the i386 disassembler. */
252b5132
RH
9563void
9564db_task_printsym (unsigned int addr)
9565{
9566 print_address (addr, stderr);
9567}
9568#endif
9569
9570int
d3ba0551 9571main (int argc, char **argv)
252b5132 9572{
ff78d6d6
L
9573 int err;
9574
252b5132
RH
9575#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
9576 setlocale (LC_MESSAGES, "");
3882b010
L
9577#endif
9578#if defined (HAVE_SETLOCALE)
9579 setlocale (LC_CTYPE, "");
252b5132
RH
9580#endif
9581 bindtextdomain (PACKAGE, LOCALEDIR);
9582 textdomain (PACKAGE);
9583
869b9d07
MM
9584 expandargv (&argc, &argv);
9585
252b5132
RH
9586 parse_args (argc, argv);
9587
18bd398b 9588 if (num_dump_sects > 0)
59f14fc0 9589 {
18bd398b 9590 /* Make a copy of the dump_sects array. */
59f14fc0
AS
9591 cmdline_dump_sects = malloc (num_dump_sects);
9592 if (cmdline_dump_sects == NULL)
9593 error (_("Out of memory allocating dump request table."));
9594 else
9595 {
9596 memcpy (cmdline_dump_sects, dump_sects, num_dump_sects);
9597 num_cmdline_dump_sects = num_dump_sects;
9598 }
9599 }
9600
18bd398b
NC
9601 if (optind < (argc - 1))
9602 show_name = 1;
9603
ff78d6d6 9604 err = 0;
252b5132 9605 while (optind < argc)
18bd398b 9606 err |= process_file (argv[optind++]);
252b5132
RH
9607
9608 if (dump_sects != NULL)
9609 free (dump_sects);
59f14fc0
AS
9610 if (cmdline_dump_sects != NULL)
9611 free (cmdline_dump_sects);
252b5132 9612
ff78d6d6 9613 return err;
252b5132 9614}