2009-09-08 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
[deliverable/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 {
7f6fed87
NC
2729 case SHT_ARM_EXIDX: return "ARM_EXIDX";
2730 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
2731 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
2732 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
2733 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
2734 default:
2735 break;
2736 }
2737 return NULL;
2738}
2739
252b5132 2740static const char *
d3ba0551 2741get_section_type_name (unsigned int sh_type)
252b5132 2742{
b34976b6 2743 static char buff[32];
252b5132
RH
2744
2745 switch (sh_type)
2746 {
2747 case SHT_NULL: return "NULL";
2748 case SHT_PROGBITS: return "PROGBITS";
2749 case SHT_SYMTAB: return "SYMTAB";
2750 case SHT_STRTAB: return "STRTAB";
2751 case SHT_RELA: return "RELA";
2752 case SHT_HASH: return "HASH";
2753 case SHT_DYNAMIC: return "DYNAMIC";
2754 case SHT_NOTE: return "NOTE";
2755 case SHT_NOBITS: return "NOBITS";
2756 case SHT_REL: return "REL";
2757 case SHT_SHLIB: return "SHLIB";
2758 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
2759 case SHT_INIT_ARRAY: return "INIT_ARRAY";
2760 case SHT_FINI_ARRAY: return "FINI_ARRAY";
2761 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 2762 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
2763 case SHT_GROUP: return "GROUP";
2764 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
2765 case SHT_GNU_verdef: return "VERDEF";
2766 case SHT_GNU_verneed: return "VERNEED";
2767 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
2768 case 0x6ffffff0: return "VERSYM";
2769 case 0x6ffffffc: return "VERDEF";
252b5132
RH
2770 case 0x7ffffffd: return "AUXILIARY";
2771 case 0x7fffffff: return "FILTER";
047b2264 2772 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
2773
2774 default:
2775 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
2776 {
2cf0635d 2777 const char * result;
252b5132
RH
2778
2779 switch (elf_header.e_machine)
2780 {
2781 case EM_MIPS:
4fe85591 2782 case EM_MIPS_RS3_LE:
252b5132
RH
2783 result = get_mips_section_type_name (sh_type);
2784 break;
103f02d3
UD
2785 case EM_PARISC:
2786 result = get_parisc_section_type_name (sh_type);
2787 break;
4d6ed7c8
NC
2788 case EM_IA_64:
2789 result = get_ia64_section_type_name (sh_type);
2790 break;
d2b2c203 2791 case EM_X86_64:
8a9036a4 2792 case EM_L1OM:
d2b2c203
DJ
2793 result = get_x86_64_section_type_name (sh_type);
2794 break;
40a18ebd
NC
2795 case EM_ARM:
2796 result = get_arm_section_type_name (sh_type);
2797 break;
252b5132
RH
2798 default:
2799 result = NULL;
2800 break;
2801 }
2802
2803 if (result != NULL)
2804 return result;
2805
c91d0dfb 2806 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
2807 }
2808 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 2809 {
2cf0635d 2810 const char * result;
148b93f2
NC
2811
2812 switch (elf_header.e_machine)
2813 {
2814 case EM_IA_64:
2815 result = get_ia64_section_type_name (sh_type);
2816 break;
2817 default:
2818 result = NULL;
2819 break;
2820 }
2821
2822 if (result != NULL)
2823 return result;
2824
2825 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
2826 }
252b5132 2827 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 2828 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 2829 else
e9e44622 2830 snprintf (buff, sizeof (buff), _("<unknown>: %x"), sh_type);
103f02d3 2831
252b5132
RH
2832 return buff;
2833 }
2834}
2835
2979dc34
JJ
2836#define OPTION_DEBUG_DUMP 512
2837
85b1c36d 2838static struct option options[] =
252b5132 2839{
b34976b6 2840 {"all", no_argument, 0, 'a'},
252b5132
RH
2841 {"file-header", no_argument, 0, 'h'},
2842 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
2843 {"headers", no_argument, 0, 'e'},
2844 {"histogram", no_argument, 0, 'I'},
2845 {"segments", no_argument, 0, 'l'},
2846 {"sections", no_argument, 0, 'S'},
252b5132 2847 {"section-headers", no_argument, 0, 'S'},
f5842774 2848 {"section-groups", no_argument, 0, 'g'},
5477e8a0 2849 {"section-details", no_argument, 0, 't'},
595cf52e 2850 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
2851 {"symbols", no_argument, 0, 's'},
2852 {"syms", no_argument, 0, 's'},
2853 {"relocs", no_argument, 0, 'r'},
2854 {"notes", no_argument, 0, 'n'},
2855 {"dynamic", no_argument, 0, 'd'},
a952a375 2856 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
2857 {"version-info", no_argument, 0, 'V'},
2858 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 2859 {"unwind", no_argument, 0, 'u'},
4145f1d5 2860 {"archive-index", no_argument, 0, 'c'},
b34976b6 2861 {"hex-dump", required_argument, 0, 'x'},
cf13d699 2862 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 2863 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
2864#ifdef SUPPORT_DISASSEMBLY
2865 {"instruction-dump", required_argument, 0, 'i'},
2866#endif
cf13d699 2867 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 2868
b34976b6
AM
2869 {"version", no_argument, 0, 'v'},
2870 {"wide", no_argument, 0, 'W'},
2871 {"help", no_argument, 0, 'H'},
2872 {0, no_argument, 0, 0}
252b5132
RH
2873};
2874
2875static void
2cf0635d 2876usage (FILE * stream)
252b5132 2877{
92f01d61
JM
2878 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
2879 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
2880 fprintf (stream, _(" Options are:\n\
8b53311e
NC
2881 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
2882 -h --file-header Display the ELF file header\n\
2883 -l --program-headers Display the program headers\n\
2884 --segments An alias for --program-headers\n\
2885 -S --section-headers Display the sections' header\n\
2886 --sections An alias for --section-headers\n\
f5842774 2887 -g --section-groups Display the section groups\n\
5477e8a0 2888 -t --section-details Display the section details\n\
8b53311e
NC
2889 -e --headers Equivalent to: -h -l -S\n\
2890 -s --syms Display the symbol table\n\
2891 --symbols An alias for --syms\n\
2892 -n --notes Display the core notes (if present)\n\
2893 -r --relocs Display the relocations (if present)\n\
2894 -u --unwind Display the unwind info (if present)\n\
b2d38a17 2895 -d --dynamic Display the dynamic section (if present)\n\
8b53311e
NC
2896 -V --version-info Display the version sections (if present)\n\
2897 -A --arch-specific Display architecture specific information (if any).\n\
4145f1d5 2898 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 2899 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
2900 -x --hex-dump=<number|name>\n\
2901 Dump the contents of section <number|name> as bytes\n\
2902 -p --string-dump=<number|name>\n\
2903 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
2904 -R --relocated-dump=<number|name>\n\
2905 Dump the contents of section <number|name> as relocated bytes\n\
a262ae96
NC
2906 -w[lLiaprmfFsoR] or\n\
2907 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]\n\
8b53311e 2908 Display the contents of DWARF2 debug sections\n"));
252b5132 2909#ifdef SUPPORT_DISASSEMBLY
92f01d61 2910 fprintf (stream, _("\
09c11c86
NC
2911 -i --instruction-dump=<number|name>\n\
2912 Disassemble the contents of section <number|name>\n"));
252b5132 2913#endif
92f01d61 2914 fprintf (stream, _("\
8b53311e
NC
2915 -I --histogram Display histogram of bucket list lengths\n\
2916 -W --wide Allow output width to exceed 80 characters\n\
07012eee 2917 @<file> Read options from <file>\n\
8b53311e
NC
2918 -H --help Display this information\n\
2919 -v --version Display the version number of readelf\n"));
1118d252 2920
92f01d61
JM
2921 if (REPORT_BUGS_TO[0] && stream == stdout)
2922 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 2923
92f01d61 2924 exit (stream == stdout ? 0 : 1);
252b5132
RH
2925}
2926
18bd398b
NC
2927/* Record the fact that the user wants the contents of section number
2928 SECTION to be displayed using the method(s) encoded as flags bits
2929 in TYPE. Note, TYPE can be zero if we are creating the array for
2930 the first time. */
2931
252b5132 2932static void
09c11c86 2933request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
2934{
2935 if (section >= num_dump_sects)
2936 {
2cf0635d 2937 dump_type * new_dump_sects;
252b5132 2938
09c11c86 2939 new_dump_sects = calloc (section + 1, sizeof (* dump_sects));
252b5132
RH
2940
2941 if (new_dump_sects == NULL)
591a748a 2942 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
2943 else
2944 {
2945 /* Copy current flag settings. */
09c11c86 2946 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
2947
2948 free (dump_sects);
2949
2950 dump_sects = new_dump_sects;
2951 num_dump_sects = section + 1;
2952 }
2953 }
2954
2955 if (dump_sects)
b34976b6 2956 dump_sects[section] |= type;
252b5132
RH
2957
2958 return;
2959}
2960
aef1f6d0
DJ
2961/* Request a dump by section name. */
2962
2963static void
2cf0635d 2964request_dump_byname (const char * section, dump_type type)
aef1f6d0 2965{
2cf0635d 2966 struct dump_list_entry * new_request;
aef1f6d0
DJ
2967
2968 new_request = malloc (sizeof (struct dump_list_entry));
2969 if (!new_request)
591a748a 2970 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
2971
2972 new_request->name = strdup (section);
2973 if (!new_request->name)
591a748a 2974 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
2975
2976 new_request->type = type;
2977
2978 new_request->next = dump_sects_byname;
2979 dump_sects_byname = new_request;
2980}
2981
cf13d699
NC
2982static inline void
2983request_dump (dump_type type)
2984{
2985 int section;
2986 char * cp;
2987
2988 do_dump++;
2989 section = strtoul (optarg, & cp, 0);
2990
2991 if (! *cp && section >= 0)
2992 request_dump_bynumber (section, type);
2993 else
2994 request_dump_byname (optarg, type);
2995}
2996
2997
252b5132 2998static void
2cf0635d 2999parse_args (int argc, char ** argv)
252b5132
RH
3000{
3001 int c;
3002
3003 if (argc < 2)
92f01d61 3004 usage (stderr);
252b5132
RH
3005
3006 while ((c = getopt_long
cf13d699 3007 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3008 {
252b5132
RH
3009 switch (c)
3010 {
3011 case 0:
3012 /* Long options. */
3013 break;
3014 case 'H':
92f01d61 3015 usage (stdout);
252b5132
RH
3016 break;
3017
3018 case 'a':
b34976b6
AM
3019 do_syms++;
3020 do_reloc++;
3021 do_unwind++;
3022 do_dynamic++;
3023 do_header++;
3024 do_sections++;
f5842774 3025 do_section_groups++;
b34976b6
AM
3026 do_segments++;
3027 do_version++;
3028 do_histogram++;
3029 do_arch++;
3030 do_notes++;
252b5132 3031 break;
f5842774
L
3032 case 'g':
3033 do_section_groups++;
3034 break;
5477e8a0 3035 case 't':
595cf52e 3036 case 'N':
5477e8a0
L
3037 do_sections++;
3038 do_section_details++;
595cf52e 3039 break;
252b5132 3040 case 'e':
b34976b6
AM
3041 do_header++;
3042 do_sections++;
3043 do_segments++;
252b5132 3044 break;
a952a375 3045 case 'A':
b34976b6 3046 do_arch++;
a952a375 3047 break;
252b5132 3048 case 'D':
b34976b6 3049 do_using_dynamic++;
252b5132
RH
3050 break;
3051 case 'r':
b34976b6 3052 do_reloc++;
252b5132 3053 break;
4d6ed7c8 3054 case 'u':
b34976b6 3055 do_unwind++;
4d6ed7c8 3056 break;
252b5132 3057 case 'h':
b34976b6 3058 do_header++;
252b5132
RH
3059 break;
3060 case 'l':
b34976b6 3061 do_segments++;
252b5132
RH
3062 break;
3063 case 's':
b34976b6 3064 do_syms++;
252b5132
RH
3065 break;
3066 case 'S':
b34976b6 3067 do_sections++;
252b5132
RH
3068 break;
3069 case 'd':
b34976b6 3070 do_dynamic++;
252b5132 3071 break;
a952a375 3072 case 'I':
b34976b6 3073 do_histogram++;
a952a375 3074 break;
779fe533 3075 case 'n':
b34976b6 3076 do_notes++;
779fe533 3077 break;
4145f1d5
NC
3078 case 'c':
3079 do_archive_index++;
3080 break;
252b5132 3081 case 'x':
cf13d699 3082 request_dump (HEX_DUMP);
aef1f6d0 3083 break;
09c11c86 3084 case 'p':
cf13d699
NC
3085 request_dump (STRING_DUMP);
3086 break;
3087 case 'R':
3088 request_dump (RELOC_DUMP);
09c11c86 3089 break;
252b5132 3090 case 'w':
b34976b6 3091 do_dump++;
252b5132 3092 if (optarg == 0)
613ff48b
CC
3093 {
3094 do_debugging = 1;
3095 dwarf_select_sections_all ();
3096 }
252b5132
RH
3097 else
3098 {
3099 do_debugging = 0;
4cb93e3b 3100 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3101 }
3102 break;
2979dc34 3103 case OPTION_DEBUG_DUMP:
b34976b6 3104 do_dump++;
2979dc34
JJ
3105 if (optarg == 0)
3106 do_debugging = 1;
3107 else
3108 {
2979dc34 3109 do_debugging = 0;
4cb93e3b 3110 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3111 }
3112 break;
252b5132
RH
3113#ifdef SUPPORT_DISASSEMBLY
3114 case 'i':
cf13d699
NC
3115 request_dump (DISASS_DUMP);
3116 break;
252b5132
RH
3117#endif
3118 case 'v':
3119 print_version (program_name);
3120 break;
3121 case 'V':
b34976b6 3122 do_version++;
252b5132 3123 break;
d974e256 3124 case 'W':
b34976b6 3125 do_wide++;
d974e256 3126 break;
252b5132 3127 default:
252b5132
RH
3128 /* xgettext:c-format */
3129 error (_("Invalid option '-%c'\n"), c);
3130 /* Drop through. */
3131 case '?':
92f01d61 3132 usage (stderr);
252b5132
RH
3133 }
3134 }
3135
4d6ed7c8 3136 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3137 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3138 && !do_histogram && !do_debugging && !do_arch && !do_notes
4145f1d5 3139 && !do_section_groups && !do_archive_index)
92f01d61 3140 usage (stderr);
252b5132
RH
3141 else if (argc < 3)
3142 {
3143 warn (_("Nothing to do.\n"));
92f01d61 3144 usage (stderr);
252b5132
RH
3145 }
3146}
3147
3148static const char *
d3ba0551 3149get_elf_class (unsigned int elf_class)
252b5132 3150{
b34976b6 3151 static char buff[32];
103f02d3 3152
252b5132
RH
3153 switch (elf_class)
3154 {
3155 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3156 case ELFCLASS32: return "ELF32";
3157 case ELFCLASS64: return "ELF64";
ab5e7794 3158 default:
e9e44622 3159 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3160 return buff;
252b5132
RH
3161 }
3162}
3163
3164static const char *
d3ba0551 3165get_data_encoding (unsigned int encoding)
252b5132 3166{
b34976b6 3167 static char buff[32];
103f02d3 3168
252b5132
RH
3169 switch (encoding)
3170 {
3171 case ELFDATANONE: return _("none");
33c63f9d
CM
3172 case ELFDATA2LSB: return _("2's complement, little endian");
3173 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3174 default:
e9e44622 3175 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3176 return buff;
252b5132
RH
3177 }
3178}
3179
252b5132 3180/* Decode the data held in 'elf_header'. */
ee42cf8c 3181
252b5132 3182static int
d3ba0551 3183process_file_header (void)
252b5132 3184{
b34976b6
AM
3185 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3186 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3187 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3188 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3189 {
3190 error
3191 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3192 return 0;
3193 }
3194
2dc4cec1
L
3195 init_dwarf_regnames (elf_header.e_machine);
3196
252b5132
RH
3197 if (do_header)
3198 {
3199 int i;
3200
3201 printf (_("ELF Header:\n"));
3202 printf (_(" Magic: "));
b34976b6
AM
3203 for (i = 0; i < EI_NIDENT; i++)
3204 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3205 printf ("\n");
3206 printf (_(" Class: %s\n"),
b34976b6 3207 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3208 printf (_(" Data: %s\n"),
b34976b6 3209 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3210 printf (_(" Version: %d %s\n"),
b34976b6
AM
3211 elf_header.e_ident[EI_VERSION],
3212 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3213 ? "(current)"
b34976b6 3214 : (elf_header.e_ident[EI_VERSION] != EV_NONE
789be9f7
ILT
3215 ? "<unknown: %lx>"
3216 : "")));
252b5132 3217 printf (_(" OS/ABI: %s\n"),
b34976b6 3218 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3219 printf (_(" ABI Version: %d\n"),
b34976b6 3220 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3221 printf (_(" Type: %s\n"),
3222 get_file_type (elf_header.e_type));
3223 printf (_(" Machine: %s\n"),
3224 get_machine_name (elf_header.e_machine));
3225 printf (_(" Version: 0x%lx\n"),
3226 (unsigned long) elf_header.e_version);
76da6bbe 3227
f7a99963
NC
3228 printf (_(" Entry point address: "));
3229 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3230 printf (_("\n Start of program headers: "));
3231 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3232 printf (_(" (bytes into file)\n Start of section headers: "));
3233 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3234 printf (_(" (bytes into file)\n"));
76da6bbe 3235
252b5132
RH
3236 printf (_(" Flags: 0x%lx%s\n"),
3237 (unsigned long) elf_header.e_flags,
3238 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3239 printf (_(" Size of this header: %ld (bytes)\n"),
3240 (long) elf_header.e_ehsize);
3241 printf (_(" Size of program headers: %ld (bytes)\n"),
3242 (long) elf_header.e_phentsize);
3243 printf (_(" Number of program headers: %ld\n"),
3244 (long) elf_header.e_phnum);
3245 printf (_(" Size of section headers: %ld (bytes)\n"),
3246 (long) elf_header.e_shentsize);
560f3c1c 3247 printf (_(" Number of section headers: %ld"),
252b5132 3248 (long) elf_header.e_shnum);
4fbb74a6 3249 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3250 printf (" (%ld)", (long) section_headers[0].sh_size);
3251 putc ('\n', stdout);
3252 printf (_(" Section header string table index: %ld"),
252b5132 3253 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3254 if (section_headers != NULL
3255 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3256 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3257 else if (elf_header.e_shstrndx != SHN_UNDEF
3258 && elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3259 printf (" <corrupt: out of range>");
560f3c1c
AM
3260 putc ('\n', stdout);
3261 }
3262
3263 if (section_headers != NULL)
3264 {
4fbb74a6 3265 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3266 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3267 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3268 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3269 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3270 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3271 free (section_headers);
3272 section_headers = NULL;
252b5132 3273 }
103f02d3 3274
9ea033b2
NC
3275 return 1;
3276}
3277
252b5132 3278
9ea033b2 3279static int
2cf0635d 3280get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * program_headers)
9ea033b2 3281{
2cf0635d
NC
3282 Elf32_External_Phdr * phdrs;
3283 Elf32_External_Phdr * external;
3284 Elf_Internal_Phdr * internal;
b34976b6 3285 unsigned int i;
103f02d3 3286
d3ba0551 3287 phdrs = get_data (NULL, file, elf_header.e_phoff,
c256ffe7 3288 elf_header.e_phentsize, elf_header.e_phnum,
d3ba0551 3289 _("program headers"));
a6e9f9df
AM
3290 if (!phdrs)
3291 return 0;
9ea033b2
NC
3292
3293 for (i = 0, internal = program_headers, external = phdrs;
3294 i < elf_header.e_phnum;
b34976b6 3295 i++, internal++, external++)
252b5132 3296 {
9ea033b2
NC
3297 internal->p_type = BYTE_GET (external->p_type);
3298 internal->p_offset = BYTE_GET (external->p_offset);
3299 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3300 internal->p_paddr = BYTE_GET (external->p_paddr);
3301 internal->p_filesz = BYTE_GET (external->p_filesz);
3302 internal->p_memsz = BYTE_GET (external->p_memsz);
3303 internal->p_flags = BYTE_GET (external->p_flags);
3304 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3305 }
3306
9ea033b2
NC
3307 free (phdrs);
3308
252b5132
RH
3309 return 1;
3310}
3311
9ea033b2 3312static int
2cf0635d 3313get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * program_headers)
9ea033b2 3314{
2cf0635d
NC
3315 Elf64_External_Phdr * phdrs;
3316 Elf64_External_Phdr * external;
3317 Elf_Internal_Phdr * internal;
b34976b6 3318 unsigned int i;
103f02d3 3319
d3ba0551 3320 phdrs = get_data (NULL, file, elf_header.e_phoff,
c256ffe7 3321 elf_header.e_phentsize, elf_header.e_phnum,
d3ba0551 3322 _("program headers"));
a6e9f9df
AM
3323 if (!phdrs)
3324 return 0;
9ea033b2
NC
3325
3326 for (i = 0, internal = program_headers, external = phdrs;
3327 i < elf_header.e_phnum;
b34976b6 3328 i++, internal++, external++)
9ea033b2
NC
3329 {
3330 internal->p_type = BYTE_GET (external->p_type);
3331 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3332 internal->p_offset = BYTE_GET (external->p_offset);
3333 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3334 internal->p_paddr = BYTE_GET (external->p_paddr);
3335 internal->p_filesz = BYTE_GET (external->p_filesz);
3336 internal->p_memsz = BYTE_GET (external->p_memsz);
3337 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3338 }
3339
3340 free (phdrs);
3341
3342 return 1;
3343}
252b5132 3344
d93f0186
NC
3345/* Returns 1 if the program headers were read into `program_headers'. */
3346
3347static int
2cf0635d 3348get_program_headers (FILE * file)
d93f0186 3349{
2cf0635d 3350 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3351
3352 /* Check cache of prior read. */
3353 if (program_headers != NULL)
3354 return 1;
3355
c256ffe7 3356 phdrs = cmalloc (elf_header.e_phnum, sizeof (Elf_Internal_Phdr));
d93f0186
NC
3357
3358 if (phdrs == NULL)
3359 {
3360 error (_("Out of memory\n"));
3361 return 0;
3362 }
3363
3364 if (is_32bit_elf
3365 ? get_32bit_program_headers (file, phdrs)
3366 : get_64bit_program_headers (file, phdrs))
3367 {
3368 program_headers = phdrs;
3369 return 1;
3370 }
3371
3372 free (phdrs);
3373 return 0;
3374}
3375
2f62977e
NC
3376/* Returns 1 if the program headers were loaded. */
3377
252b5132 3378static int
2cf0635d 3379process_program_headers (FILE * file)
252b5132 3380{
2cf0635d 3381 Elf_Internal_Phdr * segment;
b34976b6 3382 unsigned int i;
252b5132
RH
3383
3384 if (elf_header.e_phnum == 0)
3385 {
3386 if (do_segments)
3387 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3388 return 0;
252b5132
RH
3389 }
3390
3391 if (do_segments && !do_header)
3392 {
f7a99963
NC
3393 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3394 printf (_("Entry point "));
3395 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3396 printf (_("\nThere are %d program headers, starting at offset "),
3397 elf_header.e_phnum);
3398 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3399 printf ("\n");
252b5132
RH
3400 }
3401
d93f0186 3402 if (! get_program_headers (file))
252b5132 3403 return 0;
103f02d3 3404
252b5132
RH
3405 if (do_segments)
3406 {
3a1a2036
NC
3407 if (elf_header.e_phnum > 1)
3408 printf (_("\nProgram Headers:\n"));
3409 else
3410 printf (_("\nProgram Headers:\n"));
76da6bbe 3411
f7a99963
NC
3412 if (is_32bit_elf)
3413 printf
3414 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3415 else if (do_wide)
3416 printf
3417 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3418 else
3419 {
3420 printf
3421 (_(" Type Offset VirtAddr PhysAddr\n"));
3422 printf
3423 (_(" FileSiz MemSiz Flags Align\n"));
3424 }
252b5132
RH
3425 }
3426
252b5132 3427 dynamic_addr = 0;
1b228002 3428 dynamic_size = 0;
252b5132
RH
3429
3430 for (i = 0, segment = program_headers;
3431 i < elf_header.e_phnum;
b34976b6 3432 i++, segment++)
252b5132
RH
3433 {
3434 if (do_segments)
3435 {
103f02d3 3436 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3437
3438 if (is_32bit_elf)
3439 {
3440 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3441 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3442 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3443 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3444 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3445 printf ("%c%c%c ",
3446 (segment->p_flags & PF_R ? 'R' : ' '),
3447 (segment->p_flags & PF_W ? 'W' : ' '),
3448 (segment->p_flags & PF_X ? 'E' : ' '));
3449 printf ("%#lx", (unsigned long) segment->p_align);
3450 }
d974e256
JJ
3451 else if (do_wide)
3452 {
3453 if ((unsigned long) segment->p_offset == segment->p_offset)
3454 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3455 else
3456 {
3457 print_vma (segment->p_offset, FULL_HEX);
3458 putchar (' ');
3459 }
3460
3461 print_vma (segment->p_vaddr, FULL_HEX);
3462 putchar (' ');
3463 print_vma (segment->p_paddr, FULL_HEX);
3464 putchar (' ');
3465
3466 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3467 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3468 else
3469 {
3470 print_vma (segment->p_filesz, FULL_HEX);
3471 putchar (' ');
3472 }
3473
3474 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3475 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3476 else
3477 {
3478 print_vma (segment->p_offset, FULL_HEX);
3479 }
3480
3481 printf (" %c%c%c ",
3482 (segment->p_flags & PF_R ? 'R' : ' '),
3483 (segment->p_flags & PF_W ? 'W' : ' '),
3484 (segment->p_flags & PF_X ? 'E' : ' '));
3485
3486 if ((unsigned long) segment->p_align == segment->p_align)
3487 printf ("%#lx", (unsigned long) segment->p_align);
3488 else
3489 {
3490 print_vma (segment->p_align, PREFIX_HEX);
3491 }
3492 }
f7a99963
NC
3493 else
3494 {
3495 print_vma (segment->p_offset, FULL_HEX);
3496 putchar (' ');
3497 print_vma (segment->p_vaddr, FULL_HEX);
3498 putchar (' ');
3499 print_vma (segment->p_paddr, FULL_HEX);
3500 printf ("\n ");
3501 print_vma (segment->p_filesz, FULL_HEX);
3502 putchar (' ');
3503 print_vma (segment->p_memsz, FULL_HEX);
3504 printf (" %c%c%c ",
3505 (segment->p_flags & PF_R ? 'R' : ' '),
3506 (segment->p_flags & PF_W ? 'W' : ' '),
3507 (segment->p_flags & PF_X ? 'E' : ' '));
3508 print_vma (segment->p_align, HEX);
3509 }
252b5132
RH
3510 }
3511
3512 switch (segment->p_type)
3513 {
252b5132
RH
3514 case PT_DYNAMIC:
3515 if (dynamic_addr)
3516 error (_("more than one dynamic segment\n"));
3517
20737c13
AM
3518 /* By default, assume that the .dynamic section is the first
3519 section in the DYNAMIC segment. */
3520 dynamic_addr = segment->p_offset;
3521 dynamic_size = segment->p_filesz;
3522
b2d38a17
NC
3523 /* Try to locate the .dynamic section. If there is
3524 a section header table, we can easily locate it. */
3525 if (section_headers != NULL)
3526 {
2cf0635d 3527 Elf_Internal_Shdr * sec;
b2d38a17 3528
89fac5e3
RS
3529 sec = find_section (".dynamic");
3530 if (sec == NULL || sec->sh_size == 0)
b2d38a17 3531 {
591a748a 3532 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
3533 break;
3534 }
3535
42bb2e33 3536 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
3537 {
3538 dynamic_size = 0;
3539 break;
3540 }
42bb2e33 3541
b2d38a17
NC
3542 dynamic_addr = sec->sh_offset;
3543 dynamic_size = sec->sh_size;
3544
3545 if (dynamic_addr < segment->p_offset
3546 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
3547 warn (_("the .dynamic section is not contained"
3548 " within the dynamic segment\n"));
b2d38a17 3549 else if (dynamic_addr > segment->p_offset)
20737c13
AM
3550 warn (_("the .dynamic section is not the first section"
3551 " in the dynamic segment.\n"));
b2d38a17 3552 }
252b5132
RH
3553 break;
3554
3555 case PT_INTERP:
fb52b2f4
NC
3556 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3557 SEEK_SET))
252b5132
RH
3558 error (_("Unable to find program interpreter name\n"));
3559 else
3560 {
f8eae8b2
L
3561 char fmt [32];
3562 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
3563
3564 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 3565 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 3566
252b5132 3567 program_interpreter[0] = 0;
7bd7b3ef
AM
3568 if (fscanf (file, fmt, program_interpreter) <= 0)
3569 error (_("Unable to read program interpreter name\n"));
252b5132
RH
3570
3571 if (do_segments)
3572 printf (_("\n [Requesting program interpreter: %s]"),
3573 program_interpreter);
3574 }
3575 break;
3576 }
3577
3578 if (do_segments)
3579 putc ('\n', stdout);
3580 }
3581
c256ffe7 3582 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
3583 {
3584 printf (_("\n Section to Segment mapping:\n"));
3585 printf (_(" Segment Sections...\n"));
3586
252b5132
RH
3587 for (i = 0; i < elf_header.e_phnum; i++)
3588 {
9ad5cbcf 3589 unsigned int j;
2cf0635d 3590 Elf_Internal_Shdr * section;
252b5132
RH
3591
3592 segment = program_headers + i;
b391a3e3 3593 section = section_headers + 1;
252b5132
RH
3594
3595 printf (" %2.2d ", i);
3596
b34976b6 3597 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 3598 {
2cf0635d 3599 if (ELF_IS_SECTION_IN_SEGMENT_MEMORY (section, segment))
252b5132
RH
3600 printf ("%s ", SECTION_NAME (section));
3601 }
3602
3603 putc ('\n',stdout);
3604 }
3605 }
3606
252b5132
RH
3607 return 1;
3608}
3609
3610
d93f0186
NC
3611/* Find the file offset corresponding to VMA by using the program headers. */
3612
3613static long
2cf0635d 3614offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 3615{
2cf0635d 3616 Elf_Internal_Phdr * seg;
d93f0186
NC
3617
3618 if (! get_program_headers (file))
3619 {
3620 warn (_("Cannot interpret virtual addresses without program headers.\n"));
3621 return (long) vma;
3622 }
3623
3624 for (seg = program_headers;
3625 seg < program_headers + elf_header.e_phnum;
3626 ++seg)
3627 {
3628 if (seg->p_type != PT_LOAD)
3629 continue;
3630
3631 if (vma >= (seg->p_vaddr & -seg->p_align)
3632 && vma + size <= seg->p_vaddr + seg->p_filesz)
3633 return vma - seg->p_vaddr + seg->p_offset;
3634 }
3635
3636 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 3637 (unsigned long) vma);
d93f0186
NC
3638 return (long) vma;
3639}
3640
3641
252b5132 3642static int
2cf0635d 3643get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 3644{
2cf0635d
NC
3645 Elf32_External_Shdr * shdrs;
3646 Elf_Internal_Shdr * internal;
b34976b6 3647 unsigned int i;
252b5132 3648
d3ba0551 3649 shdrs = get_data (NULL, file, elf_header.e_shoff,
c256ffe7 3650 elf_header.e_shentsize, num, _("section headers"));
a6e9f9df
AM
3651 if (!shdrs)
3652 return 0;
252b5132 3653
c256ffe7 3654 section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
252b5132
RH
3655
3656 if (section_headers == NULL)
3657 {
3658 error (_("Out of memory\n"));
3659 return 0;
3660 }
3661
3662 for (i = 0, internal = section_headers;
560f3c1c 3663 i < num;
b34976b6 3664 i++, internal++)
252b5132
RH
3665 {
3666 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3667 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
3668 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3669 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3670 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3671 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3672 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3673 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3674 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3675 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
3676 }
3677
3678 free (shdrs);
3679
3680 return 1;
3681}
3682
9ea033b2 3683static int
2cf0635d 3684get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 3685{
2cf0635d
NC
3686 Elf64_External_Shdr * shdrs;
3687 Elf_Internal_Shdr * internal;
b34976b6 3688 unsigned int i;
9ea033b2 3689
d3ba0551 3690 shdrs = get_data (NULL, file, elf_header.e_shoff,
c256ffe7 3691 elf_header.e_shentsize, num, _("section headers"));
a6e9f9df
AM
3692 if (!shdrs)
3693 return 0;
9ea033b2 3694
c256ffe7 3695 section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
9ea033b2
NC
3696
3697 if (section_headers == NULL)
3698 {
3699 error (_("Out of memory\n"));
3700 return 0;
3701 }
3702
3703 for (i = 0, internal = section_headers;
560f3c1c 3704 i < num;
b34976b6 3705 i++, internal++)
9ea033b2
NC
3706 {
3707 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3708 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
3709 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3710 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3711 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3712 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
3713 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3714 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3715 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3716 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3717 }
3718
3719 free (shdrs);
3720
3721 return 1;
3722}
3723
252b5132 3724static Elf_Internal_Sym *
2cf0635d 3725get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
252b5132 3726{
9ad5cbcf 3727 unsigned long number;
2cf0635d
NC
3728 Elf32_External_Sym * esyms;
3729 Elf_External_Sym_Shndx * shndx;
3730 Elf_Internal_Sym * isyms;
3731 Elf_Internal_Sym * psym;
b34976b6 3732 unsigned int j;
252b5132 3733
c256ffe7 3734 esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
d3ba0551 3735 _("symbols"));
a6e9f9df
AM
3736 if (!esyms)
3737 return NULL;
252b5132 3738
9ad5cbcf
AM
3739 shndx = NULL;
3740 if (symtab_shndx_hdr != NULL
3741 && (symtab_shndx_hdr->sh_link
4fbb74a6 3742 == (unsigned long) (section - section_headers)))
9ad5cbcf 3743 {
d3ba0551 3744 shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
c256ffe7 3745 1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
9ad5cbcf
AM
3746 if (!shndx)
3747 {
3748 free (esyms);
3749 return NULL;
3750 }
3751 }
3752
3753 number = section->sh_size / section->sh_entsize;
c256ffe7 3754 isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
3755
3756 if (isyms == NULL)
3757 {
3758 error (_("Out of memory\n"));
9ad5cbcf
AM
3759 if (shndx)
3760 free (shndx);
252b5132 3761 free (esyms);
252b5132
RH
3762 return NULL;
3763 }
3764
3765 for (j = 0, psym = isyms;
3766 j < number;
b34976b6 3767 j++, psym++)
252b5132
RH
3768 {
3769 psym->st_name = BYTE_GET (esyms[j].st_name);
3770 psym->st_value = BYTE_GET (esyms[j].st_value);
3771 psym->st_size = BYTE_GET (esyms[j].st_size);
3772 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 3773 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
3774 psym->st_shndx
3775 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
3776 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
3777 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
3778 psym->st_info = BYTE_GET (esyms[j].st_info);
3779 psym->st_other = BYTE_GET (esyms[j].st_other);
3780 }
3781
9ad5cbcf
AM
3782 if (shndx)
3783 free (shndx);
252b5132
RH
3784 free (esyms);
3785
3786 return isyms;
3787}
3788
9ea033b2 3789static Elf_Internal_Sym *
2cf0635d 3790get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
9ea033b2 3791{
9ad5cbcf 3792 unsigned long number;
2cf0635d
NC
3793 Elf64_External_Sym * esyms;
3794 Elf_External_Sym_Shndx * shndx;
3795 Elf_Internal_Sym * isyms;
3796 Elf_Internal_Sym * psym;
b34976b6 3797 unsigned int j;
9ea033b2 3798
c256ffe7 3799 esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
d3ba0551 3800 _("symbols"));
a6e9f9df
AM
3801 if (!esyms)
3802 return NULL;
9ea033b2 3803
9ad5cbcf
AM
3804 shndx = NULL;
3805 if (symtab_shndx_hdr != NULL
3806 && (symtab_shndx_hdr->sh_link
4fbb74a6 3807 == (unsigned long) (section - section_headers)))
9ad5cbcf 3808 {
d3ba0551 3809 shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
c256ffe7 3810 1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
9ad5cbcf
AM
3811 if (!shndx)
3812 {
3813 free (esyms);
3814 return NULL;
3815 }
3816 }
3817
3818 number = section->sh_size / section->sh_entsize;
c256ffe7 3819 isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
3820
3821 if (isyms == NULL)
3822 {
3823 error (_("Out of memory\n"));
9ad5cbcf
AM
3824 if (shndx)
3825 free (shndx);
9ea033b2 3826 free (esyms);
9ea033b2
NC
3827 return NULL;
3828 }
3829
3830 for (j = 0, psym = isyms;
3831 j < number;
b34976b6 3832 j++, psym++)
9ea033b2
NC
3833 {
3834 psym->st_name = BYTE_GET (esyms[j].st_name);
3835 psym->st_info = BYTE_GET (esyms[j].st_info);
3836 psym->st_other = BYTE_GET (esyms[j].st_other);
3837 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 3838 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
3839 psym->st_shndx
3840 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
3841 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
3842 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
66543521
AM
3843 psym->st_value = BYTE_GET (esyms[j].st_value);
3844 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
3845 }
3846
9ad5cbcf
AM
3847 if (shndx)
3848 free (shndx);
9ea033b2
NC
3849 free (esyms);
3850
3851 return isyms;
3852}
3853
d1133906 3854static const char *
d3ba0551 3855get_elf_section_flags (bfd_vma sh_flags)
d1133906 3856{
5477e8a0 3857 static char buff[1024];
2cf0635d 3858 char * p = buff;
8d5ff12c
L
3859 int field_size = is_32bit_elf ? 8 : 16;
3860 int index, size = sizeof (buff) - (field_size + 4 + 1);
3861 bfd_vma os_flags = 0;
3862 bfd_vma proc_flags = 0;
3863 bfd_vma unknown_flags = 0;
148b93f2 3864 static const struct
5477e8a0 3865 {
2cf0635d 3866 const char * str;
5477e8a0
L
3867 int len;
3868 }
3869 flags [] =
3870 {
3871 { "WRITE", 5 },
3872 { "ALLOC", 5 },
3873 { "EXEC", 4 },
3874 { "MERGE", 5 },
3875 { "STRINGS", 7 },
3876 { "INFO LINK", 9 },
3877 { "LINK ORDER", 10 },
3878 { "OS NONCONF", 10 },
3879 { "GROUP", 5 },
148b93f2
NC
3880 { "TLS", 3 },
3881 /* IA-64 specific. */
3882 { "SHORT", 5 },
3883 { "NORECOV", 7 },
3884 /* IA-64 OpenVMS specific. */
3885 { "VMS_GLOBAL", 10 },
3886 { "VMS_OVERLAID", 12 },
3887 { "VMS_SHARED", 10 },
3888 { "VMS_VECTOR", 10 },
3889 { "VMS_ALLOC_64BIT", 15 },
3890 { "VMS_PROTECTED", 13}
5477e8a0
L
3891 };
3892
3893 if (do_section_details)
3894 {
8d5ff12c
L
3895 sprintf (buff, "[%*.*lx]: ",
3896 field_size, field_size, (unsigned long) sh_flags);
3897 p += field_size + 4;
5477e8a0 3898 }
76da6bbe 3899
d1133906
NC
3900 while (sh_flags)
3901 {
3902 bfd_vma flag;
3903
3904 flag = sh_flags & - sh_flags;
3905 sh_flags &= ~ flag;
76da6bbe 3906
5477e8a0 3907 if (do_section_details)
d1133906 3908 {
5477e8a0
L
3909 switch (flag)
3910 {
3911 case SHF_WRITE: index = 0; break;
3912 case SHF_ALLOC: index = 1; break;
3913 case SHF_EXECINSTR: index = 2; break;
3914 case SHF_MERGE: index = 3; break;
3915 case SHF_STRINGS: index = 4; break;
3916 case SHF_INFO_LINK: index = 5; break;
3917 case SHF_LINK_ORDER: index = 6; break;
3918 case SHF_OS_NONCONFORMING: index = 7; break;
3919 case SHF_GROUP: index = 8; break;
3920 case SHF_TLS: index = 9; break;
76da6bbe 3921
5477e8a0
L
3922 default:
3923 index = -1;
148b93f2
NC
3924 if (elf_header.e_machine == EM_IA_64)
3925 {
3926 if (flag == SHF_IA_64_SHORT)
3927 index = 10;
3928 else if (flag == SHF_IA_64_NORECOV)
3929 index = 11;
3930#ifdef BFD64
3931 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3932 switch (flag)
3933 {
3934 case SHF_IA_64_VMS_GLOBAL: index = 12; break;
3935 case SHF_IA_64_VMS_OVERLAID: index = 13; break;
3936 case SHF_IA_64_VMS_SHARED: index = 14; break;
3937 case SHF_IA_64_VMS_VECTOR: index = 15; break;
3938 case SHF_IA_64_VMS_ALLOC_64BIT: index = 16; break;
3939 case SHF_IA_64_VMS_PROTECTED: index = 17; break;
3940 default: break;
3941 }
3942#endif
3943 }
5477e8a0
L
3944 break;
3945 }
3946
5477e8a0
L
3947 if (index != -1)
3948 {
8d5ff12c
L
3949 if (p != buff + field_size + 4)
3950 {
3951 if (size < (10 + 2))
3952 abort ();
3953 size -= 2;
3954 *p++ = ',';
3955 *p++ = ' ';
3956 }
3957
5477e8a0
L
3958 size -= flags [index].len;
3959 p = stpcpy (p, flags [index].str);
3960 }
3b22753a 3961 else if (flag & SHF_MASKOS)
8d5ff12c 3962 os_flags |= flag;
d1133906 3963 else if (flag & SHF_MASKPROC)
8d5ff12c 3964 proc_flags |= flag;
d1133906 3965 else
8d5ff12c 3966 unknown_flags |= flag;
5477e8a0
L
3967 }
3968 else
3969 {
3970 switch (flag)
3971 {
3972 case SHF_WRITE: *p = 'W'; break;
3973 case SHF_ALLOC: *p = 'A'; break;
3974 case SHF_EXECINSTR: *p = 'X'; break;
3975 case SHF_MERGE: *p = 'M'; break;
3976 case SHF_STRINGS: *p = 'S'; break;
3977 case SHF_INFO_LINK: *p = 'I'; break;
3978 case SHF_LINK_ORDER: *p = 'L'; break;
3979 case SHF_OS_NONCONFORMING: *p = 'O'; break;
3980 case SHF_GROUP: *p = 'G'; break;
3981 case SHF_TLS: *p = 'T'; break;
3982
3983 default:
8a9036a4
L
3984 if ((elf_header.e_machine == EM_X86_64
3985 || elf_header.e_machine == EM_L1OM)
5477e8a0
L
3986 && flag == SHF_X86_64_LARGE)
3987 *p = 'l';
3988 else if (flag & SHF_MASKOS)
3989 {
3990 *p = 'o';
3991 sh_flags &= ~ SHF_MASKOS;
3992 }
3993 else if (flag & SHF_MASKPROC)
3994 {
3995 *p = 'p';
3996 sh_flags &= ~ SHF_MASKPROC;
3997 }
3998 else
3999 *p = 'x';
4000 break;
4001 }
4002 p++;
d1133906
NC
4003 }
4004 }
76da6bbe 4005
8d5ff12c
L
4006 if (do_section_details)
4007 {
4008 if (os_flags)
4009 {
4010 size -= 5 + field_size;
4011 if (p != buff + field_size + 4)
4012 {
4013 if (size < (2 + 1))
4014 abort ();
4015 size -= 2;
4016 *p++ = ',';
4017 *p++ = ' ';
4018 }
4019 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4020 (unsigned long) os_flags);
4021 p += 5 + field_size;
4022 }
4023 if (proc_flags)
4024 {
4025 size -= 7 + field_size;
4026 if (p != buff + field_size + 4)
4027 {
4028 if (size < (2 + 1))
4029 abort ();
4030 size -= 2;
4031 *p++ = ',';
4032 *p++ = ' ';
4033 }
4034 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4035 (unsigned long) proc_flags);
4036 p += 7 + field_size;
4037 }
4038 if (unknown_flags)
4039 {
4040 size -= 10 + field_size;
4041 if (p != buff + field_size + 4)
4042 {
4043 if (size < (2 + 1))
4044 abort ();
4045 size -= 2;
4046 *p++ = ',';
4047 *p++ = ' ';
4048 }
4049 sprintf (p, "UNKNOWN (%*.*lx)", field_size, field_size,
4050 (unsigned long) unknown_flags);
4051 p += 10 + field_size;
4052 }
4053 }
4054
e9e44622 4055 *p = '\0';
d1133906
NC
4056 return buff;
4057}
4058
252b5132 4059static int
2cf0635d 4060process_section_headers (FILE * file)
252b5132 4061{
2cf0635d 4062 Elf_Internal_Shdr * section;
b34976b6 4063 unsigned int i;
252b5132
RH
4064
4065 section_headers = NULL;
4066
4067 if (elf_header.e_shnum == 0)
4068 {
4069 if (do_sections)
4070 printf (_("\nThere are no sections in this file.\n"));
4071
4072 return 1;
4073 }
4074
4075 if (do_sections && !do_header)
9ea033b2 4076 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4077 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4078
9ea033b2
NC
4079 if (is_32bit_elf)
4080 {
560f3c1c 4081 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4082 return 0;
4083 }
560f3c1c 4084 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4085 return 0;
4086
4087 /* Read in the string table, so that we have names to display. */
0b49d371 4088 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4089 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4090 {
4fbb74a6 4091 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4092
c256ffe7
JJ
4093 if (section->sh_size != 0)
4094 {
4095 string_table = get_data (NULL, file, section->sh_offset,
4096 1, section->sh_size, _("string table"));
0de14b54 4097
c256ffe7
JJ
4098 string_table_length = string_table != NULL ? section->sh_size : 0;
4099 }
252b5132
RH
4100 }
4101
4102 /* Scan the sections for the dynamic symbol table
e3c8793a 4103 and dynamic string table and debug sections. */
252b5132
RH
4104 dynamic_symbols = NULL;
4105 dynamic_strings = NULL;
4106 dynamic_syminfo = NULL;
f1ef08cb 4107 symtab_shndx_hdr = NULL;
103f02d3 4108
89fac5e3
RS
4109 eh_addr_size = is_32bit_elf ? 4 : 8;
4110 switch (elf_header.e_machine)
4111 {
4112 case EM_MIPS:
4113 case EM_MIPS_RS3_LE:
4114 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4115 FDE addresses. However, the ABI also has a semi-official ILP32
4116 variant for which the normal FDE address size rules apply.
4117
4118 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4119 section, where XX is the size of longs in bits. Unfortunately,
4120 earlier compilers provided no way of distinguishing ILP32 objects
4121 from LP64 objects, so if there's any doubt, we should assume that
4122 the official LP64 form is being used. */
4123 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4124 && find_section (".gcc_compiled_long32") == NULL)
4125 eh_addr_size = 8;
4126 break;
0f56a26a
DD
4127
4128 case EM_H8_300:
4129 case EM_H8_300H:
4130 switch (elf_header.e_flags & EF_H8_MACH)
4131 {
4132 case E_H8_MACH_H8300:
4133 case E_H8_MACH_H8300HN:
4134 case E_H8_MACH_H8300SN:
4135 case E_H8_MACH_H8300SXN:
4136 eh_addr_size = 2;
4137 break;
4138 case E_H8_MACH_H8300H:
4139 case E_H8_MACH_H8300S:
4140 case E_H8_MACH_H8300SX:
4141 eh_addr_size = 4;
4142 break;
4143 }
f4236fe4
DD
4144 break;
4145
ff7eeb89 4146 case EM_M32C_OLD:
f4236fe4
DD
4147 case EM_M32C:
4148 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4149 {
4150 case EF_M32C_CPU_M16C:
4151 eh_addr_size = 2;
4152 break;
4153 }
4154 break;
89fac5e3
RS
4155 }
4156
08d8fa11
JJ
4157#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4158 do \
4159 { \
4160 size_t expected_entsize \
4161 = is_32bit_elf ? size32 : size64; \
4162 if (section->sh_entsize != expected_entsize) \
4163 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4164 i, (unsigned long int) section->sh_entsize, \
4165 (unsigned long int) expected_entsize); \
4166 section->sh_entsize = expected_entsize; \
4167 } \
4168 while (0)
4169#define CHECK_ENTSIZE(section, i, type) \
4170 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4171 sizeof (Elf64_External_##type))
4172
252b5132
RH
4173 for (i = 0, section = section_headers;
4174 i < elf_header.e_shnum;
b34976b6 4175 i++, section++)
252b5132 4176 {
2cf0635d 4177 char * name = SECTION_NAME (section);
252b5132
RH
4178
4179 if (section->sh_type == SHT_DYNSYM)
4180 {
4181 if (dynamic_symbols != NULL)
4182 {
4183 error (_("File contains multiple dynamic symbol tables\n"));
4184 continue;
4185 }
4186
08d8fa11 4187 CHECK_ENTSIZE (section, i, Sym);
19936277 4188 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 4189 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
4190 }
4191 else if (section->sh_type == SHT_STRTAB
18bd398b 4192 && streq (name, ".dynstr"))
252b5132
RH
4193 {
4194 if (dynamic_strings != NULL)
4195 {
4196 error (_("File contains multiple dynamic string tables\n"));
4197 continue;
4198 }
4199
d3ba0551 4200 dynamic_strings = get_data (NULL, file, section->sh_offset,
c256ffe7 4201 1, section->sh_size, _("dynamic strings"));
d79b3d50 4202 dynamic_strings_length = section->sh_size;
252b5132 4203 }
9ad5cbcf
AM
4204 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4205 {
4206 if (symtab_shndx_hdr != NULL)
4207 {
4208 error (_("File contains multiple symtab shndx tables\n"));
4209 continue;
4210 }
4211 symtab_shndx_hdr = section;
4212 }
08d8fa11
JJ
4213 else if (section->sh_type == SHT_SYMTAB)
4214 CHECK_ENTSIZE (section, i, Sym);
4215 else if (section->sh_type == SHT_GROUP)
4216 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4217 else if (section->sh_type == SHT_REL)
4218 CHECK_ENTSIZE (section, i, Rel);
4219 else if (section->sh_type == SHT_RELA)
4220 CHECK_ENTSIZE (section, i, Rela);
252b5132 4221 else if ((do_debugging || do_debug_info || do_debug_abbrevs
4cb93e3b 4222 || do_debug_lines || do_debug_pubnames
cb8f3167 4223 || do_debug_aranges || do_debug_frames || do_debug_macinfo
a262ae96 4224 || do_debug_str || do_debug_loc || do_debug_ranges)
1b315056
CS
4225 && (const_strneq (name, ".debug_")
4226 || const_strneq (name, ".zdebug_")))
252b5132 4227 {
1b315056
CS
4228 if (name[1] == 'z')
4229 name += sizeof (".zdebug_") - 1;
4230 else
4231 name += sizeof (".debug_") - 1;
252b5132
RH
4232
4233 if (do_debugging
18bd398b
NC
4234 || (do_debug_info && streq (name, "info"))
4235 || (do_debug_abbrevs && streq (name, "abbrev"))
4cb93e3b 4236 || (do_debug_lines && streq (name, "line"))
18bd398b
NC
4237 || (do_debug_pubnames && streq (name, "pubnames"))
4238 || (do_debug_aranges && streq (name, "aranges"))
4239 || (do_debug_ranges && streq (name, "ranges"))
4240 || (do_debug_frames && streq (name, "frame"))
4241 || (do_debug_macinfo && streq (name, "macinfo"))
4242 || (do_debug_str && streq (name, "str"))
4243 || (do_debug_loc && streq (name, "loc"))
252b5132 4244 )
09c11c86 4245 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4246 }
a262ae96 4247 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4248 else if ((do_debugging || do_debug_info)
0112cd26 4249 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4250 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4251 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4252 request_dump_bynumber (i, DEBUG_DUMP);
252b5132
RH
4253 }
4254
4255 if (! do_sections)
4256 return 1;
4257
3a1a2036
NC
4258 if (elf_header.e_shnum > 1)
4259 printf (_("\nSection Headers:\n"));
4260 else
4261 printf (_("\nSection Header:\n"));
76da6bbe 4262
f7a99963 4263 if (is_32bit_elf)
595cf52e 4264 {
5477e8a0 4265 if (do_section_details)
595cf52e
L
4266 {
4267 printf (_(" [Nr] Name\n"));
5477e8a0 4268 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4269 }
4270 else
4271 printf
4272 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4273 }
d974e256 4274 else if (do_wide)
595cf52e 4275 {
5477e8a0 4276 if (do_section_details)
595cf52e
L
4277 {
4278 printf (_(" [Nr] Name\n"));
5477e8a0 4279 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4280 }
4281 else
4282 printf
4283 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4284 }
f7a99963
NC
4285 else
4286 {
5477e8a0 4287 if (do_section_details)
595cf52e
L
4288 {
4289 printf (_(" [Nr] Name\n"));
5477e8a0
L
4290 printf (_(" Type Address Offset Link\n"));
4291 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4292 }
4293 else
4294 {
4295 printf (_(" [Nr] Name Type Address Offset\n"));
4296 printf (_(" Size EntSize Flags Link Info Align\n"));
4297 }
f7a99963 4298 }
252b5132 4299
5477e8a0
L
4300 if (do_section_details)
4301 printf (_(" Flags\n"));
4302
252b5132
RH
4303 for (i = 0, section = section_headers;
4304 i < elf_header.e_shnum;
b34976b6 4305 i++, section++)
252b5132 4306 {
5477e8a0 4307 if (do_section_details)
595cf52e
L
4308 {
4309 printf (" [%2u] %s\n",
4fbb74a6 4310 i,
595cf52e
L
4311 SECTION_NAME (section));
4312 if (is_32bit_elf || do_wide)
4313 printf (" %-15.15s ",
4314 get_section_type_name (section->sh_type));
4315 }
4316 else
b9eb56c1
NC
4317 printf ((do_wide ? " [%2u] %-17s %-15s "
4318 : " [%2u] %-17.17s %-15.15s "),
4fbb74a6 4319 i,
595cf52e
L
4320 SECTION_NAME (section),
4321 get_section_type_name (section->sh_type));
252b5132 4322
f7a99963
NC
4323 if (is_32bit_elf)
4324 {
4325 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4326
f7a99963
NC
4327 printf ( " %6.6lx %6.6lx %2.2lx",
4328 (unsigned long) section->sh_offset,
4329 (unsigned long) section->sh_size,
4330 (unsigned long) section->sh_entsize);
d1133906 4331
5477e8a0
L
4332 if (do_section_details)
4333 fputs (" ", stdout);
4334 else
4335 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4336
72de5009
AM
4337 printf ("%2u %3u %2lu\n",
4338 section->sh_link,
4339 section->sh_info,
f7a99963
NC
4340 (unsigned long) section->sh_addralign);
4341 }
d974e256
JJ
4342 else if (do_wide)
4343 {
4344 print_vma (section->sh_addr, LONG_HEX);
4345
4346 if ((long) section->sh_offset == section->sh_offset)
4347 printf (" %6.6lx", (unsigned long) section->sh_offset);
4348 else
4349 {
4350 putchar (' ');
4351 print_vma (section->sh_offset, LONG_HEX);
4352 }
4353
4354 if ((unsigned long) section->sh_size == section->sh_size)
4355 printf (" %6.6lx", (unsigned long) section->sh_size);
4356 else
4357 {
4358 putchar (' ');
4359 print_vma (section->sh_size, LONG_HEX);
4360 }
4361
4362 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4363 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4364 else
4365 {
4366 putchar (' ');
4367 print_vma (section->sh_entsize, LONG_HEX);
4368 }
4369
5477e8a0
L
4370 if (do_section_details)
4371 fputs (" ", stdout);
4372 else
4373 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4374
72de5009 4375 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
4376
4377 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 4378 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
4379 else
4380 {
4381 print_vma (section->sh_addralign, DEC);
4382 putchar ('\n');
4383 }
4384 }
5477e8a0 4385 else if (do_section_details)
595cf52e 4386 {
5477e8a0 4387 printf (" %-15.15s ",
595cf52e 4388 get_section_type_name (section->sh_type));
595cf52e
L
4389 print_vma (section->sh_addr, LONG_HEX);
4390 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4391 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4392 else
4393 {
4394 printf (" ");
4395 print_vma (section->sh_offset, LONG_HEX);
4396 }
72de5009 4397 printf (" %u\n ", section->sh_link);
595cf52e 4398 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4399 putchar (' ');
595cf52e
L
4400 print_vma (section->sh_entsize, LONG_HEX);
4401
72de5009
AM
4402 printf (" %-16u %lu\n",
4403 section->sh_info,
595cf52e
L
4404 (unsigned long) section->sh_addralign);
4405 }
f7a99963
NC
4406 else
4407 {
4408 putchar (' ');
4409 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4410 if ((long) section->sh_offset == section->sh_offset)
4411 printf (" %8.8lx", (unsigned long) section->sh_offset);
4412 else
4413 {
4414 printf (" ");
4415 print_vma (section->sh_offset, LONG_HEX);
4416 }
f7a99963
NC
4417 printf ("\n ");
4418 print_vma (section->sh_size, LONG_HEX);
4419 printf (" ");
4420 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4421
d1133906 4422 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4423
72de5009
AM
4424 printf (" %2u %3u %lu\n",
4425 section->sh_link,
4426 section->sh_info,
f7a99963
NC
4427 (unsigned long) section->sh_addralign);
4428 }
5477e8a0
L
4429
4430 if (do_section_details)
4431 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4432 }
4433
5477e8a0
L
4434 if (!do_section_details)
4435 printf (_("Key to Flags:\n\
e3c8793a
NC
4436 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
4437 I (info), L (link order), G (group), x (unknown)\n\
4438 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
d1133906 4439
252b5132
RH
4440 return 1;
4441}
4442
f5842774
L
4443static const char *
4444get_group_flags (unsigned int flags)
4445{
4446 static char buff[32];
4447 switch (flags)
4448 {
4449 case GRP_COMDAT:
4450 return "COMDAT";
4451
4452 default:
e9e44622 4453 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x]"), flags);
f5842774
L
4454 break;
4455 }
4456 return buff;
4457}
4458
4459static int
2cf0635d 4460process_section_groups (FILE * file)
f5842774 4461{
2cf0635d 4462 Elf_Internal_Shdr * section;
f5842774 4463 unsigned int i;
2cf0635d
NC
4464 struct group * group;
4465 Elf_Internal_Shdr * symtab_sec;
4466 Elf_Internal_Shdr * strtab_sec;
4467 Elf_Internal_Sym * symtab;
4468 char * strtab;
c256ffe7 4469 size_t strtab_size;
d1f5c6e3
L
4470
4471 /* Don't process section groups unless needed. */
4472 if (!do_unwind && !do_section_groups)
4473 return 1;
f5842774
L
4474
4475 if (elf_header.e_shnum == 0)
4476 {
4477 if (do_section_groups)
d1f5c6e3 4478 printf (_("\nThere are no sections in this file.\n"));
f5842774
L
4479
4480 return 1;
4481 }
4482
4483 if (section_headers == NULL)
4484 {
4485 error (_("Section headers are not available!\n"));
4486 abort ();
4487 }
4488
e4b17d5c
L
4489 section_headers_groups = calloc (elf_header.e_shnum,
4490 sizeof (struct group *));
4491
4492 if (section_headers_groups == NULL)
4493 {
4494 error (_("Out of memory\n"));
4495 return 0;
4496 }
4497
f5842774 4498 /* Scan the sections for the group section. */
d1f5c6e3 4499 group_count = 0;
f5842774
L
4500 for (i = 0, section = section_headers;
4501 i < elf_header.e_shnum;
4502 i++, section++)
e4b17d5c
L
4503 if (section->sh_type == SHT_GROUP)
4504 group_count++;
4505
d1f5c6e3
L
4506 if (group_count == 0)
4507 {
4508 if (do_section_groups)
4509 printf (_("\nThere are no section groups in this file.\n"));
4510
4511 return 1;
4512 }
4513
e4b17d5c
L
4514 section_groups = calloc (group_count, sizeof (struct group));
4515
4516 if (section_groups == NULL)
4517 {
4518 error (_("Out of memory\n"));
4519 return 0;
4520 }
4521
d1f5c6e3
L
4522 symtab_sec = NULL;
4523 strtab_sec = NULL;
4524 symtab = NULL;
4525 strtab = NULL;
c256ffe7 4526 strtab_size = 0;
e4b17d5c
L
4527 for (i = 0, section = section_headers, group = section_groups;
4528 i < elf_header.e_shnum;
4529 i++, section++)
f5842774
L
4530 {
4531 if (section->sh_type == SHT_GROUP)
4532 {
2cf0635d
NC
4533 char * name = SECTION_NAME (section);
4534 char * group_name;
4535 unsigned char * start;
4536 unsigned char * indices;
f5842774 4537 unsigned int entry, j, size;
2cf0635d
NC
4538 Elf_Internal_Shdr * sec;
4539 Elf_Internal_Sym * sym;
f5842774
L
4540
4541 /* Get the symbol table. */
4fbb74a6
AM
4542 if (section->sh_link >= elf_header.e_shnum
4543 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 4544 != SHT_SYMTAB))
f5842774
L
4545 {
4546 error (_("Bad sh_link in group section `%s'\n"), name);
4547 continue;
4548 }
d1f5c6e3
L
4549
4550 if (symtab_sec != sec)
4551 {
4552 symtab_sec = sec;
4553 if (symtab)
4554 free (symtab);
4555 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
4556 }
f5842774
L
4557
4558 sym = symtab + section->sh_info;
4559
4560 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4561 {
4fbb74a6
AM
4562 if (sym->st_shndx == 0
4563 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
4564 {
4565 error (_("Bad sh_info in group section `%s'\n"), name);
4566 continue;
4567 }
ba2685cc 4568
4fbb74a6 4569 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
4570 strtab_sec = NULL;
4571 if (strtab)
4572 free (strtab);
f5842774 4573 strtab = NULL;
c256ffe7 4574 strtab_size = 0;
f5842774
L
4575 }
4576 else
4577 {
4578 /* Get the string table. */
4fbb74a6 4579 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
4580 {
4581 strtab_sec = NULL;
4582 if (strtab)
4583 free (strtab);
4584 strtab = NULL;
4585 strtab_size = 0;
4586 }
4587 else if (strtab_sec
4fbb74a6 4588 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
4589 {
4590 strtab_sec = sec;
4591 if (strtab)
4592 free (strtab);
4593 strtab = get_data (NULL, file, strtab_sec->sh_offset,
c256ffe7 4594 1, strtab_sec->sh_size,
d1f5c6e3 4595 _("string table"));
c256ffe7 4596 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 4597 }
c256ffe7
JJ
4598 group_name = sym->st_name < strtab_size
4599 ? strtab + sym->st_name : "<corrupt>";
f5842774
L
4600 }
4601
4602 start = get_data (NULL, file, section->sh_offset,
c256ffe7 4603 1, section->sh_size, _("section data"));
f5842774
L
4604
4605 indices = start;
4606 size = (section->sh_size / section->sh_entsize) - 1;
4607 entry = byte_get (indices, 4);
4608 indices += 4;
e4b17d5c
L
4609
4610 if (do_section_groups)
4611 {
391cb864
L
4612 printf ("\n%s group section [%5u] `%s' [%s] contains %u sections:\n",
4613 get_group_flags (entry), i, name, group_name, size);
ba2685cc 4614
e4b17d5c
L
4615 printf (_(" [Index] Name\n"));
4616 }
4617
4618 group->group_index = i;
4619
f5842774
L
4620 for (j = 0; j < size; j++)
4621 {
2cf0635d 4622 struct group_list * g;
e4b17d5c 4623
f5842774
L
4624 entry = byte_get (indices, 4);
4625 indices += 4;
4626
4fbb74a6 4627 if (entry >= elf_header.e_shnum)
391cb864
L
4628 {
4629 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
4630 entry, i, elf_header.e_shnum - 1);
4631 continue;
4632 }
391cb864 4633
4fbb74a6 4634 if (section_headers_groups [entry] != NULL)
e4b17d5c 4635 {
d1f5c6e3
L
4636 if (entry)
4637 {
391cb864
L
4638 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
4639 entry, i,
4fbb74a6 4640 section_headers_groups [entry]->group_index);
d1f5c6e3
L
4641 continue;
4642 }
4643 else
4644 {
4645 /* Intel C/C++ compiler may put section 0 in a
4646 section group. We just warn it the first time
4647 and ignore it afterwards. */
4648 static int warned = 0;
4649 if (!warned)
4650 {
4651 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 4652 section_headers_groups [entry]->group_index);
d1f5c6e3
L
4653 warned++;
4654 }
4655 }
e4b17d5c
L
4656 }
4657
4fbb74a6 4658 section_headers_groups [entry] = group;
e4b17d5c
L
4659
4660 if (do_section_groups)
4661 {
4fbb74a6 4662 sec = section_headers + entry;
c256ffe7 4663 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
4664 }
4665
e4b17d5c
L
4666 g = xmalloc (sizeof (struct group_list));
4667 g->section_index = entry;
4668 g->next = group->root;
4669 group->root = g;
f5842774
L
4670 }
4671
f5842774
L
4672 if (start)
4673 free (start);
e4b17d5c
L
4674
4675 group++;
f5842774
L
4676 }
4677 }
4678
d1f5c6e3
L
4679 if (symtab)
4680 free (symtab);
4681 if (strtab)
4682 free (strtab);
f5842774
L
4683 return 1;
4684}
4685
85b1c36d 4686static struct
566b0d53 4687{
2cf0635d 4688 const char * name;
566b0d53
L
4689 int reloc;
4690 int size;
4691 int rela;
4692} dynamic_relocations [] =
4693{
4694 { "REL", DT_REL, DT_RELSZ, FALSE },
4695 { "RELA", DT_RELA, DT_RELASZ, TRUE },
4696 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
4697};
4698
252b5132 4699/* Process the reloc section. */
18bd398b 4700
252b5132 4701static int
2cf0635d 4702process_relocs (FILE * file)
252b5132 4703{
b34976b6
AM
4704 unsigned long rel_size;
4705 unsigned long rel_offset;
252b5132
RH
4706
4707
4708 if (!do_reloc)
4709 return 1;
4710
4711 if (do_using_dynamic)
4712 {
566b0d53 4713 int is_rela;
2cf0635d 4714 const char * name;
566b0d53
L
4715 int has_dynamic_reloc;
4716 unsigned int i;
0de14b54 4717
566b0d53 4718 has_dynamic_reloc = 0;
252b5132 4719
566b0d53 4720 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 4721 {
566b0d53
L
4722 is_rela = dynamic_relocations [i].rela;
4723 name = dynamic_relocations [i].name;
4724 rel_size = dynamic_info [dynamic_relocations [i].size];
4725 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 4726
566b0d53
L
4727 has_dynamic_reloc |= rel_size;
4728
4729 if (is_rela == UNKNOWN)
aa903cfb 4730 {
566b0d53
L
4731 if (dynamic_relocations [i].reloc == DT_JMPREL)
4732 switch (dynamic_info[DT_PLTREL])
4733 {
4734 case DT_REL:
4735 is_rela = FALSE;
4736 break;
4737 case DT_RELA:
4738 is_rela = TRUE;
4739 break;
4740 }
aa903cfb 4741 }
252b5132 4742
566b0d53
L
4743 if (rel_size)
4744 {
4745 printf
4746 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
4747 name, rel_offset, rel_size);
252b5132 4748
d93f0186
NC
4749 dump_relocations (file,
4750 offset_from_vma (file, rel_offset, rel_size),
4751 rel_size,
566b0d53 4752 dynamic_symbols, num_dynamic_syms,
d79b3d50 4753 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 4754 }
252b5132 4755 }
566b0d53
L
4756
4757 if (! has_dynamic_reloc)
252b5132
RH
4758 printf (_("\nThere are no dynamic relocations in this file.\n"));
4759 }
4760 else
4761 {
2cf0635d 4762 Elf_Internal_Shdr * section;
b34976b6
AM
4763 unsigned long i;
4764 int found = 0;
252b5132
RH
4765
4766 for (i = 0, section = section_headers;
4767 i < elf_header.e_shnum;
b34976b6 4768 i++, section++)
252b5132
RH
4769 {
4770 if ( section->sh_type != SHT_RELA
4771 && section->sh_type != SHT_REL)
4772 continue;
4773
4774 rel_offset = section->sh_offset;
4775 rel_size = section->sh_size;
4776
4777 if (rel_size)
4778 {
2cf0635d 4779 Elf_Internal_Shdr * strsec;
b34976b6 4780 int is_rela;
103f02d3 4781
252b5132
RH
4782 printf (_("\nRelocation section "));
4783
4784 if (string_table == NULL)
19936277 4785 printf ("%d", section->sh_name);
252b5132 4786 else
3a1a2036 4787 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
4788
4789 printf (_(" at offset 0x%lx contains %lu entries:\n"),
4790 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
4791
d79b3d50
NC
4792 is_rela = section->sh_type == SHT_RELA;
4793
4fbb74a6
AM
4794 if (section->sh_link != 0
4795 && section->sh_link < elf_header.e_shnum)
af3fc3bc 4796 {
2cf0635d
NC
4797 Elf_Internal_Shdr * symsec;
4798 Elf_Internal_Sym * symtab;
d79b3d50 4799 unsigned long nsyms;
c256ffe7 4800 unsigned long strtablen = 0;
2cf0635d 4801 char * strtab = NULL;
57346661 4802
4fbb74a6 4803 symsec = section_headers + section->sh_link;
08d8fa11
JJ
4804 if (symsec->sh_type != SHT_SYMTAB
4805 && symsec->sh_type != SHT_DYNSYM)
4806 continue;
4807
af3fc3bc 4808 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 4809 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 4810
af3fc3bc
AM
4811 if (symtab == NULL)
4812 continue;
252b5132 4813
4fbb74a6
AM
4814 if (symsec->sh_link != 0
4815 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 4816 {
4fbb74a6 4817 strsec = section_headers + symsec->sh_link;
103f02d3 4818
c256ffe7
JJ
4819 strtab = get_data (NULL, file, strsec->sh_offset,
4820 1, strsec->sh_size,
4821 _("string table"));
4822 strtablen = strtab == NULL ? 0 : strsec->sh_size;
4823 }
252b5132 4824
d79b3d50
NC
4825 dump_relocations (file, rel_offset, rel_size,
4826 symtab, nsyms, strtab, strtablen, is_rela);
4827 if (strtab)
4828 free (strtab);
4829 free (symtab);
4830 }
4831 else
4832 dump_relocations (file, rel_offset, rel_size,
4833 NULL, 0, NULL, 0, is_rela);
252b5132
RH
4834
4835 found = 1;
4836 }
4837 }
4838
4839 if (! found)
4840 printf (_("\nThere are no relocations in this file.\n"));
4841 }
4842
4843 return 1;
4844}
4845
57346661
AM
4846/* Process the unwind section. */
4847
4d6ed7c8
NC
4848#include "unwind-ia64.h"
4849
4850/* An absolute address consists of a section and an offset. If the
4851 section is NULL, the offset itself is the address, otherwise, the
4852 address equals to LOAD_ADDRESS(section) + offset. */
4853
4854struct absaddr
4855 {
4856 unsigned short section;
4857 bfd_vma offset;
4858 };
4859
1949de15
L
4860#define ABSADDR(a) \
4861 ((a).section \
4862 ? section_headers [(a).section].sh_addr + (a).offset \
4863 : (a).offset)
4864
57346661 4865struct ia64_unw_aux_info
4d6ed7c8 4866 {
57346661 4867 struct ia64_unw_table_entry
4d6ed7c8 4868 {
b34976b6
AM
4869 struct absaddr start;
4870 struct absaddr end;
4871 struct absaddr info;
4d6ed7c8 4872 }
b34976b6
AM
4873 *table; /* Unwind table. */
4874 unsigned long table_len; /* Length of unwind table. */
2cf0635d 4875 unsigned char * info; /* Unwind info. */
b34976b6
AM
4876 unsigned long info_size; /* Size of unwind info. */
4877 bfd_vma info_addr; /* starting address of unwind info. */
4878 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 4879 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 4880 unsigned long nsyms; /* Number of symbols. */
2cf0635d 4881 char * strtab; /* The string table. */
b34976b6 4882 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
4883 };
4884
4d6ed7c8 4885static void
2cf0635d 4886find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 4887 unsigned long nsyms,
2cf0635d 4888 const char * strtab,
57346661 4889 unsigned long strtab_size,
d3ba0551 4890 struct absaddr addr,
2cf0635d
NC
4891 const char ** symname,
4892 bfd_vma * offset)
4d6ed7c8 4893{
d3ba0551 4894 bfd_vma dist = 0x100000;
2cf0635d
NC
4895 Elf_Internal_Sym * sym;
4896 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
4897 unsigned long i;
4898
57346661 4899 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8
NC
4900 {
4901 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
4902 && sym->st_name != 0
4903 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
4904 && addr.offset >= sym->st_value
4905 && addr.offset - sym->st_value < dist)
4906 {
4907 best = sym;
4908 dist = addr.offset - sym->st_value;
4909 if (!dist)
4910 break;
4911 }
4912 }
4913 if (best)
4914 {
57346661
AM
4915 *symname = (best->st_name >= strtab_size
4916 ? "<corrupt>" : strtab + best->st_name);
4d6ed7c8
NC
4917 *offset = dist;
4918 return;
4919 }
4920 *symname = NULL;
4921 *offset = addr.offset;
4922}
4923
4924static void
2cf0635d 4925dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 4926{
2cf0635d 4927 struct ia64_unw_table_entry * tp;
4d6ed7c8 4928 int in_body;
7036c0e1 4929
4d6ed7c8
NC
4930 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
4931 {
4932 bfd_vma stamp;
4933 bfd_vma offset;
2cf0635d
NC
4934 const unsigned char * dp;
4935 const unsigned char * head;
4936 const char * procname;
4d6ed7c8 4937
57346661
AM
4938 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
4939 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
4940
4941 fputs ("\n<", stdout);
4942
4943 if (procname)
4944 {
4945 fputs (procname, stdout);
4946
4947 if (offset)
4948 printf ("+%lx", (unsigned long) offset);
4949 }
4950
4951 fputs (">: [", stdout);
4952 print_vma (tp->start.offset, PREFIX_HEX);
4953 fputc ('-', stdout);
4954 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 4955 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
4956 (unsigned long) (tp->info.offset - aux->seg_base));
4957
1949de15 4958 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 4959 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 4960
86f55779 4961 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
4962 (unsigned) UNW_VER (stamp),
4963 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
4964 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
4965 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 4966 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
4967
4968 if (UNW_VER (stamp) != 1)
4969 {
4970 printf ("\tUnknown version.\n");
4971 continue;
4972 }
4973
4974 in_body = 0;
89fac5e3 4975 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
4976 dp = unw_decode (dp, in_body, & in_body);
4977 }
4978}
4979
4980static int
2cf0635d
NC
4981slurp_ia64_unwind_table (FILE * file,
4982 struct ia64_unw_aux_info * aux,
4983 Elf_Internal_Shdr * sec)
4d6ed7c8 4984{
89fac5e3 4985 unsigned long size, nrelas, i;
2cf0635d
NC
4986 Elf_Internal_Phdr * seg;
4987 struct ia64_unw_table_entry * tep;
4988 Elf_Internal_Shdr * relsec;
4989 Elf_Internal_Rela * rela;
4990 Elf_Internal_Rela * rp;
4991 unsigned char * table;
4992 unsigned char * tp;
4993 Elf_Internal_Sym * sym;
4994 const char * relname;
4d6ed7c8 4995
4d6ed7c8
NC
4996 /* First, find the starting address of the segment that includes
4997 this section: */
4998
4999 if (elf_header.e_phnum)
5000 {
d93f0186 5001 if (! get_program_headers (file))
4d6ed7c8 5002 return 0;
4d6ed7c8 5003
d93f0186
NC
5004 for (seg = program_headers;
5005 seg < program_headers + elf_header.e_phnum;
5006 ++seg)
4d6ed7c8
NC
5007 {
5008 if (seg->p_type != PT_LOAD)
5009 continue;
5010
5011 if (sec->sh_addr >= seg->p_vaddr
5012 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5013 {
5014 aux->seg_base = seg->p_vaddr;
5015 break;
5016 }
5017 }
4d6ed7c8
NC
5018 }
5019
5020 /* Second, build the unwind table from the contents of the unwind section: */
5021 size = sec->sh_size;
c256ffe7 5022 table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
a6e9f9df
AM
5023 if (!table)
5024 return 0;
4d6ed7c8 5025
c256ffe7 5026 aux->table = xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5027 tep = aux->table;
c6a0c689 5028 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5029 {
5030 tep->start.section = SHN_UNDEF;
5031 tep->end.section = SHN_UNDEF;
5032 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5033 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5034 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5035 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5036 tep->start.offset += aux->seg_base;
5037 tep->end.offset += aux->seg_base;
5038 tep->info.offset += aux->seg_base;
5039 }
5040 free (table);
5041
41e92641 5042 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5043 for (relsec = section_headers;
5044 relsec < section_headers + elf_header.e_shnum;
5045 ++relsec)
5046 {
5047 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5048 || relsec->sh_info >= elf_header.e_shnum
5049 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5050 continue;
5051
5052 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5053 & rela, & nrelas))
5054 return 0;
5055
5056 for (rp = rela; rp < rela + nrelas; ++rp)
5057 {
aca88567
NC
5058 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5059 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5060
0112cd26 5061 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5062 {
e5fb9629 5063 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5064 continue;
5065 }
5066
89fac5e3 5067 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5068
89fac5e3 5069 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5070 {
5071 case 0:
5072 aux->table[i].start.section = sym->st_shndx;
1ffa9a18 5073 aux->table[i].start.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5074 break;
5075 case 1:
5076 aux->table[i].end.section = sym->st_shndx;
1ffa9a18 5077 aux->table[i].end.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5078 break;
5079 case 2:
5080 aux->table[i].info.section = sym->st_shndx;
1ffa9a18 5081 aux->table[i].info.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5082 break;
5083 default:
5084 break;
5085 }
5086 }
5087
5088 free (rela);
5089 }
5090
89fac5e3 5091 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5092 return 1;
5093}
5094
5095static int
2cf0635d 5096ia64_process_unwind (FILE * file)
4d6ed7c8 5097{
2cf0635d
NC
5098 Elf_Internal_Shdr * sec;
5099 Elf_Internal_Shdr * unwsec = NULL;
5100 Elf_Internal_Shdr * strsec;
89fac5e3 5101 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5102 struct ia64_unw_aux_info aux;
f1467e33 5103
4d6ed7c8
NC
5104 memset (& aux, 0, sizeof (aux));
5105
4d6ed7c8
NC
5106 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5107 {
c256ffe7 5108 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5109 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8
NC
5110 {
5111 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 5112 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 5113
4fbb74a6 5114 strsec = section_headers + sec->sh_link;
d3ba0551 5115 aux.strtab = get_data (NULL, file, strsec->sh_offset,
c256ffe7
JJ
5116 1, strsec->sh_size, _("string table"));
5117 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5118 }
5119 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5120 unwcount++;
5121 }
5122
5123 if (!unwcount)
5124 printf (_("\nThere are no unwind sections in this file.\n"));
5125
5126 while (unwcount-- > 0)
5127 {
2cf0635d 5128 char * suffix;
579f31ac
JJ
5129 size_t len, len2;
5130
5131 for (i = unwstart, sec = section_headers + unwstart;
5132 i < elf_header.e_shnum; ++i, ++sec)
5133 if (sec->sh_type == SHT_IA_64_UNWIND)
5134 {
5135 unwsec = sec;
5136 break;
5137 }
5138
5139 unwstart = i + 1;
5140 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5141
e4b17d5c
L
5142 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5143 {
5144 /* We need to find which section group it is in. */
2cf0635d 5145 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
5146
5147 for (; g != NULL; g = g->next)
5148 {
4fbb74a6 5149 sec = section_headers + g->section_index;
18bd398b
NC
5150
5151 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5152 break;
e4b17d5c
L
5153 }
5154
5155 if (g == NULL)
5156 i = elf_header.e_shnum;
5157 }
18bd398b 5158 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5159 {
18bd398b 5160 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5161 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5162 suffix = SECTION_NAME (unwsec) + len;
5163 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5164 ++i, ++sec)
18bd398b
NC
5165 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5166 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5167 break;
5168 }
5169 else
5170 {
5171 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5172 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5173 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5174 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5175 suffix = "";
18bd398b 5176 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5177 suffix = SECTION_NAME (unwsec) + len;
5178 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5179 ++i, ++sec)
18bd398b
NC
5180 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5181 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5182 break;
5183 }
5184
5185 if (i == elf_header.e_shnum)
5186 {
5187 printf (_("\nCould not find unwind info section for "));
5188
5189 if (string_table == NULL)
5190 printf ("%d", unwsec->sh_name);
5191 else
3a1a2036 5192 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5193 }
5194 else
4d6ed7c8
NC
5195 {
5196 aux.info_size = sec->sh_size;
5197 aux.info_addr = sec->sh_addr;
c256ffe7 5198 aux.info = get_data (NULL, file, sec->sh_offset, 1, aux.info_size,
d3ba0551 5199 _("unwind info"));
4d6ed7c8 5200
579f31ac 5201 printf (_("\nUnwind section "));
4d6ed7c8 5202
579f31ac
JJ
5203 if (string_table == NULL)
5204 printf ("%d", unwsec->sh_name);
5205 else
3a1a2036 5206 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5207
579f31ac 5208 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5209 (unsigned long) unwsec->sh_offset,
89fac5e3 5210 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5211
579f31ac 5212 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5213
579f31ac
JJ
5214 if (aux.table_len > 0)
5215 dump_ia64_unwind (& aux);
5216
5217 if (aux.table)
5218 free ((char *) aux.table);
5219 if (aux.info)
5220 free ((char *) aux.info);
5221 aux.table = NULL;
5222 aux.info = NULL;
5223 }
4d6ed7c8 5224 }
4d6ed7c8 5225
4d6ed7c8
NC
5226 if (aux.symtab)
5227 free (aux.symtab);
5228 if (aux.strtab)
5229 free ((char *) aux.strtab);
5230
5231 return 1;
5232}
5233
57346661
AM
5234struct hppa_unw_aux_info
5235 {
5236 struct hppa_unw_table_entry
5237 {
5238 struct absaddr start;
5239 struct absaddr end;
5240 unsigned int Cannot_unwind:1; /* 0 */
5241 unsigned int Millicode:1; /* 1 */
5242 unsigned int Millicode_save_sr0:1; /* 2 */
5243 unsigned int Region_description:2; /* 3..4 */
5244 unsigned int reserved1:1; /* 5 */
5245 unsigned int Entry_SR:1; /* 6 */
5246 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
5247 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
5248 unsigned int Args_stored:1; /* 16 */
5249 unsigned int Variable_Frame:1; /* 17 */
5250 unsigned int Separate_Package_Body:1; /* 18 */
5251 unsigned int Frame_Extension_Millicode:1; /* 19 */
5252 unsigned int Stack_Overflow_Check:1; /* 20 */
5253 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
5254 unsigned int Ada_Region:1; /* 22 */
5255 unsigned int cxx_info:1; /* 23 */
5256 unsigned int cxx_try_catch:1; /* 24 */
5257 unsigned int sched_entry_seq:1; /* 25 */
5258 unsigned int reserved2:1; /* 26 */
5259 unsigned int Save_SP:1; /* 27 */
5260 unsigned int Save_RP:1; /* 28 */
5261 unsigned int Save_MRP_in_frame:1; /* 29 */
5262 unsigned int extn_ptr_defined:1; /* 30 */
5263 unsigned int Cleanup_defined:1; /* 31 */
5264
5265 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5266 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5267 unsigned int Large_frame:1; /* 2 */
5268 unsigned int Pseudo_SP_Set:1; /* 3 */
5269 unsigned int reserved4:1; /* 4 */
5270 unsigned int Total_frame_size:27; /* 5..31 */
5271 }
5272 *table; /* Unwind table. */
5273 unsigned long table_len; /* Length of unwind table. */
5274 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5275 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 5276 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5277 char * strtab; /* The string table. */
57346661
AM
5278 unsigned long strtab_size; /* Size of string table. */
5279 };
5280
5281static void
2cf0635d 5282dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 5283{
2cf0635d 5284 struct hppa_unw_table_entry * tp;
57346661 5285
57346661
AM
5286 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5287 {
5288 bfd_vma offset;
2cf0635d 5289 const char * procname;
57346661
AM
5290
5291 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5292 aux->strtab_size, tp->start, &procname,
5293 &offset);
5294
5295 fputs ("\n<", stdout);
5296
5297 if (procname)
5298 {
5299 fputs (procname, stdout);
5300
5301 if (offset)
5302 printf ("+%lx", (unsigned long) offset);
5303 }
5304
5305 fputs (">: [", stdout);
5306 print_vma (tp->start.offset, PREFIX_HEX);
5307 fputc ('-', stdout);
5308 print_vma (tp->end.offset, PREFIX_HEX);
5309 printf ("]\n\t");
5310
18bd398b
NC
5311#define PF(_m) if (tp->_m) printf (#_m " ");
5312#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5313 PF(Cannot_unwind);
5314 PF(Millicode);
5315 PF(Millicode_save_sr0);
18bd398b 5316 /* PV(Region_description); */
57346661
AM
5317 PF(Entry_SR);
5318 PV(Entry_FR);
5319 PV(Entry_GR);
5320 PF(Args_stored);
5321 PF(Variable_Frame);
5322 PF(Separate_Package_Body);
5323 PF(Frame_Extension_Millicode);
5324 PF(Stack_Overflow_Check);
5325 PF(Two_Instruction_SP_Increment);
5326 PF(Ada_Region);
5327 PF(cxx_info);
5328 PF(cxx_try_catch);
5329 PF(sched_entry_seq);
5330 PF(Save_SP);
5331 PF(Save_RP);
5332 PF(Save_MRP_in_frame);
5333 PF(extn_ptr_defined);
5334 PF(Cleanup_defined);
5335 PF(MPE_XL_interrupt_marker);
5336 PF(HP_UX_interrupt_marker);
5337 PF(Large_frame);
5338 PF(Pseudo_SP_Set);
5339 PV(Total_frame_size);
5340#undef PF
5341#undef PV
5342 }
5343
18bd398b 5344 printf ("\n");
57346661
AM
5345}
5346
5347static int
2cf0635d
NC
5348slurp_hppa_unwind_table (FILE * file,
5349 struct hppa_unw_aux_info * aux,
5350 Elf_Internal_Shdr * sec)
57346661 5351{
1c0751b2 5352 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
5353 Elf_Internal_Phdr * seg;
5354 struct hppa_unw_table_entry * tep;
5355 Elf_Internal_Shdr * relsec;
5356 Elf_Internal_Rela * rela;
5357 Elf_Internal_Rela * rp;
5358 unsigned char * table;
5359 unsigned char * tp;
5360 Elf_Internal_Sym * sym;
5361 const char * relname;
57346661 5362
57346661
AM
5363 /* First, find the starting address of the segment that includes
5364 this section. */
5365
5366 if (elf_header.e_phnum)
5367 {
5368 if (! get_program_headers (file))
5369 return 0;
5370
5371 for (seg = program_headers;
5372 seg < program_headers + elf_header.e_phnum;
5373 ++seg)
5374 {
5375 if (seg->p_type != PT_LOAD)
5376 continue;
5377
5378 if (sec->sh_addr >= seg->p_vaddr
5379 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5380 {
5381 aux->seg_base = seg->p_vaddr;
5382 break;
5383 }
5384 }
5385 }
5386
5387 /* Second, build the unwind table from the contents of the unwind
5388 section. */
5389 size = sec->sh_size;
c256ffe7 5390 table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
57346661
AM
5391 if (!table)
5392 return 0;
5393
1c0751b2
DA
5394 unw_ent_size = 16;
5395 nentries = size / unw_ent_size;
5396 size = unw_ent_size * nentries;
57346661 5397
1c0751b2 5398 tep = aux->table = xcmalloc (nentries, sizeof (aux->table[0]));
57346661 5399
1c0751b2 5400 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
5401 {
5402 unsigned int tmp1, tmp2;
5403
5404 tep->start.section = SHN_UNDEF;
5405 tep->end.section = SHN_UNDEF;
5406
1c0751b2
DA
5407 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
5408 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
5409 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
5410 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
5411
5412 tep->start.offset += aux->seg_base;
5413 tep->end.offset += aux->seg_base;
57346661
AM
5414
5415 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
5416 tep->Millicode = (tmp1 >> 30) & 0x1;
5417 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
5418 tep->Region_description = (tmp1 >> 27) & 0x3;
5419 tep->reserved1 = (tmp1 >> 26) & 0x1;
5420 tep->Entry_SR = (tmp1 >> 25) & 0x1;
5421 tep->Entry_FR = (tmp1 >> 21) & 0xf;
5422 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
5423 tep->Args_stored = (tmp1 >> 15) & 0x1;
5424 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
5425 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
5426 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
5427 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
5428 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
5429 tep->Ada_Region = (tmp1 >> 9) & 0x1;
5430 tep->cxx_info = (tmp1 >> 8) & 0x1;
5431 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
5432 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
5433 tep->reserved2 = (tmp1 >> 5) & 0x1;
5434 tep->Save_SP = (tmp1 >> 4) & 0x1;
5435 tep->Save_RP = (tmp1 >> 3) & 0x1;
5436 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
5437 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
5438 tep->Cleanup_defined = tmp1 & 0x1;
5439
5440 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
5441 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
5442 tep->Large_frame = (tmp2 >> 29) & 0x1;
5443 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
5444 tep->reserved4 = (tmp2 >> 27) & 0x1;
5445 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
5446 }
5447 free (table);
5448
5449 /* Third, apply any relocations to the unwind table. */
57346661
AM
5450 for (relsec = section_headers;
5451 relsec < section_headers + elf_header.e_shnum;
5452 ++relsec)
5453 {
5454 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5455 || relsec->sh_info >= elf_header.e_shnum
5456 || section_headers + relsec->sh_info != sec)
57346661
AM
5457 continue;
5458
5459 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5460 & rela, & nrelas))
5461 return 0;
5462
5463 for (rp = rela; rp < rela + nrelas; ++rp)
5464 {
aca88567
NC
5465 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
5466 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
5467
5468 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 5469 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
5470 {
5471 warn (_("Skipping unexpected relocation type %s\n"), relname);
5472 continue;
5473 }
5474
5475 i = rp->r_offset / unw_ent_size;
5476
89fac5e3 5477 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
5478 {
5479 case 0:
5480 aux->table[i].start.section = sym->st_shndx;
5481 aux->table[i].start.offset += sym->st_value + rp->r_addend;
5482 break;
5483 case 1:
5484 aux->table[i].end.section = sym->st_shndx;
5485 aux->table[i].end.offset += sym->st_value + rp->r_addend;
5486 break;
5487 default:
5488 break;
5489 }
5490 }
5491
5492 free (rela);
5493 }
5494
1c0751b2 5495 aux->table_len = nentries;
57346661
AM
5496
5497 return 1;
5498}
5499
5500static int
2cf0635d 5501hppa_process_unwind (FILE * file)
57346661 5502{
57346661 5503 struct hppa_unw_aux_info aux;
2cf0635d
NC
5504 Elf_Internal_Shdr * unwsec = NULL;
5505 Elf_Internal_Shdr * strsec;
5506 Elf_Internal_Shdr * sec;
18bd398b 5507 unsigned long i;
57346661
AM
5508
5509 memset (& aux, 0, sizeof (aux));
5510
c256ffe7
JJ
5511 if (string_table == NULL)
5512 return 1;
57346661
AM
5513
5514 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5515 {
c256ffe7 5516 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5517 && sec->sh_link < elf_header.e_shnum)
57346661
AM
5518 {
5519 aux.nsyms = sec->sh_size / sec->sh_entsize;
5520 aux.symtab = GET_ELF_SYMBOLS (file, sec);
5521
4fbb74a6 5522 strsec = section_headers + sec->sh_link;
57346661 5523 aux.strtab = get_data (NULL, file, strsec->sh_offset,
c256ffe7
JJ
5524 1, strsec->sh_size, _("string table"));
5525 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 5526 }
18bd398b 5527 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
5528 unwsec = sec;
5529 }
5530
5531 if (!unwsec)
5532 printf (_("\nThere are no unwind sections in this file.\n"));
5533
5534 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5535 {
18bd398b 5536 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 5537 {
57346661
AM
5538 printf (_("\nUnwind section "));
5539 printf (_("'%s'"), SECTION_NAME (sec));
5540
5541 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5542 (unsigned long) sec->sh_offset,
89fac5e3 5543 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
5544
5545 slurp_hppa_unwind_table (file, &aux, sec);
5546 if (aux.table_len > 0)
5547 dump_hppa_unwind (&aux);
5548
5549 if (aux.table)
5550 free ((char *) aux.table);
5551 aux.table = NULL;
5552 }
5553 }
5554
5555 if (aux.symtab)
5556 free (aux.symtab);
5557 if (aux.strtab)
5558 free ((char *) aux.strtab);
5559
5560 return 1;
5561}
5562
5563static int
2cf0635d 5564process_unwind (FILE * file)
57346661 5565{
2cf0635d
NC
5566 struct unwind_handler
5567 {
57346661 5568 int machtype;
2cf0635d
NC
5569 int (* handler)(FILE *);
5570 } handlers[] =
5571 {
57346661
AM
5572 { EM_IA_64, ia64_process_unwind },
5573 { EM_PARISC, hppa_process_unwind },
5574 { 0, 0 }
5575 };
5576 int i;
5577
5578 if (!do_unwind)
5579 return 1;
5580
5581 for (i = 0; handlers[i].handler != NULL; i++)
5582 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 5583 return handlers[i].handler (file);
57346661
AM
5584
5585 printf (_("\nThere are no unwind sections in this file.\n"));
5586 return 1;
5587}
5588
252b5132 5589static void
2cf0635d 5590dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
5591{
5592 switch (entry->d_tag)
5593 {
5594 case DT_MIPS_FLAGS:
5595 if (entry->d_un.d_val == 0)
5596 printf ("NONE\n");
5597 else
5598 {
5599 static const char * opts[] =
5600 {
5601 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
5602 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
5603 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
5604 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
5605 "RLD_ORDER_SAFE"
5606 };
5607 unsigned int cnt;
5608 int first = 1;
60bca95a 5609 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
5610 if (entry->d_un.d_val & (1 << cnt))
5611 {
5612 printf ("%s%s", first ? "" : " ", opts[cnt]);
5613 first = 0;
5614 }
5615 puts ("");
5616 }
5617 break;
103f02d3 5618
252b5132 5619 case DT_MIPS_IVERSION:
d79b3d50
NC
5620 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
5621 printf ("Interface Version: %s\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 5622 else
d79b3d50 5623 printf ("<corrupt: %ld>\n", (long) entry->d_un.d_ptr);
252b5132 5624 break;
103f02d3 5625
252b5132
RH
5626 case DT_MIPS_TIME_STAMP:
5627 {
5628 char timebuf[20];
2cf0635d 5629 struct tm * tmp;
50da7a9c 5630
252b5132 5631 time_t time = entry->d_un.d_val;
50da7a9c 5632 tmp = gmtime (&time);
e9e44622
JJ
5633 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
5634 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
5635 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
5636 printf ("Time Stamp: %s\n", timebuf);
5637 }
5638 break;
103f02d3 5639
252b5132
RH
5640 case DT_MIPS_RLD_VERSION:
5641 case DT_MIPS_LOCAL_GOTNO:
5642 case DT_MIPS_CONFLICTNO:
5643 case DT_MIPS_LIBLISTNO:
5644 case DT_MIPS_SYMTABNO:
5645 case DT_MIPS_UNREFEXTNO:
5646 case DT_MIPS_HIPAGENO:
5647 case DT_MIPS_DELTA_CLASS_NO:
5648 case DT_MIPS_DELTA_INSTANCE_NO:
5649 case DT_MIPS_DELTA_RELOC_NO:
5650 case DT_MIPS_DELTA_SYM_NO:
5651 case DT_MIPS_DELTA_CLASSSYM_NO:
5652 case DT_MIPS_COMPACT_SIZE:
5653 printf ("%ld\n", (long) entry->d_un.d_ptr);
5654 break;
103f02d3
UD
5655
5656 default:
0af1713e 5657 printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr);
103f02d3
UD
5658 }
5659}
5660
5661
5662static void
2cf0635d 5663dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
5664{
5665 switch (entry->d_tag)
5666 {
5667 case DT_HP_DLD_FLAGS:
5668 {
5669 static struct
5670 {
5671 long int bit;
2cf0635d 5672 const char * str;
5e220199
NC
5673 }
5674 flags[] =
5675 {
5676 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
5677 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
5678 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
5679 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
5680 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
5681 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
5682 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
5683 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
5684 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
5685 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
5686 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
5687 { DT_HP_GST, "HP_GST" },
5688 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
5689 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
5690 { DT_HP_NODELETE, "HP_NODELETE" },
5691 { DT_HP_GROUP, "HP_GROUP" },
5692 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 5693 };
103f02d3 5694 int first = 1;
5e220199 5695 size_t cnt;
f7a99963 5696 bfd_vma val = entry->d_un.d_val;
103f02d3 5697
60bca95a 5698 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 5699 if (val & flags[cnt].bit)
30800947
NC
5700 {
5701 if (! first)
5702 putchar (' ');
5703 fputs (flags[cnt].str, stdout);
5704 first = 0;
5705 val ^= flags[cnt].bit;
5706 }
76da6bbe 5707
103f02d3 5708 if (val != 0 || first)
f7a99963
NC
5709 {
5710 if (! first)
5711 putchar (' ');
5712 print_vma (val, HEX);
5713 }
103f02d3
UD
5714 }
5715 break;
76da6bbe 5716
252b5132 5717 default:
f7a99963
NC
5718 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5719 break;
252b5132 5720 }
35b1837e 5721 putchar ('\n');
252b5132
RH
5722}
5723
ecc51f48 5724static void
2cf0635d 5725dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
5726{
5727 switch (entry->d_tag)
5728 {
0de14b54 5729 case DT_IA_64_PLT_RESERVE:
bdf4d63a 5730 /* First 3 slots reserved. */
ecc51f48
NC
5731 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5732 printf (" -- ");
5733 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
5734 break;
5735
5736 default:
5737 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5738 break;
ecc51f48 5739 }
bdf4d63a 5740 putchar ('\n');
ecc51f48
NC
5741}
5742
252b5132 5743static int
2cf0635d 5744get_32bit_dynamic_section (FILE * file)
252b5132 5745{
2cf0635d
NC
5746 Elf32_External_Dyn * edyn;
5747 Elf32_External_Dyn * ext;
5748 Elf_Internal_Dyn * entry;
103f02d3 5749
c256ffe7 5750 edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
b2d38a17 5751 _("dynamic section"));
a6e9f9df
AM
5752 if (!edyn)
5753 return 0;
103f02d3 5754
ba2685cc
AM
5755/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5756 might not have the luxury of section headers. Look for the DT_NULL
5757 terminator to determine the number of entries. */
5758 for (ext = edyn, dynamic_nent = 0;
5759 (char *) ext < (char *) edyn + dynamic_size;
5760 ext++)
5761 {
5762 dynamic_nent++;
5763 if (BYTE_GET (ext->d_tag) == DT_NULL)
5764 break;
5765 }
252b5132 5766
2cf0635d 5767 dynamic_section = cmalloc (dynamic_nent, sizeof (* entry));
b2d38a17 5768 if (dynamic_section == NULL)
252b5132 5769 {
9ea033b2
NC
5770 error (_("Out of memory\n"));
5771 free (edyn);
5772 return 0;
5773 }
252b5132 5774
fb514b26 5775 for (ext = edyn, entry = dynamic_section;
ba2685cc 5776 entry < dynamic_section + dynamic_nent;
fb514b26 5777 ext++, entry++)
9ea033b2 5778 {
fb514b26
AM
5779 entry->d_tag = BYTE_GET (ext->d_tag);
5780 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
5781 }
5782
9ea033b2
NC
5783 free (edyn);
5784
5785 return 1;
5786}
5787
5788static int
2cf0635d 5789get_64bit_dynamic_section (FILE * file)
9ea033b2 5790{
2cf0635d
NC
5791 Elf64_External_Dyn * edyn;
5792 Elf64_External_Dyn * ext;
5793 Elf_Internal_Dyn * entry;
103f02d3 5794
c256ffe7 5795 edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
b2d38a17 5796 _("dynamic section"));
a6e9f9df
AM
5797 if (!edyn)
5798 return 0;
103f02d3 5799
ba2685cc
AM
5800/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5801 might not have the luxury of section headers. Look for the DT_NULL
5802 terminator to determine the number of entries. */
5803 for (ext = edyn, dynamic_nent = 0;
5804 (char *) ext < (char *) edyn + dynamic_size;
5805 ext++)
5806 {
5807 dynamic_nent++;
66543521 5808 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
5809 break;
5810 }
252b5132 5811
2cf0635d 5812 dynamic_section = cmalloc (dynamic_nent, sizeof (* entry));
b2d38a17 5813 if (dynamic_section == NULL)
252b5132
RH
5814 {
5815 error (_("Out of memory\n"));
5816 free (edyn);
5817 return 0;
5818 }
5819
fb514b26 5820 for (ext = edyn, entry = dynamic_section;
ba2685cc 5821 entry < dynamic_section + dynamic_nent;
fb514b26 5822 ext++, entry++)
252b5132 5823 {
66543521
AM
5824 entry->d_tag = BYTE_GET (ext->d_tag);
5825 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
5826 }
5827
5828 free (edyn);
5829
9ea033b2
NC
5830 return 1;
5831}
5832
e9e44622
JJ
5833static void
5834print_dynamic_flags (bfd_vma flags)
d1133906 5835{
e9e44622 5836 int first = 1;
13ae64f3 5837
d1133906
NC
5838 while (flags)
5839 {
5840 bfd_vma flag;
5841
5842 flag = flags & - flags;
5843 flags &= ~ flag;
5844
e9e44622
JJ
5845 if (first)
5846 first = 0;
5847 else
5848 putc (' ', stdout);
13ae64f3 5849
d1133906
NC
5850 switch (flag)
5851 {
e9e44622
JJ
5852 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
5853 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
5854 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
5855 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
5856 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
5857 default: fputs ("unknown", stdout); break;
d1133906
NC
5858 }
5859 }
e9e44622 5860 puts ("");
d1133906
NC
5861}
5862
b2d38a17
NC
5863/* Parse and display the contents of the dynamic section. */
5864
9ea033b2 5865static int
2cf0635d 5866process_dynamic_section (FILE * file)
9ea033b2 5867{
2cf0635d 5868 Elf_Internal_Dyn * entry;
9ea033b2
NC
5869
5870 if (dynamic_size == 0)
5871 {
5872 if (do_dynamic)
b2d38a17 5873 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
5874
5875 return 1;
5876 }
5877
5878 if (is_32bit_elf)
5879 {
b2d38a17 5880 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
5881 return 0;
5882 }
b2d38a17 5883 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
5884 return 0;
5885
252b5132
RH
5886 /* Find the appropriate symbol table. */
5887 if (dynamic_symbols == NULL)
5888 {
86dba8ee
AM
5889 for (entry = dynamic_section;
5890 entry < dynamic_section + dynamic_nent;
5891 ++entry)
252b5132 5892 {
c8286bd1 5893 Elf_Internal_Shdr section;
252b5132
RH
5894
5895 if (entry->d_tag != DT_SYMTAB)
5896 continue;
5897
5898 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
5899
5900 /* Since we do not know how big the symbol table is,
5901 we default to reading in the entire file (!) and
5902 processing that. This is overkill, I know, but it
e3c8793a 5903 should work. */
d93f0186 5904 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 5905
fb52b2f4
NC
5906 if (archive_file_offset != 0)
5907 section.sh_size = archive_file_size - section.sh_offset;
5908 else
5909 {
5910 if (fseek (file, 0, SEEK_END))
591a748a 5911 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
5912
5913 section.sh_size = ftell (file) - section.sh_offset;
5914 }
252b5132 5915
9ea033b2 5916 if (is_32bit_elf)
9ad5cbcf 5917 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 5918 else
9ad5cbcf 5919 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 5920
9ad5cbcf 5921 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 5922 if (num_dynamic_syms < 1)
252b5132
RH
5923 {
5924 error (_("Unable to determine the number of symbols to load\n"));
5925 continue;
5926 }
5927
9ad5cbcf 5928 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
5929 }
5930 }
5931
5932 /* Similarly find a string table. */
5933 if (dynamic_strings == NULL)
5934 {
86dba8ee
AM
5935 for (entry = dynamic_section;
5936 entry < dynamic_section + dynamic_nent;
5937 ++entry)
252b5132
RH
5938 {
5939 unsigned long offset;
b34976b6 5940 long str_tab_len;
252b5132
RH
5941
5942 if (entry->d_tag != DT_STRTAB)
5943 continue;
5944
5945 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
5946
5947 /* Since we do not know how big the string table is,
5948 we default to reading in the entire file (!) and
5949 processing that. This is overkill, I know, but it
e3c8793a 5950 should work. */
252b5132 5951
d93f0186 5952 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
5953
5954 if (archive_file_offset != 0)
5955 str_tab_len = archive_file_size - offset;
5956 else
5957 {
5958 if (fseek (file, 0, SEEK_END))
5959 error (_("Unable to seek to end of file\n"));
5960 str_tab_len = ftell (file) - offset;
5961 }
252b5132
RH
5962
5963 if (str_tab_len < 1)
5964 {
5965 error
5966 (_("Unable to determine the length of the dynamic string table\n"));
5967 continue;
5968 }
5969
c256ffe7 5970 dynamic_strings = get_data (NULL, file, offset, 1, str_tab_len,
d3ba0551 5971 _("dynamic string table"));
d79b3d50 5972 dynamic_strings_length = str_tab_len;
252b5132
RH
5973 break;
5974 }
5975 }
5976
5977 /* And find the syminfo section if available. */
5978 if (dynamic_syminfo == NULL)
5979 {
3e8bba36 5980 unsigned long syminsz = 0;
252b5132 5981
86dba8ee
AM
5982 for (entry = dynamic_section;
5983 entry < dynamic_section + dynamic_nent;
5984 ++entry)
252b5132
RH
5985 {
5986 if (entry->d_tag == DT_SYMINENT)
5987 {
5988 /* Note: these braces are necessary to avoid a syntax
5989 error from the SunOS4 C compiler. */
5990 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
5991 }
5992 else if (entry->d_tag == DT_SYMINSZ)
5993 syminsz = entry->d_un.d_val;
5994 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
5995 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
5996 syminsz);
252b5132
RH
5997 }
5998
5999 if (dynamic_syminfo_offset != 0 && syminsz != 0)
6000 {
2cf0635d
NC
6001 Elf_External_Syminfo * extsyminfo;
6002 Elf_External_Syminfo * extsym;
6003 Elf_Internal_Syminfo * syminfo;
252b5132
RH
6004
6005 /* There is a syminfo section. Read the data. */
c256ffe7
JJ
6006 extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, 1,
6007 syminsz, _("symbol information"));
a6e9f9df
AM
6008 if (!extsyminfo)
6009 return 0;
252b5132 6010
d3ba0551 6011 dynamic_syminfo = malloc (syminsz);
252b5132
RH
6012 if (dynamic_syminfo == NULL)
6013 {
6014 error (_("Out of memory\n"));
6015 return 0;
6016 }
6017
6018 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
6019 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
6020 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
6021 ++syminfo, ++extsym)
252b5132 6022 {
86dba8ee
AM
6023 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
6024 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
6025 }
6026
6027 free (extsyminfo);
6028 }
6029 }
6030
6031 if (do_dynamic && dynamic_addr)
86dba8ee
AM
6032 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
6033 dynamic_addr, dynamic_nent);
252b5132
RH
6034 if (do_dynamic)
6035 printf (_(" Tag Type Name/Value\n"));
6036
86dba8ee
AM
6037 for (entry = dynamic_section;
6038 entry < dynamic_section + dynamic_nent;
6039 entry++)
252b5132
RH
6040 {
6041 if (do_dynamic)
f7a99963 6042 {
2cf0635d 6043 const char * dtype;
e699b9ff 6044
f7a99963
NC
6045 putchar (' ');
6046 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
6047 dtype = get_dynamic_type (entry->d_tag);
6048 printf (" (%s)%*s", dtype,
6049 ((is_32bit_elf ? 27 : 19)
6050 - (int) strlen (dtype)),
f7a99963
NC
6051 " ");
6052 }
252b5132
RH
6053
6054 switch (entry->d_tag)
6055 {
d1133906
NC
6056 case DT_FLAGS:
6057 if (do_dynamic)
e9e44622 6058 print_dynamic_flags (entry->d_un.d_val);
d1133906 6059 break;
76da6bbe 6060
252b5132
RH
6061 case DT_AUXILIARY:
6062 case DT_FILTER:
019148e4
L
6063 case DT_CONFIG:
6064 case DT_DEPAUDIT:
6065 case DT_AUDIT:
252b5132
RH
6066 if (do_dynamic)
6067 {
019148e4 6068 switch (entry->d_tag)
b34976b6 6069 {
019148e4
L
6070 case DT_AUXILIARY:
6071 printf (_("Auxiliary library"));
6072 break;
6073
6074 case DT_FILTER:
6075 printf (_("Filter library"));
6076 break;
6077
b34976b6 6078 case DT_CONFIG:
019148e4
L
6079 printf (_("Configuration file"));
6080 break;
6081
6082 case DT_DEPAUDIT:
6083 printf (_("Dependency audit library"));
6084 break;
6085
6086 case DT_AUDIT:
6087 printf (_("Audit library"));
6088 break;
6089 }
252b5132 6090
d79b3d50
NC
6091 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
6092 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 6093 else
f7a99963
NC
6094 {
6095 printf (": ");
6096 print_vma (entry->d_un.d_val, PREFIX_HEX);
6097 putchar ('\n');
6098 }
252b5132
RH
6099 }
6100 break;
6101
dcefbbbd 6102 case DT_FEATURE:
252b5132
RH
6103 if (do_dynamic)
6104 {
6105 printf (_("Flags:"));
86f55779 6106
252b5132
RH
6107 if (entry->d_un.d_val == 0)
6108 printf (_(" None\n"));
6109 else
6110 {
6111 unsigned long int val = entry->d_un.d_val;
86f55779 6112
252b5132
RH
6113 if (val & DTF_1_PARINIT)
6114 {
6115 printf (" PARINIT");
6116 val ^= DTF_1_PARINIT;
6117 }
dcefbbbd
L
6118 if (val & DTF_1_CONFEXP)
6119 {
6120 printf (" CONFEXP");
6121 val ^= DTF_1_CONFEXP;
6122 }
252b5132
RH
6123 if (val != 0)
6124 printf (" %lx", val);
6125 puts ("");
6126 }
6127 }
6128 break;
6129
6130 case DT_POSFLAG_1:
6131 if (do_dynamic)
6132 {
6133 printf (_("Flags:"));
86f55779 6134
252b5132
RH
6135 if (entry->d_un.d_val == 0)
6136 printf (_(" None\n"));
6137 else
6138 {
6139 unsigned long int val = entry->d_un.d_val;
86f55779 6140
252b5132
RH
6141 if (val & DF_P1_LAZYLOAD)
6142 {
6143 printf (" LAZYLOAD");
6144 val ^= DF_P1_LAZYLOAD;
6145 }
6146 if (val & DF_P1_GROUPPERM)
6147 {
6148 printf (" GROUPPERM");
6149 val ^= DF_P1_GROUPPERM;
6150 }
6151 if (val != 0)
6152 printf (" %lx", val);
6153 puts ("");
6154 }
6155 }
6156 break;
6157
6158 case DT_FLAGS_1:
6159 if (do_dynamic)
6160 {
6161 printf (_("Flags:"));
6162 if (entry->d_un.d_val == 0)
6163 printf (_(" None\n"));
6164 else
6165 {
6166 unsigned long int val = entry->d_un.d_val;
86f55779 6167
252b5132
RH
6168 if (val & DF_1_NOW)
6169 {
6170 printf (" NOW");
6171 val ^= DF_1_NOW;
6172 }
6173 if (val & DF_1_GLOBAL)
6174 {
6175 printf (" GLOBAL");
6176 val ^= DF_1_GLOBAL;
6177 }
6178 if (val & DF_1_GROUP)
6179 {
6180 printf (" GROUP");
6181 val ^= DF_1_GROUP;
6182 }
6183 if (val & DF_1_NODELETE)
6184 {
6185 printf (" NODELETE");
6186 val ^= DF_1_NODELETE;
6187 }
6188 if (val & DF_1_LOADFLTR)
6189 {
6190 printf (" LOADFLTR");
6191 val ^= DF_1_LOADFLTR;
6192 }
6193 if (val & DF_1_INITFIRST)
6194 {
6195 printf (" INITFIRST");
6196 val ^= DF_1_INITFIRST;
6197 }
6198 if (val & DF_1_NOOPEN)
6199 {
6200 printf (" NOOPEN");
6201 val ^= DF_1_NOOPEN;
6202 }
6203 if (val & DF_1_ORIGIN)
6204 {
6205 printf (" ORIGIN");
6206 val ^= DF_1_ORIGIN;
6207 }
6208 if (val & DF_1_DIRECT)
6209 {
6210 printf (" DIRECT");
6211 val ^= DF_1_DIRECT;
6212 }
6213 if (val & DF_1_TRANS)
6214 {
6215 printf (" TRANS");
6216 val ^= DF_1_TRANS;
6217 }
6218 if (val & DF_1_INTERPOSE)
6219 {
6220 printf (" INTERPOSE");
6221 val ^= DF_1_INTERPOSE;
6222 }
f7db6139 6223 if (val & DF_1_NODEFLIB)
dcefbbbd 6224 {
f7db6139
L
6225 printf (" NODEFLIB");
6226 val ^= DF_1_NODEFLIB;
dcefbbbd
L
6227 }
6228 if (val & DF_1_NODUMP)
6229 {
6230 printf (" NODUMP");
6231 val ^= DF_1_NODUMP;
6232 }
6233 if (val & DF_1_CONLFAT)
6234 {
6235 printf (" CONLFAT");
6236 val ^= DF_1_CONLFAT;
6237 }
252b5132
RH
6238 if (val != 0)
6239 printf (" %lx", val);
6240 puts ("");
6241 }
6242 }
6243 break;
6244
6245 case DT_PLTREL:
566b0d53 6246 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
6247 if (do_dynamic)
6248 puts (get_dynamic_type (entry->d_un.d_val));
6249 break;
6250
6251 case DT_NULL :
6252 case DT_NEEDED :
6253 case DT_PLTGOT :
6254 case DT_HASH :
6255 case DT_STRTAB :
6256 case DT_SYMTAB :
6257 case DT_RELA :
6258 case DT_INIT :
6259 case DT_FINI :
6260 case DT_SONAME :
6261 case DT_RPATH :
6262 case DT_SYMBOLIC:
6263 case DT_REL :
6264 case DT_DEBUG :
6265 case DT_TEXTREL :
6266 case DT_JMPREL :
019148e4 6267 case DT_RUNPATH :
252b5132
RH
6268 dynamic_info[entry->d_tag] = entry->d_un.d_val;
6269
6270 if (do_dynamic)
6271 {
2cf0635d 6272 char * name;
252b5132 6273
d79b3d50
NC
6274 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
6275 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 6276 else
d79b3d50 6277 name = NULL;
252b5132
RH
6278
6279 if (name)
6280 {
6281 switch (entry->d_tag)
6282 {
6283 case DT_NEEDED:
6284 printf (_("Shared library: [%s]"), name);
6285
18bd398b 6286 if (streq (name, program_interpreter))
f7a99963 6287 printf (_(" program interpreter"));
252b5132
RH
6288 break;
6289
6290 case DT_SONAME:
f7a99963 6291 printf (_("Library soname: [%s]"), name);
252b5132
RH
6292 break;
6293
6294 case DT_RPATH:
f7a99963 6295 printf (_("Library rpath: [%s]"), name);
252b5132
RH
6296 break;
6297
019148e4
L
6298 case DT_RUNPATH:
6299 printf (_("Library runpath: [%s]"), name);
6300 break;
6301
252b5132 6302 default:
f7a99963
NC
6303 print_vma (entry->d_un.d_val, PREFIX_HEX);
6304 break;
252b5132
RH
6305 }
6306 }
6307 else
f7a99963
NC
6308 print_vma (entry->d_un.d_val, PREFIX_HEX);
6309
6310 putchar ('\n');
252b5132
RH
6311 }
6312 break;
6313
6314 case DT_PLTRELSZ:
6315 case DT_RELASZ :
6316 case DT_STRSZ :
6317 case DT_RELSZ :
6318 case DT_RELAENT :
6319 case DT_SYMENT :
6320 case DT_RELENT :
566b0d53 6321 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
6322 case DT_PLTPADSZ:
6323 case DT_MOVEENT :
6324 case DT_MOVESZ :
6325 case DT_INIT_ARRAYSZ:
6326 case DT_FINI_ARRAYSZ:
047b2264
JJ
6327 case DT_GNU_CONFLICTSZ:
6328 case DT_GNU_LIBLISTSZ:
252b5132 6329 if (do_dynamic)
f7a99963
NC
6330 {
6331 print_vma (entry->d_un.d_val, UNSIGNED);
6332 printf (" (bytes)\n");
6333 }
252b5132
RH
6334 break;
6335
6336 case DT_VERDEFNUM:
6337 case DT_VERNEEDNUM:
6338 case DT_RELACOUNT:
6339 case DT_RELCOUNT:
6340 if (do_dynamic)
f7a99963
NC
6341 {
6342 print_vma (entry->d_un.d_val, UNSIGNED);
6343 putchar ('\n');
6344 }
252b5132
RH
6345 break;
6346
6347 case DT_SYMINSZ:
6348 case DT_SYMINENT:
6349 case DT_SYMINFO:
6350 case DT_USED:
6351 case DT_INIT_ARRAY:
6352 case DT_FINI_ARRAY:
6353 if (do_dynamic)
6354 {
d79b3d50
NC
6355 if (entry->d_tag == DT_USED
6356 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 6357 {
2cf0635d 6358 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 6359
b34976b6 6360 if (*name)
252b5132
RH
6361 {
6362 printf (_("Not needed object: [%s]\n"), name);
6363 break;
6364 }
6365 }
103f02d3 6366
f7a99963
NC
6367 print_vma (entry->d_un.d_val, PREFIX_HEX);
6368 putchar ('\n');
252b5132
RH
6369 }
6370 break;
6371
6372 case DT_BIND_NOW:
6373 /* The value of this entry is ignored. */
35b1837e
AM
6374 if (do_dynamic)
6375 putchar ('\n');
252b5132 6376 break;
103f02d3 6377
047b2264
JJ
6378 case DT_GNU_PRELINKED:
6379 if (do_dynamic)
6380 {
2cf0635d 6381 struct tm * tmp;
047b2264
JJ
6382 time_t time = entry->d_un.d_val;
6383
6384 tmp = gmtime (&time);
6385 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
6386 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
6387 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
6388
6389 }
6390 break;
6391
fdc90cb4
JJ
6392 case DT_GNU_HASH:
6393 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
6394 if (do_dynamic)
6395 {
6396 print_vma (entry->d_un.d_val, PREFIX_HEX);
6397 putchar ('\n');
6398 }
6399 break;
6400
252b5132
RH
6401 default:
6402 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 6403 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
6404 entry->d_un.d_val;
6405
6406 if (do_dynamic)
6407 {
6408 switch (elf_header.e_machine)
6409 {
6410 case EM_MIPS:
4fe85591 6411 case EM_MIPS_RS3_LE:
b2d38a17 6412 dynamic_section_mips_val (entry);
252b5132 6413 break;
103f02d3 6414 case EM_PARISC:
b2d38a17 6415 dynamic_section_parisc_val (entry);
103f02d3 6416 break;
ecc51f48 6417 case EM_IA_64:
b2d38a17 6418 dynamic_section_ia64_val (entry);
ecc51f48 6419 break;
252b5132 6420 default:
f7a99963
NC
6421 print_vma (entry->d_un.d_val, PREFIX_HEX);
6422 putchar ('\n');
252b5132
RH
6423 }
6424 }
6425 break;
6426 }
6427 }
6428
6429 return 1;
6430}
6431
6432static char *
d3ba0551 6433get_ver_flags (unsigned int flags)
252b5132 6434{
b34976b6 6435 static char buff[32];
252b5132
RH
6436
6437 buff[0] = 0;
6438
6439 if (flags == 0)
6440 return _("none");
6441
6442 if (flags & VER_FLG_BASE)
6443 strcat (buff, "BASE ");
6444
6445 if (flags & VER_FLG_WEAK)
6446 {
6447 if (flags & VER_FLG_BASE)
6448 strcat (buff, "| ");
6449
6450 strcat (buff, "WEAK ");
6451 }
6452
6453 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
6454 strcat (buff, "| <unknown>");
6455
6456 return buff;
6457}
6458
6459/* Display the contents of the version sections. */
98fb390a 6460
252b5132 6461static int
2cf0635d 6462process_version_sections (FILE * file)
252b5132 6463{
2cf0635d 6464 Elf_Internal_Shdr * section;
b34976b6
AM
6465 unsigned i;
6466 int found = 0;
252b5132
RH
6467
6468 if (! do_version)
6469 return 1;
6470
6471 for (i = 0, section = section_headers;
6472 i < elf_header.e_shnum;
b34976b6 6473 i++, section++)
252b5132
RH
6474 {
6475 switch (section->sh_type)
6476 {
6477 case SHT_GNU_verdef:
6478 {
2cf0635d 6479 Elf_External_Verdef * edefs;
b34976b6
AM
6480 unsigned int idx;
6481 unsigned int cnt;
2cf0635d 6482 char * endbuf;
252b5132
RH
6483
6484 found = 1;
6485
6486 printf
72de5009 6487 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
6488 SECTION_NAME (section), section->sh_info);
6489
6490 printf (_(" Addr: 0x"));
6491 printf_vma (section->sh_addr);
72de5009 6492 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 6493 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
6494 section->sh_link < elf_header.e_shnum
6495 ? SECTION_NAME (section_headers + section->sh_link)
c256ffe7 6496 : "<corrupt>");
252b5132 6497
c256ffe7
JJ
6498 edefs = get_data (NULL, file, section->sh_offset, 1,
6499 section->sh_size,
d3ba0551 6500 _("version definition section"));
54806181 6501 endbuf = (char *) edefs + section->sh_size;
a6e9f9df
AM
6502 if (!edefs)
6503 break;
252b5132 6504
b34976b6 6505 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 6506 {
2cf0635d
NC
6507 char * vstart;
6508 Elf_External_Verdef * edef;
b34976b6 6509 Elf_Internal_Verdef ent;
2cf0635d 6510 Elf_External_Verdaux * eaux;
b34976b6
AM
6511 Elf_Internal_Verdaux aux;
6512 int j;
6513 int isum;
103f02d3 6514
252b5132 6515 vstart = ((char *) edefs) + idx;
54806181
AM
6516 if (vstart + sizeof (*edef) > endbuf)
6517 break;
252b5132
RH
6518
6519 edef = (Elf_External_Verdef *) vstart;
6520
6521 ent.vd_version = BYTE_GET (edef->vd_version);
6522 ent.vd_flags = BYTE_GET (edef->vd_flags);
6523 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
6524 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
6525 ent.vd_hash = BYTE_GET (edef->vd_hash);
6526 ent.vd_aux = BYTE_GET (edef->vd_aux);
6527 ent.vd_next = BYTE_GET (edef->vd_next);
6528
6529 printf (_(" %#06x: Rev: %d Flags: %s"),
6530 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
6531
6532 printf (_(" Index: %d Cnt: %d "),
6533 ent.vd_ndx, ent.vd_cnt);
6534
6535 vstart += ent.vd_aux;
6536
6537 eaux = (Elf_External_Verdaux *) vstart;
6538
6539 aux.vda_name = BYTE_GET (eaux->vda_name);
6540 aux.vda_next = BYTE_GET (eaux->vda_next);
6541
d79b3d50
NC
6542 if (VALID_DYNAMIC_NAME (aux.vda_name))
6543 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
6544 else
6545 printf (_("Name index: %ld\n"), aux.vda_name);
6546
6547 isum = idx + ent.vd_aux;
6548
b34976b6 6549 for (j = 1; j < ent.vd_cnt; j++)
252b5132
RH
6550 {
6551 isum += aux.vda_next;
6552 vstart += aux.vda_next;
6553
6554 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
6555 if (vstart + sizeof (*eaux) > endbuf)
6556 break;
252b5132
RH
6557
6558 aux.vda_name = BYTE_GET (eaux->vda_name);
6559 aux.vda_next = BYTE_GET (eaux->vda_next);
6560
d79b3d50 6561 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 6562 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 6563 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
6564 else
6565 printf (_(" %#06x: Parent %d, name index: %ld\n"),
6566 isum, j, aux.vda_name);
6567 }
54806181
AM
6568 if (j < ent.vd_cnt)
6569 printf (_(" Version def aux past end of section\n"));
252b5132
RH
6570
6571 idx += ent.vd_next;
6572 }
54806181
AM
6573 if (cnt < section->sh_info)
6574 printf (_(" Version definition past end of section\n"));
252b5132
RH
6575
6576 free (edefs);
6577 }
6578 break;
103f02d3 6579
252b5132
RH
6580 case SHT_GNU_verneed:
6581 {
2cf0635d 6582 Elf_External_Verneed * eneed;
b34976b6
AM
6583 unsigned int idx;
6584 unsigned int cnt;
2cf0635d 6585 char * endbuf;
252b5132
RH
6586
6587 found = 1;
6588
72de5009 6589 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
6590 SECTION_NAME (section), section->sh_info);
6591
6592 printf (_(" Addr: 0x"));
6593 printf_vma (section->sh_addr);
72de5009 6594 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 6595 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
6596 section->sh_link < elf_header.e_shnum
6597 ? SECTION_NAME (section_headers + section->sh_link)
c256ffe7 6598 : "<corrupt>");
252b5132 6599
c256ffe7
JJ
6600 eneed = get_data (NULL, file, section->sh_offset, 1,
6601 section->sh_size,
d3ba0551 6602 _("version need section"));
54806181 6603 endbuf = (char *) eneed + section->sh_size;
a6e9f9df
AM
6604 if (!eneed)
6605 break;
252b5132
RH
6606
6607 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
6608 {
2cf0635d 6609 Elf_External_Verneed * entry;
b34976b6
AM
6610 Elf_Internal_Verneed ent;
6611 int j;
6612 int isum;
2cf0635d 6613 char * vstart;
252b5132
RH
6614
6615 vstart = ((char *) eneed) + idx;
54806181
AM
6616 if (vstart + sizeof (*entry) > endbuf)
6617 break;
252b5132
RH
6618
6619 entry = (Elf_External_Verneed *) vstart;
6620
6621 ent.vn_version = BYTE_GET (entry->vn_version);
6622 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
6623 ent.vn_file = BYTE_GET (entry->vn_file);
6624 ent.vn_aux = BYTE_GET (entry->vn_aux);
6625 ent.vn_next = BYTE_GET (entry->vn_next);
6626
6627 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
6628
d79b3d50
NC
6629 if (VALID_DYNAMIC_NAME (ent.vn_file))
6630 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
6631 else
6632 printf (_(" File: %lx"), ent.vn_file);
6633
6634 printf (_(" Cnt: %d\n"), ent.vn_cnt);
6635
6636 vstart += ent.vn_aux;
6637
6638 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
6639 {
2cf0635d 6640 Elf_External_Vernaux * eaux;
b34976b6 6641 Elf_Internal_Vernaux aux;
252b5132 6642
54806181
AM
6643 if (vstart + sizeof (*eaux) > endbuf)
6644 break;
252b5132
RH
6645 eaux = (Elf_External_Vernaux *) vstart;
6646
6647 aux.vna_hash = BYTE_GET (eaux->vna_hash);
6648 aux.vna_flags = BYTE_GET (eaux->vna_flags);
6649 aux.vna_other = BYTE_GET (eaux->vna_other);
6650 aux.vna_name = BYTE_GET (eaux->vna_name);
6651 aux.vna_next = BYTE_GET (eaux->vna_next);
6652
d79b3d50 6653 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 6654 printf (_(" %#06x: Name: %s"),
d79b3d50 6655 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 6656 else
ecc2063b 6657 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
6658 isum, aux.vna_name);
6659
6660 printf (_(" Flags: %s Version: %d\n"),
6661 get_ver_flags (aux.vna_flags), aux.vna_other);
6662
6663 isum += aux.vna_next;
6664 vstart += aux.vna_next;
6665 }
54806181
AM
6666 if (j < ent.vn_cnt)
6667 printf (_(" Version need aux past end of section\n"));
252b5132
RH
6668
6669 idx += ent.vn_next;
6670 }
54806181
AM
6671 if (cnt < section->sh_info)
6672 printf (_(" Version need past end of section\n"));
103f02d3 6673
252b5132
RH
6674 free (eneed);
6675 }
6676 break;
6677
6678 case SHT_GNU_versym:
6679 {
2cf0635d 6680 Elf_Internal_Shdr * link_section;
b34976b6
AM
6681 int total;
6682 int cnt;
2cf0635d
NC
6683 unsigned char * edata;
6684 unsigned short * data;
6685 char * strtab;
6686 Elf_Internal_Sym * symbols;
6687 Elf_Internal_Shdr * string_sec;
d3ba0551 6688 long off;
252b5132 6689
4fbb74a6 6690 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
6691 break;
6692
4fbb74a6 6693 link_section = section_headers + section->sh_link;
08d8fa11 6694 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 6695
4fbb74a6 6696 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
6697 break;
6698
252b5132
RH
6699 found = 1;
6700
9ad5cbcf 6701 symbols = GET_ELF_SYMBOLS (file, link_section);
252b5132 6702
4fbb74a6 6703 string_sec = section_headers + link_section->sh_link;
252b5132 6704
c256ffe7 6705 strtab = get_data (NULL, file, string_sec->sh_offset, 1,
d3ba0551 6706 string_sec->sh_size, _("version string table"));
a6e9f9df
AM
6707 if (!strtab)
6708 break;
252b5132
RH
6709
6710 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
6711 SECTION_NAME (section), total);
6712
6713 printf (_(" Addr: "));
6714 printf_vma (section->sh_addr);
72de5009 6715 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 6716 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
6717 SECTION_NAME (link_section));
6718
d3ba0551
AM
6719 off = offset_from_vma (file,
6720 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
6721 total * sizeof (short));
c256ffe7 6722 edata = get_data (NULL, file, off, total, sizeof (short),
d3ba0551 6723 _("version symbol data"));
a6e9f9df
AM
6724 if (!edata)
6725 {
6726 free (strtab);
6727 break;
6728 }
252b5132 6729
c256ffe7 6730 data = cmalloc (total, sizeof (short));
252b5132
RH
6731
6732 for (cnt = total; cnt --;)
b34976b6
AM
6733 data[cnt] = byte_get (edata + cnt * sizeof (short),
6734 sizeof (short));
252b5132
RH
6735
6736 free (edata);
6737
6738 for (cnt = 0; cnt < total; cnt += 4)
6739 {
6740 int j, nn;
00d93f34 6741 int check_def, check_need;
2cf0635d 6742 char * name;
252b5132
RH
6743
6744 printf (" %03x:", cnt);
6745
6746 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 6747 switch (data[cnt + j])
252b5132
RH
6748 {
6749 case 0:
6750 fputs (_(" 0 (*local*) "), stdout);
6751 break;
6752
6753 case 1:
6754 fputs (_(" 1 (*global*) "), stdout);
6755 break;
6756
6757 default:
b34976b6
AM
6758 nn = printf ("%4x%c", data[cnt + j] & 0x7fff,
6759 data[cnt + j] & 0x8000 ? 'h' : ' ');
252b5132 6760
00d93f34
JJ
6761 check_def = 1;
6762 check_need = 1;
4fbb74a6
AM
6763 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
6764 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 6765 != SHT_NOBITS)
252b5132 6766 {
b34976b6 6767 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
6768 check_def = 0;
6769 else
6770 check_need = 0;
252b5132 6771 }
00d93f34
JJ
6772
6773 if (check_need
b34976b6 6774 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 6775 {
b34976b6
AM
6776 Elf_Internal_Verneed ivn;
6777 unsigned long offset;
252b5132 6778
d93f0186
NC
6779 offset = offset_from_vma
6780 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
6781 sizeof (Elf_External_Verneed));
252b5132 6782
b34976b6 6783 do
252b5132 6784 {
b34976b6
AM
6785 Elf_Internal_Vernaux ivna;
6786 Elf_External_Verneed evn;
6787 Elf_External_Vernaux evna;
6788 unsigned long a_off;
252b5132 6789
c256ffe7 6790 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 6791 _("version need"));
252b5132
RH
6792
6793 ivn.vn_aux = BYTE_GET (evn.vn_aux);
6794 ivn.vn_next = BYTE_GET (evn.vn_next);
6795
6796 a_off = offset + ivn.vn_aux;
6797
6798 do
6799 {
a6e9f9df 6800 get_data (&evna, file, a_off, sizeof (evna),
c256ffe7 6801 1, _("version need aux (2)"));
252b5132
RH
6802
6803 ivna.vna_next = BYTE_GET (evna.vna_next);
6804 ivna.vna_other = BYTE_GET (evna.vna_other);
6805
6806 a_off += ivna.vna_next;
6807 }
b34976b6 6808 while (ivna.vna_other != data[cnt + j]
252b5132
RH
6809 && ivna.vna_next != 0);
6810
b34976b6 6811 if (ivna.vna_other == data[cnt + j])
252b5132
RH
6812 {
6813 ivna.vna_name = BYTE_GET (evna.vna_name);
6814
54806181
AM
6815 if (ivna.vna_name >= string_sec->sh_size)
6816 name = _("*invalid*");
6817 else
6818 name = strtab + ivna.vna_name;
252b5132 6819 nn += printf ("(%s%-*s",
16062207
ILT
6820 name,
6821 12 - (int) strlen (name),
252b5132 6822 ")");
00d93f34 6823 check_def = 0;
252b5132
RH
6824 break;
6825 }
6826
6827 offset += ivn.vn_next;
6828 }
6829 while (ivn.vn_next);
6830 }
00d93f34 6831
b34976b6
AM
6832 if (check_def && data[cnt + j] != 0x8001
6833 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 6834 {
b34976b6
AM
6835 Elf_Internal_Verdef ivd;
6836 Elf_External_Verdef evd;
6837 unsigned long offset;
252b5132 6838
d93f0186
NC
6839 offset = offset_from_vma
6840 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
6841 sizeof evd);
252b5132
RH
6842
6843 do
6844 {
c256ffe7 6845 get_data (&evd, file, offset, sizeof (evd), 1,
a6e9f9df 6846 _("version def"));
252b5132
RH
6847
6848 ivd.vd_next = BYTE_GET (evd.vd_next);
6849 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
6850
6851 offset += ivd.vd_next;
6852 }
b34976b6 6853 while (ivd.vd_ndx != (data[cnt + j] & 0x7fff)
252b5132
RH
6854 && ivd.vd_next != 0);
6855
b34976b6 6856 if (ivd.vd_ndx == (data[cnt + j] & 0x7fff))
252b5132 6857 {
b34976b6
AM
6858 Elf_External_Verdaux evda;
6859 Elf_Internal_Verdaux ivda;
252b5132
RH
6860
6861 ivd.vd_aux = BYTE_GET (evd.vd_aux);
6862
a6e9f9df
AM
6863 get_data (&evda, file,
6864 offset - ivd.vd_next + ivd.vd_aux,
c256ffe7
JJ
6865 sizeof (evda), 1,
6866 _("version def aux"));
252b5132
RH
6867
6868 ivda.vda_name = BYTE_GET (evda.vda_name);
6869
54806181
AM
6870 if (ivda.vda_name >= string_sec->sh_size)
6871 name = _("*invalid*");
6872 else
6873 name = strtab + ivda.vda_name;
252b5132 6874 nn += printf ("(%s%-*s",
16062207
ILT
6875 name,
6876 12 - (int) strlen (name),
252b5132
RH
6877 ")");
6878 }
6879 }
6880
6881 if (nn < 18)
6882 printf ("%*c", 18 - nn, ' ');
6883 }
6884
6885 putchar ('\n');
6886 }
6887
6888 free (data);
6889 free (strtab);
6890 free (symbols);
6891 }
6892 break;
103f02d3 6893
252b5132
RH
6894 default:
6895 break;
6896 }
6897 }
6898
6899 if (! found)
6900 printf (_("\nNo version information found in this file.\n"));
6901
6902 return 1;
6903}
6904
d1133906 6905static const char *
d3ba0551 6906get_symbol_binding (unsigned int binding)
252b5132 6907{
b34976b6 6908 static char buff[32];
252b5132
RH
6909
6910 switch (binding)
6911 {
b34976b6
AM
6912 case STB_LOCAL: return "LOCAL";
6913 case STB_GLOBAL: return "GLOBAL";
6914 case STB_WEAK: return "WEAK";
252b5132
RH
6915 default:
6916 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
6917 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
6918 binding);
252b5132 6919 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
6920 {
6921 if (binding == STB_GNU_UNIQUE
6922 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
6923 /* GNU/Linux is still using the default value 0. */
6924 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
6925 return "UNIQUE";
6926 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
6927 }
252b5132 6928 else
e9e44622 6929 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
6930 return buff;
6931 }
6932}
6933
d1133906 6934static const char *
d3ba0551 6935get_symbol_type (unsigned int type)
252b5132 6936{
b34976b6 6937 static char buff[32];
252b5132
RH
6938
6939 switch (type)
6940 {
b34976b6
AM
6941 case STT_NOTYPE: return "NOTYPE";
6942 case STT_OBJECT: return "OBJECT";
6943 case STT_FUNC: return "FUNC";
6944 case STT_SECTION: return "SECTION";
6945 case STT_FILE: return "FILE";
6946 case STT_COMMON: return "COMMON";
6947 case STT_TLS: return "TLS";
15ab5209
DB
6948 case STT_RELC: return "RELC";
6949 case STT_SRELC: return "SRELC";
252b5132
RH
6950 default:
6951 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
6952 {
6953 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
6954 return "THUMB_FUNC";
6955
351b4b40 6956 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
6957 return "REGISTER";
6958
6959 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
6960 return "PARISC_MILLI";
6961
e9e44622 6962 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 6963 }
252b5132 6964 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
6965 {
6966 if (elf_header.e_machine == EM_PARISC)
6967 {
6968 if (type == STT_HP_OPAQUE)
6969 return "HP_OPAQUE";
6970 if (type == STT_HP_STUB)
6971 return "HP_STUB";
6972 }
6973
d8045f23
NC
6974 if (type == STT_GNU_IFUNC
6975 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
6976 /* GNU/Linux is still using the default value 0. */
6977 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
6978 return "IFUNC";
6979
e9e44622 6980 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 6981 }
252b5132 6982 else
e9e44622 6983 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
6984 return buff;
6985 }
6986}
6987
d1133906 6988static const char *
d3ba0551 6989get_symbol_visibility (unsigned int visibility)
d1133906
NC
6990{
6991 switch (visibility)
6992 {
b34976b6
AM
6993 case STV_DEFAULT: return "DEFAULT";
6994 case STV_INTERNAL: return "INTERNAL";
6995 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
6996 case STV_PROTECTED: return "PROTECTED";
6997 default: abort ();
6998 }
6999}
7000
5e2b0d47
NC
7001static const char *
7002get_mips_symbol_other (unsigned int other)
7003{
7004 switch (other)
7005 {
7006 case STO_OPTIONAL: return "OPTIONAL";
7007 case STO_MIPS16: return "MIPS16";
861fb55a
DJ
7008 case STO_MIPS_PLT: return "MIPS PLT";
7009 case STO_MIPS_PIC: return "MIPS PIC";
5e2b0d47
NC
7010 default: return NULL;
7011 }
7012}
7013
7014static const char *
7015get_symbol_other (unsigned int other)
7016{
7017 const char * result = NULL;
7018 static char buff [32];
7019
7020 if (other == 0)
7021 return "";
7022
7023 switch (elf_header.e_machine)
7024 {
7025 case EM_MIPS:
7026 result = get_mips_symbol_other (other);
7027 default:
7028 break;
7029 }
7030
7031 if (result)
7032 return result;
7033
7034 snprintf (buff, sizeof buff, _("<other>: %x"), other);
7035 return buff;
7036}
7037
d1133906 7038static const char *
d3ba0551 7039get_symbol_index_type (unsigned int type)
252b5132 7040{
b34976b6 7041 static char buff[32];
5cf1065c 7042
252b5132
RH
7043 switch (type)
7044 {
b34976b6
AM
7045 case SHN_UNDEF: return "UND";
7046 case SHN_ABS: return "ABS";
7047 case SHN_COMMON: return "COM";
252b5132 7048 default:
9ce701e2
L
7049 if (type == SHN_IA_64_ANSI_COMMON
7050 && elf_header.e_machine == EM_IA_64
7051 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
7052 return "ANSI_COM";
8a9036a4
L
7053 else if ((elf_header.e_machine == EM_X86_64
7054 || elf_header.e_machine == EM_L1OM)
3b22753a
L
7055 && type == SHN_X86_64_LCOMMON)
7056 return "LARGE_COM";
172553c7
TS
7057 else if (type == SHN_MIPS_SCOMMON
7058 && elf_header.e_machine == EM_MIPS)
7059 return "SCOM";
7060 else if (type == SHN_MIPS_SUNDEFINED
7061 && elf_header.e_machine == EM_MIPS)
7062 return "SUND";
9ce701e2 7063 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 7064 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 7065 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
7066 sprintf (buff, "OS [0x%04x]", type & 0xffff);
7067 else if (type >= SHN_LORESERVE)
7068 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
252b5132 7069 else
232e7cb8 7070 sprintf (buff, "%3d", type);
5cf1065c 7071 break;
252b5132 7072 }
5cf1065c
NC
7073
7074 return buff;
252b5132
RH
7075}
7076
66543521 7077static bfd_vma *
2cf0635d 7078get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 7079{
2cf0635d
NC
7080 unsigned char * e_data;
7081 bfd_vma * i_data;
252b5132 7082
c256ffe7 7083 e_data = cmalloc (number, ent_size);
252b5132
RH
7084
7085 if (e_data == NULL)
7086 {
7087 error (_("Out of memory\n"));
7088 return NULL;
7089 }
7090
66543521 7091 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
7092 {
7093 error (_("Unable to read in dynamic data\n"));
7094 return NULL;
7095 }
7096
c256ffe7 7097 i_data = cmalloc (number, sizeof (*i_data));
252b5132
RH
7098
7099 if (i_data == NULL)
7100 {
7101 error (_("Out of memory\n"));
7102 free (e_data);
7103 return NULL;
7104 }
7105
7106 while (number--)
66543521 7107 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
7108
7109 free (e_data);
7110
7111 return i_data;
7112}
7113
6bd1a22c
L
7114static void
7115print_dynamic_symbol (bfd_vma si, unsigned long hn)
7116{
2cf0635d 7117 Elf_Internal_Sym * psym;
6bd1a22c
L
7118 int n;
7119
7120 psym = dynamic_symbols + si;
7121
7122 n = print_vma (si, DEC_5);
7123 if (n < 5)
7124 fputs (" " + n, stdout);
7125 printf (" %3lu: ", hn);
7126 print_vma (psym->st_value, LONG_HEX);
7127 putchar (' ');
7128 print_vma (psym->st_size, DEC_5);
7129
7130 printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
7131 printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
7132 printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
7133 /* Check to see if any other bits in the st_other field are set.
7134 Note - displaying this information disrupts the layout of the
7135 table being generated, but for the moment this case is very
7136 rare. */
7137 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
7138 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
7139 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
7140 if (VALID_DYNAMIC_NAME (psym->st_name))
7141 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
7142 else
7143 printf (" <corrupt: %14ld>", psym->st_name);
7144 putchar ('\n');
7145}
7146
e3c8793a 7147/* Dump the symbol table. */
252b5132 7148static int
2cf0635d 7149process_symbol_table (FILE * file)
252b5132 7150{
2cf0635d 7151 Elf_Internal_Shdr * section;
66543521
AM
7152 bfd_vma nbuckets = 0;
7153 bfd_vma nchains = 0;
2cf0635d
NC
7154 bfd_vma * buckets = NULL;
7155 bfd_vma * chains = NULL;
fdc90cb4 7156 bfd_vma ngnubuckets = 0;
2cf0635d
NC
7157 bfd_vma * gnubuckets = NULL;
7158 bfd_vma * gnuchains = NULL;
6bd1a22c 7159 bfd_vma gnusymidx = 0;
252b5132
RH
7160
7161 if (! do_syms && !do_histogram)
7162 return 1;
7163
6bd1a22c
L
7164 if (dynamic_info[DT_HASH]
7165 && (do_histogram
7166 || (do_using_dynamic && dynamic_strings != NULL)))
252b5132 7167 {
66543521
AM
7168 unsigned char nb[8];
7169 unsigned char nc[8];
7170 int hash_ent_size = 4;
7171
7172 if ((elf_header.e_machine == EM_ALPHA
7173 || elf_header.e_machine == EM_S390
7174 || elf_header.e_machine == EM_S390_OLD)
7175 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
7176 hash_ent_size = 8;
7177
fb52b2f4
NC
7178 if (fseek (file,
7179 (archive_file_offset
7180 + offset_from_vma (file, dynamic_info[DT_HASH],
7181 sizeof nb + sizeof nc)),
d93f0186 7182 SEEK_SET))
252b5132 7183 {
591a748a 7184 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 7185 goto no_hash;
252b5132
RH
7186 }
7187
66543521 7188 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
7189 {
7190 error (_("Failed to read in number of buckets\n"));
d3a44ec6 7191 goto no_hash;
252b5132
RH
7192 }
7193
66543521 7194 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
7195 {
7196 error (_("Failed to read in number of chains\n"));
d3a44ec6 7197 goto no_hash;
252b5132
RH
7198 }
7199
66543521
AM
7200 nbuckets = byte_get (nb, hash_ent_size);
7201 nchains = byte_get (nc, hash_ent_size);
252b5132 7202
66543521
AM
7203 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
7204 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 7205
d3a44ec6 7206 no_hash:
252b5132 7207 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
7208 {
7209 if (do_using_dynamic)
7210 return 0;
7211 free (buckets);
7212 free (chains);
7213 buckets = NULL;
7214 chains = NULL;
7215 nbuckets = 0;
7216 nchains = 0;
7217 }
252b5132
RH
7218 }
7219
6bd1a22c
L
7220 if (dynamic_info_DT_GNU_HASH
7221 && (do_histogram
7222 || (do_using_dynamic && dynamic_strings != NULL)))
252b5132 7223 {
6bd1a22c
L
7224 unsigned char nb[16];
7225 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
7226 bfd_vma buckets_vma;
7227
7228 if (fseek (file,
7229 (archive_file_offset
7230 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
7231 sizeof nb)),
7232 SEEK_SET))
7233 {
7234 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 7235 goto no_gnu_hash;
6bd1a22c 7236 }
252b5132 7237
6bd1a22c
L
7238 if (fread (nb, 16, 1, file) != 1)
7239 {
7240 error (_("Failed to read in number of buckets\n"));
d3a44ec6 7241 goto no_gnu_hash;
6bd1a22c
L
7242 }
7243
7244 ngnubuckets = byte_get (nb, 4);
7245 gnusymidx = byte_get (nb + 4, 4);
7246 bitmaskwords = byte_get (nb + 8, 4);
7247 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 7248 if (is_32bit_elf)
6bd1a22c 7249 buckets_vma += bitmaskwords * 4;
f7a99963 7250 else
6bd1a22c 7251 buckets_vma += bitmaskwords * 8;
252b5132 7252
6bd1a22c
L
7253 if (fseek (file,
7254 (archive_file_offset
7255 + offset_from_vma (file, buckets_vma, 4)),
7256 SEEK_SET))
252b5132 7257 {
6bd1a22c 7258 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 7259 goto no_gnu_hash;
6bd1a22c
L
7260 }
7261
7262 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 7263
6bd1a22c 7264 if (gnubuckets == NULL)
d3a44ec6 7265 goto no_gnu_hash;
6bd1a22c
L
7266
7267 for (i = 0; i < ngnubuckets; i++)
7268 if (gnubuckets[i] != 0)
7269 {
7270 if (gnubuckets[i] < gnusymidx)
7271 return 0;
7272
7273 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
7274 maxchain = gnubuckets[i];
7275 }
7276
7277 if (maxchain == 0xffffffff)
d3a44ec6 7278 goto no_gnu_hash;
6bd1a22c
L
7279
7280 maxchain -= gnusymidx;
7281
7282 if (fseek (file,
7283 (archive_file_offset
7284 + offset_from_vma (file, buckets_vma
7285 + 4 * (ngnubuckets + maxchain), 4)),
7286 SEEK_SET))
7287 {
7288 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 7289 goto no_gnu_hash;
6bd1a22c
L
7290 }
7291
7292 do
7293 {
7294 if (fread (nb, 4, 1, file) != 1)
252b5132 7295 {
6bd1a22c 7296 error (_("Failed to determine last chain length\n"));
d3a44ec6 7297 goto no_gnu_hash;
6bd1a22c 7298 }
252b5132 7299
6bd1a22c 7300 if (maxchain + 1 == 0)
d3a44ec6 7301 goto no_gnu_hash;
252b5132 7302
6bd1a22c
L
7303 ++maxchain;
7304 }
7305 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 7306
6bd1a22c
L
7307 if (fseek (file,
7308 (archive_file_offset
7309 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
7310 SEEK_SET))
7311 {
7312 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 7313 goto no_gnu_hash;
6bd1a22c
L
7314 }
7315
7316 gnuchains = get_dynamic_data (file, maxchain, 4);
7317
d3a44ec6 7318 no_gnu_hash:
6bd1a22c 7319 if (gnuchains == NULL)
d3a44ec6
JJ
7320 {
7321 free (gnubuckets);
d3a44ec6
JJ
7322 gnubuckets = NULL;
7323 ngnubuckets = 0;
f64fddf1
NC
7324 if (do_using_dynamic)
7325 return 0;
d3a44ec6 7326 }
6bd1a22c
L
7327 }
7328
7329 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
7330 && do_syms
7331 && do_using_dynamic
7332 && dynamic_strings != NULL)
7333 {
7334 unsigned long hn;
7335
7336 if (dynamic_info[DT_HASH])
7337 {
7338 bfd_vma si;
7339
7340 printf (_("\nSymbol table for image:\n"));
7341 if (is_32bit_elf)
7342 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7343 else
7344 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7345
7346 for (hn = 0; hn < nbuckets; hn++)
7347 {
7348 if (! buckets[hn])
7349 continue;
7350
7351 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
7352 print_dynamic_symbol (si, hn);
252b5132
RH
7353 }
7354 }
6bd1a22c
L
7355
7356 if (dynamic_info_DT_GNU_HASH)
7357 {
7358 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
7359 if (is_32bit_elf)
7360 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7361 else
7362 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7363
7364 for (hn = 0; hn < ngnubuckets; ++hn)
7365 if (gnubuckets[hn] != 0)
7366 {
7367 bfd_vma si = gnubuckets[hn];
7368 bfd_vma off = si - gnusymidx;
7369
7370 do
7371 {
7372 print_dynamic_symbol (si, hn);
7373 si++;
7374 }
7375 while ((gnuchains[off++] & 1) == 0);
7376 }
7377 }
252b5132
RH
7378 }
7379 else if (do_syms && !do_using_dynamic)
7380 {
b34976b6 7381 unsigned int i;
252b5132
RH
7382
7383 for (i = 0, section = section_headers;
7384 i < elf_header.e_shnum;
7385 i++, section++)
7386 {
b34976b6 7387 unsigned int si;
2cf0635d 7388 char * strtab = NULL;
c256ffe7 7389 unsigned long int strtab_size = 0;
2cf0635d
NC
7390 Elf_Internal_Sym * symtab;
7391 Elf_Internal_Sym * psym;
252b5132
RH
7392
7393 if ( section->sh_type != SHT_SYMTAB
7394 && section->sh_type != SHT_DYNSYM)
7395 continue;
7396
7397 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
7398 SECTION_NAME (section),
7399 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 7400 if (is_32bit_elf)
ca47b30c 7401 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 7402 else
ca47b30c 7403 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 7404
9ad5cbcf 7405 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
7406 if (symtab == NULL)
7407 continue;
7408
7409 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
7410 {
7411 strtab = string_table;
7412 strtab_size = string_table_length;
7413 }
4fbb74a6 7414 else if (section->sh_link < elf_header.e_shnum)
252b5132 7415 {
2cf0635d 7416 Elf_Internal_Shdr * string_sec;
252b5132 7417
4fbb74a6 7418 string_sec = section_headers + section->sh_link;
252b5132 7419
d3ba0551 7420 strtab = get_data (NULL, file, string_sec->sh_offset,
c256ffe7
JJ
7421 1, string_sec->sh_size, _("string table"));
7422 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
7423 }
7424
7425 for (si = 0, psym = symtab;
7426 si < section->sh_size / section->sh_entsize;
b34976b6 7427 si++, psym++)
252b5132 7428 {
5e220199 7429 printf ("%6d: ", si);
f7a99963
NC
7430 print_vma (psym->st_value, LONG_HEX);
7431 putchar (' ');
7432 print_vma (psym->st_size, DEC_5);
d1133906
NC
7433 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
7434 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
7435 printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
7436 /* Check to see if any other bits in the st_other field are set.
7437 Note - displaying this information disrupts the layout of the
7438 table being generated, but for the moment this case is very rare. */
7439 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
7440 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 7441 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7
JJ
7442 print_symbol (25, psym->st_name < strtab_size
7443 ? strtab + psym->st_name : "<corrupt>");
252b5132
RH
7444
7445 if (section->sh_type == SHT_DYNSYM &&
b34976b6 7446 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 7447 {
b34976b6
AM
7448 unsigned char data[2];
7449 unsigned short vers_data;
7450 unsigned long offset;
7451 int is_nobits;
7452 int check_def;
252b5132 7453
d93f0186
NC
7454 offset = offset_from_vma
7455 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
7456 sizeof data + si * sizeof (vers_data));
252b5132 7457
a6e9f9df 7458 get_data (&data, file, offset + si * sizeof (vers_data),
c256ffe7 7459 sizeof (data), 1, _("version data"));
252b5132
RH
7460
7461 vers_data = byte_get (data, 2);
7462
4fbb74a6
AM
7463 is_nobits = (psym->st_shndx < elf_header.e_shnum
7464 && section_headers[psym->st_shndx].sh_type
c256ffe7 7465 == SHT_NOBITS);
252b5132
RH
7466
7467 check_def = (psym->st_shndx != SHN_UNDEF);
7468
7469 if ((vers_data & 0x8000) || vers_data > 1)
7470 {
b34976b6 7471 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 7472 && (is_nobits || ! check_def))
252b5132 7473 {
b34976b6
AM
7474 Elf_External_Verneed evn;
7475 Elf_Internal_Verneed ivn;
7476 Elf_Internal_Vernaux ivna;
252b5132
RH
7477
7478 /* We must test both. */
d93f0186
NC
7479 offset = offset_from_vma
7480 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
7481 sizeof evn);
252b5132 7482
252b5132
RH
7483 do
7484 {
b34976b6 7485 unsigned long vna_off;
252b5132 7486
c256ffe7 7487 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 7488 _("version need"));
dd27201e
L
7489
7490 ivn.vn_aux = BYTE_GET (evn.vn_aux);
7491 ivn.vn_next = BYTE_GET (evn.vn_next);
7492
252b5132
RH
7493 vna_off = offset + ivn.vn_aux;
7494
7495 do
7496 {
b34976b6 7497 Elf_External_Vernaux evna;
252b5132 7498
a6e9f9df 7499 get_data (&evna, file, vna_off,
c256ffe7 7500 sizeof (evna), 1,
a6e9f9df 7501 _("version need aux (3)"));
252b5132
RH
7502
7503 ivna.vna_other = BYTE_GET (evna.vna_other);
7504 ivna.vna_next = BYTE_GET (evna.vna_next);
7505 ivna.vna_name = BYTE_GET (evna.vna_name);
7506
7507 vna_off += ivna.vna_next;
7508 }
7509 while (ivna.vna_other != vers_data
7510 && ivna.vna_next != 0);
7511
7512 if (ivna.vna_other == vers_data)
7513 break;
7514
7515 offset += ivn.vn_next;
7516 }
7517 while (ivn.vn_next != 0);
7518
7519 if (ivna.vna_other == vers_data)
7520 {
7521 printf ("@%s (%d)",
c256ffe7
JJ
7522 ivna.vna_name < strtab_size
7523 ? strtab + ivna.vna_name : "<corrupt>",
7524 ivna.vna_other);
252b5132
RH
7525 check_def = 0;
7526 }
7527 else if (! is_nobits)
591a748a 7528 error (_("bad dynamic symbol\n"));
252b5132
RH
7529 else
7530 check_def = 1;
7531 }
7532
7533 if (check_def)
7534 {
00d93f34 7535 if (vers_data != 0x8001
b34976b6 7536 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 7537 {
b34976b6
AM
7538 Elf_Internal_Verdef ivd;
7539 Elf_Internal_Verdaux ivda;
7540 Elf_External_Verdaux evda;
7541 unsigned long offset;
252b5132 7542
d93f0186
NC
7543 offset = offset_from_vma
7544 (file,
7545 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
7546 sizeof (Elf_External_Verdef));
252b5132
RH
7547
7548 do
7549 {
b34976b6 7550 Elf_External_Verdef evd;
252b5132 7551
a6e9f9df 7552 get_data (&evd, file, offset, sizeof (evd),
c256ffe7 7553 1, _("version def"));
252b5132 7554
b34976b6
AM
7555 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
7556 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
7557 ivd.vd_next = BYTE_GET (evd.vd_next);
7558
7559 offset += ivd.vd_next;
7560 }
7561 while (ivd.vd_ndx != (vers_data & 0x7fff)
7562 && ivd.vd_next != 0);
7563
7564 offset -= ivd.vd_next;
7565 offset += ivd.vd_aux;
7566
a6e9f9df 7567 get_data (&evda, file, offset, sizeof (evda),
c256ffe7 7568 1, _("version def aux"));
252b5132
RH
7569
7570 ivda.vda_name = BYTE_GET (evda.vda_name);
7571
7572 if (psym->st_name != ivda.vda_name)
7573 printf ((vers_data & 0x8000)
7574 ? "@%s" : "@@%s",
c256ffe7
JJ
7575 ivda.vda_name < strtab_size
7576 ? strtab + ivda.vda_name : "<corrupt>");
252b5132
RH
7577 }
7578 }
7579 }
7580 }
7581
7582 putchar ('\n');
7583 }
7584
7585 free (symtab);
7586 if (strtab != string_table)
7587 free (strtab);
7588 }
7589 }
7590 else if (do_syms)
7591 printf
7592 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
7593
7594 if (do_histogram && buckets != NULL)
7595 {
2cf0635d
NC
7596 unsigned long * lengths;
7597 unsigned long * counts;
66543521
AM
7598 unsigned long hn;
7599 bfd_vma si;
7600 unsigned long maxlength = 0;
7601 unsigned long nzero_counts = 0;
7602 unsigned long nsyms = 0;
252b5132 7603
66543521
AM
7604 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
7605 (unsigned long) nbuckets);
252b5132
RH
7606 printf (_(" Length Number %% of total Coverage\n"));
7607
66543521 7608 lengths = calloc (nbuckets, sizeof (*lengths));
252b5132
RH
7609 if (lengths == NULL)
7610 {
591a748a 7611 error (_("Out of memory\n"));
252b5132
RH
7612 return 0;
7613 }
7614 for (hn = 0; hn < nbuckets; ++hn)
7615 {
f7a99963 7616 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 7617 {
b34976b6 7618 ++nsyms;
252b5132 7619 if (maxlength < ++lengths[hn])
b34976b6 7620 ++maxlength;
252b5132
RH
7621 }
7622 }
7623
66543521 7624 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
7625 if (counts == NULL)
7626 {
591a748a 7627 error (_("Out of memory\n"));
252b5132
RH
7628 return 0;
7629 }
7630
7631 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 7632 ++counts[lengths[hn]];
252b5132 7633
103f02d3 7634 if (nbuckets > 0)
252b5132 7635 {
66543521
AM
7636 unsigned long i;
7637 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 7638 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 7639 for (i = 1; i <= maxlength; ++i)
103f02d3 7640 {
66543521
AM
7641 nzero_counts += counts[i] * i;
7642 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
7643 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
7644 (nzero_counts * 100.0) / nsyms);
7645 }
252b5132
RH
7646 }
7647
7648 free (counts);
7649 free (lengths);
7650 }
7651
7652 if (buckets != NULL)
7653 {
7654 free (buckets);
7655 free (chains);
7656 }
7657
d3a44ec6 7658 if (do_histogram && gnubuckets != NULL)
fdc90cb4 7659 {
2cf0635d
NC
7660 unsigned long * lengths;
7661 unsigned long * counts;
fdc90cb4
JJ
7662 unsigned long hn;
7663 unsigned long maxlength = 0;
7664 unsigned long nzero_counts = 0;
7665 unsigned long nsyms = 0;
fdc90cb4
JJ
7666
7667 lengths = calloc (ngnubuckets, sizeof (*lengths));
7668 if (lengths == NULL)
7669 {
591a748a 7670 error (_("Out of memory\n"));
fdc90cb4
JJ
7671 return 0;
7672 }
7673
7674 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
7675 (unsigned long) ngnubuckets);
7676 printf (_(" Length Number %% of total Coverage\n"));
7677
7678 for (hn = 0; hn < ngnubuckets; ++hn)
7679 if (gnubuckets[hn] != 0)
7680 {
7681 bfd_vma off, length = 1;
7682
6bd1a22c 7683 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
7684 (gnuchains[off] & 1) == 0; ++off)
7685 ++length;
7686 lengths[hn] = length;
7687 if (length > maxlength)
7688 maxlength = length;
7689 nsyms += length;
7690 }
7691
7692 counts = calloc (maxlength + 1, sizeof (*counts));
7693 if (counts == NULL)
7694 {
591a748a 7695 error (_("Out of memory\n"));
fdc90cb4
JJ
7696 return 0;
7697 }
7698
7699 for (hn = 0; hn < ngnubuckets; ++hn)
7700 ++counts[lengths[hn]];
7701
7702 if (ngnubuckets > 0)
7703 {
7704 unsigned long j;
7705 printf (" 0 %-10lu (%5.1f%%)\n",
7706 counts[0], (counts[0] * 100.0) / ngnubuckets);
7707 for (j = 1; j <= maxlength; ++j)
7708 {
7709 nzero_counts += counts[j] * j;
7710 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
7711 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
7712 (nzero_counts * 100.0) / nsyms);
7713 }
7714 }
7715
7716 free (counts);
7717 free (lengths);
7718 free (gnubuckets);
7719 free (gnuchains);
7720 }
7721
252b5132
RH
7722 return 1;
7723}
7724
7725static int
2cf0635d 7726process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 7727{
b4c96d0d 7728 unsigned int i;
252b5132
RH
7729
7730 if (dynamic_syminfo == NULL
7731 || !do_dynamic)
7732 /* No syminfo, this is ok. */
7733 return 1;
7734
7735 /* There better should be a dynamic symbol section. */
7736 if (dynamic_symbols == NULL || dynamic_strings == NULL)
7737 return 0;
7738
7739 if (dynamic_addr)
7740 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
7741 dynamic_syminfo_offset, dynamic_syminfo_nent);
7742
7743 printf (_(" Num: Name BoundTo Flags\n"));
7744 for (i = 0; i < dynamic_syminfo_nent; ++i)
7745 {
7746 unsigned short int flags = dynamic_syminfo[i].si_flags;
7747
31104126 7748 printf ("%4d: ", i);
d79b3d50
NC
7749 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
7750 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
7751 else
7752 printf ("<corrupt: %19ld>", dynamic_symbols[i].st_name);
31104126 7753 putchar (' ');
252b5132
RH
7754
7755 switch (dynamic_syminfo[i].si_boundto)
7756 {
7757 case SYMINFO_BT_SELF:
7758 fputs ("SELF ", stdout);
7759 break;
7760 case SYMINFO_BT_PARENT:
7761 fputs ("PARENT ", stdout);
7762 break;
7763 default:
7764 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
7765 && dynamic_syminfo[i].si_boundto < dynamic_nent
7766 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 7767 {
d79b3d50 7768 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
7769 putchar (' ' );
7770 }
252b5132
RH
7771 else
7772 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
7773 break;
7774 }
7775
7776 if (flags & SYMINFO_FLG_DIRECT)
7777 printf (" DIRECT");
7778 if (flags & SYMINFO_FLG_PASSTHRU)
7779 printf (" PASSTHRU");
7780 if (flags & SYMINFO_FLG_COPY)
7781 printf (" COPY");
7782 if (flags & SYMINFO_FLG_LAZYLOAD)
7783 printf (" LAZYLOAD");
7784
7785 puts ("");
7786 }
7787
7788 return 1;
7789}
7790
cf13d699
NC
7791/* Check to see if the given reloc needs to be handled in a target specific
7792 manner. If so then process the reloc and return TRUE otherwise return
7793 FALSE. */
09c11c86 7794
cf13d699
NC
7795static bfd_boolean
7796target_specific_reloc_handling (Elf_Internal_Rela * reloc,
7797 unsigned char * start,
7798 Elf_Internal_Sym * symtab)
252b5132 7799{
cf13d699 7800 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 7801
cf13d699 7802 switch (elf_header.e_machine)
252b5132 7803 {
cf13d699
NC
7804 case EM_MN10300:
7805 case EM_CYGNUS_MN10300:
7806 {
7807 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 7808
cf13d699
NC
7809 switch (reloc_type)
7810 {
7811 case 34: /* R_MN10300_ALIGN */
7812 return TRUE;
7813 case 33: /* R_MN10300_SYM_DIFF */
7814 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
7815 return TRUE;
7816 case 1: /* R_MN10300_32 */
7817 case 2: /* R_MN10300_16 */
7818 if (saved_sym != NULL)
7819 {
7820 bfd_vma value;
252b5132 7821
cf13d699
NC
7822 value = reloc->r_addend
7823 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
7824 - saved_sym->st_value);
252b5132 7825
cf13d699 7826 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 7827
cf13d699
NC
7828 saved_sym = NULL;
7829 return TRUE;
7830 }
7831 break;
7832 default:
7833 if (saved_sym != NULL)
7834 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
7835 break;
7836 }
7837 break;
7838 }
252b5132
RH
7839 }
7840
cf13d699 7841 return FALSE;
252b5132
RH
7842}
7843
aca88567
NC
7844/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
7845 DWARF debug sections. This is a target specific test. Note - we do not
7846 go through the whole including-target-headers-multiple-times route, (as
7847 we have already done with <elf/h8.h>) because this would become very
7848 messy and even then this function would have to contain target specific
7849 information (the names of the relocs instead of their numeric values).
7850 FIXME: This is not the correct way to solve this problem. The proper way
7851 is to have target specific reloc sizing and typing functions created by
7852 the reloc-macros.h header, in the same way that it already creates the
7853 reloc naming functions. */
7854
7855static bfd_boolean
7856is_32bit_abs_reloc (unsigned int reloc_type)
7857{
7858 switch (elf_header.e_machine)
7859 {
41e92641
NC
7860 case EM_386:
7861 case EM_486:
7862 return reloc_type == 1; /* R_386_32. */
aca88567
NC
7863 case EM_68K:
7864 return reloc_type == 1; /* R_68K_32. */
7865 case EM_860:
7866 return reloc_type == 1; /* R_860_32. */
7867 case EM_ALPHA:
7868 return reloc_type == 1; /* XXX Is this right ? */
41e92641
NC
7869 case EM_ARC:
7870 return reloc_type == 1; /* R_ARC_32. */
7871 case EM_ARM:
7872 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 7873 case EM_AVR_OLD:
aca88567
NC
7874 case EM_AVR:
7875 return reloc_type == 1;
7876 case EM_BLACKFIN:
7877 return reloc_type == 0x12; /* R_byte4_data. */
7878 case EM_CRIS:
7879 return reloc_type == 3; /* R_CRIS_32. */
7880 case EM_CR16:
6c03b1ed 7881 case EM_CR16_OLD:
aca88567
NC
7882 return reloc_type == 3; /* R_CR16_NUM32. */
7883 case EM_CRX:
7884 return reloc_type == 15; /* R_CRX_NUM32. */
7885 case EM_CYGNUS_FRV:
7886 return reloc_type == 1;
41e92641
NC
7887 case EM_CYGNUS_D10V:
7888 case EM_D10V:
7889 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
7890 case EM_CYGNUS_D30V:
7891 case EM_D30V:
7892 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
7893 case EM_DLX:
7894 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
7895 case EM_CYGNUS_FR30:
7896 case EM_FR30:
7897 return reloc_type == 3; /* R_FR30_32. */
7898 case EM_H8S:
7899 case EM_H8_300:
7900 case EM_H8_300H:
7901 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
7902 case EM_IA_64:
7903 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
7904 case EM_IP2K_OLD:
7905 case EM_IP2K:
7906 return reloc_type == 2; /* R_IP2K_32. */
7907 case EM_IQ2000:
7908 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
7909 case EM_LATTICEMICO32:
7910 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 7911 case EM_M32C_OLD:
aca88567
NC
7912 case EM_M32C:
7913 return reloc_type == 3; /* R_M32C_32. */
7914 case EM_M32R:
7915 return reloc_type == 34; /* R_M32R_32_RELA. */
7916 case EM_MCORE:
7917 return reloc_type == 1; /* R_MCORE_ADDR32. */
7918 case EM_CYGNUS_MEP:
7919 return reloc_type == 4; /* R_MEP_32. */
7920 case EM_MIPS:
7921 return reloc_type == 2; /* R_MIPS_32. */
7922 case EM_MMIX:
7923 return reloc_type == 4; /* R_MMIX_32. */
7924 case EM_CYGNUS_MN10200:
7925 case EM_MN10200:
7926 return reloc_type == 1; /* R_MN10200_32. */
7927 case EM_CYGNUS_MN10300:
7928 case EM_MN10300:
7929 return reloc_type == 1; /* R_MN10300_32. */
7930 case EM_MSP430_OLD:
7931 case EM_MSP430:
7932 return reloc_type == 1; /* R_MSP43_32. */
7933 case EM_MT:
7934 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
7935 case EM_ALTERA_NIOS2:
7936 case EM_NIOS32:
7937 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
7938 case EM_OPENRISC:
7939 case EM_OR32:
7940 return reloc_type == 1; /* R_OR32_32. */
aca88567 7941 case EM_PARISC:
5fda8eca
NC
7942 return (reloc_type == 1 /* R_PARISC_DIR32. */
7943 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
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;
58332dda
JK
8166 case EM_XTENSA_OLD:
8167 case EM_XTENSA:
8168 return reloc_type == 0 /* R_XTENSA_NONE. */
8169 || reloc_type == 17 /* R_XTENSA_DIFF8. */
8170 || reloc_type == 18 /* R_XTENSA_DIFF16. */
8171 || reloc_type == 19; /* R_XTENSA_DIFF32. */
2a7b2e88
JK
8172 }
8173 return FALSE;
8174}
8175
cf13d699
NC
8176/* Apply relocations to a section.
8177 Note: So far support has been added only for those relocations
8178 which can be found in debug sections.
8179 FIXME: Add support for more relocations ? */
1b315056 8180
cf13d699
NC
8181static void
8182apply_relocations (void * file,
8183 Elf_Internal_Shdr * section,
8184 unsigned char * start)
1b315056 8185{
cf13d699
NC
8186 Elf_Internal_Shdr * relsec;
8187 unsigned char * end = start + section->sh_size;
cb8f3167 8188
cf13d699
NC
8189 if (elf_header.e_type != ET_REL)
8190 return;
1b315056 8191
cf13d699 8192 /* Find the reloc section associated with the section. */
5b18a4bc
NC
8193 for (relsec = section_headers;
8194 relsec < section_headers + elf_header.e_shnum;
8195 ++relsec)
252b5132 8196 {
41e92641
NC
8197 bfd_boolean is_rela;
8198 unsigned long num_relocs;
2cf0635d
NC
8199 Elf_Internal_Rela * relocs;
8200 Elf_Internal_Rela * rp;
8201 Elf_Internal_Shdr * symsec;
8202 Elf_Internal_Sym * symtab;
8203 Elf_Internal_Sym * sym;
252b5132 8204
41e92641 8205 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
8206 || relsec->sh_info >= elf_header.e_shnum
8207 || section_headers + relsec->sh_info != section
c256ffe7 8208 || relsec->sh_size == 0
4fbb74a6 8209 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 8210 continue;
428409d5 8211
41e92641
NC
8212 is_rela = relsec->sh_type == SHT_RELA;
8213
8214 if (is_rela)
8215 {
8216 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
8217 & relocs, & num_relocs))
8218 return;
8219 }
8220 else
8221 {
8222 if (!slurp_rel_relocs (file, relsec->sh_offset, relsec->sh_size,
8223 & relocs, & num_relocs))
8224 return;
8225 }
8226
8227 /* SH uses RELA but uses in place value instead of the addend field. */
8228 if (elf_header.e_machine == EM_SH)
8229 is_rela = FALSE;
428409d5 8230
4fbb74a6 8231 symsec = section_headers + relsec->sh_link;
5b18a4bc 8232 symtab = GET_ELF_SYMBOLS (file, symsec);
103f02d3 8233
41e92641 8234 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 8235 {
41e92641
NC
8236 bfd_vma addend;
8237 unsigned int reloc_type;
8238 unsigned int reloc_size;
8239 unsigned char * loc;
4b78141a 8240
aca88567 8241 reloc_type = get_reloc_type (rp->r_info);
41e92641 8242
98fb390a 8243 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 8244 continue;
98fb390a
NC
8245 else if (is_none_reloc (reloc_type))
8246 continue;
8247 else if (is_32bit_abs_reloc (reloc_type)
8248 || is_32bit_pcrel_reloc (reloc_type))
aca88567 8249 reloc_size = 4;
85acf597
RH
8250 else if (is_64bit_abs_reloc (reloc_type)
8251 || is_64bit_pcrel_reloc (reloc_type))
aca88567
NC
8252 reloc_size = 8;
8253 else if (is_16bit_abs_reloc (reloc_type))
8254 reloc_size = 2;
8255 else
4b78141a 8256 {
41e92641 8257 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 8258 reloc_type, SECTION_NAME (section));
4b78141a
NC
8259 continue;
8260 }
103f02d3 8261
700dd8b7
L
8262 loc = start + rp->r_offset;
8263 if ((loc + reloc_size) > end)
8264 {
8265 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
8266 (unsigned long) rp->r_offset,
8267 SECTION_NAME (section));
8268 continue;
8269 }
103f02d3 8270
41e92641
NC
8271 sym = symtab + get_reloc_symindex (rp->r_info);
8272
8273 /* If the reloc has a symbol associated with it,
55f25fc3
L
8274 make sure that it is of an appropriate type.
8275
8276 Relocations against symbols without type can happen.
8277 Gcc -feliminate-dwarf2-dups may generate symbols
8278 without type for debug info.
8279
8280 Icc generates relocations against function symbols
8281 instead of local labels.
8282
8283 Relocations against object symbols can happen, eg when
8284 referencing a global array. For an example of this see
8285 the _clz.o binary in libgcc.a. */
aca88567 8286 if (sym != symtab
55f25fc3 8287 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 8288 {
41e92641 8289 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 8290 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 8291 (long int)(rp - relocs),
41e92641 8292 SECTION_NAME (relsec));
aca88567 8293 continue;
5b18a4bc 8294 }
252b5132 8295
41e92641 8296 addend = is_rela ? rp->r_addend : byte_get (loc, reloc_size);
cb8f3167 8297
85acf597
RH
8298 if (is_32bit_pcrel_reloc (reloc_type)
8299 || is_64bit_pcrel_reloc (reloc_type))
8300 {
8301 /* On HPPA, all pc-relative relocations are biased by 8. */
8302 if (elf_header.e_machine == EM_PARISC)
8303 addend -= 8;
8304 byte_put (loc, (addend + sym->st_value) - rp->r_offset,
8305 reloc_size);
8306 }
41e92641
NC
8307 else
8308 byte_put (loc, addend + sym->st_value, reloc_size);
5b18a4bc 8309 }
252b5132 8310
5b18a4bc 8311 free (symtab);
41e92641 8312 free (relocs);
5b18a4bc
NC
8313 break;
8314 }
5b18a4bc 8315}
103f02d3 8316
cf13d699
NC
8317#ifdef SUPPORT_DISASSEMBLY
8318static int
8319disassemble_section (Elf_Internal_Shdr * section, FILE * file)
8320{
8321 printf (_("\nAssembly dump of section %s\n"),
8322 SECTION_NAME (section));
8323
8324 /* XXX -- to be done --- XXX */
8325
8326 return 1;
8327}
8328#endif
8329
8330/* Reads in the contents of SECTION from FILE, returning a pointer
8331 to a malloc'ed buffer or NULL if something went wrong. */
8332
8333static char *
8334get_section_contents (Elf_Internal_Shdr * section, FILE * file)
8335{
8336 bfd_size_type num_bytes;
8337
8338 num_bytes = section->sh_size;
8339
8340 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
8341 {
8342 printf (_("\nSection '%s' has no data to dump.\n"),
8343 SECTION_NAME (section));
8344 return NULL;
8345 }
8346
8347 return get_data (NULL, file, section->sh_offset, 1, num_bytes,
8348 _("section contents"));
8349}
8350
8351
8352static void
8353dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
8354{
8355 Elf_Internal_Shdr * relsec;
8356 bfd_size_type num_bytes;
8357 bfd_vma addr;
8358 char * data;
8359 char * end;
8360 char * start;
8361 char * name = SECTION_NAME (section);
8362 bfd_boolean some_strings_shown;
8363
8364 start = get_section_contents (section, file);
8365 if (start == NULL)
8366 return;
8367
8368 printf (_("\nString dump of section '%s':\n"), name);
8369
8370 /* If the section being dumped has relocations against it the user might
8371 be expecting these relocations to have been applied. Check for this
8372 case and issue a warning message in order to avoid confusion.
8373 FIXME: Maybe we ought to have an option that dumps a section with
8374 relocs applied ? */
8375 for (relsec = section_headers;
8376 relsec < section_headers + elf_header.e_shnum;
8377 ++relsec)
8378 {
8379 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
8380 || relsec->sh_info >= elf_header.e_shnum
8381 || section_headers + relsec->sh_info != section
8382 || relsec->sh_size == 0
8383 || relsec->sh_link >= elf_header.e_shnum)
8384 continue;
8385
8386 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
8387 break;
8388 }
8389
8390 num_bytes = section->sh_size;
8391 addr = section->sh_addr;
8392 data = start;
8393 end = start + num_bytes;
8394 some_strings_shown = FALSE;
8395
8396 while (data < end)
8397 {
8398 while (!ISPRINT (* data))
8399 if (++ data >= end)
8400 break;
8401
8402 if (data < end)
8403 {
8404#ifndef __MSVCRT__
8405 printf (" [%6tx] %s\n", data - start, data);
8406#else
8407 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
8408#endif
8409 data += strlen (data);
8410 some_strings_shown = TRUE;
8411 }
8412 }
8413
8414 if (! some_strings_shown)
8415 printf (_(" No strings found in this section."));
8416
8417 free (start);
8418
8419 putchar ('\n');
8420}
8421
8422static void
8423dump_section_as_bytes (Elf_Internal_Shdr * section,
8424 FILE * file,
8425 bfd_boolean relocate)
8426{
8427 Elf_Internal_Shdr * relsec;
8428 bfd_size_type bytes;
8429 bfd_vma addr;
8430 unsigned char * data;
8431 unsigned char * start;
8432
8433 start = (unsigned char *) get_section_contents (section, file);
8434 if (start == NULL)
8435 return;
8436
8437 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
8438
8439 if (relocate)
8440 {
8441 apply_relocations (file, section, start);
8442 }
8443 else
8444 {
8445 /* If the section being dumped has relocations against it the user might
8446 be expecting these relocations to have been applied. Check for this
8447 case and issue a warning message in order to avoid confusion.
8448 FIXME: Maybe we ought to have an option that dumps a section with
8449 relocs applied ? */
8450 for (relsec = section_headers;
8451 relsec < section_headers + elf_header.e_shnum;
8452 ++relsec)
8453 {
8454 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
8455 || relsec->sh_info >= elf_header.e_shnum
8456 || section_headers + relsec->sh_info != section
8457 || relsec->sh_size == 0
8458 || relsec->sh_link >= elf_header.e_shnum)
8459 continue;
8460
8461 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
8462 break;
8463 }
8464 }
8465
8466 addr = section->sh_addr;
8467 bytes = section->sh_size;
8468 data = start;
8469
8470 while (bytes)
8471 {
8472 int j;
8473 int k;
8474 int lbytes;
8475
8476 lbytes = (bytes > 16 ? 16 : bytes);
8477
8478 printf (" 0x%8.8lx ", (unsigned long) addr);
8479
8480 for (j = 0; j < 16; j++)
8481 {
8482 if (j < lbytes)
8483 printf ("%2.2x", data[j]);
8484 else
8485 printf (" ");
8486
8487 if ((j & 3) == 3)
8488 printf (" ");
8489 }
8490
8491 for (j = 0; j < lbytes; j++)
8492 {
8493 k = data[j];
8494 if (k >= ' ' && k < 0x7f)
8495 printf ("%c", k);
8496 else
8497 printf (".");
8498 }
8499
8500 putchar ('\n');
8501
8502 data += lbytes;
8503 addr += lbytes;
8504 bytes -= lbytes;
8505 }
8506
8507 free (start);
8508
8509 putchar ('\n');
8510}
8511
8512/* Uncompresses a section that was compressed using zlib, in place.
8513 This is a copy of bfd_uncompress_section_contents, in bfd/compress.c */
8514
8515static int
8516uncompress_section_contents (unsigned char ** buffer, dwarf_size_type * size)
8517{
8518#ifndef HAVE_ZLIB_H
8519 /* These are just to quiet gcc. */
8520 buffer = 0;
8521 size = 0;
8522 return FALSE;
8523#else
8524 dwarf_size_type compressed_size = *size;
8525 unsigned char * compressed_buffer = *buffer;
8526 dwarf_size_type uncompressed_size;
8527 unsigned char * uncompressed_buffer;
8528 z_stream strm;
8529 int rc;
8530 dwarf_size_type header_size = 12;
8531
8532 /* Read the zlib header. In this case, it should be "ZLIB" followed
8533 by the uncompressed section size, 8 bytes in big-endian order. */
8534 if (compressed_size < header_size
8535 || ! streq ((char *) compressed_buffer, "ZLIB"))
8536 return 0;
8537
8538 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
8539 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
8540 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
8541 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
8542 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
8543 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
8544 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
8545 uncompressed_size += compressed_buffer[11];
8546
8547 /* It is possible the section consists of several compressed
8548 buffers concatenated together, so we uncompress in a loop. */
8549 strm.zalloc = NULL;
8550 strm.zfree = NULL;
8551 strm.opaque = NULL;
8552 strm.avail_in = compressed_size - header_size;
8553 strm.next_in = (Bytef *) compressed_buffer + header_size;
8554 strm.avail_out = uncompressed_size;
8555 uncompressed_buffer = xmalloc (uncompressed_size);
8556
8557 rc = inflateInit (& strm);
8558 while (strm.avail_in > 0)
8559 {
8560 if (rc != Z_OK)
8561 goto fail;
8562 strm.next_out = ((Bytef *) uncompressed_buffer
8563 + (uncompressed_size - strm.avail_out));
8564 rc = inflate (&strm, Z_FINISH);
8565 if (rc != Z_STREAM_END)
8566 goto fail;
8567 rc = inflateReset (& strm);
8568 }
8569 rc = inflateEnd (& strm);
8570 if (rc != Z_OK
8571 || strm.avail_out != 0)
8572 goto fail;
8573
8574 free (compressed_buffer);
8575 *buffer = uncompressed_buffer;
8576 *size = uncompressed_size;
8577 return 1;
8578
8579 fail:
8580 free (uncompressed_buffer);
8581 return 0;
8582#endif /* HAVE_ZLIB_H */
8583}
8584
d966045b
DJ
8585static int
8586load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 8587 Elf_Internal_Shdr * sec, void * file)
1007acb3 8588{
2cf0635d 8589 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 8590 char buf [64];
1b315056 8591 int section_is_compressed;
1007acb3 8592
19e6b90e
L
8593 /* If it is already loaded, do nothing. */
8594 if (section->start != NULL)
8595 return 1;
1007acb3 8596
a71cc8e0 8597 section_is_compressed = section->name == section->compressed_name;
1007acb3 8598
19e6b90e
L
8599 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
8600 section->address = sec->sh_addr;
8601 section->size = sec->sh_size;
8602 section->start = get_data (NULL, file, sec->sh_offset, 1,
8603 sec->sh_size, buf);
1b315056
CS
8604 if (section->start == NULL)
8605 return 0;
8606
8607 if (section_is_compressed)
8608 if (! uncompress_section_contents (&section->start, &section->size))
8609 return 0;
1007acb3 8610
19e6b90e 8611 if (debug_displays [debug].relocate)
cf13d699 8612 apply_relocations (file, sec, section->start);
1007acb3 8613
1b315056 8614 return 1;
1007acb3
L
8615}
8616
d966045b 8617int
2cf0635d 8618load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 8619{
2cf0635d
NC
8620 struct dwarf_section * section = &debug_displays [debug].section;
8621 Elf_Internal_Shdr * sec;
d966045b
DJ
8622
8623 /* Locate the debug section. */
8624 sec = find_section (section->uncompressed_name);
8625 if (sec != NULL)
8626 section->name = section->uncompressed_name;
8627 else
8628 {
8629 sec = find_section (section->compressed_name);
8630 if (sec != NULL)
8631 section->name = section->compressed_name;
8632 }
8633 if (sec == NULL)
8634 return 0;
8635
8636 return load_specific_debug_section (debug, sec, file);
8637}
8638
19e6b90e
L
8639void
8640free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 8641{
2cf0635d 8642 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 8643
19e6b90e
L
8644 if (section->start == NULL)
8645 return;
1007acb3 8646
19e6b90e
L
8647 free ((char *) section->start);
8648 section->start = NULL;
8649 section->address = 0;
8650 section->size = 0;
1007acb3
L
8651}
8652
1007acb3 8653static int
2cf0635d 8654display_debug_section (Elf_Internal_Shdr * section, FILE * file)
1007acb3 8655{
2cf0635d 8656 char * name = SECTION_NAME (section);
19e6b90e
L
8657 bfd_size_type length;
8658 int result = 1;
8659 enum dwarf_section_display_enum i;
1007acb3 8660
19e6b90e
L
8661 length = section->sh_size;
8662 if (length == 0)
1007acb3 8663 {
19e6b90e
L
8664 printf (_("\nSection '%s' has no debugging data.\n"), name);
8665 return 0;
1007acb3 8666 }
5dff79d8
NC
8667 if (section->sh_type == SHT_NOBITS)
8668 {
8669 /* There is no point in dumping the contents of a debugging section
8670 which has the NOBITS type - the bits in the file will be random.
8671 This can happen when a file containing a .eh_frame section is
8672 stripped with the --only-keep-debug command line option. */
8673 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
8674 return 0;
8675 }
1007acb3 8676
0112cd26 8677 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 8678 name = ".debug_info";
1007acb3 8679
19e6b90e
L
8680 /* See if we know how to display the contents of this section. */
8681 for (i = 0; i < max; i++)
1b315056
CS
8682 if (streq (debug_displays[i].section.uncompressed_name, name)
8683 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 8684 {
2cf0635d 8685 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
8686 int secondary = (section != find_section (name));
8687
8688 if (secondary)
8689 free_debug_section (i);
1007acb3 8690
d966045b
DJ
8691 if (streq (debug_displays[i].section.uncompressed_name, name))
8692 sec->name = sec->uncompressed_name;
8693 else
8694 sec->name = sec->compressed_name;
8695 if (load_specific_debug_section (i, section, file))
19e6b90e
L
8696 {
8697 result &= debug_displays[i].display (sec, file);
1007acb3 8698
d966045b 8699 if (secondary || (i != info && i != abbrev))
19e6b90e
L
8700 free_debug_section (i);
8701 }
1007acb3 8702
19e6b90e
L
8703 break;
8704 }
1007acb3 8705
19e6b90e 8706 if (i == max)
1007acb3 8707 {
19e6b90e
L
8708 printf (_("Unrecognized debug section: %s\n"), name);
8709 result = 0;
1007acb3
L
8710 }
8711
19e6b90e 8712 return result;
5b18a4bc 8713}
103f02d3 8714
aef1f6d0
DJ
8715/* Set DUMP_SECTS for all sections where dumps were requested
8716 based on section name. */
8717
8718static void
8719initialise_dumps_byname (void)
8720{
2cf0635d 8721 struct dump_list_entry * cur;
aef1f6d0
DJ
8722
8723 for (cur = dump_sects_byname; cur; cur = cur->next)
8724 {
8725 unsigned int i;
8726 int any;
8727
8728 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
8729 if (streq (SECTION_NAME (section_headers + i), cur->name))
8730 {
09c11c86 8731 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
8732 any = 1;
8733 }
8734
8735 if (!any)
8736 warn (_("Section '%s' was not dumped because it does not exist!\n"),
8737 cur->name);
8738 }
8739}
8740
5b18a4bc 8741static void
2cf0635d 8742process_section_contents (FILE * file)
5b18a4bc 8743{
2cf0635d 8744 Elf_Internal_Shdr * section;
19e6b90e 8745 unsigned int i;
103f02d3 8746
19e6b90e
L
8747 if (! do_dump)
8748 return;
103f02d3 8749
aef1f6d0
DJ
8750 initialise_dumps_byname ();
8751
19e6b90e
L
8752 for (i = 0, section = section_headers;
8753 i < elf_header.e_shnum && i < num_dump_sects;
8754 i++, section++)
8755 {
8756#ifdef SUPPORT_DISASSEMBLY
8757 if (dump_sects[i] & DISASS_DUMP)
8758 disassemble_section (section, file);
8759#endif
8760 if (dump_sects[i] & HEX_DUMP)
cf13d699 8761 dump_section_as_bytes (section, file, FALSE);
103f02d3 8762
cf13d699
NC
8763 if (dump_sects[i] & RELOC_DUMP)
8764 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
8765
8766 if (dump_sects[i] & STRING_DUMP)
8767 dump_section_as_strings (section, file);
cf13d699
NC
8768
8769 if (dump_sects[i] & DEBUG_DUMP)
8770 display_debug_section (section, file);
5b18a4bc 8771 }
103f02d3 8772
19e6b90e
L
8773 /* Check to see if the user requested a
8774 dump of a section that does not exist. */
8775 while (i++ < num_dump_sects)
8776 if (dump_sects[i])
8777 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 8778}
103f02d3 8779
5b18a4bc 8780static void
19e6b90e 8781process_mips_fpe_exception (int mask)
5b18a4bc 8782{
19e6b90e
L
8783 if (mask)
8784 {
8785 int first = 1;
8786 if (mask & OEX_FPU_INEX)
8787 fputs ("INEX", stdout), first = 0;
8788 if (mask & OEX_FPU_UFLO)
8789 printf ("%sUFLO", first ? "" : "|"), first = 0;
8790 if (mask & OEX_FPU_OFLO)
8791 printf ("%sOFLO", first ? "" : "|"), first = 0;
8792 if (mask & OEX_FPU_DIV0)
8793 printf ("%sDIV0", first ? "" : "|"), first = 0;
8794 if (mask & OEX_FPU_INVAL)
8795 printf ("%sINVAL", first ? "" : "|");
8796 }
5b18a4bc 8797 else
19e6b90e 8798 fputs ("0", stdout);
5b18a4bc 8799}
103f02d3 8800
11c1ff18
PB
8801/* ARM EABI attributes section. */
8802typedef struct
8803{
8804 int tag;
2cf0635d 8805 const char * name;
11c1ff18
PB
8806 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
8807 int type;
2cf0635d 8808 const char ** table;
11c1ff18
PB
8809} arm_attr_public_tag;
8810
2cf0635d 8811static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 8812 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
f5f53991 8813 "v6K", "v7", "v6-M", "v6S-M"};
2cf0635d
NC
8814static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
8815static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 8816 {"No", "Thumb-1", "Thumb-2"};
2cf0635d 8817static const char * arm_attr_tag_VFP_arch[] =
b1cc4aeb 8818 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16"};
2cf0635d
NC
8819static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
8820static const char * arm_attr_tag_Advanced_SIMD_arch[] = {"No", "NEONv1"};
8821static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
8822 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
8823 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 8824static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 8825 {"V6", "SB", "TLS", "Unused"};
2cf0635d 8826static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 8827 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 8828static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 8829 {"Absolute", "PC-relative", "None"};
2cf0635d 8830static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 8831 {"None", "direct", "GOT-indirect"};
2cf0635d 8832static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 8833 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
8834static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
8835static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 8836 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
8837static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
8838static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
8839static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 8840 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d
NC
8841static const char * arm_attr_tag_ABI_align8_needed[] = {"No", "Yes", "4-byte"};
8842static const char * arm_attr_tag_ABI_align8_preserved[] =
11c1ff18 8843 {"No", "Yes, except leaf SP", "Yes"};
2cf0635d 8844static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 8845 {"Unused", "small", "int", "forced to int"};
2cf0635d 8846static const char * arm_attr_tag_ABI_HardFP_use[] =
11c1ff18 8847 {"As Tag_VFP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 8848static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 8849 {"AAPCS", "VFP registers", "custom"};
2cf0635d 8850static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 8851 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 8852static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
8853 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
8854 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 8855static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
8856 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
8857 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d
NC
8858static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
8859static const char * arm_attr_tag_VFP_HP_extension[] =
8e79c3df 8860 {"Not Allowed", "Allowed"};
2cf0635d 8861static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 8862 {"None", "IEEE 754", "Alternative Format"};
2cf0635d
NC
8863static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
8864static const char * arm_attr_tag_Virtualization_use[] =
f5f53991 8865 {"Not Allowed", "Allowed"};
2cf0635d 8866static const char * arm_attr_tag_MPextension_use[] = {"Not Allowed", "Allowed"};
11c1ff18
PB
8867
8868#define LOOKUP(id, name) \
8869 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 8870static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
8871{
8872 {4, "CPU_raw_name", 1, NULL},
8873 {5, "CPU_name", 1, NULL},
8874 LOOKUP(6, CPU_arch),
8875 {7, "CPU_arch_profile", 0, NULL},
8876 LOOKUP(8, ARM_ISA_use),
8877 LOOKUP(9, THUMB_ISA_use),
8878 LOOKUP(10, VFP_arch),
8879 LOOKUP(11, WMMX_arch),
f5f53991
AS
8880 LOOKUP(12, Advanced_SIMD_arch),
8881 LOOKUP(13, PCS_config),
11c1ff18
PB
8882 LOOKUP(14, ABI_PCS_R9_use),
8883 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 8884 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
8885 LOOKUP(17, ABI_PCS_GOT_use),
8886 LOOKUP(18, ABI_PCS_wchar_t),
8887 LOOKUP(19, ABI_FP_rounding),
8888 LOOKUP(20, ABI_FP_denormal),
8889 LOOKUP(21, ABI_FP_exceptions),
8890 LOOKUP(22, ABI_FP_user_exceptions),
8891 LOOKUP(23, ABI_FP_number_model),
8892 LOOKUP(24, ABI_align8_needed),
8893 LOOKUP(25, ABI_align8_preserved),
8894 LOOKUP(26, ABI_enum_size),
8895 LOOKUP(27, ABI_HardFP_use),
8896 LOOKUP(28, ABI_VFP_args),
8897 LOOKUP(29, ABI_WMMX_args),
8898 LOOKUP(30, ABI_optimization_goals),
8899 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 8900 {32, "compatibility", 0, NULL},
f5f53991 8901 LOOKUP(34, CPU_unaligned_access),
8e79c3df
CM
8902 LOOKUP(36, VFP_HP_extension),
8903 LOOKUP(38, ABI_FP_16bit_format),
f5f53991
AS
8904 {64, "nodefaults", 0, NULL},
8905 {65, "also_compatible_with", 0, NULL},
8906 LOOKUP(66, T2EE_use),
8907 {67, "conformance", 1, NULL},
8908 LOOKUP(68, Virtualization_use),
8909 LOOKUP(70, MPextension_use)
11c1ff18
PB
8910};
8911#undef LOOKUP
8912
8913/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
8914 bytes read. */
2cf0635d 8915
11c1ff18 8916static unsigned int
2cf0635d 8917read_uleb128 (unsigned char * p, unsigned int * plen)
11c1ff18
PB
8918{
8919 unsigned char c;
8920 unsigned int val;
8921 int shift;
8922 int len;
8923
8924 val = 0;
8925 shift = 0;
8926 len = 0;
8927 do
8928 {
8929 c = *(p++);
8930 len++;
8931 val |= ((unsigned int)c & 0x7f) << shift;
8932 shift += 7;
8933 }
8934 while (c & 0x80);
8935
8936 *plen = len;
8937 return val;
8938}
8939
8940static unsigned char *
2cf0635d 8941display_arm_attribute (unsigned char * p)
11c1ff18
PB
8942{
8943 int tag;
8944 unsigned int len;
8945 int val;
2cf0635d 8946 arm_attr_public_tag * attr;
11c1ff18
PB
8947 unsigned i;
8948 int type;
8949
8950 tag = read_uleb128 (p, &len);
8951 p += len;
8952 attr = NULL;
2cf0635d 8953 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
8954 {
8955 if (arm_attr_public_tags[i].tag == tag)
8956 {
8957 attr = &arm_attr_public_tags[i];
8958 break;
8959 }
8960 }
8961
8962 if (attr)
8963 {
8964 printf (" Tag_%s: ", attr->name);
8965 switch (attr->type)
8966 {
8967 case 0:
8968 switch (tag)
8969 {
8970 case 7: /* Tag_CPU_arch_profile. */
8971 val = read_uleb128 (p, &len);
8972 p += len;
8973 switch (val)
8974 {
8975 case 0: printf ("None\n"); break;
8976 case 'A': printf ("Application\n"); break;
8977 case 'R': printf ("Realtime\n"); break;
8978 case 'M': printf ("Microcontroller\n"); break;
8979 default: printf ("??? (%d)\n", val); break;
8980 }
8981 break;
8982
8983 case 32: /* Tag_compatibility. */
8984 val = read_uleb128 (p, &len);
8985 p += len;
8986 printf ("flag = %d, vendor = %s\n", val, p);
2cf0635d 8987 p += strlen ((char *) p) + 1;
11c1ff18
PB
8988 break;
8989
f5f53991
AS
8990 case 64: /* Tag_nodefaults. */
8991 p++;
8992 printf ("True\n");
8993 break;
8994
8995 case 65: /* Tag_also_compatible_with. */
8996 val = read_uleb128 (p, &len);
8997 p += len;
8998 if (val == 6 /* Tag_CPU_arch. */)
8999 {
9000 val = read_uleb128 (p, &len);
9001 p += len;
2cf0635d 9002 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
9003 printf ("??? (%d)\n", val);
9004 else
9005 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
9006 }
9007 else
9008 printf ("???\n");
9009 while (*(p++) != '\0' /* NUL terminator. */);
9010 break;
9011
11c1ff18 9012 default:
2cf0635d 9013 abort ();
11c1ff18
PB
9014 }
9015 return p;
9016
9017 case 1:
9018 case 2:
9019 type = attr->type;
9020 break;
9021
9022 default:
9023 assert (attr->type & 0x80);
9024 val = read_uleb128 (p, &len);
9025 p += len;
9026 type = attr->type & 0x7f;
9027 if (val >= type)
9028 printf ("??? (%d)\n", val);
9029 else
9030 printf ("%s\n", attr->table[val]);
9031 return p;
9032 }
9033 }
9034 else
9035 {
9036 if (tag & 1)
9037 type = 1; /* String. */
9038 else
9039 type = 2; /* uleb128. */
9040 printf (" Tag_unknown_%d: ", tag);
9041 }
9042
9043 if (type == 1)
9044 {
9045 printf ("\"%s\"\n", p);
2cf0635d 9046 p += strlen ((char *) p) + 1;
11c1ff18
PB
9047 }
9048 else
9049 {
9050 val = read_uleb128 (p, &len);
9051 p += len;
9052 printf ("%d (0x%x)\n", val, val);
9053 }
9054
9055 return p;
9056}
9057
104d59d1 9058static unsigned char *
60bca95a
NC
9059display_gnu_attribute (unsigned char * p,
9060 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
9061{
9062 int tag;
9063 unsigned int len;
9064 int val;
9065 int type;
9066
9067 tag = read_uleb128 (p, &len);
9068 p += len;
9069
9070 /* Tag_compatibility is the only generic GNU attribute defined at
9071 present. */
9072 if (tag == 32)
9073 {
9074 val = read_uleb128 (p, &len);
9075 p += len;
9076 printf ("flag = %d, vendor = %s\n", val, p);
60bca95a 9077 p += strlen ((char *) p) + 1;
104d59d1
JM
9078 return p;
9079 }
9080
9081 if ((tag & 2) == 0 && display_proc_gnu_attribute)
9082 return display_proc_gnu_attribute (p, tag);
9083
9084 if (tag & 1)
9085 type = 1; /* String. */
9086 else
9087 type = 2; /* uleb128. */
9088 printf (" Tag_unknown_%d: ", tag);
9089
9090 if (type == 1)
9091 {
9092 printf ("\"%s\"\n", p);
60bca95a 9093 p += strlen ((char *) p) + 1;
104d59d1
JM
9094 }
9095 else
9096 {
9097 val = read_uleb128 (p, &len);
9098 p += len;
9099 printf ("%d (0x%x)\n", val, val);
9100 }
9101
9102 return p;
9103}
9104
34c8bcba 9105static unsigned char *
2cf0635d 9106display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
9107{
9108 int type;
9109 unsigned int len;
9110 int val;
9111
9112 if (tag == Tag_GNU_Power_ABI_FP)
9113 {
9114 val = read_uleb128 (p, &len);
9115 p += len;
9116 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 9117
34c8bcba
JM
9118 switch (val)
9119 {
9120 case 0:
9121 printf ("Hard or soft float\n");
9122 break;
9123 case 1:
9124 printf ("Hard float\n");
9125 break;
9126 case 2:
9127 printf ("Soft float\n");
9128 break;
3c7b9897
AM
9129 case 3:
9130 printf ("Single-precision hard float\n");
9131 break;
34c8bcba
JM
9132 default:
9133 printf ("??? (%d)\n", val);
9134 break;
9135 }
9136 return p;
9137 }
9138
c6e65352
DJ
9139 if (tag == Tag_GNU_Power_ABI_Vector)
9140 {
9141 val = read_uleb128 (p, &len);
9142 p += len;
9143 printf (" Tag_GNU_Power_ABI_Vector: ");
9144 switch (val)
9145 {
9146 case 0:
9147 printf ("Any\n");
9148 break;
9149 case 1:
9150 printf ("Generic\n");
9151 break;
9152 case 2:
9153 printf ("AltiVec\n");
9154 break;
9155 case 3:
9156 printf ("SPE\n");
9157 break;
9158 default:
9159 printf ("??? (%d)\n", val);
9160 break;
9161 }
9162 return p;
9163 }
9164
f82e0623
NF
9165 if (tag == Tag_GNU_Power_ABI_Struct_Return)
9166 {
9167 val = read_uleb128 (p, &len);
9168 p += len;
9169 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
9170 switch (val)
9171 {
9172 case 0:
9173 printf ("Any\n");
9174 break;
9175 case 1:
9176 printf ("r3/r4\n");
9177 break;
9178 case 2:
9179 printf ("Memory\n");
9180 break;
9181 default:
9182 printf ("??? (%d)\n", val);
9183 break;
9184 }
9185 return p;
9186 }
9187
34c8bcba
JM
9188 if (tag & 1)
9189 type = 1; /* String. */
9190 else
9191 type = 2; /* uleb128. */
9192 printf (" Tag_unknown_%d: ", tag);
9193
9194 if (type == 1)
9195 {
9196 printf ("\"%s\"\n", p);
60bca95a 9197 p += strlen ((char *) p) + 1;
34c8bcba
JM
9198 }
9199 else
9200 {
9201 val = read_uleb128 (p, &len);
9202 p += len;
9203 printf ("%d (0x%x)\n", val, val);
9204 }
9205
9206 return p;
9207}
9208
2cf19d5c 9209static unsigned char *
2cf0635d 9210display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
9211{
9212 int type;
9213 unsigned int len;
9214 int val;
9215
9216 if (tag == Tag_GNU_MIPS_ABI_FP)
9217 {
9218 val = read_uleb128 (p, &len);
9219 p += len;
9220 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 9221
2cf19d5c
JM
9222 switch (val)
9223 {
9224 case 0:
9225 printf ("Hard or soft float\n");
9226 break;
9227 case 1:
9228 printf ("Hard float (-mdouble-float)\n");
9229 break;
9230 case 2:
9231 printf ("Hard float (-msingle-float)\n");
9232 break;
9233 case 3:
9234 printf ("Soft float\n");
9235 break;
42554f6a
TS
9236 case 4:
9237 printf ("64-bit float (-mips32r2 -mfp64)\n");
9238 break;
2cf19d5c
JM
9239 default:
9240 printf ("??? (%d)\n", val);
9241 break;
9242 }
9243 return p;
9244 }
9245
9246 if (tag & 1)
9247 type = 1; /* String. */
9248 else
9249 type = 2; /* uleb128. */
9250 printf (" Tag_unknown_%d: ", tag);
9251
9252 if (type == 1)
9253 {
9254 printf ("\"%s\"\n", p);
60bca95a 9255 p += strlen ((char *) p) + 1;
2cf19d5c
JM
9256 }
9257 else
9258 {
9259 val = read_uleb128 (p, &len);
9260 p += len;
9261 printf ("%d (0x%x)\n", val, val);
9262 }
9263
9264 return p;
9265}
9266
11c1ff18 9267static int
60bca95a
NC
9268process_attributes (FILE * file,
9269 const char * public_name,
104d59d1 9270 unsigned int proc_type,
60bca95a
NC
9271 unsigned char * (* display_pub_attribute) (unsigned char *),
9272 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 9273{
2cf0635d
NC
9274 Elf_Internal_Shdr * sect;
9275 unsigned char * contents;
9276 unsigned char * p;
9277 unsigned char * end;
11c1ff18
PB
9278 bfd_vma section_len;
9279 bfd_vma len;
9280 unsigned i;
9281
9282 /* Find the section header so that we get the size. */
9283 for (i = 0, sect = section_headers;
9284 i < elf_header.e_shnum;
9285 i++, sect++)
9286 {
104d59d1 9287 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
9288 continue;
9289
9290 contents = get_data (NULL, file, sect->sh_offset, 1, sect->sh_size,
9291 _("attributes"));
60bca95a 9292 if (contents == NULL)
11c1ff18 9293 continue;
60bca95a 9294
11c1ff18
PB
9295 p = contents;
9296 if (*p == 'A')
9297 {
9298 len = sect->sh_size - 1;
9299 p++;
60bca95a 9300
11c1ff18
PB
9301 while (len > 0)
9302 {
9303 int namelen;
9304 bfd_boolean public_section;
104d59d1 9305 bfd_boolean gnu_section;
11c1ff18
PB
9306
9307 section_len = byte_get (p, 4);
9308 p += 4;
60bca95a 9309
11c1ff18
PB
9310 if (section_len > len)
9311 {
9312 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 9313 (int) section_len, (int) len);
11c1ff18
PB
9314 section_len = len;
9315 }
60bca95a 9316
11c1ff18
PB
9317 len -= section_len;
9318 printf ("Attribute Section: %s\n", p);
60bca95a
NC
9319
9320 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
9321 public_section = TRUE;
9322 else
9323 public_section = FALSE;
60bca95a
NC
9324
9325 if (streq ((char *) p, "gnu"))
104d59d1
JM
9326 gnu_section = TRUE;
9327 else
9328 gnu_section = FALSE;
60bca95a
NC
9329
9330 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
9331 p += namelen;
9332 section_len -= namelen + 4;
60bca95a 9333
11c1ff18
PB
9334 while (section_len > 0)
9335 {
9336 int tag = *(p++);
9337 int val;
9338 bfd_vma size;
60bca95a 9339
11c1ff18
PB
9340 size = byte_get (p, 4);
9341 if (size > section_len)
9342 {
9343 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 9344 (int) size, (int) section_len);
11c1ff18
PB
9345 size = section_len;
9346 }
60bca95a 9347
11c1ff18
PB
9348 section_len -= size;
9349 end = p + size - 1;
9350 p += 4;
60bca95a 9351
11c1ff18
PB
9352 switch (tag)
9353 {
9354 case 1:
9355 printf ("File Attributes\n");
9356 break;
9357 case 2:
9358 printf ("Section Attributes:");
9359 goto do_numlist;
9360 case 3:
9361 printf ("Symbol Attributes:");
9362 do_numlist:
9363 for (;;)
9364 {
9365 unsigned int i;
60bca95a 9366
11c1ff18
PB
9367 val = read_uleb128 (p, &i);
9368 p += i;
9369 if (val == 0)
9370 break;
9371 printf (" %d", val);
9372 }
9373 printf ("\n");
9374 break;
9375 default:
9376 printf ("Unknown tag: %d\n", tag);
9377 public_section = FALSE;
9378 break;
9379 }
60bca95a 9380
11c1ff18
PB
9381 if (public_section)
9382 {
9383 while (p < end)
104d59d1
JM
9384 p = display_pub_attribute (p);
9385 }
9386 else if (gnu_section)
9387 {
9388 while (p < end)
9389 p = display_gnu_attribute (p,
9390 display_proc_gnu_attribute);
11c1ff18
PB
9391 }
9392 else
9393 {
9394 /* ??? Do something sensible, like dump hex. */
9395 printf (" Unknown section contexts\n");
9396 p = end;
9397 }
9398 }
9399 }
9400 }
9401 else
60bca95a 9402 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 9403
60bca95a 9404 free (contents);
11c1ff18
PB
9405 }
9406 return 1;
9407}
9408
104d59d1 9409static int
2cf0635d 9410process_arm_specific (FILE * file)
104d59d1
JM
9411{
9412 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
9413 display_arm_attribute, NULL);
9414}
9415
34c8bcba 9416static int
2cf0635d 9417process_power_specific (FILE * file)
34c8bcba
JM
9418{
9419 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
9420 display_power_gnu_attribute);
9421}
9422
ccb4c951
RS
9423/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
9424 Print the Address, Access and Initial fields of an entry at VMA ADDR
9425 and return the VMA of the next entry. */
9426
9427static bfd_vma
2cf0635d 9428print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
9429{
9430 printf (" ");
9431 print_vma (addr, LONG_HEX);
9432 printf (" ");
9433 if (addr < pltgot + 0xfff0)
9434 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
9435 else
9436 printf ("%10s", "");
9437 printf (" ");
9438 if (data == NULL)
9439 printf ("%*s", is_32bit_elf ? 8 : 16, "<unknown>");
9440 else
9441 {
9442 bfd_vma entry;
9443
9444 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
9445 print_vma (entry, LONG_HEX);
9446 }
9447 return addr + (is_32bit_elf ? 4 : 8);
9448}
9449
861fb55a
DJ
9450/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
9451 PLTGOT. Print the Address and Initial fields of an entry at VMA
9452 ADDR and return the VMA of the next entry. */
9453
9454static bfd_vma
2cf0635d 9455print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
9456{
9457 printf (" ");
9458 print_vma (addr, LONG_HEX);
9459 printf (" ");
9460 if (data == NULL)
9461 printf ("%*s", is_32bit_elf ? 8 : 16, "<unknown>");
9462 else
9463 {
9464 bfd_vma entry;
9465
9466 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
9467 print_vma (entry, LONG_HEX);
9468 }
9469 return addr + (is_32bit_elf ? 4 : 8);
9470}
9471
19e6b90e 9472static int
2cf0635d 9473process_mips_specific (FILE * file)
5b18a4bc 9474{
2cf0635d 9475 Elf_Internal_Dyn * entry;
19e6b90e
L
9476 size_t liblist_offset = 0;
9477 size_t liblistno = 0;
9478 size_t conflictsno = 0;
9479 size_t options_offset = 0;
9480 size_t conflicts_offset = 0;
861fb55a
DJ
9481 size_t pltrelsz = 0;
9482 size_t pltrel = 0;
ccb4c951 9483 bfd_vma pltgot = 0;
861fb55a
DJ
9484 bfd_vma mips_pltgot = 0;
9485 bfd_vma jmprel = 0;
ccb4c951
RS
9486 bfd_vma local_gotno = 0;
9487 bfd_vma gotsym = 0;
9488 bfd_vma symtabno = 0;
103f02d3 9489
2cf19d5c
JM
9490 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
9491 display_mips_gnu_attribute);
9492
19e6b90e
L
9493 /* We have a lot of special sections. Thanks SGI! */
9494 if (dynamic_section == NULL)
9495 /* No information available. */
9496 return 0;
252b5132 9497
b2d38a17 9498 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
9499 switch (entry->d_tag)
9500 {
9501 case DT_MIPS_LIBLIST:
d93f0186
NC
9502 liblist_offset
9503 = offset_from_vma (file, entry->d_un.d_val,
9504 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
9505 break;
9506 case DT_MIPS_LIBLISTNO:
9507 liblistno = entry->d_un.d_val;
9508 break;
9509 case DT_MIPS_OPTIONS:
d93f0186 9510 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
9511 break;
9512 case DT_MIPS_CONFLICT:
d93f0186
NC
9513 conflicts_offset
9514 = offset_from_vma (file, entry->d_un.d_val,
9515 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
9516 break;
9517 case DT_MIPS_CONFLICTNO:
9518 conflictsno = entry->d_un.d_val;
9519 break;
ccb4c951 9520 case DT_PLTGOT:
861fb55a
DJ
9521 pltgot = entry->d_un.d_ptr;
9522 break;
ccb4c951
RS
9523 case DT_MIPS_LOCAL_GOTNO:
9524 local_gotno = entry->d_un.d_val;
9525 break;
9526 case DT_MIPS_GOTSYM:
9527 gotsym = entry->d_un.d_val;
9528 break;
9529 case DT_MIPS_SYMTABNO:
9530 symtabno = entry->d_un.d_val;
9531 break;
861fb55a
DJ
9532 case DT_MIPS_PLTGOT:
9533 mips_pltgot = entry->d_un.d_ptr;
9534 break;
9535 case DT_PLTREL:
9536 pltrel = entry->d_un.d_val;
9537 break;
9538 case DT_PLTRELSZ:
9539 pltrelsz = entry->d_un.d_val;
9540 break;
9541 case DT_JMPREL:
9542 jmprel = entry->d_un.d_ptr;
9543 break;
252b5132
RH
9544 default:
9545 break;
9546 }
9547
9548 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
9549 {
2cf0635d 9550 Elf32_External_Lib * elib;
252b5132
RH
9551 size_t cnt;
9552
d3ba0551 9553 elib = get_data (NULL, file, liblist_offset,
c256ffe7 9554 liblistno, sizeof (Elf32_External_Lib),
d3ba0551 9555 _("liblist"));
a6e9f9df 9556 if (elib)
252b5132 9557 {
a6e9f9df
AM
9558 printf ("\nSection '.liblist' contains %lu entries:\n",
9559 (unsigned long) liblistno);
9560 fputs (" Library Time Stamp Checksum Version Flags\n",
9561 stdout);
9562
9563 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 9564 {
a6e9f9df
AM
9565 Elf32_Lib liblist;
9566 time_t time;
9567 char timebuf[20];
2cf0635d 9568 struct tm * tmp;
a6e9f9df
AM
9569
9570 liblist.l_name = BYTE_GET (elib[cnt].l_name);
9571 time = BYTE_GET (elib[cnt].l_time_stamp);
9572 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
9573 liblist.l_version = BYTE_GET (elib[cnt].l_version);
9574 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
9575
9576 tmp = gmtime (&time);
e9e44622
JJ
9577 snprintf (timebuf, sizeof (timebuf),
9578 "%04u-%02u-%02uT%02u:%02u:%02u",
9579 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9580 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 9581
31104126 9582 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
9583 if (VALID_DYNAMIC_NAME (liblist.l_name))
9584 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
9585 else
9586 printf ("<corrupt: %9ld>", liblist.l_name);
31104126
NC
9587 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
9588 liblist.l_version);
a6e9f9df
AM
9589
9590 if (liblist.l_flags == 0)
9591 puts (" NONE");
9592 else
9593 {
9594 static const struct
252b5132 9595 {
2cf0635d 9596 const char * name;
a6e9f9df 9597 int bit;
252b5132 9598 }
a6e9f9df
AM
9599 l_flags_vals[] =
9600 {
9601 { " EXACT_MATCH", LL_EXACT_MATCH },
9602 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
9603 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
9604 { " EXPORTS", LL_EXPORTS },
9605 { " DELAY_LOAD", LL_DELAY_LOAD },
9606 { " DELTA", LL_DELTA }
9607 };
9608 int flags = liblist.l_flags;
9609 size_t fcnt;
9610
60bca95a 9611 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
9612 if ((flags & l_flags_vals[fcnt].bit) != 0)
9613 {
9614 fputs (l_flags_vals[fcnt].name, stdout);
9615 flags ^= l_flags_vals[fcnt].bit;
9616 }
9617 if (flags != 0)
9618 printf (" %#x", (unsigned int) flags);
252b5132 9619
a6e9f9df
AM
9620 puts ("");
9621 }
252b5132 9622 }
252b5132 9623
a6e9f9df
AM
9624 free (elib);
9625 }
252b5132
RH
9626 }
9627
9628 if (options_offset != 0)
9629 {
2cf0635d
NC
9630 Elf_External_Options * eopt;
9631 Elf_Internal_Shdr * sect = section_headers;
9632 Elf_Internal_Options * iopt;
9633 Elf_Internal_Options * option;
252b5132
RH
9634 size_t offset;
9635 int cnt;
9636
9637 /* Find the section header so that we get the size. */
9638 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 9639 ++sect;
252b5132 9640
c256ffe7 9641 eopt = get_data (NULL, file, options_offset, 1, sect->sh_size,
d3ba0551 9642 _("options"));
a6e9f9df 9643 if (eopt)
252b5132 9644 {
2cf0635d 9645 iopt = cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
9646 if (iopt == NULL)
9647 {
591a748a 9648 error (_("Out of memory\n"));
a6e9f9df
AM
9649 return 0;
9650 }
76da6bbe 9651
a6e9f9df
AM
9652 offset = cnt = 0;
9653 option = iopt;
252b5132 9654
a6e9f9df
AM
9655 while (offset < sect->sh_size)
9656 {
2cf0635d 9657 Elf_External_Options * eoption;
252b5132 9658
a6e9f9df 9659 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 9660
a6e9f9df
AM
9661 option->kind = BYTE_GET (eoption->kind);
9662 option->size = BYTE_GET (eoption->size);
9663 option->section = BYTE_GET (eoption->section);
9664 option->info = BYTE_GET (eoption->info);
76da6bbe 9665
a6e9f9df 9666 offset += option->size;
252b5132 9667
a6e9f9df
AM
9668 ++option;
9669 ++cnt;
9670 }
252b5132 9671
a6e9f9df
AM
9672 printf (_("\nSection '%s' contains %d entries:\n"),
9673 SECTION_NAME (sect), cnt);
76da6bbe 9674
a6e9f9df 9675 option = iopt;
252b5132 9676
a6e9f9df 9677 while (cnt-- > 0)
252b5132 9678 {
a6e9f9df
AM
9679 size_t len;
9680
9681 switch (option->kind)
252b5132 9682 {
a6e9f9df
AM
9683 case ODK_NULL:
9684 /* This shouldn't happen. */
9685 printf (" NULL %d %lx", option->section, option->info);
9686 break;
9687 case ODK_REGINFO:
9688 printf (" REGINFO ");
9689 if (elf_header.e_machine == EM_MIPS)
9690 {
9691 /* 32bit form. */
2cf0635d 9692 Elf32_External_RegInfo * ereg;
b34976b6 9693 Elf32_RegInfo reginfo;
a6e9f9df
AM
9694
9695 ereg = (Elf32_External_RegInfo *) (option + 1);
9696 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
9697 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
9698 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
9699 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
9700 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
9701 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
9702
9703 printf ("GPR %08lx GP 0x%lx\n",
9704 reginfo.ri_gprmask,
9705 (unsigned long) reginfo.ri_gp_value);
9706 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
9707 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
9708 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
9709 }
9710 else
9711 {
9712 /* 64 bit form. */
2cf0635d 9713 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
9714 Elf64_Internal_RegInfo reginfo;
9715
9716 ereg = (Elf64_External_RegInfo *) (option + 1);
9717 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
9718 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
9719 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
9720 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
9721 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 9722 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
9723
9724 printf ("GPR %08lx GP 0x",
9725 reginfo.ri_gprmask);
9726 printf_vma (reginfo.ri_gp_value);
9727 printf ("\n");
9728
9729 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
9730 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
9731 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
9732 }
9733 ++option;
9734 continue;
9735 case ODK_EXCEPTIONS:
9736 fputs (" EXCEPTIONS fpe_min(", stdout);
9737 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
9738 fputs (") fpe_max(", stdout);
9739 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
9740 fputs (")", stdout);
9741
9742 if (option->info & OEX_PAGE0)
9743 fputs (" PAGE0", stdout);
9744 if (option->info & OEX_SMM)
9745 fputs (" SMM", stdout);
9746 if (option->info & OEX_FPDBUG)
9747 fputs (" FPDBUG", stdout);
9748 if (option->info & OEX_DISMISS)
9749 fputs (" DISMISS", stdout);
9750 break;
9751 case ODK_PAD:
9752 fputs (" PAD ", stdout);
9753 if (option->info & OPAD_PREFIX)
9754 fputs (" PREFIX", stdout);
9755 if (option->info & OPAD_POSTFIX)
9756 fputs (" POSTFIX", stdout);
9757 if (option->info & OPAD_SYMBOL)
9758 fputs (" SYMBOL", stdout);
9759 break;
9760 case ODK_HWPATCH:
9761 fputs (" HWPATCH ", stdout);
9762 if (option->info & OHW_R4KEOP)
9763 fputs (" R4KEOP", stdout);
9764 if (option->info & OHW_R8KPFETCH)
9765 fputs (" R8KPFETCH", stdout);
9766 if (option->info & OHW_R5KEOP)
9767 fputs (" R5KEOP", stdout);
9768 if (option->info & OHW_R5KCVTL)
9769 fputs (" R5KCVTL", stdout);
9770 break;
9771 case ODK_FILL:
9772 fputs (" FILL ", stdout);
9773 /* XXX Print content of info word? */
9774 break;
9775 case ODK_TAGS:
9776 fputs (" TAGS ", stdout);
9777 /* XXX Print content of info word? */
9778 break;
9779 case ODK_HWAND:
9780 fputs (" HWAND ", stdout);
9781 if (option->info & OHWA0_R4KEOP_CHECKED)
9782 fputs (" R4KEOP_CHECKED", stdout);
9783 if (option->info & OHWA0_R4KEOP_CLEAN)
9784 fputs (" R4KEOP_CLEAN", stdout);
9785 break;
9786 case ODK_HWOR:
9787 fputs (" HWOR ", stdout);
9788 if (option->info & OHWA0_R4KEOP_CHECKED)
9789 fputs (" R4KEOP_CHECKED", stdout);
9790 if (option->info & OHWA0_R4KEOP_CLEAN)
9791 fputs (" R4KEOP_CLEAN", stdout);
9792 break;
9793 case ODK_GP_GROUP:
9794 printf (" GP_GROUP %#06lx self-contained %#06lx",
9795 option->info & OGP_GROUP,
9796 (option->info & OGP_SELF) >> 16);
9797 break;
9798 case ODK_IDENT:
9799 printf (" IDENT %#06lx self-contained %#06lx",
9800 option->info & OGP_GROUP,
9801 (option->info & OGP_SELF) >> 16);
9802 break;
9803 default:
9804 /* This shouldn't happen. */
9805 printf (" %3d ??? %d %lx",
9806 option->kind, option->section, option->info);
9807 break;
252b5132 9808 }
a6e9f9df 9809
2cf0635d 9810 len = sizeof (* eopt);
a6e9f9df
AM
9811 while (len < option->size)
9812 if (((char *) option)[len] >= ' '
9813 && ((char *) option)[len] < 0x7f)
9814 printf ("%c", ((char *) option)[len++]);
9815 else
9816 printf ("\\%03o", ((char *) option)[len++]);
9817
9818 fputs ("\n", stdout);
252b5132 9819 ++option;
252b5132
RH
9820 }
9821
a6e9f9df 9822 free (eopt);
252b5132 9823 }
252b5132
RH
9824 }
9825
9826 if (conflicts_offset != 0 && conflictsno != 0)
9827 {
2cf0635d 9828 Elf32_Conflict * iconf;
252b5132
RH
9829 size_t cnt;
9830
9831 if (dynamic_symbols == NULL)
9832 {
591a748a 9833 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
9834 return 0;
9835 }
9836
2cf0635d 9837 iconf = cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
9838 if (iconf == NULL)
9839 {
591a748a 9840 error (_("Out of memory\n"));
252b5132
RH
9841 return 0;
9842 }
9843
9ea033b2 9844 if (is_32bit_elf)
252b5132 9845 {
2cf0635d 9846 Elf32_External_Conflict * econf32;
a6e9f9df 9847
d3ba0551 9848 econf32 = get_data (NULL, file, conflicts_offset,
2cf0635d 9849 conflictsno, sizeof (* econf32), _("conflict"));
a6e9f9df
AM
9850 if (!econf32)
9851 return 0;
252b5132
RH
9852
9853 for (cnt = 0; cnt < conflictsno; ++cnt)
9854 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
9855
9856 free (econf32);
252b5132
RH
9857 }
9858 else
9859 {
2cf0635d 9860 Elf64_External_Conflict * econf64;
a6e9f9df 9861
d3ba0551 9862 econf64 = get_data (NULL, file, conflicts_offset,
2cf0635d 9863 conflictsno, sizeof (* econf64), _("conflict"));
a6e9f9df
AM
9864 if (!econf64)
9865 return 0;
252b5132
RH
9866
9867 for (cnt = 0; cnt < conflictsno; ++cnt)
9868 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
9869
9870 free (econf64);
252b5132
RH
9871 }
9872
c7e7ca54
NC
9873 printf (_("\nSection '.conflict' contains %lu entries:\n"),
9874 (unsigned long) conflictsno);
252b5132
RH
9875 puts (_(" Num: Index Value Name"));
9876
9877 for (cnt = 0; cnt < conflictsno; ++cnt)
9878 {
2cf0635d 9879 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 9880
b34976b6 9881 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 9882 print_vma (psym->st_value, FULL_HEX);
31104126 9883 putchar (' ');
d79b3d50
NC
9884 if (VALID_DYNAMIC_NAME (psym->st_name))
9885 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9886 else
9887 printf ("<corrupt: %14ld>", psym->st_name);
31104126 9888 putchar ('\n');
252b5132
RH
9889 }
9890
252b5132
RH
9891 free (iconf);
9892 }
9893
ccb4c951
RS
9894 if (pltgot != 0 && local_gotno != 0)
9895 {
9896 bfd_vma entry, local_end, global_end;
bbeee7ea 9897 size_t i, offset;
2cf0635d 9898 unsigned char * data;
bbeee7ea 9899 int addr_size;
ccb4c951
RS
9900
9901 entry = pltgot;
9902 addr_size = (is_32bit_elf ? 4 : 8);
9903 local_end = pltgot + local_gotno * addr_size;
9904 global_end = local_end + (symtabno - gotsym) * addr_size;
9905
9906 offset = offset_from_vma (file, pltgot, global_end - pltgot);
9907 data = get_data (NULL, file, offset, global_end - pltgot, 1, _("GOT"));
9908 printf (_("\nPrimary GOT:\n"));
9909 printf (_(" Canonical gp value: "));
9910 print_vma (pltgot + 0x7ff0, LONG_HEX);
9911 printf ("\n\n");
9912
9913 printf (_(" Reserved entries:\n"));
9914 printf (_(" %*s %10s %*s Purpose\n"),
9915 addr_size * 2, "Address", "Access",
9916 addr_size * 2, "Initial");
9917 entry = print_mips_got_entry (data, pltgot, entry);
9918 printf (" Lazy resolver\n");
9919 if (data
9920 && (byte_get (data + entry - pltgot, addr_size)
9921 >> (addr_size * 8 - 1)) != 0)
9922 {
9923 entry = print_mips_got_entry (data, pltgot, entry);
9924 printf (" Module pointer (GNU extension)\n");
9925 }
9926 printf ("\n");
9927
9928 if (entry < local_end)
9929 {
9930 printf (_(" Local entries:\n"));
9931 printf (_(" %*s %10s %*s\n"),
9932 addr_size * 2, "Address", "Access",
9933 addr_size * 2, "Initial");
9934 while (entry < local_end)
9935 {
9936 entry = print_mips_got_entry (data, pltgot, entry);
9937 printf ("\n");
9938 }
9939 printf ("\n");
9940 }
9941
9942 if (gotsym < symtabno)
9943 {
9944 int sym_width;
9945
9946 printf (_(" Global entries:\n"));
9947 printf (_(" %*s %10s %*s %*s %-7s %3s %s\n"),
9948 addr_size * 2, "Address", "Access",
9949 addr_size * 2, "Initial",
9950 addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name");
9951 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
9952 for (i = gotsym; i < symtabno; i++)
9953 {
2cf0635d 9954 Elf_Internal_Sym * psym;
ccb4c951
RS
9955
9956 psym = dynamic_symbols + i;
9957 entry = print_mips_got_entry (data, pltgot, entry);
9958 printf (" ");
9959 print_vma (psym->st_value, LONG_HEX);
9960 printf (" %-7s %3s ",
9961 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
9962 get_symbol_index_type (psym->st_shndx));
9963 if (VALID_DYNAMIC_NAME (psym->st_name))
9964 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
9965 else
9966 printf ("<corrupt: %14ld>", psym->st_name);
9967 printf ("\n");
9968 }
9969 printf ("\n");
9970 }
9971
9972 if (data)
9973 free (data);
9974 }
9975
861fb55a
DJ
9976 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
9977 {
9978 bfd_vma entry, end;
9979 size_t offset, rel_offset;
9980 unsigned long count, i;
2cf0635d 9981 unsigned char * data;
861fb55a 9982 int addr_size, sym_width;
2cf0635d 9983 Elf_Internal_Rela * rels;
861fb55a
DJ
9984
9985 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
9986 if (pltrel == DT_RELA)
9987 {
9988 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
9989 return 0;
9990 }
9991 else
9992 {
9993 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
9994 return 0;
9995 }
9996
9997 entry = mips_pltgot;
9998 addr_size = (is_32bit_elf ? 4 : 8);
9999 end = mips_pltgot + (2 + count) * addr_size;
10000
10001 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
10002 data = get_data (NULL, file, offset, end - mips_pltgot, 1, _("PLT GOT"));
10003 printf (_("\nPLT GOT:\n\n"));
10004 printf (_(" Reserved entries:\n"));
10005 printf (_(" %*s %*s Purpose\n"),
10006 addr_size * 2, "Address", addr_size * 2, "Initial");
10007 entry = print_mips_pltgot_entry (data, mips_pltgot, entry);
10008 printf (" PLT lazy resolver\n");
10009 entry = print_mips_pltgot_entry (data, mips_pltgot, entry);
10010 printf (" Module pointer\n");
10011 printf ("\n");
10012
10013 printf (_(" Entries:\n"));
10014 printf (_(" %*s %*s %*s %-7s %3s %s\n"),
10015 addr_size * 2, "Address",
10016 addr_size * 2, "Initial",
10017 addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name");
10018 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
10019 for (i = 0; i < count; i++)
10020 {
2cf0635d 10021 Elf_Internal_Sym * psym;
861fb55a
DJ
10022
10023 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
10024 entry = print_mips_pltgot_entry (data, mips_pltgot, entry);
10025 printf (" ");
10026 print_vma (psym->st_value, LONG_HEX);
10027 printf (" %-7s %3s ",
10028 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
10029 get_symbol_index_type (psym->st_shndx));
10030 if (VALID_DYNAMIC_NAME (psym->st_name))
10031 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
10032 else
10033 printf ("<corrupt: %14ld>", psym->st_name);
10034 printf ("\n");
10035 }
10036 printf ("\n");
10037
10038 if (data)
10039 free (data);
10040 free (rels);
10041 }
10042
252b5132
RH
10043 return 1;
10044}
10045
047b2264 10046static int
2cf0635d 10047process_gnu_liblist (FILE * file)
047b2264 10048{
2cf0635d
NC
10049 Elf_Internal_Shdr * section;
10050 Elf_Internal_Shdr * string_sec;
10051 Elf32_External_Lib * elib;
10052 char * strtab;
c256ffe7 10053 size_t strtab_size;
047b2264
JJ
10054 size_t cnt;
10055 unsigned i;
10056
10057 if (! do_arch)
10058 return 0;
10059
10060 for (i = 0, section = section_headers;
10061 i < elf_header.e_shnum;
b34976b6 10062 i++, section++)
047b2264
JJ
10063 {
10064 switch (section->sh_type)
10065 {
10066 case SHT_GNU_LIBLIST:
4fbb74a6 10067 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
10068 break;
10069
10070 elib = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
d3ba0551 10071 _("liblist"));
047b2264
JJ
10072
10073 if (elib == NULL)
10074 break;
4fbb74a6 10075 string_sec = section_headers + section->sh_link;
047b2264 10076
c256ffe7 10077 strtab = get_data (NULL, file, string_sec->sh_offset, 1,
d3ba0551 10078 string_sec->sh_size, _("liblist string table"));
c256ffe7 10079 strtab_size = string_sec->sh_size;
047b2264
JJ
10080
10081 if (strtab == NULL
10082 || section->sh_entsize != sizeof (Elf32_External_Lib))
10083 {
10084 free (elib);
10085 break;
10086 }
10087
10088 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
10089 SECTION_NAME (section),
0af1713e 10090 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264
JJ
10091
10092 puts (" Library Time Stamp Checksum Version Flags");
10093
10094 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
10095 ++cnt)
10096 {
10097 Elf32_Lib liblist;
10098 time_t time;
10099 char timebuf[20];
2cf0635d 10100 struct tm * tmp;
047b2264
JJ
10101
10102 liblist.l_name = BYTE_GET (elib[cnt].l_name);
10103 time = BYTE_GET (elib[cnt].l_time_stamp);
10104 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
10105 liblist.l_version = BYTE_GET (elib[cnt].l_version);
10106 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
10107
10108 tmp = gmtime (&time);
e9e44622
JJ
10109 snprintf (timebuf, sizeof (timebuf),
10110 "%04u-%02u-%02uT%02u:%02u:%02u",
10111 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10112 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10113
10114 printf ("%3lu: ", (unsigned long) cnt);
10115 if (do_wide)
c256ffe7
JJ
10116 printf ("%-20s", liblist.l_name < strtab_size
10117 ? strtab + liblist.l_name : "<corrupt>");
047b2264 10118 else
c256ffe7
JJ
10119 printf ("%-20.20s", liblist.l_name < strtab_size
10120 ? strtab + liblist.l_name : "<corrupt>");
047b2264
JJ
10121 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
10122 liblist.l_version, liblist.l_flags);
10123 }
10124
10125 free (elib);
10126 }
10127 }
10128
10129 return 1;
10130}
10131
9437c45b 10132static const char *
d3ba0551 10133get_note_type (unsigned e_type)
779fe533
NC
10134{
10135 static char buff[64];
103f02d3 10136
1ec5cd37
NC
10137 if (elf_header.e_type == ET_CORE)
10138 switch (e_type)
10139 {
57346661 10140 case NT_AUXV:
1ec5cd37 10141 return _("NT_AUXV (auxiliary vector)");
57346661 10142 case NT_PRSTATUS:
1ec5cd37 10143 return _("NT_PRSTATUS (prstatus structure)");
57346661 10144 case NT_FPREGSET:
1ec5cd37 10145 return _("NT_FPREGSET (floating point registers)");
57346661 10146 case NT_PRPSINFO:
1ec5cd37 10147 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 10148 case NT_TASKSTRUCT:
1ec5cd37 10149 return _("NT_TASKSTRUCT (task structure)");
57346661 10150 case NT_PRXFPREG:
1ec5cd37 10151 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
10152 case NT_PPC_VMX:
10153 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
10154 case NT_PPC_VSX:
10155 return _("NT_PPC_VSX (ppc VSX registers)");
57346661 10156 case NT_PSTATUS:
1ec5cd37 10157 return _("NT_PSTATUS (pstatus structure)");
57346661 10158 case NT_FPREGS:
1ec5cd37 10159 return _("NT_FPREGS (floating point registers)");
57346661 10160 case NT_PSINFO:
1ec5cd37 10161 return _("NT_PSINFO (psinfo structure)");
57346661 10162 case NT_LWPSTATUS:
1ec5cd37 10163 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 10164 case NT_LWPSINFO:
1ec5cd37 10165 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 10166 case NT_WIN32PSTATUS:
1ec5cd37
NC
10167 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
10168 default:
10169 break;
10170 }
10171 else
10172 switch (e_type)
10173 {
10174 case NT_VERSION:
10175 return _("NT_VERSION (version)");
10176 case NT_ARCH:
10177 return _("NT_ARCH (architecture)");
10178 default:
10179 break;
10180 }
10181
e9e44622 10182 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 10183 return buff;
779fe533
NC
10184}
10185
1118d252
RM
10186static const char *
10187get_gnu_elf_note_type (unsigned e_type)
10188{
10189 static char buff[64];
10190
10191 switch (e_type)
10192 {
10193 case NT_GNU_ABI_TAG:
10194 return _("NT_GNU_ABI_TAG (ABI version tag)");
10195 case NT_GNU_HWCAP:
10196 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
10197 case NT_GNU_BUILD_ID:
10198 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
10199 case NT_GNU_GOLD_VERSION:
10200 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
10201 default:
10202 break;
10203 }
10204
10205 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
10206 return buff;
10207}
10208
9437c45b 10209static const char *
d3ba0551 10210get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
10211{
10212 static char buff[64];
10213
b4db1224 10214 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
10215 {
10216 /* NetBSD core "procinfo" structure. */
10217 return _("NetBSD procinfo structure");
10218 }
10219
10220 /* As of Jan 2002 there are no other machine-independent notes
10221 defined for NetBSD core files. If the note type is less
10222 than the start of the machine-dependent note types, we don't
10223 understand it. */
10224
b4db1224 10225 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 10226 {
e9e44622 10227 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
10228 return buff;
10229 }
10230
10231 switch (elf_header.e_machine)
10232 {
10233 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
10234 and PT_GETFPREGS == mach+2. */
10235
10236 case EM_OLD_ALPHA:
10237 case EM_ALPHA:
10238 case EM_SPARC:
10239 case EM_SPARC32PLUS:
10240 case EM_SPARCV9:
10241 switch (e_type)
10242 {
b4db1224
JT
10243 case NT_NETBSDCORE_FIRSTMACH+0:
10244 return _("PT_GETREGS (reg structure)");
10245 case NT_NETBSDCORE_FIRSTMACH+2:
10246 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
10247 default:
10248 break;
10249 }
10250 break;
10251
10252 /* On all other arch's, PT_GETREGS == mach+1 and
10253 PT_GETFPREGS == mach+3. */
10254 default:
10255 switch (e_type)
10256 {
b4db1224
JT
10257 case NT_NETBSDCORE_FIRSTMACH+1:
10258 return _("PT_GETREGS (reg structure)");
10259 case NT_NETBSDCORE_FIRSTMACH+3:
10260 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
10261 default:
10262 break;
10263 }
10264 }
10265
e9e44622
JJ
10266 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
10267 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
10268 return buff;
10269}
10270
6d118b09
NC
10271/* Note that by the ELF standard, the name field is already null byte
10272 terminated, and namesz includes the terminating null byte.
10273 I.E. the value of namesz for the name "FSF" is 4.
10274
e3c8793a 10275 If the value of namesz is zero, there is no name present. */
779fe533 10276static int
2cf0635d 10277process_note (Elf_Internal_Note * pnote)
779fe533 10278{
2cf0635d
NC
10279 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
10280 const char * nt;
9437c45b
JT
10281
10282 if (pnote->namesz == 0)
1ec5cd37
NC
10283 /* If there is no note name, then use the default set of
10284 note type strings. */
10285 nt = get_note_type (pnote->type);
10286
1118d252
RM
10287 else if (const_strneq (pnote->namedata, "GNU"))
10288 /* GNU-specific object file notes. */
10289 nt = get_gnu_elf_note_type (pnote->type);
10290
0112cd26 10291 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
10292 /* NetBSD-specific core file notes. */
10293 nt = get_netbsd_elfcore_note_type (pnote->type);
10294
b15fa79e
AM
10295 else if (strneq (pnote->namedata, "SPU/", 4))
10296 {
10297 /* SPU-specific core file notes. */
10298 nt = pnote->namedata + 4;
10299 name = "SPU";
10300 }
10301
9437c45b 10302 else
1ec5cd37
NC
10303 /* Don't recognize this note name; just use the default set of
10304 note type strings. */
9437c45b 10305 nt = get_note_type (pnote->type);
9437c45b 10306
b15fa79e 10307 printf (" %s\t\t0x%08lx\t%s\n", name, pnote->descsz, nt);
779fe533
NC
10308 return 1;
10309}
10310
6d118b09 10311
779fe533 10312static int
2cf0635d 10313process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 10314{
2cf0635d
NC
10315 Elf_External_Note * pnotes;
10316 Elf_External_Note * external;
b34976b6 10317 int res = 1;
103f02d3 10318
779fe533
NC
10319 if (length <= 0)
10320 return 0;
103f02d3 10321
c256ffe7 10322 pnotes = get_data (NULL, file, offset, 1, length, _("notes"));
a6e9f9df
AM
10323 if (!pnotes)
10324 return 0;
779fe533 10325
103f02d3 10326 external = pnotes;
103f02d3 10327
305c7206 10328 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 10329 (unsigned long) offset, (unsigned long) length);
779fe533 10330 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 10331
2cf0635d 10332 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 10333 {
2cf0635d 10334 Elf_External_Note * next;
b34976b6 10335 Elf_Internal_Note inote;
2cf0635d 10336 char * temp = NULL;
6d118b09
NC
10337
10338 inote.type = BYTE_GET (external->type);
10339 inote.namesz = BYTE_GET (external->namesz);
10340 inote.namedata = external->name;
10341 inote.descsz = BYTE_GET (external->descsz);
10342 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
10343 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 10344
2cf0635d 10345 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
3e55a963
NC
10346
10347 if (((char *) next) > (((char *) pnotes) + length))
10348 {
0fd3a477 10349 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 10350 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 10351 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
10352 inote.type, inote.namesz, inote.descsz);
10353 break;
10354 }
10355
10356 external = next;
6d118b09
NC
10357
10358 /* Verify that name is null terminated. It appears that at least
10359 one version of Linux (RedHat 6.0) generates corefiles that don't
10360 comply with the ELF spec by failing to include the null byte in
10361 namesz. */
10362 if (inote.namedata[inote.namesz] != '\0')
10363 {
10364 temp = malloc (inote.namesz + 1);
76da6bbe 10365
6d118b09
NC
10366 if (temp == NULL)
10367 {
10368 error (_("Out of memory\n"));
10369 res = 0;
10370 break;
10371 }
76da6bbe 10372
6d118b09
NC
10373 strncpy (temp, inote.namedata, inote.namesz);
10374 temp[inote.namesz] = 0;
76da6bbe 10375
6d118b09
NC
10376 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
10377 inote.namedata = temp;
10378 }
10379
10380 res &= process_note (& inote);
103f02d3 10381
6d118b09
NC
10382 if (temp != NULL)
10383 {
10384 free (temp);
10385 temp = NULL;
10386 }
779fe533
NC
10387 }
10388
10389 free (pnotes);
103f02d3 10390
779fe533
NC
10391 return res;
10392}
10393
10394static int
2cf0635d 10395process_corefile_note_segments (FILE * file)
779fe533 10396{
2cf0635d 10397 Elf_Internal_Phdr * segment;
b34976b6
AM
10398 unsigned int i;
10399 int res = 1;
103f02d3 10400
d93f0186 10401 if (! get_program_headers (file))
779fe533 10402 return 0;
103f02d3 10403
779fe533
NC
10404 for (i = 0, segment = program_headers;
10405 i < elf_header.e_phnum;
b34976b6 10406 i++, segment++)
779fe533
NC
10407 {
10408 if (segment->p_type == PT_NOTE)
103f02d3 10409 res &= process_corefile_note_segment (file,
30800947
NC
10410 (bfd_vma) segment->p_offset,
10411 (bfd_vma) segment->p_filesz);
779fe533 10412 }
103f02d3 10413
779fe533
NC
10414 return res;
10415}
10416
10417static int
2cf0635d 10418process_note_sections (FILE * file)
1ec5cd37 10419{
2cf0635d 10420 Elf_Internal_Shdr * section;
1ec5cd37
NC
10421 unsigned long i;
10422 int res = 1;
10423
10424 for (i = 0, section = section_headers;
10425 i < elf_header.e_shnum;
10426 i++, section++)
10427 if (section->sh_type == SHT_NOTE)
10428 res &= process_corefile_note_segment (file,
10429 (bfd_vma) section->sh_offset,
10430 (bfd_vma) section->sh_size);
10431
10432 return res;
10433}
10434
10435static int
2cf0635d 10436process_notes (FILE * file)
779fe533
NC
10437{
10438 /* If we have not been asked to display the notes then do nothing. */
10439 if (! do_notes)
10440 return 1;
103f02d3 10441
779fe533 10442 if (elf_header.e_type != ET_CORE)
1ec5cd37 10443 return process_note_sections (file);
103f02d3 10444
779fe533 10445 /* No program headers means no NOTE segment. */
1ec5cd37
NC
10446 if (elf_header.e_phnum > 0)
10447 return process_corefile_note_segments (file);
779fe533 10448
1ec5cd37
NC
10449 printf (_("No note segments present in the core file.\n"));
10450 return 1;
779fe533
NC
10451}
10452
252b5132 10453static int
2cf0635d 10454process_arch_specific (FILE * file)
252b5132 10455{
a952a375
NC
10456 if (! do_arch)
10457 return 1;
10458
252b5132
RH
10459 switch (elf_header.e_machine)
10460 {
11c1ff18
PB
10461 case EM_ARM:
10462 return process_arm_specific (file);
252b5132 10463 case EM_MIPS:
4fe85591 10464 case EM_MIPS_RS3_LE:
252b5132
RH
10465 return process_mips_specific (file);
10466 break;
34c8bcba
JM
10467 case EM_PPC:
10468 return process_power_specific (file);
10469 break;
252b5132
RH
10470 default:
10471 break;
10472 }
10473 return 1;
10474}
10475
10476static int
2cf0635d 10477get_file_header (FILE * file)
252b5132 10478{
9ea033b2
NC
10479 /* Read in the identity array. */
10480 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
10481 return 0;
10482
9ea033b2 10483 /* Determine how to read the rest of the header. */
b34976b6 10484 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
10485 {
10486 default: /* fall through */
10487 case ELFDATANONE: /* fall through */
adab8cdc
AO
10488 case ELFDATA2LSB:
10489 byte_get = byte_get_little_endian;
10490 byte_put = byte_put_little_endian;
10491 break;
10492 case ELFDATA2MSB:
10493 byte_get = byte_get_big_endian;
10494 byte_put = byte_put_big_endian;
10495 break;
9ea033b2
NC
10496 }
10497
10498 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 10499 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
10500
10501 /* Read in the rest of the header. */
10502 if (is_32bit_elf)
10503 {
10504 Elf32_External_Ehdr ehdr32;
252b5132 10505
9ea033b2
NC
10506 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
10507 return 0;
103f02d3 10508
9ea033b2
NC
10509 elf_header.e_type = BYTE_GET (ehdr32.e_type);
10510 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
10511 elf_header.e_version = BYTE_GET (ehdr32.e_version);
10512 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
10513 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
10514 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
10515 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
10516 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
10517 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
10518 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
10519 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
10520 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
10521 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
10522 }
252b5132 10523 else
9ea033b2
NC
10524 {
10525 Elf64_External_Ehdr ehdr64;
a952a375
NC
10526
10527 /* If we have been compiled with sizeof (bfd_vma) == 4, then
10528 we will not be able to cope with the 64bit data found in
10529 64 ELF files. Detect this now and abort before we start
50c2245b 10530 overwriting things. */
a952a375
NC
10531 if (sizeof (bfd_vma) < 8)
10532 {
e3c8793a
NC
10533 error (_("This instance of readelf has been built without support for a\n\
1053464 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
10535 return 0;
10536 }
103f02d3 10537
9ea033b2
NC
10538 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
10539 return 0;
103f02d3 10540
9ea033b2
NC
10541 elf_header.e_type = BYTE_GET (ehdr64.e_type);
10542 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
10543 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
10544 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
10545 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
10546 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
10547 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
10548 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
10549 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
10550 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
10551 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
10552 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
10553 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
10554 }
252b5132 10555
7ece0d85
JJ
10556 if (elf_header.e_shoff)
10557 {
10558 /* There may be some extensions in the first section header. Don't
10559 bomb if we can't read it. */
10560 if (is_32bit_elf)
10561 get_32bit_section_headers (file, 1);
10562 else
10563 get_64bit_section_headers (file, 1);
10564 }
560f3c1c 10565
252b5132
RH
10566 return 1;
10567}
10568
fb52b2f4
NC
10569/* Process one ELF object file according to the command line options.
10570 This file may actually be stored in an archive. The file is
10571 positioned at the start of the ELF object. */
10572
ff78d6d6 10573static int
2cf0635d 10574process_object (char * file_name, FILE * file)
252b5132 10575{
252b5132
RH
10576 unsigned int i;
10577
252b5132
RH
10578 if (! get_file_header (file))
10579 {
10580 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 10581 return 1;
252b5132
RH
10582 }
10583
10584 /* Initialise per file variables. */
60bca95a 10585 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
10586 version_info[i] = 0;
10587
60bca95a 10588 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132
RH
10589 dynamic_info[i] = 0;
10590
10591 /* Process the file. */
10592 if (show_name)
10593 printf (_("\nFile: %s\n"), file_name);
10594
18bd398b
NC
10595 /* Initialise the dump_sects array from the cmdline_dump_sects array.
10596 Note we do this even if cmdline_dump_sects is empty because we
10597 must make sure that the dump_sets array is zeroed out before each
10598 object file is processed. */
10599 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 10600 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
10601
10602 if (num_cmdline_dump_sects > 0)
10603 {
10604 if (num_dump_sects == 0)
10605 /* A sneaky way of allocating the dump_sects array. */
09c11c86 10606 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
10607
10608 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
10609 memcpy (dump_sects, cmdline_dump_sects,
10610 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 10611 }
d70c5fc7 10612
252b5132 10613 if (! process_file_header ())
fb52b2f4 10614 return 1;
252b5132 10615
d1f5c6e3 10616 if (! process_section_headers (file))
2f62977e 10617 {
d1f5c6e3
L
10618 /* Without loaded section headers we cannot process lots of
10619 things. */
2f62977e 10620 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 10621
2f62977e
NC
10622 if (! do_using_dynamic)
10623 do_syms = do_reloc = 0;
10624 }
252b5132 10625
d1f5c6e3
L
10626 if (! process_section_groups (file))
10627 {
10628 /* Without loaded section groups we cannot process unwind. */
10629 do_unwind = 0;
10630 }
10631
2f62977e 10632 if (process_program_headers (file))
b2d38a17 10633 process_dynamic_section (file);
252b5132
RH
10634
10635 process_relocs (file);
10636
4d6ed7c8
NC
10637 process_unwind (file);
10638
252b5132
RH
10639 process_symbol_table (file);
10640
10641 process_syminfo (file);
10642
10643 process_version_sections (file);
10644
10645 process_section_contents (file);
f5842774 10646
1ec5cd37 10647 process_notes (file);
103f02d3 10648
047b2264
JJ
10649 process_gnu_liblist (file);
10650
252b5132
RH
10651 process_arch_specific (file);
10652
d93f0186
NC
10653 if (program_headers)
10654 {
10655 free (program_headers);
10656 program_headers = NULL;
10657 }
10658
252b5132
RH
10659 if (section_headers)
10660 {
10661 free (section_headers);
10662 section_headers = NULL;
10663 }
10664
10665 if (string_table)
10666 {
10667 free (string_table);
10668 string_table = NULL;
d40ac9bd 10669 string_table_length = 0;
252b5132
RH
10670 }
10671
10672 if (dynamic_strings)
10673 {
10674 free (dynamic_strings);
10675 dynamic_strings = NULL;
d79b3d50 10676 dynamic_strings_length = 0;
252b5132
RH
10677 }
10678
10679 if (dynamic_symbols)
10680 {
10681 free (dynamic_symbols);
10682 dynamic_symbols = NULL;
19936277 10683 num_dynamic_syms = 0;
252b5132
RH
10684 }
10685
10686 if (dynamic_syminfo)
10687 {
10688 free (dynamic_syminfo);
10689 dynamic_syminfo = NULL;
10690 }
ff78d6d6 10691
e4b17d5c
L
10692 if (section_headers_groups)
10693 {
10694 free (section_headers_groups);
10695 section_headers_groups = NULL;
10696 }
10697
10698 if (section_groups)
10699 {
2cf0635d
NC
10700 struct group_list * g;
10701 struct group_list * next;
e4b17d5c
L
10702
10703 for (i = 0; i < group_count; i++)
10704 {
10705 for (g = section_groups [i].root; g != NULL; g = next)
10706 {
10707 next = g->next;
10708 free (g);
10709 }
10710 }
10711
10712 free (section_groups);
10713 section_groups = NULL;
10714 }
10715
19e6b90e 10716 free_debug_memory ();
18bd398b 10717
ff78d6d6 10718 return 0;
252b5132
RH
10719}
10720
2cf0635d
NC
10721/* Return the path name for a proxy entry in a thin archive, adjusted relative
10722 to the path name of the thin archive itself if necessary. Always returns
10723 a pointer to malloc'ed memory. */
10724
10725static char *
10726adjust_relative_path (char * file_name, char * name, int name_len)
10727{
10728 char * member_file_name;
10729 const char * base_name = lbasename (file_name);
10730
10731 /* This is a proxy entry for a thin archive member.
10732 If the extended name table contains an absolute path
10733 name, or if the archive is in the current directory,
10734 use the path name as given. Otherwise, we need to
10735 find the member relative to the directory where the
10736 archive is located. */
10737 if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
10738 {
10739 member_file_name = malloc (name_len + 1);
10740 if (member_file_name == NULL)
10741 {
10742 error (_("Out of memory\n"));
10743 return NULL;
10744 }
10745 memcpy (member_file_name, name, name_len);
10746 member_file_name[name_len] = '\0';
10747 }
10748 else
10749 {
10750 /* Concatenate the path components of the archive file name
10751 to the relative path name from the extended name table. */
10752 size_t prefix_len = base_name - file_name;
10753 member_file_name = malloc (prefix_len + name_len + 1);
10754 if (member_file_name == NULL)
10755 {
10756 error (_("Out of memory\n"));
10757 return NULL;
10758 }
10759 memcpy (member_file_name, file_name, prefix_len);
10760 memcpy (member_file_name + prefix_len, name, name_len);
10761 member_file_name[prefix_len + name_len] = '\0';
10762 }
10763 return member_file_name;
10764}
10765
10766/* Structure to hold information about an archive file. */
10767
10768struct archive_info
10769{
10770 char * file_name; /* Archive file name. */
10771 FILE * file; /* Open file descriptor. */
10772 unsigned long index_num; /* Number of symbols in table. */
10773 unsigned long * index_array; /* The array of member offsets. */
10774 char * sym_table; /* The symbol table. */
10775 unsigned long sym_size; /* Size of the symbol table. */
10776 char * longnames; /* The long file names table. */
10777 unsigned long longnames_size; /* Size of the long file names table. */
10778 unsigned long nested_member_origin; /* Origin in the nested archive of the current member. */
10779 unsigned long next_arhdr_offset; /* Offset of the next archive header. */
10780 bfd_boolean is_thin_archive; /* TRUE if this is a thin archive. */
10781 struct ar_hdr arhdr; /* Current archive header. */
10782};
10783
10784/* Read the symbol table and long-name table from an archive. */
fb52b2f4
NC
10785
10786static int
2cf0635d
NC
10787setup_archive (struct archive_info * arch, char * file_name, FILE * file,
10788 bfd_boolean is_thin_archive, bfd_boolean read_symbols)
fb52b2f4 10789{
fb52b2f4
NC
10790 size_t got;
10791 unsigned long size;
fb52b2f4 10792
2cf0635d
NC
10793 arch->file_name = strdup (file_name);
10794 arch->file = file;
10795 arch->index_num = 0;
10796 arch->index_array = NULL;
10797 arch->sym_table = NULL;
10798 arch->sym_size = 0;
10799 arch->longnames = NULL;
10800 arch->longnames_size = 0;
10801 arch->nested_member_origin = 0;
10802 arch->is_thin_archive = is_thin_archive;
10803 arch->next_arhdr_offset = SARMAG;
10804
10805 /* Read the first archive member header. */
10806 if (fseek (file, SARMAG, SEEK_SET) != 0)
10807 {
10808 error (_("%s: failed to seek to first archive header\n"), file_name);
10809 return 1;
10810 }
10811 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
10812 if (got != sizeof arch->arhdr)
fb52b2f4
NC
10813 {
10814 if (got == 0)
10815 return 0;
10816
10817 error (_("%s: failed to read archive header\n"), file_name);
10818 return 1;
10819 }
10820
4145f1d5 10821 /* See if this is the archive symbol table. */
2cf0635d
NC
10822 if (const_strneq (arch->arhdr.ar_name, "/ ")
10823 || const_strneq (arch->arhdr.ar_name, "/SYM64/ "))
fb52b2f4 10824 {
2cf0635d 10825 size = strtoul (arch->arhdr.ar_size, NULL, 10);
4145f1d5
NC
10826 size = size + (size & 1);
10827
2cf0635d
NC
10828 arch->next_arhdr_offset += sizeof arch->arhdr + size;
10829
10830 if (read_symbols)
fb52b2f4 10831 {
4145f1d5
NC
10832 unsigned long i;
10833 /* A buffer used to hold numbers read in from an archive index.
10834 These are always 4 bytes long and stored in big-endian format. */
10835#define SIZEOF_AR_INDEX_NUMBERS 4
10836 unsigned char integer_buffer[SIZEOF_AR_INDEX_NUMBERS];
10837 unsigned char * index_buffer;
10838
10839 /* Check the size of the archive index. */
10840 if (size < SIZEOF_AR_INDEX_NUMBERS)
10841 {
10842 error (_("%s: the archive index is empty\n"), file_name);
10843 return 1;
10844 }
10845
10846 /* Read the numer of entries in the archive index. */
10847 got = fread (integer_buffer, 1, sizeof integer_buffer, file);
10848 if (got != sizeof (integer_buffer))
10849 {
10850 error (_("%s: failed to read archive index\n"), file_name);
10851 return 1;
10852 }
2cf0635d 10853 arch->index_num = byte_get_big_endian (integer_buffer, sizeof integer_buffer);
4145f1d5
NC
10854 size -= SIZEOF_AR_INDEX_NUMBERS;
10855
10856 /* Read in the archive index. */
2cf0635d 10857 if (size < arch->index_num * SIZEOF_AR_INDEX_NUMBERS)
4145f1d5
NC
10858 {
10859 error (_("%s: the archive index is supposed to have %ld entries, but the size in the header is too small\n"),
2cf0635d 10860 file_name, arch->index_num);
4145f1d5
NC
10861 return 1;
10862 }
2cf0635d 10863 index_buffer = malloc (arch->index_num * SIZEOF_AR_INDEX_NUMBERS);
4145f1d5
NC
10864 if (index_buffer == NULL)
10865 {
10866 error (_("Out of memory whilst trying to read archive symbol index\n"));
10867 return 1;
10868 }
2cf0635d
NC
10869 got = fread (index_buffer, SIZEOF_AR_INDEX_NUMBERS, arch->index_num, file);
10870 if (got != arch->index_num)
4145f1d5
NC
10871 {
10872 free (index_buffer);
10873 error (_("%s: failed to read archive index\n"), file_name);
2cf0635d 10874 return 1;
4145f1d5 10875 }
2cf0635d 10876 size -= arch->index_num * SIZEOF_AR_INDEX_NUMBERS;
4145f1d5
NC
10877
10878 /* Convert the index numbers into the host's numeric format. */
2cf0635d
NC
10879 arch->index_array = malloc (arch->index_num * sizeof (* arch->index_array));
10880 if (arch->index_array == NULL)
4145f1d5
NC
10881 {
10882 free (index_buffer);
10883 error (_("Out of memory whilst trying to convert the archive symbol index\n"));
10884 return 1;
10885 }
10886
2cf0635d
NC
10887 for (i = 0; i < arch->index_num; i++)
10888 arch->index_array[i] = byte_get_big_endian ((unsigned char *) (index_buffer + (i * SIZEOF_AR_INDEX_NUMBERS)),
10889 SIZEOF_AR_INDEX_NUMBERS);
4145f1d5
NC
10890 free (index_buffer);
10891
10892 /* The remaining space in the header is taken up by the symbol table. */
10893 if (size < 1)
10894 {
10895 error (_("%s: the archive has an index but no symbols\n"), file_name);
2cf0635d 10896 return 1;
4145f1d5 10897 }
2cf0635d
NC
10898 arch->sym_table = malloc (size);
10899 arch->sym_size = size;
10900 if (arch->sym_table == NULL)
4145f1d5
NC
10901 {
10902 error (_("Out of memory whilst trying to read archive index symbol table\n"));
2cf0635d 10903 return 1;
4145f1d5 10904 }
2cf0635d 10905 got = fread (arch->sym_table, 1, size, file);
4145f1d5
NC
10906 if (got != size)
10907 {
10908 error (_("%s: failed to read archive index symbol table\n"), file_name);
2cf0635d 10909 return 1;
cb8f3167 10910 }
4145f1d5
NC
10911 }
10912 else
10913 {
10914 if (fseek (file, size, SEEK_CUR) != 0)
10915 {
10916 error (_("%s: failed to skip archive symbol table\n"), file_name);
10917 return 1;
10918 }
fb52b2f4
NC
10919 }
10920
2cf0635d
NC
10921 /* Read the next archive header. */
10922 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
10923 if (got != sizeof arch->arhdr)
fb52b2f4
NC
10924 {
10925 if (got == 0)
2cf0635d 10926 return 0;
4145f1d5 10927 error (_("%s: failed to read archive header following archive index\n"), file_name);
2cf0635d 10928 return 1;
fb52b2f4
NC
10929 }
10930 }
2cf0635d 10931 else if (read_symbols)
4145f1d5 10932 printf (_("%s has no archive index\n"), file_name);
fb52b2f4 10933
2cf0635d 10934 if (const_strneq (arch->arhdr.ar_name, "// "))
fb52b2f4 10935 {
2cf0635d
NC
10936 /* This is the archive string table holding long member names. */
10937 arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
10938 arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
fb52b2f4 10939
2cf0635d
NC
10940 arch->longnames = malloc (arch->longnames_size);
10941 if (arch->longnames == NULL)
fb52b2f4 10942 {
4145f1d5 10943 error (_("Out of memory reading long symbol names in archive\n"));
2cf0635d 10944 return 1;
fb52b2f4
NC
10945 }
10946
2cf0635d 10947 if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
fb52b2f4 10948 {
2cf0635d
NC
10949 free (arch->longnames);
10950 arch->longnames = NULL;
4145f1d5 10951 error (_("%s: failed to read long symbol name string table\n"), file_name);
2cf0635d 10952 return 1;
fb52b2f4
NC
10953 }
10954
2cf0635d 10955 if ((arch->longnames_size & 1) != 0)
fb52b2f4 10956 getc (file);
2cf0635d 10957 }
fb52b2f4 10958
2cf0635d
NC
10959 return 0;
10960}
10961
10962/* Release the memory used for the archive information. */
10963
10964static void
10965release_archive (struct archive_info * arch)
10966{
10967 if (arch->file_name != NULL)
10968 free (arch->file_name);
10969 if (arch->index_array != NULL)
10970 free (arch->index_array);
10971 if (arch->sym_table != NULL)
10972 free (arch->sym_table);
10973 if (arch->longnames != NULL)
10974 free (arch->longnames);
10975}
10976
10977/* Open and setup a nested archive, if not already open. */
10978
10979static int
10980setup_nested_archive (struct archive_info * nested_arch, char * member_file_name)
10981{
10982 FILE * member_file;
10983
10984 /* Have we already setup this archive? */
10985 if (nested_arch->file_name != NULL
10986 && streq (nested_arch->file_name, member_file_name))
10987 return 0;
10988
10989 /* Close previous file and discard cached information. */
10990 if (nested_arch->file != NULL)
10991 fclose (nested_arch->file);
10992 release_archive (nested_arch);
10993
10994 member_file = fopen (member_file_name, "rb");
10995 if (member_file == NULL)
10996 return 1;
10997 return setup_archive (nested_arch, member_file_name, member_file, FALSE, FALSE);
10998}
10999
11000static char *
11001get_archive_member_name_at (struct archive_info * arch,
11002 unsigned long offset,
11003 struct archive_info * nested_arch);
11004
11005/* Get the name of an archive member from the current archive header.
11006 For simple names, this will modify the ar_name field of the current
11007 archive header. For long names, it will return a pointer to the
11008 longnames table. For nested archives, it will open the nested archive
11009 and get the name recursively. NESTED_ARCH is a single-entry cache so
11010 we don't keep rereading the same information from a nested archive. */
11011
11012static char *
11013get_archive_member_name (struct archive_info * arch,
11014 struct archive_info * nested_arch)
11015{
11016 unsigned long j, k;
11017
11018 if (arch->arhdr.ar_name[0] == '/')
11019 {
11020 /* We have a long name. */
11021 char * endp;
11022 char * member_file_name;
11023 char * member_name;
11024
11025 arch->nested_member_origin = 0;
11026 k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
11027 if (arch->is_thin_archive && endp != NULL && * endp == ':')
11028 arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
11029
11030 while ((j < arch->longnames_size)
11031 && (arch->longnames[j] != '\n')
11032 && (arch->longnames[j] != '\0'))
11033 j++;
11034 if (arch->longnames[j-1] == '/')
11035 j--;
11036 arch->longnames[j] = '\0';
11037
11038 if (!arch->is_thin_archive || arch->nested_member_origin == 0)
11039 return arch->longnames + k;
11040
11041 /* This is a proxy for a member of a nested archive.
11042 Find the name of the member in that archive. */
11043 member_file_name = adjust_relative_path (arch->file_name, arch->longnames + k, j - k);
11044 if (member_file_name != NULL
11045 && setup_nested_archive (nested_arch, member_file_name) == 0
11046 && (member_name = get_archive_member_name_at (nested_arch, arch->nested_member_origin, NULL)) != NULL)
11047 {
11048 free (member_file_name);
11049 return member_name;
11050 }
11051 free (member_file_name);
11052
11053 /* Last resort: just return the name of the nested archive. */
11054 return arch->longnames + k;
11055 }
11056
11057 /* We have a normal (short) name. */
11058 j = 0;
11059 while ((arch->arhdr.ar_name[j] != '/') && (j < 16))
11060 j++;
11061 arch->arhdr.ar_name[j] = '\0';
11062 return arch->arhdr.ar_name;
11063}
11064
11065/* Get the name of an archive member at a given OFFSET within an archive ARCH. */
11066
11067static char *
11068get_archive_member_name_at (struct archive_info * arch,
11069 unsigned long offset,
11070 struct archive_info * nested_arch)
11071{
11072 size_t got;
11073
11074 if (fseek (arch->file, offset, SEEK_SET) != 0)
11075 {
11076 error (_("%s: failed to seek to next file name\n"), arch->file_name);
11077 return NULL;
11078 }
11079 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
11080 if (got != sizeof arch->arhdr)
11081 {
11082 error (_("%s: failed to read archive header\n"), arch->file_name);
11083 return NULL;
11084 }
11085 if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
11086 {
11087 error (_("%s: did not find a valid archive header\n"), arch->file_name);
11088 return NULL;
11089 }
11090
11091 return get_archive_member_name (arch, nested_arch);
11092}
11093
11094/* Construct a string showing the name of the archive member, qualified
11095 with the name of the containing archive file. For thin archives, we
11096 use square brackets to denote the indirection. For nested archives,
11097 we show the qualified name of the external member inside the square
11098 brackets (e.g., "thin.a[normal.a(foo.o)]"). */
11099
11100static char *
11101make_qualified_name (struct archive_info * arch,
11102 struct archive_info * nested_arch,
11103 char * member_name)
11104{
11105 size_t len;
11106 char * name;
11107
11108 len = strlen (arch->file_name) + strlen (member_name) + 3;
11109 if (arch->is_thin_archive && arch->nested_member_origin != 0)
11110 len += strlen (nested_arch->file_name) + 2;
11111
11112 name = malloc (len);
11113 if (name == NULL)
11114 {
11115 error (_("Out of memory\n"));
11116 return NULL;
11117 }
11118
11119 if (arch->is_thin_archive && arch->nested_member_origin != 0)
11120 snprintf (name, len, "%s[%s(%s)]", arch->file_name, nested_arch->file_name, member_name);
11121 else if (arch->is_thin_archive)
11122 snprintf (name, len, "%s[%s]", arch->file_name, member_name);
11123 else
11124 snprintf (name, len, "%s(%s)", arch->file_name, member_name);
11125
11126 return name;
11127}
11128
11129/* Process an ELF archive.
11130 On entry the file is positioned just after the ARMAG string. */
11131
11132static int
11133process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
11134{
11135 struct archive_info arch;
11136 struct archive_info nested_arch;
11137 size_t got;
11138 size_t file_name_size;
11139 int ret;
11140
11141 show_name = 1;
11142
11143 /* The ARCH structure is used to hold information about this archive. */
11144 arch.file_name = NULL;
11145 arch.file = NULL;
11146 arch.index_array = NULL;
11147 arch.sym_table = NULL;
11148 arch.longnames = NULL;
11149
11150 /* The NESTED_ARCH structure is used as a single-item cache of information
11151 about a nested archive (when members of a thin archive reside within
11152 another regular archive file). */
11153 nested_arch.file_name = NULL;
11154 nested_arch.file = NULL;
11155 nested_arch.index_array = NULL;
11156 nested_arch.sym_table = NULL;
11157 nested_arch.longnames = NULL;
11158
11159 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
11160 {
11161 ret = 1;
11162 goto out;
4145f1d5 11163 }
fb52b2f4 11164
4145f1d5
NC
11165 if (do_archive_index)
11166 {
2cf0635d 11167 if (arch.sym_table == NULL)
4145f1d5
NC
11168 error (_("%s: unable to dump the index as none was found\n"), file_name);
11169 else
11170 {
2cf0635d 11171 unsigned int i, l;
4145f1d5
NC
11172 unsigned long current_pos;
11173
11174 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
2cf0635d 11175 file_name, arch.index_num, arch.sym_size);
4145f1d5
NC
11176 current_pos = ftell (file);
11177
2cf0635d 11178 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 11179 {
2cf0635d
NC
11180 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
11181 {
11182 char * member_name;
4145f1d5 11183
2cf0635d
NC
11184 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
11185
11186 if (member_name != NULL)
11187 {
11188 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
11189
11190 if (qualified_name != NULL)
11191 {
11192 printf (_("Binary %s contains:\n"), qualified_name);
11193 free (qualified_name);
11194 }
4145f1d5
NC
11195 }
11196 }
2cf0635d
NC
11197
11198 if (l >= arch.sym_size)
4145f1d5
NC
11199 {
11200 error (_("%s: end of the symbol table reached before the end of the index\n"),
11201 file_name);
cb8f3167 11202 break;
4145f1d5 11203 }
2cf0635d
NC
11204 printf ("\t%s\n", arch.sym_table + l);
11205 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
11206 }
11207
2cf0635d
NC
11208 if (l & 01)
11209 ++l;
11210 if (l < arch.sym_size)
4145f1d5
NC
11211 error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"),
11212 file_name);
11213
4145f1d5
NC
11214 if (fseek (file, current_pos, SEEK_SET) != 0)
11215 {
11216 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
11217 ret = 1;
11218 goto out;
4145f1d5 11219 }
fb52b2f4 11220 }
4145f1d5
NC
11221
11222 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
11223 && !do_segments && !do_header && !do_dump && !do_version
11224 && !do_histogram && !do_debugging && !do_arch && !do_notes
11225 && !do_section_groups)
2cf0635d
NC
11226 {
11227 ret = 0; /* Archive index only. */
11228 goto out;
11229 }
fb52b2f4
NC
11230 }
11231
11232 file_name_size = strlen (file_name);
d989285c 11233 ret = 0;
fb52b2f4
NC
11234
11235 while (1)
11236 {
2cf0635d
NC
11237 char * name;
11238 size_t namelen;
11239 char * qualified_name;
11240
11241 /* Read the next archive header. */
11242 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
11243 {
11244 error (_("%s: failed to seek to next archive header\n"), file_name);
11245 return 1;
11246 }
11247 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
11248 if (got != sizeof arch.arhdr)
11249 {
11250 if (got == 0)
11251 break;
11252 error (_("%s: failed to read archive header\n"), file_name);
11253 ret = 1;
11254 break;
11255 }
11256 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
11257 {
11258 error (_("%s: did not find a valid archive header\n"), arch.file_name);
11259 ret = 1;
11260 break;
11261 }
11262
11263 arch.next_arhdr_offset += sizeof arch.arhdr;
11264
11265 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
11266 if (archive_file_size & 01)
11267 ++archive_file_size;
11268
11269 name = get_archive_member_name (&arch, &nested_arch);
11270 if (name == NULL)
fb52b2f4 11271 {
0fd3a477 11272 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
11273 ret = 1;
11274 break;
fb52b2f4 11275 }
2cf0635d 11276 namelen = strlen (name);
fb52b2f4 11277
2cf0635d
NC
11278 qualified_name = make_qualified_name (&arch, &nested_arch, name);
11279 if (qualified_name == NULL)
fb52b2f4 11280 {
2cf0635d 11281 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
11282 ret = 1;
11283 break;
fb52b2f4
NC
11284 }
11285
2cf0635d
NC
11286 if (is_thin_archive && arch.nested_member_origin == 0)
11287 {
11288 /* This is a proxy for an external member of a thin archive. */
11289 FILE * member_file;
11290 char * member_file_name = adjust_relative_path (file_name, name, namelen);
11291 if (member_file_name == NULL)
11292 {
11293 ret = 1;
11294 break;
11295 }
11296
11297 member_file = fopen (member_file_name, "rb");
11298 if (member_file == NULL)
11299 {
11300 error (_("Input file '%s' is not readable.\n"), member_file_name);
11301 free (member_file_name);
11302 ret = 1;
11303 break;
11304 }
11305
11306 archive_file_offset = arch.nested_member_origin;
11307
11308 ret |= process_object (qualified_name, member_file);
11309
11310 fclose (member_file);
11311 free (member_file_name);
11312 }
11313 else if (is_thin_archive)
11314 {
11315 /* This is a proxy for a member of a nested archive. */
11316 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
11317
11318 /* The nested archive file will have been opened and setup by
11319 get_archive_member_name. */
11320 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
11321 {
11322 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
11323 ret = 1;
11324 break;
11325 }
11326
11327 ret |= process_object (qualified_name, nested_arch.file);
11328 }
11329 else
11330 {
11331 archive_file_offset = arch.next_arhdr_offset;
11332 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 11333
2cf0635d
NC
11334 ret |= process_object (qualified_name, file);
11335 }
fb52b2f4 11336
2cf0635d 11337 free (qualified_name);
fb52b2f4
NC
11338 }
11339
4145f1d5 11340 out:
2cf0635d
NC
11341 if (nested_arch.file != NULL)
11342 fclose (nested_arch.file);
11343 release_archive (&nested_arch);
11344 release_archive (&arch);
fb52b2f4 11345
d989285c 11346 return ret;
fb52b2f4
NC
11347}
11348
11349static int
2cf0635d 11350process_file (char * file_name)
fb52b2f4 11351{
2cf0635d 11352 FILE * file;
fb52b2f4
NC
11353 struct stat statbuf;
11354 char armag[SARMAG];
11355 int ret;
11356
11357 if (stat (file_name, &statbuf) < 0)
11358 {
f24ddbdd
NC
11359 if (errno == ENOENT)
11360 error (_("'%s': No such file\n"), file_name);
11361 else
11362 error (_("Could not locate '%s'. System error message: %s\n"),
11363 file_name, strerror (errno));
11364 return 1;
11365 }
11366
11367 if (! S_ISREG (statbuf.st_mode))
11368 {
11369 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
11370 return 1;
11371 }
11372
11373 file = fopen (file_name, "rb");
11374 if (file == NULL)
11375 {
f24ddbdd 11376 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
11377 return 1;
11378 }
11379
11380 if (fread (armag, SARMAG, 1, file) != 1)
11381 {
4145f1d5 11382 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
11383 fclose (file);
11384 return 1;
11385 }
11386
11387 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
11388 ret = process_archive (file_name, file, FALSE);
11389 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
11390 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
11391 else
11392 {
4145f1d5
NC
11393 if (do_archive_index)
11394 error (_("File %s is not an archive so its index cannot be displayed.\n"),
11395 file_name);
11396
fb52b2f4
NC
11397 rewind (file);
11398 archive_file_size = archive_file_offset = 0;
11399 ret = process_object (file_name, file);
11400 }
11401
11402 fclose (file);
11403
11404 return ret;
11405}
11406
252b5132
RH
11407#ifdef SUPPORT_DISASSEMBLY
11408/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 11409 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 11410 symbols. */
252b5132
RH
11411
11412void
2cf0635d 11413print_address (unsigned int addr, FILE * outfile)
252b5132
RH
11414{
11415 fprintf (outfile,"0x%8.8x", addr);
11416}
11417
e3c8793a 11418/* Needed by the i386 disassembler. */
252b5132
RH
11419void
11420db_task_printsym (unsigned int addr)
11421{
11422 print_address (addr, stderr);
11423}
11424#endif
11425
11426int
2cf0635d 11427main (int argc, char ** argv)
252b5132 11428{
ff78d6d6
L
11429 int err;
11430
252b5132
RH
11431#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
11432 setlocale (LC_MESSAGES, "");
3882b010
L
11433#endif
11434#if defined (HAVE_SETLOCALE)
11435 setlocale (LC_CTYPE, "");
252b5132
RH
11436#endif
11437 bindtextdomain (PACKAGE, LOCALEDIR);
11438 textdomain (PACKAGE);
11439
869b9d07
MM
11440 expandargv (&argc, &argv);
11441
252b5132
RH
11442 parse_args (argc, argv);
11443
18bd398b 11444 if (num_dump_sects > 0)
59f14fc0 11445 {
18bd398b 11446 /* Make a copy of the dump_sects array. */
09c11c86 11447 cmdline_dump_sects = malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 11448 if (cmdline_dump_sects == NULL)
591a748a 11449 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
11450 else
11451 {
09c11c86
NC
11452 memcpy (cmdline_dump_sects, dump_sects,
11453 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
11454 num_cmdline_dump_sects = num_dump_sects;
11455 }
11456 }
11457
18bd398b
NC
11458 if (optind < (argc - 1))
11459 show_name = 1;
11460
ff78d6d6 11461 err = 0;
252b5132 11462 while (optind < argc)
18bd398b 11463 err |= process_file (argv[optind++]);
252b5132
RH
11464
11465 if (dump_sects != NULL)
11466 free (dump_sects);
59f14fc0
AS
11467 if (cmdline_dump_sects != NULL)
11468 free (cmdline_dump_sects);
252b5132 11469
ff78d6d6 11470 return err;
252b5132 11471}
This page took 1.355033 seconds and 4 git commands to generate.