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