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