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