* elflink.h (elf_link_output_extsym): Revert 1999-04-10.
[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>
5 Modifications by Nick Clifton <nickc@cygnus.com>
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";
6018 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
6019 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
6020 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
6021 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
6022 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
6023 case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
6024 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
6025 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
6026 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
6027 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
6028 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
6029 case DW_AT_sf_names: return "DW_AT_sf_names";
6030 case DW_AT_src_info: return "DW_AT_src_info";
6031 case DW_AT_mac_info: return "DW_AT_mac_info";
6032 case DW_AT_src_coords: return "DW_AT_src_coords";
6033 case DW_AT_body_begin: return "DW_AT_body_begin";
6034 case DW_AT_body_end: return "DW_AT_body_end";
6035 default:
6036 {
6037 static char buffer [100];
6038
6039 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
6040 return buffer;
6041 }
6042 }
6043}
6044
6045static char *
6046get_FORM_name (form)
6047 unsigned long form;
6048{
6049 switch (form)
6050 {
6051 case DW_FORM_addr: return "DW_FORM_addr";
6052 case DW_FORM_block2: return "DW_FORM_block2";
6053 case DW_FORM_block4: return "DW_FORM_block4";
6054 case DW_FORM_data2: return "DW_FORM_data2";
6055 case DW_FORM_data4: return "DW_FORM_data4";
6056 case DW_FORM_data8: return "DW_FORM_data8";
6057 case DW_FORM_string: return "DW_FORM_string";
6058 case DW_FORM_block: return "DW_FORM_block";
6059 case DW_FORM_block1: return "DW_FORM_block1";
6060 case DW_FORM_data1: return "DW_FORM_data1";
6061 case DW_FORM_flag: return "DW_FORM_flag";
6062 case DW_FORM_sdata: return "DW_FORM_sdata";
6063 case DW_FORM_strp: return "DW_FORM_strp";
6064 case DW_FORM_udata: return "DW_FORM_udata";
6065 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
6066 case DW_FORM_ref1: return "DW_FORM_ref1";
6067 case DW_FORM_ref2: return "DW_FORM_ref2";
6068 case DW_FORM_ref4: return "DW_FORM_ref4";
6069 case DW_FORM_ref8: return "DW_FORM_ref8";
6070 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
6071 case DW_FORM_indirect: return "DW_FORM_indirect";
6072 default:
6073 {
6074 static char buffer [100];
6075
6076 sprintf (buffer, _("Unknown FORM value: %lx"), form);
6077 return buffer;
6078 }
6079 }
6080}
6081
6082/* FIXME: There are better and more effiecint ways to handle
6083 these structures. For now though, I just want something that
6084 is simple to implement. */
6085typedef struct abbrev_attr
6086{
6087 unsigned long attribute;
6088 unsigned long form;
6089 struct abbrev_attr * next;
6090}
6091abbrev_attr;
6092
6093typedef struct abbrev_entry
6094{
6095 unsigned long entry;
6096 unsigned long tag;
6097 int children;
6098 struct abbrev_attr * first_attr;
6099 struct abbrev_attr * last_attr;
6100 struct abbrev_entry * next;
6101}
6102abbrev_entry;
6103
6104static abbrev_entry * first_abbrev = NULL;
6105static abbrev_entry * last_abbrev = NULL;
6106
6107static void
6108free_abbrevs PARAMS ((void))
6109{
6110 abbrev_entry * abbrev;
6111
6112 for (abbrev = first_abbrev; abbrev;)
6113 {
6114 abbrev_entry * next = abbrev->next;
6115 abbrev_attr * attr;
6116
6117 for (attr = abbrev->first_attr; attr;)
6118 {
6119 abbrev_attr * next = attr->next;
6120
6121 free (attr);
6122 attr = next;
6123 }
6124
6125 free (abbrev);
6126 abbrev = next;
6127 }
6128
6129 last_abbrev = first_abbrev = NULL;
6130}
6131
6132static void
6133add_abbrev (number, tag, children)
6134 unsigned long number;
6135 unsigned long tag;
6136 int children;
6137{
6138 abbrev_entry * entry;
6139
6140 entry = (abbrev_entry *) malloc (sizeof (* entry));
6141
6142 if (entry == NULL)
6143 /* ugg */
6144 return;
6145
6146 entry->entry = number;
6147 entry->tag = tag;
6148 entry->children = children;
6149 entry->first_attr = NULL;
6150 entry->last_attr = NULL;
6151 entry->next = NULL;
6152
6153 if (first_abbrev == NULL)
6154 first_abbrev = entry;
6155 else
6156 last_abbrev->next = entry;
6157
6158 last_abbrev = entry;
6159}
6160
6161static void
6162add_abbrev_attr (attribute, form)
6163 unsigned long attribute;
6164 unsigned long form;
6165{
6166 abbrev_attr * attr;
6167
6168 attr = (abbrev_attr *) malloc (sizeof (* attr));
6169
6170 if (attr == NULL)
6171 /* ugg */
6172 return;
6173
6174 attr->attribute = attribute;
6175 attr->form = form;
6176 attr->next = NULL;
6177
6178 if (last_abbrev->first_attr == NULL)
6179 last_abbrev->first_attr = attr;
6180 else
6181 last_abbrev->last_attr->next = attr;
6182
6183 last_abbrev->last_attr = attr;
6184}
6185
6186/* Processes the (partial) contents of a .debug_abbrev section.
6187 Returns NULL if the end of the section was encountered.
6188 Returns the address after the last byte read if the end of
6189 an abbreviation set was found. */
6190
6191static unsigned char *
6192process_abbrev_section (start, end)
6193 unsigned char * start;
6194 unsigned char * end;
6195{
6196 if (first_abbrev != NULL)
6197 return NULL;
6198
6199 while (start < end)
6200 {
6201 int bytes_read;
6202 unsigned long entry;
6203 unsigned long tag;
6204 unsigned long attribute;
6205 int children;
6206
6207 entry = read_leb128 (start, & bytes_read, 0);
6208 start += bytes_read;
6209
a3f779db
NC
6210 /* A single zero is supposed to end the section according
6211 to the standard. If there's more, then signal that to
6212 the caller. */
252b5132 6213 if (entry == 0)
a3f779db 6214 return start == end ? NULL : start;
252b5132
RH
6215
6216 tag = read_leb128 (start, & bytes_read, 0);
6217 start += bytes_read;
6218
6219 children = * start ++;
6220
6221 add_abbrev (entry, tag, children);
6222
6223 do
6224 {
6225 unsigned long form;
6226
6227 attribute = read_leb128 (start, & bytes_read, 0);
6228 start += bytes_read;
6229
6230 form = read_leb128 (start, & bytes_read, 0);
6231 start += bytes_read;
6232
6233 if (attribute != 0)
6234 add_abbrev_attr (attribute, form);
6235 }
6236 while (attribute != 0);
6237 }
6238
6239 return NULL;
6240}
6241
6242
6243static int
6244display_debug_abbrev (section, start, file)
6245 Elf32_Internal_Shdr * section;
6246 unsigned char * start;
b4c96d0d 6247 FILE * file ATTRIBUTE_UNUSED;
252b5132 6248{
584da044 6249 abbrev_entry * entry;
252b5132
RH
6250 unsigned char * end = start + section->sh_size;
6251
6252 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
6253
6254 do
6255 {
6256 start = process_abbrev_section (start, end);
6257
6258 printf (_(" Number TAG\n"));
6259
6260 for (entry = first_abbrev; entry; entry = entry->next)
6261 {
6262 abbrev_attr * attr;
6263
6264 printf (_(" %ld %s [%s]\n"),
6265 entry->entry,
6266 get_TAG_name (entry->tag),
6267 entry->children ? _("has children") : _("no children"));
6268
6269 for (attr = entry->first_attr; attr; attr = attr->next)
6270 {
6271 printf (_(" %-18s %s\n"),
6272 get_AT_name (attr->attribute),
6273 get_FORM_name (attr->form));
6274 }
6275 }
6276 }
6277 while (start);
6278
6279 printf ("\n");
6280
6281 return 1;
6282}
6283
6284
6285static unsigned char *
6286display_block (data, length)
6287 unsigned char * data;
6288 unsigned long length;
6289{
6290 printf (_(" %lu byte block: "), length);
6291
6292 while (length --)
148d3c43 6293 printf ("%lx ", (unsigned long) byte_get (data ++, 1));
252b5132
RH
6294
6295 return data;
6296}
6297
6298static void
eb6bd4d3 6299decode_location_expression (data, pointer_size, length)
252b5132
RH
6300 unsigned char * data;
6301 unsigned int pointer_size;
584da044 6302 unsigned long length;
252b5132 6303{
584da044
NC
6304 unsigned op;
6305 int bytes_read;
6306 unsigned long uvalue;
6307 unsigned char * end = data + length;
252b5132 6308
eb6bd4d3 6309 while (data < end)
252b5132 6310 {
eb6bd4d3 6311 op = * data ++;
252b5132 6312
eb6bd4d3
JM
6313 switch (op)
6314 {
6315 case DW_OP_addr:
6316 printf ("DW_OP_addr: %lx",
6317 (unsigned long) byte_get (data, pointer_size));
6318 data += pointer_size;
6319 break;
6320 case DW_OP_deref:
6321 printf ("DW_OP_deref");
6322 break;
6323 case DW_OP_const1u:
6324 printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
6325 break;
6326 case DW_OP_const1s:
6327 printf ("DW_OP_const1s: %ld", (long) byte_get (data++, 1));
6328 break;
6329 case DW_OP_const2u:
6330 printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
6331 data += 2;
6332 break;
6333 case DW_OP_const2s:
6334 printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
6335 data += 2;
6336 break;
6337 case DW_OP_const4u:
6338 printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
6339 data += 4;
6340 break;
6341 case DW_OP_const4s:
6342 printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
6343 data += 4;
6344 break;
6345 case DW_OP_const8u:
6346 printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
6347 (unsigned long) byte_get (data + 4, 4));
6348 data += 8;
6349 break;
6350 case DW_OP_const8s:
6351 printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
6352 (long) byte_get (data + 4, 4));
6353 data += 8;
6354 break;
6355 case DW_OP_constu:
6356 printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
6357 data += bytes_read;
6358 break;
6359 case DW_OP_consts:
6360 printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
6361 data += bytes_read;
6362 break;
6363 case DW_OP_dup:
6364 printf ("DW_OP_dup");
6365 break;
6366 case DW_OP_drop:
6367 printf ("DW_OP_drop");
6368 break;
6369 case DW_OP_over:
6370 printf ("DW_OP_over");
6371 break;
6372 case DW_OP_pick:
6373 printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
6374 break;
6375 case DW_OP_swap:
6376 printf ("DW_OP_swap");
6377 break;
6378 case DW_OP_rot:
6379 printf ("DW_OP_rot");
6380 break;
6381 case DW_OP_xderef:
6382 printf ("DW_OP_xderef");
6383 break;
6384 case DW_OP_abs:
6385 printf ("DW_OP_abs");
6386 break;
6387 case DW_OP_and:
6388 printf ("DW_OP_and");
6389 break;
6390 case DW_OP_div:
6391 printf ("DW_OP_div");
6392 break;
6393 case DW_OP_minus:
6394 printf ("DW_OP_minus");
6395 break;
6396 case DW_OP_mod:
6397 printf ("DW_OP_mod");
6398 break;
6399 case DW_OP_mul:
6400 printf ("DW_OP_mul");
6401 break;
6402 case DW_OP_neg:
6403 printf ("DW_OP_neg");
6404 break;
6405 case DW_OP_not:
6406 printf ("DW_OP_not");
6407 break;
6408 case DW_OP_or:
6409 printf ("DW_OP_or");
6410 break;
6411 case DW_OP_plus:
6412 printf ("DW_OP_plus");
6413 break;
6414 case DW_OP_plus_uconst:
6415 printf ("DW_OP_plus_uconst: %lu",
6416 read_leb128 (data, &bytes_read, 0));
6417 data += bytes_read;
6418 break;
6419 case DW_OP_shl:
6420 printf ("DW_OP_shl");
6421 break;
6422 case DW_OP_shr:
6423 printf ("DW_OP_shr");
6424 break;
6425 case DW_OP_shra:
6426 printf ("DW_OP_shra");
6427 break;
6428 case DW_OP_xor:
6429 printf ("DW_OP_xor");
6430 break;
6431 case DW_OP_bra:
6432 printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
6433 data += 2;
6434 break;
6435 case DW_OP_eq:
6436 printf ("DW_OP_eq");
6437 break;
6438 case DW_OP_ge:
6439 printf ("DW_OP_ge");
6440 break;
6441 case DW_OP_gt:
6442 printf ("DW_OP_gt");
6443 break;
6444 case DW_OP_le:
6445 printf ("DW_OP_le");
6446 break;
6447 case DW_OP_lt:
6448 printf ("DW_OP_lt");
6449 break;
6450 case DW_OP_ne:
6451 printf ("DW_OP_ne");
6452 break;
6453 case DW_OP_skip:
6454 printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
6455 data += 2;
6456 break;
6457
6458 case DW_OP_lit0:
6459 case DW_OP_lit1:
6460 case DW_OP_lit2:
6461 case DW_OP_lit3:
6462 case DW_OP_lit4:
6463 case DW_OP_lit5:
6464 case DW_OP_lit6:
6465 case DW_OP_lit7:
6466 case DW_OP_lit8:
6467 case DW_OP_lit9:
6468 case DW_OP_lit10:
6469 case DW_OP_lit11:
6470 case DW_OP_lit12:
6471 case DW_OP_lit13:
6472 case DW_OP_lit14:
6473 case DW_OP_lit15:
6474 case DW_OP_lit16:
6475 case DW_OP_lit17:
6476 case DW_OP_lit18:
6477 case DW_OP_lit19:
6478 case DW_OP_lit20:
6479 case DW_OP_lit21:
6480 case DW_OP_lit22:
6481 case DW_OP_lit23:
6482 case DW_OP_lit24:
6483 case DW_OP_lit25:
6484 case DW_OP_lit26:
6485 case DW_OP_lit27:
6486 case DW_OP_lit28:
6487 case DW_OP_lit29:
6488 case DW_OP_lit30:
6489 case DW_OP_lit31:
6490 printf ("DW_OP_lit%d", op - DW_OP_lit0);
6491 break;
6492
6493 case DW_OP_reg0:
6494 case DW_OP_reg1:
6495 case DW_OP_reg2:
6496 case DW_OP_reg3:
6497 case DW_OP_reg4:
6498 case DW_OP_reg5:
6499 case DW_OP_reg6:
6500 case DW_OP_reg7:
6501 case DW_OP_reg8:
6502 case DW_OP_reg9:
6503 case DW_OP_reg10:
6504 case DW_OP_reg11:
6505 case DW_OP_reg12:
6506 case DW_OP_reg13:
6507 case DW_OP_reg14:
6508 case DW_OP_reg15:
6509 case DW_OP_reg16:
6510 case DW_OP_reg17:
6511 case DW_OP_reg18:
6512 case DW_OP_reg19:
6513 case DW_OP_reg20:
6514 case DW_OP_reg21:
6515 case DW_OP_reg22:
6516 case DW_OP_reg23:
6517 case DW_OP_reg24:
6518 case DW_OP_reg25:
6519 case DW_OP_reg26:
6520 case DW_OP_reg27:
6521 case DW_OP_reg28:
6522 case DW_OP_reg29:
6523 case DW_OP_reg30:
6524 case DW_OP_reg31:
6525 printf ("DW_OP_reg%d", op - DW_OP_reg0);
6526 break;
6527
6528 case DW_OP_breg0:
6529 case DW_OP_breg1:
6530 case DW_OP_breg2:
6531 case DW_OP_breg3:
6532 case DW_OP_breg4:
6533 case DW_OP_breg5:
6534 case DW_OP_breg6:
6535 case DW_OP_breg7:
6536 case DW_OP_breg8:
6537 case DW_OP_breg9:
6538 case DW_OP_breg10:
6539 case DW_OP_breg11:
6540 case DW_OP_breg12:
6541 case DW_OP_breg13:
6542 case DW_OP_breg14:
6543 case DW_OP_breg15:
6544 case DW_OP_breg16:
6545 case DW_OP_breg17:
6546 case DW_OP_breg18:
6547 case DW_OP_breg19:
6548 case DW_OP_breg20:
6549 case DW_OP_breg21:
6550 case DW_OP_breg22:
6551 case DW_OP_breg23:
6552 case DW_OP_breg24:
6553 case DW_OP_breg25:
6554 case DW_OP_breg26:
6555 case DW_OP_breg27:
6556 case DW_OP_breg28:
6557 case DW_OP_breg29:
6558 case DW_OP_breg30:
6559 case DW_OP_breg31:
6560 printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
6561 read_leb128 (data, &bytes_read, 1));
6562 data += bytes_read;
6563 break;
6564
6565 case DW_OP_regx:
6566 printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
6567 data += bytes_read;
6568 break;
6569 case DW_OP_fbreg:
6570 printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
6571 data += bytes_read;
6572 break;
6573 case DW_OP_bregx:
6574 uvalue = read_leb128 (data, &bytes_read, 0);
6575 data += bytes_read;
6576 printf ("DW_OP_bregx: %lu %ld", uvalue,
6577 read_leb128 (data, &bytes_read, 1));
6578 data += bytes_read;
6579 break;
6580 case DW_OP_piece:
6581 printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
6582 data += bytes_read;
6583 break;
6584 case DW_OP_deref_size:
6585 printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
6586 break;
6587 case DW_OP_xderef_size:
6588 printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
6589 break;
6590 case DW_OP_nop:
6591 printf ("DW_OP_nop");
6592 break;
6593
6594 default:
6595 if (op >= DW_OP_lo_user
6596 && op <= DW_OP_hi_user)
6597 printf (_("(User defined location op)"));
6598 else
6599 printf (_("(Unknown location op)"));
6600 /* No way to tell where the next op is, so just bail. */
6601 return;
6602 }
252b5132
RH
6603 }
6604}
6605
6606
6607static unsigned char *
1fa37306 6608read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
252b5132
RH
6609 unsigned long attribute;
6610 unsigned long form;
6611 unsigned char * data;
1fa37306 6612 unsigned long cu_offset;
252b5132
RH
6613 unsigned long pointer_size;
6614{
b4c96d0d
ILT
6615 unsigned long uvalue = 0;
6616 unsigned char * block_start = NULL;
252b5132 6617 int bytes_read;
252b5132
RH
6618
6619 printf (" %-18s:", get_AT_name (attribute));
6620
252b5132
RH
6621 switch (form)
6622 {
60bcf0fa
NC
6623 default:
6624 break;
76da6bbe 6625
252b5132
RH
6626 case DW_FORM_ref_addr:
6627 case DW_FORM_addr:
6628 uvalue = byte_get (data, pointer_size);
252b5132
RH
6629 data += pointer_size;
6630 break;
6631
6632 case DW_FORM_ref1:
6633 case DW_FORM_flag:
6634 case DW_FORM_data1:
6635 uvalue = byte_get (data ++, 1);
252b5132
RH
6636 break;
6637
6638 case DW_FORM_ref2:
6639 case DW_FORM_data2:
6640 uvalue = byte_get (data, 2);
6641 data += 2;
252b5132
RH
6642 break;
6643
6644 case DW_FORM_ref4:
6645 case DW_FORM_data4:
6646 uvalue = byte_get (data, 4);
6647 data += 4;
1fa37306
JM
6648 break;
6649
6650 case DW_FORM_sdata:
6651 uvalue = read_leb128 (data, & bytes_read, 1);
6652 data += bytes_read;
6653 break;
6654
6655 case DW_FORM_ref_udata:
6656 case DW_FORM_udata:
6657 uvalue = read_leb128 (data, & bytes_read, 0);
6658 data += bytes_read;
6659 break;
6660 }
6661
6662 switch (form)
6663 {
6664 case DW_FORM_ref_addr:
6665 printf (" <#%lx>", uvalue);
6666 break;
76da6bbe 6667
1fa37306
JM
6668 case DW_FORM_ref1:
6669 case DW_FORM_ref2:
6670 case DW_FORM_ref4:
6671 case DW_FORM_ref_udata:
6672 printf (" <%lx>", uvalue + cu_offset);
6673 break;
6674
6675 case DW_FORM_addr:
6676 printf (" %#lx", uvalue);
6677
6678 case DW_FORM_flag:
6679 case DW_FORM_data1:
6680 case DW_FORM_data2:
6681 case DW_FORM_data4:
6682 case DW_FORM_sdata:
6683 case DW_FORM_udata:
6684 printf (" %ld", uvalue);
252b5132
RH
6685 break;
6686
6687 case DW_FORM_ref8:
6688 case DW_FORM_data8:
6689 uvalue = byte_get (data, 4);
6690 printf (" %lx", uvalue);
148d3c43 6691 printf (" %lx", (unsigned long) byte_get (data + 4, 4));
252b5132
RH
6692 data += 8;
6693 break;
6694
6695 case DW_FORM_string:
6696 printf (" %s", data);
3c9f43b1 6697 data += strlen ((char *) data) + 1;
252b5132
RH
6698 break;
6699
252b5132
RH
6700 case DW_FORM_block:
6701 uvalue = read_leb128 (data, & bytes_read, 0);
6702 block_start = data + bytes_read;
6703 data = display_block (block_start, uvalue);
252b5132
RH
6704 break;
6705
6706 case DW_FORM_block1:
6707 uvalue = byte_get (data, 1);
6708 block_start = data + 1;
6709 data = display_block (block_start, uvalue);
252b5132
RH
6710 break;
6711
6712 case DW_FORM_block2:
6713 uvalue = byte_get (data, 2);
6714 block_start = data + 2;
6715 data = display_block (block_start, uvalue);
252b5132
RH
6716 break;
6717
6718 case DW_FORM_block4:
6719 uvalue = byte_get (data, 4);
6720 block_start = data + 4;
6721 data = display_block (block_start, uvalue);
252b5132
RH
6722 break;
6723
6724 case DW_FORM_strp:
6725 case DW_FORM_indirect:
6726 warn (_("Unable to handle FORM: %d"), form);
6727 break;
6728
6729 default:
6730 warn (_("Unrecognised form: %d"), form);
6731 break;
6732 }
6733
6734 /* For some attributes we can display futher information. */
6735
6736 printf ("\t");
6737
6738 switch (attribute)
6739 {
6740 case DW_AT_inline:
6741 switch (uvalue)
6742 {
6743 case DW_INL_not_inlined: printf (_("(not inlined)")); break;
6744 case DW_INL_inlined: printf (_("(inlined)")); break;
6745 case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
6746 case DW_INL_declared_inlined: printf (_("(declared as inline and inlined)")); break;
6747 default: printf (_(" (Unknown inline attribute value: %lx)"), uvalue); break;
6748 }
6749 break;
6750
252b5132
RH
6751 case DW_AT_language:
6752 switch (uvalue)
6753 {
6754 case DW_LANG_C: printf ("(non-ANSI C)"); break;
6755 case DW_LANG_C89: printf ("(ANSI C)"); break;
6756 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
6757 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
6758 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
6759 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
6760 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
6761 case DW_LANG_Ada83: printf ("(Ada)"); break;
6762 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
6763 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
6764 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
6765 default: printf ("(Unknown: %lx)", uvalue); break;
6766 }
6767 break;
6768
6769 case DW_AT_encoding:
6770 switch (uvalue)
6771 {
6772 case DW_ATE_void: printf ("(void)"); break;
6773 case DW_ATE_address: printf ("(machine address)"); break;
6774 case DW_ATE_boolean: printf ("(boolean)"); break;
6775 case DW_ATE_complex_float: printf ("(complex float)"); break;
6776 case DW_ATE_float: printf ("(float)"); break;
6777 case DW_ATE_signed: printf ("(signed)"); break;
6778 case DW_ATE_signed_char: printf ("(signed char)"); break;
6779 case DW_ATE_unsigned: printf ("(unsigned)"); break;
6780 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
6781 default:
6782 if (uvalue >= DW_ATE_lo_user
6783 && uvalue <= DW_ATE_hi_user)
6784 printf ("(user defined type)");
6785 else
6786 printf ("(unknown type)");
6787 break;
6788 }
6789 break;
6790
6791 case DW_AT_accessibility:
6792 switch (uvalue)
6793 {
6794 case DW_ACCESS_public: printf ("(public)"); break;
6795 case DW_ACCESS_protected: printf ("(protected)"); break;
6796 case DW_ACCESS_private: printf ("(private)"); break;
6797 default: printf ("(unknown accessibility)"); break;
6798 }
6799 break;
6800
6801 case DW_AT_visibility:
6802 switch (uvalue)
6803 {
6804 case DW_VIS_local: printf ("(local)"); break;
6805 case DW_VIS_exported: printf ("(exported)"); break;
6806 case DW_VIS_qualified: printf ("(qualified)"); break;
6807 default: printf ("(unknown visibility)"); break;
6808 }
6809 break;
6810
6811 case DW_AT_virtuality:
6812 switch (uvalue)
6813 {
6814 case DW_VIRTUALITY_none: printf ("(none)"); break;
6815 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
6816 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
6817 default: printf ("(unknown virtuality)"); break;
6818 }
6819 break;
6820
6821 case DW_AT_identifier_case:
6822 switch (uvalue)
6823 {
6824 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
6825 case DW_ID_up_case: printf ("(up_case)"); break;
6826 case DW_ID_down_case: printf ("(down_case)"); break;
6827 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
6828 default: printf ("(unknown case)"); break;
6829 }
6830 break;
6831
6832 case DW_AT_calling_convention:
6833 switch (uvalue)
6834 {
6835 case DW_CC_normal: printf ("(normal)"); break;
6836 case DW_CC_program: printf ("(program)"); break;
6837 case DW_CC_nocall: printf ("(nocall)"); break;
6838 default:
6839 if (uvalue >= DW_CC_lo_user
6840 && uvalue <= DW_CC_hi_user)
6841 printf ("(user defined)");
6842 else
6843 printf ("(unknown convention)");
6844 }
6845 break;
6846
eb6bd4d3 6847 case DW_AT_frame_base:
252b5132
RH
6848 case DW_AT_location:
6849 case DW_AT_data_member_location:
6850 case DW_AT_vtable_elem_location:
eb6bd4d3
JM
6851 if (block_start)
6852 {
6853 printf ("(");
6854 decode_location_expression (block_start, pointer_size, uvalue);
6855 printf (")");
6856 }
252b5132
RH
6857 break;
6858
6859 default:
6860 break;
6861 }
6862
6863 printf ("\n");
6864 return data;
6865}
6866
6867static int
6868display_debug_info (section, start, file)
6869 Elf32_Internal_Shdr * section;
6870 unsigned char * start;
6871 FILE * file;
6872{
6873 unsigned char * end = start + section->sh_size;
6874 unsigned char * section_begin = start;
6875
6876 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
6877
6878 while (start < end)
6879 {
6880 DWARF2_External_CompUnit * external;
6881 DWARF2_Internal_CompUnit compunit;
6882 unsigned char * tags;
6883 int i;
6884 int level;
1fa37306 6885 unsigned long cu_offset;
252b5132
RH
6886
6887 external = (DWARF2_External_CompUnit *) start;
6888
6889 compunit.cu_length = BYTE_GET (external->cu_length);
6890 compunit.cu_version = BYTE_GET (external->cu_version);
6891 compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
6892 compunit.cu_pointer_size = BYTE_GET (external->cu_pointer_size);
6893
6894 tags = start + sizeof (* external);
1fa37306 6895 cu_offset = start - section_begin;
252b5132
RH
6896 start += compunit.cu_length + sizeof (external->cu_length);
6897
09fd7e38
JM
6898 printf (_(" Compilation Unit @ %lx:\n"), cu_offset);
6899 printf (_(" Length: %ld\n"), compunit.cu_length);
6900 printf (_(" Version: %d\n"), compunit.cu_version);
6901 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
6902 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
6903
252b5132
RH
6904 if (compunit.cu_version != 2)
6905 {
6906 warn (_("Only version 2 DWARF debug information is currently supported.\n"));
6907 continue;
6908 }
6909
252b5132
RH
6910 if (first_abbrev != NULL)
6911 free_abbrevs ();
6912
6913 /* Read in the abbrevs used by this compilation unit. */
6914
6915 {
6916 Elf32_Internal_Shdr * sec;
6917 unsigned char * begin;
6918
6919 /* Locate the .debug_abbrev section and process it. */
6920 for (i = 0, sec = section_headers;
6921 i < elf_header.e_shnum;
6922 i ++, sec ++)
6923 if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
6924 break;
6925
6926 if (i == -1 || sec->sh_size == 0)
6927 {
6928 warn (_("Unable to locate .debug_abbrev section!\n"));
6929 return 0;
6930 }
6931
a6e9f9df
AM
6932 begin = ((unsigned char *)
6933 get_data (NULL, file, sec->sh_offset, sec->sh_size,
6934 _("debug_abbrev section data")));
6935 if (!begin)
6936 return 0;
252b5132
RH
6937
6938 process_abbrev_section (begin + compunit.cu_abbrev_offset,
6939 begin + sec->sh_size);
6940
6941 free (begin);
6942 }
6943
6944 level = 0;
6945 while (tags < start)
6946 {
6947 int bytes_read;
b4c96d0d 6948 unsigned long abbrev_number;
252b5132
RH
6949 abbrev_entry * entry;
6950 abbrev_attr * attr;
6951
6952 abbrev_number = read_leb128 (tags, & bytes_read, 0);
6953 tags += bytes_read;
6954
6955 /* A null DIE marks the end of a list of children. */
6956 if (abbrev_number == 0)
6957 {
6958 --level;
6959 continue;
6960 }
6961
6962 /* Scan through the abbreviation list until we reach the
6963 correct entry. */
6964 for (entry = first_abbrev;
6965 entry && entry->entry != abbrev_number;
6966 entry = entry->next)
6967 continue;
6968
6969 if (entry == NULL)
6970 {
b4c96d0d 6971 warn (_("Unable to locate entry %lu in the abbreviation table\n"),
252b5132
RH
6972 abbrev_number);
6973 return 0;
6974 }
6975
b4c96d0d 6976 printf (_(" <%d><%x>: Abbrev Number: %lu (%s)\n"),
252b5132
RH
6977 level, tags - section_begin - bytes_read,
6978 abbrev_number,
6979 get_TAG_name (entry->tag));
6980
6981 for (attr = entry->first_attr; attr; attr = attr->next)
6982 tags = read_and_display_attr (attr->attribute,
6983 attr->form,
1fa37306 6984 tags, cu_offset,
252b5132
RH
6985 compunit.cu_pointer_size);
6986
6987 if (entry->children)
6988 ++level;
6989 }
6990 }
6991
6992 printf ("\n");
6993
6994 return 1;
6995}
6996
6997static int
6998display_debug_aranges (section, start, file)
6999 Elf32_Internal_Shdr * section;
7000 unsigned char * start;
b4c96d0d 7001 FILE * file ATTRIBUTE_UNUSED;
252b5132
RH
7002{
7003 unsigned char * end = start + section->sh_size;
7004
7005 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
7006
7007 while (start < end)
7008 {
7009 DWARF2_External_ARange * external;
7010 DWARF2_Internal_ARange arange;
7011 unsigned char * ranges;
7012 unsigned long length;
7013 unsigned long address;
7a4b7442 7014 int excess;
252b5132
RH
7015
7016 external = (DWARF2_External_ARange *) start;
7017
7018 arange.ar_length = BYTE_GET (external->ar_length);
7019 arange.ar_version = BYTE_GET (external->ar_version);
7020 arange.ar_info_offset = BYTE_GET (external->ar_info_offset);
7021 arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
7022 arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
7023
3f215a10
NC
7024 if (arange.ar_version != 2)
7025 {
7026 warn (_("Only DWARF 2 aranges are currently supported.\n"));
7027 break;
7028 }
7029
252b5132
RH
7030 printf (_(" Length: %ld\n"), arange.ar_length);
7031 printf (_(" Version: %d\n"), arange.ar_version);
7032 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
7033 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
7034 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
7035
7036 printf (_("\n Address Length\n"));
7037
7038 ranges = start + sizeof (* external);
7039
7a4b7442 7040 /* Must pad to an alignment boundary that is twice the pointer size. */
584da044 7041 excess = sizeof (* external) % (2 * arange.ar_pointer_size);
7a4b7442
NC
7042 if (excess)
7043 ranges += (2 * arange.ar_pointer_size) - excess;
7044
252b5132
RH
7045 for (;;)
7046 {
7047 address = byte_get (ranges, arange.ar_pointer_size);
7048
252b5132
RH
7049 ranges += arange.ar_pointer_size;
7050
7051 length = byte_get (ranges, arange.ar_pointer_size);
7052
7053 ranges += arange.ar_pointer_size;
7054
7a4b7442
NC
7055 /* A pair of zeros marks the end of the list. */
7056 if (address == 0 && length == 0)
7057 break;
103f02d3 7058
252b5132
RH
7059 printf (" %8.8lx %lu\n", address, length);
7060 }
7061
7062 start += arange.ar_length + sizeof (external->ar_length);
7063 }
7064
7065 printf ("\n");
7066
7067 return 1;
7068}
7069
c47d488e
DD
7070typedef struct Frame_Chunk
7071{
584da044
NC
7072 struct Frame_Chunk * next;
7073 unsigned char * chunk_start;
7074 int ncols;
a98cc2b2 7075 /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */
584da044
NC
7076 short int * col_type;
7077 int * col_offset;
7078 char * augmentation;
7079 unsigned int code_factor;
31b6fca6 7080 int data_factor;
584da044
NC
7081 unsigned long pc_begin;
7082 unsigned long pc_range;
7083 int cfa_reg;
7084 int cfa_offset;
7085 int ra;
31b6fca6 7086 unsigned char fde_encoding;
c47d488e
DD
7087}
7088Frame_Chunk;
7089
a98cc2b2
AH
7090/* A marker for a col_type that means this column was never referenced
7091 in the frame info. */
7092#define DW_CFA_unreferenced (-1)
7093
c47d488e
DD
7094static void
7095frame_need_space (fc, reg)
584da044 7096 Frame_Chunk * fc;
c47d488e
DD
7097 int reg;
7098{
7099 int prev = fc->ncols;
7100
7101 if (reg < fc->ncols)
7102 return;
584da044 7103
c47d488e 7104 fc->ncols = reg + 1;
a98cc2b2
AH
7105 fc->col_type = (short int *) xrealloc (fc->col_type,
7106 fc->ncols * sizeof (short int));
c47d488e
DD
7107 fc->col_offset = (int *) xrealloc (fc->col_offset,
7108 fc->ncols * sizeof (int));
7109
7110 while (prev < fc->ncols)
7111 {
a98cc2b2 7112 fc->col_type[prev] = DW_CFA_unreferenced;
c47d488e
DD
7113 fc->col_offset[prev] = 0;
7114 prev++;
7115 }
7116}
7117
7118static void
7119frame_display_row (fc, need_col_headers, max_regs)
584da044
NC
7120 Frame_Chunk * fc;
7121 int * need_col_headers;
7122 int * max_regs;
c47d488e
DD
7123{
7124 int r;
7125 char tmp[100];
7126
584da044
NC
7127 if (* max_regs < fc->ncols)
7128 * max_regs = fc->ncols;
7129
7130 if (* need_col_headers)
c47d488e 7131 {
584da044
NC
7132 * need_col_headers = 0;
7133
c47d488e 7134 printf (" LOC CFA ");
584da044
NC
7135
7136 for (r = 0; r < * max_regs; r++)
a98cc2b2
AH
7137 if (fc->col_type[r] != DW_CFA_unreferenced)
7138 {
7139 if (r == fc->ra)
7140 printf ("ra ");
7141 else
7142 printf ("r%-4d", r);
7143 }
584da044 7144
c47d488e
DD
7145 printf ("\n");
7146 }
584da044 7147
31b6fca6 7148 printf ("%08lx ", fc->pc_begin);
c47d488e
DD
7149 sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
7150 printf ("%-8s ", tmp);
584da044
NC
7151
7152 for (r = 0; r < fc->ncols; r++)
c47d488e 7153 {
a98cc2b2 7154 if (fc->col_type[r] != DW_CFA_unreferenced)
c47d488e 7155 {
a98cc2b2
AH
7156 switch (fc->col_type[r])
7157 {
7158 case DW_CFA_undefined:
7159 strcpy (tmp, "u");
7160 break;
7161 case DW_CFA_same_value:
7162 strcpy (tmp, "s");
7163 break;
7164 case DW_CFA_offset:
7165 sprintf (tmp, "c%+d", fc->col_offset[r]);
7166 break;
7167 case DW_CFA_register:
7168 sprintf (tmp, "r%d", fc->col_offset[r]);
7169 break;
7170 default:
7171 strcpy (tmp, "n/a");
7172 break;
7173 }
7174 printf ("%-5s", tmp);
c47d488e 7175 }
c47d488e
DD
7176 }
7177 printf ("\n");
7178}
7179
31b6fca6
RH
7180static int
7181size_of_encoded_value (encoding)
7182 int encoding;
7183{
7184 switch (encoding & 0x7)
7185 {
7186 default: /* ??? */
7187 case 0: return is_32bit_elf ? 4 : 8;
7188 case 2: return 2;
7189 case 3: return 4;
7190 case 4: return 8;
7191 }
7192}
7193
c47d488e 7194#define GET(N) byte_get (start, N); start += N
584da044
NC
7195#define LEB() read_leb128 (start, & length_return, 0); start += length_return
7196#define SLEB() read_leb128 (start, & length_return, 1); start += length_return
c47d488e
DD
7197
7198static int
7199display_debug_frames (section, start, file)
7200 Elf32_Internal_Shdr * section;
7201 unsigned char * start;
7202 FILE * file ATTRIBUTE_UNUSED;
7203{
7204 unsigned char * end = start + section->sh_size;
584da044
NC
7205 unsigned char * section_start = start;
7206 Frame_Chunk * chunks = 0;
7207 Frame_Chunk * remembered_state = 0;
7208 Frame_Chunk * rs;
7209 int is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
7210 int length_return;
7211 int max_regs = 0;
31b6fca6 7212 int addr_size = is_32bit_elf ? 4 : 8;
c47d488e
DD
7213
7214 printf (_("The section %s contains:\n"), SECTION_NAME (section));
7215
7216 while (start < end)
7217 {
584da044
NC
7218 unsigned char * saved_start;
7219 unsigned char * block_end;
7220 unsigned long length;
7221 unsigned long cie_id;
7222 Frame_Chunk * fc;
7223 Frame_Chunk * cie;
7224 int need_col_headers = 1;
31b6fca6
RH
7225 unsigned char * augmentation_data = NULL;
7226 unsigned long augmentation_data_len = 0;
7227 int encoded_ptr_size = addr_size;
c47d488e
DD
7228
7229 saved_start = start;
7230 length = byte_get (start, 4); start += 4;
7231
7232 if (length == 0)
7233 return 1;
7234
7235 block_end = saved_start + length + 4;
7236 cie_id = byte_get (start, 4); start += 4;
7237
c47d488e
DD
7238 if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
7239 {
31b6fca6
RH
7240 int version;
7241
c47d488e
DD
7242 fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
7243 memset (fc, 0, sizeof (Frame_Chunk));
7244
7245 fc->next = chunks;
7246 chunks = fc;
7247 fc->chunk_start = saved_start;
7248 fc->ncols = 0;
a98cc2b2 7249 fc->col_type = (short int *) xmalloc (sizeof (short int));
c47d488e
DD
7250 fc->col_offset = (int *) xmalloc (sizeof (int));
7251 frame_need_space (fc, max_regs-1);
7252
31b6fca6 7253 version = *start++;
584da044 7254
31b6fca6
RH
7255 fc->augmentation = start;
7256 start = strchr (start, '\0') + 1;
584da044 7257
c47d488e
DD
7258 if (fc->augmentation[0] == 'z')
7259 {
c47d488e
DD
7260 fc->code_factor = LEB ();
7261 fc->data_factor = SLEB ();
7262 fc->ra = byte_get (start, 1); start += 1;
31b6fca6
RH
7263 augmentation_data_len = LEB ();
7264 augmentation_data = start;
7265 start += augmentation_data_len;
c47d488e
DD
7266 }
7267 else if (strcmp (fc->augmentation, "eh") == 0)
7268 {
31b6fca6 7269 start += addr_size;
c47d488e
DD
7270 fc->code_factor = LEB ();
7271 fc->data_factor = SLEB ();
7272 fc->ra = byte_get (start, 1); start += 1;
7273 }
7274 else
7275 {
7276 fc->code_factor = LEB ();
7277 fc->data_factor = SLEB ();
7278 fc->ra = byte_get (start, 1); start += 1;
7279 }
7280 cie = fc;
31b6fca6
RH
7281
7282 if (do_debug_frames_interp)
7283 printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
7036c0e1 7284 (unsigned long)(saved_start - section_start), length, cie_id,
31b6fca6
RH
7285 fc->augmentation, fc->code_factor, fc->data_factor,
7286 fc->ra);
7287 else
7288 {
7289 printf ("\n%08lx %08lx %08lx CIE\n",
7036c0e1 7290 (unsigned long)(saved_start - section_start), length, cie_id);
31b6fca6
RH
7291 printf (" Version: %d\n", version);
7292 printf (" Augmentation: \"%s\"\n", fc->augmentation);
7293 printf (" Code alignment factor: %u\n", fc->code_factor);
7294 printf (" Data alignment factor: %d\n", fc->data_factor);
7295 printf (" Return address column: %d\n", fc->ra);
7296
7297 if (augmentation_data_len)
7298 {
7299 unsigned long i;
7300 printf (" Augmentation data: ");
7301 for (i = 0; i < augmentation_data_len; ++i)
7302 printf (" %02x", augmentation_data[i]);
7303 putchar ('\n');
7304 }
7305 putchar ('\n');
7306 }
7307
7308 if (augmentation_data_len)
7309 {
7310 unsigned char *p, *q;
7311 p = fc->augmentation + 1;
7312 q = augmentation_data;
7313
7314 while (1)
7315 {
7316 if (*p == 'L')
7036c0e1 7317 q++;
31b6fca6
RH
7318 else if (*p == 'P')
7319 q += 1 + size_of_encoded_value (*q);
7320 else if (*p == 'R')
7321 fc->fde_encoding = *q++;
7322 else
7323 break;
7324 p++;
7325 }
7326
7327 if (fc->fde_encoding)
7328 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
7329 }
c47d488e
DD
7330
7331 frame_need_space (fc, fc->ra);
7332 }
7333 else
7334 {
584da044 7335 unsigned char * look_for;
c47d488e 7336 static Frame_Chunk fde_fc;
584da044
NC
7337
7338 fc = & fde_fc;
c47d488e
DD
7339 memset (fc, 0, sizeof (Frame_Chunk));
7340
31b6fca6 7341 look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
c47d488e 7342
31b6fca6
RH
7343 for (cie=chunks; cie ; cie = cie->next)
7344 if (cie->chunk_start == look_for)
7345 break;
c47d488e 7346
c47d488e
DD
7347 if (!cie)
7348 {
31b6fca6
RH
7349 warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
7350 cie_id, saved_start);
c47d488e
DD
7351 start = block_end;
7352 fc->ncols = 0;
a98cc2b2 7353 fc->col_type = (short int *) xmalloc (sizeof (short int));
c47d488e 7354 fc->col_offset = (int *) xmalloc (sizeof (int));
584da044 7355 frame_need_space (fc, max_regs - 1);
c47d488e
DD
7356 cie = fc;
7357 fc->augmentation = "";
31b6fca6 7358 fc->fde_encoding = 0;
c47d488e
DD
7359 }
7360 else
7361 {
7362 fc->ncols = cie->ncols;
a98cc2b2 7363 fc->col_type = (short int *) xmalloc (fc->ncols * sizeof (short int));
c47d488e 7364 fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
a98cc2b2 7365 memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
c47d488e
DD
7366 memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
7367 fc->augmentation = cie->augmentation;
7368 fc->code_factor = cie->code_factor;
7369 fc->data_factor = cie->data_factor;
7370 fc->cfa_reg = cie->cfa_reg;
7371 fc->cfa_offset = cie->cfa_offset;
7372 fc->ra = cie->ra;
7373 frame_need_space (fc, max_regs-1);
31b6fca6 7374 fc->fde_encoding = cie->fde_encoding;
c47d488e
DD
7375 }
7376
31b6fca6
RH
7377 if (fc->fde_encoding)
7378 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
7379
7380 fc->pc_begin = byte_get (start, encoded_ptr_size);
7381 start += encoded_ptr_size;
7382 fc->pc_range = byte_get (start, encoded_ptr_size);
7383 start += encoded_ptr_size;
7384
c47d488e
DD
7385 if (cie->augmentation[0] == 'z')
7386 {
31b6fca6
RH
7387 augmentation_data_len = LEB ();
7388 augmentation_data = start;
7389 start += augmentation_data_len;
c47d488e
DD
7390 }
7391
31b6fca6 7392 printf ("\n%08lx %08lx %08lx FDE cie=%08x pc=%08lx..%08lx\n",
7036c0e1 7393 (unsigned long)(saved_start - section_start), length, cie_id,
31b6fca6 7394 cie->chunk_start - section_start, fc->pc_begin,
c47d488e 7395 fc->pc_begin + fc->pc_range);
31b6fca6
RH
7396 if (! do_debug_frames_interp && augmentation_data_len)
7397 {
7398 unsigned long i;
7399 printf (" Augmentation data: ");
7400 for (i = 0; i < augmentation_data_len; ++i)
7401 printf (" %02x", augmentation_data[i]);
7402 putchar ('\n');
7403 putchar ('\n');
7404 }
c47d488e
DD
7405 }
7406
7407 /* At this point, fc is the current chunk, cie (if any) is set, and we're
7408 about to interpret instructions for the chunk. */
7409
31b6fca6 7410 if (do_debug_frames_interp)
a98cc2b2
AH
7411 {
7412 /* Start by making a pass over the chunk, allocating storage
7413 and taking note of what registers are used. */
584da044 7414 unsigned char * tmp = start;
a98cc2b2 7415
a98cc2b2
AH
7416 while (start < block_end)
7417 {
7418 unsigned op, opa;
7419 unsigned long reg;
7036c0e1 7420
584da044 7421 op = * start ++;
a98cc2b2
AH
7422 opa = op & 0x3f;
7423 if (op & 0xc0)
7424 op &= 0xc0;
7036c0e1 7425
a98cc2b2
AH
7426 /* Warning: if you add any more cases to this switch, be
7427 sure to add them to the corresponding switch below. */
7428 switch (op)
7429 {
7430 case DW_CFA_advance_loc:
7431 break;
7432 case DW_CFA_offset:
7433 LEB ();
7434 frame_need_space (fc, opa);
7435 fc->col_type[opa] = DW_CFA_undefined;
7436 break;
7437 case DW_CFA_restore:
7438 frame_need_space (fc, opa);
7439 fc->col_type[opa] = DW_CFA_undefined;
7440 break;
7441 case DW_CFA_set_loc:
31b6fca6 7442 start += encoded_ptr_size;
a98cc2b2
AH
7443 break;
7444 case DW_CFA_advance_loc1:
7445 start += 1;
7446 break;
7447 case DW_CFA_advance_loc2:
7448 start += 2;
7449 break;
7450 case DW_CFA_advance_loc4:
7451 start += 4;
7452 break;
7453 case DW_CFA_offset_extended:
7454 reg = LEB (); LEB ();
7455 frame_need_space (fc, reg);
7456 fc->col_type[reg] = DW_CFA_undefined;
7457 break;
7458 case DW_CFA_restore_extended:
7459 reg = LEB ();
7460 frame_need_space (fc, reg);
7461 fc->col_type[reg] = DW_CFA_undefined;
7462 break;
7463 case DW_CFA_undefined:
7464 reg = LEB ();
7465 frame_need_space (fc, reg);
7466 fc->col_type[reg] = DW_CFA_undefined;
7467 break;
7468 case DW_CFA_same_value:
7469 reg = LEB ();
7470 frame_need_space (fc, reg);
7471 fc->col_type[reg] = DW_CFA_undefined;
7472 break;
7473 case DW_CFA_register:
7474 reg = LEB (); LEB ();
7475 frame_need_space (fc, reg);
7476 fc->col_type[reg] = DW_CFA_undefined;
7477 break;
7478 case DW_CFA_def_cfa:
7479 LEB (); LEB ();
7480 break;
7481 case DW_CFA_def_cfa_register:
7482 LEB ();
7483 break;
7484 case DW_CFA_def_cfa_offset:
7485 LEB ();
7486 break;
7487#ifndef DW_CFA_GNU_args_size
7488#define DW_CFA_GNU_args_size 0x2e
7489#endif
7490 case DW_CFA_GNU_args_size:
7491 LEB ();
7036c0e1 7492 break;
a98cc2b2
AH
7493#ifndef DW_CFA_GNU_negative_offset_extended
7494#define DW_CFA_GNU_negative_offset_extended 0x2f
7495#endif
7496 case DW_CFA_GNU_negative_offset_extended:
7036c0e1 7497 reg = LEB (); LEB ();
a98cc2b2
AH
7498 frame_need_space (fc, reg);
7499 fc->col_type[reg] = DW_CFA_undefined;
7036c0e1 7500
a98cc2b2
AH
7501 default:
7502 break;
7503 }
7504 }
7505 start = tmp;
7506 }
7507
7508 /* Now we know what registers are used, make a second pass over
7509 the chunk, this time actually printing out the info. */
7510
c47d488e
DD
7511 while (start < block_end)
7512 {
7513 unsigned op, opa;
7514 unsigned long ul, reg, roffs;
7515 long l, ofs;
7516 bfd_vma vma;
7517
7518 op = * start ++;
7519 opa = op & 0x3f;
7520 if (op & 0xc0)
7521 op &= 0xc0;
7522
a98cc2b2
AH
7523 /* Warning: if you add any more cases to this switch, be
7524 sure to add them to the corresponding switch above. */
c47d488e
DD
7525 switch (op)
7526 {
7527 case DW_CFA_advance_loc:
31b6fca6
RH
7528 if (do_debug_frames_interp)
7529 frame_display_row (fc, &need_col_headers, &max_regs);
7530 else
7531 printf (" DW_CFA_advance_loc: %d to %08lx\n",
7532 opa * fc->code_factor,
7533 fc->pc_begin + opa * fc->code_factor);
c47d488e
DD
7534 fc->pc_begin += opa * fc->code_factor;
7535 break;
7536
7537 case DW_CFA_offset:
c47d488e 7538 roffs = LEB ();
31b6fca6 7539 if (! do_debug_frames_interp)
7036c0e1 7540 printf (" DW_CFA_offset: r%d at cfa%+ld\n",
31b6fca6 7541 opa, roffs * fc->data_factor);
c47d488e
DD
7542 fc->col_type[opa] = DW_CFA_offset;
7543 fc->col_offset[opa] = roffs * fc->data_factor;
7544 break;
7545
7546 case DW_CFA_restore:
31b6fca6
RH
7547 if (! do_debug_frames_interp)
7548 printf (" DW_CFA_restore: r%d\n", opa);
c47d488e
DD
7549 fc->col_type[opa] = cie->col_type[opa];
7550 fc->col_offset[opa] = cie->col_offset[opa];
7551 break;
7552
7553 case DW_CFA_set_loc:
31b6fca6
RH
7554 vma = byte_get (start, encoded_ptr_size);
7555 start += encoded_ptr_size;
7556 if (do_debug_frames_interp)
7557 frame_display_row (fc, &need_col_headers, &max_regs);
7558 else
7036c0e1 7559 printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
c47d488e
DD
7560 fc->pc_begin = vma;
7561 break;
7562
7563 case DW_CFA_advance_loc1:
c47d488e 7564 ofs = byte_get (start, 1); start += 1;
31b6fca6
RH
7565 if (do_debug_frames_interp)
7566 frame_display_row (fc, &need_col_headers, &max_regs);
7567 else
7036c0e1 7568 printf (" DW_CFA_advance_loc1: %ld to %08lx\n",
31b6fca6
RH
7569 ofs * fc->code_factor,
7570 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
7571 fc->pc_begin += ofs * fc->code_factor;
7572 break;
7573
7574 case DW_CFA_advance_loc2:
c47d488e 7575 ofs = byte_get (start, 2); start += 2;
31b6fca6
RH
7576 if (do_debug_frames_interp)
7577 frame_display_row (fc, &need_col_headers, &max_regs);
7578 else
7036c0e1 7579 printf (" DW_CFA_advance_loc2: %ld to %08lx\n",
31b6fca6
RH
7580 ofs * fc->code_factor,
7581 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
7582 fc->pc_begin += ofs * fc->code_factor;
7583 break;
7584
7585 case DW_CFA_advance_loc4:
c47d488e 7586 ofs = byte_get (start, 4); start += 4;
31b6fca6
RH
7587 if (do_debug_frames_interp)
7588 frame_display_row (fc, &need_col_headers, &max_regs);
7589 else
7036c0e1 7590 printf (" DW_CFA_advance_loc4: %ld to %08lx\n",
31b6fca6
RH
7591 ofs * fc->code_factor,
7592 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
7593 fc->pc_begin += ofs * fc->code_factor;
7594 break;
7595
7596 case DW_CFA_offset_extended:
7597 reg = LEB ();
7598 roffs = LEB ();
31b6fca6 7599 if (! do_debug_frames_interp)
7036c0e1 7600 printf (" DW_CFA_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 7601 reg, roffs * fc->data_factor);
c47d488e
DD
7602 fc->col_type[reg] = DW_CFA_offset;
7603 fc->col_offset[reg] = roffs * fc->data_factor;
7604 break;
7605
7606 case DW_CFA_restore_extended:
7607 reg = LEB ();
31b6fca6 7608 if (! do_debug_frames_interp)
7036c0e1 7609 printf (" DW_CFA_restore_extended: r%ld\n", reg);
c47d488e
DD
7610 fc->col_type[reg] = cie->col_type[reg];
7611 fc->col_offset[reg] = cie->col_offset[reg];
7612 break;
7613
7614 case DW_CFA_undefined:
7615 reg = LEB ();
31b6fca6 7616 if (! do_debug_frames_interp)
7036c0e1 7617 printf (" DW_CFA_undefined: r%ld\n", reg);
c47d488e
DD
7618 fc->col_type[reg] = DW_CFA_undefined;
7619 fc->col_offset[reg] = 0;
7620 break;
7621
7622 case DW_CFA_same_value:
7623 reg = LEB ();
31b6fca6 7624 if (! do_debug_frames_interp)
7036c0e1 7625 printf (" DW_CFA_same_value: r%ld\n", reg);
c47d488e
DD
7626 fc->col_type[reg] = DW_CFA_same_value;
7627 fc->col_offset[reg] = 0;
7628 break;
7629
7630 case DW_CFA_register:
7631 reg = LEB ();
7632 roffs = LEB ();
31b6fca6 7633 if (! do_debug_frames_interp)
7036c0e1 7634 printf (" DW_CFA_register: r%ld\n", reg);
c47d488e
DD
7635 fc->col_type[reg] = DW_CFA_register;
7636 fc->col_offset[reg] = roffs;
7637 break;
7638
7639 case DW_CFA_remember_state:
31b6fca6
RH
7640 if (! do_debug_frames_interp)
7641 printf (" DW_CFA_remember_state\n");
c47d488e
DD
7642 rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
7643 rs->ncols = fc->ncols;
a98cc2b2 7644 rs->col_type = (short int *) xmalloc (rs->ncols * sizeof (short int));
c47d488e
DD
7645 rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
7646 memcpy (rs->col_type, fc->col_type, rs->ncols);
7647 memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
7648 rs->next = remembered_state;
7649 remembered_state = rs;
7650 break;
7651
7652 case DW_CFA_restore_state:
31b6fca6
RH
7653 if (! do_debug_frames_interp)
7654 printf (" DW_CFA_restore_state\n");
c47d488e
DD
7655 rs = remembered_state;
7656 remembered_state = rs->next;
7657 frame_need_space (fc, rs->ncols-1);
7658 memcpy (fc->col_type, rs->col_type, rs->ncols);
7659 memcpy (fc->col_offset, rs->col_offset, rs->ncols * sizeof (int));
7660 free (rs->col_type);
7661 free (rs->col_offset);
7662 free (rs);
7663 break;
7664
7665 case DW_CFA_def_cfa:
7666 fc->cfa_reg = LEB ();
7667 fc->cfa_offset = LEB ();
31b6fca6
RH
7668 if (! do_debug_frames_interp)
7669 printf (" DW_CFA_def_cfa: r%d ofs %d\n",
7670 fc->cfa_reg, fc->cfa_offset);
c47d488e
DD
7671 break;
7672
7673 case DW_CFA_def_cfa_register:
7674 fc->cfa_reg = LEB ();
31b6fca6
RH
7675 if (! do_debug_frames_interp)
7676 printf (" DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
c47d488e
DD
7677 break;
7678
7679 case DW_CFA_def_cfa_offset:
7680 fc->cfa_offset = LEB ();
31b6fca6
RH
7681 if (! do_debug_frames_interp)
7682 printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
c47d488e
DD
7683 break;
7684
7685 case DW_CFA_nop:
31b6fca6
RH
7686 if (! do_debug_frames_interp)
7687 printf (" DW_CFA_nop\n");
c47d488e
DD
7688 break;
7689
7690#ifndef DW_CFA_GNU_window_save
7691#define DW_CFA_GNU_window_save 0x2d
7692#endif
7693 case DW_CFA_GNU_window_save:
31b6fca6
RH
7694 if (! do_debug_frames_interp)
7695 printf (" DW_CFA_GNU_window_save\n");
c47d488e
DD
7696 break;
7697
c47d488e
DD
7698 case DW_CFA_GNU_args_size:
7699 ul = LEB ();
31b6fca6 7700 if (! do_debug_frames_interp)
7036c0e1 7701 printf (" DW_CFA_GNU_args_size: %ld\n", ul);
c47d488e
DD
7702 break;
7703
c47d488e
DD
7704 case DW_CFA_GNU_negative_offset_extended:
7705 reg = LEB ();
7706 l = - LEB ();
7707 frame_need_space (fc, reg);
31b6fca6 7708 if (! do_debug_frames_interp)
7036c0e1 7709 printf (" DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 7710 reg, l * fc->data_factor);
c47d488e
DD
7711 fc->col_type[reg] = DW_CFA_offset;
7712 fc->col_offset[reg] = l * fc->data_factor;
7713 break;
7714
7715 default:
7716 fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
7717 start = block_end;
7718 }
7719 }
7720
31b6fca6
RH
7721 if (do_debug_frames_interp)
7722 frame_display_row (fc, &need_col_headers, &max_regs);
c47d488e
DD
7723
7724 start = block_end;
7725 }
7726
7727 printf ("\n");
7728
7729 return 1;
7730}
7731
7732#undef GET
7733#undef LEB
7734#undef SLEB
252b5132
RH
7735
7736static int
7737display_debug_not_supported (section, start, file)
7738 Elf32_Internal_Shdr * section;
b4c96d0d
ILT
7739 unsigned char * start ATTRIBUTE_UNUSED;
7740 FILE * file ATTRIBUTE_UNUSED;
252b5132
RH
7741{
7742 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
7743 SECTION_NAME (section));
7744
7745 return 1;
7746}
7747
3590ea00
NC
7748/* Pre-scan the .debug_info section to record the size of address.
7749 When dumping the .debug_line, we use that size information, assuming
7750 that all compilation units have the same address size. */
7751static int
7752prescan_debug_info (section, start, file)
7753 Elf32_Internal_Shdr * section ATTRIBUTE_UNUSED;
7754 unsigned char * start;
7755 FILE * file ATTRIBUTE_UNUSED;
7756{
7757 DWARF2_External_CompUnit * external;
7758
7759 external = (DWARF2_External_CompUnit *) start;
7760
7761 debug_line_pointer_size = BYTE_GET (external->cu_pointer_size);
7762 return 0;
7763}
7764
252b5132 7765 /* A structure containing the name of a debug section and a pointer
3590ea00
NC
7766 to a function that can decode it. The third field is a prescan
7767 function to be run over the section before displaying any of the
7768 sections. */
252b5132
RH
7769struct
7770{
7771 char * name;
3590ea00
NC
7772 int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
7773 int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
252b5132
RH
7774}
7775debug_displays[] =
7776{
3590ea00
NC
7777 { ".debug_info", display_debug_info, prescan_debug_info },
7778 { ".debug_abbrev", display_debug_abbrev, NULL },
7779 { ".debug_line", display_debug_lines, NULL },
7780 { ".debug_aranges", display_debug_aranges, NULL },
7781 { ".debug_pubnames", display_debug_pubnames, NULL },
c47d488e
DD
7782 { ".debug_frame", display_debug_frames, NULL },
7783 { ".eh_frame", display_debug_frames, NULL },
3590ea00 7784 { ".debug_macinfo", display_debug_not_supported, NULL },
3590ea00
NC
7785 { ".debug_str", display_debug_not_supported, NULL },
7786 { ".debug_static_func", display_debug_not_supported, NULL },
7787 { ".debug_static_vars", display_debug_not_supported, NULL },
7788 { ".debug_types", display_debug_not_supported, NULL },
7789 { ".debug_weaknames", display_debug_not_supported, NULL }
252b5132
RH
7790};
7791
7792static int
7793display_debug_section (section, file)
7794 Elf32_Internal_Shdr * section;
7795 FILE * file;
7796{
7797 char * name = SECTION_NAME (section);
7798 bfd_size_type length;
7799 unsigned char * start;
7800 int i;
7801
7802 length = section->sh_size;
7803 if (length == 0)
7804 {
7805 printf (_("\nSection '%s' has no debugging data.\n"), name);
7806 return 0;
7807 }
7808
a6e9f9df
AM
7809 start = (unsigned char *) get_data (NULL, file, section->sh_offset, length,
7810 _("debug section data"));
7811 if (!start)
7812 return 0;
252b5132
RH
7813
7814 /* See if we know how to display the contents of this section. */
09fd7e38 7815 if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
7036c0e1 7816 name = ".debug_info";
584da044 7817
252b5132
RH
7818 for (i = NUM_ELEM (debug_displays); i--;)
7819 if (strcmp (debug_displays[i].name, name) == 0)
7820 {
7821 debug_displays[i].display (section, start, file);
7822 break;
7823 }
7824
7825 if (i == -1)
7826 printf (_("Unrecognised debug section: %s\n"), name);
7827
7828 free (start);
7829
7830 /* If we loaded in the abbrev section at some point,
7831 we must release it here. */
7832 if (first_abbrev != NULL)
7833 free_abbrevs ();
7834
7835 return 1;
7836}
7837
7838static int
7839process_section_contents (file)
7840 FILE * file;
7841{
3590ea00 7842 Elf32_Internal_Shdr * section;
7036c0e1 7843 unsigned int i;
252b5132
RH
7844
7845 if (! do_dump)
7846 return 1;
7847
3590ea00
NC
7848 /* Pre-scan the debug sections to find some debug information not
7849 present in some of them. For the .debug_line, we must find out the
7850 size of address (specified in .debug_info and .debug_aranges). */
7851 for (i = 0, section = section_headers;
7852 i < elf_header.e_shnum && i < num_dump_sects;
7853 i ++, section ++)
7854 {
7855 char * name = SECTION_NAME (section);
7856 int j;
7857
7858 if (section->sh_size == 0)
7859 continue;
7860
7861 /* See if there is some pre-scan operation for this section. */
7862 for (j = NUM_ELEM (debug_displays); j--;)
7863 if (strcmp (debug_displays[j].name, name) == 0)
7864 {
7865 if (debug_displays[j].prescan != NULL)
7866 {
7867 bfd_size_type length;
7868 unsigned char * start;
7869
7870 length = section->sh_size;
a6e9f9df
AM
7871 start = ((unsigned char *)
7872 get_data (NULL, file, section->sh_offset, length,
7873 _("debug section data")));
7874 if (!start)
7875 return 0;
3590ea00
NC
7876
7877 debug_displays[j].prescan (section, start, file);
7878 free (start);
7879 }
103f02d3 7880
3590ea00
NC
7881 break;
7882 }
7883 }
7884
252b5132 7885 for (i = 0, section = section_headers;
3590ea00 7886 i < elf_header.e_shnum && i < num_dump_sects;
252b5132
RH
7887 i ++, section ++)
7888 {
7889#ifdef SUPPORT_DISASSEMBLY
7890 if (dump_sects[i] & DISASS_DUMP)
7891 disassemble_section (section, file);
7892#endif
7893 if (dump_sects[i] & HEX_DUMP)
7894 dump_section (section, file);
7895
7896 if (dump_sects[i] & DEBUG_DUMP)
7897 display_debug_section (section, file);
7898 }
7899
7900 if (i < num_dump_sects)
7901 warn (_("Some sections were not dumped because they do not exist!\n"));
7902
7903 return 1;
7904}
7905
7906static void
7907process_mips_fpe_exception (mask)
7908 int mask;
7909{
7910 if (mask)
7911 {
7912 int first = 1;
7913 if (mask & OEX_FPU_INEX)
7914 fputs ("INEX", stdout), first = 0;
7915 if (mask & OEX_FPU_UFLO)
7916 printf ("%sUFLO", first ? "" : "|"), first = 0;
7917 if (mask & OEX_FPU_OFLO)
7918 printf ("%sOFLO", first ? "" : "|"), first = 0;
7919 if (mask & OEX_FPU_DIV0)
7920 printf ("%sDIV0", first ? "" : "|"), first = 0;
7921 if (mask & OEX_FPU_INVAL)
7922 printf ("%sINVAL", first ? "" : "|");
7923 }
7924 else
7925 fputs ("0", stdout);
7926}
7927
7928static int
7929process_mips_specific (file)
9ea033b2 7930 FILE * file;
252b5132 7931{
9ea033b2 7932 Elf_Internal_Dyn * entry;
252b5132
RH
7933 size_t liblist_offset = 0;
7934 size_t liblistno = 0;
7935 size_t conflictsno = 0;
7936 size_t options_offset = 0;
7937 size_t conflicts_offset = 0;
7938
7939 /* We have a lot of special sections. Thanks SGI! */
7940 if (dynamic_segment == NULL)
7941 /* No information available. */
7942 return 0;
7943
7944 for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
7945 switch (entry->d_tag)
7946 {
7947 case DT_MIPS_LIBLIST:
7948 liblist_offset = entry->d_un.d_val - loadaddr;
7949 break;
7950 case DT_MIPS_LIBLISTNO:
7951 liblistno = entry->d_un.d_val;
7952 break;
7953 case DT_MIPS_OPTIONS:
7954 options_offset = entry->d_un.d_val - loadaddr;
7955 break;
7956 case DT_MIPS_CONFLICT:
7957 conflicts_offset = entry->d_un.d_val - loadaddr;
7958 break;
7959 case DT_MIPS_CONFLICTNO:
7960 conflictsno = entry->d_un.d_val;
7961 break;
7962 default:
7963 break;
7964 }
7965
7966 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
7967 {
9ea033b2 7968 Elf32_External_Lib * elib;
252b5132
RH
7969 size_t cnt;
7970
a6e9f9df
AM
7971 elib = ((Elf32_External_Lib *)
7972 get_data (NULL, file, liblist_offset,
7973 liblistno * sizeof (Elf32_External_Lib),
7974 _("liblist")));
7975 if (elib)
252b5132 7976 {
a6e9f9df
AM
7977 printf ("\nSection '.liblist' contains %lu entries:\n",
7978 (unsigned long) liblistno);
7979 fputs (" Library Time Stamp Checksum Version Flags\n",
7980 stdout);
7981
7982 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 7983 {
a6e9f9df
AM
7984 Elf32_Lib liblist;
7985 time_t time;
7986 char timebuf[20];
7987 struct tm * tmp;
7988
7989 liblist.l_name = BYTE_GET (elib[cnt].l_name);
7990 time = BYTE_GET (elib[cnt].l_time_stamp);
7991 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
7992 liblist.l_version = BYTE_GET (elib[cnt].l_version);
7993 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
7994
7995 tmp = gmtime (&time);
7996 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
7997 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7998 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
7999
8000 printf ("%3lu: %-20s %s %#10lx %-7ld", (unsigned long) cnt,
8001 dynamic_strings + liblist.l_name, timebuf,
8002 liblist.l_checksum, liblist.l_version);
8003
8004 if (liblist.l_flags == 0)
8005 puts (" NONE");
8006 else
8007 {
8008 static const struct
252b5132 8009 {
a6e9f9df
AM
8010 const char * name;
8011 int bit;
252b5132 8012 }
a6e9f9df
AM
8013 l_flags_vals[] =
8014 {
8015 { " EXACT_MATCH", LL_EXACT_MATCH },
8016 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
8017 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
8018 { " EXPORTS", LL_EXPORTS },
8019 { " DELAY_LOAD", LL_DELAY_LOAD },
8020 { " DELTA", LL_DELTA }
8021 };
8022 int flags = liblist.l_flags;
8023 size_t fcnt;
8024
8025 for (fcnt = 0;
8026 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
8027 ++fcnt)
8028 if ((flags & l_flags_vals[fcnt].bit) != 0)
8029 {
8030 fputs (l_flags_vals[fcnt].name, stdout);
8031 flags ^= l_flags_vals[fcnt].bit;
8032 }
8033 if (flags != 0)
8034 printf (" %#x", (unsigned int) flags);
252b5132 8035
a6e9f9df
AM
8036 puts ("");
8037 }
252b5132 8038 }
252b5132 8039
a6e9f9df
AM
8040 free (elib);
8041 }
252b5132
RH
8042 }
8043
8044 if (options_offset != 0)
8045 {
9ea033b2 8046 Elf_External_Options * eopt;
d1133906 8047 Elf_Internal_Shdr * sect = section_headers;
9ea033b2
NC
8048 Elf_Internal_Options * iopt;
8049 Elf_Internal_Options * option;
252b5132
RH
8050 size_t offset;
8051 int cnt;
8052
8053 /* Find the section header so that we get the size. */
8054 while (sect->sh_type != SHT_MIPS_OPTIONS)
d1133906 8055 ++ sect;
252b5132 8056
a6e9f9df
AM
8057 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset,
8058 sect->sh_size, _("options"));
8059 if (eopt)
252b5132 8060 {
a6e9f9df
AM
8061 iopt = ((Elf_Internal_Options *)
8062 malloc ((sect->sh_size / sizeof (eopt)) * sizeof (* iopt)));
8063 if (iopt == NULL)
8064 {
8065 error (_("Out of memory"));
8066 return 0;
8067 }
76da6bbe 8068
a6e9f9df
AM
8069 offset = cnt = 0;
8070 option = iopt;
252b5132 8071
a6e9f9df
AM
8072 while (offset < sect->sh_size)
8073 {
8074 Elf_External_Options * eoption;
252b5132 8075
a6e9f9df 8076 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 8077
a6e9f9df
AM
8078 option->kind = BYTE_GET (eoption->kind);
8079 option->size = BYTE_GET (eoption->size);
8080 option->section = BYTE_GET (eoption->section);
8081 option->info = BYTE_GET (eoption->info);
76da6bbe 8082
a6e9f9df 8083 offset += option->size;
252b5132 8084
a6e9f9df
AM
8085 ++option;
8086 ++cnt;
8087 }
252b5132 8088
a6e9f9df
AM
8089 printf (_("\nSection '%s' contains %d entries:\n"),
8090 SECTION_NAME (sect), cnt);
76da6bbe 8091
a6e9f9df 8092 option = iopt;
252b5132 8093
a6e9f9df 8094 while (cnt-- > 0)
252b5132 8095 {
a6e9f9df
AM
8096 size_t len;
8097
8098 switch (option->kind)
252b5132 8099 {
a6e9f9df
AM
8100 case ODK_NULL:
8101 /* This shouldn't happen. */
8102 printf (" NULL %d %lx", option->section, option->info);
8103 break;
8104 case ODK_REGINFO:
8105 printf (" REGINFO ");
8106 if (elf_header.e_machine == EM_MIPS)
8107 {
8108 /* 32bit form. */
8109 Elf32_External_RegInfo * ereg;
8110 Elf32_RegInfo reginfo;
8111
8112 ereg = (Elf32_External_RegInfo *) (option + 1);
8113 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8114 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8115 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8116 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8117 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8118 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
8119
8120 printf ("GPR %08lx GP 0x%lx\n",
8121 reginfo.ri_gprmask,
8122 (unsigned long) reginfo.ri_gp_value);
8123 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
8124 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8125 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8126 }
8127 else
8128 {
8129 /* 64 bit form. */
8130 Elf64_External_RegInfo * ereg;
8131 Elf64_Internal_RegInfo reginfo;
8132
8133 ereg = (Elf64_External_RegInfo *) (option + 1);
8134 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8135 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8136 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8137 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8138 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8139 reginfo.ri_gp_value = BYTE_GET8 (ereg->ri_gp_value);
8140
8141 printf ("GPR %08lx GP 0x",
8142 reginfo.ri_gprmask);
8143 printf_vma (reginfo.ri_gp_value);
8144 printf ("\n");
8145
8146 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
8147 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8148 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8149 }
8150 ++option;
8151 continue;
8152 case ODK_EXCEPTIONS:
8153 fputs (" EXCEPTIONS fpe_min(", stdout);
8154 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
8155 fputs (") fpe_max(", stdout);
8156 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
8157 fputs (")", stdout);
8158
8159 if (option->info & OEX_PAGE0)
8160 fputs (" PAGE0", stdout);
8161 if (option->info & OEX_SMM)
8162 fputs (" SMM", stdout);
8163 if (option->info & OEX_FPDBUG)
8164 fputs (" FPDBUG", stdout);
8165 if (option->info & OEX_DISMISS)
8166 fputs (" DISMISS", stdout);
8167 break;
8168 case ODK_PAD:
8169 fputs (" PAD ", stdout);
8170 if (option->info & OPAD_PREFIX)
8171 fputs (" PREFIX", stdout);
8172 if (option->info & OPAD_POSTFIX)
8173 fputs (" POSTFIX", stdout);
8174 if (option->info & OPAD_SYMBOL)
8175 fputs (" SYMBOL", stdout);
8176 break;
8177 case ODK_HWPATCH:
8178 fputs (" HWPATCH ", stdout);
8179 if (option->info & OHW_R4KEOP)
8180 fputs (" R4KEOP", stdout);
8181 if (option->info & OHW_R8KPFETCH)
8182 fputs (" R8KPFETCH", stdout);
8183 if (option->info & OHW_R5KEOP)
8184 fputs (" R5KEOP", stdout);
8185 if (option->info & OHW_R5KCVTL)
8186 fputs (" R5KCVTL", stdout);
8187 break;
8188 case ODK_FILL:
8189 fputs (" FILL ", stdout);
8190 /* XXX Print content of info word? */
8191 break;
8192 case ODK_TAGS:
8193 fputs (" TAGS ", stdout);
8194 /* XXX Print content of info word? */
8195 break;
8196 case ODK_HWAND:
8197 fputs (" HWAND ", stdout);
8198 if (option->info & OHWA0_R4KEOP_CHECKED)
8199 fputs (" R4KEOP_CHECKED", stdout);
8200 if (option->info & OHWA0_R4KEOP_CLEAN)
8201 fputs (" R4KEOP_CLEAN", stdout);
8202 break;
8203 case ODK_HWOR:
8204 fputs (" HWOR ", stdout);
8205 if (option->info & OHWA0_R4KEOP_CHECKED)
8206 fputs (" R4KEOP_CHECKED", stdout);
8207 if (option->info & OHWA0_R4KEOP_CLEAN)
8208 fputs (" R4KEOP_CLEAN", stdout);
8209 break;
8210 case ODK_GP_GROUP:
8211 printf (" GP_GROUP %#06lx self-contained %#06lx",
8212 option->info & OGP_GROUP,
8213 (option->info & OGP_SELF) >> 16);
8214 break;
8215 case ODK_IDENT:
8216 printf (" IDENT %#06lx self-contained %#06lx",
8217 option->info & OGP_GROUP,
8218 (option->info & OGP_SELF) >> 16);
8219 break;
8220 default:
8221 /* This shouldn't happen. */
8222 printf (" %3d ??? %d %lx",
8223 option->kind, option->section, option->info);
8224 break;
252b5132 8225 }
a6e9f9df
AM
8226
8227 len = sizeof (* eopt);
8228 while (len < option->size)
8229 if (((char *) option)[len] >= ' '
8230 && ((char *) option)[len] < 0x7f)
8231 printf ("%c", ((char *) option)[len++]);
8232 else
8233 printf ("\\%03o", ((char *) option)[len++]);
8234
8235 fputs ("\n", stdout);
252b5132 8236 ++option;
252b5132
RH
8237 }
8238
a6e9f9df 8239 free (eopt);
252b5132 8240 }
252b5132
RH
8241 }
8242
8243 if (conflicts_offset != 0 && conflictsno != 0)
8244 {
9ea033b2 8245 Elf32_Conflict * iconf;
252b5132
RH
8246 size_t cnt;
8247
8248 if (dynamic_symbols == NULL)
8249 {
8250 error (_("conflict list with without table"));
8251 return 0;
8252 }
8253
584da044 8254 iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (* iconf));
252b5132
RH
8255 if (iconf == NULL)
8256 {
8257 error (_("Out of memory"));
8258 return 0;
8259 }
8260
9ea033b2 8261 if (is_32bit_elf)
252b5132 8262 {
a6e9f9df
AM
8263 Elf32_External_Conflict * econf32;
8264
8265 econf32 = ((Elf32_External_Conflict *)
8266 get_data (NULL, file, conflicts_offset,
8267 conflictsno * sizeof (* econf32),
8268 _("conflict")));
8269 if (!econf32)
8270 return 0;
252b5132
RH
8271
8272 for (cnt = 0; cnt < conflictsno; ++cnt)
8273 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
8274
8275 free (econf32);
252b5132
RH
8276 }
8277 else
8278 {
a6e9f9df
AM
8279 Elf64_External_Conflict * econf64;
8280
8281 econf64 = ((Elf64_External_Conflict *)
8282 get_data (NULL, file, conflicts_offset,
8283 conflictsno * sizeof (* econf64),
8284 _("conflict")));
8285 if (!econf64)
8286 return 0;
252b5132
RH
8287
8288 for (cnt = 0; cnt < conflictsno; ++cnt)
8289 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
8290
8291 free (econf64);
252b5132
RH
8292 }
8293
8294 printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
8295 puts (_(" Num: Index Value Name"));
8296
8297 for (cnt = 0; cnt < conflictsno; ++cnt)
8298 {
19936277 8299 Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
252b5132 8300
16062207 8301 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963
NC
8302 print_vma (psym->st_value, FULL_HEX);
8303 printf (" %s\n", dynamic_strings + psym->st_name);
252b5132
RH
8304 }
8305
252b5132
RH
8306 free (iconf);
8307 }
8308
8309 return 1;
8310}
8311
779fe533
NC
8312static char *
8313get_note_type (e_type)
8314 unsigned e_type;
8315{
8316 static char buff[64];
103f02d3 8317
779fe533
NC
8318 switch (e_type)
8319 {
8320 case NT_PRSTATUS: return _("NT_PRSTATUS (prstatus structure)");
8321 case NT_FPREGSET: return _("NT_FPREGSET (floating point registers)");
8322 case NT_PRPSINFO: return _("NT_PRPSINFO (prpsinfo structure)");
8323 case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
d1133906 8324 case NT_PRXFPREG: return _("NT_PRXFPREG (user_xfpregs structure)");
779fe533
NC
8325 case NT_PSTATUS: return _("NT_PSTATUS (pstatus structure)");
8326 case NT_FPREGS: return _("NT_FPREGS (floating point registers)");
8327 case NT_PSINFO: return _("NT_PSINFO (psinfo structure)");
8328 case NT_LWPSTATUS: return _("NT_LWPSTATUS (lwpstatus_t structure)");
8329 case NT_LWPSINFO: return _("NT_LWPSINFO (lwpsinfo_t structure)");
7bea2f73 8330 case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus strcuture)");
779fe533
NC
8331 default:
8332 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
8333 return buff;
8334 }
8335}
8336
6d118b09
NC
8337/* Note that by the ELF standard, the name field is already null byte
8338 terminated, and namesz includes the terminating null byte.
8339 I.E. the value of namesz for the name "FSF" is 4.
8340
8341 If the value of namesz is zero, there is no name present. */
779fe533
NC
8342static int
8343process_note (pnote)
6d118b09 8344 Elf32_Internal_Note * pnote;
779fe533 8345{
103f02d3 8346 printf (" %s\t\t0x%08lx\t%s\n",
6d118b09 8347 pnote->namesz ? pnote->namedata : "(NONE)",
7036c0e1 8348 pnote->descsz, get_note_type (pnote->type));
779fe533
NC
8349 return 1;
8350}
8351
6d118b09 8352
779fe533
NC
8353static int
8354process_corefile_note_segment (file, offset, length)
8355 FILE * file;
f7a99963
NC
8356 bfd_vma offset;
8357 bfd_vma length;
779fe533
NC
8358{
8359 Elf_External_Note * pnotes;
8360 Elf_External_Note * external;
779fe533 8361 int res = 1;
103f02d3 8362
779fe533
NC
8363 if (length <= 0)
8364 return 0;
103f02d3 8365
a6e9f9df
AM
8366 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, length,
8367 _("notes"));
8368 if (!pnotes)
8369 return 0;
779fe533 8370
103f02d3 8371 external = pnotes;
103f02d3 8372
305c7206 8373 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 8374 (unsigned long) offset, (unsigned long) length);
779fe533 8375 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 8376
6d118b09 8377 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 8378 {
6d118b09
NC
8379 Elf32_Internal_Note inote;
8380 char * temp = NULL;
8381
8382 inote.type = BYTE_GET (external->type);
8383 inote.namesz = BYTE_GET (external->namesz);
8384 inote.namedata = external->name;
8385 inote.descsz = BYTE_GET (external->descsz);
8386 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
8387 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 8388
6d118b09
NC
8389 external = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
8390
8391 /* Verify that name is null terminated. It appears that at least
8392 one version of Linux (RedHat 6.0) generates corefiles that don't
8393 comply with the ELF spec by failing to include the null byte in
8394 namesz. */
8395 if (inote.namedata[inote.namesz] != '\0')
8396 {
8397 temp = malloc (inote.namesz + 1);
76da6bbe 8398
6d118b09
NC
8399 if (temp == NULL)
8400 {
8401 error (_("Out of memory\n"));
8402 res = 0;
8403 break;
8404 }
76da6bbe 8405
6d118b09
NC
8406 strncpy (temp, inote.namedata, inote.namesz);
8407 temp[inote.namesz] = 0;
76da6bbe 8408
6d118b09
NC
8409 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
8410 inote.namedata = temp;
8411 }
8412
8413 res &= process_note (& inote);
103f02d3 8414
6d118b09
NC
8415 if (temp != NULL)
8416 {
8417 free (temp);
8418 temp = NULL;
8419 }
779fe533
NC
8420 }
8421
8422 free (pnotes);
103f02d3 8423
779fe533
NC
8424 return res;
8425}
8426
8427static int
8428process_corefile_note_segments (file)
8429 FILE * file;
8430{
8431 Elf_Internal_Phdr * program_headers;
8432 Elf_Internal_Phdr * segment;
8433 unsigned int i;
8434 int res = 1;
103f02d3 8435
779fe533
NC
8436 program_headers = (Elf_Internal_Phdr *) malloc
8437 (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
8438
8439 if (program_headers == NULL)
8440 {
8441 error (_("Out of memory\n"));
8442 return 0;
8443 }
8444
8445 if (is_32bit_elf)
8446 i = get_32bit_program_headers (file, program_headers);
8447 else
8448 i = get_64bit_program_headers (file, program_headers);
8449
8450 if (i == 0)
8451 {
8452 free (program_headers);
8453 return 0;
8454 }
103f02d3 8455
779fe533
NC
8456 for (i = 0, segment = program_headers;
8457 i < elf_header.e_phnum;
8458 i ++, segment ++)
8459 {
8460 if (segment->p_type == PT_NOTE)
103f02d3 8461 res &= process_corefile_note_segment (file,
30800947
NC
8462 (bfd_vma) segment->p_offset,
8463 (bfd_vma) segment->p_filesz);
779fe533 8464 }
103f02d3 8465
779fe533
NC
8466 free (program_headers);
8467
8468 return res;
8469}
8470
8471static int
8472process_corefile_contents (file)
8473 FILE * file;
8474{
8475 /* If we have not been asked to display the notes then do nothing. */
8476 if (! do_notes)
8477 return 1;
103f02d3 8478
779fe533
NC
8479 /* If file is not a core file then exit. */
8480 if (elf_header.e_type != ET_CORE)
8481 return 1;
103f02d3 8482
779fe533
NC
8483 /* No program headers means no NOTE segment. */
8484 if (elf_header.e_phnum == 0)
8485 {
8486 printf (_("No note segments present in the core file.\n"));
8487 return 1;
8488 }
8489
8490 return process_corefile_note_segments (file);
8491}
8492
252b5132
RH
8493static int
8494process_arch_specific (file)
9ea033b2 8495 FILE * file;
252b5132 8496{
a952a375
NC
8497 if (! do_arch)
8498 return 1;
8499
252b5132
RH
8500 switch (elf_header.e_machine)
8501 {
8502 case EM_MIPS:
4fe85591 8503 case EM_MIPS_RS3_LE:
252b5132
RH
8504 return process_mips_specific (file);
8505 break;
8506 default:
8507 break;
8508 }
8509 return 1;
8510}
8511
8512static int
8513get_file_header (file)
8514 FILE * file;
8515{
9ea033b2
NC
8516 /* Read in the identity array. */
8517 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
8518 return 0;
8519
9ea033b2
NC
8520 /* Determine how to read the rest of the header. */
8521 switch (elf_header.e_ident [EI_DATA])
8522 {
8523 default: /* fall through */
8524 case ELFDATANONE: /* fall through */
8525 case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
8526 case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
8527 }
8528
8529 /* For now we only support 32 bit and 64 bit ELF files. */
8530 is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
8531
8532 /* Read in the rest of the header. */
8533 if (is_32bit_elf)
8534 {
8535 Elf32_External_Ehdr ehdr32;
252b5132 8536
9ea033b2
NC
8537 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
8538 return 0;
103f02d3 8539
9ea033b2
NC
8540 elf_header.e_type = BYTE_GET (ehdr32.e_type);
8541 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
8542 elf_header.e_version = BYTE_GET (ehdr32.e_version);
8543 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
8544 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
8545 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
8546 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
8547 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
8548 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
8549 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
8550 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
8551 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
8552 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
8553 }
252b5132 8554 else
9ea033b2
NC
8555 {
8556 Elf64_External_Ehdr ehdr64;
a952a375
NC
8557
8558 /* If we have been compiled with sizeof (bfd_vma) == 4, then
8559 we will not be able to cope with the 64bit data found in
8560 64 ELF files. Detect this now and abort before we start
8561 overwritting things. */
8562 if (sizeof (bfd_vma) < 8)
8563 {
8564 error (_("This instance of readelf has been built without support for a\n"));
8565 error (_("64 bit data type and so it cannot read 64 bit ELF files.\n"));
8566 return 0;
8567 }
103f02d3 8568
9ea033b2
NC
8569 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
8570 return 0;
103f02d3 8571
9ea033b2
NC
8572 elf_header.e_type = BYTE_GET (ehdr64.e_type);
8573 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
8574 elf_header.e_version = BYTE_GET (ehdr64.e_version);
8575 elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry);
8576 elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff);
8577 elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff);
8578 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
8579 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
8580 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
8581 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
8582 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
8583 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
8584 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
8585 }
252b5132
RH
8586
8587 return 1;
8588}
8589
8590static void
8591process_file (file_name)
8592 char * file_name;
8593{
8594 FILE * file;
8595 struct stat statbuf;
8596 unsigned int i;
8597
8598 if (stat (file_name, & statbuf) < 0)
8599 {
8600 error (_("Cannot stat input file %s.\n"), file_name);
8601 return;
8602 }
8603
8604 file = fopen (file_name, "rb");
8605 if (file == NULL)
8606 {
8607 error (_("Input file %s not found.\n"), file_name);
8608 return;
8609 }
8610
8611 if (! get_file_header (file))
8612 {
8613 error (_("%s: Failed to read file header\n"), file_name);
8614 fclose (file);
8615 return;
8616 }
8617
8618 /* Initialise per file variables. */
8619 for (i = NUM_ELEM (version_info); i--;)
8620 version_info[i] = 0;
8621
8622 for (i = NUM_ELEM (dynamic_info); i--;)
8623 dynamic_info[i] = 0;
8624
8625 /* Process the file. */
8626 if (show_name)
8627 printf (_("\nFile: %s\n"), file_name);
8628
8629 if (! process_file_header ())
8630 {
8631 fclose (file);
8632 return;
8633 }
8634
8635 process_section_headers (file);
8636
8637 process_program_headers (file);
8638
8639 process_dynamic_segment (file);
8640
8641 process_relocs (file);
8642
4d6ed7c8
NC
8643 process_unwind (file);
8644
252b5132
RH
8645 process_symbol_table (file);
8646
8647 process_syminfo (file);
8648
8649 process_version_sections (file);
8650
8651 process_section_contents (file);
103f02d3 8652
779fe533 8653 process_corefile_contents (file);
103f02d3 8654
252b5132
RH
8655 process_arch_specific (file);
8656
8657 fclose (file);
8658
8659 if (section_headers)
8660 {
8661 free (section_headers);
8662 section_headers = NULL;
8663 }
8664
8665 if (string_table)
8666 {
8667 free (string_table);
8668 string_table = NULL;
d40ac9bd 8669 string_table_length = 0;
252b5132
RH
8670 }
8671
8672 if (dynamic_strings)
8673 {
8674 free (dynamic_strings);
8675 dynamic_strings = NULL;
8676 }
8677
8678 if (dynamic_symbols)
8679 {
8680 free (dynamic_symbols);
8681 dynamic_symbols = NULL;
19936277 8682 num_dynamic_syms = 0;
252b5132
RH
8683 }
8684
8685 if (dynamic_syminfo)
8686 {
8687 free (dynamic_syminfo);
8688 dynamic_syminfo = NULL;
8689 }
8690}
8691
8692#ifdef SUPPORT_DISASSEMBLY
8693/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2
NC
8694 fix this so that we insert symbolic addresses here, esp for GOT/PLT
8695 symbols */
252b5132
RH
8696
8697void
8698print_address (unsigned int addr, FILE * outfile)
8699{
8700 fprintf (outfile,"0x%8.8x", addr);
8701}
8702
8703/* Needed by the i386 disassembler. */
8704void
8705db_task_printsym (unsigned int addr)
8706{
8707 print_address (addr, stderr);
8708}
8709#endif
8710
8711int
8712main (argc, argv)
8713 int argc;
8714 char ** argv;
8715{
8716#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
8717 setlocale (LC_MESSAGES, "");
8718#endif
8719 bindtextdomain (PACKAGE, LOCALEDIR);
8720 textdomain (PACKAGE);
8721
8722 parse_args (argc, argv);
8723
8724 if (optind < (argc - 1))
8725 show_name = 1;
8726
8727 while (optind < argc)
8728 process_file (argv [optind ++]);
8729
8730 if (dump_sects != NULL)
8731 free (dump_sects);
8732
8733 return 0;
8734}
This page took 0.5084 seconds and 4 git commands to generate.