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