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