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