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