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