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