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