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