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