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