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