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