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