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