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