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