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