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