]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
include:
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
9437c45b 2 Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 02111-1307, USA. */
23\f
24
25#include <assert.h>
00ed88bd 26#include <sys/types.h>
252b5132
RH
27#include <sys/stat.h>
28#include <stdio.h>
29#include <time.h>
30
a952a375 31#if __GNUC__ >= 2
19936277 32/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375
NC
33 as this will allow us to read in and parse 64bit and 32bit ELF files.
34 Only do this if we belive that the compiler can support a 64 bit
35 data type. For now we only rely on GCC being able to do this. */
19936277 36#define BFD64
a952a375
NC
37#endif
38
252b5132
RH
39#include "bfd.h"
40
41#include "elf/common.h"
42#include "elf/external.h"
43#include "elf/internal.h"
44#include "elf/dwarf2.h"
45
46/* The following headers use the elf/reloc-macros.h file to
47 automatically generate relocation recognition functions
48 such as elf_mips_reloc_type() */
49
50#define RELOC_MACROS_GEN_FUNC
51
252b5132 52#include "elf/alpha.h"
3b16e843 53#include "elf/arc.h"
252b5132 54#include "elf/arm.h"
3b16e843
NC
55#include "elf/avr.h"
56#include "elf/cris.h"
252b5132
RH
57#include "elf/d10v.h"
58#include "elf/d30v.h"
252b5132 59#include "elf/fr30.h"
3b16e843
NC
60#include "elf/h8.h"
61#include "elf/hppa.h"
62#include "elf/i386.h"
63#include "elf/i860.h"
64#include "elf/i960.h"
65#include "elf/ia64.h"
66#include "elf/m32r.h"
67#include "elf/m68k.h"
252b5132 68#include "elf/mcore.h"
3b16e843 69#include "elf/mips.h"
3c3bdf30 70#include "elf/mmix.h"
3b16e843
NC
71#include "elf/mn10200.h"
72#include "elf/mn10300.h"
73#include "elf/or32.h"
7d466069 74#include "elf/pj.h"
3b16e843 75#include "elf/ppc.h"
a85d7ed0 76#include "elf/s390.h"
3b16e843
NC
77#include "elf/sh.h"
78#include "elf/sparc.h"
79#include "elf/v850.h"
80#include "elf/x86-64.h"
93fbbb04 81#include "elf/xstormy16.h"
252b5132
RH
82
83#include "bucomm.h"
84#include "getopt.h"
85
c45021f2
NC
86char * program_name = "readelf";
87unsigned int dynamic_addr;
7036c0e1 88bfd_size_type dynamic_size;
c45021f2
NC
89unsigned int rela_addr;
90unsigned int rela_size;
91char * dynamic_strings;
252b5132 92char * string_table;
d40ac9bd 93unsigned long string_table_length;
19936277 94unsigned long num_dynamic_syms;
7036c0e1 95Elf_Internal_Sym * dynamic_symbols;
252b5132 96Elf_Internal_Syminfo * dynamic_syminfo;
c45021f2 97unsigned long dynamic_syminfo_offset;
252b5132 98unsigned int dynamic_syminfo_nent;
c45021f2
NC
99char program_interpreter [64];
100int dynamic_info[DT_JMPREL + 1];
101int version_info[16];
102int loadaddr = 0;
252b5132
RH
103Elf_Internal_Ehdr elf_header;
104Elf_Internal_Shdr * section_headers;
105Elf_Internal_Dyn * dynamic_segment;
9ad5cbcf 106Elf_Internal_Shdr * symtab_shndx_hdr;
7036c0e1
AJ
107int show_name;
108int do_dynamic;
109int do_syms;
110int do_reloc;
111int do_sections;
112int do_segments;
4d6ed7c8 113int do_unwind;
7036c0e1
AJ
114int do_using_dynamic;
115int do_header;
116int do_dump;
117int do_version;
d974e256 118int do_wide;
252b5132
RH
119int do_histogram;
120int do_debugging;
121int do_debug_info;
122int do_debug_abbrevs;
123int do_debug_lines;
124int do_debug_pubnames;
125int do_debug_aranges;
c47d488e 126int do_debug_frames;
31b6fca6 127int do_debug_frames_interp;
e0c60db2 128int do_debug_macinfo;
261a45ad 129int do_debug_str;
a952a375 130int do_arch;
779fe533 131int do_notes;
9ea033b2 132int is_32bit_elf;
252b5132
RH
133
134/* A dynamic array of flags indicating which sections require dumping. */
135char * dump_sects = NULL;
136unsigned int num_dump_sects = 0;
137
138#define HEX_DUMP (1 << 0)
139#define DISASS_DUMP (1 << 1)
140#define DEBUG_DUMP (1 << 2)
141
843dd992
NC
142/* How to rpint a vma value. */
143typedef enum print_mode
144{
145 HEX,
146 DEC,
147 DEC_5,
148 UNSIGNED,
149 PREFIX_HEX,
150 FULL_HEX,
151 LONG_HEX
152}
153print_mode;
154
252b5132 155/* Forward declarations for dumb compilers. */
30800947 156static void print_vma PARAMS ((bfd_vma, print_mode));
31104126 157static void print_symbol PARAMS ((int, char *));
9ea033b2
NC
158static bfd_vma (* byte_get) PARAMS ((unsigned char *, int));
159static bfd_vma byte_get_little_endian PARAMS ((unsigned char *, int));
160static bfd_vma byte_get_big_endian PARAMS ((unsigned char *, int));
161static const char * get_mips_dynamic_type PARAMS ((unsigned long));
9a097730 162static const char * get_sparc64_dynamic_type PARAMS ((unsigned long));
f1cb7e17 163static const char * get_ppc64_dynamic_type PARAMS ((unsigned long));
103f02d3 164static const char * get_parisc_dynamic_type PARAMS ((unsigned long));
9ea033b2 165static const char * get_dynamic_type PARAMS ((unsigned long));
7036c0e1
AJ
166static int slurp_rela_relocs PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Rela **, unsigned long *));
167static int slurp_rel_relocs PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Rel **, unsigned long *));
19936277 168static int dump_relocations PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, unsigned long, char *, int));
9ea033b2
NC
169static char * get_file_type PARAMS ((unsigned));
170static char * get_machine_name PARAMS ((unsigned));
f3485b74 171static void decode_ARM_machine_flags PARAMS ((unsigned, char []));
9ea033b2
NC
172static char * get_machine_flags PARAMS ((unsigned, unsigned));
173static const char * get_mips_segment_type PARAMS ((unsigned long));
103f02d3 174static const char * get_parisc_segment_type PARAMS ((unsigned long));
4d6ed7c8 175static const char * get_ia64_segment_type PARAMS ((unsigned long));
9ea033b2
NC
176static const char * get_segment_type PARAMS ((unsigned long));
177static const char * get_mips_section_type_name PARAMS ((unsigned int));
103f02d3 178static const char * get_parisc_section_type_name PARAMS ((unsigned int));
4d6ed7c8 179static const char * get_ia64_section_type_name PARAMS ((unsigned int));
9ea033b2 180static const char * get_section_type_name PARAMS ((unsigned int));
d1133906
NC
181static const char * get_symbol_binding PARAMS ((unsigned int));
182static const char * get_symbol_type PARAMS ((unsigned int));
183static const char * get_symbol_visibility PARAMS ((unsigned int));
184static const char * get_symbol_index_type PARAMS ((unsigned int));
7036c0e1 185static const char * get_dynamic_flags PARAMS ((bfd_vma));
252b5132 186static void usage PARAMS ((void));
9ea033b2 187static void parse_args PARAMS ((int, char **));
252b5132
RH
188static int process_file_header PARAMS ((void));
189static int process_program_headers PARAMS ((FILE *));
190static int process_section_headers PARAMS ((FILE *));
4d6ed7c8 191static int process_unwind PARAMS ((FILE *));
9ea033b2 192static void dynamic_segment_mips_val PARAMS ((Elf_Internal_Dyn *));
103f02d3 193static void dynamic_segment_parisc_val PARAMS ((Elf_Internal_Dyn *));
252b5132
RH
194static int process_dynamic_segment PARAMS ((FILE *));
195static int process_symbol_table PARAMS ((FILE *));
2863d58a 196static int process_syminfo PARAMS ((FILE *));
252b5132 197static int process_section_contents PARAMS ((FILE *));
2863d58a
AM
198static void process_mips_fpe_exception PARAMS ((int));
199static int process_mips_specific PARAMS ((FILE *));
ff78d6d6 200static int process_file PARAMS ((char *));
252b5132
RH
201static int process_relocs PARAMS ((FILE *));
202static int process_version_sections PARAMS ((FILE *));
9ea033b2 203static char * get_ver_flags PARAMS ((unsigned int));
560f3c1c
AM
204static int get_32bit_section_headers PARAMS ((FILE *, unsigned int));
205static int get_64bit_section_headers PARAMS ((FILE *, unsigned int));
9ea033b2
NC
206static int get_32bit_program_headers PARAMS ((FILE *, Elf_Internal_Phdr *));
207static int get_64bit_program_headers PARAMS ((FILE *, Elf_Internal_Phdr *));
208static int get_file_header PARAMS ((FILE *));
9ad5cbcf
AM
209static Elf_Internal_Sym * get_32bit_elf_symbols PARAMS ((FILE *, Elf_Internal_Shdr *));
210static Elf_Internal_Sym * get_64bit_elf_symbols PARAMS ((FILE *, Elf_Internal_Shdr *));
4d6ed7c8 211static const char * get_elf_section_flags PARAMS ((bfd_vma));
9ea033b2
NC
212static int * get_dynamic_data PARAMS ((FILE *, unsigned int));
213static int get_32bit_dynamic_segment PARAMS ((FILE *));
214static int get_64bit_dynamic_segment PARAMS ((FILE *));
252b5132 215#ifdef SUPPORT_DISASSEMBLY
7036c0e1 216static int disassemble_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
252b5132 217#endif
7036c0e1
AJ
218static int dump_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
219static int display_debug_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
252b5132
RH
220static int display_debug_info PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
221static int display_debug_not_supported PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
2863d58a 222static int prescan_debug_info PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
252b5132 223static int display_debug_lines PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
2863d58a 224static int display_debug_pubnames PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
252b5132
RH
225static int display_debug_abbrev PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
226static int display_debug_aranges PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
c47d488e 227static int display_debug_frames PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
e0c60db2 228static int display_debug_macinfo PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
261a45ad 229static int display_debug_str PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
252b5132 230static unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *));
261a45ad
NC
231static void load_debug_str PARAMS ((FILE *));
232static void free_debug_str PARAMS ((void));
233static const char * fetch_indirect_string PARAMS ((unsigned long));
252b5132 234static unsigned long read_leb128 PARAMS ((unsigned char *, int *, int));
3590ea00 235static int process_extended_line_op PARAMS ((unsigned char *, int, int));
252b5132
RH
236static void reset_state_machine PARAMS ((int));
237static char * get_TAG_name PARAMS ((unsigned long));
238static char * get_AT_name PARAMS ((unsigned long));
239static char * get_FORM_name PARAMS ((unsigned long));
240static void free_abbrevs PARAMS ((void));
241static void add_abbrev PARAMS ((unsigned long, unsigned long, int));
242static void add_abbrev_attr PARAMS ((unsigned long, unsigned long));
1fa37306 243static unsigned char * read_and_display_attr PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long, unsigned long));
81766fca 244static unsigned char * read_and_display_attr_value PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long, unsigned long));
252b5132 245static unsigned char * display_block PARAMS ((unsigned char *, unsigned long));
eb6bd4d3 246static void decode_location_expression PARAMS ((unsigned char *, unsigned int, unsigned long));
91770270
JL
247static void request_dump PARAMS ((unsigned int, int));
248static const char * get_elf_class PARAMS ((unsigned int));
249static const char * get_data_encoding PARAMS ((unsigned int));
250static const char * get_osabi_name PARAMS ((unsigned int));
9c19a809 251static int guess_is_rela PARAMS ((unsigned long));
9437c45b
JT
252static const char * get_note_type PARAMS ((unsigned int));
253static const char * get_netbsd_elfcore_note_type PARAMS ((unsigned int));
6d118b09 254static int process_note PARAMS ((Elf32_Internal_Note *));
f7a99963 255static int process_corefile_note_segment PARAMS ((FILE *, bfd_vma, bfd_vma));
779fe533 256static int process_corefile_note_segments PARAMS ((FILE *));
7036c0e1 257static int process_corefile_contents PARAMS ((FILE *));
2863d58a 258static int process_arch_specific PARAMS ((FILE *));
252b5132
RH
259
260typedef int Elf32_Word;
261
9c19a809
NC
262#ifndef TRUE
263#define TRUE 1
264#define FALSE 0
265#endif
266#define UNKNOWN -1
267
7036c0e1 268#define SECTION_NAME(X) ((X) == NULL ? "<none>" : \
d40ac9bd
NC
269 ((X)->sh_name >= string_table_length \
270 ? "<corrupt>" : string_table + (X)->sh_name))
252b5132 271
9ad5cbcf
AM
272/* Given st_shndx I, map to section_headers index. */
273#define SECTION_HEADER_INDEX(I) \
274 ((I) < SHN_LORESERVE \
275 ? (I) \
276 : ((I) <= SHN_HIRESERVE \
277 ? 0 \
278 : (I) - (SHN_HIRESERVE + 1 - SHN_LORESERVE)))
279
280/* Reverse of the above. */
281#define SECTION_HEADER_NUM(N) \
282 ((N) < SHN_LORESERVE \
283 ? (N) \
284 : (N) + (SHN_HIRESERVE + 1 - SHN_LORESERVE))
285
286#define SECTION_HEADER(I) (section_headers + SECTION_HEADER_INDEX (I))
287
252b5132
RH
288#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
289
7036c0e1 290#define BYTE_GET(field) byte_get (field, sizeof (field))
a952a375
NC
291
292/* If we can support a 64 bit data type then BFD64 should be defined
293 and sizeof (bfd_vma) == 8. In this case when translating from an
294 external 8 byte field to an internal field, we can assume that the
4d6ed7c8 295 internal field is also 8 bytes wide and so we can extract all the data.
a952a375
NC
296 If, however, BFD64 is not defined, then we must assume that the
297 internal data structure only has 4 byte wide fields that are the
298 equivalent of the 8 byte wide external counterparts, and so we must
299 truncate the data. */
300#ifdef BFD64
7036c0e1 301#define BYTE_GET8(field) byte_get (field, -8)
a952a375 302#else
7036c0e1 303#define BYTE_GET8(field) byte_get (field, 8)
a952a375 304#endif
252b5132 305
261a45ad 306#define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
252b5132 307
9ad5cbcf
AM
308#define GET_ELF_SYMBOLS(file, section) \
309 (is_32bit_elf ? get_32bit_elf_symbols (file, section) \
310 : get_64bit_elf_symbols (file, section))
9ea033b2
NC
311
312
252b5132 313static void
451dad9c 314error VPARAMS ((const char *message, ...))
252b5132 315{
451dad9c
AM
316 VA_OPEN (args, message);
317 VA_FIXEDARG (args, const char *, message);
252b5132
RH
318
319 fprintf (stderr, _("%s: Error: "), program_name);
252b5132 320 vfprintf (stderr, message, args);
451dad9c 321 VA_CLOSE (args);
252b5132
RH
322}
323
324static void
451dad9c 325warn VPARAMS ((const char *message, ...))
252b5132 326{
451dad9c
AM
327 VA_OPEN (args, message);
328 VA_FIXEDARG (args, const char *, message);
252b5132
RH
329
330 fprintf (stderr, _("%s: Warning: "), program_name);
252b5132 331 vfprintf (stderr, message, args);
451dad9c 332 VA_CLOSE (args);
252b5132 333}
252b5132 334
a6e9f9df
AM
335static PTR get_data PARAMS ((PTR, FILE *, long, size_t, const char *));
336
337static PTR
338get_data (var, file, offset, size, reason)
339 PTR var;
340 FILE *file;
341 long offset;
342 size_t size;
343 const char *reason;
344{
345 PTR mvar;
346
347 if (size == 0)
348 return NULL;
349
350 if (fseek (file, offset, SEEK_SET))
351 {
352 error (_("Unable to seek to %x for %s\n"), offset, reason);
353 return NULL;
354 }
355
356 mvar = var;
357 if (mvar == NULL)
358 {
359 mvar = (PTR) malloc (size);
360
361 if (mvar == NULL)
362 {
363 error (_("Out of memory allocating %d bytes for %s\n"),
364 size, reason);
365 return NULL;
366 }
367 }
368
369 if (fread (mvar, size, 1, file) != 1)
370 {
371 error (_("Unable to read in %d bytes of %s\n"), size, reason);
372 if (mvar != var)
373 free (mvar);
374 return NULL;
375 }
376
377 return mvar;
378}
379
9ea033b2 380static bfd_vma
252b5132
RH
381byte_get_little_endian (field, size)
382 unsigned char * field;
383 int size;
384{
385 switch (size)
386 {
387 case 1:
388 return * field;
389
390 case 2:
391 return ((unsigned int) (field [0]))
392 | (((unsigned int) (field [1])) << 8);
393
31b6fca6 394#ifndef BFD64
9ea033b2
NC
395 case 8:
396 /* We want to extract data from an 8 byte wide field and
397 place it into a 4 byte wide field. Since this is a little
398 endian source we can juts use the 4 byte extraction code. */
399 /* Fall through. */
31b6fca6 400#endif
252b5132
RH
401 case 4:
402 return ((unsigned long) (field [0]))
403 | (((unsigned long) (field [1])) << 8)
404 | (((unsigned long) (field [2])) << 16)
405 | (((unsigned long) (field [3])) << 24);
406
a952a375 407#ifdef BFD64
31b6fca6 408 case 8:
9ea033b2
NC
409 case -8:
410 /* This is a special case, generated by the BYTE_GET8 macro.
411 It means that we are loading an 8 byte value from a field
412 in an external structure into an 8 byte value in a field
413 in an internal strcuture. */
414 return ((bfd_vma) (field [0]))
415 | (((bfd_vma) (field [1])) << 8)
416 | (((bfd_vma) (field [2])) << 16)
417 | (((bfd_vma) (field [3])) << 24)
418 | (((bfd_vma) (field [4])) << 32)
419 | (((bfd_vma) (field [5])) << 40)
420 | (((bfd_vma) (field [6])) << 48)
421 | (((bfd_vma) (field [7])) << 56);
a952a375 422#endif
252b5132
RH
423 default:
424 error (_("Unhandled data length: %d\n"), size);
9ea033b2 425 abort ();
252b5132
RH
426 }
427}
428
f7a99963 429/* Print a VMA value. */
f7a99963
NC
430static void
431print_vma (vma, mode)
432 bfd_vma vma;
433 print_mode mode;
434{
435#ifdef BFD64
436 if (is_32bit_elf)
437#endif
438 {
439 switch (mode)
440 {
441 case FULL_HEX: printf ("0x"); /* drop through */
5e220199 442 case LONG_HEX: printf ("%8.8lx", (unsigned long) vma); break;
f7a99963 443 case PREFIX_HEX: printf ("0x"); /* drop through */
5e220199
NC
444 case HEX: printf ("%lx", (unsigned long) vma); break;
445 case DEC: printf ("%ld", (unsigned long) vma); break;
446 case DEC_5: printf ("%5ld", (long) vma); break;
447 case UNSIGNED: printf ("%lu", (unsigned long) vma); break;
f7a99963
NC
448 }
449 }
450#ifdef BFD64
451 else
452 {
453 switch (mode)
454 {
455 case FULL_HEX:
456 printf ("0x");
457 /* drop through */
76da6bbe 458
f7a99963
NC
459 case LONG_HEX:
460 printf_vma (vma);
461 break;
76da6bbe 462
f7a99963
NC
463 case PREFIX_HEX:
464 printf ("0x");
465 /* drop through */
76da6bbe 466
f7a99963
NC
467 case HEX:
468#if BFD_HOST_64BIT_LONG
469 printf ("%lx", vma);
470#else
471 if (_bfd_int64_high (vma))
2f11c261 472 printf ("%lx%8.8lx", _bfd_int64_high (vma), _bfd_int64_low (vma));
f7a99963
NC
473 else
474 printf ("%lx", _bfd_int64_low (vma));
475#endif
476 break;
477
478 case DEC:
2f528887
NC
479#if BFD_HOST_64BIT_LONG
480 printf ("%ld", vma);
481#else
f7a99963
NC
482 if (_bfd_int64_high (vma))
483 /* ugg */
484 printf ("++%ld", _bfd_int64_low (vma));
485 else
486 printf ("%ld", _bfd_int64_low (vma));
76da6bbe 487#endif
f7a99963
NC
488 break;
489
490 case DEC_5:
2f528887
NC
491#if BFD_HOST_64BIT_LONG
492 printf ("%5ld", vma);
493#else
f7a99963
NC
494 if (_bfd_int64_high (vma))
495 /* ugg */
496 printf ("++%ld", _bfd_int64_low (vma));
497 else
498 printf ("%5ld", _bfd_int64_low (vma));
76da6bbe 499#endif
f7a99963 500 break;
76da6bbe 501
f7a99963 502 case UNSIGNED:
2f528887
NC
503#if BFD_HOST_64BIT_LONG
504 printf ("%lu", vma);
76da6bbe 505#else
f7a99963
NC
506 if (_bfd_int64_high (vma))
507 /* ugg */
508 printf ("++%lu", _bfd_int64_low (vma));
509 else
510 printf ("%lu", _bfd_int64_low (vma));
2f528887 511#endif
f7a99963
NC
512 break;
513 }
514 }
515#endif
516}
517
31104126
NC
518/* Display a symbol on stdout. If do_wide is not true then
519 format the symbol to be at most WIDTH characters,
520 truhncating as necessary. If WIDTH is negative then
521 format the string to be exactly - WIDTH characters,
522 truncating or padding as necessary. */
523
524static void
525print_symbol (width, symbol)
526 int width;
527 char * symbol;
528{
529 if (do_wide)
530 printf (symbol);
531 else if (width < 0)
532 printf ("%-*.*s", width, width, symbol);
533 else
534 printf ("%-.*s", width, symbol);
535}
536
9ea033b2 537static bfd_vma
252b5132
RH
538byte_get_big_endian (field, size)
539 unsigned char * field;
540 int size;
541{
542 switch (size)
543 {
544 case 1:
545 return * field;
546
547 case 2:
548 return ((unsigned int) (field [1])) | (((int) (field [0])) << 8);
549
550 case 4:
551 return ((unsigned long) (field [3]))
552 | (((unsigned long) (field [2])) << 8)
553 | (((unsigned long) (field [1])) << 16)
554 | (((unsigned long) (field [0])) << 24);
555
31b6fca6 556#ifndef BFD64
9ea033b2
NC
557 case 8:
558 /* Although we are extracing data from an 8 byte wide field, we
559 are returning only 4 bytes of data. */
560 return ((unsigned long) (field [7]))
561 | (((unsigned long) (field [6])) << 8)
562 | (((unsigned long) (field [5])) << 16)
563 | (((unsigned long) (field [4])) << 24);
31b6fca6
RH
564#else
565 case 8:
9ea033b2
NC
566 case -8:
567 /* This is a special case, generated by the BYTE_GET8 macro.
568 It means that we are loading an 8 byte value from a field
569 in an external structure into an 8 byte value in a field
570 in an internal strcuture. */
571 return ((bfd_vma) (field [7]))
572 | (((bfd_vma) (field [6])) << 8)
573 | (((bfd_vma) (field [5])) << 16)
574 | (((bfd_vma) (field [4])) << 24)
575 | (((bfd_vma) (field [3])) << 32)
576 | (((bfd_vma) (field [2])) << 40)
577 | (((bfd_vma) (field [1])) << 48)
578 | (((bfd_vma) (field [0])) << 56);
a952a375 579#endif
103f02d3 580
252b5132
RH
581 default:
582 error (_("Unhandled data length: %d\n"), size);
9ea033b2 583 abort ();
252b5132
RH
584 }
585}
586
bcedfee6 587/* Guess the relocation size commonly used by the specific machines. */
252b5132 588
252b5132 589static int
9c19a809
NC
590guess_is_rela (e_machine)
591 unsigned long e_machine;
252b5132 592{
9c19a809 593 switch (e_machine)
252b5132
RH
594 {
595 /* Targets that use REL relocations. */
596 case EM_ARM:
597 case EM_386:
598 case EM_486:
63fcb9e9 599 case EM_960:
3b16e843
NC
600 case EM_OPENRISC:
601 case EM_OR32:
2b0337b0 602 case EM_M32R:
252b5132 603 case EM_CYGNUS_M32R:
2b0337b0 604 case EM_D10V:
252b5132
RH
605 case EM_CYGNUS_D10V:
606 case EM_MIPS:
4fe85591 607 case EM_MIPS_RS3_LE:
9c19a809 608 return FALSE;
103f02d3 609
252b5132
RH
610 /* Targets that use RELA relocations. */
611 case EM_68K:
b8720f9d
JL
612 case EM_H8_300:
613 case EM_H8_300H:
614 case EM_H8S:
351b4b40
RH
615 case EM_SPARC32PLUS:
616 case EM_SPARCV9:
252b5132
RH
617 case EM_SPARC:
618 case EM_PPC:
285d1771 619 case EM_PPC64:
2b0337b0 620 case EM_V850:
252b5132 621 case EM_CYGNUS_V850:
2b0337b0 622 case EM_D30V:
252b5132 623 case EM_CYGNUS_D30V:
2b0337b0 624 case EM_MN10200:
252b5132 625 case EM_CYGNUS_MN10200:
2b0337b0 626 case EM_MN10300:
252b5132 627 case EM_CYGNUS_MN10300:
2b0337b0 628 case EM_FR30:
252b5132
RH
629 case EM_CYGNUS_FR30:
630 case EM_SH:
631 case EM_ALPHA:
632 case EM_MCORE:
800eeca4 633 case EM_IA_64:
dff14200 634 case EM_AVR:
2b0337b0 635 case EM_AVR_OLD:
1b61cf92 636 case EM_CRIS:
535c37ff 637 case EM_860:
bcedfee6 638 case EM_X86_64:
a85d7ed0 639 case EM_S390:
b7498e0e 640 case EM_S390_OLD:
3c3bdf30 641 case EM_MMIX:
93fbbb04 642 case EM_XSTORMY16:
9c19a809 643 return TRUE;
103f02d3 644
d1133906
NC
645 case EM_MMA:
646 case EM_PCP:
647 case EM_NCPU:
648 case EM_NDR1:
649 case EM_STARCORE:
650 case EM_ME16:
651 case EM_ST100:
652 case EM_TINYJ:
653 case EM_FX66:
654 case EM_ST9PLUS:
655 case EM_ST7:
656 case EM_68HC16:
657 case EM_68HC11:
658 case EM_68HC08:
659 case EM_68HC05:
660 case EM_SVX:
661 case EM_ST19:
662 case EM_VAX:
9c19a809
NC
663 default:
664 warn (_("Don't know about relocations on this machine architecture\n"));
665 return FALSE;
666 }
667}
252b5132 668
9c19a809 669static int
4d6ed7c8
NC
670slurp_rela_relocs (file, rel_offset, rel_size, relasp, nrelasp)
671 FILE *file;
672 unsigned long rel_offset;
673 unsigned long rel_size;
674 Elf_Internal_Rela **relasp;
675 unsigned long *nrelasp;
9c19a809 676{
4d6ed7c8
NC
677 Elf_Internal_Rela *relas;
678 unsigned long nrelas;
679 unsigned int i;
252b5132 680
4d6ed7c8
NC
681 if (is_32bit_elf)
682 {
683 Elf32_External_Rela * erelas;
103f02d3 684
a6e9f9df
AM
685 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset,
686 rel_size, _("relocs"));
687 if (!erelas)
688 return 0;
252b5132 689
4d6ed7c8 690 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 691
4d6ed7c8
NC
692 relas = (Elf_Internal_Rela *)
693 malloc (nrelas * sizeof (Elf_Internal_Rela));
103f02d3 694
4d6ed7c8
NC
695 if (relas == NULL)
696 {
697 error(_("out of memory parsing relocs"));
698 return 0;
699 }
103f02d3 700
4d6ed7c8
NC
701 for (i = 0; i < nrelas; i++)
702 {
703 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
704 relas[i].r_info = BYTE_GET (erelas[i].r_info);
705 relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
706 }
103f02d3 707
4d6ed7c8
NC
708 free (erelas);
709 }
710 else
711 {
712 Elf64_External_Rela * erelas;
103f02d3 713
a6e9f9df
AM
714 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset,
715 rel_size, _("relocs"));
716 if (!erelas)
717 return 0;
4d6ed7c8
NC
718
719 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 720
4d6ed7c8
NC
721 relas = (Elf_Internal_Rela *)
722 malloc (nrelas * sizeof (Elf_Internal_Rela));
103f02d3 723
4d6ed7c8
NC
724 if (relas == NULL)
725 {
726 error(_("out of memory parsing relocs"));
727 return 0;
9c19a809 728 }
4d6ed7c8
NC
729
730 for (i = 0; i < nrelas; i++)
9c19a809 731 {
4d6ed7c8
NC
732 relas[i].r_offset = BYTE_GET8 (erelas[i].r_offset);
733 relas[i].r_info = BYTE_GET8 (erelas[i].r_info);
734 relas[i].r_addend = BYTE_GET8 (erelas[i].r_addend);
735 }
103f02d3 736
4d6ed7c8
NC
737 free (erelas);
738 }
739 *relasp = relas;
740 *nrelasp = nrelas;
741 return 1;
742}
103f02d3 743
4d6ed7c8
NC
744static int
745slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp)
746 FILE *file;
747 unsigned long rel_offset;
748 unsigned long rel_size;
749 Elf_Internal_Rel **relsp;
750 unsigned long *nrelsp;
751{
752 Elf_Internal_Rel *rels;
753 unsigned long nrels;
754 unsigned int i;
103f02d3 755
4d6ed7c8
NC
756 if (is_32bit_elf)
757 {
758 Elf32_External_Rel * erels;
103f02d3 759
a6e9f9df
AM
760 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset,
761 rel_size, _("relocs"));
762 if (!erels)
763 return 0;
103f02d3 764
4d6ed7c8 765 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 766
4d6ed7c8 767 rels = (Elf_Internal_Rel *) malloc (nrels * sizeof (Elf_Internal_Rel));
103f02d3 768
4d6ed7c8
NC
769 if (rels == NULL)
770 {
771 error(_("out of memory parsing relocs"));
772 return 0;
773 }
774
775 for (i = 0; i < nrels; i++)
776 {
777 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
778 rels[i].r_info = BYTE_GET (erels[i].r_info);
9ea033b2 779 }
4d6ed7c8
NC
780
781 free (erels);
9c19a809
NC
782 }
783 else
784 {
4d6ed7c8 785 Elf64_External_Rel * erels;
9ea033b2 786
a6e9f9df
AM
787 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset,
788 rel_size, _("relocs"));
789 if (!erels)
790 return 0;
103f02d3 791
4d6ed7c8 792 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 793
4d6ed7c8 794 rels = (Elf_Internal_Rel *) malloc (nrels * sizeof (Elf_Internal_Rel));
103f02d3 795
4d6ed7c8 796 if (rels == NULL)
9c19a809 797 {
4d6ed7c8
NC
798 error(_("out of memory parsing relocs"));
799 return 0;
800 }
103f02d3 801
4d6ed7c8
NC
802 for (i = 0; i < nrels; i++)
803 {
804 rels[i].r_offset = BYTE_GET8 (erels[i].r_offset);
805 rels[i].r_info = BYTE_GET8 (erels[i].r_info);
806 }
103f02d3 807
4d6ed7c8
NC
808 free (erels);
809 }
810 *relsp = rels;
811 *nrelsp = nrels;
812 return 1;
813}
103f02d3 814
4d6ed7c8
NC
815/* Display the contents of the relocation data found at the specified offset. */
816static int
817dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
818 FILE * file;
819 unsigned long rel_offset;
820 unsigned long rel_size;
821 Elf_Internal_Sym * symtab;
822 unsigned long nsyms;
823 char * strtab;
824 int is_rela;
825{
826 unsigned int i;
827 Elf_Internal_Rel * rels;
828 Elf_Internal_Rela * relas;
103f02d3 829
103f02d3 830
4d6ed7c8
NC
831 if (is_rela == UNKNOWN)
832 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 833
4d6ed7c8
NC
834 if (is_rela)
835 {
836 if (!slurp_rela_relocs (file, rel_offset, rel_size, &relas, &rel_size))
837 return 0;
838 }
839 else
840 {
841 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
842 return 0;
252b5132
RH
843 }
844
410f7a12
L
845 if (is_32bit_elf)
846 {
847 if (is_rela)
2c71103e
NC
848 {
849 if (do_wide)
850 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
851 else
852 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
853 }
410f7a12 854 else
2c71103e
NC
855 {
856 if (do_wide)
857 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
858 else
859 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
860 }
410f7a12 861 }
252b5132 862 else
410f7a12
L
863 {
864 if (is_rela)
2c71103e
NC
865 {
866 if (do_wide)
867 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
868 else
869 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
870 }
410f7a12 871 else
2c71103e
NC
872 {
873 if (do_wide)
874 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
875 else
876 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
877 }
410f7a12 878 }
252b5132
RH
879
880 for (i = 0; i < rel_size; i++)
881 {
9ea033b2 882 const char * rtype;
2c71103e
NC
883 const char * rtype2 = NULL;
884 const char * rtype3 = NULL;
9ea033b2
NC
885 bfd_vma offset;
886 bfd_vma info;
887 bfd_vma symtab_index;
888 bfd_vma type;
2c71103e
NC
889 bfd_vma type2 = (bfd_vma) NULL;
890 bfd_vma type3 = (bfd_vma) NULL;
103f02d3 891
252b5132
RH
892 if (is_rela)
893 {
894 offset = relas [i].r_offset;
895 info = relas [i].r_info;
896 }
897 else
898 {
899 offset = rels [i].r_offset;
900 info = rels [i].r_info;
901 }
103f02d3 902
9ea033b2
NC
903 if (is_32bit_elf)
904 {
905 type = ELF32_R_TYPE (info);
906 symtab_index = ELF32_R_SYM (info);
907 }
908 else
909 {
2c71103e
NC
910 if (elf_header.e_machine == EM_MIPS)
911 {
912 type = ELF64_MIPS_R_TYPE (info);
913 type2 = ELF64_MIPS_R_TYPE2 (info);
914 type3 = ELF64_MIPS_R_TYPE3 (info);
915 }
916 else if (elf_header.e_machine == EM_SPARCV9)
917 type = ELF64_R_TYPE_ID (info);
351b4b40 918 else
2c71103e 919 type = ELF64_R_TYPE (info);
a952a375
NC
920 /* The #ifdef BFD64 below is to prevent a compile time warning.
921 We know that if we do not have a 64 bit data type that we
922 will never execute this code anyway. */
103f02d3 923#ifdef BFD64
9ea033b2 924 symtab_index = ELF64_R_SYM (info);
a952a375 925#endif
9ea033b2 926 }
252b5132 927
410f7a12
L
928 if (is_32bit_elf)
929 {
930#ifdef _bfd_int64_low
931 printf ("%8.8lx %8.8lx ", _bfd_int64_low (offset), _bfd_int64_low (info));
932#else
933 printf ("%8.8lx %8.8lx ", offset, info);
934#endif
935 }
936 else
937 {
9ea033b2 938#ifdef _bfd_int64_low
2c71103e
NC
939 printf (do_wide
940 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
941 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
942 _bfd_int64_high (offset),
943 _bfd_int64_low (offset),
944 _bfd_int64_high (info),
945 _bfd_int64_low (info));
9ea033b2 946#else
2c71103e
NC
947 printf (do_wide
948 ? "%16.16lx %16.16lx ",
949 : "%12.12lx %12.12lx ",
950 offset, info);
9ea033b2 951#endif
410f7a12 952 }
103f02d3 953
252b5132
RH
954 switch (elf_header.e_machine)
955 {
956 default:
957 rtype = NULL;
958 break;
959
2b0337b0 960 case EM_M32R:
252b5132 961 case EM_CYGNUS_M32R:
9ea033b2 962 rtype = elf_m32r_reloc_type (type);
252b5132
RH
963 break;
964
965 case EM_386:
966 case EM_486:
9ea033b2 967 rtype = elf_i386_reloc_type (type);
252b5132
RH
968 break;
969
970 case EM_68K:
9ea033b2 971 rtype = elf_m68k_reloc_type (type);
252b5132
RH
972 break;
973
63fcb9e9 974 case EM_960:
9ea033b2 975 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
976 break;
977
adde6300 978 case EM_AVR:
2b0337b0 979 case EM_AVR_OLD:
adde6300
AM
980 rtype = elf_avr_reloc_type (type);
981 break;
982
9ea033b2
NC
983 case EM_OLD_SPARCV9:
984 case EM_SPARC32PLUS:
985 case EM_SPARCV9:
252b5132 986 case EM_SPARC:
9ea033b2 987 rtype = elf_sparc_reloc_type (type);
252b5132
RH
988 break;
989
2b0337b0 990 case EM_V850:
252b5132 991 case EM_CYGNUS_V850:
9ea033b2 992 rtype = v850_reloc_type (type);
252b5132
RH
993 break;
994
2b0337b0 995 case EM_D10V:
252b5132 996 case EM_CYGNUS_D10V:
9ea033b2 997 rtype = elf_d10v_reloc_type (type);
252b5132
RH
998 break;
999
2b0337b0 1000 case EM_D30V:
252b5132 1001 case EM_CYGNUS_D30V:
9ea033b2 1002 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1003 break;
1004
1005 case EM_SH:
9ea033b2 1006 rtype = elf_sh_reloc_type (type);
252b5132
RH
1007 break;
1008
2b0337b0 1009 case EM_MN10300:
252b5132 1010 case EM_CYGNUS_MN10300:
9ea033b2 1011 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1012 break;
1013
2b0337b0 1014 case EM_MN10200:
252b5132 1015 case EM_CYGNUS_MN10200:
9ea033b2 1016 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1017 break;
1018
2b0337b0 1019 case EM_FR30:
252b5132 1020 case EM_CYGNUS_FR30:
9ea033b2 1021 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1022 break;
1023
1024 case EM_MCORE:
9ea033b2 1025 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1026 break;
1027
3c3bdf30
NC
1028 case EM_MMIX:
1029 rtype = elf_mmix_reloc_type (type);
1030 break;
1031
252b5132 1032 case EM_PPC:
25a1ff5b 1033 case EM_PPC64:
9ea033b2 1034 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1035 break;
1036
1037 case EM_MIPS:
4fe85591 1038 case EM_MIPS_RS3_LE:
9ea033b2 1039 rtype = elf_mips_reloc_type (type);
2c71103e
NC
1040 if (!is_32bit_elf)
1041 {
1042 rtype2 = elf_mips_reloc_type (type2);
1043 rtype3 = elf_mips_reloc_type (type3);
1044 }
252b5132
RH
1045 break;
1046
1047 case EM_ALPHA:
9ea033b2 1048 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1049 break;
1050
1051 case EM_ARM:
9ea033b2 1052 rtype = elf_arm_reloc_type (type);
252b5132
RH
1053 break;
1054
584da044 1055 case EM_ARC:
9ea033b2 1056 rtype = elf_arc_reloc_type (type);
252b5132
RH
1057 break;
1058
1059 case EM_PARISC:
69e617ca 1060 rtype = elf_hppa_reloc_type (type);
252b5132 1061 break;
7d466069 1062
b8720f9d
JL
1063 case EM_H8_300:
1064 case EM_H8_300H:
1065 case EM_H8S:
1066 rtype = elf_h8_reloc_type (type);
1067 break;
1068
3b16e843
NC
1069 case EM_OPENRISC:
1070 case EM_OR32:
1071 rtype = elf_or32_reloc_type (type);
1072 break;
1073
7d466069 1074 case EM_PJ:
2b0337b0 1075 case EM_PJ_OLD:
7d466069
ILT
1076 rtype = elf_pj_reloc_type (type);
1077 break;
800eeca4
JW
1078 case EM_IA_64:
1079 rtype = elf_ia64_reloc_type (type);
1080 break;
1b61cf92
HPN
1081
1082 case EM_CRIS:
1083 rtype = elf_cris_reloc_type (type);
1084 break;
535c37ff
JE
1085
1086 case EM_860:
1087 rtype = elf_i860_reloc_type (type);
1088 break;
bcedfee6
NC
1089
1090 case EM_X86_64:
1091 rtype = elf_x86_64_reloc_type (type);
1092 break;
a85d7ed0 1093
b7498e0e 1094 case EM_S390_OLD:
a85d7ed0
NC
1095 case EM_S390:
1096 rtype = elf_s390_reloc_type (type);
1097 break;
93fbbb04
GK
1098
1099 case EM_XSTORMY16:
1100 rtype = elf_xstormy16_reloc_type (type);
1101 break;
252b5132
RH
1102 }
1103
1104 if (rtype == NULL)
103f02d3 1105#ifdef _bfd_int64_low
2c71103e 1106 printf (_("unrecognized: %-7lx"), _bfd_int64_low (type));
9ea033b2 1107#else
2c71103e 1108 printf (_("unrecognized: %-7lx"), type);
9ea033b2 1109#endif
252b5132 1110 else
2c71103e 1111 printf (do_wide ? "%-21.21s" : "%-17.17s", rtype);
252b5132 1112
19936277 1113 if (symtab_index)
252b5132 1114 {
af3fc3bc
AM
1115 if (symtab == NULL || symtab_index >= nsyms)
1116 printf (" bad symbol index: %08lx", (unsigned long) symtab_index);
1117 else
19936277 1118 {
af3fc3bc 1119 Elf_Internal_Sym * psym;
19936277 1120
af3fc3bc 1121 psym = symtab + symtab_index;
103f02d3 1122
af3fc3bc
AM
1123 printf (" ");
1124 print_vma (psym->st_value, LONG_HEX);
2c71103e 1125 printf (is_32bit_elf ? " " : " ");
103f02d3 1126
af3fc3bc 1127 if (psym->st_name == 0)
2c71103e 1128 print_symbol (22, SECTION_NAME (section_headers + psym->st_shndx));
af3fc3bc
AM
1129 else if (strtab == NULL)
1130 printf (_("<string table index %3ld>"), psym->st_name);
1131 else
2c71103e 1132 print_symbol (22, strtab + psym->st_name);
103f02d3 1133
af3fc3bc
AM
1134 if (is_rela)
1135 printf (" + %lx", (unsigned long) relas [i].r_addend);
19936277 1136 }
252b5132 1137 }
1b228002 1138 else if (is_rela)
f7a99963 1139 {
2c71103e 1140 printf ("%*c", is_32bit_elf ? (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' ');
f7a99963
NC
1141 print_vma (relas[i].r_addend, LONG_HEX);
1142 }
252b5132 1143
351b4b40
RH
1144 if (elf_header.e_machine == EM_SPARCV9
1145 && !strcmp (rtype, "R_SPARC_OLO10"))
1146 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (info));
1147
252b5132 1148 putchar ('\n');
2c71103e
NC
1149
1150 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
1151 {
1152 printf (" Type2: ");
1153
1154 if (rtype2 == NULL)
1155#ifdef _bfd_int64_low
1156 printf (_("unrecognized: %-7lx"), _bfd_int64_low (type2));
1157#else
1158 printf (_("unrecognized: %-7lx"), type2);
1159#endif
1160 else
1161 printf ("%-17.17s", rtype2);
1162
1163 printf("\n Type3: ");
1164
1165 if (rtype3 == NULL)
1166#ifdef _bfd_int64_low
1167 printf (_("unrecognized: %-7lx"), _bfd_int64_low (type3));
1168#else
1169 printf (_("unrecognized: %-7lx"), type3);
1170#endif
1171 else
1172 printf ("%-17.17s", rtype3);
1173
1174 putchar ('\n');
1175 }
252b5132
RH
1176 }
1177
88ec60c7
NC
1178 if (is_rela)
1179 free (relas);
1180 else
1181 free (rels);
252b5132
RH
1182
1183 return 1;
1184}
1185
1186static const char *
1187get_mips_dynamic_type (type)
1188 unsigned long type;
1189{
1190 switch (type)
1191 {
1192 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1193 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1194 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1195 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1196 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1197 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1198 case DT_MIPS_MSYM: return "MIPS_MSYM";
1199 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1200 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1201 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1202 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1203 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1204 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1205 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1206 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1207 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1208 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1209 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1210 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1211 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1212 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1213 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1214 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1215 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1216 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1217 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1218 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1219 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1220 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1221 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1222 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1223 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1224 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1225 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1226 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1227 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1228 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1229 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1230 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1231 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1232 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1233 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1234 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
1235 default:
1236 return NULL;
1237 }
1238}
1239
9a097730
RH
1240static const char *
1241get_sparc64_dynamic_type (type)
1242 unsigned long type;
1243{
1244 switch (type)
1245 {
1246 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1247 default:
1248 return NULL;
1249 }
103f02d3
UD
1250}
1251
f1cb7e17
AM
1252static const char *
1253get_ppc64_dynamic_type (type)
1254 unsigned long type;
1255{
1256 switch (type)
1257 {
1258 case DT_PPC64_GLINK: return "PPC64_GLINK";
19397422
AM
1259 case DT_PPC64_OPD: return "PPC64_OPD";
1260 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
f1cb7e17
AM
1261 default:
1262 return NULL;
1263 }
1264}
1265
103f02d3
UD
1266static const char *
1267get_parisc_dynamic_type (type)
1268 unsigned long type;
1269{
1270 switch (type)
1271 {
1272 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1273 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1274 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1275 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1276 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1277 case DT_HP_PREINIT: return "HP_PREINIT";
1278 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1279 case DT_HP_NEEDED: return "HP_NEEDED";
1280 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1281 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1282 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1283 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1284 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
1285 default:
1286 return NULL;
1287 }
1288}
9a097730 1289
252b5132
RH
1290static const char *
1291get_dynamic_type (type)
1292 unsigned long type;
1293{
1294 static char buff [32];
1295
1296 switch (type)
1297 {
1298 case DT_NULL: return "NULL";
1299 case DT_NEEDED: return "NEEDED";
1300 case DT_PLTRELSZ: return "PLTRELSZ";
1301 case DT_PLTGOT: return "PLTGOT";
1302 case DT_HASH: return "HASH";
1303 case DT_STRTAB: return "STRTAB";
1304 case DT_SYMTAB: return "SYMTAB";
1305 case DT_RELA: return "RELA";
1306 case DT_RELASZ: return "RELASZ";
1307 case DT_RELAENT: return "RELAENT";
1308 case DT_STRSZ: return "STRSZ";
1309 case DT_SYMENT: return "SYMENT";
1310 case DT_INIT: return "INIT";
1311 case DT_FINI: return "FINI";
1312 case DT_SONAME: return "SONAME";
1313 case DT_RPATH: return "RPATH";
1314 case DT_SYMBOLIC: return "SYMBOLIC";
1315 case DT_REL: return "REL";
1316 case DT_RELSZ: return "RELSZ";
1317 case DT_RELENT: return "RELENT";
1318 case DT_PLTREL: return "PLTREL";
1319 case DT_DEBUG: return "DEBUG";
1320 case DT_TEXTREL: return "TEXTREL";
1321 case DT_JMPREL: return "JMPREL";
1322 case DT_BIND_NOW: return "BIND_NOW";
1323 case DT_INIT_ARRAY: return "INIT_ARRAY";
1324 case DT_FINI_ARRAY: return "FINI_ARRAY";
1325 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1326 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1327 case DT_RUNPATH: return "RUNPATH";
1328 case DT_FLAGS: return "FLAGS";
2d0e6f43 1329
d1133906
NC
1330 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1331 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1332
05107a46 1333 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1334 case DT_PLTPADSZ: return "PLTPADSZ";
1335 case DT_MOVEENT: return "MOVEENT";
1336 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1337 case DT_FEATURE: return "FEATURE";
252b5132
RH
1338 case DT_POSFLAG_1: return "POSFLAG_1";
1339 case DT_SYMINSZ: return "SYMINSZ";
1340 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1341
252b5132 1342 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1343 case DT_CONFIG: return "CONFIG";
1344 case DT_DEPAUDIT: return "DEPAUDIT";
1345 case DT_AUDIT: return "AUDIT";
1346 case DT_PLTPAD: return "PLTPAD";
1347 case DT_MOVETAB: return "MOVETAB";
252b5132 1348 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1349
252b5132 1350 case DT_VERSYM: return "VERSYM";
103f02d3 1351
252b5132
RH
1352 case DT_RELACOUNT: return "RELACOUNT";
1353 case DT_RELCOUNT: return "RELCOUNT";
1354 case DT_FLAGS_1: return "FLAGS_1";
1355 case DT_VERDEF: return "VERDEF";
1356 case DT_VERDEFNUM: return "VERDEFNUM";
1357 case DT_VERNEED: return "VERNEED";
1358 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1359
019148e4 1360 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1361 case DT_USED: return "USED";
1362 case DT_FILTER: return "FILTER";
103f02d3 1363
252b5132
RH
1364 default:
1365 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1366 {
1367 const char * result;
103f02d3 1368
252b5132
RH
1369 switch (elf_header.e_machine)
1370 {
1371 case EM_MIPS:
4fe85591 1372 case EM_MIPS_RS3_LE:
252b5132
RH
1373 result = get_mips_dynamic_type (type);
1374 break;
9a097730
RH
1375 case EM_SPARCV9:
1376 result = get_sparc64_dynamic_type (type);
1377 break;
f1cb7e17
AM
1378 case EM_PPC64:
1379 result = get_ppc64_dynamic_type (type);
1380 break;
252b5132
RH
1381 default:
1382 result = NULL;
1383 break;
1384 }
1385
1386 if (result != NULL)
1387 return result;
1388
1389 sprintf (buff, _("Processor Specific: %lx"), type);
1390 }
1391 else if ((type >= DT_LOOS) && (type <= DT_HIOS))
103f02d3
UD
1392 {
1393 const char * result;
1394
1395 switch (elf_header.e_machine)
1396 {
1397 case EM_PARISC:
1398 result = get_parisc_dynamic_type (type);
1399 break;
1400 default:
1401 result = NULL;
1402 break;
1403 }
1404
1405 if (result != NULL)
1406 return result;
1407
1408 sprintf (buff, _("Operating System specific: %lx"), type);
1409 }
252b5132
RH
1410 else
1411 sprintf (buff, _("<unknown>: %lx"), type);
103f02d3 1412
252b5132
RH
1413 return buff;
1414 }
1415}
1416
1417static char *
1418get_file_type (e_type)
1419 unsigned e_type;
1420{
1421 static char buff [32];
1422
1423 switch (e_type)
1424 {
1425 case ET_NONE: return _("NONE (None)");
1426 case ET_REL: return _("REL (Relocatable file)");
1427 case ET_EXEC: return _("EXEC (Executable file)");
1428 case ET_DYN: return _("DYN (Shared object file)");
1429 case ET_CORE: return _("CORE (Core file)");
1430
1431 default:
1432 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
1433 sprintf (buff, _("Processor Specific: (%x)"), e_type);
1434 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
1435 sprintf (buff, _("OS Specific: (%x)"), e_type);
1436 else
1437 sprintf (buff, _("<unknown>: %x"), e_type);
1438 return buff;
1439 }
1440}
1441
1442static char *
1443get_machine_name (e_machine)
1444 unsigned e_machine;
1445{
d1133906 1446 static char buff [64]; /* XXX */
252b5132
RH
1447
1448 switch (e_machine)
1449 {
c45021f2
NC
1450 case EM_NONE: return _("None");
1451 case EM_M32: return "WE32100";
1452 case EM_SPARC: return "Sparc";
1453 case EM_386: return "Intel 80386";
1454 case EM_68K: return "MC68000";
1455 case EM_88K: return "MC88000";
1456 case EM_486: return "Intel 80486";
1457 case EM_860: return "Intel 80860";
1458 case EM_MIPS: return "MIPS R3000";
1459 case EM_S370: return "IBM System/370";
7036c0e1 1460 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1461 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1462 case EM_PARISC: return "HPPA";
252b5132 1463 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1464 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1465 case EM_960: return "Intel 90860";
1466 case EM_PPC: return "PowerPC";
285d1771 1467 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1468 case EM_V800: return "NEC V800";
1469 case EM_FR20: return "Fujitsu FR20";
1470 case EM_RH32: return "TRW RH32";
252b5132 1471 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1472 case EM_ARM: return "ARM";
1473 case EM_OLD_ALPHA: return "Digital Alpha (old)";
1474 case EM_SH: return "Hitachi SH";
c45021f2
NC
1475 case EM_SPARCV9: return "Sparc v9";
1476 case EM_TRICORE: return "Siemens Tricore";
584da044 1477 case EM_ARC: return "ARC";
252b5132
RH
1478 case EM_H8_300: return "Hitachi H8/300";
1479 case EM_H8_300H: return "Hitachi H8/300H";
1480 case EM_H8S: return "Hitachi H8S";
1481 case EM_H8_500: return "Hitachi H8/500";
30800947 1482 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1483 case EM_MIPS_X: return "Stanford MIPS-X";
1484 case EM_COLDFIRE: return "Motorola Coldfire";
1485 case EM_68HC12: return "Motorola M68HC12";
c45021f2 1486 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1487 case EM_CYGNUS_D10V:
1488 case EM_D10V: return "d10v";
1489 case EM_CYGNUS_D30V:
1490 case EM_D30V: return "d30v";
1491 case EM_CYGNUS_M32R:
1492 case EM_M32R: return "Mitsubishi M32r";
1493 case EM_CYGNUS_V850:
1494 case EM_V850: return "NEC v850";
1495 case EM_CYGNUS_MN10300:
1496 case EM_MN10300: return "mn10300";
1497 case EM_CYGNUS_MN10200:
1498 case EM_MN10200: return "mn10200";
1499 case EM_CYGNUS_FR30:
1500 case EM_FR30: return "Fujitsu FR30";
1501 case EM_PJ_OLD:
7d466069 1502 case EM_PJ: return "picoJava";
7036c0e1
AJ
1503 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1504 case EM_PCP: return "Siemens PCP";
1505 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1506 case EM_NDR1: return "Denso NDR1 microprocesspr";
1507 case EM_STARCORE: return "Motorola Star*Core processor";
1508 case EM_ME16: return "Toyota ME16 processor";
1509 case EM_ST100: return "STMicroelectronics ST100 processor";
1510 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
1511 case EM_FX66: return "Siemens FX66 microcontroller";
1512 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1513 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1514 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
1515 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1516 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1517 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1518 case EM_SVX: return "Silicon Graphics SVx";
1519 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1520 case EM_VAX: return "Digital VAX";
2b0337b0 1521 case EM_AVR_OLD:
dff14200 1522 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1523 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1524 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1525 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1526 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
93ebe586 1527 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2
NC
1528 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
1529 case EM_PRISM: return "SiTera Prism";
bcedfee6 1530 case EM_X86_64: return "Advanced Micro Devices X86-64";
b7498e0e 1531 case EM_S390_OLD:
a85d7ed0 1532 case EM_S390: return "IBM S/390";
93fbbb04 1533 case EM_XSTORMY16: return "Sanyo Xstormy16 CPU core";
3b16e843
NC
1534 case EM_OPENRISC:
1535 case EM_OR32: return "OpenRISC";
252b5132
RH
1536 default:
1537 sprintf (buff, _("<unknown>: %x"), e_machine);
1538 return buff;
1539 }
1540}
1541
f3485b74
NC
1542static void
1543decode_ARM_machine_flags (e_flags, buf)
1544 unsigned e_flags;
1545 char buf[];
1546{
1547 unsigned eabi;
1548 int unknown = 0;
1549
1550 eabi = EF_ARM_EABI_VERSION (e_flags);
1551 e_flags &= ~ EF_ARM_EABIMASK;
1552
1553 /* Handle "generic" ARM flags. */
1554 if (e_flags & EF_ARM_RELEXEC)
1555 {
1556 strcat (buf, ", relocatable executable");
1557 e_flags &= ~ EF_ARM_RELEXEC;
1558 }
76da6bbe 1559
f3485b74
NC
1560 if (e_flags & EF_ARM_HASENTRY)
1561 {
1562 strcat (buf, ", has entry point");
1563 e_flags &= ~ EF_ARM_HASENTRY;
1564 }
76da6bbe 1565
f3485b74
NC
1566 /* Now handle EABI specific flags. */
1567 switch (eabi)
1568 {
1569 default:
2c71103e 1570 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
1571 if (e_flags)
1572 unknown = 1;
1573 break;
1574
1575 case EF_ARM_EABI_VER1:
a5bcd848 1576 strcat (buf, ", Version1 EABI");
f3485b74
NC
1577 while (e_flags)
1578 {
1579 unsigned flag;
76da6bbe 1580
f3485b74
NC
1581 /* Process flags one bit at a time. */
1582 flag = e_flags & - e_flags;
1583 e_flags &= ~ flag;
76da6bbe 1584
f3485b74
NC
1585 switch (flag)
1586 {
a5bcd848 1587 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
1588 strcat (buf, ", sorted symbol tables");
1589 break;
76da6bbe 1590
f3485b74
NC
1591 default:
1592 unknown = 1;
1593 break;
1594 }
1595 }
1596 break;
76da6bbe 1597
a5bcd848
PB
1598 case EF_ARM_EABI_VER2:
1599 strcat (buf, ", Version2 EABI");
1600 while (e_flags)
1601 {
1602 unsigned flag;
1603
1604 /* Process flags one bit at a time. */
1605 flag = e_flags & - e_flags;
1606 e_flags &= ~ flag;
1607
1608 switch (flag)
1609 {
1610 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
1611 strcat (buf, ", sorted symbol tables");
1612 break;
1613
1614 case EF_ARM_DYNSYMSUSESEGIDX:
1615 strcat (buf, ", dynamic symbols use segment index");
1616 break;
1617
1618 case EF_ARM_MAPSYMSFIRST:
1619 strcat (buf, ", mapping symbols precede others");
1620 break;
1621
1622 default:
1623 unknown = 1;
1624 break;
1625 }
1626 }
1627 break;
1628
f3485b74 1629 case EF_ARM_EABI_UNKNOWN:
a5bcd848 1630 strcat (buf, ", GNU EABI");
f3485b74
NC
1631 while (e_flags)
1632 {
1633 unsigned flag;
76da6bbe 1634
f3485b74
NC
1635 /* Process flags one bit at a time. */
1636 flag = e_flags & - e_flags;
1637 e_flags &= ~ flag;
76da6bbe 1638
f3485b74
NC
1639 switch (flag)
1640 {
a5bcd848 1641 case EF_ARM_INTERWORK:
f3485b74
NC
1642 strcat (buf, ", interworking enabled");
1643 break;
76da6bbe 1644
a5bcd848 1645 case EF_ARM_APCS_26:
f3485b74
NC
1646 strcat (buf, ", uses APCS/26");
1647 break;
76da6bbe 1648
a5bcd848 1649 case EF_ARM_APCS_FLOAT:
f3485b74
NC
1650 strcat (buf, ", uses APCS/float");
1651 break;
76da6bbe 1652
a5bcd848 1653 case EF_ARM_PIC:
f3485b74
NC
1654 strcat (buf, ", position independent");
1655 break;
76da6bbe 1656
a5bcd848 1657 case EF_ARM_ALIGN8:
f3485b74
NC
1658 strcat (buf, ", 8 bit structure alignment");
1659 break;
76da6bbe 1660
a5bcd848 1661 case EF_ARM_NEW_ABI:
f3485b74
NC
1662 strcat (buf, ", uses new ABI");
1663 break;
76da6bbe 1664
a5bcd848 1665 case EF_ARM_OLD_ABI:
f3485b74
NC
1666 strcat (buf, ", uses old ABI");
1667 break;
76da6bbe 1668
a5bcd848 1669 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
1670 strcat (buf, ", software FP");
1671 break;
76da6bbe 1672
f3485b74
NC
1673 default:
1674 unknown = 1;
1675 break;
1676 }
1677 }
1678 }
f3485b74
NC
1679
1680 if (unknown)
1681 strcat (buf,", <unknown>");
1682}
1683
252b5132
RH
1684static char *
1685get_machine_flags (e_flags, e_machine)
1686 unsigned e_flags;
1687 unsigned e_machine;
1688{
1689 static char buf [1024];
1690
1691 buf[0] = '\0';
76da6bbe 1692
252b5132
RH
1693 if (e_flags)
1694 {
1695 switch (e_machine)
1696 {
1697 default:
1698 break;
1699
f3485b74
NC
1700 case EM_ARM:
1701 decode_ARM_machine_flags (e_flags, buf);
1702 break;
76da6bbe 1703
33c63f9d
CM
1704 case EM_68K:
1705 if (e_flags & EF_CPU32)
1706 strcat (buf, ", cpu32");
76f57f3a
JT
1707 if (e_flags & EF_M68000)
1708 strcat (buf, ", m68000");
33c63f9d
CM
1709 break;
1710
252b5132
RH
1711 case EM_PPC:
1712 if (e_flags & EF_PPC_EMB)
1713 strcat (buf, ", emb");
1714
1715 if (e_flags & EF_PPC_RELOCATABLE)
1716 strcat (buf, ", relocatable");
1717
1718 if (e_flags & EF_PPC_RELOCATABLE_LIB)
1719 strcat (buf, ", relocatable-lib");
1720 break;
1721
2b0337b0 1722 case EM_V850:
252b5132
RH
1723 case EM_CYGNUS_V850:
1724 switch (e_flags & EF_V850_ARCH)
1725 {
1726 case E_V850E_ARCH:
1727 strcat (buf, ", v850e");
1728 break;
1729 case E_V850EA_ARCH:
1730 strcat (buf, ", v850ea");
1731 break;
1732 case E_V850_ARCH:
1733 strcat (buf, ", v850");
1734 break;
1735 default:
1736 strcat (buf, ", unknown v850 architecture variant");
1737 break;
1738 }
1739 break;
1740
2b0337b0 1741 case EM_M32R:
252b5132
RH
1742 case EM_CYGNUS_M32R:
1743 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
1744 strcat (buf, ", m32r");
1745
1746 break;
1747
1748 case EM_MIPS:
4fe85591 1749 case EM_MIPS_RS3_LE:
252b5132
RH
1750 if (e_flags & EF_MIPS_NOREORDER)
1751 strcat (buf, ", noreorder");
1752
1753 if (e_flags & EF_MIPS_PIC)
1754 strcat (buf, ", pic");
1755
1756 if (e_flags & EF_MIPS_CPIC)
1757 strcat (buf, ", cpic");
1758
d1bdd336
TS
1759 if (e_flags & EF_MIPS_UCODE)
1760 strcat (buf, ", ugen_reserved");
1761
252b5132
RH
1762 if (e_flags & EF_MIPS_ABI2)
1763 strcat (buf, ", abi2");
1764
43521d43
TS
1765 if (e_flags & EF_MIPS_OPTIONS_FIRST)
1766 strcat (buf, ", odk first");
1767
a5d22d2a
TS
1768 if (e_flags & EF_MIPS_32BITMODE)
1769 strcat (buf, ", 32bitmode");
1770
156c2f8b
NC
1771 switch ((e_flags & EF_MIPS_MACH))
1772 {
1773 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
1774 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
1775 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
1776 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
1777 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
c6c98b38 1778 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
43521d43
TS
1779 case 0:
1780 /* We simply ignore the field in this case to avoid confusion:
1781 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
1782 extension. */
1783 break;
1784 default: strcat (buf, ", unknown CPU"); break;
156c2f8b 1785 }
43521d43
TS
1786
1787 switch ((e_flags & EF_MIPS_ABI))
1788 {
1789 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
1790 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
1791 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
1792 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
1793 case 0:
1794 /* We simply ignore the field in this case to avoid confusion:
1795 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
1796 This means it is likely to be an o32 file, but not for
1797 sure. */
1798 break;
1799 default: strcat (buf, ", unknown ABI"); break;
1800 }
1801
1802 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
1803 strcat (buf, ", mdmx");
1804
1805 if (e_flags & EF_MIPS_ARCH_ASE_M16)
1806 strcat (buf, ", mips16");
1807
1808 switch ((e_flags & EF_MIPS_ARCH))
1809 {
1810 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
1811 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
1812 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
1813 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
1814 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
1815 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
1816 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
1817 default: strcat (buf, ", unknown ISA"); break;
1818 }
1819
252b5132 1820 break;
351b4b40
RH
1821
1822 case EM_SPARCV9:
1823 if (e_flags & EF_SPARC_32PLUS)
1824 strcat (buf, ", v8+");
1825
1826 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
1827 strcat (buf, ", ultrasparcI");
1828
1829 if (e_flags & EF_SPARC_SUN_US3)
1830 strcat (buf, ", ultrasparcIII");
351b4b40
RH
1831
1832 if (e_flags & EF_SPARC_HAL_R1)
1833 strcat (buf, ", halr1");
1834
1835 if (e_flags & EF_SPARC_LEDATA)
1836 strcat (buf, ", ledata");
1837
1838 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
1839 strcat (buf, ", tso");
1840
1841 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
1842 strcat (buf, ", pso");
1843
1844 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
1845 strcat (buf, ", rmo");
1846 break;
7d466069 1847
103f02d3
UD
1848 case EM_PARISC:
1849 switch (e_flags & EF_PARISC_ARCH)
1850 {
1851 case EFA_PARISC_1_0:
1852 strcpy (buf, ", PA-RISC 1.0");
1853 break;
1854 case EFA_PARISC_1_1:
1855 strcpy (buf, ", PA-RISC 1.1");
1856 break;
1857 case EFA_PARISC_2_0:
1858 strcpy (buf, ", PA-RISC 2.0");
1859 break;
1860 default:
1861 break;
1862 }
1863 if (e_flags & EF_PARISC_TRAPNIL)
1864 strcat (buf, ", trapnil");
1865 if (e_flags & EF_PARISC_EXT)
1866 strcat (buf, ", ext");
1867 if (e_flags & EF_PARISC_LSB)
1868 strcat (buf, ", lsb");
1869 if (e_flags & EF_PARISC_WIDE)
1870 strcat (buf, ", wide");
1871 if (e_flags & EF_PARISC_NO_KABP)
1872 strcat (buf, ", no kabp");
1873 if (e_flags & EF_PARISC_LAZYSWAP)
1874 strcat (buf, ", lazyswap");
30800947 1875 break;
76da6bbe 1876
7d466069 1877 case EM_PJ:
2b0337b0 1878 case EM_PJ_OLD:
7d466069
ILT
1879 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
1880 strcat (buf, ", new calling convention");
1881
1882 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
1883 strcat (buf, ", gnu calling convention");
1884 break;
4d6ed7c8
NC
1885
1886 case EM_IA_64:
1887 if ((e_flags & EF_IA_64_ABI64))
1888 strcat (buf, ", 64-bit");
1889 else
1890 strcat (buf, ", 32-bit");
1891 if ((e_flags & EF_IA_64_REDUCEDFP))
1892 strcat (buf, ", reduced fp model");
1893 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
1894 strcat (buf, ", no function descriptors, constant gp");
1895 else if ((e_flags & EF_IA_64_CONS_GP))
1896 strcat (buf, ", constant gp");
1897 if ((e_flags & EF_IA_64_ABSOLUTE))
1898 strcat (buf, ", absolute");
1899 break;
252b5132
RH
1900 }
1901 }
1902
1903 return buf;
1904}
1905
252b5132
RH
1906static const char *
1907get_mips_segment_type (type)
1908 unsigned long type;
1909{
1910 switch (type)
1911 {
1912 case PT_MIPS_REGINFO:
1913 return "REGINFO";
1914 case PT_MIPS_RTPROC:
1915 return "RTPROC";
1916 case PT_MIPS_OPTIONS:
1917 return "OPTIONS";
1918 default:
1919 break;
1920 }
1921
1922 return NULL;
1923}
1924
103f02d3
UD
1925static const char *
1926get_parisc_segment_type (type)
1927 unsigned long type;
1928{
1929 switch (type)
1930 {
1931 case PT_HP_TLS: return "HP_TLS";
1932 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
1933 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
1934 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
1935 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
1936 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
1937 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
1938 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
1939 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
1940 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
1941 case PT_HP_PARALLEL: return "HP_PARALLEL";
1942 case PT_HP_FASTBIND: return "HP_FASTBIND";
1943 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
1944 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
1945 default:
1946 break;
1947 }
1948
1949 return NULL;
1950}
1951
4d6ed7c8
NC
1952static const char *
1953get_ia64_segment_type (type)
1954 unsigned long type;
1955{
1956 switch (type)
1957 {
1958 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
1959 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
1960 case PT_HP_TLS: return "HP_TLS";
1961 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
1962 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
1963 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
1964 default:
1965 break;
1966 }
1967
1968 return NULL;
1969}
1970
252b5132
RH
1971static const char *
1972get_segment_type (p_type)
1973 unsigned long p_type;
1974{
1975 static char buff [32];
1976
1977 switch (p_type)
1978 {
1979 case PT_NULL: return "NULL";
1980 case PT_LOAD: return "LOAD";
1981 case PT_DYNAMIC: return "DYNAMIC";
1982 case PT_INTERP: return "INTERP";
1983 case PT_NOTE: return "NOTE";
1984 case PT_SHLIB: return "SHLIB";
1985 case PT_PHDR: return "PHDR";
1986
65765700
JJ
1987 case PT_GNU_EH_FRAME:
1988 return "GNU_EH_FRAME";
1989
252b5132
RH
1990 default:
1991 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
1992 {
1993 const char * result;
103f02d3 1994
252b5132
RH
1995 switch (elf_header.e_machine)
1996 {
1997 case EM_MIPS:
4fe85591 1998 case EM_MIPS_RS3_LE:
252b5132
RH
1999 result = get_mips_segment_type (p_type);
2000 break;
103f02d3
UD
2001 case EM_PARISC:
2002 result = get_parisc_segment_type (p_type);
2003 break;
4d6ed7c8
NC
2004 case EM_IA_64:
2005 result = get_ia64_segment_type (p_type);
2006 break;
252b5132
RH
2007 default:
2008 result = NULL;
2009 break;
2010 }
103f02d3 2011
252b5132
RH
2012 if (result != NULL)
2013 return result;
103f02d3 2014
252b5132
RH
2015 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2016 }
2017 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3
UD
2018 {
2019 const char * result;
2020
2021 switch (elf_header.e_machine)
2022 {
2023 case EM_PARISC:
2024 result = get_parisc_segment_type (p_type);
2025 break;
00428cca
AM
2026 case EM_IA_64:
2027 result = get_ia64_segment_type (p_type);
2028 break;
103f02d3
UD
2029 default:
2030 result = NULL;
2031 break;
2032 }
2033
2034 if (result != NULL)
2035 return result;
2036
2037 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
2038 }
252b5132
RH
2039 else
2040 sprintf (buff, _("<unknown>: %lx"), p_type);
2041
2042 return buff;
2043 }
2044}
2045
2046static const char *
2047get_mips_section_type_name (sh_type)
2048 unsigned int sh_type;
2049{
2050 switch (sh_type)
2051 {
2052 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2053 case SHT_MIPS_MSYM: return "MIPS_MSYM";
2054 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2055 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
2056 case SHT_MIPS_UCODE: return "MIPS_UCODE";
2057 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
2058 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
2059 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
2060 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
2061 case SHT_MIPS_RELD: return "MIPS_RELD";
2062 case SHT_MIPS_IFACE: return "MIPS_IFACE";
2063 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
2064 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2065 case SHT_MIPS_SHDR: return "MIPS_SHDR";
2066 case SHT_MIPS_FDESC: return "MIPS_FDESC";
2067 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
2068 case SHT_MIPS_DENSE: return "MIPS_DENSE";
2069 case SHT_MIPS_PDESC: return "MIPS_PDESC";
2070 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
2071 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
2072 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
2073 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
2074 case SHT_MIPS_LINE: return "MIPS_LINE";
2075 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
2076 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
2077 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
2078 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
2079 case SHT_MIPS_DWARF: return "MIPS_DWARF";
2080 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
2081 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2082 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
2083 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
2084 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
2085 case SHT_MIPS_XLATE: return "MIPS_XLATE";
2086 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
2087 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
2088 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
2089 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
2090 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
2091 default:
2092 break;
2093 }
2094 return NULL;
2095}
2096
103f02d3
UD
2097static const char *
2098get_parisc_section_type_name (sh_type)
2099 unsigned int sh_type;
2100{
2101 switch (sh_type)
2102 {
2103 case SHT_PARISC_EXT: return "PARISC_EXT";
2104 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
2105 case SHT_PARISC_DOC: return "PARISC_DOC";
2106 default:
2107 break;
2108 }
2109 return NULL;
2110}
2111
4d6ed7c8
NC
2112static const char *
2113get_ia64_section_type_name (sh_type)
2114 unsigned int sh_type;
2115{
2116 switch (sh_type)
2117 {
2118 case SHT_IA_64_EXT: return "IA_64_EXT";
2119 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
2120 default:
2121 break;
2122 }
2123 return NULL;
2124}
2125
252b5132
RH
2126static const char *
2127get_section_type_name (sh_type)
2128 unsigned int sh_type;
2129{
2130 static char buff [32];
2131
2132 switch (sh_type)
2133 {
2134 case SHT_NULL: return "NULL";
2135 case SHT_PROGBITS: return "PROGBITS";
2136 case SHT_SYMTAB: return "SYMTAB";
2137 case SHT_STRTAB: return "STRTAB";
2138 case SHT_RELA: return "RELA";
2139 case SHT_HASH: return "HASH";
2140 case SHT_DYNAMIC: return "DYNAMIC";
2141 case SHT_NOTE: return "NOTE";
2142 case SHT_NOBITS: return "NOBITS";
2143 case SHT_REL: return "REL";
2144 case SHT_SHLIB: return "SHLIB";
2145 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
2146 case SHT_INIT_ARRAY: return "INIT_ARRAY";
2147 case SHT_FINI_ARRAY: return "FINI_ARRAY";
2148 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
93ebe586
NC
2149 case SHT_GROUP: return "GROUP";
2150 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
2151 case SHT_GNU_verdef: return "VERDEF";
2152 case SHT_GNU_verneed: return "VERNEED";
2153 case SHT_GNU_versym: return "VERSYM";
2154 case 0x6ffffff0: return "VERSYM";
2155 case 0x6ffffffc: return "VERDEF";
2156 case 0x7ffffffd: return "AUXILIARY";
2157 case 0x7fffffff: return "FILTER";
2158
2159 default:
2160 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
2161 {
2162 const char * result;
2163
2164 switch (elf_header.e_machine)
2165 {
2166 case EM_MIPS:
4fe85591 2167 case EM_MIPS_RS3_LE:
252b5132
RH
2168 result = get_mips_section_type_name (sh_type);
2169 break;
103f02d3
UD
2170 case EM_PARISC:
2171 result = get_parisc_section_type_name (sh_type);
2172 break;
4d6ed7c8
NC
2173 case EM_IA_64:
2174 result = get_ia64_section_type_name (sh_type);
2175 break;
252b5132
RH
2176 default:
2177 result = NULL;
2178 break;
2179 }
2180
2181 if (result != NULL)
2182 return result;
2183
c91d0dfb 2184 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
2185 }
2186 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
c91d0dfb 2187 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
252b5132 2188 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 2189 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132
RH
2190 else
2191 sprintf (buff, _("<unknown>: %x"), sh_type);
103f02d3 2192
252b5132
RH
2193 return buff;
2194 }
2195}
2196
2197struct option options [] =
2198{
2199 {"all", no_argument, 0, 'a'},
2200 {"file-header", no_argument, 0, 'h'},
2201 {"program-headers", no_argument, 0, 'l'},
2202 {"headers", no_argument, 0, 'e'},
a952a375 2203 {"histogram", no_argument, 0, 'I'},
252b5132
RH
2204 {"segments", no_argument, 0, 'l'},
2205 {"sections", no_argument, 0, 'S'},
2206 {"section-headers", no_argument, 0, 'S'},
2207 {"symbols", no_argument, 0, 's'},
2208 {"syms", no_argument, 0, 's'},
2209 {"relocs", no_argument, 0, 'r'},
779fe533 2210 {"notes", no_argument, 0, 'n'},
252b5132 2211 {"dynamic", no_argument, 0, 'd'},
a952a375 2212 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
2213 {"version-info", no_argument, 0, 'V'},
2214 {"use-dynamic", no_argument, 0, 'D'},
2215 {"hex-dump", required_argument, 0, 'x'},
2216 {"debug-dump", optional_argument, 0, 'w'},
4d6ed7c8 2217 {"unwind", no_argument, 0, 'u'},
252b5132
RH
2218#ifdef SUPPORT_DISASSEMBLY
2219 {"instruction-dump", required_argument, 0, 'i'},
2220#endif
2221
2222 {"version", no_argument, 0, 'v'},
d974e256 2223 {"wide", no_argument, 0, 'W'},
252b5132
RH
2224 {"help", no_argument, 0, 'H'},
2225 {0, no_argument, 0, 0}
2226};
2227
2228static void
2229usage ()
2230{
8b53311e
NC
2231 fprintf (stdout, _("Usage: readelf <option(s)> elf-file(s)\n"));
2232 fprintf (stdout, _(" Display information about the contents of ELF format files\n"));
2233 fprintf (stdout, _(" Options are:\n\
2234 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
2235 -h --file-header Display the ELF file header\n\
2236 -l --program-headers Display the program headers\n\
2237 --segments An alias for --program-headers\n\
2238 -S --section-headers Display the sections' header\n\
2239 --sections An alias for --section-headers\n\
2240 -e --headers Equivalent to: -h -l -S\n\
2241 -s --syms Display the symbol table\n\
2242 --symbols An alias for --syms\n\
2243 -n --notes Display the core notes (if present)\n\
2244 -r --relocs Display the relocations (if present)\n\
2245 -u --unwind Display the unwind info (if present)\n\
2246 -d --dynamic Display the dynamic segment (if present)\n\
2247 -V --version-info Display the version sections (if present)\n\
2248 -A --arch-specific Display architecture specific information (if any).\n\
2249 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
2250 -x --hex-dump=<number> Dump the contents of section <number>\n\
2251 -w --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames,=str]\n\
2252 Display the contents of DWARF2 debug sections\n"));
252b5132 2253#ifdef SUPPORT_DISASSEMBLY
8b53311e
NC
2254 fprintf (stdout, _("\
2255 -i --instruction-dump=<number>\n\
2256 Disassemble the contents of section <number>\n"));
252b5132 2257#endif
8b53311e
NC
2258 fprintf (stdout, _("\
2259 -I --histogram Display histogram of bucket list lengths\n\
2260 -W --wide Allow output width to exceed 80 characters\n\
2261 -H --help Display this information\n\
2262 -v --version Display the version number of readelf\n"));
8ad3436c 2263 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
2264
2265 exit (0);
2266}
2267
2268static void
2269request_dump (section, type)
2270 unsigned int section;
91770270 2271 int type;
252b5132
RH
2272{
2273 if (section >= num_dump_sects)
2274 {
2275 char * new_dump_sects;
2276
2277 new_dump_sects = (char *) calloc (section + 1, 1);
2278
2279 if (new_dump_sects == NULL)
2280 error (_("Out of memory allocating dump request table."));
2281 else
2282 {
2283 /* Copy current flag settings. */
2284 memcpy (new_dump_sects, dump_sects, num_dump_sects);
2285
2286 free (dump_sects);
2287
2288 dump_sects = new_dump_sects;
2289 num_dump_sects = section + 1;
2290 }
2291 }
2292
2293 if (dump_sects)
2294 dump_sects [section] |= type;
2295
2296 return;
2297}
2298
2299static void
2300parse_args (argc, argv)
2301 int argc;
2302 char ** argv;
2303{
2304 int c;
2305
2306 if (argc < 2)
2307 usage ();
2308
2309 while ((c = getopt_long
d974e256 2310 (argc, argv, "ersuahnldSDAIw::x:i:vVW", options, NULL)) != EOF)
252b5132
RH
2311 {
2312 char * cp;
2313 int section;
2314
2315 switch (c)
2316 {
2317 case 0:
2318 /* Long options. */
2319 break;
2320 case 'H':
2321 usage ();
2322 break;
2323
2324 case 'a':
2325 do_syms ++;
2326 do_reloc ++;
4d6ed7c8 2327 do_unwind ++;
252b5132
RH
2328 do_dynamic ++;
2329 do_header ++;
2330 do_sections ++;
2331 do_segments ++;
2332 do_version ++;
2333 do_histogram ++;
a952a375 2334 do_arch ++;
779fe533 2335 do_notes ++;
252b5132
RH
2336 break;
2337 case 'e':
2338 do_header ++;
2339 do_sections ++;
2340 do_segments ++;
2341 break;
a952a375
NC
2342 case 'A':
2343 do_arch ++;
2344 break;
252b5132
RH
2345 case 'D':
2346 do_using_dynamic ++;
2347 break;
2348 case 'r':
2349 do_reloc ++;
2350 break;
4d6ed7c8
NC
2351 case 'u':
2352 do_unwind ++;
2353 break;
252b5132
RH
2354 case 'h':
2355 do_header ++;
2356 break;
2357 case 'l':
2358 do_segments ++;
2359 break;
2360 case 's':
2361 do_syms ++;
2362 break;
2363 case 'S':
2364 do_sections ++;
2365 break;
2366 case 'd':
2367 do_dynamic ++;
2368 break;
a952a375
NC
2369 case 'I':
2370 do_histogram ++;
2371 break;
779fe533
NC
2372 case 'n':
2373 do_notes ++;
2374 break;
252b5132
RH
2375 case 'x':
2376 do_dump ++;
2377 section = strtoul (optarg, & cp, 0);
2378 if (! * cp && section >= 0)
2379 {
2380 request_dump (section, HEX_DUMP);
2381 break;
2382 }
2383 goto oops;
2384 case 'w':
2385 do_dump ++;
2386 if (optarg == 0)
2387 do_debugging = 1;
2388 else
2389 {
f662939a
NC
2390 unsigned int index = 0;
2391
252b5132 2392 do_debugging = 0;
252b5132 2393
f662939a
NC
2394 while (optarg[index])
2395 switch (optarg[index++])
2396 {
2397 case 'i':
2398 case 'I':
2399 do_debug_info = 1;
2400 break;
2401
2402 case 'a':
2403 case 'A':
2404 do_debug_abbrevs = 1;
2405 break;
2406
2407 case 'l':
2408 case 'L':
2409 do_debug_lines = 1;
2410 break;
2411
2412 case 'p':
2413 case 'P':
2414 do_debug_pubnames = 1;
2415 break;
2416
2417 case 'r':
2418 case 'R':
2419 do_debug_aranges = 1;
2420 break;
2421
2422 case 'F':
2423 do_debug_frames_interp = 1;
2424 case 'f':
2425 do_debug_frames = 1;
2426 break;
2427
2428 case 'm':
2429 case 'M':
2430 do_debug_macinfo = 1;
2431 break;
2432
261a45ad
NC
2433 case 's':
2434 case 'S':
2435 do_debug_str = 1;
2436 break;
2437
f662939a 2438 default:
2c71103e 2439 warn (_("Unrecognized debug option '%s'\n"), optarg);
f662939a
NC
2440 break;
2441 }
252b5132
RH
2442 }
2443 break;
2444#ifdef SUPPORT_DISASSEMBLY
2445 case 'i':
2446 do_dump ++;
2447 section = strtoul (optarg, & cp, 0);
2448 if (! * cp && section >= 0)
2449 {
2450 request_dump (section, DISASS_DUMP);
2451 break;
2452 }
2453 goto oops;
2454#endif
2455 case 'v':
2456 print_version (program_name);
2457 break;
2458 case 'V':
2459 do_version ++;
2460 break;
d974e256
JJ
2461 case 'W':
2462 do_wide ++;
2463 break;
252b5132
RH
2464 default:
2465 oops:
2466 /* xgettext:c-format */
2467 error (_("Invalid option '-%c'\n"), c);
2468 /* Drop through. */
2469 case '?':
2470 usage ();
2471 }
2472 }
2473
4d6ed7c8 2474 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 2475 && !do_segments && !do_header && !do_dump && !do_version
779fe533 2476 && !do_histogram && !do_debugging && !do_arch && !do_notes)
252b5132
RH
2477 usage ();
2478 else if (argc < 3)
2479 {
2480 warn (_("Nothing to do.\n"));
2481 usage();
2482 }
2483}
2484
2485static const char *
2486get_elf_class (elf_class)
91770270 2487 unsigned int elf_class;
252b5132 2488{
ab5e7794 2489 static char buff [32];
103f02d3 2490
252b5132
RH
2491 switch (elf_class)
2492 {
2493 case ELFCLASSNONE: return _("none");
e3c8793a
NC
2494 case ELFCLASS32: return "ELF32";
2495 case ELFCLASS64: return "ELF64";
ab5e7794 2496 default:
789be9f7 2497 sprintf (buff, _("<unknown: %x>"), elf_class);
ab5e7794 2498 return buff;
252b5132
RH
2499 }
2500}
2501
2502static const char *
2503get_data_encoding (encoding)
91770270 2504 unsigned int encoding;
252b5132 2505{
ab5e7794 2506 static char buff [32];
103f02d3 2507
252b5132
RH
2508 switch (encoding)
2509 {
2510 case ELFDATANONE: return _("none");
33c63f9d
CM
2511 case ELFDATA2LSB: return _("2's complement, little endian");
2512 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 2513 default:
789be9f7 2514 sprintf (buff, _("<unknown: %x>"), encoding);
ab5e7794 2515 return buff;
252b5132
RH
2516 }
2517}
2518
2519static const char *
2520get_osabi_name (osabi)
91770270 2521 unsigned int osabi;
252b5132 2522{
ab5e7794 2523 static char buff [32];
103f02d3 2524
252b5132
RH
2525 switch (osabi)
2526 {
e3c8793a
NC
2527 case ELFOSABI_NONE: return "UNIX - System V";
2528 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2529 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
2530 case ELFOSABI_LINUX: return "UNIX - Linux";
2531 case ELFOSABI_HURD: return "GNU/Hurd";
2532 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2533 case ELFOSABI_AIX: return "UNIX - AIX";
2534 case ELFOSABI_IRIX: return "UNIX - IRIX";
2535 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2536 case ELFOSABI_TRU64: return "UNIX - TRU64";
2537 case ELFOSABI_MODESTO: return "Novell - Modesto";
2538 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
252b5132 2539 case ELFOSABI_STANDALONE: return _("Standalone App");
e3c8793a 2540 case ELFOSABI_ARM: return "ARM";
ab5e7794 2541 default:
789be9f7 2542 sprintf (buff, _("<unknown: %x>"), osabi);
ab5e7794 2543 return buff;
252b5132
RH
2544 }
2545}
2546
2547/* Decode the data held in 'elf_header'. */
2548static int
2549process_file_header ()
2550{
2551 if ( elf_header.e_ident [EI_MAG0] != ELFMAG0
2552 || elf_header.e_ident [EI_MAG1] != ELFMAG1
2553 || elf_header.e_ident [EI_MAG2] != ELFMAG2
2554 || elf_header.e_ident [EI_MAG3] != ELFMAG3)
2555 {
2556 error
2557 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
2558 return 0;
2559 }
2560
2561 if (do_header)
2562 {
2563 int i;
2564
2565 printf (_("ELF Header:\n"));
2566 printf (_(" Magic: "));
2567 for (i = 0; i < EI_NIDENT; i ++)
2568 printf ("%2.2x ", elf_header.e_ident [i]);
2569 printf ("\n");
2570 printf (_(" Class: %s\n"),
2571 get_elf_class (elf_header.e_ident [EI_CLASS]));
2572 printf (_(" Data: %s\n"),
2573 get_data_encoding (elf_header.e_ident [EI_DATA]));
2574 printf (_(" Version: %d %s\n"),
2575 elf_header.e_ident [EI_VERSION],
789be9f7
ILT
2576 (elf_header.e_ident [EI_VERSION] == EV_CURRENT
2577 ? "(current)"
2578 : (elf_header.e_ident [EI_VERSION] != EV_NONE
2579 ? "<unknown: %lx>"
2580 : "")));
252b5132
RH
2581 printf (_(" OS/ABI: %s\n"),
2582 get_osabi_name (elf_header.e_ident [EI_OSABI]));
2583 printf (_(" ABI Version: %d\n"),
2584 elf_header.e_ident [EI_ABIVERSION]);
2585 printf (_(" Type: %s\n"),
2586 get_file_type (elf_header.e_type));
2587 printf (_(" Machine: %s\n"),
2588 get_machine_name (elf_header.e_machine));
2589 printf (_(" Version: 0x%lx\n"),
2590 (unsigned long) elf_header.e_version);
76da6bbe 2591
f7a99963
NC
2592 printf (_(" Entry point address: "));
2593 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
2594 printf (_("\n Start of program headers: "));
2595 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
2596 printf (_(" (bytes into file)\n Start of section headers: "));
2597 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
2598 printf (_(" (bytes into file)\n"));
76da6bbe 2599
252b5132
RH
2600 printf (_(" Flags: 0x%lx%s\n"),
2601 (unsigned long) elf_header.e_flags,
2602 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
2603 printf (_(" Size of this header: %ld (bytes)\n"),
2604 (long) elf_header.e_ehsize);
2605 printf (_(" Size of program headers: %ld (bytes)\n"),
2606 (long) elf_header.e_phentsize);
2607 printf (_(" Number of program headers: %ld\n"),
2608 (long) elf_header.e_phnum);
2609 printf (_(" Size of section headers: %ld (bytes)\n"),
2610 (long) elf_header.e_shentsize);
560f3c1c 2611 printf (_(" Number of section headers: %ld"),
252b5132 2612 (long) elf_header.e_shnum);
560f3c1c
AM
2613 if (section_headers != NULL && elf_header.e_shnum == 0)
2614 printf (" (%ld)", (long) section_headers[0].sh_size);
2615 putc ('\n', stdout);
2616 printf (_(" Section header string table index: %ld"),
252b5132 2617 (long) elf_header.e_shstrndx);
560f3c1c
AM
2618 if (section_headers != NULL && elf_header.e_shstrndx == SHN_XINDEX)
2619 printf (" (%ld)", (long) section_headers[0].sh_link);
2620 putc ('\n', stdout);
2621 }
2622
2623 if (section_headers != NULL)
2624 {
2625 if (elf_header.e_shnum == 0)
2626 elf_header.e_shnum = section_headers[0].sh_size;
2627 if (elf_header.e_shstrndx == SHN_XINDEX)
2628 elf_header.e_shstrndx = section_headers[0].sh_link;
2629 free (section_headers);
2630 section_headers = NULL;
252b5132 2631 }
103f02d3 2632
9ea033b2
NC
2633 return 1;
2634}
2635
252b5132 2636
9ea033b2
NC
2637static int
2638get_32bit_program_headers (file, program_headers)
2639 FILE * file;
2640 Elf_Internal_Phdr * program_headers;
2641{
2642 Elf32_External_Phdr * phdrs;
2643 Elf32_External_Phdr * external;
2644 Elf32_Internal_Phdr * internal;
2645 unsigned int i;
103f02d3 2646
a6e9f9df
AM
2647 phdrs = ((Elf32_External_Phdr *)
2648 get_data (NULL, file, elf_header.e_phoff,
2649 elf_header.e_phentsize * elf_header.e_phnum,
2650 _("program headers")));
2651 if (!phdrs)
2652 return 0;
9ea033b2
NC
2653
2654 for (i = 0, internal = program_headers, external = phdrs;
2655 i < elf_header.e_phnum;
2656 i ++, internal ++, external ++)
252b5132 2657 {
9ea033b2
NC
2658 internal->p_type = BYTE_GET (external->p_type);
2659 internal->p_offset = BYTE_GET (external->p_offset);
2660 internal->p_vaddr = BYTE_GET (external->p_vaddr);
2661 internal->p_paddr = BYTE_GET (external->p_paddr);
2662 internal->p_filesz = BYTE_GET (external->p_filesz);
2663 internal->p_memsz = BYTE_GET (external->p_memsz);
2664 internal->p_flags = BYTE_GET (external->p_flags);
2665 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
2666 }
2667
9ea033b2
NC
2668 free (phdrs);
2669
252b5132
RH
2670 return 1;
2671}
2672
9ea033b2
NC
2673static int
2674get_64bit_program_headers (file, program_headers)
2675 FILE * file;
2676 Elf_Internal_Phdr * program_headers;
2677{
2678 Elf64_External_Phdr * phdrs;
2679 Elf64_External_Phdr * external;
2680 Elf64_Internal_Phdr * internal;
2681 unsigned int i;
103f02d3 2682
a6e9f9df
AM
2683 phdrs = ((Elf64_External_Phdr *)
2684 get_data (NULL, file, elf_header.e_phoff,
2685 elf_header.e_phentsize * elf_header.e_phnum,
2686 _("program headers")));
2687 if (!phdrs)
2688 return 0;
9ea033b2
NC
2689
2690 for (i = 0, internal = program_headers, external = phdrs;
2691 i < elf_header.e_phnum;
2692 i ++, internal ++, external ++)
2693 {
2694 internal->p_type = BYTE_GET (external->p_type);
2695 internal->p_flags = BYTE_GET (external->p_flags);
2696 internal->p_offset = BYTE_GET8 (external->p_offset);
2697 internal->p_vaddr = BYTE_GET8 (external->p_vaddr);
2698 internal->p_paddr = BYTE_GET8 (external->p_paddr);
2699 internal->p_filesz = BYTE_GET8 (external->p_filesz);
2700 internal->p_memsz = BYTE_GET8 (external->p_memsz);
2701 internal->p_align = BYTE_GET8 (external->p_align);
2702 }
2703
2704 free (phdrs);
2705
2706 return 1;
2707}
252b5132
RH
2708
2709static int
2710process_program_headers (file)
2711 FILE * file;
2712{
9ea033b2
NC
2713 Elf_Internal_Phdr * program_headers;
2714 Elf_Internal_Phdr * segment;
2715 unsigned int i;
252b5132
RH
2716
2717 if (elf_header.e_phnum == 0)
2718 {
2719 if (do_segments)
2720 printf (_("\nThere are no program headers in this file.\n"));
2721 return 1;
2722 }
2723
2724 if (do_segments && !do_header)
2725 {
f7a99963
NC
2726 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
2727 printf (_("Entry point "));
2728 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
2729 printf (_("\nThere are %d program headers, starting at offset "),
2730 elf_header.e_phnum);
2731 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
2732 printf ("\n");
252b5132
RH
2733 }
2734
9ea033b2
NC
2735 program_headers = (Elf_Internal_Phdr *) malloc
2736 (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
252b5132
RH
2737
2738 if (program_headers == NULL)
2739 {
2740 error (_("Out of memory\n"));
2741 return 0;
2742 }
2743
9ea033b2
NC
2744 if (is_32bit_elf)
2745 i = get_32bit_program_headers (file, program_headers);
2746 else
2747 i = get_64bit_program_headers (file, program_headers);
2748
2749 if (i == 0)
252b5132 2750 {
9ea033b2
NC
2751 free (program_headers);
2752 return 0;
252b5132 2753 }
103f02d3 2754
252b5132
RH
2755 if (do_segments)
2756 {
2757 printf
2758 (_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
76da6bbe 2759
f7a99963
NC
2760 if (is_32bit_elf)
2761 printf
2762 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
2763 else if (do_wide)
2764 printf
2765 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
2766 else
2767 {
2768 printf
2769 (_(" Type Offset VirtAddr PhysAddr\n"));
2770 printf
2771 (_(" FileSiz MemSiz Flags Align\n"));
2772 }
252b5132
RH
2773 }
2774
2775 loadaddr = -1;
2776 dynamic_addr = 0;
1b228002 2777 dynamic_size = 0;
252b5132
RH
2778
2779 for (i = 0, segment = program_headers;
2780 i < elf_header.e_phnum;
2781 i ++, segment ++)
2782 {
2783 if (do_segments)
2784 {
103f02d3 2785 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
2786
2787 if (is_32bit_elf)
2788 {
2789 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
2790 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
2791 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
2792 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
2793 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
2794 printf ("%c%c%c ",
2795 (segment->p_flags & PF_R ? 'R' : ' '),
2796 (segment->p_flags & PF_W ? 'W' : ' '),
2797 (segment->p_flags & PF_X ? 'E' : ' '));
2798 printf ("%#lx", (unsigned long) segment->p_align);
2799 }
d974e256
JJ
2800 else if (do_wide)
2801 {
2802 if ((unsigned long) segment->p_offset == segment->p_offset)
2803 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
2804 else
2805 {
2806 print_vma (segment->p_offset, FULL_HEX);
2807 putchar (' ');
2808 }
2809
2810 print_vma (segment->p_vaddr, FULL_HEX);
2811 putchar (' ');
2812 print_vma (segment->p_paddr, FULL_HEX);
2813 putchar (' ');
2814
2815 if ((unsigned long) segment->p_filesz == segment->p_filesz)
2816 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
2817 else
2818 {
2819 print_vma (segment->p_filesz, FULL_HEX);
2820 putchar (' ');
2821 }
2822
2823 if ((unsigned long) segment->p_memsz == segment->p_memsz)
2824 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
2825 else
2826 {
2827 print_vma (segment->p_offset, FULL_HEX);
2828 }
2829
2830 printf (" %c%c%c ",
2831 (segment->p_flags & PF_R ? 'R' : ' '),
2832 (segment->p_flags & PF_W ? 'W' : ' '),
2833 (segment->p_flags & PF_X ? 'E' : ' '));
2834
2835 if ((unsigned long) segment->p_align == segment->p_align)
2836 printf ("%#lx", (unsigned long) segment->p_align);
2837 else
2838 {
2839 print_vma (segment->p_align, PREFIX_HEX);
2840 }
2841 }
f7a99963
NC
2842 else
2843 {
2844 print_vma (segment->p_offset, FULL_HEX);
2845 putchar (' ');
2846 print_vma (segment->p_vaddr, FULL_HEX);
2847 putchar (' ');
2848 print_vma (segment->p_paddr, FULL_HEX);
2849 printf ("\n ");
2850 print_vma (segment->p_filesz, FULL_HEX);
2851 putchar (' ');
2852 print_vma (segment->p_memsz, FULL_HEX);
2853 printf (" %c%c%c ",
2854 (segment->p_flags & PF_R ? 'R' : ' '),
2855 (segment->p_flags & PF_W ? 'W' : ' '),
2856 (segment->p_flags & PF_X ? 'E' : ' '));
2857 print_vma (segment->p_align, HEX);
2858 }
252b5132
RH
2859 }
2860
2861 switch (segment->p_type)
2862 {
2863 case PT_LOAD:
2864 if (loadaddr == -1)
2865 loadaddr = (segment->p_vaddr & 0xfffff000)
2866 - (segment->p_offset & 0xfffff000);
2867 break;
2868
2869 case PT_DYNAMIC:
2870 if (dynamic_addr)
2871 error (_("more than one dynamic segment\n"));
2872
2873 dynamic_addr = segment->p_offset;
2874 dynamic_size = segment->p_filesz;
2875 break;
2876
2877 case PT_INTERP:
f7a99963 2878 if (fseek (file, (long) segment->p_offset, SEEK_SET))
252b5132
RH
2879 error (_("Unable to find program interpreter name\n"));
2880 else
2881 {
2882 program_interpreter[0] = 0;
2883 fscanf (file, "%63s", program_interpreter);
2884
2885 if (do_segments)
2886 printf (_("\n [Requesting program interpreter: %s]"),
2887 program_interpreter);
2888 }
2889 break;
2890 }
2891
2892 if (do_segments)
2893 putc ('\n', stdout);
2894 }
2895
2896 if (loadaddr == -1)
2897 {
e3c8793a 2898 /* Very strange. */
252b5132
RH
2899 loadaddr = 0;
2900 }
2901
2902 if (do_segments && section_headers != NULL)
2903 {
2904 printf (_("\n Section to Segment mapping:\n"));
2905 printf (_(" Segment Sections...\n"));
2906
2907 assert (string_table != NULL);
2908
2909 for (i = 0; i < elf_header.e_phnum; i++)
2910 {
9ad5cbcf 2911 unsigned int j;
9ea033b2 2912 Elf_Internal_Shdr * section;
252b5132
RH
2913
2914 segment = program_headers + i;
2915 section = section_headers;
2916
2917 printf (" %2.2d ", i);
2918
9ad5cbcf 2919 for (j = 1; j < elf_header.e_shnum; j++, section ++)
252b5132
RH
2920 {
2921 if (section->sh_size > 0
2922 /* Compare allocated sections by VMA, unallocated
2923 sections by file offset. */
2924 && (section->sh_flags & SHF_ALLOC
2925 ? (section->sh_addr >= segment->p_vaddr
2926 && section->sh_addr + section->sh_size
2927 <= segment->p_vaddr + segment->p_memsz)
b4c96d0d 2928 : ((bfd_vma) section->sh_offset >= segment->p_offset
252b5132
RH
2929 && (section->sh_offset + section->sh_size
2930 <= segment->p_offset + segment->p_filesz))))
2931 printf ("%s ", SECTION_NAME (section));
2932 }
2933
2934 putc ('\n',stdout);
2935 }
2936 }
2937
2938 free (program_headers);
2939
2940 return 1;
2941}
2942
2943
2944static int
560f3c1c 2945get_32bit_section_headers (file, num)
252b5132 2946 FILE * file;
560f3c1c 2947 unsigned int num;
252b5132
RH
2948{
2949 Elf32_External_Shdr * shdrs;
2950 Elf32_Internal_Shdr * internal;
2951 unsigned int i;
2952
a6e9f9df
AM
2953 shdrs = ((Elf32_External_Shdr *)
2954 get_data (NULL, file, elf_header.e_shoff,
560f3c1c 2955 elf_header.e_shentsize * num,
a6e9f9df
AM
2956 _("section headers")));
2957 if (!shdrs)
2958 return 0;
252b5132 2959
560f3c1c
AM
2960 section_headers = ((Elf_Internal_Shdr *)
2961 malloc (num * sizeof (Elf_Internal_Shdr)));
252b5132
RH
2962
2963 if (section_headers == NULL)
2964 {
2965 error (_("Out of memory\n"));
2966 return 0;
2967 }
2968
2969 for (i = 0, internal = section_headers;
560f3c1c 2970 i < num;
252b5132
RH
2971 i ++, internal ++)
2972 {
2973 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
2974 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
2975 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
2976 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
2977 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
2978 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
2979 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
2980 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
2981 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
2982 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
2983 }
2984
2985 free (shdrs);
2986
2987 return 1;
2988}
2989
9ea033b2 2990static int
560f3c1c 2991get_64bit_section_headers (file, num)
9ea033b2 2992 FILE * file;
560f3c1c 2993 unsigned int num;
9ea033b2
NC
2994{
2995 Elf64_External_Shdr * shdrs;
2996 Elf64_Internal_Shdr * internal;
2997 unsigned int i;
2998
a6e9f9df
AM
2999 shdrs = ((Elf64_External_Shdr *)
3000 get_data (NULL, file, elf_header.e_shoff,
560f3c1c 3001 elf_header.e_shentsize * num,
a6e9f9df
AM
3002 _("section headers")));
3003 if (!shdrs)
3004 return 0;
9ea033b2 3005
560f3c1c
AM
3006 section_headers = ((Elf_Internal_Shdr *)
3007 malloc (num * sizeof (Elf_Internal_Shdr)));
9ea033b2
NC
3008
3009 if (section_headers == NULL)
3010 {
3011 error (_("Out of memory\n"));
3012 return 0;
3013 }
3014
3015 for (i = 0, internal = section_headers;
560f3c1c 3016 i < num;
9ea033b2
NC
3017 i ++, internal ++)
3018 {
3019 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3020 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
3021 internal->sh_flags = BYTE_GET8 (shdrs[i].sh_flags);
3022 internal->sh_addr = BYTE_GET8 (shdrs[i].sh_addr);
3023 internal->sh_size = BYTE_GET8 (shdrs[i].sh_size);
3024 internal->sh_entsize = BYTE_GET8 (shdrs[i].sh_entsize);
3025 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3026 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3027 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3028 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3029 }
3030
3031 free (shdrs);
3032
3033 return 1;
3034}
3035
252b5132 3036static Elf_Internal_Sym *
9ad5cbcf 3037get_32bit_elf_symbols (file, section)
252b5132 3038 FILE * file;
9ad5cbcf 3039 Elf_Internal_Shdr *section;
252b5132 3040{
9ad5cbcf 3041 unsigned long number;
252b5132 3042 Elf32_External_Sym * esyms;
9ad5cbcf 3043 Elf_External_Sym_Shndx *shndx;
252b5132
RH
3044 Elf_Internal_Sym * isyms;
3045 Elf_Internal_Sym * psym;
3046 unsigned int j;
3047
a6e9f9df 3048 esyms = ((Elf32_External_Sym *)
9ad5cbcf
AM
3049 get_data (NULL, file, section->sh_offset,
3050 section->sh_size, _("symbols")));
a6e9f9df
AM
3051 if (!esyms)
3052 return NULL;
252b5132 3053
9ad5cbcf
AM
3054 shndx = NULL;
3055 if (symtab_shndx_hdr != NULL
3056 && (symtab_shndx_hdr->sh_link
3057 == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
3058 {
3059 shndx = ((Elf_External_Sym_Shndx *)
3060 get_data (NULL, file, symtab_shndx_hdr->sh_offset,
3061 symtab_shndx_hdr->sh_size, _("symtab shndx")));
3062 if (!shndx)
3063 {
3064 free (esyms);
3065 return NULL;
3066 }
3067 }
3068
3069 number = section->sh_size / section->sh_entsize;
252b5132
RH
3070 isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
3071
3072 if (isyms == NULL)
3073 {
3074 error (_("Out of memory\n"));
9ad5cbcf
AM
3075 if (shndx)
3076 free (shndx);
252b5132 3077 free (esyms);
252b5132
RH
3078 return NULL;
3079 }
3080
3081 for (j = 0, psym = isyms;
3082 j < number;
3083 j ++, psym ++)
3084 {
3085 psym->st_name = BYTE_GET (esyms[j].st_name);
3086 psym->st_value = BYTE_GET (esyms[j].st_value);
3087 psym->st_size = BYTE_GET (esyms[j].st_size);
3088 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
9ad5cbcf
AM
3089 if (psym->st_shndx == SHN_XINDEX && shndx != NULL)
3090 psym->st_shndx
3091 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
252b5132
RH
3092 psym->st_info = BYTE_GET (esyms[j].st_info);
3093 psym->st_other = BYTE_GET (esyms[j].st_other);
3094 }
3095
9ad5cbcf
AM
3096 if (shndx)
3097 free (shndx);
252b5132
RH
3098 free (esyms);
3099
3100 return isyms;
3101}
3102
9ea033b2 3103static Elf_Internal_Sym *
9ad5cbcf 3104get_64bit_elf_symbols (file, section)
9ea033b2 3105 FILE * file;
9ad5cbcf 3106 Elf_Internal_Shdr *section;
9ea033b2 3107{
9ad5cbcf 3108 unsigned long number;
9ea033b2 3109 Elf64_External_Sym * esyms;
9ad5cbcf 3110 Elf_External_Sym_Shndx *shndx;
9ea033b2
NC
3111 Elf_Internal_Sym * isyms;
3112 Elf_Internal_Sym * psym;
3113 unsigned int j;
3114
a6e9f9df 3115 esyms = ((Elf64_External_Sym *)
9ad5cbcf
AM
3116 get_data (NULL, file, section->sh_offset,
3117 section->sh_size, _("symbols")));
a6e9f9df
AM
3118 if (!esyms)
3119 return NULL;
9ea033b2 3120
9ad5cbcf
AM
3121 shndx = NULL;
3122 if (symtab_shndx_hdr != NULL
3123 && (symtab_shndx_hdr->sh_link
3124 == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
3125 {
3126 shndx = ((Elf_External_Sym_Shndx *)
3127 get_data (NULL, file, symtab_shndx_hdr->sh_offset,
3128 symtab_shndx_hdr->sh_size, _("symtab shndx")));
3129 if (!shndx)
3130 {
3131 free (esyms);
3132 return NULL;
3133 }
3134 }
3135
3136 number = section->sh_size / section->sh_entsize;
9ea033b2
NC
3137 isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
3138
3139 if (isyms == NULL)
3140 {
3141 error (_("Out of memory\n"));
9ad5cbcf
AM
3142 if (shndx)
3143 free (shndx);
9ea033b2 3144 free (esyms);
9ea033b2
NC
3145 return NULL;
3146 }
3147
3148 for (j = 0, psym = isyms;
3149 j < number;
3150 j ++, psym ++)
3151 {
3152 psym->st_name = BYTE_GET (esyms[j].st_name);
3153 psym->st_info = BYTE_GET (esyms[j].st_info);
3154 psym->st_other = BYTE_GET (esyms[j].st_other);
3155 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
9ad5cbcf
AM
3156 if (psym->st_shndx == SHN_XINDEX && shndx != NULL)
3157 psym->st_shndx
3158 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
9ea033b2
NC
3159 psym->st_value = BYTE_GET8 (esyms[j].st_value);
3160 psym->st_size = BYTE_GET8 (esyms[j].st_size);
3161 }
3162
9ad5cbcf
AM
3163 if (shndx)
3164 free (shndx);
9ea033b2
NC
3165 free (esyms);
3166
3167 return isyms;
3168}
3169
d1133906
NC
3170static const char *
3171get_elf_section_flags (sh_flags)
3172 bfd_vma sh_flags;
3173{
3174 static char buff [32];
3175
3176 * buff = 0;
76da6bbe 3177
d1133906
NC
3178 while (sh_flags)
3179 {
3180 bfd_vma flag;
3181
3182 flag = sh_flags & - sh_flags;
3183 sh_flags &= ~ flag;
76da6bbe 3184
d1133906
NC
3185 switch (flag)
3186 {
3187 case SHF_WRITE: strcat (buff, "W"); break;
3188 case SHF_ALLOC: strcat (buff, "A"); break;
3189 case SHF_EXECINSTR: strcat (buff, "X"); break;
3190 case SHF_MERGE: strcat (buff, "M"); break;
3191 case SHF_STRINGS: strcat (buff, "S"); break;
3192 case SHF_INFO_LINK: strcat (buff, "I"); break;
3193 case SHF_LINK_ORDER: strcat (buff, "L"); break;
3194 case SHF_OS_NONCONFORMING: strcat (buff, "O"); break;
93ebe586 3195 case SHF_GROUP: strcat (buff, "G"); break;
76da6bbe 3196
d1133906
NC
3197 default:
3198 if (flag & SHF_MASKOS)
3199 {
3200 strcat (buff, "o");
3201 sh_flags &= ~ SHF_MASKOS;
3202 }
3203 else if (flag & SHF_MASKPROC)
3204 {
3205 strcat (buff, "p");
3206 sh_flags &= ~ SHF_MASKPROC;
3207 }
3208 else
3209 strcat (buff, "x");
3210 break;
3211 }
3212 }
76da6bbe 3213
d1133906
NC
3214 return buff;
3215}
3216
252b5132
RH
3217static int
3218process_section_headers (file)
3219 FILE * file;
3220{
9ea033b2 3221 Elf_Internal_Shdr * section;
9ad5cbcf 3222 unsigned int i;
252b5132
RH
3223
3224 section_headers = NULL;
3225
3226 if (elf_header.e_shnum == 0)
3227 {
3228 if (do_sections)
3229 printf (_("\nThere are no sections in this file.\n"));
3230
3231 return 1;
3232 }
3233
3234 if (do_sections && !do_header)
9ea033b2 3235 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
3236 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
3237
9ea033b2
NC
3238 if (is_32bit_elf)
3239 {
560f3c1c 3240 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
3241 return 0;
3242 }
560f3c1c 3243 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
3244 return 0;
3245
3246 /* Read in the string table, so that we have names to display. */
9ad5cbcf 3247 section = SECTION_HEADER (elf_header.e_shstrndx);
252b5132
RH
3248
3249 if (section->sh_size != 0)
3250 {
a6e9f9df
AM
3251 string_table = (char *) get_data (NULL, file, section->sh_offset,
3252 section->sh_size, _("string table"));
d40ac9bd
NC
3253
3254 string_table_length = section->sh_size;
252b5132
RH
3255 }
3256
3257 /* Scan the sections for the dynamic symbol table
e3c8793a 3258 and dynamic string table and debug sections. */
252b5132
RH
3259 dynamic_symbols = NULL;
3260 dynamic_strings = NULL;
3261 dynamic_syminfo = NULL;
103f02d3 3262
252b5132
RH
3263 for (i = 0, section = section_headers;
3264 i < elf_header.e_shnum;
3265 i ++, section ++)
3266 {
3267 char * name = SECTION_NAME (section);
3268
3269 if (section->sh_type == SHT_DYNSYM)
3270 {
3271 if (dynamic_symbols != NULL)
3272 {
3273 error (_("File contains multiple dynamic symbol tables\n"));
3274 continue;
3275 }
3276
19936277 3277 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 3278 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
3279 }
3280 else if (section->sh_type == SHT_STRTAB
3281 && strcmp (name, ".dynstr") == 0)
3282 {
3283 if (dynamic_strings != NULL)
3284 {
3285 error (_("File contains multiple dynamic string tables\n"));
3286 continue;
3287 }
3288
a6e9f9df
AM
3289 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
3290 section->sh_size,
3291 _("dynamic strings"));
252b5132 3292 }
9ad5cbcf
AM
3293 else if (section->sh_type == SHT_SYMTAB_SHNDX)
3294 {
3295 if (symtab_shndx_hdr != NULL)
3296 {
3297 error (_("File contains multiple symtab shndx tables\n"));
3298 continue;
3299 }
3300 symtab_shndx_hdr = section;
3301 }
252b5132 3302 else if ((do_debugging || do_debug_info || do_debug_abbrevs
31b6fca6 3303 || do_debug_lines || do_debug_pubnames || do_debug_aranges
261a45ad 3304 || do_debug_frames || do_debug_macinfo || do_debug_str)
252b5132
RH
3305 && strncmp (name, ".debug_", 7) == 0)
3306 {
3307 name += 7;
3308
3309 if (do_debugging
3310 || (do_debug_info && (strcmp (name, "info") == 0))
3311 || (do_debug_abbrevs && (strcmp (name, "abbrev") == 0))
3312 || (do_debug_lines && (strcmp (name, "line") == 0))
3313 || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
3314 || (do_debug_aranges && (strcmp (name, "aranges") == 0))
c47d488e 3315 || (do_debug_frames && (strcmp (name, "frame") == 0))
e0c60db2 3316 || (do_debug_macinfo && (strcmp (name, "macinfo") == 0))
261a45ad 3317 || (do_debug_str && (strcmp (name, "str") == 0))
252b5132
RH
3318 )
3319 request_dump (i, DEBUG_DUMP);
3320 }
09fd7e38
JM
3321 /* linkonce section to be combined with .debug_info at link time. */
3322 else if ((do_debugging || do_debug_info)
3323 && strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
3324 request_dump (i, DEBUG_DUMP);
c47d488e
DD
3325 else if (do_debug_frames && strcmp (name, ".eh_frame") == 0)
3326 request_dump (i, DEBUG_DUMP);
252b5132
RH
3327 }
3328
3329 if (! do_sections)
3330 return 1;
3331
3332 printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
76da6bbe 3333
f7a99963
NC
3334 if (is_32bit_elf)
3335 printf
3336 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
d974e256
JJ
3337 else if (do_wide)
3338 printf
3339 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
f7a99963
NC
3340 else
3341 {
3342 printf (_(" [Nr] Name Type Address Offset\n"));
3343 printf (_(" Size EntSize Flags Link Info Align\n"));
3344 }
252b5132
RH
3345
3346 for (i = 0, section = section_headers;
3347 i < elf_header.e_shnum;
3348 i ++, section ++)
3349 {
9ad5cbcf
AM
3350 printf (" [%2u] %-17.17s %-15.15s ",
3351 SECTION_HEADER_NUM (i),
252b5132
RH
3352 SECTION_NAME (section),
3353 get_section_type_name (section->sh_type));
3354
f7a99963
NC
3355 if (is_32bit_elf)
3356 {
3357 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 3358
f7a99963
NC
3359 printf ( " %6.6lx %6.6lx %2.2lx",
3360 (unsigned long) section->sh_offset,
3361 (unsigned long) section->sh_size,
3362 (unsigned long) section->sh_entsize);
d1133906
NC
3363
3364 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 3365
93ebe586 3366 printf ("%2ld %3lx %2ld\n",
f7a99963
NC
3367 (unsigned long) section->sh_link,
3368 (unsigned long) section->sh_info,
3369 (unsigned long) section->sh_addralign);
3370 }
d974e256
JJ
3371 else if (do_wide)
3372 {
3373 print_vma (section->sh_addr, LONG_HEX);
3374
3375 if ((long) section->sh_offset == section->sh_offset)
3376 printf (" %6.6lx", (unsigned long) section->sh_offset);
3377 else
3378 {
3379 putchar (' ');
3380 print_vma (section->sh_offset, LONG_HEX);
3381 }
3382
3383 if ((unsigned long) section->sh_size == section->sh_size)
3384 printf (" %6.6lx", (unsigned long) section->sh_size);
3385 else
3386 {
3387 putchar (' ');
3388 print_vma (section->sh_size, LONG_HEX);
3389 }
3390
3391 if ((unsigned long) section->sh_entsize == section->sh_entsize)
3392 printf (" %2.2lx", (unsigned long) section->sh_entsize);
3393 else
3394 {
3395 putchar (' ');
3396 print_vma (section->sh_entsize, LONG_HEX);
3397 }
3398
3399 printf (" %3s ", get_elf_section_flags (section->sh_flags));
3400
3401 printf ("%2ld %3lx ",
3402 (unsigned long) section->sh_link,
3403 (unsigned long) section->sh_info);
3404
3405 if ((unsigned long) section->sh_addralign == section->sh_addralign)
3406 printf ("%2ld\n", (unsigned long) section->sh_addralign);
3407 else
3408 {
3409 print_vma (section->sh_addralign, DEC);
3410 putchar ('\n');
3411 }
3412 }
f7a99963
NC
3413 else
3414 {
3415 putchar (' ');
3416 print_vma (section->sh_addr, LONG_HEX);
d974e256
JJ
3417 if ((long) section->sh_offset == section->sh_offset)
3418 printf (" %8.8lx", (unsigned long) section->sh_offset);
3419 else
3420 {
3421 printf (" ");
3422 print_vma (section->sh_offset, LONG_HEX);
3423 }
f7a99963
NC
3424 printf ("\n ");
3425 print_vma (section->sh_size, LONG_HEX);
3426 printf (" ");
3427 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 3428
d1133906 3429 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 3430
f7a99963
NC
3431 printf (" %2ld %3lx %ld\n",
3432 (unsigned long) section->sh_link,
3433 (unsigned long) section->sh_info,
3434 (unsigned long) section->sh_addralign);
3435 }
252b5132
RH
3436 }
3437
e3c8793a
NC
3438 printf (_("Key to Flags:\n\
3439 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
3440 I (info), L (link order), G (group), x (unknown)\n\
3441 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
d1133906 3442
252b5132
RH
3443 return 1;
3444}
3445
3446/* Process the reloc section. */
3447static int
3448process_relocs (file)
3449 FILE * file;
3450{
3451 unsigned long rel_size;
3452 unsigned long rel_offset;
3453
3454
3455 if (!do_reloc)
3456 return 1;
3457
3458 if (do_using_dynamic)
3459 {
b4c96d0d 3460 int is_rela = FALSE;
9c19a809 3461
252b5132
RH
3462 rel_size = 0;
3463 rel_offset = 0;
3464
3465 if (dynamic_info[DT_REL])
3466 {
3467 rel_offset = dynamic_info[DT_REL];
3468 rel_size = dynamic_info[DT_RELSZ];
9c19a809 3469 is_rela = FALSE;
252b5132
RH
3470 }
3471 else if (dynamic_info [DT_RELA])
3472 {
3473 rel_offset = dynamic_info[DT_RELA];
3474 rel_size = dynamic_info[DT_RELASZ];
9c19a809 3475 is_rela = TRUE;
252b5132
RH
3476 }
3477 else if (dynamic_info[DT_JMPREL])
3478 {
3479 rel_offset = dynamic_info[DT_JMPREL];
3480 rel_size = dynamic_info[DT_PLTRELSZ];
103f02d3 3481
aa903cfb
AS
3482 switch (dynamic_info[DT_PLTREL])
3483 {
3484 case DT_REL:
3485 is_rela = FALSE;
3486 break;
3487 case DT_RELA:
3488 is_rela = TRUE;
3489 break;
3490 default:
3491 is_rela = UNKNOWN;
3492 break;
3493 }
252b5132
RH
3494 }
3495
3496 if (rel_size)
3497 {
3498 printf
3499 (_("\nRelocation section at offset 0x%lx contains %ld bytes:\n"),
3500 rel_offset, rel_size);
3501
3502 dump_relocations (file, rel_offset - loadaddr, rel_size,
19936277 3503 dynamic_symbols, num_dynamic_syms, dynamic_strings, is_rela);
252b5132
RH
3504 }
3505 else
3506 printf (_("\nThere are no dynamic relocations in this file.\n"));
3507 }
3508 else
3509 {
3510 Elf32_Internal_Shdr * section;
7036c0e1
AJ
3511 unsigned long i;
3512 int found = 0;
252b5132
RH
3513
3514 for (i = 0, section = section_headers;
3515 i < elf_header.e_shnum;
3516 i++, section ++)
3517 {
3518 if ( section->sh_type != SHT_RELA
3519 && section->sh_type != SHT_REL)
3520 continue;
3521
3522 rel_offset = section->sh_offset;
3523 rel_size = section->sh_size;
3524
3525 if (rel_size)
3526 {
3527 Elf32_Internal_Shdr * strsec;
252b5132
RH
3528 Elf_Internal_Sym * symtab;
3529 char * strtab;
9c19a809 3530 int is_rela;
19936277 3531 unsigned long nsyms;
103f02d3 3532
252b5132
RH
3533 printf (_("\nRelocation section "));
3534
3535 if (string_table == NULL)
19936277 3536 printf ("%d", section->sh_name);
252b5132 3537 else
19936277 3538 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
3539
3540 printf (_(" at offset 0x%lx contains %lu entries:\n"),
3541 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
3542
af3fc3bc
AM
3543 symtab = NULL;
3544 strtab = NULL;
3545 nsyms = 0;
3546 if (section->sh_link)
3547 {
3548 Elf32_Internal_Shdr * symsec;
252b5132 3549
9ad5cbcf 3550 symsec = SECTION_HEADER (section->sh_link);
af3fc3bc 3551 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 3552 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 3553
af3fc3bc
AM
3554 if (symtab == NULL)
3555 continue;
252b5132 3556
9ad5cbcf 3557 strsec = SECTION_HEADER (symsec->sh_link);
103f02d3 3558
a6e9f9df
AM
3559 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
3560 strsec->sh_size,
3561 _("string table"));
af3fc3bc 3562 }
aa903cfb 3563 is_rela = section->sh_type == SHT_RELA;
252b5132 3564
af3fc3bc
AM
3565 dump_relocations (file, rel_offset, rel_size,
3566 symtab, nsyms, strtab, is_rela);
252b5132 3567
af3fc3bc
AM
3568 if (strtab)
3569 free (strtab);
3570 if (symtab)
3571 free (symtab);
252b5132
RH
3572
3573 found = 1;
3574 }
3575 }
3576
3577 if (! found)
3578 printf (_("\nThere are no relocations in this file.\n"));
3579 }
3580
3581 return 1;
3582}
3583
4d6ed7c8
NC
3584#include "unwind-ia64.h"
3585
3586/* An absolute address consists of a section and an offset. If the
3587 section is NULL, the offset itself is the address, otherwise, the
3588 address equals to LOAD_ADDRESS(section) + offset. */
3589
3590struct absaddr
3591 {
3592 unsigned short section;
3593 bfd_vma offset;
3594 };
3595
3596struct unw_aux_info
3597 {
3598 struct unw_table_entry
3599 {
3600 struct absaddr start;
3601 struct absaddr end;
3602 struct absaddr info;
3603 }
3604 *table; /* Unwind table. */
3605 unsigned long table_len; /* Length of unwind table. */
ecd03389 3606 unsigned char * info; /* Unwind info. */
4d6ed7c8
NC
3607 unsigned long info_size; /* Size of unwind info. */
3608 bfd_vma info_addr; /* starting address of unwind info. */
3609 bfd_vma seg_base; /* Starting address of segment. */
3610 Elf_Internal_Sym * symtab; /* The symbol table. */
3611 unsigned long nsyms; /* Number of symbols. */
a59e3bd7 3612 char * strtab; /* The string table. */
4d6ed7c8
NC
3613 unsigned long strtab_size; /* Size of string table. */
3614 };
3615
3616static void find_symbol_for_address PARAMS ((struct unw_aux_info *,
3617 struct absaddr, const char **,
3618 bfd_vma *));
3619static void dump_ia64_unwind PARAMS ((struct unw_aux_info *));
f5e21966 3620static int slurp_ia64_unwind_table PARAMS ((FILE *, struct unw_aux_info *,
4d6ed7c8
NC
3621 Elf32_Internal_Shdr *));
3622
3623static void
3624find_symbol_for_address (aux, addr, symname, offset)
3625 struct unw_aux_info *aux;
3626 struct absaddr addr;
3627 const char **symname;
3628 bfd_vma *offset;
3629{
3630 bfd_vma dist = (bfd_vma) 0x100000;
3631 Elf_Internal_Sym *sym, *best = NULL;
3632 unsigned long i;
3633
3634 for (i = 0, sym = aux->symtab; i < aux->nsyms; ++i, ++sym)
3635 {
3636 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
3637 && sym->st_name != 0
3638 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
3639 && addr.offset >= sym->st_value
3640 && addr.offset - sym->st_value < dist)
3641 {
3642 best = sym;
3643 dist = addr.offset - sym->st_value;
3644 if (!dist)
3645 break;
3646 }
3647 }
3648 if (best)
3649 {
3650 *symname = (best->st_name >= aux->strtab_size
3651 ? "<corrupt>" : aux->strtab + best->st_name);
3652 *offset = dist;
3653 return;
3654 }
3655 *symname = NULL;
3656 *offset = addr.offset;
3657}
3658
3659static void
3660dump_ia64_unwind (aux)
3661 struct unw_aux_info *aux;
3662{
3663 bfd_vma addr_size;
3664 struct unw_table_entry * tp;
3665 int in_body;
7036c0e1 3666
4d6ed7c8
NC
3667 addr_size = is_32bit_elf ? 4 : 8;
3668
3669 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
3670 {
3671 bfd_vma stamp;
3672 bfd_vma offset;
3673 const unsigned char * dp;
3674 const unsigned char * head;
3675 const char * procname;
3676
3677 find_symbol_for_address (aux, tp->start, &procname, &offset);
3678
3679 fputs ("\n<", stdout);
3680
3681 if (procname)
3682 {
3683 fputs (procname, stdout);
3684
3685 if (offset)
3686 printf ("+%lx", (unsigned long) offset);
3687 }
3688
3689 fputs (">: [", stdout);
3690 print_vma (tp->start.offset, PREFIX_HEX);
3691 fputc ('-', stdout);
3692 print_vma (tp->end.offset, PREFIX_HEX);
3693 printf ("), info at +0x%lx\n",
3694 (unsigned long) (tp->info.offset - aux->seg_base));
3695
3696 head = aux->info + (tp->info.offset - aux->info_addr);
3697 stamp = BYTE_GET8 ((unsigned char *) head);
3698
3699 printf (" v%u, flags=0x%lx (%s%s ), len=%lu bytes\n",
3700 (unsigned) UNW_VER (stamp),
3701 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
3702 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
3703 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
3704 (unsigned long) (addr_size * UNW_LENGTH (stamp)));
3705
3706 if (UNW_VER (stamp) != 1)
3707 {
3708 printf ("\tUnknown version.\n");
3709 continue;
3710 }
3711
3712 in_body = 0;
3713 for (dp = head + 8; dp < head + 8 + addr_size * UNW_LENGTH (stamp);)
3714 dp = unw_decode (dp, in_body, & in_body);
3715 }
3716}
3717
3718static int
3719slurp_ia64_unwind_table (file, aux, sec)
3720 FILE *file;
3721 struct unw_aux_info *aux;
3722 Elf32_Internal_Shdr *sec;
3723{
3724 unsigned long size, addr_size, nrelas, i;
3725 Elf_Internal_Phdr *prog_hdrs, *seg;
3726 struct unw_table_entry *tep;
3727 Elf32_Internal_Shdr *relsec;
3728 Elf_Internal_Rela *rela, *rp;
3729 unsigned char *table, *tp;
3730 Elf_Internal_Sym *sym;
3731 const char *relname;
3732 int result;
3733
3734 addr_size = is_32bit_elf ? 4 : 8;
3735
3736 /* First, find the starting address of the segment that includes
3737 this section: */
3738
3739 if (elf_header.e_phnum)
3740 {
3741 prog_hdrs = (Elf_Internal_Phdr *)
3742 xmalloc (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
3743
3744 if (is_32bit_elf)
3745 result = get_32bit_program_headers (file, prog_hdrs);
3746 else
3747 result = get_64bit_program_headers (file, prog_hdrs);
3748
3749 if (!result)
3750 {
3751 free (prog_hdrs);
3752 return 0;
3753 }
3754
3755 for (seg = prog_hdrs; seg < prog_hdrs + elf_header.e_phnum; ++seg)
3756 {
3757 if (seg->p_type != PT_LOAD)
3758 continue;
3759
3760 if (sec->sh_addr >= seg->p_vaddr
3761 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
3762 {
3763 aux->seg_base = seg->p_vaddr;
3764 break;
3765 }
3766 }
3767
3768 free (prog_hdrs);
3769 }
3770
3771 /* Second, build the unwind table from the contents of the unwind section: */
3772 size = sec->sh_size;
a6e9f9df
AM
3773 table = (char *) get_data (NULL, file, sec->sh_offset,
3774 size, _("unwind table"));
3775 if (!table)
3776 return 0;
4d6ed7c8
NC
3777
3778 tep = aux->table = xmalloc (size / (3 * addr_size) * sizeof (aux->table[0]));
3779 for (tp = table; tp < table + size; tp += 3 * addr_size, ++ tep)
3780 {
3781 tep->start.section = SHN_UNDEF;
3782 tep->end.section = SHN_UNDEF;
3783 tep->info.section = SHN_UNDEF;
3784 if (is_32bit_elf)
3785 {
3786 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
3787 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
3788 tep->info.offset = byte_get ((unsigned char *) tp + 8, 4);
3789 }
3790 else
3791 {
3792 tep->start.offset = BYTE_GET8 ((unsigned char *) tp + 0);
3793 tep->end.offset = BYTE_GET8 ((unsigned char *) tp + 8);
3794 tep->info.offset = BYTE_GET8 ((unsigned char *) tp + 16);
3795 }
3796 tep->start.offset += aux->seg_base;
3797 tep->end.offset += aux->seg_base;
3798 tep->info.offset += aux->seg_base;
3799 }
3800 free (table);
3801
3802 /* Third, apply any relocations to the unwind table: */
3803
3804 for (relsec = section_headers;
3805 relsec < section_headers + elf_header.e_shnum;
3806 ++relsec)
3807 {
3808 if (relsec->sh_type != SHT_RELA
9ad5cbcf 3809 || SECTION_HEADER (relsec->sh_info) != sec)
4d6ed7c8
NC
3810 continue;
3811
3812 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
3813 & rela, & nrelas))
3814 return 0;
3815
3816 for (rp = rela; rp < rela + nrelas; ++rp)
3817 {
3818 if (is_32bit_elf)
3819 {
3820 relname = elf_ia64_reloc_type (ELF32_R_TYPE (rp->r_info));
3821 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
3822
3823 if (ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
3824 {
e5fb9629 3825 warn (_("Skipping unexpected symbol type %u\n"),
4d6ed7c8
NC
3826 ELF32_ST_TYPE (sym->st_info));
3827 continue;
3828 }
3829 }
3830 else
3831 {
3832 relname = elf_ia64_reloc_type (ELF64_R_TYPE (rp->r_info));
3833 sym = aux->symtab + ELF64_R_SYM (rp->r_info);
3834
3835 if (ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
3836 {
e5fb9629 3837 warn (_("Skipping unexpected symbol type %u\n"),
4d6ed7c8
NC
3838 ELF64_ST_TYPE (sym->st_info));
3839 continue;
3840 }
3841 }
3842
3843 if (strncmp (relname, "R_IA64_SEGREL", 13) != 0)
3844 {
e5fb9629 3845 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
3846 continue;
3847 }
3848
3849 i = rp->r_offset / (3 * addr_size);
3850
3851 switch (rp->r_offset/addr_size % 3)
3852 {
3853 case 0:
3854 aux->table[i].start.section = sym->st_shndx;
3855 aux->table[i].start.offset += rp->r_addend;
3856 break;
3857 case 1:
3858 aux->table[i].end.section = sym->st_shndx;
3859 aux->table[i].end.offset += rp->r_addend;
3860 break;
3861 case 2:
3862 aux->table[i].info.section = sym->st_shndx;
3863 aux->table[i].info.offset += rp->r_addend;
3864 break;
3865 default:
3866 break;
3867 }
3868 }
3869
3870 free (rela);
3871 }
3872
3873 aux->table_len = size / (3 * addr_size);
3874 return 1;
3875}
3876
3877static int
3878process_unwind (file)
3879 FILE * file;
3880{
3881 Elf32_Internal_Shdr *sec, *unwsec = NULL, *strsec;
579f31ac 3882 unsigned long i, addr_size, unwcount = 0, unwstart = 0;
4d6ed7c8
NC
3883 struct unw_aux_info aux;
3884
e58d53af
L
3885 if (!do_unwind)
3886 return 1;
3887
f1467e33
L
3888 if (elf_header.e_machine != EM_IA_64)
3889 {
3890 printf (_("\nThere are no unwind sections in this file.\n"));
3891 return 1;
3892 }
3893
4d6ed7c8
NC
3894 memset (& aux, 0, sizeof (aux));
3895
3896 addr_size = is_32bit_elf ? 4 : 8;
3897
4d6ed7c8
NC
3898 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
3899 {
3900 if (sec->sh_type == SHT_SYMTAB)
3901 {
3902 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 3903 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 3904
9ad5cbcf 3905 strsec = SECTION_HEADER (sec->sh_link);
4d6ed7c8 3906 aux.strtab_size = strsec->sh_size;
a6e9f9df
AM
3907 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
3908 aux.strtab_size, _("string table"));
4d6ed7c8
NC
3909 }
3910 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
3911 unwcount++;
3912 }
3913
3914 if (!unwcount)
3915 printf (_("\nThere are no unwind sections in this file.\n"));
3916
3917 while (unwcount-- > 0)
3918 {
3919 char *suffix;
3920 size_t len, len2;
3921
3922 for (i = unwstart, sec = section_headers + unwstart;
3923 i < elf_header.e_shnum; ++i, ++sec)
3924 if (sec->sh_type == SHT_IA_64_UNWIND)
3925 {
3926 unwsec = sec;
3927 break;
3928 }
3929
3930 unwstart = i + 1;
3931 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
3932
3933 if (strncmp (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once,
3934 len) == 0)
3935 {
3936 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO */
3937 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
3938 suffix = SECTION_NAME (unwsec) + len;
3939 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
3940 ++i, ++sec)
3941 if (strncmp (SECTION_NAME (sec),
3942 ELF_STRING_ia64_unwind_info_once, len2) == 0
3943 && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
3944 break;
3945 }
3946 else
3947 {
3948 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
3949 .IA_64.unwind or BAR -> .IA_64.unwind_info */
3950 len = sizeof (ELF_STRING_ia64_unwind) - 1;
3951 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
3952 suffix = "";
3953 if (strncmp (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind,
3954 len) == 0)
3955 suffix = SECTION_NAME (unwsec) + len;
3956 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
3957 ++i, ++sec)
3958 if (strncmp (SECTION_NAME (sec),
3959 ELF_STRING_ia64_unwind_info, len2) == 0
3960 && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
3961 break;
3962 }
3963
3964 if (i == elf_header.e_shnum)
3965 {
3966 printf (_("\nCould not find unwind info section for "));
3967
3968 if (string_table == NULL)
3969 printf ("%d", unwsec->sh_name);
3970 else
3971 printf ("'%s'", SECTION_NAME (unwsec));
3972 }
3973 else
4d6ed7c8
NC
3974 {
3975 aux.info_size = sec->sh_size;
3976 aux.info_addr = sec->sh_addr;
a6e9f9df
AM
3977 aux.info = (char *) get_data (NULL, file, sec->sh_offset,
3978 aux.info_size, _("unwind info"));
4d6ed7c8 3979
579f31ac 3980 printf (_("\nUnwind section "));
4d6ed7c8 3981
579f31ac
JJ
3982 if (string_table == NULL)
3983 printf ("%d", unwsec->sh_name);
3984 else
3985 printf ("'%s'", SECTION_NAME (unwsec));
4d6ed7c8 3986
579f31ac 3987 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 3988 (unsigned long) unwsec->sh_offset,
579f31ac 3989 (unsigned long) (unwsec->sh_size / (3 * addr_size)));
4d6ed7c8 3990
579f31ac 3991 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 3992
579f31ac
JJ
3993 if (aux.table_len > 0)
3994 dump_ia64_unwind (& aux);
3995
3996 if (aux.table)
3997 free ((char *) aux.table);
3998 if (aux.info)
3999 free ((char *) aux.info);
4000 aux.table = NULL;
4001 aux.info = NULL;
4002 }
4d6ed7c8 4003 }
4d6ed7c8 4004
4d6ed7c8
NC
4005 if (aux.symtab)
4006 free (aux.symtab);
4007 if (aux.strtab)
4008 free ((char *) aux.strtab);
4009
4010 return 1;
4011}
4012
252b5132
RH
4013static void
4014dynamic_segment_mips_val (entry)
4015 Elf_Internal_Dyn * entry;
4016{
4017 switch (entry->d_tag)
4018 {
4019 case DT_MIPS_FLAGS:
4020 if (entry->d_un.d_val == 0)
4021 printf ("NONE\n");
4022 else
4023 {
4024 static const char * opts[] =
4025 {
4026 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
4027 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
4028 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
4029 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
4030 "RLD_ORDER_SAFE"
4031 };
4032 unsigned int cnt;
4033 int first = 1;
4034 for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
4035 if (entry->d_un.d_val & (1 << cnt))
4036 {
4037 printf ("%s%s", first ? "" : " ", opts[cnt]);
4038 first = 0;
4039 }
4040 puts ("");
4041 }
4042 break;
103f02d3 4043
252b5132
RH
4044 case DT_MIPS_IVERSION:
4045 if (dynamic_strings != NULL)
4046 printf ("Interface Version: %s\n",
4047 dynamic_strings + entry->d_un.d_val);
4048 else
4049 printf ("%ld\n", (long) entry->d_un.d_ptr);
4050 break;
103f02d3 4051
252b5132
RH
4052 case DT_MIPS_TIME_STAMP:
4053 {
4054 char timebuf[20];
50da7a9c
NC
4055 struct tm * tmp;
4056
252b5132 4057 time_t time = entry->d_un.d_val;
50da7a9c
NC
4058 tmp = gmtime (&time);
4059 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
4060 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
4061 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
4062 printf ("Time Stamp: %s\n", timebuf);
4063 }
4064 break;
103f02d3 4065
252b5132
RH
4066 case DT_MIPS_RLD_VERSION:
4067 case DT_MIPS_LOCAL_GOTNO:
4068 case DT_MIPS_CONFLICTNO:
4069 case DT_MIPS_LIBLISTNO:
4070 case DT_MIPS_SYMTABNO:
4071 case DT_MIPS_UNREFEXTNO:
4072 case DT_MIPS_HIPAGENO:
4073 case DT_MIPS_DELTA_CLASS_NO:
4074 case DT_MIPS_DELTA_INSTANCE_NO:
4075 case DT_MIPS_DELTA_RELOC_NO:
4076 case DT_MIPS_DELTA_SYM_NO:
4077 case DT_MIPS_DELTA_CLASSSYM_NO:
4078 case DT_MIPS_COMPACT_SIZE:
4079 printf ("%ld\n", (long) entry->d_un.d_ptr);
4080 break;
103f02d3
UD
4081
4082 default:
4083 printf ("%#lx\n", (long) entry->d_un.d_ptr);
4084 }
4085}
4086
4087
4088static void
4089dynamic_segment_parisc_val (entry)
4090 Elf_Internal_Dyn * entry;
4091{
4092 switch (entry->d_tag)
4093 {
4094 case DT_HP_DLD_FLAGS:
4095 {
4096 static struct
4097 {
4098 long int bit;
5e220199
NC
4099 const char * str;
4100 }
4101 flags[] =
4102 {
4103 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
4104 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
4105 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
4106 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
4107 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
4108 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
4109 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
4110 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
4111 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
4112 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
4113 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" }
4114 };
103f02d3 4115 int first = 1;
5e220199 4116 size_t cnt;
f7a99963 4117 bfd_vma val = entry->d_un.d_val;
103f02d3
UD
4118
4119 for (cnt = 0; cnt < sizeof (flags) / sizeof (flags[0]); ++cnt)
4120 if (val & flags[cnt].bit)
30800947
NC
4121 {
4122 if (! first)
4123 putchar (' ');
4124 fputs (flags[cnt].str, stdout);
4125 first = 0;
4126 val ^= flags[cnt].bit;
4127 }
76da6bbe 4128
103f02d3 4129 if (val != 0 || first)
f7a99963
NC
4130 {
4131 if (! first)
4132 putchar (' ');
4133 print_vma (val, HEX);
4134 }
103f02d3
UD
4135 }
4136 break;
76da6bbe 4137
252b5132 4138 default:
f7a99963
NC
4139 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
4140 break;
252b5132
RH
4141 }
4142}
4143
252b5132 4144static int
9ea033b2 4145get_32bit_dynamic_segment (file)
252b5132
RH
4146 FILE * file;
4147{
9ea033b2
NC
4148 Elf32_External_Dyn * edyn;
4149 Elf_Internal_Dyn * entry;
4150 bfd_size_type i;
103f02d3 4151
a6e9f9df
AM
4152 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr,
4153 dynamic_size, _("dynamic segment"));
4154 if (!edyn)
4155 return 0;
103f02d3 4156
9ea033b2
NC
4157 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
4158 how large this .dynamic is now. We can do this even before the byte
4159 swapping since the DT_NULL tag is recognizable. */
4160 dynamic_size = 0;
4161 while (*(Elf32_Word *) edyn [dynamic_size++].d_tag != DT_NULL)
4162 ;
252b5132 4163
9ea033b2
NC
4164 dynamic_segment = (Elf_Internal_Dyn *)
4165 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
4166
4167 if (dynamic_segment == NULL)
252b5132 4168 {
9ea033b2
NC
4169 error (_("Out of memory\n"));
4170 free (edyn);
4171 return 0;
4172 }
252b5132 4173
9ea033b2
NC
4174 for (i = 0, entry = dynamic_segment;
4175 i < dynamic_size;
4176 i ++, entry ++)
4177 {
4178 entry->d_tag = BYTE_GET (edyn [i].d_tag);
4179 entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
252b5132
RH
4180 }
4181
9ea033b2
NC
4182 free (edyn);
4183
4184 return 1;
4185}
4186
4187static int
4188get_64bit_dynamic_segment (file)
4189 FILE * file;
4190{
4191 Elf64_External_Dyn * edyn;
4192 Elf_Internal_Dyn * entry;
4193 bfd_size_type i;
103f02d3 4194
a6e9f9df
AM
4195 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr,
4196 dynamic_size, _("dynamic segment"));
4197 if (!edyn)
4198 return 0;
103f02d3 4199
252b5132 4200 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
9ea033b2 4201 how large this .dynamic is now. We can do this even before the byte
252b5132
RH
4202 swapping since the DT_NULL tag is recognizable. */
4203 dynamic_size = 0;
9ea033b2 4204 while (*(bfd_vma *) edyn [dynamic_size ++].d_tag != DT_NULL)
252b5132
RH
4205 ;
4206
4207 dynamic_segment = (Elf_Internal_Dyn *)
4208 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
4209
4210 if (dynamic_segment == NULL)
4211 {
4212 error (_("Out of memory\n"));
4213 free (edyn);
4214 return 0;
4215 }
4216
4217 for (i = 0, entry = dynamic_segment;
4218 i < dynamic_size;
4219 i ++, entry ++)
4220 {
9ea033b2
NC
4221 entry->d_tag = BYTE_GET8 (edyn [i].d_tag);
4222 entry->d_un.d_val = BYTE_GET8 (edyn [i].d_un.d_val);
252b5132
RH
4223 }
4224
4225 free (edyn);
4226
9ea033b2
NC
4227 return 1;
4228}
4229
d1133906
NC
4230static const char *
4231get_dynamic_flags (flags)
4232 bfd_vma flags;
4233{
4234 static char buff [64];
4235 while (flags)
4236 {
4237 bfd_vma flag;
4238
4239 flag = flags & - flags;
4240 flags &= ~ flag;
4241
4242 switch (flag)
4243 {
4244 case DF_ORIGIN: strcat (buff, "ORIGIN "); break;
4245 case DF_SYMBOLIC: strcat (buff, "SYMBOLIC "); break;
4246 case DF_TEXTREL: strcat (buff, "TEXTREL "); break;
4247 case DF_BIND_NOW: strcat (buff, "BIND_NOW "); break;
305c7206 4248 default: strcat (buff, "unknown "); break;
d1133906
NC
4249 }
4250 }
305c7206 4251 return buff;
d1133906
NC
4252}
4253
9ea033b2
NC
4254/* Parse and display the contents of the dynamic segment. */
4255static int
4256process_dynamic_segment (file)
4257 FILE * file;
4258{
4259 Elf_Internal_Dyn * entry;
4260 bfd_size_type i;
4261
4262 if (dynamic_size == 0)
4263 {
4264 if (do_dynamic)
4265 printf (_("\nThere is no dynamic segment in this file.\n"));
4266
4267 return 1;
4268 }
4269
4270 if (is_32bit_elf)
4271 {
4272 if (! get_32bit_dynamic_segment (file))
4273 return 0;
4274 }
4275 else if (! get_64bit_dynamic_segment (file))
4276 return 0;
4277
252b5132
RH
4278 /* Find the appropriate symbol table. */
4279 if (dynamic_symbols == NULL)
4280 {
4281 for (i = 0, entry = dynamic_segment;
4282 i < dynamic_size;
4283 ++i, ++ entry)
4284 {
9ad5cbcf 4285 Elf32_Internal_Shdr section;
252b5132
RH
4286
4287 if (entry->d_tag != DT_SYMTAB)
4288 continue;
4289
4290 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
4291
4292 /* Since we do not know how big the symbol table is,
4293 we default to reading in the entire file (!) and
4294 processing that. This is overkill, I know, but it
e3c8793a 4295 should work. */
9ad5cbcf 4296 section.sh_offset = entry->d_un.d_val - loadaddr;
252b5132
RH
4297
4298 if (fseek (file, 0, SEEK_END))
4299 error (_("Unable to seek to end of file!"));
4300
9ad5cbcf 4301 section.sh_size = ftell (file) - section.sh_offset;
9ea033b2 4302 if (is_32bit_elf)
9ad5cbcf 4303 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 4304 else
9ad5cbcf 4305 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 4306
9ad5cbcf 4307 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 4308 if (num_dynamic_syms < 1)
252b5132
RH
4309 {
4310 error (_("Unable to determine the number of symbols to load\n"));
4311 continue;
4312 }
4313
9ad5cbcf 4314 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
4315 }
4316 }
4317
4318 /* Similarly find a string table. */
4319 if (dynamic_strings == NULL)
4320 {
4321 for (i = 0, entry = dynamic_segment;
4322 i < dynamic_size;
4323 ++i, ++ entry)
4324 {
4325 unsigned long offset;
4326 long str_tab_len;
4327
4328 if (entry->d_tag != DT_STRTAB)
4329 continue;
4330
4331 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
4332
4333 /* Since we do not know how big the string table is,
4334 we default to reading in the entire file (!) and
4335 processing that. This is overkill, I know, but it
e3c8793a 4336 should work. */
252b5132
RH
4337
4338 offset = entry->d_un.d_val - loadaddr;
4339 if (fseek (file, 0, SEEK_END))
4340 error (_("Unable to seek to end of file\n"));
4341 str_tab_len = ftell (file) - offset;
4342
4343 if (str_tab_len < 1)
4344 {
4345 error
4346 (_("Unable to determine the length of the dynamic string table\n"));
4347 continue;
4348 }
4349
a6e9f9df
AM
4350 dynamic_strings = (char *) get_data (NULL, file, offset, str_tab_len,
4351 _("dynamic string table"));
252b5132
RH
4352 break;
4353 }
4354 }
4355
4356 /* And find the syminfo section if available. */
4357 if (dynamic_syminfo == NULL)
4358 {
4359 unsigned int syminsz = 0;
4360
4361 for (i = 0, entry = dynamic_segment;
4362 i < dynamic_size;
4363 ++i, ++ entry)
4364 {
4365 if (entry->d_tag == DT_SYMINENT)
4366 {
4367 /* Note: these braces are necessary to avoid a syntax
4368 error from the SunOS4 C compiler. */
4369 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
4370 }
4371 else if (entry->d_tag == DT_SYMINSZ)
4372 syminsz = entry->d_un.d_val;
4373 else if (entry->d_tag == DT_SYMINFO)
4374 dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
4375 }
4376
4377 if (dynamic_syminfo_offset != 0 && syminsz != 0)
4378 {
9ea033b2
NC
4379 Elf_External_Syminfo * extsyminfo;
4380 Elf_Internal_Syminfo * syminfo;
252b5132
RH
4381
4382 /* There is a syminfo section. Read the data. */
a6e9f9df
AM
4383 extsyminfo = ((Elf_External_Syminfo *)
4384 get_data (NULL, file, dynamic_syminfo_offset,
4385 syminsz, _("symbol information")));
4386 if (!extsyminfo)
4387 return 0;
252b5132
RH
4388
4389 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
4390 if (dynamic_syminfo == NULL)
4391 {
4392 error (_("Out of memory\n"));
4393 return 0;
4394 }
4395
4396 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
4397 for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
4398 ++i, ++syminfo)
4399 {
4400 syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
4401 syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
4402 }
4403
4404 free (extsyminfo);
4405 }
4406 }
4407
4408 if (do_dynamic && dynamic_addr)
789be9f7
ILT
4409 printf (_("\nDynamic segment at offset 0x%x contains %ld entries:\n"),
4410 dynamic_addr, (long) dynamic_size);
252b5132
RH
4411 if (do_dynamic)
4412 printf (_(" Tag Type Name/Value\n"));
4413
4414 for (i = 0, entry = dynamic_segment;
4415 i < dynamic_size;
4416 i++, entry ++)
4417 {
4418 if (do_dynamic)
f7a99963 4419 {
f3485b74 4420 const char * dtype;
e699b9ff 4421
f7a99963
NC
4422 putchar (' ');
4423 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
4424 dtype = get_dynamic_type (entry->d_tag);
4425 printf (" (%s)%*s", dtype,
4426 ((is_32bit_elf ? 27 : 19)
4427 - (int) strlen (dtype)),
f7a99963
NC
4428 " ");
4429 }
252b5132
RH
4430
4431 switch (entry->d_tag)
4432 {
d1133906
NC
4433 case DT_FLAGS:
4434 if (do_dynamic)
305c7206 4435 printf ("%s", get_dynamic_flags (entry->d_un.d_val));
d1133906 4436 break;
76da6bbe 4437
252b5132
RH
4438 case DT_AUXILIARY:
4439 case DT_FILTER:
019148e4
L
4440 case DT_CONFIG:
4441 case DT_DEPAUDIT:
4442 case DT_AUDIT:
252b5132
RH
4443 if (do_dynamic)
4444 {
019148e4
L
4445 switch (entry->d_tag)
4446 {
4447 case DT_AUXILIARY:
4448 printf (_("Auxiliary library"));
4449 break;
4450
4451 case DT_FILTER:
4452 printf (_("Filter library"));
4453 break;
4454
4455 case DT_CONFIG:
4456 printf (_("Configuration file"));
4457 break;
4458
4459 case DT_DEPAUDIT:
4460 printf (_("Dependency audit library"));
4461 break;
4462
4463 case DT_AUDIT:
4464 printf (_("Audit library"));
4465 break;
4466 }
252b5132
RH
4467
4468 if (dynamic_strings)
4469 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
4470 else
f7a99963
NC
4471 {
4472 printf (": ");
4473 print_vma (entry->d_un.d_val, PREFIX_HEX);
4474 putchar ('\n');
4475 }
252b5132
RH
4476 }
4477 break;
4478
dcefbbbd 4479 case DT_FEATURE:
252b5132
RH
4480 if (do_dynamic)
4481 {
4482 printf (_("Flags:"));
4483 if (entry->d_un.d_val == 0)
4484 printf (_(" None\n"));
4485 else
4486 {
4487 unsigned long int val = entry->d_un.d_val;
4488 if (val & DTF_1_PARINIT)
4489 {
4490 printf (" PARINIT");
4491 val ^= DTF_1_PARINIT;
4492 }
dcefbbbd
L
4493 if (val & DTF_1_CONFEXP)
4494 {
4495 printf (" CONFEXP");
4496 val ^= DTF_1_CONFEXP;
4497 }
252b5132
RH
4498 if (val != 0)
4499 printf (" %lx", val);
4500 puts ("");
4501 }
4502 }
4503 break;
4504
4505 case DT_POSFLAG_1:
4506 if (do_dynamic)
4507 {
4508 printf (_("Flags:"));
4509 if (entry->d_un.d_val == 0)
4510 printf (_(" None\n"));
4511 else
4512 {
4513 unsigned long int val = entry->d_un.d_val;
4514 if (val & DF_P1_LAZYLOAD)
4515 {
4516 printf (" LAZYLOAD");
4517 val ^= DF_P1_LAZYLOAD;
4518 }
4519 if (val & DF_P1_GROUPPERM)
4520 {
4521 printf (" GROUPPERM");
4522 val ^= DF_P1_GROUPPERM;
4523 }
4524 if (val != 0)
4525 printf (" %lx", val);
4526 puts ("");
4527 }
4528 }
4529 break;
4530
4531 case DT_FLAGS_1:
4532 if (do_dynamic)
4533 {
4534 printf (_("Flags:"));
4535 if (entry->d_un.d_val == 0)
4536 printf (_(" None\n"));
4537 else
4538 {
4539 unsigned long int val = entry->d_un.d_val;
4540 if (val & DF_1_NOW)
4541 {
4542 printf (" NOW");
4543 val ^= DF_1_NOW;
4544 }
4545 if (val & DF_1_GLOBAL)
4546 {
4547 printf (" GLOBAL");
4548 val ^= DF_1_GLOBAL;
4549 }
4550 if (val & DF_1_GROUP)
4551 {
4552 printf (" GROUP");
4553 val ^= DF_1_GROUP;
4554 }
4555 if (val & DF_1_NODELETE)
4556 {
4557 printf (" NODELETE");
4558 val ^= DF_1_NODELETE;
4559 }
4560 if (val & DF_1_LOADFLTR)
4561 {
4562 printf (" LOADFLTR");
4563 val ^= DF_1_LOADFLTR;
4564 }
4565 if (val & DF_1_INITFIRST)
4566 {
4567 printf (" INITFIRST");
4568 val ^= DF_1_INITFIRST;
4569 }
4570 if (val & DF_1_NOOPEN)
4571 {
4572 printf (" NOOPEN");
4573 val ^= DF_1_NOOPEN;
4574 }
4575 if (val & DF_1_ORIGIN)
4576 {
4577 printf (" ORIGIN");
4578 val ^= DF_1_ORIGIN;
4579 }
4580 if (val & DF_1_DIRECT)
4581 {
4582 printf (" DIRECT");
4583 val ^= DF_1_DIRECT;
4584 }
4585 if (val & DF_1_TRANS)
4586 {
4587 printf (" TRANS");
4588 val ^= DF_1_TRANS;
4589 }
4590 if (val & DF_1_INTERPOSE)
4591 {
4592 printf (" INTERPOSE");
4593 val ^= DF_1_INTERPOSE;
4594 }
f7db6139 4595 if (val & DF_1_NODEFLIB)
dcefbbbd 4596 {
f7db6139
L
4597 printf (" NODEFLIB");
4598 val ^= DF_1_NODEFLIB;
dcefbbbd
L
4599 }
4600 if (val & DF_1_NODUMP)
4601 {
4602 printf (" NODUMP");
4603 val ^= DF_1_NODUMP;
4604 }
4605 if (val & DF_1_CONLFAT)
4606 {
4607 printf (" CONLFAT");
4608 val ^= DF_1_CONLFAT;
4609 }
252b5132
RH
4610 if (val != 0)
4611 printf (" %lx", val);
4612 puts ("");
4613 }
4614 }
4615 break;
4616
4617 case DT_PLTREL:
4618 if (do_dynamic)
4619 puts (get_dynamic_type (entry->d_un.d_val));
4620 break;
4621
4622 case DT_NULL :
4623 case DT_NEEDED :
4624 case DT_PLTGOT :
4625 case DT_HASH :
4626 case DT_STRTAB :
4627 case DT_SYMTAB :
4628 case DT_RELA :
4629 case DT_INIT :
4630 case DT_FINI :
4631 case DT_SONAME :
4632 case DT_RPATH :
4633 case DT_SYMBOLIC:
4634 case DT_REL :
4635 case DT_DEBUG :
4636 case DT_TEXTREL :
4637 case DT_JMPREL :
019148e4 4638 case DT_RUNPATH :
252b5132
RH
4639 dynamic_info[entry->d_tag] = entry->d_un.d_val;
4640
4641 if (do_dynamic)
4642 {
4643 char * name;
4644
4645 if (dynamic_strings == NULL)
4646 name = NULL;
4647 else
4648 name = dynamic_strings + entry->d_un.d_val;
4649
4650 if (name)
4651 {
4652 switch (entry->d_tag)
4653 {
4654 case DT_NEEDED:
4655 printf (_("Shared library: [%s]"), name);
4656
f7a99963
NC
4657 if (strcmp (name, program_interpreter) == 0)
4658 printf (_(" program interpreter"));
252b5132
RH
4659 break;
4660
4661 case DT_SONAME:
f7a99963 4662 printf (_("Library soname: [%s]"), name);
252b5132
RH
4663 break;
4664
4665 case DT_RPATH:
f7a99963 4666 printf (_("Library rpath: [%s]"), name);
252b5132
RH
4667 break;
4668
019148e4
L
4669 case DT_RUNPATH:
4670 printf (_("Library runpath: [%s]"), name);
4671 break;
4672
252b5132 4673 default:
f7a99963
NC
4674 print_vma (entry->d_un.d_val, PREFIX_HEX);
4675 break;
252b5132
RH
4676 }
4677 }
4678 else
f7a99963
NC
4679 print_vma (entry->d_un.d_val, PREFIX_HEX);
4680
4681 putchar ('\n');
252b5132
RH
4682 }
4683 break;
4684
4685 case DT_PLTRELSZ:
4686 case DT_RELASZ :
4687 case DT_STRSZ :
4688 case DT_RELSZ :
4689 case DT_RELAENT :
4690 case DT_SYMENT :
4691 case DT_RELENT :
4692 case DT_PLTPADSZ:
4693 case DT_MOVEENT :
4694 case DT_MOVESZ :
4695 case DT_INIT_ARRAYSZ:
4696 case DT_FINI_ARRAYSZ:
4697 if (do_dynamic)
f7a99963
NC
4698 {
4699 print_vma (entry->d_un.d_val, UNSIGNED);
4700 printf (" (bytes)\n");
4701 }
252b5132
RH
4702 break;
4703
4704 case DT_VERDEFNUM:
4705 case DT_VERNEEDNUM:
4706 case DT_RELACOUNT:
4707 case DT_RELCOUNT:
4708 if (do_dynamic)
f7a99963
NC
4709 {
4710 print_vma (entry->d_un.d_val, UNSIGNED);
4711 putchar ('\n');
4712 }
252b5132
RH
4713 break;
4714
4715 case DT_SYMINSZ:
4716 case DT_SYMINENT:
4717 case DT_SYMINFO:
4718 case DT_USED:
4719 case DT_INIT_ARRAY:
4720 case DT_FINI_ARRAY:
4721 if (do_dynamic)
4722 {
4723 if (dynamic_strings != NULL && entry->d_tag == DT_USED)
4724 {
4725 char * name;
4726
4727 name = dynamic_strings + entry->d_un.d_val;
4728
4729 if (* name)
4730 {
4731 printf (_("Not needed object: [%s]\n"), name);
4732 break;
4733 }
4734 }
103f02d3 4735
f7a99963
NC
4736 print_vma (entry->d_un.d_val, PREFIX_HEX);
4737 putchar ('\n');
252b5132
RH
4738 }
4739 break;
4740
4741 case DT_BIND_NOW:
4742 /* The value of this entry is ignored. */
4743 break;
103f02d3 4744
252b5132
RH
4745 default:
4746 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
4747 version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
4748 entry->d_un.d_val;
4749
4750 if (do_dynamic)
4751 {
4752 switch (elf_header.e_machine)
4753 {
4754 case EM_MIPS:
4fe85591 4755 case EM_MIPS_RS3_LE:
252b5132
RH
4756 dynamic_segment_mips_val (entry);
4757 break;
103f02d3
UD
4758 case EM_PARISC:
4759 dynamic_segment_parisc_val (entry);
4760 break;
252b5132 4761 default:
f7a99963
NC
4762 print_vma (entry->d_un.d_val, PREFIX_HEX);
4763 putchar ('\n');
252b5132
RH
4764 }
4765 }
4766 break;
4767 }
4768 }
4769
4770 return 1;
4771}
4772
4773static char *
4774get_ver_flags (flags)
4775 unsigned int flags;
4776{
4777 static char buff [32];
4778
4779 buff[0] = 0;
4780
4781 if (flags == 0)
4782 return _("none");
4783
4784 if (flags & VER_FLG_BASE)
4785 strcat (buff, "BASE ");
4786
4787 if (flags & VER_FLG_WEAK)
4788 {
4789 if (flags & VER_FLG_BASE)
4790 strcat (buff, "| ");
4791
4792 strcat (buff, "WEAK ");
4793 }
4794
4795 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
4796 strcat (buff, "| <unknown>");
4797
4798 return buff;
4799}
4800
4801/* Display the contents of the version sections. */
4802static int
4803process_version_sections (file)
4804 FILE * file;
4805{
4806 Elf32_Internal_Shdr * section;
4807 unsigned i;
4808 int found = 0;
4809
4810 if (! do_version)
4811 return 1;
4812
4813 for (i = 0, section = section_headers;
4814 i < elf_header.e_shnum;
4815 i++, section ++)
4816 {
4817 switch (section->sh_type)
4818 {
4819 case SHT_GNU_verdef:
4820 {
4821 Elf_External_Verdef * edefs;
4822 unsigned int idx;
4823 unsigned int cnt;
4824
4825 found = 1;
4826
4827 printf
4828 (_("\nVersion definition section '%s' contains %ld entries:\n"),
4829 SECTION_NAME (section), section->sh_info);
4830
4831 printf (_(" Addr: 0x"));
4832 printf_vma (section->sh_addr);
4833 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 4834 (unsigned long) section->sh_offset, section->sh_link,
9ad5cbcf 4835 SECTION_NAME (SECTION_HEADER (section->sh_link)));
252b5132 4836
a6e9f9df
AM
4837 edefs = ((Elf_External_Verdef *)
4838 get_data (NULL, file, section->sh_offset,
4839 section->sh_size,
4840 _("version definition section")));
4841 if (!edefs)
4842 break;
252b5132
RH
4843
4844 for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
4845 {
4846 char * vstart;
4847 Elf_External_Verdef * edef;
4848 Elf_Internal_Verdef ent;
4849 Elf_External_Verdaux * eaux;
4850 Elf_Internal_Verdaux aux;
4851 int j;
4852 int isum;
103f02d3 4853
252b5132
RH
4854 vstart = ((char *) edefs) + idx;
4855
4856 edef = (Elf_External_Verdef *) vstart;
4857
4858 ent.vd_version = BYTE_GET (edef->vd_version);
4859 ent.vd_flags = BYTE_GET (edef->vd_flags);
4860 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
4861 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
4862 ent.vd_hash = BYTE_GET (edef->vd_hash);
4863 ent.vd_aux = BYTE_GET (edef->vd_aux);
4864 ent.vd_next = BYTE_GET (edef->vd_next);
4865
4866 printf (_(" %#06x: Rev: %d Flags: %s"),
4867 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
4868
4869 printf (_(" Index: %d Cnt: %d "),
4870 ent.vd_ndx, ent.vd_cnt);
4871
4872 vstart += ent.vd_aux;
4873
4874 eaux = (Elf_External_Verdaux *) vstart;
4875
4876 aux.vda_name = BYTE_GET (eaux->vda_name);
4877 aux.vda_next = BYTE_GET (eaux->vda_next);
4878
4879 if (dynamic_strings)
4880 printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
4881 else
4882 printf (_("Name index: %ld\n"), aux.vda_name);
4883
4884 isum = idx + ent.vd_aux;
4885
4886 for (j = 1; j < ent.vd_cnt; j ++)
4887 {
4888 isum += aux.vda_next;
4889 vstart += aux.vda_next;
4890
4891 eaux = (Elf_External_Verdaux *) vstart;
4892
4893 aux.vda_name = BYTE_GET (eaux->vda_name);
4894 aux.vda_next = BYTE_GET (eaux->vda_next);
4895
4896 if (dynamic_strings)
4897 printf (_(" %#06x: Parent %d: %s\n"),
4898 isum, j, dynamic_strings + aux.vda_name);
4899 else
4900 printf (_(" %#06x: Parent %d, name index: %ld\n"),
4901 isum, j, aux.vda_name);
4902 }
4903
4904 idx += ent.vd_next;
4905 }
4906
4907 free (edefs);
4908 }
4909 break;
103f02d3 4910
252b5132
RH
4911 case SHT_GNU_verneed:
4912 {
4913 Elf_External_Verneed * eneed;
4914 unsigned int idx;
4915 unsigned int cnt;
4916
4917 found = 1;
4918
4919 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
4920 SECTION_NAME (section), section->sh_info);
4921
4922 printf (_(" Addr: 0x"));
4923 printf_vma (section->sh_addr);
4924 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
1b228002 4925 (unsigned long) section->sh_offset, section->sh_link,
9ad5cbcf 4926 SECTION_NAME (SECTION_HEADER (section->sh_link)));
252b5132 4927
a6e9f9df
AM
4928 eneed = ((Elf_External_Verneed *)
4929 get_data (NULL, file, section->sh_offset,
4930 section->sh_size, _("version need section")));
4931 if (!eneed)
4932 break;
252b5132
RH
4933
4934 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
4935 {
4936 Elf_External_Verneed * entry;
4937 Elf_Internal_Verneed ent;
4938 int j;
4939 int isum;
4940 char * vstart;
4941
4942 vstart = ((char *) eneed) + idx;
4943
4944 entry = (Elf_External_Verneed *) vstart;
4945
4946 ent.vn_version = BYTE_GET (entry->vn_version);
4947 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
4948 ent.vn_file = BYTE_GET (entry->vn_file);
4949 ent.vn_aux = BYTE_GET (entry->vn_aux);
4950 ent.vn_next = BYTE_GET (entry->vn_next);
4951
4952 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
4953
4954 if (dynamic_strings)
4955 printf (_(" File: %s"), dynamic_strings + ent.vn_file);
4956 else
4957 printf (_(" File: %lx"), ent.vn_file);
4958
4959 printf (_(" Cnt: %d\n"), ent.vn_cnt);
4960
4961 vstart += ent.vn_aux;
4962
4963 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
4964 {
4965 Elf_External_Vernaux * eaux;
4966 Elf_Internal_Vernaux aux;
4967
4968 eaux = (Elf_External_Vernaux *) vstart;
4969
4970 aux.vna_hash = BYTE_GET (eaux->vna_hash);
4971 aux.vna_flags = BYTE_GET (eaux->vna_flags);
4972 aux.vna_other = BYTE_GET (eaux->vna_other);
4973 aux.vna_name = BYTE_GET (eaux->vna_name);
4974 aux.vna_next = BYTE_GET (eaux->vna_next);
4975
4976 if (dynamic_strings)
4977 printf (_(" %#06x: Name: %s"),
4978 isum, dynamic_strings + aux.vna_name);
4979 else
4980 printf (_(" %#06x: Name index: %lx"),
4981 isum, aux.vna_name);
4982
4983 printf (_(" Flags: %s Version: %d\n"),
4984 get_ver_flags (aux.vna_flags), aux.vna_other);
4985
4986 isum += aux.vna_next;
4987 vstart += aux.vna_next;
4988 }
4989
4990 idx += ent.vn_next;
4991 }
103f02d3 4992
252b5132
RH
4993 free (eneed);
4994 }
4995 break;
4996
4997 case SHT_GNU_versym:
4998 {
4999 Elf32_Internal_Shdr * link_section;
261a45ad
NC
5000 int total;
5001 int cnt;
5002 unsigned char * edata;
5003 unsigned short * data;
5004 char * strtab;
5005 Elf_Internal_Sym * symbols;
252b5132
RH
5006 Elf32_Internal_Shdr * string_sec;
5007
9ad5cbcf 5008 link_section = SECTION_HEADER (section->sh_link);
252b5132
RH
5009 total = section->sh_size / section->sh_entsize;
5010
5011 found = 1;
5012
9ad5cbcf 5013 symbols = GET_ELF_SYMBOLS (file, link_section);
252b5132 5014
9ad5cbcf 5015 string_sec = SECTION_HEADER (link_section->sh_link);
252b5132 5016
a6e9f9df
AM
5017 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
5018 string_sec->sh_size,
5019 _("version string table"));
5020 if (!strtab)
5021 break;
252b5132
RH
5022
5023 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
5024 SECTION_NAME (section), total);
5025
5026 printf (_(" Addr: "));
5027 printf_vma (section->sh_addr);
5028 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 5029 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
5030 SECTION_NAME (link_section));
5031
a6e9f9df
AM
5032 edata =
5033 ((unsigned char *)
5034 get_data (NULL, file,
5035 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] - loadaddr,
5036 total * sizeof (short), _("version symbol data")));
5037 if (!edata)
5038 {
5039 free (strtab);
5040 break;
5041 }
252b5132
RH
5042
5043 data = (unsigned short *) malloc (total * sizeof (short));
5044
5045 for (cnt = total; cnt --;)
5046 data [cnt] = byte_get (edata + cnt * sizeof (short),
5047 sizeof (short));
5048
5049 free (edata);
5050
5051 for (cnt = 0; cnt < total; cnt += 4)
5052 {
5053 int j, nn;
00d93f34 5054 int check_def, check_need;
f3485b74 5055 char * name;
252b5132
RH
5056
5057 printf (" %03x:", cnt);
5058
5059 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
5060 switch (data [cnt + j])
5061 {
5062 case 0:
5063 fputs (_(" 0 (*local*) "), stdout);
5064 break;
5065
5066 case 1:
5067 fputs (_(" 1 (*global*) "), stdout);
5068 break;
5069
5070 default:
5071 nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
5072 data [cnt + j] & 0x8000 ? 'h' : ' ');
5073
00d93f34
JJ
5074 check_def = 1;
5075 check_need = 1;
9ad5cbcf 5076 if (SECTION_HEADER (symbols [cnt + j].st_shndx)->sh_type
00d93f34 5077 != SHT_NOBITS)
252b5132 5078 {
00d93f34
JJ
5079 if (symbols [cnt + j].st_shndx == SHN_UNDEF)
5080 check_def = 0;
5081 else
5082 check_need = 0;
252b5132 5083 }
00d93f34
JJ
5084
5085 if (check_need
5086 && version_info [DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132
RH
5087 {
5088 Elf_Internal_Verneed ivn;
5089 unsigned long offset;
5090
5091 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
5092 - loadaddr;
5093
5094 do
5095 {
dd27201e 5096 Elf_Internal_Vernaux ivna;
252b5132
RH
5097 Elf_External_Verneed evn;
5098 Elf_External_Vernaux evna;
dd27201e 5099 unsigned long a_off;
252b5132 5100
a6e9f9df
AM
5101 get_data (&evn, file, offset, sizeof (evn),
5102 _("version need"));
252b5132
RH
5103
5104 ivn.vn_aux = BYTE_GET (evn.vn_aux);
5105 ivn.vn_next = BYTE_GET (evn.vn_next);
5106
5107 a_off = offset + ivn.vn_aux;
5108
5109 do
5110 {
a6e9f9df
AM
5111 get_data (&evna, file, a_off, sizeof (evna),
5112 _("version need aux (2)"));
252b5132
RH
5113
5114 ivna.vna_next = BYTE_GET (evna.vna_next);
5115 ivna.vna_other = BYTE_GET (evna.vna_other);
5116
5117 a_off += ivna.vna_next;
5118 }
5119 while (ivna.vna_other != data [cnt + j]
5120 && ivna.vna_next != 0);
5121
5122 if (ivna.vna_other == data [cnt + j])
5123 {
5124 ivna.vna_name = BYTE_GET (evna.vna_name);
5125
16062207 5126 name = strtab + ivna.vna_name;
252b5132 5127 nn += printf ("(%s%-*s",
16062207
ILT
5128 name,
5129 12 - (int) strlen (name),
252b5132 5130 ")");
00d93f34 5131 check_def = 0;
252b5132
RH
5132 break;
5133 }
5134
5135 offset += ivn.vn_next;
5136 }
5137 while (ivn.vn_next);
5138 }
00d93f34
JJ
5139
5140 if (check_def && data [cnt + j] != 0x8001
5141 && version_info [DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132
RH
5142 {
5143 Elf_Internal_Verdef ivd;
5144 Elf_External_Verdef evd;
5145 unsigned long offset;
5146
5147 offset = version_info
5148 [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
5149
5150 do
5151 {
a6e9f9df
AM
5152 get_data (&evd, file, offset, sizeof (evd),
5153 _("version def"));
252b5132
RH
5154
5155 ivd.vd_next = BYTE_GET (evd.vd_next);
5156 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
5157
5158 offset += ivd.vd_next;
5159 }
5160 while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
5161 && ivd.vd_next != 0);
5162
5163 if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
5164 {
5165 Elf_External_Verdaux evda;
5166 Elf_Internal_Verdaux ivda;
5167
5168 ivd.vd_aux = BYTE_GET (evd.vd_aux);
5169
a6e9f9df
AM
5170 get_data (&evda, file,
5171 offset - ivd.vd_next + ivd.vd_aux,
5172 sizeof (evda), _("version def aux"));
252b5132
RH
5173
5174 ivda.vda_name = BYTE_GET (evda.vda_name);
5175
16062207 5176 name = strtab + ivda.vda_name;
252b5132 5177 nn += printf ("(%s%-*s",
16062207
ILT
5178 name,
5179 12 - (int) strlen (name),
252b5132
RH
5180 ")");
5181 }
5182 }
5183
5184 if (nn < 18)
5185 printf ("%*c", 18 - nn, ' ');
5186 }
5187
5188 putchar ('\n');
5189 }
5190
5191 free (data);
5192 free (strtab);
5193 free (symbols);
5194 }
5195 break;
103f02d3 5196
252b5132
RH
5197 default:
5198 break;
5199 }
5200 }
5201
5202 if (! found)
5203 printf (_("\nNo version information found in this file.\n"));
5204
5205 return 1;
5206}
5207
d1133906 5208static const char *
252b5132
RH
5209get_symbol_binding (binding)
5210 unsigned int binding;
5211{
5212 static char buff [32];
5213
5214 switch (binding)
5215 {
103f02d3
UD
5216 case STB_LOCAL: return "LOCAL";
5217 case STB_GLOBAL: return "GLOBAL";
5218 case STB_WEAK: return "WEAK";
252b5132
RH
5219 default:
5220 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
5221 sprintf (buff, _("<processor specific>: %d"), binding);
5222 else if (binding >= STB_LOOS && binding <= STB_HIOS)
5223 sprintf (buff, _("<OS specific>: %d"), binding);
5224 else
5225 sprintf (buff, _("<unknown>: %d"), binding);
5226 return buff;
5227 }
5228}
5229
d1133906 5230static const char *
252b5132
RH
5231get_symbol_type (type)
5232 unsigned int type;
5233{
5234 static char buff [32];
5235
5236 switch (type)
5237 {
103f02d3
UD
5238 case STT_NOTYPE: return "NOTYPE";
5239 case STT_OBJECT: return "OBJECT";
5240 case STT_FUNC: return "FUNC";
5241 case STT_SECTION: return "SECTION";
5242 case STT_FILE: return "FILE";
d1133906 5243 case STT_COMMON: return "COMMON";
252b5132
RH
5244 default:
5245 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
5246 {
5247 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
5248 return "THUMB_FUNC";
5249
351b4b40 5250 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
5251 return "REGISTER";
5252
5253 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
5254 return "PARISC_MILLI";
5255
df75f1af
NC
5256 sprintf (buff, _("<processor specific>: %d"), type);
5257 }
252b5132 5258 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
5259 {
5260 if (elf_header.e_machine == EM_PARISC)
5261 {
5262 if (type == STT_HP_OPAQUE)
5263 return "HP_OPAQUE";
5264 if (type == STT_HP_STUB)
5265 return "HP_STUB";
5266 }
5267
5268 sprintf (buff, _("<OS specific>: %d"), type);
5269 }
252b5132
RH
5270 else
5271 sprintf (buff, _("<unknown>: %d"), type);
5272 return buff;
5273 }
5274}
5275
d1133906
NC
5276static const char *
5277get_symbol_visibility (visibility)
5278 unsigned int visibility;
5279{
5280 switch (visibility)
5281 {
5282 case STV_DEFAULT: return "DEFAULT";
5283 case STV_INTERNAL: return "INTERNAL";
5284 case STV_HIDDEN: return "HIDDEN";
5285 case STV_PROTECTED: return "PROTECTED";
5286 default: abort ();
5287 }
5288}
5289
5290static const char *
252b5132
RH
5291get_symbol_index_type (type)
5292 unsigned int type;
5293{
5294 switch (type)
5295 {
5296 case SHN_UNDEF: return "UND";
5297 case SHN_ABS: return "ABS";
5298 case SHN_COMMON: return "COM";
5299 default:
5300 if (type >= SHN_LOPROC && type <= SHN_HIPROC)
5301 return "PRC";
252b5132
RH
5302 else if (type >= SHN_LOOS && type <= SHN_HIOS)
5303 return "OS ";
9ad5cbcf
AM
5304 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
5305 return "RSV";
252b5132
RH
5306 else
5307 {
5308 static char buff [32];
5309
5310 sprintf (buff, "%3d", type);
5311 return buff;
5312 }
5313 }
5314}
5315
252b5132
RH
5316static int *
5317get_dynamic_data (file, number)
5318 FILE * file;
5319 unsigned int number;
5320{
3c9f43b1 5321 unsigned char * e_data;
252b5132
RH
5322 int * i_data;
5323
3c9f43b1 5324 e_data = (unsigned char *) malloc (number * 4);
252b5132
RH
5325
5326 if (e_data == NULL)
5327 {
5328 error (_("Out of memory\n"));
5329 return NULL;
5330 }
5331
5332 if (fread (e_data, 4, number, file) != number)
5333 {
5334 error (_("Unable to read in dynamic data\n"));
5335 return NULL;
5336 }
5337
5338 i_data = (int *) malloc (number * sizeof (* i_data));
5339
5340 if (i_data == NULL)
5341 {
5342 error (_("Out of memory\n"));
5343 free (e_data);
5344 return NULL;
5345 }
5346
5347 while (number--)
5348 i_data [number] = byte_get (e_data + number * 4, 4);
5349
5350 free (e_data);
5351
5352 return i_data;
5353}
5354
e3c8793a 5355/* Dump the symbol table. */
252b5132
RH
5356static int
5357process_symbol_table (file)
5358 FILE * file;
5359{
5360 Elf32_Internal_Shdr * section;
3c9f43b1
AM
5361 unsigned char nb [4];
5362 unsigned char nc [4];
b4c96d0d 5363 int nbuckets = 0;
5e220199 5364 int nchains = 0;
252b5132
RH
5365 int * buckets = NULL;
5366 int * chains = NULL;
5367
5368 if (! do_syms && !do_histogram)
5369 return 1;
5370
5371 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
5372 || do_histogram))
5373 {
5374 if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
5375 {
5376 error (_("Unable to seek to start of dynamic information"));
5377 return 0;
5378 }
5379
5380 if (fread (nb, sizeof (nb), 1, file) != 1)
5381 {
5382 error (_("Failed to read in number of buckets\n"));
5383 return 0;
5384 }
5385
5386 if (fread (nc, sizeof (nc), 1, file) != 1)
5387 {
5388 error (_("Failed to read in number of chains\n"));
5389 return 0;
5390 }
5391
5392 nbuckets = byte_get (nb, 4);
5393 nchains = byte_get (nc, 4);
5394
5395 buckets = get_dynamic_data (file, nbuckets);
5396 chains = get_dynamic_data (file, nchains);
5397
5398 if (buckets == NULL || chains == NULL)
5399 return 0;
5400 }
5401
5402 if (do_syms
5403 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
5404 {
5405 int hn;
5406 int si;
5407
5408 printf (_("\nSymbol table for image:\n"));
f7a99963 5409 if (is_32bit_elf)
ca47b30c 5410 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 5411 else
ca47b30c 5412 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
252b5132
RH
5413
5414 for (hn = 0; hn < nbuckets; hn++)
5415 {
5416 if (! buckets [hn])
5417 continue;
5418
f7a99963 5419 for (si = buckets [hn]; si < nchains && si > 0; si = chains [si])
252b5132
RH
5420 {
5421 Elf_Internal_Sym * psym;
5422
5423 psym = dynamic_symbols + si;
5424
f7a99963
NC
5425 printf (" %3d %3d: ", si, hn);
5426 print_vma (psym->st_value, LONG_HEX);
5427 putchar (' ' );
d1133906 5428 print_vma (psym->st_size, DEC_5);
76da6bbe 5429
d1133906
NC
5430 printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
5431 printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
5432 printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126
NC
5433 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
5434 print_symbol (25, dynamic_strings + psym->st_name);
5435 putchar ('\n');
252b5132
RH
5436 }
5437 }
5438 }
5439 else if (do_syms && !do_using_dynamic)
5440 {
5441 unsigned int i;
5442
5443 for (i = 0, section = section_headers;
5444 i < elf_header.e_shnum;
5445 i++, section++)
5446 {
5447 unsigned int si;
5448 char * strtab;
5449 Elf_Internal_Sym * symtab;
5450 Elf_Internal_Sym * psym;
5451
5452
5453 if ( section->sh_type != SHT_SYMTAB
5454 && section->sh_type != SHT_DYNSYM)
5455 continue;
5456
5457 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
5458 SECTION_NAME (section),
5459 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 5460 if (is_32bit_elf)
ca47b30c 5461 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 5462 else
ca47b30c 5463 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 5464
9ad5cbcf 5465 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
5466 if (symtab == NULL)
5467 continue;
5468
5469 if (section->sh_link == elf_header.e_shstrndx)
5470 strtab = string_table;
5471 else
5472 {
5473 Elf32_Internal_Shdr * string_sec;
5474
9ad5cbcf 5475 string_sec = SECTION_HEADER (section->sh_link);
252b5132 5476
a6e9f9df
AM
5477 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
5478 string_sec->sh_size,
5479 _("string table"));
252b5132
RH
5480 }
5481
5482 for (si = 0, psym = symtab;
5483 si < section->sh_size / section->sh_entsize;
5484 si ++, psym ++)
5485 {
5e220199 5486 printf ("%6d: ", si);
f7a99963
NC
5487 print_vma (psym->st_value, LONG_HEX);
5488 putchar (' ');
5489 print_vma (psym->st_size, DEC_5);
d1133906
NC
5490 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
5491 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
5492 printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126
NC
5493 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
5494 print_symbol (25, strtab + psym->st_name);
252b5132
RH
5495
5496 if (section->sh_type == SHT_DYNSYM &&
5497 version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
5498 {
5499 unsigned char data[2];
5500 unsigned short vers_data;
5501 unsigned long offset;
5502 int is_nobits;
5503 int check_def;
5504
5505 offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
5506 - loadaddr;
5507
a6e9f9df
AM
5508 get_data (&data, file, offset + si * sizeof (vers_data),
5509 sizeof (data), _("version data"));
252b5132
RH
5510
5511 vers_data = byte_get (data, 2);
5512
9ad5cbcf
AM
5513 is_nobits = (SECTION_HEADER (psym->st_shndx)->sh_type
5514 == SHT_NOBITS);
252b5132
RH
5515
5516 check_def = (psym->st_shndx != SHN_UNDEF);
5517
5518 if ((vers_data & 0x8000) || vers_data > 1)
5519 {
00d93f34
JJ
5520 if (version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
5521 && (is_nobits || ! check_def))
252b5132
RH
5522 {
5523 Elf_External_Verneed evn;
5524 Elf_Internal_Verneed ivn;
5525 Elf_Internal_Vernaux ivna;
5526
5527 /* We must test both. */
5528 offset = version_info
5529 [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
5530
252b5132
RH
5531 do
5532 {
5533 unsigned long vna_off;
5534
a6e9f9df
AM
5535 get_data (&evn, file, offset, sizeof (evn),
5536 _("version need"));
dd27201e
L
5537
5538 ivn.vn_aux = BYTE_GET (evn.vn_aux);
5539 ivn.vn_next = BYTE_GET (evn.vn_next);
5540
252b5132
RH
5541 vna_off = offset + ivn.vn_aux;
5542
5543 do
5544 {
5545 Elf_External_Vernaux evna;
5546
a6e9f9df
AM
5547 get_data (&evna, file, vna_off,
5548 sizeof (evna),
5549 _("version need aux (3)"));
252b5132
RH
5550
5551 ivna.vna_other = BYTE_GET (evna.vna_other);
5552 ivna.vna_next = BYTE_GET (evna.vna_next);
5553 ivna.vna_name = BYTE_GET (evna.vna_name);
5554
5555 vna_off += ivna.vna_next;
5556 }
5557 while (ivna.vna_other != vers_data
5558 && ivna.vna_next != 0);
5559
5560 if (ivna.vna_other == vers_data)
5561 break;
5562
5563 offset += ivn.vn_next;
5564 }
5565 while (ivn.vn_next != 0);
5566
5567 if (ivna.vna_other == vers_data)
5568 {
5569 printf ("@%s (%d)",
5570 strtab + ivna.vna_name, ivna.vna_other);
5571 check_def = 0;
5572 }
5573 else if (! is_nobits)
5574 error (_("bad dynamic symbol"));
5575 else
5576 check_def = 1;
5577 }
5578
5579 if (check_def)
5580 {
00d93f34
JJ
5581 if (vers_data != 0x8001
5582 && version_info [DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132
RH
5583 {
5584 Elf_Internal_Verdef ivd;
5585 Elf_Internal_Verdaux ivda;
5586 Elf_External_Verdaux evda;
5587 unsigned long offset;
5588
5589 offset =
5590 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
5591 - loadaddr;
5592
5593 do
5594 {
5595 Elf_External_Verdef evd;
5596
a6e9f9df
AM
5597 get_data (&evd, file, offset, sizeof (evd),
5598 _("version def"));
252b5132
RH
5599
5600 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
5601 ivd.vd_aux = BYTE_GET (evd.vd_aux);
5602 ivd.vd_next = BYTE_GET (evd.vd_next);
5603
5604 offset += ivd.vd_next;
5605 }
5606 while (ivd.vd_ndx != (vers_data & 0x7fff)
5607 && ivd.vd_next != 0);
5608
5609 offset -= ivd.vd_next;
5610 offset += ivd.vd_aux;
5611
a6e9f9df
AM
5612 get_data (&evda, file, offset, sizeof (evda),
5613 _("version def aux"));
252b5132
RH
5614
5615 ivda.vda_name = BYTE_GET (evda.vda_name);
5616
5617 if (psym->st_name != ivda.vda_name)
5618 printf ((vers_data & 0x8000)
5619 ? "@%s" : "@@%s",
5620 strtab + ivda.vda_name);
5621 }
5622 }
5623 }
5624 }
5625
5626 putchar ('\n');
5627 }
5628
5629 free (symtab);
5630 if (strtab != string_table)
5631 free (strtab);
5632 }
5633 }
5634 else if (do_syms)
5635 printf
5636 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
5637
5638 if (do_histogram && buckets != NULL)
5639 {
584da044
NC
5640 int * lengths;
5641 int * counts;
5642 int hn;
5643 int si;
5644 int maxlength = 0;
5645 int nzero_counts = 0;
5646 int nsyms = 0;
252b5132
RH
5647
5648 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
5649 nbuckets);
5650 printf (_(" Length Number %% of total Coverage\n"));
5651
5652 lengths = (int *) calloc (nbuckets, sizeof (int));
5653 if (lengths == NULL)
5654 {
5655 error (_("Out of memory"));
5656 return 0;
5657 }
5658 for (hn = 0; hn < nbuckets; ++hn)
5659 {
5660 if (! buckets [hn])
5661 continue;
5662
f7a99963 5663 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 5664 {
f7a99963 5665 ++ nsyms;
252b5132 5666 if (maxlength < ++lengths[hn])
f7a99963 5667 ++ maxlength;
252b5132
RH
5668 }
5669 }
5670
5671 counts = (int *) calloc (maxlength + 1, sizeof (int));
5672 if (counts == NULL)
5673 {
5674 error (_("Out of memory"));
5675 return 0;
5676 }
5677
5678 for (hn = 0; hn < nbuckets; ++hn)
30800947 5679 ++ counts [lengths [hn]];
252b5132 5680
103f02d3 5681 if (nbuckets > 0)
252b5132 5682 {
103f02d3
UD
5683 printf (" 0 %-10d (%5.1f%%)\n",
5684 counts[0], (counts[0] * 100.0) / nbuckets);
5685 for (si = 1; si <= maxlength; ++si)
5686 {
5687 nzero_counts += counts[si] * si;
5688 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
5689 si, counts[si], (counts[si] * 100.0) / nbuckets,
5690 (nzero_counts * 100.0) / nsyms);
5691 }
252b5132
RH
5692 }
5693
5694 free (counts);
5695 free (lengths);
5696 }
5697
5698 if (buckets != NULL)
5699 {
5700 free (buckets);
5701 free (chains);
5702 }
5703
5704 return 1;
5705}
5706
5707static int
5708process_syminfo (file)
b4c96d0d 5709 FILE * file ATTRIBUTE_UNUSED;
252b5132 5710{
b4c96d0d 5711 unsigned int i;
252b5132
RH
5712
5713 if (dynamic_syminfo == NULL
5714 || !do_dynamic)
5715 /* No syminfo, this is ok. */
5716 return 1;
5717
5718 /* There better should be a dynamic symbol section. */
5719 if (dynamic_symbols == NULL || dynamic_strings == NULL)
5720 return 0;
5721
5722 if (dynamic_addr)
5723 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
5724 dynamic_syminfo_offset, dynamic_syminfo_nent);
5725
5726 printf (_(" Num: Name BoundTo Flags\n"));
5727 for (i = 0; i < dynamic_syminfo_nent; ++i)
5728 {
5729 unsigned short int flags = dynamic_syminfo[i].si_flags;
5730
31104126
NC
5731 printf ("%4d: ", i);
5732 print_symbol (30, dynamic_strings + dynamic_symbols[i].st_name);
5733 putchar (' ');
252b5132
RH
5734
5735 switch (dynamic_syminfo[i].si_boundto)
5736 {
5737 case SYMINFO_BT_SELF:
5738 fputs ("SELF ", stdout);
5739 break;
5740 case SYMINFO_BT_PARENT:
5741 fputs ("PARENT ", stdout);
5742 break;
5743 default:
5744 if (dynamic_syminfo[i].si_boundto > 0
5745 && dynamic_syminfo[i].si_boundto < dynamic_size)
31104126
NC
5746 {
5747 print_symbol (10, dynamic_strings
5748 + dynamic_segment
5749 [dynamic_syminfo[i].si_boundto].d_un.d_val);
5750 putchar (' ' );
5751 }
252b5132
RH
5752 else
5753 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
5754 break;
5755 }
5756
5757 if (flags & SYMINFO_FLG_DIRECT)
5758 printf (" DIRECT");
5759 if (flags & SYMINFO_FLG_PASSTHRU)
5760 printf (" PASSTHRU");
5761 if (flags & SYMINFO_FLG_COPY)
5762 printf (" COPY");
5763 if (flags & SYMINFO_FLG_LAZYLOAD)
5764 printf (" LAZYLOAD");
5765
5766 puts ("");
5767 }
5768
5769 return 1;
5770}
5771
5772#ifdef SUPPORT_DISASSEMBLY
5773static void
5774disassemble_section (section, file)
5775 Elf32_Internal_Shdr * section;
5776 FILE * file;
5777{
5778 printf (_("\nAssembly dump of section %s\n"),
5779 SECTION_NAME (section));
5780
5781 /* XXX -- to be done --- XXX */
5782
5783 return 1;
5784}
5785#endif
5786
5787static int
5788dump_section (section, file)
5789 Elf32_Internal_Shdr * section;
5790 FILE * file;
5791{
9ea033b2
NC
5792 bfd_size_type bytes;
5793 bfd_vma addr;
252b5132
RH
5794 unsigned char * data;
5795 unsigned char * start;
5796
5797 bytes = section->sh_size;
5798
5799 if (bytes == 0)
5800 {
5801 printf (_("\nSection '%s' has no data to dump.\n"),
5802 SECTION_NAME (section));
5803 return 0;
5804 }
5805 else
5806 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
5807
5808 addr = section->sh_addr;
5809
a6e9f9df
AM
5810 start = (unsigned char *) get_data (NULL, file, section->sh_offset, bytes,
5811 _("section data"));
5812 if (!start)
5813 return 0;
252b5132
RH
5814
5815 data = start;
5816
5817 while (bytes)
5818 {
5819 int j;
5820 int k;
5821 int lbytes;
5822
5823 lbytes = (bytes > 16 ? 16 : bytes);
5824
148d3c43 5825 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132
RH
5826
5827 switch (elf_header.e_ident [EI_DATA])
5828 {
9ea033b2 5829 default:
252b5132
RH
5830 case ELFDATA2LSB:
5831 for (j = 15; j >= 0; j --)
5832 {
5833 if (j < lbytes)
5834 printf ("%2.2x", data [j]);
5835 else
5836 printf (" ");
5837
5838 if (!(j & 0x3))
5839 printf (" ");
5840 }
5841 break;
5842
5843 case ELFDATA2MSB:
5844 for (j = 0; j < 16; j++)
5845 {
5846 if (j < lbytes)
5847 printf ("%2.2x", data [j]);
5848 else
5849 printf (" ");
5850
5851 if ((j & 3) == 3)
5852 printf (" ");
5853 }
5854 break;
5855 }
5856
5857 for (j = 0; j < lbytes; j++)
5858 {
5859 k = data [j];
5860 if (k >= ' ' && k < 0x80)
5861 printf ("%c", k);
5862 else
5863 printf (".");
5864 }
5865
5866 putchar ('\n');
5867
5868 data += lbytes;
5869 addr += lbytes;
5870 bytes -= lbytes;
5871 }
5872
5873 free (start);
5874
5875 return 1;
5876}
5877
5878
5879static unsigned long int
5880read_leb128 (data, length_return, sign)
5881 unsigned char * data;
5882 int * length_return;
5883 int sign;
5884{
5885 unsigned long int result = 0;
5886 unsigned int num_read = 0;
5887 int shift = 0;
5888 unsigned char byte;
5889
5890 do
5891 {
5892 byte = * data ++;
5893 num_read ++;
5894
5895 result |= (byte & 0x7f) << shift;
5896
5897 shift += 7;
5898
5899 }
5900 while (byte & 0x80);
5901
5902 if (length_return != NULL)
5903 * length_return = num_read;
5904
5905 if (sign && (shift < 32) && (byte & 0x40))
5906 result |= -1 << shift;
5907
5908 return result;
5909}
5910
5911typedef struct State_Machine_Registers
5912{
5913 unsigned long address;
5914 unsigned int file;
5915 unsigned int line;
5916 unsigned int column;
5917 int is_stmt;
5918 int basic_block;
5919 int end_sequence;
5920/* This variable hold the number of the last entry seen
5921 in the File Table. */
5922 unsigned int last_file_entry;
5923} SMR;
5924
5925static SMR state_machine_regs;
5926
5927static void
5928reset_state_machine (is_stmt)
5929 int is_stmt;
5930{
5931 state_machine_regs.address = 0;
5932 state_machine_regs.file = 1;
5933 state_machine_regs.line = 1;
5934 state_machine_regs.column = 0;
5935 state_machine_regs.is_stmt = is_stmt;
5936 state_machine_regs.basic_block = 0;
5937 state_machine_regs.end_sequence = 0;
5938 state_machine_regs.last_file_entry = 0;
5939}
5940
5941/* Handled an extend line op. Returns true if this is the end
5942 of sequence. */
5943static int
3590ea00 5944process_extended_line_op (data, is_stmt, pointer_size)
252b5132
RH
5945 unsigned char * data;
5946 int is_stmt;
3590ea00 5947 int pointer_size;
252b5132
RH
5948{
5949 unsigned char op_code;
5950 int bytes_read;
5951 unsigned int len;
5952 unsigned char * name;
5953 unsigned long adr;
103f02d3 5954
252b5132
RH
5955 len = read_leb128 (data, & bytes_read, 0);
5956 data += bytes_read;
5957
5958 if (len == 0)
5959 {
e5fb9629 5960 warn (_("badly formed extended line op encountered!\n"));
252b5132
RH
5961 return bytes_read;
5962 }
5963
5964 len += bytes_read;
5965 op_code = * data ++;
5966
5967 printf (_(" Extended opcode %d: "), op_code);
103f02d3 5968
252b5132
RH
5969 switch (op_code)
5970 {
5971 case DW_LNE_end_sequence:
5972 printf (_("End of Sequence\n\n"));
5973 reset_state_machine (is_stmt);
5974 break;
5975
5976 case DW_LNE_set_address:
3590ea00 5977 adr = byte_get (data, pointer_size);
252b5132
RH
5978 printf (_("set Address to 0x%lx\n"), adr);
5979 state_machine_regs.address = adr;
5980 break;
5981
5982 case DW_LNE_define_file:
5983 printf (_(" define new File Table entry\n"));
5984 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
103f02d3 5985
252b5132
RH
5986 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
5987 name = data;
3c9f43b1 5988 data += strlen ((char *) data) + 1;
252b5132
RH
5989 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5990 data += bytes_read;
5991 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5992 data += bytes_read;
5993 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5994 printf (_("%s\n\n"), name);
5995 break;
5996
5997 default:
5998 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
5999 break;
6000 }
6001
6002 return len;
6003}
6004
3590ea00
NC
6005/* Size of pointers in the .debug_line section. This information is not
6006 really present in that section. It's obtained before dumping the debug
6007 sections by doing some pre-scan of the .debug_info section. */
6008static int debug_line_pointer_size = 4;
252b5132
RH
6009
6010static int
6011display_debug_lines (section, start, file)
6012 Elf32_Internal_Shdr * section;
6013 unsigned char * start;
b4c96d0d 6014 FILE * file ATTRIBUTE_UNUSED;
252b5132
RH
6015{
6016 DWARF2_External_LineInfo * external;
6017 DWARF2_Internal_LineInfo info;
6018 unsigned char * standard_opcodes;
6019 unsigned char * data = start;
6020 unsigned char * end = start + section->sh_size;
6021 unsigned char * end_of_sequence;
6022 int i;
6023
6024 printf (_("\nDump of debug contents of section %s:\n\n"),
6025 SECTION_NAME (section));
6026
6027 while (data < end)
6028 {
6029 external = (DWARF2_External_LineInfo *) data;
6030
6031 /* Check the length of the block. */
6032 info.li_length = BYTE_GET (external->li_length);
428409d5
NC
6033
6034 if (info.li_length == 0xffffffff)
6035 {
6036 warn (_("64-bit DWARF line info is not supported yet.\n"));
6037 break;
6038 }
6039
b612ab9c 6040 if (info.li_length + sizeof (external->li_length) > section->sh_size)
252b5132
RH
6041 {
6042 warn
6043 (_("The line info appears to be corrupt - the section is too small\n"));
6044 return 0;
6045 }
103f02d3 6046
252b5132
RH
6047 /* Check its version number. */
6048 info.li_version = BYTE_GET (external->li_version);
6049 if (info.li_version != 2)
6050 {
6051 warn (_("Only DWARF version 2 line info is currently supported.\n"));
6052 return 0;
6053 }
103f02d3 6054
252b5132
RH
6055 info.li_prologue_length = BYTE_GET (external->li_prologue_length);
6056 info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
6057 info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
6058 info.li_line_base = BYTE_GET (external->li_line_base);
6059 info.li_line_range = BYTE_GET (external->li_line_range);
6060 info.li_opcode_base = BYTE_GET (external->li_opcode_base);
103f02d3 6061
252b5132
RH
6062 /* Sign extend the line base field. */
6063 info.li_line_base <<= 24;
6064 info.li_line_base >>= 24;
103f02d3 6065
252b5132
RH
6066 printf (_(" Length: %ld\n"), info.li_length);
6067 printf (_(" DWARF Version: %d\n"), info.li_version);
ff94ebf2 6068 printf (_(" Prologue Length: %d\n"), info.li_prologue_length);
252b5132
RH
6069 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
6070 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
6071 printf (_(" Line Base: %d\n"), info.li_line_base);
6072 printf (_(" Line Range: %d\n"), info.li_line_range);
6073 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
6074
b612ab9c 6075 end_of_sequence = data + info.li_length + sizeof (external->li_length);
252b5132
RH
6076
6077 reset_state_machine (info.li_default_is_stmt);
103f02d3 6078
252b5132
RH
6079 /* Display the contents of the Opcodes table. */
6080 standard_opcodes = data + sizeof (* external);
103f02d3 6081
252b5132 6082 printf (_("\n Opcodes:\n"));
103f02d3 6083
252b5132 6084 for (i = 1; i < info.li_opcode_base; i++)
7a4b7442 6085 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
103f02d3 6086
252b5132
RH
6087 /* Display the contents of the Directory table. */
6088 data = standard_opcodes + info.li_opcode_base - 1;
103f02d3 6089
252b5132
RH
6090 if (* data == 0)
6091 printf (_("\n The Directory Table is empty.\n"));
6092 else
6093 {
6094 printf (_("\n The Directory Table:\n"));
103f02d3 6095
252b5132
RH
6096 while (* data != 0)
6097 {
6098 printf (_(" %s\n"), data);
103f02d3 6099
3c9f43b1 6100 data += strlen ((char *) data) + 1;
252b5132
RH
6101 }
6102 }
103f02d3 6103
252b5132
RH
6104 /* Skip the NUL at the end of the table. */
6105 data ++;
103f02d3 6106
252b5132
RH
6107 /* Display the contents of the File Name table. */
6108 if (* data == 0)
6109 printf (_("\n The File Name Table is empty.\n"));
6110 else
6111 {
6112 printf (_("\n The File Name Table:\n"));
6113 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
103f02d3 6114
252b5132
RH
6115 while (* data != 0)
6116 {
3c9f43b1 6117 unsigned char * name;
252b5132 6118 int bytes_read;
103f02d3 6119
252b5132
RH
6120 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
6121 name = data;
103f02d3 6122
3c9f43b1 6123 data += strlen ((char *) data) + 1;
103f02d3 6124
252b5132
RH
6125 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6126 data += bytes_read;
6127 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6128 data += bytes_read;
6129 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6130 data += bytes_read;
6131 printf (_("%s\n"), name);
6132 }
6133 }
103f02d3 6134
252b5132
RH
6135 /* Skip the NUL at the end of the table. */
6136 data ++;
103f02d3 6137
252b5132
RH
6138 /* Now display the statements. */
6139 printf (_("\n Line Number Statements:\n"));
103f02d3
UD
6140
6141
252b5132
RH
6142 while (data < end_of_sequence)
6143 {
6144 unsigned char op_code;
6145 int adv;
6146 int bytes_read;
103f02d3 6147
252b5132 6148 op_code = * data ++;
103f02d3 6149
1a509dcc
GK
6150 if (op_code >= info.li_opcode_base)
6151 {
6152 op_code -= info.li_opcode_base;
6153 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
6154 state_machine_regs.address += adv;
6155 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
6156 op_code, adv, state_machine_regs.address);
6157 adv = (op_code % info.li_line_range) + info.li_line_base;
6158 state_machine_regs.line += adv;
6159 printf (_(" and Line by %d to %d\n"),
6160 adv, state_machine_regs.line);
6161 }
6162 else switch (op_code)
252b5132
RH
6163 {
6164 case DW_LNS_extended_op:
3590ea00
NC
6165 data += process_extended_line_op (data, info.li_default_is_stmt,
6166 debug_line_pointer_size);
252b5132 6167 break;
103f02d3 6168
252b5132
RH
6169 case DW_LNS_copy:
6170 printf (_(" Copy\n"));
6171 break;
103f02d3 6172
252b5132
RH
6173 case DW_LNS_advance_pc:
6174 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
6175 data += bytes_read;
6176 state_machine_regs.address += adv;
6177 printf (_(" Advance PC by %d to %lx\n"), adv,
6178 state_machine_regs.address);
6179 break;
103f02d3 6180
252b5132
RH
6181 case DW_LNS_advance_line:
6182 adv = read_leb128 (data, & bytes_read, 1);
6183 data += bytes_read;
6184 state_machine_regs.line += adv;
6185 printf (_(" Advance Line by %d to %d\n"), adv,
6186 state_machine_regs.line);
6187 break;
103f02d3 6188
252b5132
RH
6189 case DW_LNS_set_file:
6190 adv = read_leb128 (data, & bytes_read, 0);
6191 data += bytes_read;
6192 printf (_(" Set File Name to entry %d in the File Name Table\n"),
6193 adv);
6194 state_machine_regs.file = adv;
6195 break;
103f02d3 6196
252b5132
RH
6197 case DW_LNS_set_column:
6198 adv = read_leb128 (data, & bytes_read, 0);
6199 data += bytes_read;
6200 printf (_(" Set column to %d\n"), adv);
6201 state_machine_regs.column = adv;
6202 break;
103f02d3 6203
252b5132
RH
6204 case DW_LNS_negate_stmt:
6205 adv = state_machine_regs.is_stmt;
6206 adv = ! adv;
6207 printf (_(" Set is_stmt to %d\n"), adv);
6208 state_machine_regs.is_stmt = adv;
6209 break;
103f02d3 6210
252b5132
RH
6211 case DW_LNS_set_basic_block:
6212 printf (_(" Set basic block\n"));
6213 state_machine_regs.basic_block = 1;
6214 break;
103f02d3 6215
252b5132 6216 case DW_LNS_const_add_pc:
2366453a
NC
6217 adv = (((255 - info.li_opcode_base) / info.li_line_range)
6218 * info.li_min_insn_length);
252b5132
RH
6219 state_machine_regs.address += adv;
6220 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
6221 state_machine_regs.address);
6222 break;
103f02d3 6223
252b5132
RH
6224 case DW_LNS_fixed_advance_pc:
6225 adv = byte_get (data, 2);
6226 data += 2;
6227 state_machine_regs.address += adv;
6228 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
6229 adv, state_machine_regs.address);
6230 break;
103f02d3 6231
1a509dcc
GK
6232 case DW_LNS_set_prologue_end:
6233 printf (_(" Set prologue_end to true\n"));
6234 break;
6235
6236 case DW_LNS_set_epilogue_begin:
6237 printf (_(" Set epilogue_begin to true\n"));
6238 break;
6239
6240 case DW_LNS_set_isa:
6241 adv = read_leb128 (data, & bytes_read, 0);
6242 data += bytes_read;
6243 printf (_(" Set ISA to %d\n"), adv);
6244 break;
6245
252b5132 6246 default:
1a509dcc
GK
6247 printf (_(" Unknown opcode %d with operands: "), op_code);
6248 {
6249 int i;
6250 for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
6251 {
6252 printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
6253 i == 1 ? "" : ", ");
6254 data += bytes_read;
6255 }
6256 putchar ('\n');
6257 }
252b5132
RH
6258 break;
6259 }
6260 }
1a509dcc 6261 putchar ('\n');
252b5132 6262 }
103f02d3 6263
252b5132
RH
6264 return 1;
6265}
6266
6267static int
6268display_debug_pubnames (section, start, file)
6269 Elf32_Internal_Shdr * section;
6270 unsigned char * start;
b4c96d0d 6271 FILE * file ATTRIBUTE_UNUSED;
252b5132
RH
6272{
6273 DWARF2_External_PubNames * external;
6274 DWARF2_Internal_PubNames pubnames;
6275 unsigned char * end;
6276
6277 end = start + section->sh_size;
6278
6279 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
6280
6281 while (start < end)
6282 {
6283 unsigned char * data;
6284 unsigned long offset;
6285
6286 external = (DWARF2_External_PubNames *) start;
6287
6288 pubnames.pn_length = BYTE_GET (external->pn_length);
6289 pubnames.pn_version = BYTE_GET (external->pn_version);
6290 pubnames.pn_offset = BYTE_GET (external->pn_offset);
6291 pubnames.pn_size = BYTE_GET (external->pn_size);
6292
6293 data = start + sizeof (* external);
6294 start += pubnames.pn_length + sizeof (external->pn_length);
6295
428409d5
NC
6296 if (pubnames.pn_length == 0xffffffff)
6297 {
6298 warn (_("64-bit DWARF pubnames are not supported yet.\n"));
6299 break;
6300 }
6301
252b5132
RH
6302 if (pubnames.pn_version != 2)
6303 {
3f215a10
NC
6304 static int warned = 0;
6305
6306 if (! warned)
6307 {
6308 warn (_("Only DWARF 2 pubnames are currently supported\n"));
6309 warned = 1;
6310 }
76da6bbe 6311
252b5132
RH
6312 continue;
6313 }
6314
6315 printf (_(" Length: %ld\n"),
6316 pubnames.pn_length);
6317 printf (_(" Version: %d\n"),
6318 pubnames.pn_version);
6319 printf (_(" Offset into .debug_info section: %ld\n"),
6320 pubnames.pn_offset);
6321 printf (_(" Size of area in .debug_info section: %ld\n"),
6322 pubnames.pn_size);
6323
6324 printf (_("\n Offset\tName\n"));
6325
6326 do
6327 {
6328 offset = byte_get (data, 4);
6329
6330 if (offset != 0)
6331 {
6332 data += 4;
6333 printf (" %ld\t\t%s\n", offset, data);
3c9f43b1 6334 data += strlen ((char *) data) + 1;
252b5132
RH
6335 }
6336 }
6337 while (offset != 0);
6338 }
6339
6340 printf ("\n");
6341 return 1;
6342}
6343
6344static char *
6345get_TAG_name (tag)
6346 unsigned long tag;
6347{
6348 switch (tag)
6349 {
b811889f
NC
6350 case DW_TAG_padding: return "DW_TAG_padding";
6351 case DW_TAG_array_type: return "DW_TAG_array_type";
6352 case DW_TAG_class_type: return "DW_TAG_class_type";
6353 case DW_TAG_entry_point: return "DW_TAG_entry_point";
6354 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
6355 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
6356 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
6357 case DW_TAG_label: return "DW_TAG_label";
6358 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
6359 case DW_TAG_member: return "DW_TAG_member";
6360 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
6361 case DW_TAG_reference_type: return "DW_TAG_reference_type";
6362 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
6363 case DW_TAG_string_type: return "DW_TAG_string_type";
6364 case DW_TAG_structure_type: return "DW_TAG_structure_type";
6365 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
6366 case DW_TAG_typedef: return "DW_TAG_typedef";
6367 case DW_TAG_union_type: return "DW_TAG_union_type";
252b5132 6368 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
b811889f
NC
6369 case DW_TAG_variant: return "DW_TAG_variant";
6370 case DW_TAG_common_block: return "DW_TAG_common_block";
6371 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
6372 case DW_TAG_inheritance: return "DW_TAG_inheritance";
6373 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
6374 case DW_TAG_module: return "DW_TAG_module";
6375 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
6376 case DW_TAG_set_type: return "DW_TAG_set_type";
6377 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
6378 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
6379 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
6380 case DW_TAG_base_type: return "DW_TAG_base_type";
6381 case DW_TAG_catch_block: return "DW_TAG_catch_block";
6382 case DW_TAG_const_type: return "DW_TAG_const_type";
6383 case DW_TAG_constant: return "DW_TAG_constant";
6384 case DW_TAG_enumerator: return "DW_TAG_enumerator";
6385 case DW_TAG_file_type: return "DW_TAG_file_type";
6386 case DW_TAG_friend: return "DW_TAG_friend";
6387 case DW_TAG_namelist: return "DW_TAG_namelist";
6388 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
6389 case DW_TAG_packed_type: return "DW_TAG_packed_type";
6390 case DW_TAG_subprogram: return "DW_TAG_subprogram";
6391 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
6392 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
6393 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
6394 case DW_TAG_try_block: return "DW_TAG_try_block";
6395 case DW_TAG_variant_part: return "DW_TAG_variant_part";
6396 case DW_TAG_variable: return "DW_TAG_variable";
6397 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
6398 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
6399 case DW_TAG_format_label: return "DW_TAG_format_label";
6400 case DW_TAG_function_template: return "DW_TAG_function_template";
6401 case DW_TAG_class_template: return "DW_TAG_class_template";
6402 /* DWARF 2.1 values. */
6403 case DW_TAG_dwarf_procedure: return "DW_TAG_dwarf_procedure";
6404 case DW_TAG_restrict_type: return "DW_TAG_restrict_type";
6405 case DW_TAG_interface_type: return "DW_TAG_interface_type";
6406 case DW_TAG_namespace: return "DW_TAG_namespace";
6407 case DW_TAG_imported_module: return "DW_TAG_imported_module";
6408 case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type";
6409 case DW_TAG_partial_unit: return "DW_TAG_partial_unit";
6410 case DW_TAG_imported_unit: return "DW_TAG_imported_unit";
252b5132
RH
6411 default:
6412 {
6413 static char buffer [100];
6414
6415 sprintf (buffer, _("Unknown TAG value: %lx"), tag);
6416 return buffer;
6417 }
6418 }
6419}
6420
6421static char *
6422get_AT_name (attribute)
6423 unsigned long attribute;
6424{
6425 switch (attribute)
6426 {
b811889f
NC
6427 case DW_AT_sibling: return "DW_AT_sibling";
6428 case DW_AT_location: return "DW_AT_location";
6429 case DW_AT_name: return "DW_AT_name";
6430 case DW_AT_ordering: return "DW_AT_ordering";
6431 case DW_AT_subscr_data: return "DW_AT_subscr_data";
6432 case DW_AT_byte_size: return "DW_AT_byte_size";
6433 case DW_AT_bit_offset: return "DW_AT_bit_offset";
6434 case DW_AT_bit_size: return "DW_AT_bit_size";
6435 case DW_AT_element_list: return "DW_AT_element_list";
6436 case DW_AT_stmt_list: return "DW_AT_stmt_list";
6437 case DW_AT_low_pc: return "DW_AT_low_pc";
6438 case DW_AT_high_pc: return "DW_AT_high_pc";
6439 case DW_AT_language: return "DW_AT_language";
6440 case DW_AT_member: return "DW_AT_member";
6441 case DW_AT_discr: return "DW_AT_discr";
6442 case DW_AT_discr_value: return "DW_AT_discr_value";
6443 case DW_AT_visibility: return "DW_AT_visibility";
6444 case DW_AT_import: return "DW_AT_import";
6445 case DW_AT_string_length: return "DW_AT_string_length";
6446 case DW_AT_common_reference: return "DW_AT_common_reference";
6447 case DW_AT_comp_dir: return "DW_AT_comp_dir";
6448 case DW_AT_const_value: return "DW_AT_const_value";
6449 case DW_AT_containing_type: return "DW_AT_containing_type";
6450 case DW_AT_default_value: return "DW_AT_default_value";
6451 case DW_AT_inline: return "DW_AT_inline";
6452 case DW_AT_is_optional: return "DW_AT_is_optional";
6453 case DW_AT_lower_bound: return "DW_AT_lower_bound";
6454 case DW_AT_producer: return "DW_AT_producer";
6455 case DW_AT_prototyped: return "DW_AT_prototyped";
6456 case DW_AT_return_addr: return "DW_AT_return_addr";
6457 case DW_AT_start_scope: return "DW_AT_start_scope";
6458 case DW_AT_stride_size: return "DW_AT_stride_size";
6459 case DW_AT_upper_bound: return "DW_AT_upper_bound";
6460 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
6461 case DW_AT_accessibility: return "DW_AT_accessibility";
6462 case DW_AT_address_class: return "DW_AT_address_class";
6463 case DW_AT_artificial: return "DW_AT_artificial";
6464 case DW_AT_base_types: return "DW_AT_base_types";
6465 case DW_AT_calling_convention: return "DW_AT_calling_convention";
6466 case DW_AT_count: return "DW_AT_count";
252b5132 6467 case DW_AT_data_member_location: return "DW_AT_data_member_location";
b811889f
NC
6468 case DW_AT_decl_column: return "DW_AT_decl_column";
6469 case DW_AT_decl_file: return "DW_AT_decl_file";
6470 case DW_AT_decl_line: return "DW_AT_decl_line";
6471 case DW_AT_declaration: return "DW_AT_declaration";
6472 case DW_AT_discr_list: return "DW_AT_discr_list";
6473 case DW_AT_encoding: return "DW_AT_encoding";
6474 case DW_AT_external: return "DW_AT_external";
6475 case DW_AT_frame_base: return "DW_AT_frame_base";
6476 case DW_AT_friend: return "DW_AT_friend";
6477 case DW_AT_identifier_case: return "DW_AT_identifier_case";
6478 case DW_AT_macro_info: return "DW_AT_macro_info";
6479 case DW_AT_namelist_items: return "DW_AT_namelist_items";
6480 case DW_AT_priority: return "DW_AT_priority";
6481 case DW_AT_segment: return "DW_AT_segment";
6482 case DW_AT_specification: return "DW_AT_specification";
6483 case DW_AT_static_link: return "DW_AT_static_link";
6484 case DW_AT_type: return "DW_AT_type";
6485 case DW_AT_use_location: return "DW_AT_use_location";
6486 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
6487 case DW_AT_virtuality: return "DW_AT_virtuality";
252b5132 6488 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
12ab83a9 6489 /* DWARF 2.1 values. */
b811889f
NC
6490 case DW_AT_allocated: return "DW_AT_allocated";
6491 case DW_AT_associated: return "DW_AT_associated";
6492 case DW_AT_data_location: return "DW_AT_data_location";
6493 case DW_AT_stride: return "DW_AT_stride";
6494 case DW_AT_entry_pc: return "DW_AT_entry_pc";
6495 case DW_AT_use_UTF8: return "DW_AT_use_UTF8";
6496 case DW_AT_extension: return "DW_AT_extension";
6497 case DW_AT_ranges: return "DW_AT_ranges";
6498 case DW_AT_trampoline: return "DW_AT_trampoline";
6499 case DW_AT_call_column: return "DW_AT_call_column";
6500 case DW_AT_call_file: return "DW_AT_call_file";
6501 case DW_AT_call_line: return "DW_AT_call_line";
12ab83a9 6502 /* SGI/MIPS extensions. */
b811889f
NC
6503 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
6504 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
252b5132 6505 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
b811889f 6506 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
252b5132
RH
6507 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
6508 case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
b811889f
NC
6509 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
6510 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
6511 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
6512 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
6513 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
12ab83a9 6514 /* GNU extensions. */
b811889f
NC
6515 case DW_AT_sf_names: return "DW_AT_sf_names";
6516 case DW_AT_src_info: return "DW_AT_src_info";
6517 case DW_AT_mac_info: return "DW_AT_mac_info";
6518 case DW_AT_src_coords: return "DW_AT_src_coords";
6519 case DW_AT_body_begin: return "DW_AT_body_begin";
6520 case DW_AT_body_end: return "DW_AT_body_end";
252b5132
RH
6521 default:
6522 {
6523 static char buffer [100];
6524
6525 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
6526 return buffer;
6527 }
6528 }
6529}
6530
6531static char *
6532get_FORM_name (form)
6533 unsigned long form;
6534{
6535 switch (form)
6536 {
b811889f
NC
6537 case DW_FORM_addr: return "DW_FORM_addr";
6538 case DW_FORM_block2: return "DW_FORM_block2";
6539 case DW_FORM_block4: return "DW_FORM_block4";
6540 case DW_FORM_data2: return "DW_FORM_data2";
6541 case DW_FORM_data4: return "DW_FORM_data4";
6542 case DW_FORM_data8: return "DW_FORM_data8";
6543 case DW_FORM_string: return "DW_FORM_string";
6544 case DW_FORM_block: return "DW_FORM_block";
6545 case DW_FORM_block1: return "DW_FORM_block1";
6546 case DW_FORM_data1: return "DW_FORM_data1";
6547 case DW_FORM_flag: return "DW_FORM_flag";
6548 case DW_FORM_sdata: return "DW_FORM_sdata";
6549 case DW_FORM_strp: return "DW_FORM_strp";
6550 case DW_FORM_udata: return "DW_FORM_udata";
6551 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
6552 case DW_FORM_ref1: return "DW_FORM_ref1";
6553 case DW_FORM_ref2: return "DW_FORM_ref2";
6554 case DW_FORM_ref4: return "DW_FORM_ref4";
6555 case DW_FORM_ref8: return "DW_FORM_ref8";
252b5132 6556 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
b811889f 6557 case DW_FORM_indirect: return "DW_FORM_indirect";
252b5132
RH
6558 default:
6559 {
6560 static char buffer [100];
6561
6562 sprintf (buffer, _("Unknown FORM value: %lx"), form);
6563 return buffer;
6564 }
6565 }
6566}
6567
6568/* FIXME: There are better and more effiecint ways to handle
6569 these structures. For now though, I just want something that
6570 is simple to implement. */
6571typedef struct abbrev_attr
6572{
6573 unsigned long attribute;
6574 unsigned long form;
6575 struct abbrev_attr * next;
6576}
6577abbrev_attr;
6578
6579typedef struct abbrev_entry
6580{
6581 unsigned long entry;
6582 unsigned long tag;
6583 int children;
6584 struct abbrev_attr * first_attr;
6585 struct abbrev_attr * last_attr;
6586 struct abbrev_entry * next;
6587}
6588abbrev_entry;
6589
6590static abbrev_entry * first_abbrev = NULL;
6591static abbrev_entry * last_abbrev = NULL;
6592
6593static void
6594free_abbrevs PARAMS ((void))
6595{
6596 abbrev_entry * abbrev;
6597
6598 for (abbrev = first_abbrev; abbrev;)
6599 {
6600 abbrev_entry * next = abbrev->next;
6601 abbrev_attr * attr;
6602
6603 for (attr = abbrev->first_attr; attr;)
6604 {
6605 abbrev_attr * next = attr->next;
6606
6607 free (attr);
6608 attr = next;
6609 }
6610
6611 free (abbrev);
6612 abbrev = next;
6613 }
6614
6615 last_abbrev = first_abbrev = NULL;
6616}
6617
6618static void
6619add_abbrev (number, tag, children)
6620 unsigned long number;
6621 unsigned long tag;
6622 int children;
6623{
6624 abbrev_entry * entry;
6625
6626 entry = (abbrev_entry *) malloc (sizeof (* entry));
6627
6628 if (entry == NULL)
6629 /* ugg */
6630 return;
6631
6632 entry->entry = number;
6633 entry->tag = tag;
6634 entry->children = children;
6635 entry->first_attr = NULL;
6636 entry->last_attr = NULL;
6637 entry->next = NULL;
6638
6639 if (first_abbrev == NULL)
6640 first_abbrev = entry;
6641 else
6642 last_abbrev->next = entry;
6643
6644 last_abbrev = entry;
6645}
6646
6647static void
6648add_abbrev_attr (attribute, form)
6649 unsigned long attribute;
6650 unsigned long form;
6651{
6652 abbrev_attr * attr;
6653
6654 attr = (abbrev_attr *) malloc (sizeof (* attr));
6655
6656 if (attr == NULL)
6657 /* ugg */
6658 return;
6659
6660 attr->attribute = attribute;
6661 attr->form = form;
6662 attr->next = NULL;
6663
6664 if (last_abbrev->first_attr == NULL)
6665 last_abbrev->first_attr = attr;
6666 else
6667 last_abbrev->last_attr->next = attr;
6668
6669 last_abbrev->last_attr = attr;
6670}
6671
6672/* Processes the (partial) contents of a .debug_abbrev section.
6673 Returns NULL if the end of the section was encountered.
6674 Returns the address after the last byte read if the end of
6675 an abbreviation set was found. */
6676
6677static unsigned char *
6678process_abbrev_section (start, end)
6679 unsigned char * start;
6680 unsigned char * end;
6681{
6682 if (first_abbrev != NULL)
6683 return NULL;
6684
6685 while (start < end)
6686 {
6687 int bytes_read;
6688 unsigned long entry;
6689 unsigned long tag;
6690 unsigned long attribute;
6691 int children;
6692
6693 entry = read_leb128 (start, & bytes_read, 0);
6694 start += bytes_read;
6695
a3f779db
NC
6696 /* A single zero is supposed to end the section according
6697 to the standard. If there's more, then signal that to
6698 the caller. */
252b5132 6699 if (entry == 0)
a3f779db 6700 return start == end ? NULL : start;
252b5132
RH
6701
6702 tag = read_leb128 (start, & bytes_read, 0);
6703 start += bytes_read;
6704
6705 children = * start ++;
6706
6707 add_abbrev (entry, tag, children);
6708
6709 do
6710 {
6711 unsigned long form;
6712
6713 attribute = read_leb128 (start, & bytes_read, 0);
6714 start += bytes_read;
6715
6716 form = read_leb128 (start, & bytes_read, 0);
6717 start += bytes_read;
6718
6719 if (attribute != 0)
6720 add_abbrev_attr (attribute, form);
6721 }
6722 while (attribute != 0);
6723 }
6724
6725 return NULL;
6726}
6727
6728
e0c60db2
NC
6729static int
6730display_debug_macinfo (section, start, file)
6731 Elf32_Internal_Shdr * section;
6732 unsigned char * start;
6733 FILE * file ATTRIBUTE_UNUSED;
6734{
6735 unsigned char * end = start + section->sh_size;
6736 unsigned char * curr = start;
6737 unsigned int bytes_read;
6738 enum dwarf_macinfo_record_type op;
6739
6740 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
6741
6742 while (curr < end)
6743 {
6744 unsigned int lineno;
6745 const char * string;
6746
6747 op = * curr;
6748 curr ++;
6749
6750 switch (op)
6751 {
6752 case DW_MACINFO_start_file:
6753 {
6754 unsigned int filenum;
6755
6756 lineno = read_leb128 (curr, & bytes_read, 0);
6757 curr += bytes_read;
6758 filenum = read_leb128 (curr, & bytes_read, 0);
6759 curr += bytes_read;
6760
6761 printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"), lineno, filenum);
6762 }
6763 break;
6764
6765 case DW_MACINFO_end_file:
6766 printf (_(" DW_MACINFO_end_file\n"));
6767 break;
6768
6769 case DW_MACINFO_define:
6770 lineno = read_leb128 (curr, & bytes_read, 0);
6771 curr += bytes_read;
6772 string = curr;
6773 curr += strlen (string) + 1;
6774 printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"), lineno, string);
6775 break;
6776
6777 case DW_MACINFO_undef:
6778 lineno = read_leb128 (curr, & bytes_read, 0);
6779 curr += bytes_read;
6780 string = curr;
6781 curr += strlen (string) + 1;
6782 printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"), lineno, string);
6783 break;
6784
6785 case DW_MACINFO_vendor_ext:
6786 {
6787 unsigned int constant;
6788
6789 constant = read_leb128 (curr, & bytes_read, 0);
6790 curr += bytes_read;
6791 string = curr;
6792 curr += strlen (string) + 1;
6793 printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"), constant, string);
6794 }
6795 break;
6796 }
6797 }
6798
6799 return 1;
6800}
0823fbca 6801
e0c60db2 6802
252b5132
RH
6803static int
6804display_debug_abbrev (section, start, file)
6805 Elf32_Internal_Shdr * section;
6806 unsigned char * start;
b4c96d0d 6807 FILE * file ATTRIBUTE_UNUSED;
252b5132 6808{
584da044 6809 abbrev_entry * entry;
252b5132
RH
6810 unsigned char * end = start + section->sh_size;
6811
6812 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
6813
6814 do
6815 {
6816 start = process_abbrev_section (start, end);
6817
ef5cdfc7
JJ
6818 if (first_abbrev == NULL)
6819 continue;
6820
252b5132
RH
6821 printf (_(" Number TAG\n"));
6822
6823 for (entry = first_abbrev; entry; entry = entry->next)
6824 {
6825 abbrev_attr * attr;
6826
6827 printf (_(" %ld %s [%s]\n"),
6828 entry->entry,
6829 get_TAG_name (entry->tag),
6830 entry->children ? _("has children") : _("no children"));
6831
6832 for (attr = entry->first_attr; attr; attr = attr->next)
6833 {
6834 printf (_(" %-18s %s\n"),
6835 get_AT_name (attr->attribute),
6836 get_FORM_name (attr->form));
6837 }
6838 }
ef5cdfc7
JJ
6839
6840 free_abbrevs ();
252b5132
RH
6841 }
6842 while (start);
6843
6844 printf ("\n");
6845
6846 return 1;
6847}
6848
6849
6850static unsigned char *
6851display_block (data, length)
6852 unsigned char * data;
6853 unsigned long length;
6854{
6855 printf (_(" %lu byte block: "), length);
6856
6857 while (length --)
148d3c43 6858 printf ("%lx ", (unsigned long) byte_get (data ++, 1));
252b5132
RH
6859
6860 return data;
6861}
6862
6863static void
eb6bd4d3 6864decode_location_expression (data, pointer_size, length)
252b5132
RH
6865 unsigned char * data;
6866 unsigned int pointer_size;
584da044 6867 unsigned long length;
252b5132 6868{
584da044
NC
6869 unsigned op;
6870 int bytes_read;
6871 unsigned long uvalue;
6872 unsigned char * end = data + length;
252b5132 6873
eb6bd4d3 6874 while (data < end)
252b5132 6875 {
eb6bd4d3 6876 op = * data ++;
252b5132 6877
eb6bd4d3
JM
6878 switch (op)
6879 {
6880 case DW_OP_addr:
6881 printf ("DW_OP_addr: %lx",
6882 (unsigned long) byte_get (data, pointer_size));
6883 data += pointer_size;
6884 break;
6885 case DW_OP_deref:
6886 printf ("DW_OP_deref");
6887 break;
6888 case DW_OP_const1u:
6889 printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
6890 break;
6891 case DW_OP_const1s:
6892 printf ("DW_OP_const1s: %ld", (long) byte_get (data++, 1));
6893 break;
6894 case DW_OP_const2u:
6895 printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
6896 data += 2;
6897 break;
6898 case DW_OP_const2s:
6899 printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
6900 data += 2;
6901 break;
6902 case DW_OP_const4u:
6903 printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
6904 data += 4;
6905 break;
6906 case DW_OP_const4s:
6907 printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
6908 data += 4;
6909 break;
6910 case DW_OP_const8u:
6911 printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
6912 (unsigned long) byte_get (data + 4, 4));
6913 data += 8;
6914 break;
6915 case DW_OP_const8s:
6916 printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
6917 (long) byte_get (data + 4, 4));
6918 data += 8;
6919 break;
6920 case DW_OP_constu:
6921 printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
6922 data += bytes_read;
6923 break;
6924 case DW_OP_consts:
6925 printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
6926 data += bytes_read;
6927 break;
6928 case DW_OP_dup:
6929 printf ("DW_OP_dup");
6930 break;
6931 case DW_OP_drop:
6932 printf ("DW_OP_drop");
6933 break;
6934 case DW_OP_over:
6935 printf ("DW_OP_over");
6936 break;
6937 case DW_OP_pick:
6938 printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
6939 break;
6940 case DW_OP_swap:
6941 printf ("DW_OP_swap");
6942 break;
6943 case DW_OP_rot:
6944 printf ("DW_OP_rot");
6945 break;
6946 case DW_OP_xderef:
6947 printf ("DW_OP_xderef");
6948 break;
6949 case DW_OP_abs:
6950 printf ("DW_OP_abs");
6951 break;
6952 case DW_OP_and:
6953 printf ("DW_OP_and");
6954 break;
6955 case DW_OP_div:
6956 printf ("DW_OP_div");
6957 break;
6958 case DW_OP_minus:
6959 printf ("DW_OP_minus");
6960 break;
6961 case DW_OP_mod:
6962 printf ("DW_OP_mod");
6963 break;
6964 case DW_OP_mul:
6965 printf ("DW_OP_mul");
6966 break;
6967 case DW_OP_neg:
6968 printf ("DW_OP_neg");
6969 break;
6970 case DW_OP_not:
6971 printf ("DW_OP_not");
6972 break;
6973 case DW_OP_or:
6974 printf ("DW_OP_or");
6975 break;
6976 case DW_OP_plus:
6977 printf ("DW_OP_plus");
6978 break;
6979 case DW_OP_plus_uconst:
6980 printf ("DW_OP_plus_uconst: %lu",
6981 read_leb128 (data, &bytes_read, 0));
6982 data += bytes_read;
6983 break;
6984 case DW_OP_shl:
6985 printf ("DW_OP_shl");
6986 break;
6987 case DW_OP_shr:
6988 printf ("DW_OP_shr");
6989 break;
6990 case DW_OP_shra:
6991 printf ("DW_OP_shra");
6992 break;
6993 case DW_OP_xor:
6994 printf ("DW_OP_xor");
6995 break;
6996 case DW_OP_bra:
6997 printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
6998 data += 2;
6999 break;
7000 case DW_OP_eq:
7001 printf ("DW_OP_eq");
7002 break;
7003 case DW_OP_ge:
7004 printf ("DW_OP_ge");
7005 break;
7006 case DW_OP_gt:
7007 printf ("DW_OP_gt");
7008 break;
7009 case DW_OP_le:
7010 printf ("DW_OP_le");
7011 break;
7012 case DW_OP_lt:
7013 printf ("DW_OP_lt");
7014 break;
7015 case DW_OP_ne:
7016 printf ("DW_OP_ne");
7017 break;
7018 case DW_OP_skip:
7019 printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
7020 data += 2;
7021 break;
7022
7023 case DW_OP_lit0:
7024 case DW_OP_lit1:
7025 case DW_OP_lit2:
7026 case DW_OP_lit3:
7027 case DW_OP_lit4:
7028 case DW_OP_lit5:
7029 case DW_OP_lit6:
7030 case DW_OP_lit7:
7031 case DW_OP_lit8:
7032 case DW_OP_lit9:
7033 case DW_OP_lit10:
7034 case DW_OP_lit11:
7035 case DW_OP_lit12:
7036 case DW_OP_lit13:
7037 case DW_OP_lit14:
7038 case DW_OP_lit15:
7039 case DW_OP_lit16:
7040 case DW_OP_lit17:
7041 case DW_OP_lit18:
7042 case DW_OP_lit19:
7043 case DW_OP_lit20:
7044 case DW_OP_lit21:
7045 case DW_OP_lit22:
7046 case DW_OP_lit23:
7047 case DW_OP_lit24:
7048 case DW_OP_lit25:
7049 case DW_OP_lit26:
7050 case DW_OP_lit27:
7051 case DW_OP_lit28:
7052 case DW_OP_lit29:
7053 case DW_OP_lit30:
7054 case DW_OP_lit31:
7055 printf ("DW_OP_lit%d", op - DW_OP_lit0);
7056 break;
7057
7058 case DW_OP_reg0:
7059 case DW_OP_reg1:
7060 case DW_OP_reg2:
7061 case DW_OP_reg3:
7062 case DW_OP_reg4:
7063 case DW_OP_reg5:
7064 case DW_OP_reg6:
7065 case DW_OP_reg7:
7066 case DW_OP_reg8:
7067 case DW_OP_reg9:
7068 case DW_OP_reg10:
7069 case DW_OP_reg11:
7070 case DW_OP_reg12:
7071 case DW_OP_reg13:
7072 case DW_OP_reg14:
7073 case DW_OP_reg15:
7074 case DW_OP_reg16:
7075 case DW_OP_reg17:
7076 case DW_OP_reg18:
7077 case DW_OP_reg19:
7078 case DW_OP_reg20:
7079 case DW_OP_reg21:
7080 case DW_OP_reg22:
7081 case DW_OP_reg23:
7082 case DW_OP_reg24:
7083 case DW_OP_reg25:
7084 case DW_OP_reg26:
7085 case DW_OP_reg27:
7086 case DW_OP_reg28:
7087 case DW_OP_reg29:
7088 case DW_OP_reg30:
7089 case DW_OP_reg31:
7090 printf ("DW_OP_reg%d", op - DW_OP_reg0);
7091 break;
7092
7093 case DW_OP_breg0:
7094 case DW_OP_breg1:
7095 case DW_OP_breg2:
7096 case DW_OP_breg3:
7097 case DW_OP_breg4:
7098 case DW_OP_breg5:
7099 case DW_OP_breg6:
7100 case DW_OP_breg7:
7101 case DW_OP_breg8:
7102 case DW_OP_breg9:
7103 case DW_OP_breg10:
7104 case DW_OP_breg11:
7105 case DW_OP_breg12:
7106 case DW_OP_breg13:
7107 case DW_OP_breg14:
7108 case DW_OP_breg15:
7109 case DW_OP_breg16:
7110 case DW_OP_breg17:
7111 case DW_OP_breg18:
7112 case DW_OP_breg19:
7113 case DW_OP_breg20:
7114 case DW_OP_breg21:
7115 case DW_OP_breg22:
7116 case DW_OP_breg23:
7117 case DW_OP_breg24:
7118 case DW_OP_breg25:
7119 case DW_OP_breg26:
7120 case DW_OP_breg27:
7121 case DW_OP_breg28:
7122 case DW_OP_breg29:
7123 case DW_OP_breg30:
7124 case DW_OP_breg31:
7125 printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
7126 read_leb128 (data, &bytes_read, 1));
7127 data += bytes_read;
7128 break;
7129
7130 case DW_OP_regx:
7131 printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
7132 data += bytes_read;
7133 break;
7134 case DW_OP_fbreg:
7135 printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
7136 data += bytes_read;
7137 break;
7138 case DW_OP_bregx:
7139 uvalue = read_leb128 (data, &bytes_read, 0);
7140 data += bytes_read;
7141 printf ("DW_OP_bregx: %lu %ld", uvalue,
7142 read_leb128 (data, &bytes_read, 1));
7143 data += bytes_read;
7144 break;
7145 case DW_OP_piece:
7146 printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
7147 data += bytes_read;
7148 break;
7149 case DW_OP_deref_size:
7150 printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
7151 break;
7152 case DW_OP_xderef_size:
7153 printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
7154 break;
7155 case DW_OP_nop:
7156 printf ("DW_OP_nop");
7157 break;
7158
12ab83a9
NC
7159 /* DWARF 2.1 extensions. */
7160 case DW_OP_push_object_address:
7161 printf ("DW_OP_push_object_address");
7162 break;
7163 case DW_OP_call2:
7164 printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2));
7165 data += 2;
7166 break;
7167 case DW_OP_call4:
7168 printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4));
7169 data += 4;
7170 break;
7171 case DW_OP_calli:
7172 printf ("DW_OP_calli");
7173 break;
7174
eb6bd4d3
JM
7175 default:
7176 if (op >= DW_OP_lo_user
7177 && op <= DW_OP_hi_user)
7178 printf (_("(User defined location op)"));
7179 else
7180 printf (_("(Unknown location op)"));
7181 /* No way to tell where the next op is, so just bail. */
7182 return;
7183 }
12ab83a9
NC
7184
7185 /* Separate the ops. */
7186 printf ("; ");
252b5132
RH
7187 }
7188}
7189
7190
261a45ad
NC
7191static const char * debug_str_contents;
7192static bfd_vma debug_str_size;
7193
7194static void
7195load_debug_str (file)
7196 FILE * file;
7197{
7198 Elf32_Internal_Shdr * sec;
9ad5cbcf 7199 unsigned int i;
261a45ad
NC
7200
7201 /* If it is already loaded, do nothing. */
7202 if (debug_str_contents != NULL)
7203 return;
7204
7205 /* Locate the .debug_str section. */
7206 for (i = 0, sec = section_headers;
7207 i < elf_header.e_shnum;
7208 i ++, sec ++)
7209 if (strcmp (SECTION_NAME (sec), ".debug_str") == 0)
7210 break;
7211
7212 if (i == elf_header.e_shnum || sec->sh_size == 0)
7213 return;
7214
7215 debug_str_size = sec->sh_size;
7216
7217 debug_str_contents = ((char *)
7218 get_data (NULL, file, sec->sh_offset, sec->sh_size,
7219 _("debug_str section data")));
7220}
7221
7222static void
7223free_debug_str ()
7224{
7225 if (debug_str_contents == NULL)
7226 return;
7227
7228 free ((char *) debug_str_contents);
7229 debug_str_contents = NULL;
7230 debug_str_size = 0;
7231}
7232
7233static const char *
7234fetch_indirect_string (offset)
7235 unsigned long offset;
7236{
7237 if (debug_str_contents == NULL)
7238 return _("<no .debug_str section>");
7239
7240 if (offset > debug_str_size)
7241 return _("<offset is too big>");
7242
7243 return debug_str_contents + offset;
7244}
7245
7246
7247static int
7248display_debug_str (section, start, file)
7249 Elf32_Internal_Shdr * section;
7250 unsigned char * start;
7251 FILE * file ATTRIBUTE_UNUSED;
7252{
7253 unsigned long bytes;
7254 bfd_vma addr;
7255
7256 addr = section->sh_addr;
7257 bytes = section->sh_size;
7258
7259 if (bytes == 0)
7260 {
7261 printf (_("\nThe .debug_str section is empty.\n"));
7262 return 0;
7263 }
7264
7265 printf (_("Contents of the .debug_str section:\n\n"));
7266
7267 while (bytes)
7268 {
7269 int j;
7270 int k;
7271 int lbytes;
7272
7273 lbytes = (bytes > 16 ? 16 : bytes);
7274
7275 printf (" 0x%8.8lx ", (unsigned long) addr);
7276
7277 for (j = 0; j < 16; j++)
7278 {
7279 if (j < lbytes)
7280 printf ("%2.2x", start [j]);
7281 else
7282 printf (" ");
7283
7284 if ((j & 3) == 3)
7285 printf (" ");
7286 }
7287
7288 for (j = 0; j < lbytes; j++)
7289 {
7290 k = start [j];
7291 if (k >= ' ' && k < 0x80)
7292 printf ("%c", k);
7293 else
7294 printf (".");
7295 }
7296
7297 putchar ('\n');
7298
7299 start += lbytes;
7300 addr += lbytes;
7301 bytes -= lbytes;
7302 }
7303
7304 return 1;
7305}
7306
7307
252b5132 7308static unsigned char *
81766fca 7309read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size)
252b5132
RH
7310 unsigned long attribute;
7311 unsigned long form;
7312 unsigned char * data;
1fa37306 7313 unsigned long cu_offset;
252b5132
RH
7314 unsigned long pointer_size;
7315{
b4c96d0d
ILT
7316 unsigned long uvalue = 0;
7317 unsigned char * block_start = NULL;
252b5132 7318 int bytes_read;
252b5132 7319
252b5132
RH
7320 switch (form)
7321 {
60bcf0fa
NC
7322 default:
7323 break;
76da6bbe 7324
252b5132
RH
7325 case DW_FORM_ref_addr:
7326 case DW_FORM_addr:
7327 uvalue = byte_get (data, pointer_size);
252b5132
RH
7328 data += pointer_size;
7329 break;
7330
ef5cdfc7
JJ
7331 case DW_FORM_strp:
7332 uvalue = byte_get (data, /* offset_size */ 4);
7333 data += /* offset_size */ 4;
7334 break;
7335
252b5132
RH
7336 case DW_FORM_ref1:
7337 case DW_FORM_flag:
7338 case DW_FORM_data1:
7339 uvalue = byte_get (data ++, 1);
252b5132
RH
7340 break;
7341
7342 case DW_FORM_ref2:
7343 case DW_FORM_data2:
7344 uvalue = byte_get (data, 2);
7345 data += 2;
252b5132
RH
7346 break;
7347
7348 case DW_FORM_ref4:
7349 case DW_FORM_data4:
7350 uvalue = byte_get (data, 4);
7351 data += 4;
1fa37306
JM
7352 break;
7353
7354 case DW_FORM_sdata:
7355 uvalue = read_leb128 (data, & bytes_read, 1);
7356 data += bytes_read;
7357 break;
7358
7359 case DW_FORM_ref_udata:
7360 case DW_FORM_udata:
7361 uvalue = read_leb128 (data, & bytes_read, 0);
7362 data += bytes_read;
7363 break;
81766fca
RH
7364
7365 case DW_FORM_indirect:
7366 form = read_leb128 (data, & bytes_read, 0);
7367 data += bytes_read;
7368 printf (" %s", get_FORM_name (form));
7369 return read_and_display_attr_value (attribute, form, data, cu_offset,
7370 pointer_size);
1fa37306
JM
7371 }
7372
7373 switch (form)
7374 {
7375 case DW_FORM_ref_addr:
7376 printf (" <#%lx>", uvalue);
7377 break;
76da6bbe 7378
1fa37306
JM
7379 case DW_FORM_ref1:
7380 case DW_FORM_ref2:
7381 case DW_FORM_ref4:
7382 case DW_FORM_ref_udata:
7383 printf (" <%lx>", uvalue + cu_offset);
7384 break;
7385
7386 case DW_FORM_addr:
7387 printf (" %#lx", uvalue);
7388
7389 case DW_FORM_flag:
7390 case DW_FORM_data1:
7391 case DW_FORM_data2:
7392 case DW_FORM_data4:
7393 case DW_FORM_sdata:
7394 case DW_FORM_udata:
7395 printf (" %ld", uvalue);
252b5132
RH
7396 break;
7397
7398 case DW_FORM_ref8:
7399 case DW_FORM_data8:
7400 uvalue = byte_get (data, 4);
7401 printf (" %lx", uvalue);
148d3c43 7402 printf (" %lx", (unsigned long) byte_get (data + 4, 4));
252b5132
RH
7403 data += 8;
7404 break;
7405
7406 case DW_FORM_string:
7407 printf (" %s", data);
3c9f43b1 7408 data += strlen ((char *) data) + 1;
252b5132
RH
7409 break;
7410
252b5132
RH
7411 case DW_FORM_block:
7412 uvalue = read_leb128 (data, & bytes_read, 0);
7413 block_start = data + bytes_read;
7414 data = display_block (block_start, uvalue);
252b5132
RH
7415 break;
7416
7417 case DW_FORM_block1:
7418 uvalue = byte_get (data, 1);
7419 block_start = data + 1;
7420 data = display_block (block_start, uvalue);
252b5132
RH
7421 break;
7422
7423 case DW_FORM_block2:
7424 uvalue = byte_get (data, 2);
7425 block_start = data + 2;
7426 data = display_block (block_start, uvalue);
252b5132
RH
7427 break;
7428
7429 case DW_FORM_block4:
7430 uvalue = byte_get (data, 4);
7431 block_start = data + 4;
7432 data = display_block (block_start, uvalue);
252b5132
RH
7433 break;
7434
7435 case DW_FORM_strp:
261a45ad
NC
7436 printf (_(" (indirect string, offset: 0x%lx): "), uvalue);
7437 printf (fetch_indirect_string (uvalue));
ef5cdfc7
JJ
7438 break;
7439
252b5132 7440 case DW_FORM_indirect:
e3c8793a 7441 /* Handled above. */
252b5132
RH
7442 break;
7443
7444 default:
2c71103e 7445 warn (_("Unrecognized form: %d\n"), form);
252b5132
RH
7446 break;
7447 }
7448
7449 /* For some attributes we can display futher information. */
7450
7451 printf ("\t");
7452
7453 switch (attribute)
7454 {
7455 case DW_AT_inline:
7456 switch (uvalue)
7457 {
7458 case DW_INL_not_inlined: printf (_("(not inlined)")); break;
7459 case DW_INL_inlined: printf (_("(inlined)")); break;
7460 case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
7461 case DW_INL_declared_inlined: printf (_("(declared as inline and inlined)")); break;
7462 default: printf (_(" (Unknown inline attribute value: %lx)"), uvalue); break;
7463 }
7464 break;
7465
252b5132
RH
7466 case DW_AT_language:
7467 switch (uvalue)
7468 {
7469 case DW_LANG_C: printf ("(non-ANSI C)"); break;
7470 case DW_LANG_C89: printf ("(ANSI C)"); break;
7471 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
7472 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
7473 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
7474 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
7475 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
7476 case DW_LANG_Ada83: printf ("(Ada)"); break;
7477 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
7478 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
b811889f
NC
7479 /* DWARF 2.1 values. */
7480 case DW_LANG_C99: printf ("(ANSI C99)"); break;
7481 case DW_LANG_Ada95: printf ("(ADA 95)"); break;
f662939a 7482 case DW_LANG_Fortran95: printf ("(Fortran 95)"); break;
b811889f 7483 /* MIPS extension. */
252b5132
RH
7484 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
7485 default: printf ("(Unknown: %lx)", uvalue); break;
7486 }
7487 break;
7488
7489 case DW_AT_encoding:
7490 switch (uvalue)
7491 {
7492 case DW_ATE_void: printf ("(void)"); break;
7493 case DW_ATE_address: printf ("(machine address)"); break;
7494 case DW_ATE_boolean: printf ("(boolean)"); break;
7495 case DW_ATE_complex_float: printf ("(complex float)"); break;
7496 case DW_ATE_float: printf ("(float)"); break;
7497 case DW_ATE_signed: printf ("(signed)"); break;
7498 case DW_ATE_signed_char: printf ("(signed char)"); break;
7499 case DW_ATE_unsigned: printf ("(unsigned)"); break;
7500 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
b811889f
NC
7501 /* DWARF 2.1 value. */
7502 case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
252b5132
RH
7503 default:
7504 if (uvalue >= DW_ATE_lo_user
7505 && uvalue <= DW_ATE_hi_user)
7506 printf ("(user defined type)");
7507 else
7508 printf ("(unknown type)");
7509 break;
7510 }
7511 break;
7512
7513 case DW_AT_accessibility:
7514 switch (uvalue)
7515 {
7516 case DW_ACCESS_public: printf ("(public)"); break;
7517 case DW_ACCESS_protected: printf ("(protected)"); break;
7518 case DW_ACCESS_private: printf ("(private)"); break;
7519 default: printf ("(unknown accessibility)"); break;
7520 }
7521 break;
7522
7523 case DW_AT_visibility:
7524 switch (uvalue)
7525 {
7526 case DW_VIS_local: printf ("(local)"); break;
7527 case DW_VIS_exported: printf ("(exported)"); break;
7528 case DW_VIS_qualified: printf ("(qualified)"); break;
7529 default: printf ("(unknown visibility)"); break;
7530 }
7531 break;
7532
7533 case DW_AT_virtuality:
7534 switch (uvalue)
7535 {
7536 case DW_VIRTUALITY_none: printf ("(none)"); break;
7537 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
7538 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
7539 default: printf ("(unknown virtuality)"); break;
7540 }
7541 break;
7542
7543 case DW_AT_identifier_case:
7544 switch (uvalue)
7545 {
7546 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
7547 case DW_ID_up_case: printf ("(up_case)"); break;
7548 case DW_ID_down_case: printf ("(down_case)"); break;
7549 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
7550 default: printf ("(unknown case)"); break;
7551 }
7552 break;
7553
7554 case DW_AT_calling_convention:
7555 switch (uvalue)
7556 {
7557 case DW_CC_normal: printf ("(normal)"); break;
7558 case DW_CC_program: printf ("(program)"); break;
7559 case DW_CC_nocall: printf ("(nocall)"); break;
7560 default:
7561 if (uvalue >= DW_CC_lo_user
7562 && uvalue <= DW_CC_hi_user)
7563 printf ("(user defined)");
7564 else
7565 printf ("(unknown convention)");
7566 }
7567 break;
7568
12ab83a9
NC
7569 case DW_AT_ordering:
7570 switch (uvalue)
7571 {
7572 case -1: printf ("(undefined)"); break;
7573 case 0: printf ("(row major)"); break;
7574 case 1: printf ("(column major)"); break;
7575 }
7576 break;
7577
eb6bd4d3 7578 case DW_AT_frame_base:
252b5132
RH
7579 case DW_AT_location:
7580 case DW_AT_data_member_location:
7581 case DW_AT_vtable_elem_location:
12ab83a9
NC
7582 case DW_AT_allocated:
7583 case DW_AT_associated:
7584 case DW_AT_data_location:
7585 case DW_AT_stride:
7586 case DW_AT_upper_bound:
7587 case DW_AT_lower_bound:
eb6bd4d3
JM
7588 if (block_start)
7589 {
7590 printf ("(");
7591 decode_location_expression (block_start, pointer_size, uvalue);
7592 printf (")");
7593 }
252b5132
RH
7594 break;
7595
7596 default:
7597 break;
7598 }
7599
81766fca
RH
7600 return data;
7601}
7602
7603static unsigned char *
7604read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
7605 unsigned long attribute;
7606 unsigned long form;
7607 unsigned char * data;
7608 unsigned long cu_offset;
7609 unsigned long pointer_size;
7610{
7611 printf (" %-18s:", get_AT_name (attribute));
7612 data = read_and_display_attr_value (attribute, form, data, cu_offset,
7613 pointer_size);
252b5132
RH
7614 printf ("\n");
7615 return data;
7616}
7617
7618static int
7619display_debug_info (section, start, file)
7620 Elf32_Internal_Shdr * section;
7621 unsigned char * start;
7622 FILE * file;
7623{
7624 unsigned char * end = start + section->sh_size;
7625 unsigned char * section_begin = start;
7626
7627 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
7628
261a45ad 7629 load_debug_str (file);
ef5cdfc7 7630
252b5132
RH
7631 while (start < end)
7632 {
7633 DWARF2_External_CompUnit * external;
7634 DWARF2_Internal_CompUnit compunit;
c0e047e0 7635 Elf32_Internal_Shdr * relsec;
252b5132 7636 unsigned char * tags;
9ad5cbcf 7637 unsigned int i;
252b5132 7638 int level;
1fa37306 7639 unsigned long cu_offset;
252b5132
RH
7640
7641 external = (DWARF2_External_CompUnit *) start;
7642
7643 compunit.cu_length = BYTE_GET (external->cu_length);
7644 compunit.cu_version = BYTE_GET (external->cu_version);
7645 compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
7646 compunit.cu_pointer_size = BYTE_GET (external->cu_pointer_size);
7647
428409d5
NC
7648 if (compunit.cu_length == 0xffffffff)
7649 {
7650 warn (_("64-bit DWARF debug info is not supported yet.\n"));
7651 break;
7652 }
7653
c0e047e0
AO
7654 /* Check for RELA relocations in the abbrev_offset address, and
7655 apply them. */
7656 for (relsec = section_headers;
7657 relsec < section_headers + elf_header.e_shnum;
7658 ++relsec)
7659 {
9ad5cbcf 7660 unsigned long nrelas;
c0e047e0
AO
7661 Elf_Internal_Rela *rela, *rp;
7662 Elf32_Internal_Shdr *symsec;
7663 Elf_Internal_Sym *symtab;
7664 Elf_Internal_Sym *sym;
7665
7666 if (relsec->sh_type != SHT_RELA
9ad5cbcf 7667 || SECTION_HEADER (relsec->sh_info) != section)
c0e047e0
AO
7668 continue;
7669
7670 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7671 & rela, & nrelas))
7672 return 0;
7673
9ad5cbcf
AM
7674 symsec = SECTION_HEADER (relsec->sh_link);
7675 symtab = GET_ELF_SYMBOLS (file, symsec);
c0e047e0
AO
7676
7677 for (rp = rela; rp < rela + nrelas; ++rp)
7678 {
7679 if (rp->r_offset
7680 != (bfd_vma) ((unsigned char *) &external->cu_abbrev_offset
7681 - section_begin))
7682 continue;
0823fbca 7683
c0e047e0
AO
7684 if (is_32bit_elf)
7685 {
7686 sym = symtab + ELF32_R_SYM (rp->r_info);
7687
7688 if (ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
7689 {
e5fb9629 7690 warn (_("Skipping unexpected symbol type %u\n"),
c0e047e0
AO
7691 ELF32_ST_TYPE (sym->st_info));
7692 continue;
7693 }
7694 }
7695 else
7696 {
7697 sym = symtab + ELF64_R_SYM (rp->r_info);
7698
7699 if (ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
7700 {
e5fb9629 7701 warn (_("Skipping unexpected symbol type %u\n"),
c0e047e0
AO
7702 ELF64_ST_TYPE (sym->st_info));
7703 continue;
7704 }
7705 }
7706
7707 compunit.cu_abbrev_offset += rp->r_addend;
7708 break;
7709 }
7710
7711 free (rela);
7712 break;
7713 }
7714
252b5132 7715 tags = start + sizeof (* external);
1fa37306 7716 cu_offset = start - section_begin;
252b5132
RH
7717 start += compunit.cu_length + sizeof (external->cu_length);
7718
09fd7e38
JM
7719 printf (_(" Compilation Unit @ %lx:\n"), cu_offset);
7720 printf (_(" Length: %ld\n"), compunit.cu_length);
7721 printf (_(" Version: %d\n"), compunit.cu_version);
7722 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
7723 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
7724
252b5132
RH
7725 if (compunit.cu_version != 2)
7726 {
7727 warn (_("Only version 2 DWARF debug information is currently supported.\n"));
7728 continue;
7729 }
7730
261a45ad 7731 free_abbrevs ();
252b5132
RH
7732
7733 /* Read in the abbrevs used by this compilation unit. */
7734
7735 {
7736 Elf32_Internal_Shdr * sec;
7737 unsigned char * begin;
7738
7739 /* Locate the .debug_abbrev section and process it. */
7740 for (i = 0, sec = section_headers;
7741 i < elf_header.e_shnum;
7742 i ++, sec ++)
7743 if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
7744 break;
7745
ef5cdfc7 7746 if (i == elf_header.e_shnum || sec->sh_size == 0)
252b5132
RH
7747 {
7748 warn (_("Unable to locate .debug_abbrev section!\n"));
7749 return 0;
7750 }
7751
a6e9f9df 7752 begin = ((unsigned char *)
0823fbca 7753 get_data (NULL, file, sec->sh_offset, sec->sh_size,
a6e9f9df
AM
7754 _("debug_abbrev section data")));
7755 if (!begin)
7756 return 0;
252b5132
RH
7757
7758 process_abbrev_section (begin + compunit.cu_abbrev_offset,
7759 begin + sec->sh_size);
7760
7761 free (begin);
7762 }
7763
7764 level = 0;
7765 while (tags < start)
7766 {
7767 int bytes_read;
b4c96d0d 7768 unsigned long abbrev_number;
252b5132
RH
7769 abbrev_entry * entry;
7770 abbrev_attr * attr;
7771
7772 abbrev_number = read_leb128 (tags, & bytes_read, 0);
7773 tags += bytes_read;
7774
7775 /* A null DIE marks the end of a list of children. */
7776 if (abbrev_number == 0)
7777 {
7778 --level;
7779 continue;
7780 }
7781
7782 /* Scan through the abbreviation list until we reach the
7783 correct entry. */
7784 for (entry = first_abbrev;
7785 entry && entry->entry != abbrev_number;
7786 entry = entry->next)
7787 continue;
7788
7789 if (entry == NULL)
7790 {
b4c96d0d 7791 warn (_("Unable to locate entry %lu in the abbreviation table\n"),
252b5132
RH
7792 abbrev_number);
7793 return 0;
7794 }
7795
410f7a12
L
7796 printf (_(" <%d><%lx>: Abbrev Number: %lu (%s)\n"),
7797 level,
7798 (unsigned long) (tags - section_begin - bytes_read),
252b5132
RH
7799 abbrev_number,
7800 get_TAG_name (entry->tag));
7801
7802 for (attr = entry->first_attr; attr; attr = attr->next)
7803 tags = read_and_display_attr (attr->attribute,
7804 attr->form,
1fa37306 7805 tags, cu_offset,
252b5132
RH
7806 compunit.cu_pointer_size);
7807
7808 if (entry->children)
7809 ++level;
7810 }
7811 }
7812
261a45ad 7813 free_debug_str ();
ef5cdfc7 7814
252b5132
RH
7815 printf ("\n");
7816
7817 return 1;
7818}
7819
7820static int
7821display_debug_aranges (section, start, file)
7822 Elf32_Internal_Shdr * section;
7823 unsigned char * start;
b4c96d0d 7824 FILE * file ATTRIBUTE_UNUSED;
252b5132
RH
7825{
7826 unsigned char * end = start + section->sh_size;
7827
7828 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
7829
7830 while (start < end)
7831 {
7832 DWARF2_External_ARange * external;
7833 DWARF2_Internal_ARange arange;
7834 unsigned char * ranges;
7835 unsigned long length;
7836 unsigned long address;
7a4b7442 7837 int excess;
252b5132
RH
7838
7839 external = (DWARF2_External_ARange *) start;
7840
7841 arange.ar_length = BYTE_GET (external->ar_length);
7842 arange.ar_version = BYTE_GET (external->ar_version);
7843 arange.ar_info_offset = BYTE_GET (external->ar_info_offset);
7844 arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
7845 arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
7846
e414a165
NC
7847 if (arange.ar_length == 0xffffffff)
7848 {
428409d5 7849 warn (_("64-bit DWARF aranges are not supported yet.\n"));
e414a165
NC
7850 break;
7851 }
7852
3f215a10
NC
7853 if (arange.ar_version != 2)
7854 {
7855 warn (_("Only DWARF 2 aranges are currently supported.\n"));
7856 break;
7857 }
7858
252b5132
RH
7859 printf (_(" Length: %ld\n"), arange.ar_length);
7860 printf (_(" Version: %d\n"), arange.ar_version);
7861 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
7862 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
7863 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
7864
7865 printf (_("\n Address Length\n"));
7866
7867 ranges = start + sizeof (* external);
7868
7a4b7442 7869 /* Must pad to an alignment boundary that is twice the pointer size. */
584da044 7870 excess = sizeof (* external) % (2 * arange.ar_pointer_size);
7a4b7442
NC
7871 if (excess)
7872 ranges += (2 * arange.ar_pointer_size) - excess;
7873
252b5132
RH
7874 for (;;)
7875 {
7876 address = byte_get (ranges, arange.ar_pointer_size);
7877
252b5132
RH
7878 ranges += arange.ar_pointer_size;
7879
7880 length = byte_get (ranges, arange.ar_pointer_size);
7881
7882 ranges += arange.ar_pointer_size;
7883
7a4b7442
NC
7884 /* A pair of zeros marks the end of the list. */
7885 if (address == 0 && length == 0)
7886 break;
103f02d3 7887
252b5132
RH
7888 printf (" %8.8lx %lu\n", address, length);
7889 }
7890
7891 start += arange.ar_length + sizeof (external->ar_length);
7892 }
7893
7894 printf ("\n");
7895
7896 return 1;
7897}
7898
c47d488e
DD
7899typedef struct Frame_Chunk
7900{
584da044
NC
7901 struct Frame_Chunk * next;
7902 unsigned char * chunk_start;
7903 int ncols;
a98cc2b2 7904 /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */
584da044
NC
7905 short int * col_type;
7906 int * col_offset;
7907 char * augmentation;
7908 unsigned int code_factor;
31b6fca6 7909 int data_factor;
584da044
NC
7910 unsigned long pc_begin;
7911 unsigned long pc_range;
7912 int cfa_reg;
7913 int cfa_offset;
7914 int ra;
31b6fca6 7915 unsigned char fde_encoding;
c47d488e
DD
7916}
7917Frame_Chunk;
7918
a98cc2b2
AH
7919/* A marker for a col_type that means this column was never referenced
7920 in the frame info. */
7921#define DW_CFA_unreferenced (-1)
7922
2863d58a
AM
7923static void frame_need_space PARAMS ((Frame_Chunk *, int));
7924static void frame_display_row PARAMS ((Frame_Chunk *, int *, int *));
7925static int size_of_encoded_value PARAMS ((int));
7926
c47d488e
DD
7927static void
7928frame_need_space (fc, reg)
584da044 7929 Frame_Chunk * fc;
c47d488e
DD
7930 int reg;
7931{
7932 int prev = fc->ncols;
7933
7934 if (reg < fc->ncols)
7935 return;
584da044 7936
c47d488e 7937 fc->ncols = reg + 1;
a98cc2b2
AH
7938 fc->col_type = (short int *) xrealloc (fc->col_type,
7939 fc->ncols * sizeof (short int));
c47d488e
DD
7940 fc->col_offset = (int *) xrealloc (fc->col_offset,
7941 fc->ncols * sizeof (int));
7942
7943 while (prev < fc->ncols)
7944 {
a98cc2b2 7945 fc->col_type[prev] = DW_CFA_unreferenced;
c47d488e
DD
7946 fc->col_offset[prev] = 0;
7947 prev++;
7948 }
7949}
7950
7951static void
7952frame_display_row (fc, need_col_headers, max_regs)
584da044
NC
7953 Frame_Chunk * fc;
7954 int * need_col_headers;
7955 int * max_regs;
c47d488e
DD
7956{
7957 int r;
7958 char tmp[100];
7959
584da044
NC
7960 if (* max_regs < fc->ncols)
7961 * max_regs = fc->ncols;
7962
7963 if (* need_col_headers)
c47d488e 7964 {
584da044
NC
7965 * need_col_headers = 0;
7966
c47d488e 7967 printf (" LOC CFA ");
584da044
NC
7968
7969 for (r = 0; r < * max_regs; r++)
a98cc2b2
AH
7970 if (fc->col_type[r] != DW_CFA_unreferenced)
7971 {
7972 if (r == fc->ra)
7973 printf ("ra ");
7974 else
7975 printf ("r%-4d", r);
7976 }
584da044 7977
c47d488e
DD
7978 printf ("\n");
7979 }
584da044 7980
31b6fca6 7981 printf ("%08lx ", fc->pc_begin);
c47d488e
DD
7982 sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
7983 printf ("%-8s ", tmp);
584da044
NC
7984
7985 for (r = 0; r < fc->ncols; r++)
c47d488e 7986 {
a98cc2b2 7987 if (fc->col_type[r] != DW_CFA_unreferenced)
c47d488e 7988 {
a98cc2b2
AH
7989 switch (fc->col_type[r])
7990 {
7991 case DW_CFA_undefined:
7992 strcpy (tmp, "u");
7993 break;
7994 case DW_CFA_same_value:
7995 strcpy (tmp, "s");
7996 break;
7997 case DW_CFA_offset:
7998 sprintf (tmp, "c%+d", fc->col_offset[r]);
7999 break;
8000 case DW_CFA_register:
8001 sprintf (tmp, "r%d", fc->col_offset[r]);
8002 break;
8003 default:
8004 strcpy (tmp, "n/a");
8005 break;
8006 }
8007 printf ("%-5s", tmp);
c47d488e 8008 }
c47d488e
DD
8009 }
8010 printf ("\n");
8011}
8012
31b6fca6
RH
8013static int
8014size_of_encoded_value (encoding)
8015 int encoding;
8016{
8017 switch (encoding & 0x7)
8018 {
8019 default: /* ??? */
8020 case 0: return is_32bit_elf ? 4 : 8;
8021 case 2: return 2;
8022 case 3: return 4;
8023 case 4: return 8;
8024 }
8025}
8026
c47d488e 8027#define GET(N) byte_get (start, N); start += N
584da044
NC
8028#define LEB() read_leb128 (start, & length_return, 0); start += length_return
8029#define SLEB() read_leb128 (start, & length_return, 1); start += length_return
c47d488e
DD
8030
8031static int
8032display_debug_frames (section, start, file)
8033 Elf32_Internal_Shdr * section;
8034 unsigned char * start;
8035 FILE * file ATTRIBUTE_UNUSED;
8036{
8037 unsigned char * end = start + section->sh_size;
584da044
NC
8038 unsigned char * section_start = start;
8039 Frame_Chunk * chunks = 0;
8040 Frame_Chunk * remembered_state = 0;
8041 Frame_Chunk * rs;
8042 int is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
8043 int length_return;
8044 int max_regs = 0;
31b6fca6 8045 int addr_size = is_32bit_elf ? 4 : 8;
c47d488e
DD
8046
8047 printf (_("The section %s contains:\n"), SECTION_NAME (section));
8048
8049 while (start < end)
8050 {
584da044
NC
8051 unsigned char * saved_start;
8052 unsigned char * block_end;
8053 unsigned long length;
8054 unsigned long cie_id;
8055 Frame_Chunk * fc;
8056 Frame_Chunk * cie;
8057 int need_col_headers = 1;
31b6fca6
RH
8058 unsigned char * augmentation_data = NULL;
8059 unsigned long augmentation_data_len = 0;
8060 int encoded_ptr_size = addr_size;
c47d488e
DD
8061
8062 saved_start = start;
8063 length = byte_get (start, 4); start += 4;
8064
8065 if (length == 0)
8066 return 1;
8067
428409d5
NC
8068 if (length == 0xffffffff)
8069 {
8070 warn (_("64-bit DWARF format frames are not supported yet.\n"));
8071 break;
8072 }
8073
c47d488e
DD
8074 block_end = saved_start + length + 4;
8075 cie_id = byte_get (start, 4); start += 4;
8076
c47d488e
DD
8077 if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
8078 {
31b6fca6
RH
8079 int version;
8080
c47d488e
DD
8081 fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
8082 memset (fc, 0, sizeof (Frame_Chunk));
8083
8084 fc->next = chunks;
8085 chunks = fc;
8086 fc->chunk_start = saved_start;
8087 fc->ncols = 0;
a98cc2b2 8088 fc->col_type = (short int *) xmalloc (sizeof (short int));
c47d488e
DD
8089 fc->col_offset = (int *) xmalloc (sizeof (int));
8090 frame_need_space (fc, max_regs-1);
8091
31b6fca6 8092 version = *start++;
584da044 8093
31b6fca6
RH
8094 fc->augmentation = start;
8095 start = strchr (start, '\0') + 1;
584da044 8096
c47d488e
DD
8097 if (fc->augmentation[0] == 'z')
8098 {
c47d488e
DD
8099 fc->code_factor = LEB ();
8100 fc->data_factor = SLEB ();
8101 fc->ra = byte_get (start, 1); start += 1;
31b6fca6
RH
8102 augmentation_data_len = LEB ();
8103 augmentation_data = start;
8104 start += augmentation_data_len;
c47d488e
DD
8105 }
8106 else if (strcmp (fc->augmentation, "eh") == 0)
8107 {
31b6fca6 8108 start += addr_size;
c47d488e
DD
8109 fc->code_factor = LEB ();
8110 fc->data_factor = SLEB ();
8111 fc->ra = byte_get (start, 1); start += 1;
8112 }
8113 else
8114 {
8115 fc->code_factor = LEB ();
8116 fc->data_factor = SLEB ();
8117 fc->ra = byte_get (start, 1); start += 1;
8118 }
8119 cie = fc;
31b6fca6
RH
8120
8121 if (do_debug_frames_interp)
8122 printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
7036c0e1 8123 (unsigned long)(saved_start - section_start), length, cie_id,
31b6fca6
RH
8124 fc->augmentation, fc->code_factor, fc->data_factor,
8125 fc->ra);
8126 else
8127 {
8128 printf ("\n%08lx %08lx %08lx CIE\n",
7036c0e1 8129 (unsigned long)(saved_start - section_start), length, cie_id);
31b6fca6
RH
8130 printf (" Version: %d\n", version);
8131 printf (" Augmentation: \"%s\"\n", fc->augmentation);
8132 printf (" Code alignment factor: %u\n", fc->code_factor);
8133 printf (" Data alignment factor: %d\n", fc->data_factor);
8134 printf (" Return address column: %d\n", fc->ra);
8135
8136 if (augmentation_data_len)
8137 {
8138 unsigned long i;
8139 printf (" Augmentation data: ");
8140 for (i = 0; i < augmentation_data_len; ++i)
8141 printf (" %02x", augmentation_data[i]);
8142 putchar ('\n');
8143 }
8144 putchar ('\n');
8145 }
8146
8147 if (augmentation_data_len)
8148 {
8149 unsigned char *p, *q;
8150 p = fc->augmentation + 1;
8151 q = augmentation_data;
8152
8153 while (1)
8154 {
8155 if (*p == 'L')
7036c0e1 8156 q++;
31b6fca6
RH
8157 else if (*p == 'P')
8158 q += 1 + size_of_encoded_value (*q);
8159 else if (*p == 'R')
8160 fc->fde_encoding = *q++;
8161 else
8162 break;
8163 p++;
8164 }
8165
8166 if (fc->fde_encoding)
8167 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
8168 }
c47d488e
DD
8169
8170 frame_need_space (fc, fc->ra);
8171 }
8172 else
8173 {
584da044 8174 unsigned char * look_for;
c47d488e 8175 static Frame_Chunk fde_fc;
584da044
NC
8176
8177 fc = & fde_fc;
c47d488e
DD
8178 memset (fc, 0, sizeof (Frame_Chunk));
8179
31b6fca6 8180 look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
c47d488e 8181
428409d5 8182 for (cie = chunks; cie ; cie = cie->next)
31b6fca6
RH
8183 if (cie->chunk_start == look_for)
8184 break;
c47d488e 8185
c47d488e
DD
8186 if (!cie)
8187 {
31b6fca6
RH
8188 warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
8189 cie_id, saved_start);
c47d488e
DD
8190 start = block_end;
8191 fc->ncols = 0;
a98cc2b2 8192 fc->col_type = (short int *) xmalloc (sizeof (short int));
c47d488e 8193 fc->col_offset = (int *) xmalloc (sizeof (int));
584da044 8194 frame_need_space (fc, max_regs - 1);
c47d488e
DD
8195 cie = fc;
8196 fc->augmentation = "";
31b6fca6 8197 fc->fde_encoding = 0;
c47d488e
DD
8198 }
8199 else
8200 {
8201 fc->ncols = cie->ncols;
a98cc2b2 8202 fc->col_type = (short int *) xmalloc (fc->ncols * sizeof (short int));
c47d488e 8203 fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
a98cc2b2 8204 memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
c47d488e
DD
8205 memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
8206 fc->augmentation = cie->augmentation;
8207 fc->code_factor = cie->code_factor;
8208 fc->data_factor = cie->data_factor;
8209 fc->cfa_reg = cie->cfa_reg;
8210 fc->cfa_offset = cie->cfa_offset;
8211 fc->ra = cie->ra;
8212 frame_need_space (fc, max_regs-1);
31b6fca6 8213 fc->fde_encoding = cie->fde_encoding;
c47d488e
DD
8214 }
8215
31b6fca6
RH
8216 if (fc->fde_encoding)
8217 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
8218
8219 fc->pc_begin = byte_get (start, encoded_ptr_size);
8220 start += encoded_ptr_size;
8221 fc->pc_range = byte_get (start, encoded_ptr_size);
8222 start += encoded_ptr_size;
8223
c47d488e
DD
8224 if (cie->augmentation[0] == 'z')
8225 {
31b6fca6
RH
8226 augmentation_data_len = LEB ();
8227 augmentation_data = start;
8228 start += augmentation_data_len;
c47d488e
DD
8229 }
8230
410f7a12 8231 printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
7036c0e1 8232 (unsigned long)(saved_start - section_start), length, cie_id,
410f7a12
L
8233 (unsigned long)(cie->chunk_start - section_start),
8234 fc->pc_begin, fc->pc_begin + fc->pc_range);
31b6fca6
RH
8235 if (! do_debug_frames_interp && augmentation_data_len)
8236 {
8237 unsigned long i;
8238 printf (" Augmentation data: ");
8239 for (i = 0; i < augmentation_data_len; ++i)
8240 printf (" %02x", augmentation_data[i]);
8241 putchar ('\n');
8242 putchar ('\n');
8243 }
c47d488e
DD
8244 }
8245
8246 /* At this point, fc is the current chunk, cie (if any) is set, and we're
8247 about to interpret instructions for the chunk. */
8248
31b6fca6 8249 if (do_debug_frames_interp)
a98cc2b2
AH
8250 {
8251 /* Start by making a pass over the chunk, allocating storage
8252 and taking note of what registers are used. */
584da044 8253 unsigned char * tmp = start;
a98cc2b2 8254
a98cc2b2
AH
8255 while (start < block_end)
8256 {
8257 unsigned op, opa;
8258 unsigned long reg;
7036c0e1 8259
584da044 8260 op = * start ++;
a98cc2b2
AH
8261 opa = op & 0x3f;
8262 if (op & 0xc0)
8263 op &= 0xc0;
7036c0e1 8264
a98cc2b2
AH
8265 /* Warning: if you add any more cases to this switch, be
8266 sure to add them to the corresponding switch below. */
8267 switch (op)
8268 {
8269 case DW_CFA_advance_loc:
8270 break;
8271 case DW_CFA_offset:
8272 LEB ();
8273 frame_need_space (fc, opa);
8274 fc->col_type[opa] = DW_CFA_undefined;
8275 break;
8276 case DW_CFA_restore:
8277 frame_need_space (fc, opa);
8278 fc->col_type[opa] = DW_CFA_undefined;
8279 break;
8280 case DW_CFA_set_loc:
31b6fca6 8281 start += encoded_ptr_size;
a98cc2b2
AH
8282 break;
8283 case DW_CFA_advance_loc1:
8284 start += 1;
8285 break;
8286 case DW_CFA_advance_loc2:
8287 start += 2;
8288 break;
8289 case DW_CFA_advance_loc4:
8290 start += 4;
8291 break;
8292 case DW_CFA_offset_extended:
8293 reg = LEB (); LEB ();
8294 frame_need_space (fc, reg);
8295 fc->col_type[reg] = DW_CFA_undefined;
8296 break;
8297 case DW_CFA_restore_extended:
8298 reg = LEB ();
8299 frame_need_space (fc, reg);
8300 fc->col_type[reg] = DW_CFA_undefined;
8301 break;
8302 case DW_CFA_undefined:
8303 reg = LEB ();
8304 frame_need_space (fc, reg);
8305 fc->col_type[reg] = DW_CFA_undefined;
8306 break;
8307 case DW_CFA_same_value:
8308 reg = LEB ();
8309 frame_need_space (fc, reg);
8310 fc->col_type[reg] = DW_CFA_undefined;
8311 break;
8312 case DW_CFA_register:
8313 reg = LEB (); LEB ();
8314 frame_need_space (fc, reg);
8315 fc->col_type[reg] = DW_CFA_undefined;
8316 break;
8317 case DW_CFA_def_cfa:
8318 LEB (); LEB ();
8319 break;
8320 case DW_CFA_def_cfa_register:
8321 LEB ();
8322 break;
8323 case DW_CFA_def_cfa_offset:
8324 LEB ();
8325 break;
8326#ifndef DW_CFA_GNU_args_size
8327#define DW_CFA_GNU_args_size 0x2e
8328#endif
8329 case DW_CFA_GNU_args_size:
8330 LEB ();
7036c0e1 8331 break;
a98cc2b2
AH
8332#ifndef DW_CFA_GNU_negative_offset_extended
8333#define DW_CFA_GNU_negative_offset_extended 0x2f
8334#endif
8335 case DW_CFA_GNU_negative_offset_extended:
7036c0e1 8336 reg = LEB (); LEB ();
a98cc2b2
AH
8337 frame_need_space (fc, reg);
8338 fc->col_type[reg] = DW_CFA_undefined;
7036c0e1 8339
a98cc2b2
AH
8340 default:
8341 break;
8342 }
8343 }
8344 start = tmp;
8345 }
8346
8347 /* Now we know what registers are used, make a second pass over
8348 the chunk, this time actually printing out the info. */
8349
c47d488e
DD
8350 while (start < block_end)
8351 {
8352 unsigned op, opa;
8353 unsigned long ul, reg, roffs;
8354 long l, ofs;
8355 bfd_vma vma;
8356
8357 op = * start ++;
8358 opa = op & 0x3f;
8359 if (op & 0xc0)
8360 op &= 0xc0;
8361
a98cc2b2
AH
8362 /* Warning: if you add any more cases to this switch, be
8363 sure to add them to the corresponding switch above. */
c47d488e
DD
8364 switch (op)
8365 {
8366 case DW_CFA_advance_loc:
31b6fca6
RH
8367 if (do_debug_frames_interp)
8368 frame_display_row (fc, &need_col_headers, &max_regs);
8369 else
8370 printf (" DW_CFA_advance_loc: %d to %08lx\n",
8371 opa * fc->code_factor,
8372 fc->pc_begin + opa * fc->code_factor);
c47d488e
DD
8373 fc->pc_begin += opa * fc->code_factor;
8374 break;
8375
8376 case DW_CFA_offset:
c47d488e 8377 roffs = LEB ();
31b6fca6 8378 if (! do_debug_frames_interp)
7036c0e1 8379 printf (" DW_CFA_offset: r%d at cfa%+ld\n",
31b6fca6 8380 opa, roffs * fc->data_factor);
c47d488e
DD
8381 fc->col_type[opa] = DW_CFA_offset;
8382 fc->col_offset[opa] = roffs * fc->data_factor;
8383 break;
8384
8385 case DW_CFA_restore:
31b6fca6
RH
8386 if (! do_debug_frames_interp)
8387 printf (" DW_CFA_restore: r%d\n", opa);
c47d488e
DD
8388 fc->col_type[opa] = cie->col_type[opa];
8389 fc->col_offset[opa] = cie->col_offset[opa];
8390 break;
8391
8392 case DW_CFA_set_loc:
31b6fca6
RH
8393 vma = byte_get (start, encoded_ptr_size);
8394 start += encoded_ptr_size;
8395 if (do_debug_frames_interp)
8396 frame_display_row (fc, &need_col_headers, &max_regs);
8397 else
7036c0e1 8398 printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
c47d488e
DD
8399 fc->pc_begin = vma;
8400 break;
8401
8402 case DW_CFA_advance_loc1:
c47d488e 8403 ofs = byte_get (start, 1); start += 1;
31b6fca6
RH
8404 if (do_debug_frames_interp)
8405 frame_display_row (fc, &need_col_headers, &max_regs);
8406 else
7036c0e1 8407 printf (" DW_CFA_advance_loc1: %ld to %08lx\n",
31b6fca6
RH
8408 ofs * fc->code_factor,
8409 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
8410 fc->pc_begin += ofs * fc->code_factor;
8411 break;
8412
8413 case DW_CFA_advance_loc2:
c47d488e 8414 ofs = byte_get (start, 2); start += 2;
31b6fca6
RH
8415 if (do_debug_frames_interp)
8416 frame_display_row (fc, &need_col_headers, &max_regs);
8417 else
7036c0e1 8418 printf (" DW_CFA_advance_loc2: %ld to %08lx\n",
31b6fca6
RH
8419 ofs * fc->code_factor,
8420 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
8421 fc->pc_begin += ofs * fc->code_factor;
8422 break;
8423
8424 case DW_CFA_advance_loc4:
c47d488e 8425 ofs = byte_get (start, 4); start += 4;
31b6fca6
RH
8426 if (do_debug_frames_interp)
8427 frame_display_row (fc, &need_col_headers, &max_regs);
8428 else
7036c0e1 8429 printf (" DW_CFA_advance_loc4: %ld to %08lx\n",
31b6fca6
RH
8430 ofs * fc->code_factor,
8431 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
8432 fc->pc_begin += ofs * fc->code_factor;
8433 break;
8434
8435 case DW_CFA_offset_extended:
8436 reg = LEB ();
8437 roffs = LEB ();
31b6fca6 8438 if (! do_debug_frames_interp)
7036c0e1 8439 printf (" DW_CFA_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 8440 reg, roffs * fc->data_factor);
c47d488e
DD
8441 fc->col_type[reg] = DW_CFA_offset;
8442 fc->col_offset[reg] = roffs * fc->data_factor;
8443 break;
8444
8445 case DW_CFA_restore_extended:
8446 reg = LEB ();
31b6fca6 8447 if (! do_debug_frames_interp)
7036c0e1 8448 printf (" DW_CFA_restore_extended: r%ld\n", reg);
c47d488e
DD
8449 fc->col_type[reg] = cie->col_type[reg];
8450 fc->col_offset[reg] = cie->col_offset[reg];
8451 break;
8452
8453 case DW_CFA_undefined:
8454 reg = LEB ();
31b6fca6 8455 if (! do_debug_frames_interp)
7036c0e1 8456 printf (" DW_CFA_undefined: r%ld\n", reg);
c47d488e
DD
8457 fc->col_type[reg] = DW_CFA_undefined;
8458 fc->col_offset[reg] = 0;
8459 break;
8460
8461 case DW_CFA_same_value:
8462 reg = LEB ();
31b6fca6 8463 if (! do_debug_frames_interp)
7036c0e1 8464 printf (" DW_CFA_same_value: r%ld\n", reg);
c47d488e
DD
8465 fc->col_type[reg] = DW_CFA_same_value;
8466 fc->col_offset[reg] = 0;
8467 break;
8468
8469 case DW_CFA_register:
8470 reg = LEB ();
8471 roffs = LEB ();
31b6fca6 8472 if (! do_debug_frames_interp)
7036c0e1 8473 printf (" DW_CFA_register: r%ld\n", reg);
c47d488e
DD
8474 fc->col_type[reg] = DW_CFA_register;
8475 fc->col_offset[reg] = roffs;
8476 break;
8477
8478 case DW_CFA_remember_state:
31b6fca6
RH
8479 if (! do_debug_frames_interp)
8480 printf (" DW_CFA_remember_state\n");
c47d488e
DD
8481 rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
8482 rs->ncols = fc->ncols;
a98cc2b2 8483 rs->col_type = (short int *) xmalloc (rs->ncols * sizeof (short int));
c47d488e
DD
8484 rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
8485 memcpy (rs->col_type, fc->col_type, rs->ncols);
8486 memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
8487 rs->next = remembered_state;
8488 remembered_state = rs;
8489 break;
8490
8491 case DW_CFA_restore_state:
31b6fca6
RH
8492 if (! do_debug_frames_interp)
8493 printf (" DW_CFA_restore_state\n");
c47d488e
DD
8494 rs = remembered_state;
8495 remembered_state = rs->next;
8496 frame_need_space (fc, rs->ncols-1);
8497 memcpy (fc->col_type, rs->col_type, rs->ncols);
8498 memcpy (fc->col_offset, rs->col_offset, rs->ncols * sizeof (int));
8499 free (rs->col_type);
8500 free (rs->col_offset);
8501 free (rs);
8502 break;
8503
8504 case DW_CFA_def_cfa:
8505 fc->cfa_reg = LEB ();
8506 fc->cfa_offset = LEB ();
31b6fca6
RH
8507 if (! do_debug_frames_interp)
8508 printf (" DW_CFA_def_cfa: r%d ofs %d\n",
8509 fc->cfa_reg, fc->cfa_offset);
c47d488e
DD
8510 break;
8511
8512 case DW_CFA_def_cfa_register:
8513 fc->cfa_reg = LEB ();
31b6fca6
RH
8514 if (! do_debug_frames_interp)
8515 printf (" DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
c47d488e
DD
8516 break;
8517
8518 case DW_CFA_def_cfa_offset:
8519 fc->cfa_offset = LEB ();
31b6fca6
RH
8520 if (! do_debug_frames_interp)
8521 printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
c47d488e
DD
8522 break;
8523
8524 case DW_CFA_nop:
31b6fca6
RH
8525 if (! do_debug_frames_interp)
8526 printf (" DW_CFA_nop\n");
c47d488e
DD
8527 break;
8528
8529#ifndef DW_CFA_GNU_window_save
8530#define DW_CFA_GNU_window_save 0x2d
8531#endif
8532 case DW_CFA_GNU_window_save:
31b6fca6
RH
8533 if (! do_debug_frames_interp)
8534 printf (" DW_CFA_GNU_window_save\n");
c47d488e
DD
8535 break;
8536
c47d488e
DD
8537 case DW_CFA_GNU_args_size:
8538 ul = LEB ();
31b6fca6 8539 if (! do_debug_frames_interp)
7036c0e1 8540 printf (" DW_CFA_GNU_args_size: %ld\n", ul);
c47d488e
DD
8541 break;
8542
c47d488e
DD
8543 case DW_CFA_GNU_negative_offset_extended:
8544 reg = LEB ();
8545 l = - LEB ();
8546 frame_need_space (fc, reg);
31b6fca6 8547 if (! do_debug_frames_interp)
7036c0e1 8548 printf (" DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 8549 reg, l * fc->data_factor);
c47d488e
DD
8550 fc->col_type[reg] = DW_CFA_offset;
8551 fc->col_offset[reg] = l * fc->data_factor;
8552 break;
8553
8554 default:
8555 fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
8556 start = block_end;
8557 }
8558 }
8559
31b6fca6
RH
8560 if (do_debug_frames_interp)
8561 frame_display_row (fc, &need_col_headers, &max_regs);
c47d488e
DD
8562
8563 start = block_end;
8564 }
8565
8566 printf ("\n");
8567
8568 return 1;
8569}
8570
8571#undef GET
8572#undef LEB
8573#undef SLEB
252b5132
RH
8574
8575static int
8576display_debug_not_supported (section, start, file)
8577 Elf32_Internal_Shdr * section;
b4c96d0d
ILT
8578 unsigned char * start ATTRIBUTE_UNUSED;
8579 FILE * file ATTRIBUTE_UNUSED;
252b5132
RH
8580{
8581 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
8582 SECTION_NAME (section));
8583
8584 return 1;
8585}
8586
3590ea00
NC
8587/* Pre-scan the .debug_info section to record the size of address.
8588 When dumping the .debug_line, we use that size information, assuming
8589 that all compilation units have the same address size. */
8590static int
8591prescan_debug_info (section, start, file)
8592 Elf32_Internal_Shdr * section ATTRIBUTE_UNUSED;
8593 unsigned char * start;
8594 FILE * file ATTRIBUTE_UNUSED;
8595{
8596 DWARF2_External_CompUnit * external;
8597
8598 external = (DWARF2_External_CompUnit *) start;
8599
8600 debug_line_pointer_size = BYTE_GET (external->cu_pointer_size);
8601 return 0;
8602}
8603
252b5132 8604 /* A structure containing the name of a debug section and a pointer
3590ea00
NC
8605 to a function that can decode it. The third field is a prescan
8606 function to be run over the section before displaying any of the
8607 sections. */
252b5132
RH
8608struct
8609{
261a45ad 8610 const char * const name;
3590ea00
NC
8611 int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
8612 int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
252b5132
RH
8613}
8614debug_displays[] =
8615{
3590ea00 8616 { ".debug_abbrev", display_debug_abbrev, NULL },
3590ea00 8617 { ".debug_aranges", display_debug_aranges, NULL },
c47d488e 8618 { ".debug_frame", display_debug_frames, NULL },
261a45ad
NC
8619 { ".debug_info", display_debug_info, prescan_debug_info },
8620 { ".debug_line", display_debug_lines, NULL },
8621 { ".debug_pubnames", display_debug_pubnames, NULL },
c47d488e 8622 { ".eh_frame", display_debug_frames, NULL },
e0c60db2 8623 { ".debug_macinfo", display_debug_macinfo, NULL },
261a45ad
NC
8624 { ".debug_str", display_debug_str, NULL },
8625
428409d5 8626 { ".debug_pubtypes", display_debug_not_supported, NULL },
261a45ad 8627 { ".debug_ranges", display_debug_not_supported, NULL },
3590ea00
NC
8628 { ".debug_static_func", display_debug_not_supported, NULL },
8629 { ".debug_static_vars", display_debug_not_supported, NULL },
8630 { ".debug_types", display_debug_not_supported, NULL },
8631 { ".debug_weaknames", display_debug_not_supported, NULL }
252b5132
RH
8632};
8633
8634static int
8635display_debug_section (section, file)
8636 Elf32_Internal_Shdr * section;
8637 FILE * file;
8638{
8639 char * name = SECTION_NAME (section);
8640 bfd_size_type length;
8641 unsigned char * start;
8642 int i;
8643
8644 length = section->sh_size;
8645 if (length == 0)
8646 {
8647 printf (_("\nSection '%s' has no debugging data.\n"), name);
8648 return 0;
8649 }
8650
0823fbca 8651 start = (unsigned char *) get_data (NULL, file, section->sh_offset, length,
a6e9f9df
AM
8652 _("debug section data"));
8653 if (!start)
8654 return 0;
252b5132
RH
8655
8656 /* See if we know how to display the contents of this section. */
09fd7e38 8657 if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
7036c0e1 8658 name = ".debug_info";
584da044 8659
252b5132
RH
8660 for (i = NUM_ELEM (debug_displays); i--;)
8661 if (strcmp (debug_displays[i].name, name) == 0)
8662 {
8663 debug_displays[i].display (section, start, file);
8664 break;
8665 }
8666
8667 if (i == -1)
2c71103e 8668 printf (_("Unrecognized debug section: %s\n"), name);
252b5132
RH
8669
8670 free (start);
8671
8672 /* If we loaded in the abbrev section at some point,
8673 we must release it here. */
261a45ad 8674 free_abbrevs ();
252b5132
RH
8675
8676 return 1;
8677}
8678
8679static int
8680process_section_contents (file)
8681 FILE * file;
8682{
3590ea00 8683 Elf32_Internal_Shdr * section;
7036c0e1 8684 unsigned int i;
252b5132
RH
8685
8686 if (! do_dump)
8687 return 1;
8688
3590ea00
NC
8689 /* Pre-scan the debug sections to find some debug information not
8690 present in some of them. For the .debug_line, we must find out the
8691 size of address (specified in .debug_info and .debug_aranges). */
8692 for (i = 0, section = section_headers;
8693 i < elf_header.e_shnum && i < num_dump_sects;
8694 i ++, section ++)
8695 {
8696 char * name = SECTION_NAME (section);
8697 int j;
8698
8699 if (section->sh_size == 0)
8700 continue;
8701
8702 /* See if there is some pre-scan operation for this section. */
8703 for (j = NUM_ELEM (debug_displays); j--;)
8704 if (strcmp (debug_displays[j].name, name) == 0)
8705 {
8706 if (debug_displays[j].prescan != NULL)
8707 {
8708 bfd_size_type length;
8709 unsigned char * start;
8710
8711 length = section->sh_size;
a6e9f9df 8712 start = ((unsigned char *)
0823fbca 8713 get_data (NULL, file, section->sh_offset, length,
a6e9f9df
AM
8714 _("debug section data")));
8715 if (!start)
8716 return 0;
3590ea00
NC
8717
8718 debug_displays[j].prescan (section, start, file);
8719 free (start);
8720 }
103f02d3 8721
3590ea00
NC
8722 break;
8723 }
8724 }
8725
252b5132 8726 for (i = 0, section = section_headers;
3590ea00 8727 i < elf_header.e_shnum && i < num_dump_sects;
252b5132
RH
8728 i ++, section ++)
8729 {
8730#ifdef SUPPORT_DISASSEMBLY
8731 if (dump_sects[i] & DISASS_DUMP)
8732 disassemble_section (section, file);
8733#endif
8734 if (dump_sects[i] & HEX_DUMP)
8735 dump_section (section, file);
8736
8737 if (dump_sects[i] & DEBUG_DUMP)
8738 display_debug_section (section, file);
8739 }
8740
8741 if (i < num_dump_sects)
8742 warn (_("Some sections were not dumped because they do not exist!\n"));
8743
8744 return 1;
8745}
8746
8747static void
8748process_mips_fpe_exception (mask)
8749 int mask;
8750{
8751 if (mask)
8752 {
8753 int first = 1;
8754 if (mask & OEX_FPU_INEX)
8755 fputs ("INEX", stdout), first = 0;
8756 if (mask & OEX_FPU_UFLO)
8757 printf ("%sUFLO", first ? "" : "|"), first = 0;
8758 if (mask & OEX_FPU_OFLO)
8759 printf ("%sOFLO", first ? "" : "|"), first = 0;
8760 if (mask & OEX_FPU_DIV0)
8761 printf ("%sDIV0", first ? "" : "|"), first = 0;
8762 if (mask & OEX_FPU_INVAL)
8763 printf ("%sINVAL", first ? "" : "|");
8764 }
8765 else
8766 fputs ("0", stdout);
8767}
8768
8769static int
8770process_mips_specific (file)
9ea033b2 8771 FILE * file;
252b5132 8772{
9ea033b2 8773 Elf_Internal_Dyn * entry;
252b5132
RH
8774 size_t liblist_offset = 0;
8775 size_t liblistno = 0;
8776 size_t conflictsno = 0;
8777 size_t options_offset = 0;
8778 size_t conflicts_offset = 0;
8779
8780 /* We have a lot of special sections. Thanks SGI! */
8781 if (dynamic_segment == NULL)
8782 /* No information available. */
8783 return 0;
8784
8785 for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
8786 switch (entry->d_tag)
8787 {
8788 case DT_MIPS_LIBLIST:
8789 liblist_offset = entry->d_un.d_val - loadaddr;
8790 break;
8791 case DT_MIPS_LIBLISTNO:
8792 liblistno = entry->d_un.d_val;
8793 break;
8794 case DT_MIPS_OPTIONS:
8795 options_offset = entry->d_un.d_val - loadaddr;
8796 break;
8797 case DT_MIPS_CONFLICT:
8798 conflicts_offset = entry->d_un.d_val - loadaddr;
8799 break;
8800 case DT_MIPS_CONFLICTNO:
8801 conflictsno = entry->d_un.d_val;
8802 break;
8803 default:
8804 break;
8805 }
8806
8807 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
8808 {
9ea033b2 8809 Elf32_External_Lib * elib;
252b5132
RH
8810 size_t cnt;
8811
a6e9f9df
AM
8812 elib = ((Elf32_External_Lib *)
8813 get_data (NULL, file, liblist_offset,
8814 liblistno * sizeof (Elf32_External_Lib),
8815 _("liblist")));
8816 if (elib)
252b5132 8817 {
a6e9f9df
AM
8818 printf ("\nSection '.liblist' contains %lu entries:\n",
8819 (unsigned long) liblistno);
8820 fputs (" Library Time Stamp Checksum Version Flags\n",
8821 stdout);
8822
8823 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 8824 {
a6e9f9df
AM
8825 Elf32_Lib liblist;
8826 time_t time;
8827 char timebuf[20];
8828 struct tm * tmp;
8829
8830 liblist.l_name = BYTE_GET (elib[cnt].l_name);
8831 time = BYTE_GET (elib[cnt].l_time_stamp);
8832 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
8833 liblist.l_version = BYTE_GET (elib[cnt].l_version);
8834 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
8835
8836 tmp = gmtime (&time);
8837 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
8838 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8839 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8840
31104126
NC
8841 printf ("%3lu: ", (unsigned long) cnt);
8842 print_symbol (20, dynamic_strings + liblist.l_name);
8843 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
8844 liblist.l_version);
a6e9f9df
AM
8845
8846 if (liblist.l_flags == 0)
8847 puts (" NONE");
8848 else
8849 {
8850 static const struct
252b5132 8851 {
a6e9f9df
AM
8852 const char * name;
8853 int bit;
252b5132 8854 }
a6e9f9df
AM
8855 l_flags_vals[] =
8856 {
8857 { " EXACT_MATCH", LL_EXACT_MATCH },
8858 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
8859 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
8860 { " EXPORTS", LL_EXPORTS },
8861 { " DELAY_LOAD", LL_DELAY_LOAD },
8862 { " DELTA", LL_DELTA }
8863 };
8864 int flags = liblist.l_flags;
8865 size_t fcnt;
8866
8867 for (fcnt = 0;
8868 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
8869 ++fcnt)
8870 if ((flags & l_flags_vals[fcnt].bit) != 0)
8871 {
8872 fputs (l_flags_vals[fcnt].name, stdout);
8873 flags ^= l_flags_vals[fcnt].bit;
8874 }
8875 if (flags != 0)
8876 printf (" %#x", (unsigned int) flags);
252b5132 8877
a6e9f9df
AM
8878 puts ("");
8879 }
252b5132 8880 }
252b5132 8881
a6e9f9df
AM
8882 free (elib);
8883 }
252b5132
RH
8884 }
8885
8886 if (options_offset != 0)
8887 {
9ea033b2 8888 Elf_External_Options * eopt;
d1133906 8889 Elf_Internal_Shdr * sect = section_headers;
9ea033b2
NC
8890 Elf_Internal_Options * iopt;
8891 Elf_Internal_Options * option;
252b5132
RH
8892 size_t offset;
8893 int cnt;
8894
8895 /* Find the section header so that we get the size. */
8896 while (sect->sh_type != SHT_MIPS_OPTIONS)
d1133906 8897 ++ sect;
252b5132 8898
a6e9f9df
AM
8899 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset,
8900 sect->sh_size, _("options"));
8901 if (eopt)
252b5132 8902 {
a6e9f9df
AM
8903 iopt = ((Elf_Internal_Options *)
8904 malloc ((sect->sh_size / sizeof (eopt)) * sizeof (* iopt)));
8905 if (iopt == NULL)
8906 {
8907 error (_("Out of memory"));
8908 return 0;
8909 }
76da6bbe 8910
a6e9f9df
AM
8911 offset = cnt = 0;
8912 option = iopt;
252b5132 8913
a6e9f9df
AM
8914 while (offset < sect->sh_size)
8915 {
8916 Elf_External_Options * eoption;
252b5132 8917
a6e9f9df 8918 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 8919
a6e9f9df
AM
8920 option->kind = BYTE_GET (eoption->kind);
8921 option->size = BYTE_GET (eoption->size);
8922 option->section = BYTE_GET (eoption->section);
8923 option->info = BYTE_GET (eoption->info);
76da6bbe 8924
a6e9f9df 8925 offset += option->size;
252b5132 8926
a6e9f9df
AM
8927 ++option;
8928 ++cnt;
8929 }
252b5132 8930
a6e9f9df
AM
8931 printf (_("\nSection '%s' contains %d entries:\n"),
8932 SECTION_NAME (sect), cnt);
76da6bbe 8933
a6e9f9df 8934 option = iopt;
252b5132 8935
a6e9f9df 8936 while (cnt-- > 0)
252b5132 8937 {
a6e9f9df
AM
8938 size_t len;
8939
8940 switch (option->kind)
252b5132 8941 {
a6e9f9df
AM
8942 case ODK_NULL:
8943 /* This shouldn't happen. */
8944 printf (" NULL %d %lx", option->section, option->info);
8945 break;
8946 case ODK_REGINFO:
8947 printf (" REGINFO ");
8948 if (elf_header.e_machine == EM_MIPS)
8949 {
8950 /* 32bit form. */
8951 Elf32_External_RegInfo * ereg;
8952 Elf32_RegInfo reginfo;
8953
8954 ereg = (Elf32_External_RegInfo *) (option + 1);
8955 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8956 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8957 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8958 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8959 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8960 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
8961
8962 printf ("GPR %08lx GP 0x%lx\n",
8963 reginfo.ri_gprmask,
8964 (unsigned long) reginfo.ri_gp_value);
8965 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
8966 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8967 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8968 }
8969 else
8970 {
8971 /* 64 bit form. */
8972 Elf64_External_RegInfo * ereg;
8973 Elf64_Internal_RegInfo reginfo;
8974
8975 ereg = (Elf64_External_RegInfo *) (option + 1);
8976 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8977 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8978 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8979 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8980 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8981 reginfo.ri_gp_value = BYTE_GET8 (ereg->ri_gp_value);
8982
8983 printf ("GPR %08lx GP 0x",
8984 reginfo.ri_gprmask);
8985 printf_vma (reginfo.ri_gp_value);
8986 printf ("\n");
8987
8988 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
8989 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8990 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8991 }
8992 ++option;
8993 continue;
8994 case ODK_EXCEPTIONS:
8995 fputs (" EXCEPTIONS fpe_min(", stdout);
8996 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
8997 fputs (") fpe_max(", stdout);
8998 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
8999 fputs (")", stdout);
9000
9001 if (option->info & OEX_PAGE0)
9002 fputs (" PAGE0", stdout);
9003 if (option->info & OEX_SMM)
9004 fputs (" SMM", stdout);
9005 if (option->info & OEX_FPDBUG)
9006 fputs (" FPDBUG", stdout);
9007 if (option->info & OEX_DISMISS)
9008 fputs (" DISMISS", stdout);
9009 break;
9010 case ODK_PAD:
9011 fputs (" PAD ", stdout);
9012 if (option->info & OPAD_PREFIX)
9013 fputs (" PREFIX", stdout);
9014 if (option->info & OPAD_POSTFIX)
9015 fputs (" POSTFIX", stdout);
9016 if (option->info & OPAD_SYMBOL)
9017 fputs (" SYMBOL", stdout);
9018 break;
9019 case ODK_HWPATCH:
9020 fputs (" HWPATCH ", stdout);
9021 if (option->info & OHW_R4KEOP)
9022 fputs (" R4KEOP", stdout);
9023 if (option->info & OHW_R8KPFETCH)
9024 fputs (" R8KPFETCH", stdout);
9025 if (option->info & OHW_R5KEOP)
9026 fputs (" R5KEOP", stdout);
9027 if (option->info & OHW_R5KCVTL)
9028 fputs (" R5KCVTL", stdout);
9029 break;
9030 case ODK_FILL:
9031 fputs (" FILL ", stdout);
9032 /* XXX Print content of info word? */
9033 break;
9034 case ODK_TAGS:
9035 fputs (" TAGS ", stdout);
9036 /* XXX Print content of info word? */
9037 break;
9038 case ODK_HWAND:
9039 fputs (" HWAND ", stdout);
9040 if (option->info & OHWA0_R4KEOP_CHECKED)
9041 fputs (" R4KEOP_CHECKED", stdout);
9042 if (option->info & OHWA0_R4KEOP_CLEAN)
9043 fputs (" R4KEOP_CLEAN", stdout);
9044 break;
9045 case ODK_HWOR:
9046 fputs (" HWOR ", stdout);
9047 if (option->info & OHWA0_R4KEOP_CHECKED)
9048 fputs (" R4KEOP_CHECKED", stdout);
9049 if (option->info & OHWA0_R4KEOP_CLEAN)
9050 fputs (" R4KEOP_CLEAN", stdout);
9051 break;
9052 case ODK_GP_GROUP:
9053 printf (" GP_GROUP %#06lx self-contained %#06lx",
9054 option->info & OGP_GROUP,
9055 (option->info & OGP_SELF) >> 16);
9056 break;
9057 case ODK_IDENT:
9058 printf (" IDENT %#06lx self-contained %#06lx",
9059 option->info & OGP_GROUP,
9060 (option->info & OGP_SELF) >> 16);
9061 break;
9062 default:
9063 /* This shouldn't happen. */
9064 printf (" %3d ??? %d %lx",
9065 option->kind, option->section, option->info);
9066 break;
252b5132 9067 }
a6e9f9df
AM
9068
9069 len = sizeof (* eopt);
9070 while (len < option->size)
9071 if (((char *) option)[len] >= ' '
9072 && ((char *) option)[len] < 0x7f)
9073 printf ("%c", ((char *) option)[len++]);
9074 else
9075 printf ("\\%03o", ((char *) option)[len++]);
9076
9077 fputs ("\n", stdout);
252b5132 9078 ++option;
252b5132
RH
9079 }
9080
a6e9f9df 9081 free (eopt);
252b5132 9082 }
252b5132
RH
9083 }
9084
9085 if (conflicts_offset != 0 && conflictsno != 0)
9086 {
9ea033b2 9087 Elf32_Conflict * iconf;
252b5132
RH
9088 size_t cnt;
9089
9090 if (dynamic_symbols == NULL)
9091 {
9092 error (_("conflict list with without table"));
9093 return 0;
9094 }
9095
584da044 9096 iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (* iconf));
252b5132
RH
9097 if (iconf == NULL)
9098 {
9099 error (_("Out of memory"));
9100 return 0;
9101 }
9102
9ea033b2 9103 if (is_32bit_elf)
252b5132 9104 {
a6e9f9df
AM
9105 Elf32_External_Conflict * econf32;
9106
9107 econf32 = ((Elf32_External_Conflict *)
9108 get_data (NULL, file, conflicts_offset,
9109 conflictsno * sizeof (* econf32),
9110 _("conflict")));
9111 if (!econf32)
9112 return 0;
252b5132
RH
9113
9114 for (cnt = 0; cnt < conflictsno; ++cnt)
9115 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
9116
9117 free (econf32);
252b5132
RH
9118 }
9119 else
9120 {
a6e9f9df
AM
9121 Elf64_External_Conflict * econf64;
9122
9123 econf64 = ((Elf64_External_Conflict *)
9124 get_data (NULL, file, conflicts_offset,
9125 conflictsno * sizeof (* econf64),
9126 _("conflict")));
9127 if (!econf64)
9128 return 0;
252b5132
RH
9129
9130 for (cnt = 0; cnt < conflictsno; ++cnt)
9131 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
9132
9133 free (econf64);
252b5132
RH
9134 }
9135
410f7a12
L
9136 printf (_("\nSection '.conflict' contains %ld entries:\n"),
9137 (long) conflictsno);
252b5132
RH
9138 puts (_(" Num: Index Value Name"));
9139
9140 for (cnt = 0; cnt < conflictsno; ++cnt)
9141 {
31104126 9142 Elf_Internal_Sym * psym = & dynamic_symbols [iconf [cnt]];
252b5132 9143
31104126 9144 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf [cnt]);
f7a99963 9145 print_vma (psym->st_value, FULL_HEX);
31104126
NC
9146 putchar (' ');
9147 print_symbol (25, dynamic_strings + psym->st_name);
9148 putchar ('\n');
252b5132
RH
9149 }
9150
252b5132
RH
9151 free (iconf);
9152 }
9153
9154 return 1;
9155}
9156
9437c45b 9157static const char *
779fe533
NC
9158get_note_type (e_type)
9159 unsigned e_type;
9160{
9161 static char buff[64];
103f02d3 9162
779fe533
NC
9163 switch (e_type)
9164 {
9165 case NT_PRSTATUS: return _("NT_PRSTATUS (prstatus structure)");
9166 case NT_FPREGSET: return _("NT_FPREGSET (floating point registers)");
9167 case NT_PRPSINFO: return _("NT_PRPSINFO (prpsinfo structure)");
9168 case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
d1133906 9169 case NT_PRXFPREG: return _("NT_PRXFPREG (user_xfpregs structure)");
779fe533
NC
9170 case NT_PSTATUS: return _("NT_PSTATUS (pstatus structure)");
9171 case NT_FPREGS: return _("NT_FPREGS (floating point registers)");
9172 case NT_PSINFO: return _("NT_PSINFO (psinfo structure)");
9173 case NT_LWPSTATUS: return _("NT_LWPSTATUS (lwpstatus_t structure)");
9174 case NT_LWPSINFO: return _("NT_LWPSINFO (lwpsinfo_t structure)");
7bea2f73 9175 case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus strcuture)");
779fe533
NC
9176 default:
9177 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
9178 return buff;
9179 }
9180}
9181
9437c45b
JT
9182static const char *
9183get_netbsd_elfcore_note_type (e_type)
9184 unsigned e_type;
9185{
9186 static char buff[64];
9187
b4db1224 9188 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
9189 {
9190 /* NetBSD core "procinfo" structure. */
9191 return _("NetBSD procinfo structure");
9192 }
9193
9194 /* As of Jan 2002 there are no other machine-independent notes
9195 defined for NetBSD core files. If the note type is less
9196 than the start of the machine-dependent note types, we don't
9197 understand it. */
9198
b4db1224 9199 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b
JT
9200 {
9201 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
9202 return buff;
9203 }
9204
9205 switch (elf_header.e_machine)
9206 {
9207 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
9208 and PT_GETFPREGS == mach+2. */
9209
9210 case EM_OLD_ALPHA:
9211 case EM_ALPHA:
9212 case EM_SPARC:
9213 case EM_SPARC32PLUS:
9214 case EM_SPARCV9:
9215 switch (e_type)
9216 {
b4db1224
JT
9217 case NT_NETBSDCORE_FIRSTMACH+0:
9218 return _("PT_GETREGS (reg structure)");
9219 case NT_NETBSDCORE_FIRSTMACH+2:
9220 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
9221 default:
9222 break;
9223 }
9224 break;
9225
9226 /* On all other arch's, PT_GETREGS == mach+1 and
9227 PT_GETFPREGS == mach+3. */
9228 default:
9229 switch (e_type)
9230 {
b4db1224
JT
9231 case NT_NETBSDCORE_FIRSTMACH+1:
9232 return _("PT_GETREGS (reg structure)");
9233 case NT_NETBSDCORE_FIRSTMACH+3:
9234 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
9235 default:
9236 break;
9237 }
9238 }
9239
b4db1224 9240 sprintf (buff, _("PT_FIRSTMACH+%d"), e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
9241 return buff;
9242}
9243
6d118b09
NC
9244/* Note that by the ELF standard, the name field is already null byte
9245 terminated, and namesz includes the terminating null byte.
9246 I.E. the value of namesz for the name "FSF" is 4.
9247
e3c8793a 9248 If the value of namesz is zero, there is no name present. */
779fe533
NC
9249static int
9250process_note (pnote)
6d118b09 9251 Elf32_Internal_Note * pnote;
779fe533 9252{
9437c45b
JT
9253 const char *nt;
9254
9255 if (pnote->namesz == 0)
9256 {
9257 /* If there is no note name, then use the default set of
9258 note type strings. */
9259 nt = get_note_type (pnote->type);
9260 }
9261 else if (strncmp (pnote->namedata, "NetBSD-CORE", 11) == 0)
9262 {
9263 /* NetBSD-specific core file notes. */
9264 nt = get_netbsd_elfcore_note_type (pnote->type);
9265 }
9266 else
9267 {
9268 /* Don't recognize this note name; just use the default set of
9269 note type strings. */
9270 nt = get_note_type (pnote->type);
9271 }
9272
103f02d3 9273 printf (" %s\t\t0x%08lx\t%s\n",
6d118b09 9274 pnote->namesz ? pnote->namedata : "(NONE)",
9437c45b 9275 pnote->descsz, nt);
779fe533
NC
9276 return 1;
9277}
9278
6d118b09 9279
779fe533
NC
9280static int
9281process_corefile_note_segment (file, offset, length)
9282 FILE * file;
f7a99963
NC
9283 bfd_vma offset;
9284 bfd_vma length;
779fe533
NC
9285{
9286 Elf_External_Note * pnotes;
9287 Elf_External_Note * external;
779fe533 9288 int res = 1;
103f02d3 9289
779fe533
NC
9290 if (length <= 0)
9291 return 0;
103f02d3 9292
a6e9f9df
AM
9293 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, length,
9294 _("notes"));
9295 if (!pnotes)
9296 return 0;
779fe533 9297
103f02d3 9298 external = pnotes;
103f02d3 9299
305c7206 9300 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 9301 (unsigned long) offset, (unsigned long) length);
779fe533 9302 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 9303
6d118b09 9304 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 9305 {
6d118b09
NC
9306 Elf32_Internal_Note inote;
9307 char * temp = NULL;
9308
9309 inote.type = BYTE_GET (external->type);
9310 inote.namesz = BYTE_GET (external->namesz);
9311 inote.namedata = external->name;
9312 inote.descsz = BYTE_GET (external->descsz);
9313 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
9314 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 9315
6d118b09
NC
9316 external = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
9317
9318 /* Verify that name is null terminated. It appears that at least
9319 one version of Linux (RedHat 6.0) generates corefiles that don't
9320 comply with the ELF spec by failing to include the null byte in
9321 namesz. */
9322 if (inote.namedata[inote.namesz] != '\0')
9323 {
9324 temp = malloc (inote.namesz + 1);
76da6bbe 9325
6d118b09
NC
9326 if (temp == NULL)
9327 {
9328 error (_("Out of memory\n"));
9329 res = 0;
9330 break;
9331 }
76da6bbe 9332
6d118b09
NC
9333 strncpy (temp, inote.namedata, inote.namesz);
9334 temp[inote.namesz] = 0;
76da6bbe 9335
6d118b09
NC
9336 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
9337 inote.namedata = temp;
9338 }
9339
9340 res &= process_note (& inote);
103f02d3 9341
6d118b09
NC
9342 if (temp != NULL)
9343 {
9344 free (temp);
9345 temp = NULL;
9346 }
779fe533
NC
9347 }
9348
9349 free (pnotes);
103f02d3 9350
779fe533
NC
9351 return res;
9352}
9353
9354static int
9355process_corefile_note_segments (file)
9356 FILE * file;
9357{
9358 Elf_Internal_Phdr * program_headers;
9359 Elf_Internal_Phdr * segment;
9360 unsigned int i;
9361 int res = 1;
103f02d3 9362
779fe533
NC
9363 program_headers = (Elf_Internal_Phdr *) malloc
9364 (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
9365
9366 if (program_headers == NULL)
9367 {
9368 error (_("Out of memory\n"));
9369 return 0;
9370 }
9371
9372 if (is_32bit_elf)
9373 i = get_32bit_program_headers (file, program_headers);
9374 else
9375 i = get_64bit_program_headers (file, program_headers);
9376
9377 if (i == 0)
9378 {
9379 free (program_headers);
9380 return 0;
9381 }
103f02d3 9382
779fe533
NC
9383 for (i = 0, segment = program_headers;
9384 i < elf_header.e_phnum;
9385 i ++, segment ++)
9386 {
9387 if (segment->p_type == PT_NOTE)
103f02d3 9388 res &= process_corefile_note_segment (file,
30800947
NC
9389 (bfd_vma) segment->p_offset,
9390 (bfd_vma) segment->p_filesz);
779fe533 9391 }
103f02d3 9392
779fe533
NC
9393 free (program_headers);
9394
9395 return res;
9396}
9397
9398static int
9399process_corefile_contents (file)
9400 FILE * file;
9401{
9402 /* If we have not been asked to display the notes then do nothing. */
9403 if (! do_notes)
9404 return 1;
103f02d3 9405
779fe533
NC
9406 /* If file is not a core file then exit. */
9407 if (elf_header.e_type != ET_CORE)
9408 return 1;
103f02d3 9409
779fe533
NC
9410 /* No program headers means no NOTE segment. */
9411 if (elf_header.e_phnum == 0)
9412 {
9413 printf (_("No note segments present in the core file.\n"));
9414 return 1;
9415 }
9416
9417 return process_corefile_note_segments (file);
9418}
9419
252b5132
RH
9420static int
9421process_arch_specific (file)
9ea033b2 9422 FILE * file;
252b5132 9423{
a952a375
NC
9424 if (! do_arch)
9425 return 1;
9426
252b5132
RH
9427 switch (elf_header.e_machine)
9428 {
9429 case EM_MIPS:
4fe85591 9430 case EM_MIPS_RS3_LE:
252b5132
RH
9431 return process_mips_specific (file);
9432 break;
9433 default:
9434 break;
9435 }
9436 return 1;
9437}
9438
9439static int
9440get_file_header (file)
9441 FILE * file;
9442{
9ea033b2
NC
9443 /* Read in the identity array. */
9444 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
9445 return 0;
9446
9ea033b2
NC
9447 /* Determine how to read the rest of the header. */
9448 switch (elf_header.e_ident [EI_DATA])
9449 {
9450 default: /* fall through */
9451 case ELFDATANONE: /* fall through */
9452 case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
9453 case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
9454 }
9455
9456 /* For now we only support 32 bit and 64 bit ELF files. */
9457 is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
9458
9459 /* Read in the rest of the header. */
9460 if (is_32bit_elf)
9461 {
9462 Elf32_External_Ehdr ehdr32;
252b5132 9463
9ea033b2
NC
9464 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
9465 return 0;
103f02d3 9466
9ea033b2
NC
9467 elf_header.e_type = BYTE_GET (ehdr32.e_type);
9468 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
9469 elf_header.e_version = BYTE_GET (ehdr32.e_version);
9470 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
9471 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
9472 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
9473 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
9474 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
9475 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
9476 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
9477 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
9478 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
9479 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9480 }
252b5132 9481 else
9ea033b2
NC
9482 {
9483 Elf64_External_Ehdr ehdr64;
a952a375
NC
9484
9485 /* If we have been compiled with sizeof (bfd_vma) == 4, then
9486 we will not be able to cope with the 64bit data found in
9487 64 ELF files. Detect this now and abort before we start
9488 overwritting things. */
9489 if (sizeof (bfd_vma) < 8)
9490 {
e3c8793a
NC
9491 error (_("This instance of readelf has been built without support for a\n\
949264 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
9493 return 0;
9494 }
103f02d3 9495
9ea033b2
NC
9496 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
9497 return 0;
103f02d3 9498
9ea033b2
NC
9499 elf_header.e_type = BYTE_GET (ehdr64.e_type);
9500 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
9501 elf_header.e_version = BYTE_GET (ehdr64.e_version);
9502 elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry);
9503 elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff);
9504 elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff);
9505 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
9506 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
9507 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
9508 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
9509 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
9510 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
9511 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9512 }
252b5132 9513
560f3c1c
AM
9514 /* There may be some extensions in the first section header. Don't
9515 bomb if we can't read it. */
9516 if (is_32bit_elf)
9517 get_32bit_section_headers (file, 1);
9518 else
9519 get_64bit_section_headers (file, 1);
9520
252b5132
RH
9521 return 1;
9522}
9523
ff78d6d6 9524static int
252b5132
RH
9525process_file (file_name)
9526 char * file_name;
9527{
9528 FILE * file;
9529 struct stat statbuf;
9530 unsigned int i;
9531
9532 if (stat (file_name, & statbuf) < 0)
9533 {
9534 error (_("Cannot stat input file %s.\n"), file_name);
ff78d6d6 9535 return 1;
252b5132
RH
9536 }
9537
9538 file = fopen (file_name, "rb");
9539 if (file == NULL)
9540 {
9541 error (_("Input file %s not found.\n"), file_name);
ff78d6d6 9542 return 1;
252b5132
RH
9543 }
9544
9545 if (! get_file_header (file))
9546 {
9547 error (_("%s: Failed to read file header\n"), file_name);
9548 fclose (file);
ff78d6d6 9549 return 1;
252b5132
RH
9550 }
9551
9552 /* Initialise per file variables. */
9553 for (i = NUM_ELEM (version_info); i--;)
9554 version_info[i] = 0;
9555
9556 for (i = NUM_ELEM (dynamic_info); i--;)
9557 dynamic_info[i] = 0;
9558
9559 /* Process the file. */
9560 if (show_name)
9561 printf (_("\nFile: %s\n"), file_name);
9562
9563 if (! process_file_header ())
9564 {
9565 fclose (file);
ff78d6d6 9566 return 1;
252b5132
RH
9567 }
9568
9569 process_section_headers (file);
9570
9571 process_program_headers (file);
9572
9573 process_dynamic_segment (file);
9574
9575 process_relocs (file);
9576
4d6ed7c8
NC
9577 process_unwind (file);
9578
252b5132
RH
9579 process_symbol_table (file);
9580
9581 process_syminfo (file);
9582
9583 process_version_sections (file);
9584
9585 process_section_contents (file);
103f02d3 9586
779fe533 9587 process_corefile_contents (file);
103f02d3 9588
252b5132
RH
9589 process_arch_specific (file);
9590
9591 fclose (file);
9592
9593 if (section_headers)
9594 {
9595 free (section_headers);
9596 section_headers = NULL;
9597 }
9598
9599 if (string_table)
9600 {
9601 free (string_table);
9602 string_table = NULL;
d40ac9bd 9603 string_table_length = 0;
252b5132
RH
9604 }
9605
9606 if (dynamic_strings)
9607 {
9608 free (dynamic_strings);
9609 dynamic_strings = NULL;
9610 }
9611
9612 if (dynamic_symbols)
9613 {
9614 free (dynamic_symbols);
9615 dynamic_symbols = NULL;
19936277 9616 num_dynamic_syms = 0;
252b5132
RH
9617 }
9618
9619 if (dynamic_syminfo)
9620 {
9621 free (dynamic_syminfo);
9622 dynamic_syminfo = NULL;
9623 }
ff78d6d6
L
9624
9625 return 0;
252b5132
RH
9626}
9627
9628#ifdef SUPPORT_DISASSEMBLY
9629/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 9630 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 9631 symbols. */
252b5132
RH
9632
9633void
9634print_address (unsigned int addr, FILE * outfile)
9635{
9636 fprintf (outfile,"0x%8.8x", addr);
9637}
9638
e3c8793a 9639/* Needed by the i386 disassembler. */
252b5132
RH
9640void
9641db_task_printsym (unsigned int addr)
9642{
9643 print_address (addr, stderr);
9644}
9645#endif
9646
e414a165
NC
9647int main PARAMS ((int, char **));
9648
252b5132
RH
9649int
9650main (argc, argv)
9651 int argc;
9652 char ** argv;
9653{
ff78d6d6
L
9654 int err;
9655
252b5132
RH
9656#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
9657 setlocale (LC_MESSAGES, "");
3882b010
L
9658#endif
9659#if defined (HAVE_SETLOCALE)
9660 setlocale (LC_CTYPE, "");
252b5132
RH
9661#endif
9662 bindtextdomain (PACKAGE, LOCALEDIR);
9663 textdomain (PACKAGE);
9664
9665 parse_args (argc, argv);
9666
9667 if (optind < (argc - 1))
9668 show_name = 1;
9669
ff78d6d6 9670 err = 0;
252b5132 9671 while (optind < argc)
ff78d6d6 9672 err |= process_file (argv [optind ++]);
252b5132
RH
9673
9674 if (dump_sects != NULL)
9675 free (dump_sects);
9676
ff78d6d6 9677 return err;
252b5132 9678}