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