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