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