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