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