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