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