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