]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - binutils/readelf.c
Fix typos in ChangeLogs and update copyright notices
[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 memset (& aux, 0, sizeof (aux));
3415
3416 addr_size = is_32bit_elf ? 4 : 8;
3417
3418 if (!do_unwind)
3419 return 1;
3420
3421 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
3422 {
3423 if (sec->sh_type == SHT_SYMTAB)
3424 {
3425 aux.nsyms = sec->sh_size / sec->sh_entsize;
3426 aux.symtab = GET_ELF_SYMBOLS (file, sec->sh_offset, aux.nsyms);
3427
3428 strsec = section_headers + sec->sh_link;
3429 aux.strtab_size = strsec->sh_size;
3430 GET_DATA_ALLOC (strsec->sh_offset, aux.strtab_size,
3431 aux.strtab, const char *, "string table");
3432 }
3433 else if (sec->sh_type == SHT_IA_64_UNWIND)
3434 unwsec = sec;
3435 else if (strcmp (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info) == 0)
3436 {
3437 aux.info_size = sec->sh_size;
3438 aux.info_addr = sec->sh_addr;
3439 GET_DATA_ALLOC (sec->sh_offset, aux.info_size, aux.info,
3440 char *, "unwind info");
3441 }
3442 }
3443
3444 if (unwsec)
3445 {
3446 printf (_("\nUnwind section "));
3447
3448 if (string_table == NULL)
3449 printf ("%d", unwsec->sh_name);
3450 else
3451 printf ("'%s'", SECTION_NAME (unwsec));
3452
3453 printf (_(" at offset 0x%lx contains %lu entries:\n"),
3454 unwsec->sh_offset, (unsigned long) (unwsec->sh_size / (3 * addr_size)));
3455
3456 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
3457
3458 if (aux.table_len > 0)
3459 dump_ia64_unwind (& aux);
3460 }
3461 else
3462 printf (_("\nThere are no unwind sections in this file.\n"));
3463
3464 if (aux.table)
3465 free ((char *) aux.table);
3466 if (aux.info)
3467 free ((char *) aux.info);
3468 if (aux.symtab)
3469 free (aux.symtab);
3470 if (aux.strtab)
3471 free ((char *) aux.strtab);
3472
3473 return 1;
3474 }
3475
3476 static void
3477 dynamic_segment_mips_val (entry)
3478 Elf_Internal_Dyn * entry;
3479 {
3480 switch (entry->d_tag)
3481 {
3482 case DT_MIPS_FLAGS:
3483 if (entry->d_un.d_val == 0)
3484 printf ("NONE\n");
3485 else
3486 {
3487 static const char * opts[] =
3488 {
3489 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
3490 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
3491 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
3492 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
3493 "RLD_ORDER_SAFE"
3494 };
3495 unsigned int cnt;
3496 int first = 1;
3497 for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
3498 if (entry->d_un.d_val & (1 << cnt))
3499 {
3500 printf ("%s%s", first ? "" : " ", opts[cnt]);
3501 first = 0;
3502 }
3503 puts ("");
3504 }
3505 break;
3506
3507 case DT_MIPS_IVERSION:
3508 if (dynamic_strings != NULL)
3509 printf ("Interface Version: %s\n",
3510 dynamic_strings + entry->d_un.d_val);
3511 else
3512 printf ("%ld\n", (long) entry->d_un.d_ptr);
3513 break;
3514
3515 case DT_MIPS_TIME_STAMP:
3516 {
3517 char timebuf[20];
3518 struct tm * tmp;
3519
3520 time_t time = entry->d_un.d_val;
3521 tmp = gmtime (&time);
3522 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
3523 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
3524 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
3525 printf ("Time Stamp: %s\n", timebuf);
3526 }
3527 break;
3528
3529 case DT_MIPS_RLD_VERSION:
3530 case DT_MIPS_LOCAL_GOTNO:
3531 case DT_MIPS_CONFLICTNO:
3532 case DT_MIPS_LIBLISTNO:
3533 case DT_MIPS_SYMTABNO:
3534 case DT_MIPS_UNREFEXTNO:
3535 case DT_MIPS_HIPAGENO:
3536 case DT_MIPS_DELTA_CLASS_NO:
3537 case DT_MIPS_DELTA_INSTANCE_NO:
3538 case DT_MIPS_DELTA_RELOC_NO:
3539 case DT_MIPS_DELTA_SYM_NO:
3540 case DT_MIPS_DELTA_CLASSSYM_NO:
3541 case DT_MIPS_COMPACT_SIZE:
3542 printf ("%ld\n", (long) entry->d_un.d_ptr);
3543 break;
3544
3545 default:
3546 printf ("%#lx\n", (long) entry->d_un.d_ptr);
3547 }
3548 }
3549
3550
3551 static void
3552 dynamic_segment_parisc_val (entry)
3553 Elf_Internal_Dyn * entry;
3554 {
3555 switch (entry->d_tag)
3556 {
3557 case DT_HP_DLD_FLAGS:
3558 {
3559 static struct
3560 {
3561 long int bit;
3562 const char * str;
3563 }
3564 flags[] =
3565 {
3566 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
3567 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
3568 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
3569 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
3570 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
3571 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
3572 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
3573 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
3574 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
3575 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
3576 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" }
3577 };
3578 int first = 1;
3579 size_t cnt;
3580 bfd_vma val = entry->d_un.d_val;
3581
3582 for (cnt = 0; cnt < sizeof (flags) / sizeof (flags[0]); ++cnt)
3583 if (val & flags[cnt].bit)
3584 {
3585 if (! first)
3586 putchar (' ');
3587 fputs (flags[cnt].str, stdout);
3588 first = 0;
3589 val ^= flags[cnt].bit;
3590 }
3591
3592 if (val != 0 || first)
3593 {
3594 if (! first)
3595 putchar (' ');
3596 print_vma (val, HEX);
3597 }
3598 }
3599 break;
3600
3601 default:
3602 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
3603 break;
3604 }
3605 }
3606
3607 static int
3608 get_32bit_dynamic_segment (file)
3609 FILE * file;
3610 {
3611 Elf32_External_Dyn * edyn;
3612 Elf_Internal_Dyn * entry;
3613 bfd_size_type i;
3614
3615 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
3616 edyn, Elf32_External_Dyn *, "dynamic segment");
3617
3618 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
3619 how large this .dynamic is now. We can do this even before the byte
3620 swapping since the DT_NULL tag is recognizable. */
3621 dynamic_size = 0;
3622 while (*(Elf32_Word *) edyn [dynamic_size++].d_tag != DT_NULL)
3623 ;
3624
3625 dynamic_segment = (Elf_Internal_Dyn *)
3626 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
3627
3628 if (dynamic_segment == NULL)
3629 {
3630 error (_("Out of memory\n"));
3631 free (edyn);
3632 return 0;
3633 }
3634
3635 for (i = 0, entry = dynamic_segment;
3636 i < dynamic_size;
3637 i ++, entry ++)
3638 {
3639 entry->d_tag = BYTE_GET (edyn [i].d_tag);
3640 entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
3641 }
3642
3643 free (edyn);
3644
3645 return 1;
3646 }
3647
3648 static int
3649 get_64bit_dynamic_segment (file)
3650 FILE * file;
3651 {
3652 Elf64_External_Dyn * edyn;
3653 Elf_Internal_Dyn * entry;
3654 bfd_size_type i;
3655
3656 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
3657 edyn, Elf64_External_Dyn *, "dynamic segment");
3658
3659 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
3660 how large this .dynamic is now. We can do this even before the byte
3661 swapping since the DT_NULL tag is recognizable. */
3662 dynamic_size = 0;
3663 while (*(bfd_vma *) edyn [dynamic_size ++].d_tag != DT_NULL)
3664 ;
3665
3666 dynamic_segment = (Elf_Internal_Dyn *)
3667 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
3668
3669 if (dynamic_segment == NULL)
3670 {
3671 error (_("Out of memory\n"));
3672 free (edyn);
3673 return 0;
3674 }
3675
3676 for (i = 0, entry = dynamic_segment;
3677 i < dynamic_size;
3678 i ++, entry ++)
3679 {
3680 entry->d_tag = BYTE_GET8 (edyn [i].d_tag);
3681 entry->d_un.d_val = BYTE_GET8 (edyn [i].d_un.d_val);
3682 }
3683
3684 free (edyn);
3685
3686 return 1;
3687 }
3688
3689 static const char *
3690 get_dynamic_flags (flags)
3691 bfd_vma flags;
3692 {
3693 static char buff [64];
3694 while (flags)
3695 {
3696 bfd_vma flag;
3697
3698 flag = flags & - flags;
3699 flags &= ~ flag;
3700
3701 switch (flag)
3702 {
3703 case DF_ORIGIN: strcat (buff, "ORIGIN "); break;
3704 case DF_SYMBOLIC: strcat (buff, "SYMBOLIC "); break;
3705 case DF_TEXTREL: strcat (buff, "TEXTREL "); break;
3706 case DF_BIND_NOW: strcat (buff, "BIND_NOW "); break;
3707 default: strcat (buff, "unknown "); break;
3708 }
3709 }
3710 return buff;
3711 }
3712
3713 /* Parse and display the contents of the dynamic segment. */
3714 static int
3715 process_dynamic_segment (file)
3716 FILE * file;
3717 {
3718 Elf_Internal_Dyn * entry;
3719 bfd_size_type i;
3720
3721 if (dynamic_size == 0)
3722 {
3723 if (do_dynamic)
3724 printf (_("\nThere is no dynamic segment in this file.\n"));
3725
3726 return 1;
3727 }
3728
3729 if (is_32bit_elf)
3730 {
3731 if (! get_32bit_dynamic_segment (file))
3732 return 0;
3733 }
3734 else if (! get_64bit_dynamic_segment (file))
3735 return 0;
3736
3737 /* Find the appropriate symbol table. */
3738 if (dynamic_symbols == NULL)
3739 {
3740 for (i = 0, entry = dynamic_segment;
3741 i < dynamic_size;
3742 ++i, ++ entry)
3743 {
3744 unsigned long offset;
3745
3746 if (entry->d_tag != DT_SYMTAB)
3747 continue;
3748
3749 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
3750
3751 /* Since we do not know how big the symbol table is,
3752 we default to reading in the entire file (!) and
3753 processing that. This is overkill, I know, but it
3754 should work. */
3755 offset = entry->d_un.d_val - loadaddr;
3756
3757 if (fseek (file, 0, SEEK_END))
3758 error (_("Unable to seek to end of file!"));
3759
3760 if (is_32bit_elf)
3761 num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
3762 else
3763 num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf64_External_Sym);
3764
3765 if (num_dynamic_syms < 1)
3766 {
3767 error (_("Unable to determine the number of symbols to load\n"));
3768 continue;
3769 }
3770
3771 dynamic_symbols = GET_ELF_SYMBOLS (file, offset, num_dynamic_syms);
3772 }
3773 }
3774
3775 /* Similarly find a string table. */
3776 if (dynamic_strings == NULL)
3777 {
3778 for (i = 0, entry = dynamic_segment;
3779 i < dynamic_size;
3780 ++i, ++ entry)
3781 {
3782 unsigned long offset;
3783 long str_tab_len;
3784
3785 if (entry->d_tag != DT_STRTAB)
3786 continue;
3787
3788 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
3789
3790 /* Since we do not know how big the string table is,
3791 we default to reading in the entire file (!) and
3792 processing that. This is overkill, I know, but it
3793 should work. */
3794
3795 offset = entry->d_un.d_val - loadaddr;
3796 if (fseek (file, 0, SEEK_END))
3797 error (_("Unable to seek to end of file\n"));
3798 str_tab_len = ftell (file) - offset;
3799
3800 if (str_tab_len < 1)
3801 {
3802 error
3803 (_("Unable to determine the length of the dynamic string table\n"));
3804 continue;
3805 }
3806
3807 GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
3808 "dynamic string table");
3809
3810 break;
3811 }
3812 }
3813
3814 /* And find the syminfo section if available. */
3815 if (dynamic_syminfo == NULL)
3816 {
3817 unsigned int syminsz = 0;
3818
3819 for (i = 0, entry = dynamic_segment;
3820 i < dynamic_size;
3821 ++i, ++ entry)
3822 {
3823 if (entry->d_tag == DT_SYMINENT)
3824 {
3825 /* Note: these braces are necessary to avoid a syntax
3826 error from the SunOS4 C compiler. */
3827 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
3828 }
3829 else if (entry->d_tag == DT_SYMINSZ)
3830 syminsz = entry->d_un.d_val;
3831 else if (entry->d_tag == DT_SYMINFO)
3832 dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
3833 }
3834
3835 if (dynamic_syminfo_offset != 0 && syminsz != 0)
3836 {
3837 Elf_External_Syminfo * extsyminfo;
3838 Elf_Internal_Syminfo * syminfo;
3839
3840 /* There is a syminfo section. Read the data. */
3841 GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
3842 Elf_External_Syminfo *, "symbol information");
3843
3844 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
3845 if (dynamic_syminfo == NULL)
3846 {
3847 error (_("Out of memory\n"));
3848 return 0;
3849 }
3850
3851 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
3852 for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
3853 ++i, ++syminfo)
3854 {
3855 syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
3856 syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
3857 }
3858
3859 free (extsyminfo);
3860 }
3861 }
3862
3863 if (do_dynamic && dynamic_addr)
3864 printf (_("\nDynamic segment at offset 0x%x contains %ld entries:\n"),
3865 dynamic_addr, (long) dynamic_size);
3866 if (do_dynamic)
3867 printf (_(" Tag Type Name/Value\n"));
3868
3869 for (i = 0, entry = dynamic_segment;
3870 i < dynamic_size;
3871 i++, entry ++)
3872 {
3873 if (do_dynamic)
3874 {
3875 const char * dtype;
3876
3877 putchar (' ');
3878 print_vma (entry->d_tag, FULL_HEX);
3879 dtype = get_dynamic_type (entry->d_tag);
3880 printf (" (%s)%*s", dtype,
3881 ((is_32bit_elf ? 27 : 19)
3882 - (int) strlen (dtype)),
3883 " ");
3884 }
3885
3886 switch (entry->d_tag)
3887 {
3888 case DT_FLAGS:
3889 if (do_dynamic)
3890 printf ("%s", get_dynamic_flags (entry->d_un.d_val));
3891 break;
3892
3893 case DT_AUXILIARY:
3894 case DT_FILTER:
3895 case DT_CONFIG:
3896 case DT_DEPAUDIT:
3897 case DT_AUDIT:
3898 if (do_dynamic)
3899 {
3900 switch (entry->d_tag)
3901 {
3902 case DT_AUXILIARY:
3903 printf (_("Auxiliary library"));
3904 break;
3905
3906 case DT_FILTER:
3907 printf (_("Filter library"));
3908 break;
3909
3910 case DT_CONFIG:
3911 printf (_("Configuration file"));
3912 break;
3913
3914 case DT_DEPAUDIT:
3915 printf (_("Dependency audit library"));
3916 break;
3917
3918 case DT_AUDIT:
3919 printf (_("Audit library"));
3920 break;
3921 }
3922
3923 if (dynamic_strings)
3924 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
3925 else
3926 {
3927 printf (": ");
3928 print_vma (entry->d_un.d_val, PREFIX_HEX);
3929 putchar ('\n');
3930 }
3931 }
3932 break;
3933
3934 case DT_FEATURE:
3935 if (do_dynamic)
3936 {
3937 printf (_("Flags:"));
3938 if (entry->d_un.d_val == 0)
3939 printf (_(" None\n"));
3940 else
3941 {
3942 unsigned long int val = entry->d_un.d_val;
3943 if (val & DTF_1_PARINIT)
3944 {
3945 printf (" PARINIT");
3946 val ^= DTF_1_PARINIT;
3947 }
3948 if (val & DTF_1_CONFEXP)
3949 {
3950 printf (" CONFEXP");
3951 val ^= DTF_1_CONFEXP;
3952 }
3953 if (val != 0)
3954 printf (" %lx", val);
3955 puts ("");
3956 }
3957 }
3958 break;
3959
3960 case DT_POSFLAG_1:
3961 if (do_dynamic)
3962 {
3963 printf (_("Flags:"));
3964 if (entry->d_un.d_val == 0)
3965 printf (_(" None\n"));
3966 else
3967 {
3968 unsigned long int val = entry->d_un.d_val;
3969 if (val & DF_P1_LAZYLOAD)
3970 {
3971 printf (" LAZYLOAD");
3972 val ^= DF_P1_LAZYLOAD;
3973 }
3974 if (val & DF_P1_GROUPPERM)
3975 {
3976 printf (" GROUPPERM");
3977 val ^= DF_P1_GROUPPERM;
3978 }
3979 if (val != 0)
3980 printf (" %lx", val);
3981 puts ("");
3982 }
3983 }
3984 break;
3985
3986 case DT_FLAGS_1:
3987 if (do_dynamic)
3988 {
3989 printf (_("Flags:"));
3990 if (entry->d_un.d_val == 0)
3991 printf (_(" None\n"));
3992 else
3993 {
3994 unsigned long int val = entry->d_un.d_val;
3995 if (val & DF_1_NOW)
3996 {
3997 printf (" NOW");
3998 val ^= DF_1_NOW;
3999 }
4000 if (val & DF_1_GLOBAL)
4001 {
4002 printf (" GLOBAL");
4003 val ^= DF_1_GLOBAL;
4004 }
4005 if (val & DF_1_GROUP)
4006 {
4007 printf (" GROUP");
4008 val ^= DF_1_GROUP;
4009 }
4010 if (val & DF_1_NODELETE)
4011 {
4012 printf (" NODELETE");
4013 val ^= DF_1_NODELETE;
4014 }
4015 if (val & DF_1_LOADFLTR)
4016 {
4017 printf (" LOADFLTR");
4018 val ^= DF_1_LOADFLTR;
4019 }
4020 if (val & DF_1_INITFIRST)
4021 {
4022 printf (" INITFIRST");
4023 val ^= DF_1_INITFIRST;
4024 }
4025 if (val & DF_1_NOOPEN)
4026 {
4027 printf (" NOOPEN");
4028 val ^= DF_1_NOOPEN;
4029 }
4030 if (val & DF_1_ORIGIN)
4031 {
4032 printf (" ORIGIN");
4033 val ^= DF_1_ORIGIN;
4034 }
4035 if (val & DF_1_DIRECT)
4036 {
4037 printf (" DIRECT");
4038 val ^= DF_1_DIRECT;
4039 }
4040 if (val & DF_1_TRANS)
4041 {
4042 printf (" TRANS");
4043 val ^= DF_1_TRANS;
4044 }
4045 if (val & DF_1_INTERPOSE)
4046 {
4047 printf (" INTERPOSE");
4048 val ^= DF_1_INTERPOSE;
4049 }
4050 if (val & DF_1_NODEFLIB)
4051 {
4052 printf (" NODEFLIB");
4053 val ^= DF_1_NODEFLIB;
4054 }
4055 if (val & DF_1_NODUMP)
4056 {
4057 printf (" NODUMP");
4058 val ^= DF_1_NODUMP;
4059 }
4060 if (val & DF_1_CONLFAT)
4061 {
4062 printf (" CONLFAT");
4063 val ^= DF_1_CONLFAT;
4064 }
4065 if (val != 0)
4066 printf (" %lx", val);
4067 puts ("");
4068 }
4069 }
4070 break;
4071
4072 case DT_PLTREL:
4073 if (do_dynamic)
4074 puts (get_dynamic_type (entry->d_un.d_val));
4075 break;
4076
4077 case DT_NULL :
4078 case DT_NEEDED :
4079 case DT_PLTGOT :
4080 case DT_HASH :
4081 case DT_STRTAB :
4082 case DT_SYMTAB :
4083 case DT_RELA :
4084 case DT_INIT :
4085 case DT_FINI :
4086 case DT_SONAME :
4087 case DT_RPATH :
4088 case DT_SYMBOLIC:
4089 case DT_REL :
4090 case DT_DEBUG :
4091 case DT_TEXTREL :
4092 case DT_JMPREL :
4093 case DT_RUNPATH :
4094 dynamic_info[entry->d_tag] = entry->d_un.d_val;
4095
4096 if (do_dynamic)
4097 {
4098 char * name;
4099
4100 if (dynamic_strings == NULL)
4101 name = NULL;
4102 else
4103 name = dynamic_strings + entry->d_un.d_val;
4104
4105 if (name)
4106 {
4107 switch (entry->d_tag)
4108 {
4109 case DT_NEEDED:
4110 printf (_("Shared library: [%s]"), name);
4111
4112 if (strcmp (name, program_interpreter) == 0)
4113 printf (_(" program interpreter"));
4114 break;
4115
4116 case DT_SONAME:
4117 printf (_("Library soname: [%s]"), name);
4118 break;
4119
4120 case DT_RPATH:
4121 printf (_("Library rpath: [%s]"), name);
4122 break;
4123
4124 case DT_RUNPATH:
4125 printf (_("Library runpath: [%s]"), name);
4126 break;
4127
4128 default:
4129 print_vma (entry->d_un.d_val, PREFIX_HEX);
4130 break;
4131 }
4132 }
4133 else
4134 print_vma (entry->d_un.d_val, PREFIX_HEX);
4135
4136 putchar ('\n');
4137 }
4138 break;
4139
4140 case DT_PLTRELSZ:
4141 case DT_RELASZ :
4142 case DT_STRSZ :
4143 case DT_RELSZ :
4144 case DT_RELAENT :
4145 case DT_SYMENT :
4146 case DT_RELENT :
4147 case DT_PLTPADSZ:
4148 case DT_MOVEENT :
4149 case DT_MOVESZ :
4150 case DT_INIT_ARRAYSZ:
4151 case DT_FINI_ARRAYSZ:
4152 if (do_dynamic)
4153 {
4154 print_vma (entry->d_un.d_val, UNSIGNED);
4155 printf (" (bytes)\n");
4156 }
4157 break;
4158
4159 case DT_VERDEFNUM:
4160 case DT_VERNEEDNUM:
4161 case DT_RELACOUNT:
4162 case DT_RELCOUNT:
4163 if (do_dynamic)
4164 {
4165 print_vma (entry->d_un.d_val, UNSIGNED);
4166 putchar ('\n');
4167 }
4168 break;
4169
4170 case DT_SYMINSZ:
4171 case DT_SYMINENT:
4172 case DT_SYMINFO:
4173 case DT_USED:
4174 case DT_INIT_ARRAY:
4175 case DT_FINI_ARRAY:
4176 if (do_dynamic)
4177 {
4178 if (dynamic_strings != NULL && entry->d_tag == DT_USED)
4179 {
4180 char * name;
4181
4182 name = dynamic_strings + entry->d_un.d_val;
4183
4184 if (* name)
4185 {
4186 printf (_("Not needed object: [%s]\n"), name);
4187 break;
4188 }
4189 }
4190
4191 print_vma (entry->d_un.d_val, PREFIX_HEX);
4192 putchar ('\n');
4193 }
4194 break;
4195
4196 case DT_BIND_NOW:
4197 /* The value of this entry is ignored. */
4198 break;
4199
4200 default:
4201 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
4202 version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
4203 entry->d_un.d_val;
4204
4205 if (do_dynamic)
4206 {
4207 switch (elf_header.e_machine)
4208 {
4209 case EM_MIPS:
4210 case EM_MIPS_RS4_BE:
4211 dynamic_segment_mips_val (entry);
4212 break;
4213 case EM_PARISC:
4214 dynamic_segment_parisc_val (entry);
4215 break;
4216 default:
4217 print_vma (entry->d_un.d_val, PREFIX_HEX);
4218 putchar ('\n');
4219 }
4220 }
4221 break;
4222 }
4223 }
4224
4225 return 1;
4226 }
4227
4228 static char *
4229 get_ver_flags (flags)
4230 unsigned int flags;
4231 {
4232 static char buff [32];
4233
4234 buff[0] = 0;
4235
4236 if (flags == 0)
4237 return _("none");
4238
4239 if (flags & VER_FLG_BASE)
4240 strcat (buff, "BASE ");
4241
4242 if (flags & VER_FLG_WEAK)
4243 {
4244 if (flags & VER_FLG_BASE)
4245 strcat (buff, "| ");
4246
4247 strcat (buff, "WEAK ");
4248 }
4249
4250 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
4251 strcat (buff, "| <unknown>");
4252
4253 return buff;
4254 }
4255
4256 /* Display the contents of the version sections. */
4257 static int
4258 process_version_sections (file)
4259 FILE * file;
4260 {
4261 Elf32_Internal_Shdr * section;
4262 unsigned i;
4263 int found = 0;
4264
4265 if (! do_version)
4266 return 1;
4267
4268 for (i = 0, section = section_headers;
4269 i < elf_header.e_shnum;
4270 i++, section ++)
4271 {
4272 switch (section->sh_type)
4273 {
4274 case SHT_GNU_verdef:
4275 {
4276 Elf_External_Verdef * edefs;
4277 unsigned int idx;
4278 unsigned int cnt;
4279
4280 found = 1;
4281
4282 printf
4283 (_("\nVersion definition section '%s' contains %ld entries:\n"),
4284 SECTION_NAME (section), section->sh_info);
4285
4286 printf (_(" Addr: 0x"));
4287 printf_vma (section->sh_addr);
4288 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
4289 (unsigned long) section->sh_offset, section->sh_link,
4290 SECTION_NAME (section_headers + section->sh_link));
4291
4292 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
4293 edefs, Elf_External_Verdef *,
4294 "version definition section");
4295
4296 for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
4297 {
4298 char * vstart;
4299 Elf_External_Verdef * edef;
4300 Elf_Internal_Verdef ent;
4301 Elf_External_Verdaux * eaux;
4302 Elf_Internal_Verdaux aux;
4303 int j;
4304 int isum;
4305
4306 vstart = ((char *) edefs) + idx;
4307
4308 edef = (Elf_External_Verdef *) vstart;
4309
4310 ent.vd_version = BYTE_GET (edef->vd_version);
4311 ent.vd_flags = BYTE_GET (edef->vd_flags);
4312 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
4313 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
4314 ent.vd_hash = BYTE_GET (edef->vd_hash);
4315 ent.vd_aux = BYTE_GET (edef->vd_aux);
4316 ent.vd_next = BYTE_GET (edef->vd_next);
4317
4318 printf (_(" %#06x: Rev: %d Flags: %s"),
4319 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
4320
4321 printf (_(" Index: %d Cnt: %d "),
4322 ent.vd_ndx, ent.vd_cnt);
4323
4324 vstart += ent.vd_aux;
4325
4326 eaux = (Elf_External_Verdaux *) vstart;
4327
4328 aux.vda_name = BYTE_GET (eaux->vda_name);
4329 aux.vda_next = BYTE_GET (eaux->vda_next);
4330
4331 if (dynamic_strings)
4332 printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
4333 else
4334 printf (_("Name index: %ld\n"), aux.vda_name);
4335
4336 isum = idx + ent.vd_aux;
4337
4338 for (j = 1; j < ent.vd_cnt; j ++)
4339 {
4340 isum += aux.vda_next;
4341 vstart += aux.vda_next;
4342
4343 eaux = (Elf_External_Verdaux *) vstart;
4344
4345 aux.vda_name = BYTE_GET (eaux->vda_name);
4346 aux.vda_next = BYTE_GET (eaux->vda_next);
4347
4348 if (dynamic_strings)
4349 printf (_(" %#06x: Parent %d: %s\n"),
4350 isum, j, dynamic_strings + aux.vda_name);
4351 else
4352 printf (_(" %#06x: Parent %d, name index: %ld\n"),
4353 isum, j, aux.vda_name);
4354 }
4355
4356 idx += ent.vd_next;
4357 }
4358
4359 free (edefs);
4360 }
4361 break;
4362
4363 case SHT_GNU_verneed:
4364 {
4365 Elf_External_Verneed * eneed;
4366 unsigned int idx;
4367 unsigned int cnt;
4368
4369 found = 1;
4370
4371 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
4372 SECTION_NAME (section), section->sh_info);
4373
4374 printf (_(" Addr: 0x"));
4375 printf_vma (section->sh_addr);
4376 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
4377 (unsigned long) section->sh_offset, section->sh_link,
4378 SECTION_NAME (section_headers + section->sh_link));
4379
4380 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
4381 eneed, Elf_External_Verneed *,
4382 "version need section");
4383
4384 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
4385 {
4386 Elf_External_Verneed * entry;
4387 Elf_Internal_Verneed ent;
4388 int j;
4389 int isum;
4390 char * vstart;
4391
4392 vstart = ((char *) eneed) + idx;
4393
4394 entry = (Elf_External_Verneed *) vstart;
4395
4396 ent.vn_version = BYTE_GET (entry->vn_version);
4397 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
4398 ent.vn_file = BYTE_GET (entry->vn_file);
4399 ent.vn_aux = BYTE_GET (entry->vn_aux);
4400 ent.vn_next = BYTE_GET (entry->vn_next);
4401
4402 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
4403
4404 if (dynamic_strings)
4405 printf (_(" File: %s"), dynamic_strings + ent.vn_file);
4406 else
4407 printf (_(" File: %lx"), ent.vn_file);
4408
4409 printf (_(" Cnt: %d\n"), ent.vn_cnt);
4410
4411 vstart += ent.vn_aux;
4412
4413 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
4414 {
4415 Elf_External_Vernaux * eaux;
4416 Elf_Internal_Vernaux aux;
4417
4418 eaux = (Elf_External_Vernaux *) vstart;
4419
4420 aux.vna_hash = BYTE_GET (eaux->vna_hash);
4421 aux.vna_flags = BYTE_GET (eaux->vna_flags);
4422 aux.vna_other = BYTE_GET (eaux->vna_other);
4423 aux.vna_name = BYTE_GET (eaux->vna_name);
4424 aux.vna_next = BYTE_GET (eaux->vna_next);
4425
4426 if (dynamic_strings)
4427 printf (_(" %#06x: Name: %s"),
4428 isum, dynamic_strings + aux.vna_name);
4429 else
4430 printf (_(" %#06x: Name index: %lx"),
4431 isum, aux.vna_name);
4432
4433 printf (_(" Flags: %s Version: %d\n"),
4434 get_ver_flags (aux.vna_flags), aux.vna_other);
4435
4436 isum += aux.vna_next;
4437 vstart += aux.vna_next;
4438 }
4439
4440 idx += ent.vn_next;
4441 }
4442
4443 free (eneed);
4444 }
4445 break;
4446
4447 case SHT_GNU_versym:
4448 {
4449 Elf32_Internal_Shdr * link_section;
4450 int total;
4451 int cnt;
4452 unsigned char * edata;
4453 unsigned short * data;
4454 char * strtab;
4455 Elf_Internal_Sym * symbols;
4456 Elf32_Internal_Shdr * string_sec;
4457
4458 link_section = section_headers + section->sh_link;
4459 total = section->sh_size / section->sh_entsize;
4460
4461 found = 1;
4462
4463 symbols = GET_ELF_SYMBOLS (file, link_section->sh_offset,
4464 link_section->sh_size / link_section->sh_entsize);
4465
4466 string_sec = section_headers + link_section->sh_link;
4467
4468 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
4469 strtab, char *, "version string table");
4470
4471 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
4472 SECTION_NAME (section), total);
4473
4474 printf (_(" Addr: "));
4475 printf_vma (section->sh_addr);
4476 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
4477 (unsigned long) section->sh_offset, section->sh_link,
4478 SECTION_NAME (link_section));
4479
4480 GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
4481 - loadaddr,
4482 total * sizeof (short), edata,
4483 unsigned char *, "version symbol data");
4484
4485 data = (unsigned short *) malloc (total * sizeof (short));
4486
4487 for (cnt = total; cnt --;)
4488 data [cnt] = byte_get (edata + cnt * sizeof (short),
4489 sizeof (short));
4490
4491 free (edata);
4492
4493 for (cnt = 0; cnt < total; cnt += 4)
4494 {
4495 int j, nn;
4496 int check_def, check_need;
4497 char * name;
4498
4499 printf (" %03x:", cnt);
4500
4501 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
4502 switch (data [cnt + j])
4503 {
4504 case 0:
4505 fputs (_(" 0 (*local*) "), stdout);
4506 break;
4507
4508 case 1:
4509 fputs (_(" 1 (*global*) "), stdout);
4510 break;
4511
4512 default:
4513 nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
4514 data [cnt + j] & 0x8000 ? 'h' : ' ');
4515
4516 check_def = 1;
4517 check_need = 1;
4518 if (symbols [cnt + j].st_shndx >= SHN_LORESERVE
4519 || section_headers[symbols [cnt + j].st_shndx].sh_type
4520 != SHT_NOBITS)
4521 {
4522 if (symbols [cnt + j].st_shndx == SHN_UNDEF)
4523 check_def = 0;
4524 else
4525 check_need = 0;
4526 }
4527
4528 if (check_need
4529 && version_info [DT_VERSIONTAGIDX (DT_VERNEED)])
4530 {
4531 Elf_Internal_Verneed ivn;
4532 unsigned long offset;
4533
4534 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
4535 - loadaddr;
4536
4537 do
4538 {
4539 Elf_Internal_Vernaux ivna;
4540 Elf_External_Verneed evn;
4541 Elf_External_Vernaux evna;
4542 unsigned long a_off;
4543
4544 GET_DATA (offset, evn, "version need");
4545
4546 ivn.vn_aux = BYTE_GET (evn.vn_aux);
4547 ivn.vn_next = BYTE_GET (evn.vn_next);
4548
4549 a_off = offset + ivn.vn_aux;
4550
4551 do
4552 {
4553 GET_DATA (a_off, evna,
4554 "version need aux (2)");
4555
4556 ivna.vna_next = BYTE_GET (evna.vna_next);
4557 ivna.vna_other = BYTE_GET (evna.vna_other);
4558
4559 a_off += ivna.vna_next;
4560 }
4561 while (ivna.vna_other != data [cnt + j]
4562 && ivna.vna_next != 0);
4563
4564 if (ivna.vna_other == data [cnt + j])
4565 {
4566 ivna.vna_name = BYTE_GET (evna.vna_name);
4567
4568 name = strtab + ivna.vna_name;
4569 nn += printf ("(%s%-*s",
4570 name,
4571 12 - (int) strlen (name),
4572 ")");
4573 check_def = 0;
4574 break;
4575 }
4576
4577 offset += ivn.vn_next;
4578 }
4579 while (ivn.vn_next);
4580 }
4581
4582 if (check_def && data [cnt + j] != 0x8001
4583 && version_info [DT_VERSIONTAGIDX (DT_VERDEF)])
4584 {
4585 Elf_Internal_Verdef ivd;
4586 Elf_External_Verdef evd;
4587 unsigned long offset;
4588
4589 offset = version_info
4590 [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
4591
4592 do
4593 {
4594 GET_DATA (offset, evd, "version def");
4595
4596 ivd.vd_next = BYTE_GET (evd.vd_next);
4597 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
4598
4599 offset += ivd.vd_next;
4600 }
4601 while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
4602 && ivd.vd_next != 0);
4603
4604 if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
4605 {
4606 Elf_External_Verdaux evda;
4607 Elf_Internal_Verdaux ivda;
4608
4609 ivd.vd_aux = BYTE_GET (evd.vd_aux);
4610
4611 GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
4612 evda, "version def aux");
4613
4614 ivda.vda_name = BYTE_GET (evda.vda_name);
4615
4616 name = strtab + ivda.vda_name;
4617 nn += printf ("(%s%-*s",
4618 name,
4619 12 - (int) strlen (name),
4620 ")");
4621 }
4622 }
4623
4624 if (nn < 18)
4625 printf ("%*c", 18 - nn, ' ');
4626 }
4627
4628 putchar ('\n');
4629 }
4630
4631 free (data);
4632 free (strtab);
4633 free (symbols);
4634 }
4635 break;
4636
4637 default:
4638 break;
4639 }
4640 }
4641
4642 if (! found)
4643 printf (_("\nNo version information found in this file.\n"));
4644
4645 return 1;
4646 }
4647
4648 static const char *
4649 get_symbol_binding (binding)
4650 unsigned int binding;
4651 {
4652 static char buff [32];
4653
4654 switch (binding)
4655 {
4656 case STB_LOCAL: return "LOCAL";
4657 case STB_GLOBAL: return "GLOBAL";
4658 case STB_WEAK: return "WEAK";
4659 default:
4660 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
4661 sprintf (buff, _("<processor specific>: %d"), binding);
4662 else if (binding >= STB_LOOS && binding <= STB_HIOS)
4663 sprintf (buff, _("<OS specific>: %d"), binding);
4664 else
4665 sprintf (buff, _("<unknown>: %d"), binding);
4666 return buff;
4667 }
4668 }
4669
4670 static const char *
4671 get_symbol_type (type)
4672 unsigned int type;
4673 {
4674 static char buff [32];
4675
4676 switch (type)
4677 {
4678 case STT_NOTYPE: return "NOTYPE";
4679 case STT_OBJECT: return "OBJECT";
4680 case STT_FUNC: return "FUNC";
4681 case STT_SECTION: return "SECTION";
4682 case STT_FILE: return "FILE";
4683 case STT_COMMON: return "COMMON";
4684 default:
4685 if (type >= STT_LOPROC && type <= STT_HIPROC)
4686 {
4687 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
4688 return "THUMB_FUNC";
4689
4690 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
4691 return "REGISTER";
4692
4693 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
4694 return "PARISC_MILLI";
4695
4696 sprintf (buff, _("<processor specific>: %d"), type);
4697 }
4698 else if (type >= STT_LOOS && type <= STT_HIOS)
4699 {
4700 if (elf_header.e_machine == EM_PARISC)
4701 {
4702 if (type == STT_HP_OPAQUE)
4703 return "HP_OPAQUE";
4704 if (type == STT_HP_STUB)
4705 return "HP_STUB";
4706 }
4707
4708 sprintf (buff, _("<OS specific>: %d"), type);
4709 }
4710 else
4711 sprintf (buff, _("<unknown>: %d"), type);
4712 return buff;
4713 }
4714 }
4715
4716 static const char *
4717 get_symbol_visibility (visibility)
4718 unsigned int visibility;
4719 {
4720 switch (visibility)
4721 {
4722 case STV_DEFAULT: return "DEFAULT";
4723 case STV_INTERNAL: return "INTERNAL";
4724 case STV_HIDDEN: return "HIDDEN";
4725 case STV_PROTECTED: return "PROTECTED";
4726 default: abort ();
4727 }
4728 }
4729
4730 static const char *
4731 get_symbol_index_type (type)
4732 unsigned int type;
4733 {
4734 switch (type)
4735 {
4736 case SHN_UNDEF: return "UND";
4737 case SHN_ABS: return "ABS";
4738 case SHN_COMMON: return "COM";
4739 default:
4740 if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4741 return "PRC";
4742 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
4743 return "RSV";
4744 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4745 return "OS ";
4746 else
4747 {
4748 static char buff [32];
4749
4750 sprintf (buff, "%3d", type);
4751 return buff;
4752 }
4753 }
4754 }
4755
4756 static int *
4757 get_dynamic_data (file, number)
4758 FILE * file;
4759 unsigned int number;
4760 {
4761 unsigned char * e_data;
4762 int * i_data;
4763
4764 e_data = (unsigned char *) malloc (number * 4);
4765
4766 if (e_data == NULL)
4767 {
4768 error (_("Out of memory\n"));
4769 return NULL;
4770 }
4771
4772 if (fread (e_data, 4, number, file) != number)
4773 {
4774 error (_("Unable to read in dynamic data\n"));
4775 return NULL;
4776 }
4777
4778 i_data = (int *) malloc (number * sizeof (* i_data));
4779
4780 if (i_data == NULL)
4781 {
4782 error (_("Out of memory\n"));
4783 free (e_data);
4784 return NULL;
4785 }
4786
4787 while (number--)
4788 i_data [number] = byte_get (e_data + number * 4, 4);
4789
4790 free (e_data);
4791
4792 return i_data;
4793 }
4794
4795 /* Dump the symbol table */
4796 static int
4797 process_symbol_table (file)
4798 FILE * file;
4799 {
4800 Elf32_Internal_Shdr * section;
4801 unsigned char nb [4];
4802 unsigned char nc [4];
4803 int nbuckets = 0;
4804 int nchains = 0;
4805 int * buckets = NULL;
4806 int * chains = NULL;
4807
4808 if (! do_syms && !do_histogram)
4809 return 1;
4810
4811 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
4812 || do_histogram))
4813 {
4814 if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
4815 {
4816 error (_("Unable to seek to start of dynamic information"));
4817 return 0;
4818 }
4819
4820 if (fread (nb, sizeof (nb), 1, file) != 1)
4821 {
4822 error (_("Failed to read in number of buckets\n"));
4823 return 0;
4824 }
4825
4826 if (fread (nc, sizeof (nc), 1, file) != 1)
4827 {
4828 error (_("Failed to read in number of chains\n"));
4829 return 0;
4830 }
4831
4832 nbuckets = byte_get (nb, 4);
4833 nchains = byte_get (nc, 4);
4834
4835 buckets = get_dynamic_data (file, nbuckets);
4836 chains = get_dynamic_data (file, nchains);
4837
4838 if (buckets == NULL || chains == NULL)
4839 return 0;
4840 }
4841
4842 if (do_syms
4843 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
4844 {
4845 int hn;
4846 int si;
4847
4848 printf (_("\nSymbol table for image:\n"));
4849 if (is_32bit_elf)
4850 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
4851 else
4852 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
4853
4854 for (hn = 0; hn < nbuckets; hn++)
4855 {
4856 if (! buckets [hn])
4857 continue;
4858
4859 for (si = buckets [hn]; si < nchains && si > 0; si = chains [si])
4860 {
4861 Elf_Internal_Sym * psym;
4862
4863 psym = dynamic_symbols + si;
4864
4865 printf (" %3d %3d: ", si, hn);
4866 print_vma (psym->st_value, LONG_HEX);
4867 putchar (' ' );
4868 print_vma (psym->st_size, DEC_5);
4869
4870 printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
4871 printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
4872 printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
4873 printf (" %3.3s", get_symbol_index_type (psym->st_shndx));
4874 printf (" %s\n", dynamic_strings + psym->st_name);
4875 }
4876 }
4877 }
4878 else if (do_syms && !do_using_dynamic)
4879 {
4880 unsigned int i;
4881
4882 for (i = 0, section = section_headers;
4883 i < elf_header.e_shnum;
4884 i++, section++)
4885 {
4886 unsigned int si;
4887 char * strtab;
4888 Elf_Internal_Sym * symtab;
4889 Elf_Internal_Sym * psym;
4890
4891
4892 if ( section->sh_type != SHT_SYMTAB
4893 && section->sh_type != SHT_DYNSYM)
4894 continue;
4895
4896 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
4897 SECTION_NAME (section),
4898 (unsigned long) (section->sh_size / section->sh_entsize));
4899 if (is_32bit_elf)
4900 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
4901 else
4902 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
4903
4904 symtab = GET_ELF_SYMBOLS (file, section->sh_offset,
4905 section->sh_size / section->sh_entsize);
4906 if (symtab == NULL)
4907 continue;
4908
4909 if (section->sh_link == elf_header.e_shstrndx)
4910 strtab = string_table;
4911 else
4912 {
4913 Elf32_Internal_Shdr * string_sec;
4914
4915 string_sec = section_headers + section->sh_link;
4916
4917 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
4918 strtab, char *, "string table");
4919 }
4920
4921 for (si = 0, psym = symtab;
4922 si < section->sh_size / section->sh_entsize;
4923 si ++, psym ++)
4924 {
4925 printf ("%6d: ", si);
4926 print_vma (psym->st_value, LONG_HEX);
4927 putchar (' ');
4928 print_vma (psym->st_size, DEC_5);
4929 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
4930 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
4931 printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
4932 printf (" %4s", get_symbol_index_type (psym->st_shndx));
4933 printf (" %s", strtab + psym->st_name);
4934
4935 if (section->sh_type == SHT_DYNSYM &&
4936 version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
4937 {
4938 unsigned char data[2];
4939 unsigned short vers_data;
4940 unsigned long offset;
4941 int is_nobits;
4942 int check_def;
4943
4944 offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
4945 - loadaddr;
4946
4947 GET_DATA (offset + si * sizeof (vers_data), data,
4948 "version data");
4949
4950 vers_data = byte_get (data, 2);
4951
4952 is_nobits = psym->st_shndx < SHN_LORESERVE ?
4953 (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
4954 : 0;
4955
4956 check_def = (psym->st_shndx != SHN_UNDEF);
4957
4958 if ((vers_data & 0x8000) || vers_data > 1)
4959 {
4960 if (version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
4961 && (is_nobits || ! check_def))
4962 {
4963 Elf_External_Verneed evn;
4964 Elf_Internal_Verneed ivn;
4965 Elf_Internal_Vernaux ivna;
4966
4967 /* We must test both. */
4968 offset = version_info
4969 [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
4970
4971 do
4972 {
4973 unsigned long vna_off;
4974
4975 GET_DATA (offset, evn, "version need");
4976
4977 ivn.vn_aux = BYTE_GET (evn.vn_aux);
4978 ivn.vn_next = BYTE_GET (evn.vn_next);
4979
4980 vna_off = offset + ivn.vn_aux;
4981
4982 do
4983 {
4984 Elf_External_Vernaux evna;
4985
4986 GET_DATA (vna_off, evna,
4987 "version need aux (3)");
4988
4989 ivna.vna_other = BYTE_GET (evna.vna_other);
4990 ivna.vna_next = BYTE_GET (evna.vna_next);
4991 ivna.vna_name = BYTE_GET (evna.vna_name);
4992
4993 vna_off += ivna.vna_next;
4994 }
4995 while (ivna.vna_other != vers_data
4996 && ivna.vna_next != 0);
4997
4998 if (ivna.vna_other == vers_data)
4999 break;
5000
5001 offset += ivn.vn_next;
5002 }
5003 while (ivn.vn_next != 0);
5004
5005 if (ivna.vna_other == vers_data)
5006 {
5007 printf ("@%s (%d)",
5008 strtab + ivna.vna_name, ivna.vna_other);
5009 check_def = 0;
5010 }
5011 else if (! is_nobits)
5012 error (_("bad dynamic symbol"));
5013 else
5014 check_def = 1;
5015 }
5016
5017 if (check_def)
5018 {
5019 if (vers_data != 0x8001
5020 && version_info [DT_VERSIONTAGIDX (DT_VERDEF)])
5021 {
5022 Elf_Internal_Verdef ivd;
5023 Elf_Internal_Verdaux ivda;
5024 Elf_External_Verdaux evda;
5025 unsigned long offset;
5026
5027 offset =
5028 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
5029 - loadaddr;
5030
5031 do
5032 {
5033 Elf_External_Verdef evd;
5034
5035 GET_DATA (offset, evd, "version def");
5036
5037 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
5038 ivd.vd_aux = BYTE_GET (evd.vd_aux);
5039 ivd.vd_next = BYTE_GET (evd.vd_next);
5040
5041 offset += ivd.vd_next;
5042 }
5043 while (ivd.vd_ndx != (vers_data & 0x7fff)
5044 && ivd.vd_next != 0);
5045
5046 offset -= ivd.vd_next;
5047 offset += ivd.vd_aux;
5048
5049 GET_DATA (offset, evda, "version def aux");
5050
5051 ivda.vda_name = BYTE_GET (evda.vda_name);
5052
5053 if (psym->st_name != ivda.vda_name)
5054 printf ((vers_data & 0x8000)
5055 ? "@%s" : "@@%s",
5056 strtab + ivda.vda_name);
5057 }
5058 }
5059 }
5060 }
5061
5062 putchar ('\n');
5063 }
5064
5065 free (symtab);
5066 if (strtab != string_table)
5067 free (strtab);
5068 }
5069 }
5070 else if (do_syms)
5071 printf
5072 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
5073
5074 if (do_histogram && buckets != NULL)
5075 {
5076 int * lengths;
5077 int * counts;
5078 int hn;
5079 int si;
5080 int maxlength = 0;
5081 int nzero_counts = 0;
5082 int nsyms = 0;
5083
5084 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
5085 nbuckets);
5086 printf (_(" Length Number %% of total Coverage\n"));
5087
5088 lengths = (int *) calloc (nbuckets, sizeof (int));
5089 if (lengths == NULL)
5090 {
5091 error (_("Out of memory"));
5092 return 0;
5093 }
5094 for (hn = 0; hn < nbuckets; ++hn)
5095 {
5096 if (! buckets [hn])
5097 continue;
5098
5099 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
5100 {
5101 ++ nsyms;
5102 if (maxlength < ++lengths[hn])
5103 ++ maxlength;
5104 }
5105 }
5106
5107 counts = (int *) calloc (maxlength + 1, sizeof (int));
5108 if (counts == NULL)
5109 {
5110 error (_("Out of memory"));
5111 return 0;
5112 }
5113
5114 for (hn = 0; hn < nbuckets; ++hn)
5115 ++ counts [lengths [hn]];
5116
5117 if (nbuckets > 0)
5118 {
5119 printf (" 0 %-10d (%5.1f%%)\n",
5120 counts[0], (counts[0] * 100.0) / nbuckets);
5121 for (si = 1; si <= maxlength; ++si)
5122 {
5123 nzero_counts += counts[si] * si;
5124 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
5125 si, counts[si], (counts[si] * 100.0) / nbuckets,
5126 (nzero_counts * 100.0) / nsyms);
5127 }
5128 }
5129
5130 free (counts);
5131 free (lengths);
5132 }
5133
5134 if (buckets != NULL)
5135 {
5136 free (buckets);
5137 free (chains);
5138 }
5139
5140 return 1;
5141 }
5142
5143 static int
5144 process_syminfo (file)
5145 FILE * file ATTRIBUTE_UNUSED;
5146 {
5147 unsigned int i;
5148
5149 if (dynamic_syminfo == NULL
5150 || !do_dynamic)
5151 /* No syminfo, this is ok. */
5152 return 1;
5153
5154 /* There better should be a dynamic symbol section. */
5155 if (dynamic_symbols == NULL || dynamic_strings == NULL)
5156 return 0;
5157
5158 if (dynamic_addr)
5159 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
5160 dynamic_syminfo_offset, dynamic_syminfo_nent);
5161
5162 printf (_(" Num: Name BoundTo Flags\n"));
5163 for (i = 0; i < dynamic_syminfo_nent; ++i)
5164 {
5165 unsigned short int flags = dynamic_syminfo[i].si_flags;
5166
5167 printf ("%4d: %-30s ", i,
5168 dynamic_strings + dynamic_symbols[i].st_name);
5169
5170 switch (dynamic_syminfo[i].si_boundto)
5171 {
5172 case SYMINFO_BT_SELF:
5173 fputs ("SELF ", stdout);
5174 break;
5175 case SYMINFO_BT_PARENT:
5176 fputs ("PARENT ", stdout);
5177 break;
5178 default:
5179 if (dynamic_syminfo[i].si_boundto > 0
5180 && dynamic_syminfo[i].si_boundto < dynamic_size)
5181 printf ("%-10s ",
5182 dynamic_strings
5183 + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
5184 else
5185 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
5186 break;
5187 }
5188
5189 if (flags & SYMINFO_FLG_DIRECT)
5190 printf (" DIRECT");
5191 if (flags & SYMINFO_FLG_PASSTHRU)
5192 printf (" PASSTHRU");
5193 if (flags & SYMINFO_FLG_COPY)
5194 printf (" COPY");
5195 if (flags & SYMINFO_FLG_LAZYLOAD)
5196 printf (" LAZYLOAD");
5197
5198 puts ("");
5199 }
5200
5201 return 1;
5202 }
5203
5204 #ifdef SUPPORT_DISASSEMBLY
5205 static void
5206 disassemble_section (section, file)
5207 Elf32_Internal_Shdr * section;
5208 FILE * file;
5209 {
5210 printf (_("\nAssembly dump of section %s\n"),
5211 SECTION_NAME (section));
5212
5213 /* XXX -- to be done --- XXX */
5214
5215 return 1;
5216 }
5217 #endif
5218
5219 static int
5220 dump_section (section, file)
5221 Elf32_Internal_Shdr * section;
5222 FILE * file;
5223 {
5224 bfd_size_type bytes;
5225 bfd_vma addr;
5226 unsigned char * data;
5227 unsigned char * start;
5228
5229 bytes = section->sh_size;
5230
5231 if (bytes == 0)
5232 {
5233 printf (_("\nSection '%s' has no data to dump.\n"),
5234 SECTION_NAME (section));
5235 return 0;
5236 }
5237 else
5238 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
5239
5240 addr = section->sh_addr;
5241
5242 GET_DATA_ALLOC (section->sh_offset, bytes, start, unsigned char *,
5243 "section data");
5244
5245 data = start;
5246
5247 while (bytes)
5248 {
5249 int j;
5250 int k;
5251 int lbytes;
5252
5253 lbytes = (bytes > 16 ? 16 : bytes);
5254
5255 printf (" 0x%8.8lx ", (unsigned long) addr);
5256
5257 switch (elf_header.e_ident [EI_DATA])
5258 {
5259 default:
5260 case ELFDATA2LSB:
5261 for (j = 15; j >= 0; j --)
5262 {
5263 if (j < lbytes)
5264 printf ("%2.2x", data [j]);
5265 else
5266 printf (" ");
5267
5268 if (!(j & 0x3))
5269 printf (" ");
5270 }
5271 break;
5272
5273 case ELFDATA2MSB:
5274 for (j = 0; j < 16; j++)
5275 {
5276 if (j < lbytes)
5277 printf ("%2.2x", data [j]);
5278 else
5279 printf (" ");
5280
5281 if ((j & 3) == 3)
5282 printf (" ");
5283 }
5284 break;
5285 }
5286
5287 for (j = 0; j < lbytes; j++)
5288 {
5289 k = data [j];
5290 if (k >= ' ' && k < 0x80)
5291 printf ("%c", k);
5292 else
5293 printf (".");
5294 }
5295
5296 putchar ('\n');
5297
5298 data += lbytes;
5299 addr += lbytes;
5300 bytes -= lbytes;
5301 }
5302
5303 free (start);
5304
5305 return 1;
5306 }
5307
5308
5309 static unsigned long int
5310 read_leb128 (data, length_return, sign)
5311 unsigned char * data;
5312 int * length_return;
5313 int sign;
5314 {
5315 unsigned long int result = 0;
5316 unsigned int num_read = 0;
5317 int shift = 0;
5318 unsigned char byte;
5319
5320 do
5321 {
5322 byte = * data ++;
5323 num_read ++;
5324
5325 result |= (byte & 0x7f) << shift;
5326
5327 shift += 7;
5328
5329 }
5330 while (byte & 0x80);
5331
5332 if (length_return != NULL)
5333 * length_return = num_read;
5334
5335 if (sign && (shift < 32) && (byte & 0x40))
5336 result |= -1 << shift;
5337
5338 return result;
5339 }
5340
5341 typedef struct State_Machine_Registers
5342 {
5343 unsigned long address;
5344 unsigned int file;
5345 unsigned int line;
5346 unsigned int column;
5347 int is_stmt;
5348 int basic_block;
5349 int end_sequence;
5350 /* This variable hold the number of the last entry seen
5351 in the File Table. */
5352 unsigned int last_file_entry;
5353 } SMR;
5354
5355 static SMR state_machine_regs;
5356
5357 static void
5358 reset_state_machine (is_stmt)
5359 int is_stmt;
5360 {
5361 state_machine_regs.address = 0;
5362 state_machine_regs.file = 1;
5363 state_machine_regs.line = 1;
5364 state_machine_regs.column = 0;
5365 state_machine_regs.is_stmt = is_stmt;
5366 state_machine_regs.basic_block = 0;
5367 state_machine_regs.end_sequence = 0;
5368 state_machine_regs.last_file_entry = 0;
5369 }
5370
5371 /* Handled an extend line op. Returns true if this is the end
5372 of sequence. */
5373 static int
5374 process_extended_line_op (data, is_stmt, pointer_size)
5375 unsigned char * data;
5376 int is_stmt;
5377 int pointer_size;
5378 {
5379 unsigned char op_code;
5380 int bytes_read;
5381 unsigned int len;
5382 unsigned char * name;
5383 unsigned long adr;
5384
5385 len = read_leb128 (data, & bytes_read, 0);
5386 data += bytes_read;
5387
5388 if (len == 0)
5389 {
5390 warn (_("badly formed extended line op encountered!"));
5391 return bytes_read;
5392 }
5393
5394 len += bytes_read;
5395 op_code = * data ++;
5396
5397 printf (_(" Extended opcode %d: "), op_code);
5398
5399 switch (op_code)
5400 {
5401 case DW_LNE_end_sequence:
5402 printf (_("End of Sequence\n\n"));
5403 reset_state_machine (is_stmt);
5404 break;
5405
5406 case DW_LNE_set_address:
5407 adr = byte_get (data, pointer_size);
5408 printf (_("set Address to 0x%lx\n"), adr);
5409 state_machine_regs.address = adr;
5410 break;
5411
5412 case DW_LNE_define_file:
5413 printf (_(" define new File Table entry\n"));
5414 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
5415
5416 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
5417 name = data;
5418 data += strlen ((char *) data) + 1;
5419 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5420 data += bytes_read;
5421 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5422 data += bytes_read;
5423 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5424 printf (_("%s\n\n"), name);
5425 break;
5426
5427 default:
5428 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
5429 break;
5430 }
5431
5432 return len;
5433 }
5434
5435 /* Size of pointers in the .debug_line section. This information is not
5436 really present in that section. It's obtained before dumping the debug
5437 sections by doing some pre-scan of the .debug_info section. */
5438 static int debug_line_pointer_size = 4;
5439
5440 static int
5441 display_debug_lines (section, start, file)
5442 Elf32_Internal_Shdr * section;
5443 unsigned char * start;
5444 FILE * file ATTRIBUTE_UNUSED;
5445 {
5446 DWARF2_External_LineInfo * external;
5447 DWARF2_Internal_LineInfo info;
5448 unsigned char * standard_opcodes;
5449 unsigned char * data = start;
5450 unsigned char * end = start + section->sh_size;
5451 unsigned char * end_of_sequence;
5452 int i;
5453
5454 printf (_("\nDump of debug contents of section %s:\n\n"),
5455 SECTION_NAME (section));
5456
5457 while (data < end)
5458 {
5459 external = (DWARF2_External_LineInfo *) data;
5460
5461 /* Check the length of the block. */
5462 info.li_length = BYTE_GET (external->li_length);
5463 if (info.li_length + sizeof (external->li_length) > section->sh_size)
5464 {
5465 warn
5466 (_("The line info appears to be corrupt - the section is too small\n"));
5467 return 0;
5468 }
5469
5470 /* Check its version number. */
5471 info.li_version = BYTE_GET (external->li_version);
5472 if (info.li_version != 2)
5473 {
5474 warn (_("Only DWARF version 2 line info is currently supported.\n"));
5475 return 0;
5476 }
5477
5478 info.li_prologue_length = BYTE_GET (external->li_prologue_length);
5479 info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
5480 info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
5481 info.li_line_base = BYTE_GET (external->li_line_base);
5482 info.li_line_range = BYTE_GET (external->li_line_range);
5483 info.li_opcode_base = BYTE_GET (external->li_opcode_base);
5484
5485 /* Sign extend the line base field. */
5486 info.li_line_base <<= 24;
5487 info.li_line_base >>= 24;
5488
5489 printf (_(" Length: %ld\n"), info.li_length);
5490 printf (_(" DWARF Version: %d\n"), info.li_version);
5491 printf (_(" Prolgue Length: %d\n"), info.li_prologue_length);
5492 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
5493 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
5494 printf (_(" Line Base: %d\n"), info.li_line_base);
5495 printf (_(" Line Range: %d\n"), info.li_line_range);
5496 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
5497
5498 end_of_sequence = data + info.li_length + sizeof (external->li_length);
5499
5500 reset_state_machine (info.li_default_is_stmt);
5501
5502 /* Display the contents of the Opcodes table. */
5503 standard_opcodes = data + sizeof (* external);
5504
5505 printf (_("\n Opcodes:\n"));
5506
5507 for (i = 1; i < info.li_opcode_base; i++)
5508 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
5509
5510 /* Display the contents of the Directory table. */
5511 data = standard_opcodes + info.li_opcode_base - 1;
5512
5513 if (* data == 0)
5514 printf (_("\n The Directory Table is empty.\n"));
5515 else
5516 {
5517 printf (_("\n The Directory Table:\n"));
5518
5519 while (* data != 0)
5520 {
5521 printf (_(" %s\n"), data);
5522
5523 data += strlen ((char *) data) + 1;
5524 }
5525 }
5526
5527 /* Skip the NUL at the end of the table. */
5528 data ++;
5529
5530 /* Display the contents of the File Name table. */
5531 if (* data == 0)
5532 printf (_("\n The File Name Table is empty.\n"));
5533 else
5534 {
5535 printf (_("\n The File Name Table:\n"));
5536 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
5537
5538 while (* data != 0)
5539 {
5540 unsigned char * name;
5541 int bytes_read;
5542
5543 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
5544 name = data;
5545
5546 data += strlen ((char *) data) + 1;
5547
5548 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5549 data += bytes_read;
5550 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5551 data += bytes_read;
5552 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5553 data += bytes_read;
5554 printf (_("%s\n"), name);
5555 }
5556 }
5557
5558 /* Skip the NUL at the end of the table. */
5559 data ++;
5560
5561 /* Now display the statements. */
5562 printf (_("\n Line Number Statements:\n"));
5563
5564
5565 while (data < end_of_sequence)
5566 {
5567 unsigned char op_code;
5568 int adv;
5569 int bytes_read;
5570
5571 op_code = * data ++;
5572
5573 switch (op_code)
5574 {
5575 case DW_LNS_extended_op:
5576 data += process_extended_line_op (data, info.li_default_is_stmt,
5577 debug_line_pointer_size);
5578 break;
5579
5580 case DW_LNS_copy:
5581 printf (_(" Copy\n"));
5582 break;
5583
5584 case DW_LNS_advance_pc:
5585 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
5586 data += bytes_read;
5587 state_machine_regs.address += adv;
5588 printf (_(" Advance PC by %d to %lx\n"), adv,
5589 state_machine_regs.address);
5590 break;
5591
5592 case DW_LNS_advance_line:
5593 adv = read_leb128 (data, & bytes_read, 1);
5594 data += bytes_read;
5595 state_machine_regs.line += adv;
5596 printf (_(" Advance Line by %d to %d\n"), adv,
5597 state_machine_regs.line);
5598 break;
5599
5600 case DW_LNS_set_file:
5601 adv = read_leb128 (data, & bytes_read, 0);
5602 data += bytes_read;
5603 printf (_(" Set File Name to entry %d in the File Name Table\n"),
5604 adv);
5605 state_machine_regs.file = adv;
5606 break;
5607
5608 case DW_LNS_set_column:
5609 adv = read_leb128 (data, & bytes_read, 0);
5610 data += bytes_read;
5611 printf (_(" Set column to %d\n"), adv);
5612 state_machine_regs.column = adv;
5613 break;
5614
5615 case DW_LNS_negate_stmt:
5616 adv = state_machine_regs.is_stmt;
5617 adv = ! adv;
5618 printf (_(" Set is_stmt to %d\n"), adv);
5619 state_machine_regs.is_stmt = adv;
5620 break;
5621
5622 case DW_LNS_set_basic_block:
5623 printf (_(" Set basic block\n"));
5624 state_machine_regs.basic_block = 1;
5625 break;
5626
5627 case DW_LNS_const_add_pc:
5628 adv = (((255 - info.li_opcode_base) / info.li_line_range)
5629 * info.li_min_insn_length);
5630 state_machine_regs.address += adv;
5631 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
5632 state_machine_regs.address);
5633 break;
5634
5635 case DW_LNS_fixed_advance_pc:
5636 adv = byte_get (data, 2);
5637 data += 2;
5638 state_machine_regs.address += adv;
5639 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
5640 adv, state_machine_regs.address);
5641 break;
5642
5643 default:
5644 op_code -= info.li_opcode_base;
5645 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
5646 state_machine_regs.address += adv;
5647 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
5648 op_code, adv, state_machine_regs.address);
5649 adv = (op_code % info.li_line_range) + info.li_line_base;
5650 state_machine_regs.line += adv;
5651 printf (_(" and Line by %d to %d\n"),
5652 adv, state_machine_regs.line);
5653 break;
5654 }
5655 }
5656 printf ("\n");
5657 }
5658
5659 return 1;
5660 }
5661
5662 static int
5663 display_debug_pubnames (section, start, file)
5664 Elf32_Internal_Shdr * section;
5665 unsigned char * start;
5666 FILE * file ATTRIBUTE_UNUSED;
5667 {
5668 DWARF2_External_PubNames * external;
5669 DWARF2_Internal_PubNames pubnames;
5670 unsigned char * end;
5671
5672 end = start + section->sh_size;
5673
5674 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
5675
5676 while (start < end)
5677 {
5678 unsigned char * data;
5679 unsigned long offset;
5680
5681 external = (DWARF2_External_PubNames *) start;
5682
5683 pubnames.pn_length = BYTE_GET (external->pn_length);
5684 pubnames.pn_version = BYTE_GET (external->pn_version);
5685 pubnames.pn_offset = BYTE_GET (external->pn_offset);
5686 pubnames.pn_size = BYTE_GET (external->pn_size);
5687
5688 data = start + sizeof (* external);
5689 start += pubnames.pn_length + sizeof (external->pn_length);
5690
5691 if (pubnames.pn_version != 2)
5692 {
5693 static int warned = 0;
5694
5695 if (! warned)
5696 {
5697 warn (_("Only DWARF 2 pubnames are currently supported\n"));
5698 warned = 1;
5699 }
5700
5701 continue;
5702 }
5703
5704 printf (_(" Length: %ld\n"),
5705 pubnames.pn_length);
5706 printf (_(" Version: %d\n"),
5707 pubnames.pn_version);
5708 printf (_(" Offset into .debug_info section: %ld\n"),
5709 pubnames.pn_offset);
5710 printf (_(" Size of area in .debug_info section: %ld\n"),
5711 pubnames.pn_size);
5712
5713 printf (_("\n Offset\tName\n"));
5714
5715 do
5716 {
5717 offset = byte_get (data, 4);
5718
5719 if (offset != 0)
5720 {
5721 data += 4;
5722 printf (" %ld\t\t%s\n", offset, data);
5723 data += strlen ((char *) data) + 1;
5724 }
5725 }
5726 while (offset != 0);
5727 }
5728
5729 printf ("\n");
5730 return 1;
5731 }
5732
5733 static char *
5734 get_TAG_name (tag)
5735 unsigned long tag;
5736 {
5737 switch (tag)
5738 {
5739 case DW_TAG_padding: return "DW_TAG_padding";
5740 case DW_TAG_array_type: return "DW_TAG_array_type";
5741 case DW_TAG_class_type: return "DW_TAG_class_type";
5742 case DW_TAG_entry_point: return "DW_TAG_entry_point";
5743 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
5744 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
5745 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
5746 case DW_TAG_label: return "DW_TAG_label";
5747 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
5748 case DW_TAG_member: return "DW_TAG_member";
5749 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
5750 case DW_TAG_reference_type: return "DW_TAG_reference_type";
5751 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
5752 case DW_TAG_string_type: return "DW_TAG_string_type";
5753 case DW_TAG_structure_type: return "DW_TAG_structure_type";
5754 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
5755 case DW_TAG_typedef: return "DW_TAG_typedef";
5756 case DW_TAG_union_type: return "DW_TAG_union_type";
5757 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
5758 case DW_TAG_variant: return "DW_TAG_variant";
5759 case DW_TAG_common_block: return "DW_TAG_common_block";
5760 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
5761 case DW_TAG_inheritance: return "DW_TAG_inheritance";
5762 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
5763 case DW_TAG_module: return "DW_TAG_module";
5764 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
5765 case DW_TAG_set_type: return "DW_TAG_set_type";
5766 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
5767 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
5768 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
5769 case DW_TAG_base_type: return "DW_TAG_base_type";
5770 case DW_TAG_catch_block: return "DW_TAG_catch_block";
5771 case DW_TAG_const_type: return "DW_TAG_const_type";
5772 case DW_TAG_constant: return "DW_TAG_constant";
5773 case DW_TAG_enumerator: return "DW_TAG_enumerator";
5774 case DW_TAG_file_type: return "DW_TAG_file_type";
5775 case DW_TAG_friend: return "DW_TAG_friend";
5776 case DW_TAG_namelist: return "DW_TAG_namelist";
5777 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
5778 case DW_TAG_packed_type: return "DW_TAG_packed_type";
5779 case DW_TAG_subprogram: return "DW_TAG_subprogram";
5780 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
5781 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
5782 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
5783 case DW_TAG_try_block: return "DW_TAG_try_block";
5784 case DW_TAG_variant_part: return "DW_TAG_variant_part";
5785 case DW_TAG_variable: return "DW_TAG_variable";
5786 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
5787 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
5788 case DW_TAG_format_label: return "DW_TAG_format_label";
5789 case DW_TAG_function_template: return "DW_TAG_function_template";
5790 case DW_TAG_class_template: return "DW_TAG_class_template";
5791 default:
5792 {
5793 static char buffer [100];
5794
5795 sprintf (buffer, _("Unknown TAG value: %lx"), tag);
5796 return buffer;
5797 }
5798 }
5799 }
5800
5801 static char *
5802 get_AT_name (attribute)
5803 unsigned long attribute;
5804 {
5805 switch (attribute)
5806 {
5807 case DW_AT_sibling: return "DW_AT_sibling";
5808 case DW_AT_location: return "DW_AT_location";
5809 case DW_AT_name: return "DW_AT_name";
5810 case DW_AT_ordering: return "DW_AT_ordering";
5811 case DW_AT_subscr_data: return "DW_AT_subscr_data";
5812 case DW_AT_byte_size: return "DW_AT_byte_size";
5813 case DW_AT_bit_offset: return "DW_AT_bit_offset";
5814 case DW_AT_bit_size: return "DW_AT_bit_size";
5815 case DW_AT_element_list: return "DW_AT_element_list";
5816 case DW_AT_stmt_list: return "DW_AT_stmt_list";
5817 case DW_AT_low_pc: return "DW_AT_low_pc";
5818 case DW_AT_high_pc: return "DW_AT_high_pc";
5819 case DW_AT_language: return "DW_AT_language";
5820 case DW_AT_member: return "DW_AT_member";
5821 case DW_AT_discr: return "DW_AT_discr";
5822 case DW_AT_discr_value: return "DW_AT_discr_value";
5823 case DW_AT_visibility: return "DW_AT_visibility";
5824 case DW_AT_import: return "DW_AT_import";
5825 case DW_AT_string_length: return "DW_AT_string_length";
5826 case DW_AT_common_reference: return "DW_AT_common_reference";
5827 case DW_AT_comp_dir: return "DW_AT_comp_dir";
5828 case DW_AT_const_value: return "DW_AT_const_value";
5829 case DW_AT_containing_type: return "DW_AT_containing_type";
5830 case DW_AT_default_value: return "DW_AT_default_value";
5831 case DW_AT_inline: return "DW_AT_inline";
5832 case DW_AT_is_optional: return "DW_AT_is_optional";
5833 case DW_AT_lower_bound: return "DW_AT_lower_bound";
5834 case DW_AT_producer: return "DW_AT_producer";
5835 case DW_AT_prototyped: return "DW_AT_prototyped";
5836 case DW_AT_return_addr: return "DW_AT_return_addr";
5837 case DW_AT_start_scope: return "DW_AT_start_scope";
5838 case DW_AT_stride_size: return "DW_AT_stride_size";
5839 case DW_AT_upper_bound: return "DW_AT_upper_bound";
5840 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
5841 case DW_AT_accessibility: return "DW_AT_accessibility";
5842 case DW_AT_address_class: return "DW_AT_address_class";
5843 case DW_AT_artificial: return "DW_AT_artificial";
5844 case DW_AT_base_types: return "DW_AT_base_types";
5845 case DW_AT_calling_convention: return "DW_AT_calling_convention";
5846 case DW_AT_count: return "DW_AT_count";
5847 case DW_AT_data_member_location: return "DW_AT_data_member_location";
5848 case DW_AT_decl_column: return "DW_AT_decl_column";
5849 case DW_AT_decl_file: return "DW_AT_decl_file";
5850 case DW_AT_decl_line: return "DW_AT_decl_line";
5851 case DW_AT_declaration: return "DW_AT_declaration";
5852 case DW_AT_discr_list: return "DW_AT_discr_list";
5853 case DW_AT_encoding: return "DW_AT_encoding";
5854 case DW_AT_external: return "DW_AT_external";
5855 case DW_AT_frame_base: return "DW_AT_frame_base";
5856 case DW_AT_friend: return "DW_AT_friend";
5857 case DW_AT_identifier_case: return "DW_AT_identifier_case";
5858 case DW_AT_macro_info: return "DW_AT_macro_info";
5859 case DW_AT_namelist_items: return "DW_AT_namelist_items";
5860 case DW_AT_priority: return "DW_AT_priority";
5861 case DW_AT_segment: return "DW_AT_segment";
5862 case DW_AT_specification: return "DW_AT_specification";
5863 case DW_AT_static_link: return "DW_AT_static_link";
5864 case DW_AT_type: return "DW_AT_type";
5865 case DW_AT_use_location: return "DW_AT_use_location";
5866 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
5867 case DW_AT_virtuality: return "DW_AT_virtuality";
5868 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
5869 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
5870 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
5871 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
5872 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
5873 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
5874 case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
5875 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
5876 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
5877 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
5878 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
5879 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
5880 case DW_AT_sf_names: return "DW_AT_sf_names";
5881 case DW_AT_src_info: return "DW_AT_src_info";
5882 case DW_AT_mac_info: return "DW_AT_mac_info";
5883 case DW_AT_src_coords: return "DW_AT_src_coords";
5884 case DW_AT_body_begin: return "DW_AT_body_begin";
5885 case DW_AT_body_end: return "DW_AT_body_end";
5886 default:
5887 {
5888 static char buffer [100];
5889
5890 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
5891 return buffer;
5892 }
5893 }
5894 }
5895
5896 static char *
5897 get_FORM_name (form)
5898 unsigned long form;
5899 {
5900 switch (form)
5901 {
5902 case DW_FORM_addr: return "DW_FORM_addr";
5903 case DW_FORM_block2: return "DW_FORM_block2";
5904 case DW_FORM_block4: return "DW_FORM_block4";
5905 case DW_FORM_data2: return "DW_FORM_data2";
5906 case DW_FORM_data4: return "DW_FORM_data4";
5907 case DW_FORM_data8: return "DW_FORM_data8";
5908 case DW_FORM_string: return "DW_FORM_string";
5909 case DW_FORM_block: return "DW_FORM_block";
5910 case DW_FORM_block1: return "DW_FORM_block1";
5911 case DW_FORM_data1: return "DW_FORM_data1";
5912 case DW_FORM_flag: return "DW_FORM_flag";
5913 case DW_FORM_sdata: return "DW_FORM_sdata";
5914 case DW_FORM_strp: return "DW_FORM_strp";
5915 case DW_FORM_udata: return "DW_FORM_udata";
5916 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
5917 case DW_FORM_ref1: return "DW_FORM_ref1";
5918 case DW_FORM_ref2: return "DW_FORM_ref2";
5919 case DW_FORM_ref4: return "DW_FORM_ref4";
5920 case DW_FORM_ref8: return "DW_FORM_ref8";
5921 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
5922 case DW_FORM_indirect: return "DW_FORM_indirect";
5923 default:
5924 {
5925 static char buffer [100];
5926
5927 sprintf (buffer, _("Unknown FORM value: %lx"), form);
5928 return buffer;
5929 }
5930 }
5931 }
5932
5933 /* FIXME: There are better and more effiecint ways to handle
5934 these structures. For now though, I just want something that
5935 is simple to implement. */
5936 typedef struct abbrev_attr
5937 {
5938 unsigned long attribute;
5939 unsigned long form;
5940 struct abbrev_attr * next;
5941 }
5942 abbrev_attr;
5943
5944 typedef struct abbrev_entry
5945 {
5946 unsigned long entry;
5947 unsigned long tag;
5948 int children;
5949 struct abbrev_attr * first_attr;
5950 struct abbrev_attr * last_attr;
5951 struct abbrev_entry * next;
5952 }
5953 abbrev_entry;
5954
5955 static abbrev_entry * first_abbrev = NULL;
5956 static abbrev_entry * last_abbrev = NULL;
5957
5958 static void
5959 free_abbrevs PARAMS ((void))
5960 {
5961 abbrev_entry * abbrev;
5962
5963 for (abbrev = first_abbrev; abbrev;)
5964 {
5965 abbrev_entry * next = abbrev->next;
5966 abbrev_attr * attr;
5967
5968 for (attr = abbrev->first_attr; attr;)
5969 {
5970 abbrev_attr * next = attr->next;
5971
5972 free (attr);
5973 attr = next;
5974 }
5975
5976 free (abbrev);
5977 abbrev = next;
5978 }
5979
5980 last_abbrev = first_abbrev = NULL;
5981 }
5982
5983 static void
5984 add_abbrev (number, tag, children)
5985 unsigned long number;
5986 unsigned long tag;
5987 int children;
5988 {
5989 abbrev_entry * entry;
5990
5991 entry = (abbrev_entry *) malloc (sizeof (* entry));
5992
5993 if (entry == NULL)
5994 /* ugg */
5995 return;
5996
5997 entry->entry = number;
5998 entry->tag = tag;
5999 entry->children = children;
6000 entry->first_attr = NULL;
6001 entry->last_attr = NULL;
6002 entry->next = NULL;
6003
6004 if (first_abbrev == NULL)
6005 first_abbrev = entry;
6006 else
6007 last_abbrev->next = entry;
6008
6009 last_abbrev = entry;
6010 }
6011
6012 static void
6013 add_abbrev_attr (attribute, form)
6014 unsigned long attribute;
6015 unsigned long form;
6016 {
6017 abbrev_attr * attr;
6018
6019 attr = (abbrev_attr *) malloc (sizeof (* attr));
6020
6021 if (attr == NULL)
6022 /* ugg */
6023 return;
6024
6025 attr->attribute = attribute;
6026 attr->form = form;
6027 attr->next = NULL;
6028
6029 if (last_abbrev->first_attr == NULL)
6030 last_abbrev->first_attr = attr;
6031 else
6032 last_abbrev->last_attr->next = attr;
6033
6034 last_abbrev->last_attr = attr;
6035 }
6036
6037 /* Processes the (partial) contents of a .debug_abbrev section.
6038 Returns NULL if the end of the section was encountered.
6039 Returns the address after the last byte read if the end of
6040 an abbreviation set was found. */
6041
6042 static unsigned char *
6043 process_abbrev_section (start, end)
6044 unsigned char * start;
6045 unsigned char * end;
6046 {
6047 if (first_abbrev != NULL)
6048 return NULL;
6049
6050 while (start < end)
6051 {
6052 int bytes_read;
6053 unsigned long entry;
6054 unsigned long tag;
6055 unsigned long attribute;
6056 int children;
6057
6058 entry = read_leb128 (start, & bytes_read, 0);
6059 start += bytes_read;
6060
6061 /* A single zero is supposed to end the section according
6062 to the standard. If there's more, then signal that to
6063 the caller. */
6064 if (entry == 0)
6065 return start == end ? NULL : start;
6066
6067 tag = read_leb128 (start, & bytes_read, 0);
6068 start += bytes_read;
6069
6070 children = * start ++;
6071
6072 add_abbrev (entry, tag, children);
6073
6074 do
6075 {
6076 unsigned long form;
6077
6078 attribute = read_leb128 (start, & bytes_read, 0);
6079 start += bytes_read;
6080
6081 form = read_leb128 (start, & bytes_read, 0);
6082 start += bytes_read;
6083
6084 if (attribute != 0)
6085 add_abbrev_attr (attribute, form);
6086 }
6087 while (attribute != 0);
6088 }
6089
6090 return NULL;
6091 }
6092
6093
6094 static int
6095 display_debug_abbrev (section, start, file)
6096 Elf32_Internal_Shdr * section;
6097 unsigned char * start;
6098 FILE * file ATTRIBUTE_UNUSED;
6099 {
6100 abbrev_entry * entry;
6101 unsigned char * end = start + section->sh_size;
6102
6103 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
6104
6105 do
6106 {
6107 start = process_abbrev_section (start, end);
6108
6109 printf (_(" Number TAG\n"));
6110
6111 for (entry = first_abbrev; entry; entry = entry->next)
6112 {
6113 abbrev_attr * attr;
6114
6115 printf (_(" %ld %s [%s]\n"),
6116 entry->entry,
6117 get_TAG_name (entry->tag),
6118 entry->children ? _("has children") : _("no children"));
6119
6120 for (attr = entry->first_attr; attr; attr = attr->next)
6121 {
6122 printf (_(" %-18s %s\n"),
6123 get_AT_name (attr->attribute),
6124 get_FORM_name (attr->form));
6125 }
6126 }
6127 }
6128 while (start);
6129
6130 printf ("\n");
6131
6132 return 1;
6133 }
6134
6135
6136 static unsigned char *
6137 display_block (data, length)
6138 unsigned char * data;
6139 unsigned long length;
6140 {
6141 printf (_(" %lu byte block: "), length);
6142
6143 while (length --)
6144 printf ("%lx ", (unsigned long) byte_get (data ++, 1));
6145
6146 return data;
6147 }
6148
6149 static void
6150 decode_location_expression (data, pointer_size, length)
6151 unsigned char * data;
6152 unsigned int pointer_size;
6153 unsigned long length;
6154 {
6155 unsigned op;
6156 int bytes_read;
6157 unsigned long uvalue;
6158 unsigned char * end = data + length;
6159
6160 while (data < end)
6161 {
6162 op = * data ++;
6163
6164 switch (op)
6165 {
6166 case DW_OP_addr:
6167 printf ("DW_OP_addr: %lx",
6168 (unsigned long) byte_get (data, pointer_size));
6169 data += pointer_size;
6170 break;
6171 case DW_OP_deref:
6172 printf ("DW_OP_deref");
6173 break;
6174 case DW_OP_const1u:
6175 printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
6176 break;
6177 case DW_OP_const1s:
6178 printf ("DW_OP_const1s: %ld", (long) byte_get (data++, 1));
6179 break;
6180 case DW_OP_const2u:
6181 printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
6182 data += 2;
6183 break;
6184 case DW_OP_const2s:
6185 printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
6186 data += 2;
6187 break;
6188 case DW_OP_const4u:
6189 printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
6190 data += 4;
6191 break;
6192 case DW_OP_const4s:
6193 printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
6194 data += 4;
6195 break;
6196 case DW_OP_const8u:
6197 printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
6198 (unsigned long) byte_get (data + 4, 4));
6199 data += 8;
6200 break;
6201 case DW_OP_const8s:
6202 printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
6203 (long) byte_get (data + 4, 4));
6204 data += 8;
6205 break;
6206 case DW_OP_constu:
6207 printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
6208 data += bytes_read;
6209 break;
6210 case DW_OP_consts:
6211 printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
6212 data += bytes_read;
6213 break;
6214 case DW_OP_dup:
6215 printf ("DW_OP_dup");
6216 break;
6217 case DW_OP_drop:
6218 printf ("DW_OP_drop");
6219 break;
6220 case DW_OP_over:
6221 printf ("DW_OP_over");
6222 break;
6223 case DW_OP_pick:
6224 printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
6225 break;
6226 case DW_OP_swap:
6227 printf ("DW_OP_swap");
6228 break;
6229 case DW_OP_rot:
6230 printf ("DW_OP_rot");
6231 break;
6232 case DW_OP_xderef:
6233 printf ("DW_OP_xderef");
6234 break;
6235 case DW_OP_abs:
6236 printf ("DW_OP_abs");
6237 break;
6238 case DW_OP_and:
6239 printf ("DW_OP_and");
6240 break;
6241 case DW_OP_div:
6242 printf ("DW_OP_div");
6243 break;
6244 case DW_OP_minus:
6245 printf ("DW_OP_minus");
6246 break;
6247 case DW_OP_mod:
6248 printf ("DW_OP_mod");
6249 break;
6250 case DW_OP_mul:
6251 printf ("DW_OP_mul");
6252 break;
6253 case DW_OP_neg:
6254 printf ("DW_OP_neg");
6255 break;
6256 case DW_OP_not:
6257 printf ("DW_OP_not");
6258 break;
6259 case DW_OP_or:
6260 printf ("DW_OP_or");
6261 break;
6262 case DW_OP_plus:
6263 printf ("DW_OP_plus");
6264 break;
6265 case DW_OP_plus_uconst:
6266 printf ("DW_OP_plus_uconst: %lu",
6267 read_leb128 (data, &bytes_read, 0));
6268 data += bytes_read;
6269 break;
6270 case DW_OP_shl:
6271 printf ("DW_OP_shl");
6272 break;
6273 case DW_OP_shr:
6274 printf ("DW_OP_shr");
6275 break;
6276 case DW_OP_shra:
6277 printf ("DW_OP_shra");
6278 break;
6279 case DW_OP_xor:
6280 printf ("DW_OP_xor");
6281 break;
6282 case DW_OP_bra:
6283 printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
6284 data += 2;
6285 break;
6286 case DW_OP_eq:
6287 printf ("DW_OP_eq");
6288 break;
6289 case DW_OP_ge:
6290 printf ("DW_OP_ge");
6291 break;
6292 case DW_OP_gt:
6293 printf ("DW_OP_gt");
6294 break;
6295 case DW_OP_le:
6296 printf ("DW_OP_le");
6297 break;
6298 case DW_OP_lt:
6299 printf ("DW_OP_lt");
6300 break;
6301 case DW_OP_ne:
6302 printf ("DW_OP_ne");
6303 break;
6304 case DW_OP_skip:
6305 printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
6306 data += 2;
6307 break;
6308
6309 case DW_OP_lit0:
6310 case DW_OP_lit1:
6311 case DW_OP_lit2:
6312 case DW_OP_lit3:
6313 case DW_OP_lit4:
6314 case DW_OP_lit5:
6315 case DW_OP_lit6:
6316 case DW_OP_lit7:
6317 case DW_OP_lit8:
6318 case DW_OP_lit9:
6319 case DW_OP_lit10:
6320 case DW_OP_lit11:
6321 case DW_OP_lit12:
6322 case DW_OP_lit13:
6323 case DW_OP_lit14:
6324 case DW_OP_lit15:
6325 case DW_OP_lit16:
6326 case DW_OP_lit17:
6327 case DW_OP_lit18:
6328 case DW_OP_lit19:
6329 case DW_OP_lit20:
6330 case DW_OP_lit21:
6331 case DW_OP_lit22:
6332 case DW_OP_lit23:
6333 case DW_OP_lit24:
6334 case DW_OP_lit25:
6335 case DW_OP_lit26:
6336 case DW_OP_lit27:
6337 case DW_OP_lit28:
6338 case DW_OP_lit29:
6339 case DW_OP_lit30:
6340 case DW_OP_lit31:
6341 printf ("DW_OP_lit%d", op - DW_OP_lit0);
6342 break;
6343
6344 case DW_OP_reg0:
6345 case DW_OP_reg1:
6346 case DW_OP_reg2:
6347 case DW_OP_reg3:
6348 case DW_OP_reg4:
6349 case DW_OP_reg5:
6350 case DW_OP_reg6:
6351 case DW_OP_reg7:
6352 case DW_OP_reg8:
6353 case DW_OP_reg9:
6354 case DW_OP_reg10:
6355 case DW_OP_reg11:
6356 case DW_OP_reg12:
6357 case DW_OP_reg13:
6358 case DW_OP_reg14:
6359 case DW_OP_reg15:
6360 case DW_OP_reg16:
6361 case DW_OP_reg17:
6362 case DW_OP_reg18:
6363 case DW_OP_reg19:
6364 case DW_OP_reg20:
6365 case DW_OP_reg21:
6366 case DW_OP_reg22:
6367 case DW_OP_reg23:
6368 case DW_OP_reg24:
6369 case DW_OP_reg25:
6370 case DW_OP_reg26:
6371 case DW_OP_reg27:
6372 case DW_OP_reg28:
6373 case DW_OP_reg29:
6374 case DW_OP_reg30:
6375 case DW_OP_reg31:
6376 printf ("DW_OP_reg%d", op - DW_OP_reg0);
6377 break;
6378
6379 case DW_OP_breg0:
6380 case DW_OP_breg1:
6381 case DW_OP_breg2:
6382 case DW_OP_breg3:
6383 case DW_OP_breg4:
6384 case DW_OP_breg5:
6385 case DW_OP_breg6:
6386 case DW_OP_breg7:
6387 case DW_OP_breg8:
6388 case DW_OP_breg9:
6389 case DW_OP_breg10:
6390 case DW_OP_breg11:
6391 case DW_OP_breg12:
6392 case DW_OP_breg13:
6393 case DW_OP_breg14:
6394 case DW_OP_breg15:
6395 case DW_OP_breg16:
6396 case DW_OP_breg17:
6397 case DW_OP_breg18:
6398 case DW_OP_breg19:
6399 case DW_OP_breg20:
6400 case DW_OP_breg21:
6401 case DW_OP_breg22:
6402 case DW_OP_breg23:
6403 case DW_OP_breg24:
6404 case DW_OP_breg25:
6405 case DW_OP_breg26:
6406 case DW_OP_breg27:
6407 case DW_OP_breg28:
6408 case DW_OP_breg29:
6409 case DW_OP_breg30:
6410 case DW_OP_breg31:
6411 printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
6412 read_leb128 (data, &bytes_read, 1));
6413 data += bytes_read;
6414 break;
6415
6416 case DW_OP_regx:
6417 printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
6418 data += bytes_read;
6419 break;
6420 case DW_OP_fbreg:
6421 printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
6422 data += bytes_read;
6423 break;
6424 case DW_OP_bregx:
6425 uvalue = read_leb128 (data, &bytes_read, 0);
6426 data += bytes_read;
6427 printf ("DW_OP_bregx: %lu %ld", uvalue,
6428 read_leb128 (data, &bytes_read, 1));
6429 data += bytes_read;
6430 break;
6431 case DW_OP_piece:
6432 printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
6433 data += bytes_read;
6434 break;
6435 case DW_OP_deref_size:
6436 printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
6437 break;
6438 case DW_OP_xderef_size:
6439 printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
6440 break;
6441 case DW_OP_nop:
6442 printf ("DW_OP_nop");
6443 break;
6444
6445 default:
6446 if (op >= DW_OP_lo_user
6447 && op <= DW_OP_hi_user)
6448 printf (_("(User defined location op)"));
6449 else
6450 printf (_("(Unknown location op)"));
6451 /* No way to tell where the next op is, so just bail. */
6452 return;
6453 }
6454 }
6455 }
6456
6457
6458 static unsigned char *
6459 read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
6460 unsigned long attribute;
6461 unsigned long form;
6462 unsigned char * data;
6463 unsigned long cu_offset;
6464 unsigned long pointer_size;
6465 {
6466 unsigned long uvalue = 0;
6467 unsigned char * block_start = NULL;
6468 int bytes_read;
6469
6470 printf (" %-18s:", get_AT_name (attribute));
6471
6472 switch (form)
6473 {
6474 default:
6475 break;
6476
6477 case DW_FORM_ref_addr:
6478 case DW_FORM_addr:
6479 uvalue = byte_get (data, pointer_size);
6480 data += pointer_size;
6481 break;
6482
6483 case DW_FORM_ref1:
6484 case DW_FORM_flag:
6485 case DW_FORM_data1:
6486 uvalue = byte_get (data ++, 1);
6487 break;
6488
6489 case DW_FORM_ref2:
6490 case DW_FORM_data2:
6491 uvalue = byte_get (data, 2);
6492 data += 2;
6493 break;
6494
6495 case DW_FORM_ref4:
6496 case DW_FORM_data4:
6497 uvalue = byte_get (data, 4);
6498 data += 4;
6499 break;
6500
6501 case DW_FORM_sdata:
6502 uvalue = read_leb128 (data, & bytes_read, 1);
6503 data += bytes_read;
6504 break;
6505
6506 case DW_FORM_ref_udata:
6507 case DW_FORM_udata:
6508 uvalue = read_leb128 (data, & bytes_read, 0);
6509 data += bytes_read;
6510 break;
6511 }
6512
6513 switch (form)
6514 {
6515 case DW_FORM_ref_addr:
6516 printf (" <#%lx>", uvalue);
6517 break;
6518
6519 case DW_FORM_ref1:
6520 case DW_FORM_ref2:
6521 case DW_FORM_ref4:
6522 case DW_FORM_ref_udata:
6523 printf (" <%lx>", uvalue + cu_offset);
6524 break;
6525
6526 case DW_FORM_addr:
6527 printf (" %#lx", uvalue);
6528
6529 case DW_FORM_flag:
6530 case DW_FORM_data1:
6531 case DW_FORM_data2:
6532 case DW_FORM_data4:
6533 case DW_FORM_sdata:
6534 case DW_FORM_udata:
6535 printf (" %ld", uvalue);
6536 break;
6537
6538 case DW_FORM_ref8:
6539 case DW_FORM_data8:
6540 uvalue = byte_get (data, 4);
6541 printf (" %lx", uvalue);
6542 printf (" %lx", (unsigned long) byte_get (data + 4, 4));
6543 data += 8;
6544 break;
6545
6546 case DW_FORM_string:
6547 printf (" %s", data);
6548 data += strlen ((char *) data) + 1;
6549 break;
6550
6551 case DW_FORM_block:
6552 uvalue = read_leb128 (data, & bytes_read, 0);
6553 block_start = data + bytes_read;
6554 data = display_block (block_start, uvalue);
6555 break;
6556
6557 case DW_FORM_block1:
6558 uvalue = byte_get (data, 1);
6559 block_start = data + 1;
6560 data = display_block (block_start, uvalue);
6561 break;
6562
6563 case DW_FORM_block2:
6564 uvalue = byte_get (data, 2);
6565 block_start = data + 2;
6566 data = display_block (block_start, uvalue);
6567 break;
6568
6569 case DW_FORM_block4:
6570 uvalue = byte_get (data, 4);
6571 block_start = data + 4;
6572 data = display_block (block_start, uvalue);
6573 break;
6574
6575 case DW_FORM_strp:
6576 case DW_FORM_indirect:
6577 warn (_("Unable to handle FORM: %d"), form);
6578 break;
6579
6580 default:
6581 warn (_("Unrecognised form: %d"), form);
6582 break;
6583 }
6584
6585 /* For some attributes we can display futher information. */
6586
6587 printf ("\t");
6588
6589 switch (attribute)
6590 {
6591 case DW_AT_inline:
6592 switch (uvalue)
6593 {
6594 case DW_INL_not_inlined: printf (_("(not inlined)")); break;
6595 case DW_INL_inlined: printf (_("(inlined)")); break;
6596 case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
6597 case DW_INL_declared_inlined: printf (_("(declared as inline and inlined)")); break;
6598 default: printf (_(" (Unknown inline attribute value: %lx)"), uvalue); break;
6599 }
6600 break;
6601
6602 case DW_AT_language:
6603 switch (uvalue)
6604 {
6605 case DW_LANG_C: printf ("(non-ANSI C)"); break;
6606 case DW_LANG_C89: printf ("(ANSI C)"); break;
6607 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
6608 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
6609 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
6610 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
6611 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
6612 case DW_LANG_Ada83: printf ("(Ada)"); break;
6613 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
6614 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
6615 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
6616 default: printf ("(Unknown: %lx)", uvalue); break;
6617 }
6618 break;
6619
6620 case DW_AT_encoding:
6621 switch (uvalue)
6622 {
6623 case DW_ATE_void: printf ("(void)"); break;
6624 case DW_ATE_address: printf ("(machine address)"); break;
6625 case DW_ATE_boolean: printf ("(boolean)"); break;
6626 case DW_ATE_complex_float: printf ("(complex float)"); break;
6627 case DW_ATE_float: printf ("(float)"); break;
6628 case DW_ATE_signed: printf ("(signed)"); break;
6629 case DW_ATE_signed_char: printf ("(signed char)"); break;
6630 case DW_ATE_unsigned: printf ("(unsigned)"); break;
6631 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
6632 default:
6633 if (uvalue >= DW_ATE_lo_user
6634 && uvalue <= DW_ATE_hi_user)
6635 printf ("(user defined type)");
6636 else
6637 printf ("(unknown type)");
6638 break;
6639 }
6640 break;
6641
6642 case DW_AT_accessibility:
6643 switch (uvalue)
6644 {
6645 case DW_ACCESS_public: printf ("(public)"); break;
6646 case DW_ACCESS_protected: printf ("(protected)"); break;
6647 case DW_ACCESS_private: printf ("(private)"); break;
6648 default: printf ("(unknown accessibility)"); break;
6649 }
6650 break;
6651
6652 case DW_AT_visibility:
6653 switch (uvalue)
6654 {
6655 case DW_VIS_local: printf ("(local)"); break;
6656 case DW_VIS_exported: printf ("(exported)"); break;
6657 case DW_VIS_qualified: printf ("(qualified)"); break;
6658 default: printf ("(unknown visibility)"); break;
6659 }
6660 break;
6661
6662 case DW_AT_virtuality:
6663 switch (uvalue)
6664 {
6665 case DW_VIRTUALITY_none: printf ("(none)"); break;
6666 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
6667 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
6668 default: printf ("(unknown virtuality)"); break;
6669 }
6670 break;
6671
6672 case DW_AT_identifier_case:
6673 switch (uvalue)
6674 {
6675 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
6676 case DW_ID_up_case: printf ("(up_case)"); break;
6677 case DW_ID_down_case: printf ("(down_case)"); break;
6678 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
6679 default: printf ("(unknown case)"); break;
6680 }
6681 break;
6682
6683 case DW_AT_calling_convention:
6684 switch (uvalue)
6685 {
6686 case DW_CC_normal: printf ("(normal)"); break;
6687 case DW_CC_program: printf ("(program)"); break;
6688 case DW_CC_nocall: printf ("(nocall)"); break;
6689 default:
6690 if (uvalue >= DW_CC_lo_user
6691 && uvalue <= DW_CC_hi_user)
6692 printf ("(user defined)");
6693 else
6694 printf ("(unknown convention)");
6695 }
6696 break;
6697
6698 case DW_AT_frame_base:
6699 case DW_AT_location:
6700 case DW_AT_data_member_location:
6701 case DW_AT_vtable_elem_location:
6702 if (block_start)
6703 {
6704 printf ("(");
6705 decode_location_expression (block_start, pointer_size, uvalue);
6706 printf (")");
6707 }
6708 break;
6709
6710 default:
6711 break;
6712 }
6713
6714 printf ("\n");
6715 return data;
6716 }
6717
6718 static int
6719 display_debug_info (section, start, file)
6720 Elf32_Internal_Shdr * section;
6721 unsigned char * start;
6722 FILE * file;
6723 {
6724 unsigned char * end = start + section->sh_size;
6725 unsigned char * section_begin = start;
6726
6727 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
6728
6729 while (start < end)
6730 {
6731 DWARF2_External_CompUnit * external;
6732 DWARF2_Internal_CompUnit compunit;
6733 unsigned char * tags;
6734 int i;
6735 int level;
6736 unsigned long cu_offset;
6737
6738 external = (DWARF2_External_CompUnit *) start;
6739
6740 compunit.cu_length = BYTE_GET (external->cu_length);
6741 compunit.cu_version = BYTE_GET (external->cu_version);
6742 compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
6743 compunit.cu_pointer_size = BYTE_GET (external->cu_pointer_size);
6744
6745 tags = start + sizeof (* external);
6746 cu_offset = start - section_begin;
6747 start += compunit.cu_length + sizeof (external->cu_length);
6748
6749 printf (_(" Compilation Unit @ %lx:\n"), cu_offset);
6750 printf (_(" Length: %ld\n"), compunit.cu_length);
6751 printf (_(" Version: %d\n"), compunit.cu_version);
6752 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
6753 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
6754
6755 if (compunit.cu_version != 2)
6756 {
6757 warn (_("Only version 2 DWARF debug information is currently supported.\n"));
6758 continue;
6759 }
6760
6761 if (first_abbrev != NULL)
6762 free_abbrevs ();
6763
6764 /* Read in the abbrevs used by this compilation unit. */
6765
6766 {
6767 Elf32_Internal_Shdr * sec;
6768 unsigned char * begin;
6769
6770 /* Locate the .debug_abbrev section and process it. */
6771 for (i = 0, sec = section_headers;
6772 i < elf_header.e_shnum;
6773 i ++, sec ++)
6774 if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
6775 break;
6776
6777 if (i == -1 || sec->sh_size == 0)
6778 {
6779 warn (_("Unable to locate .debug_abbrev section!\n"));
6780 return 0;
6781 }
6782
6783 GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, unsigned char *,
6784 "debug_abbrev section data");
6785
6786 process_abbrev_section (begin + compunit.cu_abbrev_offset,
6787 begin + sec->sh_size);
6788
6789 free (begin);
6790 }
6791
6792 level = 0;
6793 while (tags < start)
6794 {
6795 int bytes_read;
6796 unsigned long abbrev_number;
6797 abbrev_entry * entry;
6798 abbrev_attr * attr;
6799
6800 abbrev_number = read_leb128 (tags, & bytes_read, 0);
6801 tags += bytes_read;
6802
6803 /* A null DIE marks the end of a list of children. */
6804 if (abbrev_number == 0)
6805 {
6806 --level;
6807 continue;
6808 }
6809
6810 /* Scan through the abbreviation list until we reach the
6811 correct entry. */
6812 for (entry = first_abbrev;
6813 entry && entry->entry != abbrev_number;
6814 entry = entry->next)
6815 continue;
6816
6817 if (entry == NULL)
6818 {
6819 warn (_("Unable to locate entry %lu in the abbreviation table\n"),
6820 abbrev_number);
6821 return 0;
6822 }
6823
6824 printf (_(" <%d><%x>: Abbrev Number: %lu (%s)\n"),
6825 level, tags - section_begin - bytes_read,
6826 abbrev_number,
6827 get_TAG_name (entry->tag));
6828
6829 for (attr = entry->first_attr; attr; attr = attr->next)
6830 tags = read_and_display_attr (attr->attribute,
6831 attr->form,
6832 tags, cu_offset,
6833 compunit.cu_pointer_size);
6834
6835 if (entry->children)
6836 ++level;
6837 }
6838 }
6839
6840 printf ("\n");
6841
6842 return 1;
6843 }
6844
6845 static int
6846 display_debug_aranges (section, start, file)
6847 Elf32_Internal_Shdr * section;
6848 unsigned char * start;
6849 FILE * file ATTRIBUTE_UNUSED;
6850 {
6851 unsigned char * end = start + section->sh_size;
6852
6853 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
6854
6855 while (start < end)
6856 {
6857 DWARF2_External_ARange * external;
6858 DWARF2_Internal_ARange arange;
6859 unsigned char * ranges;
6860 unsigned long length;
6861 unsigned long address;
6862 int excess;
6863
6864 external = (DWARF2_External_ARange *) start;
6865
6866 arange.ar_length = BYTE_GET (external->ar_length);
6867 arange.ar_version = BYTE_GET (external->ar_version);
6868 arange.ar_info_offset = BYTE_GET (external->ar_info_offset);
6869 arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
6870 arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
6871
6872 if (arange.ar_version != 2)
6873 {
6874 warn (_("Only DWARF 2 aranges are currently supported.\n"));
6875 break;
6876 }
6877
6878 printf (_(" Length: %ld\n"), arange.ar_length);
6879 printf (_(" Version: %d\n"), arange.ar_version);
6880 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
6881 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
6882 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
6883
6884 printf (_("\n Address Length\n"));
6885
6886 ranges = start + sizeof (* external);
6887
6888 /* Must pad to an alignment boundary that is twice the pointer size. */
6889 excess = sizeof (* external) % (2 * arange.ar_pointer_size);
6890 if (excess)
6891 ranges += (2 * arange.ar_pointer_size) - excess;
6892
6893 for (;;)
6894 {
6895 address = byte_get (ranges, arange.ar_pointer_size);
6896
6897 ranges += arange.ar_pointer_size;
6898
6899 length = byte_get (ranges, arange.ar_pointer_size);
6900
6901 ranges += arange.ar_pointer_size;
6902
6903 /* A pair of zeros marks the end of the list. */
6904 if (address == 0 && length == 0)
6905 break;
6906
6907 printf (" %8.8lx %lu\n", address, length);
6908 }
6909
6910 start += arange.ar_length + sizeof (external->ar_length);
6911 }
6912
6913 printf ("\n");
6914
6915 return 1;
6916 }
6917
6918 typedef struct Frame_Chunk
6919 {
6920 struct Frame_Chunk * next;
6921 unsigned char * chunk_start;
6922 int ncols;
6923 /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */
6924 short int * col_type;
6925 int * col_offset;
6926 char * augmentation;
6927 unsigned int code_factor;
6928 unsigned int data_factor;
6929 unsigned long pc_begin;
6930 unsigned long pc_range;
6931 int cfa_reg;
6932 int cfa_offset;
6933 int ra;
6934 }
6935 Frame_Chunk;
6936
6937 /* A marker for a col_type that means this column was never referenced
6938 in the frame info. */
6939 #define DW_CFA_unreferenced (-1)
6940
6941 static void
6942 frame_need_space (fc, reg)
6943 Frame_Chunk * fc;
6944 int reg;
6945 {
6946 int prev = fc->ncols;
6947
6948 if (reg < fc->ncols)
6949 return;
6950
6951 fc->ncols = reg + 1;
6952 fc->col_type = (short int *) xrealloc (fc->col_type,
6953 fc->ncols * sizeof (short int));
6954 fc->col_offset = (int *) xrealloc (fc->col_offset,
6955 fc->ncols * sizeof (int));
6956
6957 while (prev < fc->ncols)
6958 {
6959 fc->col_type[prev] = DW_CFA_unreferenced;
6960 fc->col_offset[prev] = 0;
6961 prev++;
6962 }
6963 }
6964
6965 static void
6966 frame_display_row (fc, need_col_headers, max_regs)
6967 Frame_Chunk * fc;
6968 int * need_col_headers;
6969 int * max_regs;
6970 {
6971 int r;
6972 char tmp[100];
6973
6974 if (* max_regs < fc->ncols)
6975 * max_regs = fc->ncols;
6976
6977 if (* need_col_headers)
6978 {
6979 * need_col_headers = 0;
6980
6981 printf (" LOC CFA ");
6982
6983 for (r = 0; r < * max_regs; r++)
6984 if (fc->col_type[r] != DW_CFA_unreferenced)
6985 {
6986 if (r == fc->ra)
6987 printf ("ra ");
6988 else
6989 printf ("r%-4d", r);
6990 }
6991
6992 printf ("\n");
6993 }
6994
6995 printf ("%08x ", (unsigned int) fc->pc_begin);
6996 sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
6997 printf ("%-8s ", tmp);
6998
6999 for (r = 0; r < fc->ncols; r++)
7000 {
7001 if (fc->col_type[r] != DW_CFA_unreferenced)
7002 {
7003 switch (fc->col_type[r])
7004 {
7005 case DW_CFA_undefined:
7006 strcpy (tmp, "u");
7007 break;
7008 case DW_CFA_same_value:
7009 strcpy (tmp, "s");
7010 break;
7011 case DW_CFA_offset:
7012 sprintf (tmp, "c%+d", fc->col_offset[r]);
7013 break;
7014 case DW_CFA_register:
7015 sprintf (tmp, "r%d", fc->col_offset[r]);
7016 break;
7017 default:
7018 strcpy (tmp, "n/a");
7019 break;
7020 }
7021 printf ("%-5s", tmp);
7022 }
7023 }
7024 printf ("\n");
7025 }
7026
7027 #define GET(N) byte_get (start, N); start += N
7028 #define LEB() read_leb128 (start, & length_return, 0); start += length_return
7029 #define SLEB() read_leb128 (start, & length_return, 1); start += length_return
7030
7031 static int
7032 display_debug_frames (section, start, file)
7033 Elf32_Internal_Shdr * section;
7034 unsigned char * start;
7035 FILE * file ATTRIBUTE_UNUSED;
7036 {
7037 unsigned char * end = start + section->sh_size;
7038 unsigned char * section_start = start;
7039 Frame_Chunk * chunks = 0;
7040 Frame_Chunk * remembered_state = 0;
7041 Frame_Chunk * rs;
7042 int is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
7043 int length_return;
7044 int max_regs = 0;
7045
7046 printf (_("The section %s contains:\n"), SECTION_NAME (section));
7047
7048 while (start < end)
7049 {
7050 unsigned char * saved_start;
7051 unsigned char * block_end;
7052 unsigned long length;
7053 unsigned long cie_id;
7054 Frame_Chunk * fc;
7055 Frame_Chunk * cie;
7056 int need_col_headers = 1;
7057
7058 saved_start = start;
7059 length = byte_get (start, 4); start += 4;
7060
7061 if (length == 0)
7062 return 1;
7063
7064 block_end = saved_start + length + 4;
7065 cie_id = byte_get (start, 4); start += 4;
7066
7067 printf ("\n%08x %08lx %08lx ", saved_start - section_start, length, cie_id);
7068
7069 if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
7070 {
7071 fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
7072 memset (fc, 0, sizeof (Frame_Chunk));
7073
7074 fc->next = chunks;
7075 chunks = fc;
7076 fc->chunk_start = saved_start;
7077 fc->ncols = 0;
7078 fc->col_type = (short int *) xmalloc (sizeof (short int));
7079 fc->col_offset = (int *) xmalloc (sizeof (int));
7080 frame_need_space (fc, max_regs-1);
7081
7082 start ++; /* version */
7083 fc->augmentation = start;
7084
7085 while (* start)
7086 start++;
7087
7088 start++; /* skip past NUL */
7089
7090 if (fc->augmentation[0] == 'z')
7091 {
7092 int xtra;
7093 fc->code_factor = LEB ();
7094 fc->data_factor = SLEB ();
7095 fc->ra = byte_get (start, 1); start += 1;
7096 xtra = LEB ();
7097 printf ("skipping %d extra bytes\n", xtra);
7098 start += xtra;
7099 }
7100 else if (strcmp (fc->augmentation, "eh") == 0)
7101 {
7102 start += 4;
7103 fc->code_factor = LEB ();
7104 fc->data_factor = SLEB ();
7105 fc->ra = byte_get (start, 1); start += 1;
7106 }
7107 else
7108 {
7109 fc->code_factor = LEB ();
7110 fc->data_factor = SLEB ();
7111 fc->ra = byte_get (start, 1); start += 1;
7112 }
7113 cie = fc;
7114 printf ("CIE \"%s\" cf=%d df=%d ra=%d\n",
7115 fc->augmentation, fc->code_factor, fc->data_factor, fc->ra);
7116
7117 frame_need_space (fc, fc->ra);
7118 }
7119 else
7120 {
7121 unsigned char * look_for;
7122 static Frame_Chunk fde_fc;
7123
7124 fc = & fde_fc;
7125 memset (fc, 0, sizeof (Frame_Chunk));
7126
7127 look_for = is_eh ? start-4-cie_id : (unsigned char *) cie_id;
7128
7129 fc->pc_begin = byte_get (start, 4); start += 4;
7130 fc->pc_range = byte_get (start, 4); start += 4;
7131
7132 for (cie=chunks; cie && (cie->chunk_start != look_for); cie = cie->next);
7133 if (!cie)
7134 {
7135 warn ("Invalid CIE pointer %08x in FDE at %08x\n", cie_id, saved_start);
7136 start = block_end;
7137 fc->ncols = 0;
7138 fc->col_type = (short int *) xmalloc (sizeof (short int));
7139 fc->col_offset = (int *) xmalloc (sizeof (int));
7140 frame_need_space (fc, max_regs - 1);
7141 cie = fc;
7142 fc->augmentation = "";
7143 }
7144 else
7145 {
7146 fc->ncols = cie->ncols;
7147 fc->col_type = (short int *) xmalloc (fc->ncols * sizeof (short int));
7148 fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
7149 memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
7150 memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
7151 fc->augmentation = cie->augmentation;
7152 fc->code_factor = cie->code_factor;
7153 fc->data_factor = cie->data_factor;
7154 fc->cfa_reg = cie->cfa_reg;
7155 fc->cfa_offset = cie->cfa_offset;
7156 fc->ra = cie->ra;
7157 frame_need_space (fc, max_regs-1);
7158 }
7159
7160 if (cie->augmentation[0] == 'z')
7161 {
7162 unsigned long l = LEB ();
7163 start += l;
7164 }
7165
7166 printf ("FDE cie=%08x pc=%08lx..%08lx\n",
7167 cie->chunk_start-section_start, fc->pc_begin,
7168 fc->pc_begin + fc->pc_range);
7169 }
7170
7171 /* At this point, fc is the current chunk, cie (if any) is set, and we're
7172 about to interpret instructions for the chunk. */
7173
7174 /* This exists for readelf maintainers. */
7175 #define FDEBUG 0
7176
7177 {
7178 /* Start by making a pass over the chunk, allocating storage
7179 and taking note of what registers are used. */
7180 unsigned char * tmp = start;
7181
7182 while (start < block_end)
7183 {
7184 unsigned op, opa;
7185 unsigned long reg;
7186 bfd_vma vma;
7187
7188 op = * start ++;
7189 opa = op & 0x3f;
7190 if (op & 0xc0)
7191 op &= 0xc0;
7192
7193 /* Warning: if you add any more cases to this switch, be
7194 sure to add them to the corresponding switch below. */
7195 switch (op)
7196 {
7197 case DW_CFA_advance_loc:
7198 break;
7199 case DW_CFA_offset:
7200 LEB ();
7201 frame_need_space (fc, opa);
7202 fc->col_type[opa] = DW_CFA_undefined;
7203 break;
7204 case DW_CFA_restore:
7205 frame_need_space (fc, opa);
7206 fc->col_type[opa] = DW_CFA_undefined;
7207 break;
7208 case DW_CFA_set_loc:
7209 start += sizeof (vma);
7210 break;
7211 case DW_CFA_advance_loc1:
7212 start += 1;
7213 break;
7214 case DW_CFA_advance_loc2:
7215 start += 2;
7216 break;
7217 case DW_CFA_advance_loc4:
7218 start += 4;
7219 break;
7220 case DW_CFA_offset_extended:
7221 reg = LEB (); LEB ();
7222 frame_need_space (fc, reg);
7223 fc->col_type[reg] = DW_CFA_undefined;
7224 break;
7225 case DW_CFA_restore_extended:
7226 reg = LEB ();
7227 frame_need_space (fc, reg);
7228 fc->col_type[reg] = DW_CFA_undefined;
7229 break;
7230 case DW_CFA_undefined:
7231 reg = LEB ();
7232 frame_need_space (fc, reg);
7233 fc->col_type[reg] = DW_CFA_undefined;
7234 break;
7235 case DW_CFA_same_value:
7236 reg = LEB ();
7237 frame_need_space (fc, reg);
7238 fc->col_type[reg] = DW_CFA_undefined;
7239 break;
7240 case DW_CFA_register:
7241 reg = LEB (); LEB ();
7242 frame_need_space (fc, reg);
7243 fc->col_type[reg] = DW_CFA_undefined;
7244 break;
7245 case DW_CFA_def_cfa:
7246 LEB (); LEB ();
7247 break;
7248 case DW_CFA_def_cfa_register:
7249 LEB ();
7250 break;
7251 case DW_CFA_def_cfa_offset:
7252 LEB ();
7253 break;
7254 #ifndef DW_CFA_GNU_args_size
7255 #define DW_CFA_GNU_args_size 0x2e
7256 #endif
7257 case DW_CFA_GNU_args_size:
7258 LEB ();
7259 break;
7260 #ifndef DW_CFA_GNU_negative_offset_extended
7261 #define DW_CFA_GNU_negative_offset_extended 0x2f
7262 #endif
7263 case DW_CFA_GNU_negative_offset_extended:
7264 reg = LEB (); LEB ();
7265 frame_need_space (fc, reg);
7266 fc->col_type[reg] = DW_CFA_undefined;
7267
7268 default:
7269 break;
7270 }
7271 }
7272 start = tmp;
7273 }
7274
7275 /* Now we know what registers are used, make a second pass over
7276 the chunk, this time actually printing out the info. */
7277
7278 while (start < block_end)
7279 {
7280 unsigned op, opa;
7281 unsigned long ul, reg, roffs;
7282 long l, ofs;
7283 bfd_vma vma;
7284
7285 op = * start ++;
7286 opa = op & 0x3f;
7287 if (op & 0xc0)
7288 op &= 0xc0;
7289
7290 /* Warning: if you add any more cases to this switch, be
7291 sure to add them to the corresponding switch above. */
7292 switch (op)
7293 {
7294 case DW_CFA_advance_loc:
7295 frame_display_row (fc, &need_col_headers, &max_regs);
7296 #if FDEBUG
7297 printf (" DW_CFA_advance_loc: %08x = %08x + %d*%d\n",
7298 fc->pc_begin + opa * fc->code_factor, fc->pc_begin, opa, fc->code_factor);
7299 #endif
7300 fc->pc_begin += opa * fc->code_factor;
7301 break;
7302
7303 case DW_CFA_offset:
7304 roffs = LEB ();
7305 #if FDEBUG
7306 printf (" DW_CFA_offset: r%d = cfa[%d*%d]\n", opa, roffs, fc->data_factor);
7307 #endif
7308 fc->col_type[opa] = DW_CFA_offset;
7309 fc->col_offset[opa] = roffs * fc->data_factor;
7310 break;
7311
7312 case DW_CFA_restore:
7313 #if FDEBUG
7314 printf (" DW_CFA_restore: r%d\n", opa);
7315 #endif
7316 fc->col_type[opa] = cie->col_type[opa];
7317 fc->col_offset[opa] = cie->col_offset[opa];
7318 break;
7319
7320 case DW_CFA_set_loc:
7321 frame_display_row (fc, &need_col_headers, &max_regs);
7322 vma = byte_get (start, sizeof (vma)); start += sizeof (vma);
7323 #if FDEBUG
7324 printf (" DW_CFA_set_loc: %08x\n", vma);
7325 #endif
7326 fc->pc_begin = vma;
7327 break;
7328
7329 case DW_CFA_advance_loc1:
7330 frame_display_row (fc, &need_col_headers, &max_regs);
7331 ofs = byte_get (start, 1); start += 1;
7332 #if FDEBUG
7333 printf (" DW_CFA_advance_loc1: %08x = %08x + %d*%d\n",
7334 fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
7335 #endif
7336 fc->pc_begin += ofs * fc->code_factor;
7337 break;
7338
7339 case DW_CFA_advance_loc2:
7340 frame_display_row (fc, &need_col_headers, &max_regs);
7341 ofs = byte_get (start, 2); start += 2;
7342 #if FDEBUG
7343 printf (" DW_CFA_advance_loc2: %08x = %08x + %d*%d\n",
7344 fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
7345 #endif
7346 fc->pc_begin += ofs * fc->code_factor;
7347 break;
7348
7349 case DW_CFA_advance_loc4:
7350 frame_display_row (fc, &need_col_headers, &max_regs);
7351 ofs = byte_get (start, 4); start += 4;
7352 #if FDEBUG
7353 printf (" DW_CFA_advance_loc4: %08x = %08x + %d*%d\n",
7354 fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
7355 #endif
7356 fc->pc_begin += ofs * fc->code_factor;
7357 break;
7358
7359 case DW_CFA_offset_extended:
7360 reg = LEB ();
7361 roffs = LEB ();
7362 #if FDEBUG
7363 printf (" DW_CFA_offset_extended: r%d = cfa[%d*%d]\n", reg, roffs, fc->data_factor);
7364 #endif
7365 fc->col_type[reg] = DW_CFA_offset;
7366 fc->col_offset[reg] = roffs * fc->data_factor;
7367 break;
7368
7369 case DW_CFA_restore_extended:
7370 reg = LEB ();
7371 #if FDEBUG
7372 printf (" DW_CFA_restore_extended: r%d\n", reg);
7373 #endif
7374 fc->col_type[reg] = cie->col_type[reg];
7375 fc->col_offset[reg] = cie->col_offset[reg];
7376 break;
7377
7378 case DW_CFA_undefined:
7379 reg = LEB ();
7380 #if FDEBUG
7381 printf (" DW_CFA_undefined: r%d\n", reg);
7382 #endif
7383 fc->col_type[reg] = DW_CFA_undefined;
7384 fc->col_offset[reg] = 0;
7385 break;
7386
7387 case DW_CFA_same_value:
7388 reg = LEB ();
7389 #if FDEBUG
7390 printf (" DW_CFA_same_value: r%d\n", reg);
7391 #endif
7392 fc->col_type[reg] = DW_CFA_same_value;
7393 fc->col_offset[reg] = 0;
7394 break;
7395
7396 case DW_CFA_register:
7397 reg = LEB ();
7398 roffs = LEB ();
7399 #if FDEBUG
7400 printf (" DW_CFA_register: r%d\n", reg);
7401 #endif
7402 fc->col_type[reg] = DW_CFA_register;
7403 fc->col_offset[reg] = roffs;
7404 break;
7405
7406 case DW_CFA_remember_state:
7407 #if FDEBUG
7408 printf (" DW_CFA_remember_state\n");
7409 #endif
7410 rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
7411 rs->ncols = fc->ncols;
7412 rs->col_type = (short int *) xmalloc (rs->ncols * sizeof (short int));
7413 rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
7414 memcpy (rs->col_type, fc->col_type, rs->ncols);
7415 memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
7416 rs->next = remembered_state;
7417 remembered_state = rs;
7418 break;
7419
7420 case DW_CFA_restore_state:
7421 #if FDEBUG
7422 printf (" DW_CFA_restore_state\n");
7423 #endif
7424 rs = remembered_state;
7425 remembered_state = rs->next;
7426 frame_need_space (fc, rs->ncols-1);
7427 memcpy (fc->col_type, rs->col_type, rs->ncols);
7428 memcpy (fc->col_offset, rs->col_offset, rs->ncols * sizeof (int));
7429 free (rs->col_type);
7430 free (rs->col_offset);
7431 free (rs);
7432 break;
7433
7434 case DW_CFA_def_cfa:
7435 fc->cfa_reg = LEB ();
7436 fc->cfa_offset = LEB ();
7437 #if FDEBUG
7438 printf (" DW_CFA_def_cfa: reg %d ofs %d\n", fc->cfa_reg, fc->cfa_offset);
7439 #endif
7440 break;
7441
7442 case DW_CFA_def_cfa_register:
7443 fc->cfa_reg = LEB ();
7444 #if FDEBUG
7445 printf (" DW_CFA_def_cfa_reg: %d\n", fc->cfa_reg);
7446 #endif
7447 break;
7448
7449 case DW_CFA_def_cfa_offset:
7450 fc->cfa_offset = LEB ();
7451 #if FDEBUG
7452 printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
7453 #endif
7454 break;
7455
7456 case DW_CFA_nop:
7457 #if FDEBUG
7458 printf (" DW_CFA_nop\n");
7459 #endif
7460 break;
7461
7462 #ifndef DW_CFA_GNU_window_save
7463 #define DW_CFA_GNU_window_save 0x2d
7464 #endif
7465 case DW_CFA_GNU_window_save:
7466 #if FDEBUG
7467 printf (" DW_CFA_GNU_window_save\n");
7468 #endif
7469 break;
7470
7471 #ifndef DW_CFA_GNU_args_size
7472 #define DW_CFA_GNU_args_size 0x2e
7473 #endif
7474 case DW_CFA_GNU_args_size:
7475 ul = LEB ();
7476 #if FDEBUG
7477 printf (" DW_CFA_GNU_args_size: %d\n", ul);
7478 #endif
7479 break;
7480
7481 #ifndef DW_CFA_GNU_negative_offset_extended
7482 #define DW_CFA_GNU_negative_offset_extended 0x2f
7483 #endif
7484 case DW_CFA_GNU_negative_offset_extended:
7485 reg = LEB ();
7486 l = - LEB ();
7487 frame_need_space (fc, reg);
7488 #if FDEBUG
7489 printf (" DW_CFA_GNU_negative_offset_extended: r%d = cfa[%d*%d]\n", reg, l, fc->data_factor);
7490 #endif
7491 fc->col_type[reg] = DW_CFA_offset;
7492 fc->col_offset[reg] = l * fc->data_factor;
7493 break;
7494
7495 default:
7496 fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
7497 start = block_end;
7498 }
7499 }
7500
7501 frame_display_row (fc, &need_col_headers, &max_regs);
7502
7503 start = block_end;
7504 }
7505
7506 printf ("\n");
7507
7508 return 1;
7509 }
7510
7511 #undef GET
7512 #undef LEB
7513 #undef SLEB
7514
7515 static int
7516 display_debug_not_supported (section, start, file)
7517 Elf32_Internal_Shdr * section;
7518 unsigned char * start ATTRIBUTE_UNUSED;
7519 FILE * file ATTRIBUTE_UNUSED;
7520 {
7521 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
7522 SECTION_NAME (section));
7523
7524 return 1;
7525 }
7526
7527 /* Pre-scan the .debug_info section to record the size of address.
7528 When dumping the .debug_line, we use that size information, assuming
7529 that all compilation units have the same address size. */
7530 static int
7531 prescan_debug_info (section, start, file)
7532 Elf32_Internal_Shdr * section ATTRIBUTE_UNUSED;
7533 unsigned char * start;
7534 FILE * file ATTRIBUTE_UNUSED;
7535 {
7536 DWARF2_External_CompUnit * external;
7537
7538 external = (DWARF2_External_CompUnit *) start;
7539
7540 debug_line_pointer_size = BYTE_GET (external->cu_pointer_size);
7541 return 0;
7542 }
7543
7544 /* A structure containing the name of a debug section and a pointer
7545 to a function that can decode it. The third field is a prescan
7546 function to be run over the section before displaying any of the
7547 sections. */
7548 struct
7549 {
7550 char * name;
7551 int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
7552 int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
7553 }
7554 debug_displays[] =
7555 {
7556 { ".debug_info", display_debug_info, prescan_debug_info },
7557 { ".debug_abbrev", display_debug_abbrev, NULL },
7558 { ".debug_line", display_debug_lines, NULL },
7559 { ".debug_aranges", display_debug_aranges, NULL },
7560 { ".debug_pubnames", display_debug_pubnames, NULL },
7561 { ".debug_frame", display_debug_frames, NULL },
7562 { ".eh_frame", display_debug_frames, NULL },
7563 { ".debug_macinfo", display_debug_not_supported, NULL },
7564 { ".debug_frame", display_debug_not_supported, NULL },
7565 { ".debug_str", display_debug_not_supported, NULL },
7566 { ".debug_static_func", display_debug_not_supported, NULL },
7567 { ".debug_static_vars", display_debug_not_supported, NULL },
7568 { ".debug_types", display_debug_not_supported, NULL },
7569 { ".debug_weaknames", display_debug_not_supported, NULL }
7570 };
7571
7572 static int
7573 display_debug_section (section, file)
7574 Elf32_Internal_Shdr * section;
7575 FILE * file;
7576 {
7577 char * name = SECTION_NAME (section);
7578 bfd_size_type length;
7579 unsigned char * start;
7580 int i;
7581
7582 length = section->sh_size;
7583 if (length == 0)
7584 {
7585 printf (_("\nSection '%s' has no debugging data.\n"), name);
7586 return 0;
7587 }
7588
7589 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
7590 "debug section data");
7591
7592 /* See if we know how to display the contents of this section. */
7593 if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
7594 name = ".debug_info";
7595
7596 for (i = NUM_ELEM (debug_displays); i--;)
7597 if (strcmp (debug_displays[i].name, name) == 0)
7598 {
7599 debug_displays[i].display (section, start, file);
7600 break;
7601 }
7602
7603 if (i == -1)
7604 printf (_("Unrecognised debug section: %s\n"), name);
7605
7606 free (start);
7607
7608 /* If we loaded in the abbrev section at some point,
7609 we must release it here. */
7610 if (first_abbrev != NULL)
7611 free_abbrevs ();
7612
7613 return 1;
7614 }
7615
7616 static int
7617 process_section_contents (file)
7618 FILE * file;
7619 {
7620 Elf32_Internal_Shdr * section;
7621 unsigned int i;
7622
7623 if (! do_dump)
7624 return 1;
7625
7626 /* Pre-scan the debug sections to find some debug information not
7627 present in some of them. For the .debug_line, we must find out the
7628 size of address (specified in .debug_info and .debug_aranges). */
7629 for (i = 0, section = section_headers;
7630 i < elf_header.e_shnum && i < num_dump_sects;
7631 i ++, section ++)
7632 {
7633 char * name = SECTION_NAME (section);
7634 int j;
7635
7636 if (section->sh_size == 0)
7637 continue;
7638
7639 /* See if there is some pre-scan operation for this section. */
7640 for (j = NUM_ELEM (debug_displays); j--;)
7641 if (strcmp (debug_displays[j].name, name) == 0)
7642 {
7643 if (debug_displays[j].prescan != NULL)
7644 {
7645 bfd_size_type length;
7646 unsigned char * start;
7647
7648 length = section->sh_size;
7649 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
7650 "debug section data");
7651
7652 debug_displays[j].prescan (section, start, file);
7653 free (start);
7654 }
7655
7656 break;
7657 }
7658 }
7659
7660 for (i = 0, section = section_headers;
7661 i < elf_header.e_shnum && i < num_dump_sects;
7662 i ++, section ++)
7663 {
7664 #ifdef SUPPORT_DISASSEMBLY
7665 if (dump_sects[i] & DISASS_DUMP)
7666 disassemble_section (section, file);
7667 #endif
7668 if (dump_sects[i] & HEX_DUMP)
7669 dump_section (section, file);
7670
7671 if (dump_sects[i] & DEBUG_DUMP)
7672 display_debug_section (section, file);
7673 }
7674
7675 if (i < num_dump_sects)
7676 warn (_("Some sections were not dumped because they do not exist!\n"));
7677
7678 return 1;
7679 }
7680
7681 static void
7682 process_mips_fpe_exception (mask)
7683 int mask;
7684 {
7685 if (mask)
7686 {
7687 int first = 1;
7688 if (mask & OEX_FPU_INEX)
7689 fputs ("INEX", stdout), first = 0;
7690 if (mask & OEX_FPU_UFLO)
7691 printf ("%sUFLO", first ? "" : "|"), first = 0;
7692 if (mask & OEX_FPU_OFLO)
7693 printf ("%sOFLO", first ? "" : "|"), first = 0;
7694 if (mask & OEX_FPU_DIV0)
7695 printf ("%sDIV0", first ? "" : "|"), first = 0;
7696 if (mask & OEX_FPU_INVAL)
7697 printf ("%sINVAL", first ? "" : "|");
7698 }
7699 else
7700 fputs ("0", stdout);
7701 }
7702
7703 static int
7704 process_mips_specific (file)
7705 FILE * file;
7706 {
7707 Elf_Internal_Dyn * entry;
7708 size_t liblist_offset = 0;
7709 size_t liblistno = 0;
7710 size_t conflictsno = 0;
7711 size_t options_offset = 0;
7712 size_t conflicts_offset = 0;
7713
7714 /* We have a lot of special sections. Thanks SGI! */
7715 if (dynamic_segment == NULL)
7716 /* No information available. */
7717 return 0;
7718
7719 for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
7720 switch (entry->d_tag)
7721 {
7722 case DT_MIPS_LIBLIST:
7723 liblist_offset = entry->d_un.d_val - loadaddr;
7724 break;
7725 case DT_MIPS_LIBLISTNO:
7726 liblistno = entry->d_un.d_val;
7727 break;
7728 case DT_MIPS_OPTIONS:
7729 options_offset = entry->d_un.d_val - loadaddr;
7730 break;
7731 case DT_MIPS_CONFLICT:
7732 conflicts_offset = entry->d_un.d_val - loadaddr;
7733 break;
7734 case DT_MIPS_CONFLICTNO:
7735 conflictsno = entry->d_un.d_val;
7736 break;
7737 default:
7738 break;
7739 }
7740
7741 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
7742 {
7743 Elf32_External_Lib * elib;
7744 size_t cnt;
7745
7746 GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
7747 elib, Elf32_External_Lib *, "liblist");
7748
7749 printf ("\nSection '.liblist' contains %lu entries:\n",
7750 (unsigned long) liblistno);
7751 fputs (" Library Time Stamp Checksum Version Flags\n",
7752 stdout);
7753
7754 for (cnt = 0; cnt < liblistno; ++cnt)
7755 {
7756 Elf32_Lib liblist;
7757 time_t time;
7758 char timebuf[20];
7759 struct tm * tmp;
7760
7761 liblist.l_name = BYTE_GET (elib[cnt].l_name);
7762 time = BYTE_GET (elib[cnt].l_time_stamp);
7763 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
7764 liblist.l_version = BYTE_GET (elib[cnt].l_version);
7765 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
7766
7767 tmp = gmtime (&time);
7768 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
7769 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7770 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
7771
7772 printf ("%3lu: %-20s %s %#10lx %-7ld", (unsigned long) cnt,
7773 dynamic_strings + liblist.l_name, timebuf,
7774 liblist.l_checksum, liblist.l_version);
7775
7776 if (liblist.l_flags == 0)
7777 puts (" NONE");
7778 else
7779 {
7780 static const struct
7781 {
7782 const char * name;
7783 int bit;
7784 }
7785 l_flags_vals[] =
7786 {
7787 { " EXACT_MATCH", LL_EXACT_MATCH },
7788 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
7789 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
7790 { " EXPORTS", LL_EXPORTS },
7791 { " DELAY_LOAD", LL_DELAY_LOAD },
7792 { " DELTA", LL_DELTA }
7793 };
7794 int flags = liblist.l_flags;
7795 size_t fcnt;
7796
7797 for (fcnt = 0;
7798 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
7799 ++fcnt)
7800 if ((flags & l_flags_vals[fcnt].bit) != 0)
7801 {
7802 fputs (l_flags_vals[fcnt].name, stdout);
7803 flags ^= l_flags_vals[fcnt].bit;
7804 }
7805 if (flags != 0)
7806 printf (" %#x", (unsigned int) flags);
7807
7808 puts ("");
7809 }
7810 }
7811
7812 free (elib);
7813 }
7814
7815 if (options_offset != 0)
7816 {
7817 Elf_External_Options * eopt;
7818 Elf_Internal_Shdr * sect = section_headers;
7819 Elf_Internal_Options * iopt;
7820 Elf_Internal_Options * option;
7821 size_t offset;
7822 int cnt;
7823
7824 /* Find the section header so that we get the size. */
7825 while (sect->sh_type != SHT_MIPS_OPTIONS)
7826 ++ sect;
7827
7828 GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
7829 Elf_External_Options *, "options");
7830
7831 iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
7832 * sizeof (* iopt));
7833 if (iopt == NULL)
7834 {
7835 error (_("Out of memory"));
7836 return 0;
7837 }
7838
7839 offset = cnt = 0;
7840 option = iopt;
7841
7842 while (offset < sect->sh_size)
7843 {
7844 Elf_External_Options * eoption;
7845
7846 eoption = (Elf_External_Options *) ((char *) eopt + offset);
7847
7848 option->kind = BYTE_GET (eoption->kind);
7849 option->size = BYTE_GET (eoption->size);
7850 option->section = BYTE_GET (eoption->section);
7851 option->info = BYTE_GET (eoption->info);
7852
7853 offset += option->size;
7854
7855 ++option;
7856 ++cnt;
7857 }
7858
7859 printf (_("\nSection '%s' contains %d entries:\n"),
7860 SECTION_NAME (sect), cnt);
7861
7862 option = iopt;
7863
7864 while (cnt-- > 0)
7865 {
7866 size_t len;
7867
7868 switch (option->kind)
7869 {
7870 case ODK_NULL:
7871 /* This shouldn't happen. */
7872 printf (" NULL %d %lx", option->section, option->info);
7873 break;
7874 case ODK_REGINFO:
7875 printf (" REGINFO ");
7876 if (elf_header.e_machine == EM_MIPS)
7877 {
7878 /* 32bit form. */
7879 Elf32_External_RegInfo * ereg;
7880 Elf32_RegInfo reginfo;
7881
7882 ereg = (Elf32_External_RegInfo *) (option + 1);
7883 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
7884 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
7885 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
7886 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
7887 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
7888 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
7889
7890 printf ("GPR %08lx GP 0x%lx\n",
7891 reginfo.ri_gprmask,
7892 (unsigned long) reginfo.ri_gp_value);
7893 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
7894 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
7895 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
7896 }
7897 else
7898 {
7899 /* 64 bit form. */
7900 Elf64_External_RegInfo * ereg;
7901 Elf64_Internal_RegInfo reginfo;
7902
7903 ereg = (Elf64_External_RegInfo *) (option + 1);
7904 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
7905 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
7906 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
7907 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
7908 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
7909 reginfo.ri_gp_value = BYTE_GET8 (ereg->ri_gp_value);
7910
7911 printf ("GPR %08lx GP 0x",
7912 reginfo.ri_gprmask);
7913 printf_vma (reginfo.ri_gp_value);
7914 printf ("\n");
7915
7916 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
7917 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
7918 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
7919 }
7920 ++option;
7921 continue;
7922 case ODK_EXCEPTIONS:
7923 fputs (" EXCEPTIONS fpe_min(", stdout);
7924 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
7925 fputs (") fpe_max(", stdout);
7926 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
7927 fputs (")", stdout);
7928
7929 if (option->info & OEX_PAGE0)
7930 fputs (" PAGE0", stdout);
7931 if (option->info & OEX_SMM)
7932 fputs (" SMM", stdout);
7933 if (option->info & OEX_FPDBUG)
7934 fputs (" FPDBUG", stdout);
7935 if (option->info & OEX_DISMISS)
7936 fputs (" DISMISS", stdout);
7937 break;
7938 case ODK_PAD:
7939 fputs (" PAD ", stdout);
7940 if (option->info & OPAD_PREFIX)
7941 fputs (" PREFIX", stdout);
7942 if (option->info & OPAD_POSTFIX)
7943 fputs (" POSTFIX", stdout);
7944 if (option->info & OPAD_SYMBOL)
7945 fputs (" SYMBOL", stdout);
7946 break;
7947 case ODK_HWPATCH:
7948 fputs (" HWPATCH ", stdout);
7949 if (option->info & OHW_R4KEOP)
7950 fputs (" R4KEOP", stdout);
7951 if (option->info & OHW_R8KPFETCH)
7952 fputs (" R8KPFETCH", stdout);
7953 if (option->info & OHW_R5KEOP)
7954 fputs (" R5KEOP", stdout);
7955 if (option->info & OHW_R5KCVTL)
7956 fputs (" R5KCVTL", stdout);
7957 break;
7958 case ODK_FILL:
7959 fputs (" FILL ", stdout);
7960 /* XXX Print content of info word? */
7961 break;
7962 case ODK_TAGS:
7963 fputs (" TAGS ", stdout);
7964 /* XXX Print content of info word? */
7965 break;
7966 case ODK_HWAND:
7967 fputs (" HWAND ", stdout);
7968 if (option->info & OHWA0_R4KEOP_CHECKED)
7969 fputs (" R4KEOP_CHECKED", stdout);
7970 if (option->info & OHWA0_R4KEOP_CLEAN)
7971 fputs (" R4KEOP_CLEAN", stdout);
7972 break;
7973 case ODK_HWOR:
7974 fputs (" HWOR ", stdout);
7975 if (option->info & OHWA0_R4KEOP_CHECKED)
7976 fputs (" R4KEOP_CHECKED", stdout);
7977 if (option->info & OHWA0_R4KEOP_CLEAN)
7978 fputs (" R4KEOP_CLEAN", stdout);
7979 break;
7980 case ODK_GP_GROUP:
7981 printf (" GP_GROUP %#06lx self-contained %#06lx",
7982 option->info & OGP_GROUP,
7983 (option->info & OGP_SELF) >> 16);
7984 break;
7985 case ODK_IDENT:
7986 printf (" IDENT %#06lx self-contained %#06lx",
7987 option->info & OGP_GROUP,
7988 (option->info & OGP_SELF) >> 16);
7989 break;
7990 default:
7991 /* This shouldn't happen. */
7992 printf (" %3d ??? %d %lx",
7993 option->kind, option->section, option->info);
7994 break;
7995 }
7996
7997 len = sizeof (* eopt);
7998 while (len < option->size)
7999 if (((char *) option)[len] >= ' '
8000 && ((char *) option)[len] < 0x7f)
8001 printf ("%c", ((char *) option)[len++]);
8002 else
8003 printf ("\\%03o", ((char *) option)[len++]);
8004
8005 fputs ("\n", stdout);
8006 ++option;
8007 }
8008
8009 free (eopt);
8010 }
8011
8012 if (conflicts_offset != 0 && conflictsno != 0)
8013 {
8014 Elf32_External_Conflict * econf32;
8015 Elf64_External_Conflict * econf64;
8016 Elf32_Conflict * iconf;
8017 size_t cnt;
8018
8019 if (dynamic_symbols == NULL)
8020 {
8021 error (_("conflict list with without table"));
8022 return 0;
8023 }
8024
8025 iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (* iconf));
8026 if (iconf == NULL)
8027 {
8028 error (_("Out of memory"));
8029 return 0;
8030 }
8031
8032 if (is_32bit_elf)
8033 {
8034 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (* econf32),
8035 econf32, Elf32_External_Conflict *, "conflict");
8036
8037 for (cnt = 0; cnt < conflictsno; ++cnt)
8038 iconf[cnt] = BYTE_GET (econf32[cnt]);
8039 }
8040 else
8041 {
8042 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (* econf64),
8043 econf64, Elf64_External_Conflict *, "conflict");
8044
8045 for (cnt = 0; cnt < conflictsno; ++cnt)
8046 iconf[cnt] = BYTE_GET (econf64[cnt]);
8047 }
8048
8049 printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
8050 puts (_(" Num: Index Value Name"));
8051
8052 for (cnt = 0; cnt < conflictsno; ++cnt)
8053 {
8054 Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
8055
8056 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
8057 print_vma (psym->st_value, FULL_HEX);
8058 printf (" %s\n", dynamic_strings + psym->st_name);
8059 }
8060
8061 free (iconf);
8062 }
8063
8064 return 1;
8065 }
8066
8067 static char *
8068 get_note_type (e_type)
8069 unsigned e_type;
8070 {
8071 static char buff[64];
8072
8073 switch (e_type)
8074 {
8075 case NT_PRSTATUS: return _("NT_PRSTATUS (prstatus structure)");
8076 case NT_FPREGSET: return _("NT_FPREGSET (floating point registers)");
8077 case NT_PRPSINFO: return _("NT_PRPSINFO (prpsinfo structure)");
8078 case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
8079 case NT_PRXFPREG: return _("NT_PRXFPREG (user_xfpregs structure)");
8080 case NT_PSTATUS: return _("NT_PSTATUS (pstatus structure)");
8081 case NT_FPREGS: return _("NT_FPREGS (floating point registers)");
8082 case NT_PSINFO: return _("NT_PSINFO (psinfo structure)");
8083 case NT_LWPSTATUS: return _("NT_LWPSTATUS (lwpstatus_t structure)");
8084 case NT_LWPSINFO: return _("NT_LWPSINFO (lwpsinfo_t structure)");
8085 case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus strcuture)");
8086 default:
8087 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
8088 return buff;
8089 }
8090 }
8091
8092 /* Note that by the ELF standard, the name field is already null byte
8093 terminated, and namesz includes the terminating null byte.
8094 I.E. the value of namesz for the name "FSF" is 4.
8095
8096 If the value of namesz is zero, there is no name present. */
8097 static int
8098 process_note (pnote)
8099 Elf32_Internal_Note * pnote;
8100 {
8101 printf (" %s\t\t0x%08lx\t%s\n",
8102 pnote->namesz ? pnote->namedata : "(NONE)",
8103 pnote->descsz, get_note_type (pnote->type));
8104 return 1;
8105 }
8106
8107
8108 static int
8109 process_corefile_note_segment (file, offset, length)
8110 FILE * file;
8111 bfd_vma offset;
8112 bfd_vma length;
8113 {
8114 Elf_External_Note * pnotes;
8115 Elf_External_Note * external;
8116 int res = 1;
8117
8118 if (length <= 0)
8119 return 0;
8120
8121 GET_DATA_ALLOC (offset, length, pnotes, Elf_External_Note *, "notes");
8122
8123 external = pnotes;
8124
8125 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
8126 (unsigned long) offset, (unsigned long) length);
8127 printf (_(" Owner\t\tData size\tDescription\n"));
8128
8129 while (external < (Elf_External_Note *)((char *) pnotes + length))
8130 {
8131 Elf32_Internal_Note inote;
8132 char * temp = NULL;
8133
8134 inote.type = BYTE_GET (external->type);
8135 inote.namesz = BYTE_GET (external->namesz);
8136 inote.namedata = external->name;
8137 inote.descsz = BYTE_GET (external->descsz);
8138 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
8139 inote.descpos = offset + (inote.descdata - (char *) pnotes);
8140
8141 external = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
8142
8143 /* Verify that name is null terminated. It appears that at least
8144 one version of Linux (RedHat 6.0) generates corefiles that don't
8145 comply with the ELF spec by failing to include the null byte in
8146 namesz. */
8147 if (inote.namedata[inote.namesz] != '\0')
8148 {
8149 temp = malloc (inote.namesz + 1);
8150
8151 if (temp == NULL)
8152 {
8153 error (_("Out of memory\n"));
8154 res = 0;
8155 break;
8156 }
8157
8158 strncpy (temp, inote.namedata, inote.namesz);
8159 temp[inote.namesz] = 0;
8160
8161 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
8162 inote.namedata = temp;
8163 }
8164
8165 res &= process_note (& inote);
8166
8167 if (temp != NULL)
8168 {
8169 free (temp);
8170 temp = NULL;
8171 }
8172 }
8173
8174 free (pnotes);
8175
8176 return res;
8177 }
8178
8179 static int
8180 process_corefile_note_segments (file)
8181 FILE * file;
8182 {
8183 Elf_Internal_Phdr * program_headers;
8184 Elf_Internal_Phdr * segment;
8185 unsigned int i;
8186 int res = 1;
8187
8188 program_headers = (Elf_Internal_Phdr *) malloc
8189 (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
8190
8191 if (program_headers == NULL)
8192 {
8193 error (_("Out of memory\n"));
8194 return 0;
8195 }
8196
8197 if (is_32bit_elf)
8198 i = get_32bit_program_headers (file, program_headers);
8199 else
8200 i = get_64bit_program_headers (file, program_headers);
8201
8202 if (i == 0)
8203 {
8204 free (program_headers);
8205 return 0;
8206 }
8207
8208 for (i = 0, segment = program_headers;
8209 i < elf_header.e_phnum;
8210 i ++, segment ++)
8211 {
8212 if (segment->p_type == PT_NOTE)
8213 res &= process_corefile_note_segment (file,
8214 (bfd_vma) segment->p_offset,
8215 (bfd_vma) segment->p_filesz);
8216 }
8217
8218 free (program_headers);
8219
8220 return res;
8221 }
8222
8223 static int
8224 process_corefile_contents (file)
8225 FILE * file;
8226 {
8227 /* If we have not been asked to display the notes then do nothing. */
8228 if (! do_notes)
8229 return 1;
8230
8231 /* If file is not a core file then exit. */
8232 if (elf_header.e_type != ET_CORE)
8233 return 1;
8234
8235 /* No program headers means no NOTE segment. */
8236 if (elf_header.e_phnum == 0)
8237 {
8238 printf (_("No note segments present in the core file.\n"));
8239 return 1;
8240 }
8241
8242 return process_corefile_note_segments (file);
8243 }
8244
8245 static int
8246 process_arch_specific (file)
8247 FILE * file;
8248 {
8249 if (! do_arch)
8250 return 1;
8251
8252 switch (elf_header.e_machine)
8253 {
8254 case EM_MIPS:
8255 case EM_MIPS_RS4_BE:
8256 return process_mips_specific (file);
8257 break;
8258 default:
8259 break;
8260 }
8261 return 1;
8262 }
8263
8264 static int
8265 get_file_header (file)
8266 FILE * file;
8267 {
8268 /* Read in the identity array. */
8269 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
8270 return 0;
8271
8272 /* Determine how to read the rest of the header. */
8273 switch (elf_header.e_ident [EI_DATA])
8274 {
8275 default: /* fall through */
8276 case ELFDATANONE: /* fall through */
8277 case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
8278 case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
8279 }
8280
8281 /* For now we only support 32 bit and 64 bit ELF files. */
8282 is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
8283
8284 /* Read in the rest of the header. */
8285 if (is_32bit_elf)
8286 {
8287 Elf32_External_Ehdr ehdr32;
8288
8289 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
8290 return 0;
8291
8292 elf_header.e_type = BYTE_GET (ehdr32.e_type);
8293 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
8294 elf_header.e_version = BYTE_GET (ehdr32.e_version);
8295 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
8296 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
8297 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
8298 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
8299 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
8300 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
8301 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
8302 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
8303 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
8304 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
8305 }
8306 else
8307 {
8308 Elf64_External_Ehdr ehdr64;
8309
8310 /* If we have been compiled with sizeof (bfd_vma) == 4, then
8311 we will not be able to cope with the 64bit data found in
8312 64 ELF files. Detect this now and abort before we start
8313 overwritting things. */
8314 if (sizeof (bfd_vma) < 8)
8315 {
8316 error (_("This instance of readelf has been built without support for a\n"));
8317 error (_("64 bit data type and so it cannot read 64 bit ELF files.\n"));
8318 return 0;
8319 }
8320
8321 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
8322 return 0;
8323
8324 elf_header.e_type = BYTE_GET (ehdr64.e_type);
8325 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
8326 elf_header.e_version = BYTE_GET (ehdr64.e_version);
8327 elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry);
8328 elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff);
8329 elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff);
8330 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
8331 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
8332 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
8333 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
8334 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
8335 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
8336 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
8337 }
8338
8339 return 1;
8340 }
8341
8342 static void
8343 process_file (file_name)
8344 char * file_name;
8345 {
8346 FILE * file;
8347 struct stat statbuf;
8348 unsigned int i;
8349
8350 if (stat (file_name, & statbuf) < 0)
8351 {
8352 error (_("Cannot stat input file %s.\n"), file_name);
8353 return;
8354 }
8355
8356 file = fopen (file_name, "rb");
8357 if (file == NULL)
8358 {
8359 error (_("Input file %s not found.\n"), file_name);
8360 return;
8361 }
8362
8363 if (! get_file_header (file))
8364 {
8365 error (_("%s: Failed to read file header\n"), file_name);
8366 fclose (file);
8367 return;
8368 }
8369
8370 /* Initialise per file variables. */
8371 for (i = NUM_ELEM (version_info); i--;)
8372 version_info[i] = 0;
8373
8374 for (i = NUM_ELEM (dynamic_info); i--;)
8375 dynamic_info[i] = 0;
8376
8377 /* Process the file. */
8378 if (show_name)
8379 printf (_("\nFile: %s\n"), file_name);
8380
8381 if (! process_file_header ())
8382 {
8383 fclose (file);
8384 return;
8385 }
8386
8387 process_section_headers (file);
8388
8389 process_program_headers (file);
8390
8391 process_dynamic_segment (file);
8392
8393 process_relocs (file);
8394
8395 process_unwind (file);
8396
8397 process_symbol_table (file);
8398
8399 process_syminfo (file);
8400
8401 process_version_sections (file);
8402
8403 process_section_contents (file);
8404
8405 process_corefile_contents (file);
8406
8407 process_arch_specific (file);
8408
8409 fclose (file);
8410
8411 if (section_headers)
8412 {
8413 free (section_headers);
8414 section_headers = NULL;
8415 }
8416
8417 if (string_table)
8418 {
8419 free (string_table);
8420 string_table = NULL;
8421 string_table_length = 0;
8422 }
8423
8424 if (dynamic_strings)
8425 {
8426 free (dynamic_strings);
8427 dynamic_strings = NULL;
8428 }
8429
8430 if (dynamic_symbols)
8431 {
8432 free (dynamic_symbols);
8433 dynamic_symbols = NULL;
8434 num_dynamic_syms = 0;
8435 }
8436
8437 if (dynamic_syminfo)
8438 {
8439 free (dynamic_syminfo);
8440 dynamic_syminfo = NULL;
8441 }
8442 }
8443
8444 #ifdef SUPPORT_DISASSEMBLY
8445 /* Needed by the i386 disassembler. For extra credit, someone could
8446 fix this so that we insert symbolic addresses here, esp for GOT/PLT
8447 symbols */
8448
8449 void
8450 print_address (unsigned int addr, FILE * outfile)
8451 {
8452 fprintf (outfile,"0x%8.8x", addr);
8453 }
8454
8455 /* Needed by the i386 disassembler. */
8456 void
8457 db_task_printsym (unsigned int addr)
8458 {
8459 print_address (addr, stderr);
8460 }
8461 #endif
8462
8463 int
8464 main (argc, argv)
8465 int argc;
8466 char ** argv;
8467 {
8468 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
8469 setlocale (LC_MESSAGES, "");
8470 #endif
8471 bindtextdomain (PACKAGE, LOCALEDIR);
8472 textdomain (PACKAGE);
8473
8474 parse_args (argc, argv);
8475
8476 if (optind < (argc - 1))
8477 show_name = 1;
8478
8479 while (optind < argc)
8480 process_file (argv [optind ++]);
8481
8482 if (dump_sects != NULL)
8483 free (dump_sects);
8484
8485 return 0;
8486 }