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