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