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