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