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