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