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