Add detection of IMB and IMBRange SWIs.
[deliverable/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132
RH
1/* readelf.c -- display contents of an ELF format file
2 Copyright (C) 1998, 1999 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/stat.h>
27#include <stdio.h>
28#include <time.h>
29
19936277
NC
30/* Define BFD64 here, even if our default architecture is 32 bit ELF
31 as this will allow us to read in and parse 64bit and 32bit ELF files. */
32#define BFD64
252b5132
RH
33#include "bfd.h"
34
35#include "elf/common.h"
36#include "elf/external.h"
37#include "elf/internal.h"
38#include "elf/dwarf2.h"
39
40/* The following headers use the elf/reloc-macros.h file to
41 automatically generate relocation recognition functions
42 such as elf_mips_reloc_type() */
43
44#define RELOC_MACROS_GEN_FUNC
45
46#include "elf/i386.h"
47#include "elf/v850.h"
48#include "elf/ppc.h"
49#include "elf/mips.h"
50#include "elf/alpha.h"
51#include "elf/arm.h"
52#include "elf/m68k.h"
53#include "elf/sparc.h"
54#include "elf/m32r.h"
55#include "elf/d10v.h"
56#include "elf/d30v.h"
57#include "elf/sh.h"
58#include "elf/mn10200.h"
59#include "elf/mn10300.h"
60#include "elf/hppa.h"
61#include "elf/arc.h"
62#include "elf/fr30.h"
63#include "elf/mcore.h"
63fcb9e9 64#include "elf/i960.h"
252b5132
RH
65
66#include "bucomm.h"
67#include "getopt.h"
68
69#ifdef ANSI_PROTOTYPES
70#include <stdarg.h>
71#else
72#include <varargs.h>
73#endif
74
75char * program_name = "readelf";
76unsigned int dynamic_addr;
9ea033b2 77bfd_size_type dynamic_size;
252b5132
RH
78unsigned int rela_addr;
79unsigned int rela_size;
80char * dynamic_strings;
81char * string_table;
19936277 82unsigned long num_dynamic_syms;
252b5132
RH
83Elf_Internal_Sym * dynamic_symbols;
84Elf_Internal_Syminfo * dynamic_syminfo;
85unsigned long dynamic_syminfo_offset;
86unsigned int dynamic_syminfo_nent;
87char program_interpreter [64];
88int dynamic_info[DT_JMPREL + 1];
89int version_info[16];
90int loadaddr = 0;
91Elf_Internal_Ehdr elf_header;
92Elf_Internal_Shdr * section_headers;
93Elf_Internal_Dyn * dynamic_segment;
94int show_name;
95int do_dynamic;
96int do_syms;
97int do_reloc;
98int do_sections;
99int do_segments;
100int do_using_dynamic;
101int do_header;
102int do_dump;
103int do_version;
104int do_histogram;
105int do_debugging;
106int do_debug_info;
107int do_debug_abbrevs;
108int do_debug_lines;
109int do_debug_pubnames;
110int do_debug_aranges;
9ea033b2 111int is_32bit_elf;
252b5132
RH
112
113/* A dynamic array of flags indicating which sections require dumping. */
114char * dump_sects = NULL;
115unsigned int num_dump_sects = 0;
116
117#define HEX_DUMP (1 << 0)
118#define DISASS_DUMP (1 << 1)
119#define DEBUG_DUMP (1 << 2)
120
121/* Forward declarations for dumb compilers. */
9ea033b2
NC
122static bfd_vma (* byte_get) PARAMS ((unsigned char *, int));
123static bfd_vma byte_get_little_endian PARAMS ((unsigned char *, int));
124static bfd_vma byte_get_big_endian PARAMS ((unsigned char *, int));
125static const char * get_mips_dynamic_type PARAMS ((unsigned long));
126static const char * get_dynamic_type PARAMS ((unsigned long));
19936277 127static int dump_relocations PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, unsigned long, char *, int));
9ea033b2
NC
128static char * get_file_type PARAMS ((unsigned));
129static char * get_machine_name PARAMS ((unsigned));
130static char * get_machine_flags PARAMS ((unsigned, unsigned));
131static const char * get_mips_segment_type PARAMS ((unsigned long));
132static const char * get_segment_type PARAMS ((unsigned long));
133static const char * get_mips_section_type_name PARAMS ((unsigned int));
134static const char * get_section_type_name PARAMS ((unsigned int));
135static char * get_symbol_binding PARAMS ((unsigned int));
136static char * get_symbol_type PARAMS ((unsigned int));
252b5132 137static void usage PARAMS ((void));
9ea033b2 138static void parse_args PARAMS ((int, char **));
252b5132
RH
139static int process_file_header PARAMS ((void));
140static int process_program_headers PARAMS ((FILE *));
141static int process_section_headers PARAMS ((FILE *));
9ea033b2 142static void dynamic_segment_mips_val PARAMS ((Elf_Internal_Dyn *));
252b5132
RH
143static int process_dynamic_segment PARAMS ((FILE *));
144static int process_symbol_table PARAMS ((FILE *));
145static int process_section_contents PARAMS ((FILE *));
9ea033b2 146static void process_file PARAMS ((char *));
252b5132
RH
147static int process_relocs PARAMS ((FILE *));
148static int process_version_sections PARAMS ((FILE *));
9ea033b2
NC
149static char * get_ver_flags PARAMS ((unsigned int));
150static char * get_symbol_index_type PARAMS ((unsigned int));
151static int get_32bit_section_headers PARAMS ((FILE *));
152static int get_64bit_section_headers PARAMS ((FILE *));
153static int get_32bit_program_headers PARAMS ((FILE *, Elf_Internal_Phdr *));
154static int get_64bit_program_headers PARAMS ((FILE *, Elf_Internal_Phdr *));
155static int get_file_header PARAMS ((FILE *));
156static Elf_Internal_Sym * get_32bit_elf_symbols PARAMS ((FILE *, unsigned long, unsigned long));
157static Elf_Internal_Sym * get_64bit_elf_symbols PARAMS ((FILE *, unsigned long, unsigned long));
158static int * get_dynamic_data PARAMS ((FILE *, unsigned int));
159static int get_32bit_dynamic_segment PARAMS ((FILE *));
160static int get_64bit_dynamic_segment PARAMS ((FILE *));
252b5132
RH
161#ifdef SUPPORT_DISASSEMBLY
162static int disassemble_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
163#endif
164static int dump_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
165static int display_debug_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
166static int display_debug_info PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
167static int display_debug_not_supported PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
168static int display_debug_lines PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
169static int display_debug_abbrev PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
170static int display_debug_aranges PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
171static unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *));
172static unsigned long read_leb128 PARAMS ((unsigned char *, int *, int));
173static int process_extended_line_op PARAMS ((unsigned char *, int));
174static void reset_state_machine PARAMS ((int));
175static char * get_TAG_name PARAMS ((unsigned long));
176static char * get_AT_name PARAMS ((unsigned long));
177static char * get_FORM_name PARAMS ((unsigned long));
178static void free_abbrevs PARAMS ((void));
179static void add_abbrev PARAMS ((unsigned long, unsigned long, int));
180static void add_abbrev_attr PARAMS ((unsigned long, unsigned long));
181static unsigned char * read_and_display_attr PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long));
182static unsigned char * display_block PARAMS ((unsigned char *, unsigned long));
183static void decode_location_expression PARAMS ((unsigned char *, unsigned int));
184static void request_dump PARAMS ((unsigned int, char));
185static const char * get_elf_class PARAMS ((unsigned char));
186static const char * get_data_encoding PARAMS ((unsigned char));
187static const char * get_osabi_name PARAMS ((unsigned char));
9c19a809 188static int guess_is_rela PARAMS ((unsigned long));
252b5132
RH
189
190typedef int Elf32_Word;
191
9c19a809
NC
192#ifndef TRUE
193#define TRUE 1
194#define FALSE 0
195#endif
196#define UNKNOWN -1
197
252b5132
RH
198#define SECTION_NAME(X) (string_table + (X)->sh_name)
199
200#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
201
202#define BYTE_GET(field) byte_get (field, sizeof (field))
9ea033b2 203#define BYTE_GET8(field) byte_get (field, -8)
252b5132
RH
204
205#define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
206
207#define GET_DATA_ALLOC(offset, size, var, type, reason) \
208 if (fseek (file, offset, SEEK_SET)) \
209 { \
210 error (_("Unable to seek to start of %s at %x\n"), reason, offset); \
211 return 0; \
212 } \
213 \
214 var = (type) malloc (size); \
215 \
216 if (var == NULL) \
217 { \
218 error (_("Out of memory allocating %d bytes for %s\n"), size, reason); \
219 return 0; \
220 } \
221 \
222 if (fread (var, size, 1, file) != 1) \
223 { \
224 error (_("Unable to read in %d bytes of %s\n"), size, reason); \
225 free (var); \
226 var = NULL; \
227 return 0; \
228 }
229
230
231#define GET_DATA(offset, var, reason) \
232 if (fseek (file, offset, SEEK_SET)) \
233 { \
234 error (_("Unable to seek to %x for %s\n"), offset, reason); \
235 return 0; \
236 } \
237 else if (fread (& var, sizeof (var), 1, file) != 1) \
238 { \
239 error (_("Unable to read data at %x for %s\n"), offset, reason); \
240 return 0; \
241 }
242
9ea033b2
NC
243#define GET_ELF_SYMBOLS(file, offset, size) \
244 (is_32bit_elf ? get_32bit_elf_symbols (file, offset, size) \
245 : get_64bit_elf_symbols (file, offset, size))
246
247
252b5132
RH
248#ifdef ANSI_PROTOTYPES
249static void
250error (const char * message, ...)
251{
252 va_list args;
253
254 fprintf (stderr, _("%s: Error: "), program_name);
255 va_start (args, message);
256 vfprintf (stderr, message, args);
257 va_end (args);
258 return;
259}
260
261static void
262warn (const char * message, ...)
263{
264 va_list args;
265
266 fprintf (stderr, _("%s: Warning: "), program_name);
267 va_start (args, message);
268 vfprintf (stderr, message, args);
269 va_end (args);
270 return;
271}
272#else
273static void
274error (va_alist)
275 va_dcl
276{
277 char * message;
278 va_list args;
279
280 fprintf (stderr, _("%s: Error: "), program_name);
281 va_start (args);
282 message = va_arg (args, char *);
283 vfprintf (stderr, message, args);
284 va_end (args);
285 return;
286}
287
288static void
289warn (va_alist)
290 va_dcl
291{
292 char * message;
293 va_list args;
294
295 fprintf (stderr, _("%s: Warning: "), program_name);
296 va_start (args);
297 message = va_arg (args, char *);
298 vfprintf (stderr, message, args);
299 va_end (args);
300 return;
301}
302#endif
303
9ea033b2 304static bfd_vma
252b5132
RH
305byte_get_little_endian (field, size)
306 unsigned char * field;
307 int size;
308{
309 switch (size)
310 {
311 case 1:
312 return * field;
313
314 case 2:
315 return ((unsigned int) (field [0]))
316 | (((unsigned int) (field [1])) << 8);
317
9ea033b2
NC
318 case 8:
319 /* We want to extract data from an 8 byte wide field and
320 place it into a 4 byte wide field. Since this is a little
321 endian source we can juts use the 4 byte extraction code. */
322 /* Fall through. */
252b5132
RH
323 case 4:
324 return ((unsigned long) (field [0]))
325 | (((unsigned long) (field [1])) << 8)
326 | (((unsigned long) (field [2])) << 16)
327 | (((unsigned long) (field [3])) << 24);
328
9ea033b2
NC
329 case -8:
330 /* This is a special case, generated by the BYTE_GET8 macro.
331 It means that we are loading an 8 byte value from a field
332 in an external structure into an 8 byte value in a field
333 in an internal strcuture. */
334 return ((bfd_vma) (field [0]))
335 | (((bfd_vma) (field [1])) << 8)
336 | (((bfd_vma) (field [2])) << 16)
337 | (((bfd_vma) (field [3])) << 24)
338 | (((bfd_vma) (field [4])) << 32)
339 | (((bfd_vma) (field [5])) << 40)
340 | (((bfd_vma) (field [6])) << 48)
341 | (((bfd_vma) (field [7])) << 56);
342
252b5132
RH
343 default:
344 error (_("Unhandled data length: %d\n"), size);
9ea033b2 345 abort ();
252b5132
RH
346 }
347}
348
9ea033b2 349static bfd_vma
252b5132
RH
350byte_get_big_endian (field, size)
351 unsigned char * field;
352 int size;
353{
354 switch (size)
355 {
356 case 1:
357 return * field;
358
359 case 2:
360 return ((unsigned int) (field [1])) | (((int) (field [0])) << 8);
361
362 case 4:
363 return ((unsigned long) (field [3]))
364 | (((unsigned long) (field [2])) << 8)
365 | (((unsigned long) (field [1])) << 16)
366 | (((unsigned long) (field [0])) << 24);
367
9ea033b2
NC
368 case 8:
369 /* Although we are extracing data from an 8 byte wide field, we
370 are returning only 4 bytes of data. */
371 return ((unsigned long) (field [7]))
372 | (((unsigned long) (field [6])) << 8)
373 | (((unsigned long) (field [5])) << 16)
374 | (((unsigned long) (field [4])) << 24);
375
376 case -8:
377 /* This is a special case, generated by the BYTE_GET8 macro.
378 It means that we are loading an 8 byte value from a field
379 in an external structure into an 8 byte value in a field
380 in an internal strcuture. */
381 return ((bfd_vma) (field [7]))
382 | (((bfd_vma) (field [6])) << 8)
383 | (((bfd_vma) (field [5])) << 16)
384 | (((bfd_vma) (field [4])) << 24)
385 | (((bfd_vma) (field [3])) << 32)
386 | (((bfd_vma) (field [2])) << 40)
387 | (((bfd_vma) (field [1])) << 48)
388 | (((bfd_vma) (field [0])) << 56);
389
252b5132
RH
390 default:
391 error (_("Unhandled data length: %d\n"), size);
9ea033b2 392 abort ();
252b5132
RH
393 }
394}
395
396
9c19a809 397/* Guess the relocation sized based on the sized commonly used by the specific machine. */
252b5132 398static int
9c19a809
NC
399guess_is_rela (e_machine)
400 unsigned long e_machine;
252b5132 401{
9c19a809 402 switch (e_machine)
252b5132
RH
403 {
404 /* Targets that use REL relocations. */
405 case EM_ARM:
406 case EM_386:
407 case EM_486:
63fcb9e9 408 case EM_960:
252b5132
RH
409 case EM_CYGNUS_M32R:
410 case EM_CYGNUS_D10V:
411 case EM_MIPS:
412 case EM_MIPS_RS4_BE:
9c19a809
NC
413 return FALSE;
414
252b5132
RH
415 /* Targets that use RELA relocations. */
416 case EM_68K:
417 case EM_SPARC:
418 case EM_PPC:
419 case EM_CYGNUS_V850:
420 case EM_CYGNUS_D30V:
421 case EM_CYGNUS_MN10200:
422 case EM_CYGNUS_MN10300:
423 case EM_CYGNUS_FR30:
424 case EM_SH:
425 case EM_ALPHA:
426 case EM_MCORE:
9c19a809
NC
427 return TRUE;
428
429 default:
430 warn (_("Don't know about relocations on this machine architecture\n"));
431 return FALSE;
432 }
433}
252b5132 434
9ea033b2 435/* Display the contents of the relocation data found at the specified offset. */
9c19a809 436static int
19936277 437dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
9ea033b2
NC
438 FILE * file;
439 unsigned long rel_offset;
440 unsigned long rel_size;
441 Elf_Internal_Sym * symtab;
19936277 442 unsigned long nsyms;
9ea033b2
NC
443 char * strtab;
444 int is_rela;
9c19a809
NC
445{
446 unsigned int i;
447 Elf_Internal_Rel * rels;
448 Elf_Internal_Rela * relas;
252b5132 449
9c19a809
NC
450
451 if (is_rela == UNKNOWN)
452 is_rela = guess_is_rela (elf_header.e_machine);
252b5132 453
9c19a809
NC
454 if (is_rela)
455 {
9ea033b2
NC
456 if (is_32bit_elf)
457 {
458 Elf32_External_Rela * erelas;
459
460 GET_DATA_ALLOC (rel_offset, rel_size, erelas,
461 Elf32_External_Rela *, "relocs");
462
463 rel_size = rel_size / sizeof (Elf32_External_Rela);
464
465 relas = (Elf_Internal_Rela *)
466 malloc (rel_size * sizeof (Elf_Internal_Rela));
9c19a809 467
9ea033b2
NC
468 if (relas == NULL)
469 {
470 error(_("out of memory parsing relocs"));
471 return 0;
472 }
473
474 for (i = 0; i < rel_size; i++)
475 {
476 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
477 relas[i].r_info = BYTE_GET (erelas[i].r_info);
478 relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
479 }
9c19a809 480
9ea033b2 481 free (erelas);
9c19a809 482
9ea033b2 483 rels = (Elf_Internal_Rel *) relas;
9c19a809 484 }
9ea033b2 485 else
9c19a809 486 {
9ea033b2
NC
487 Elf64_External_Rela * erelas;
488
489 GET_DATA_ALLOC (rel_offset, rel_size, erelas,
490 Elf64_External_Rela *, "relocs");
491
492 rel_size = rel_size / sizeof (Elf64_External_Rela);
493
494 relas = (Elf_Internal_Rela *)
495 malloc (rel_size * sizeof (Elf_Internal_Rela));
496
497 if (relas == NULL)
498 {
499 error(_("out of memory parsing relocs"));
500 return 0;
501 }
502
503 for (i = 0; i < rel_size; i++)
504 {
505 relas[i].r_offset = BYTE_GET8 (erelas[i].r_offset);
506 relas[i].r_info = BYTE_GET8 (erelas[i].r_info);
507 relas[i].r_addend = BYTE_GET8 (erelas[i].r_addend);
508 }
9c19a809 509
9ea033b2 510 free (erelas);
9c19a809 511
9ea033b2
NC
512 rels = (Elf_Internal_Rel *) relas;
513 }
9c19a809
NC
514 }
515 else
516 {
9ea033b2 517 if (is_32bit_elf)
9c19a809 518 {
9ea033b2
NC
519 Elf32_External_Rel * erels;
520
521 GET_DATA_ALLOC (rel_offset, rel_size, erels,
522 Elf32_External_Rel *, "relocs");
523
524 rel_size = rel_size / sizeof (Elf32_External_Rel);
525
526 rels = (Elf_Internal_Rel *)
527 malloc (rel_size * sizeof (Elf_Internal_Rel));
528
529 if (rels == NULL)
530 {
531 error(_("out of memory parsing relocs"));
532 return 0;
533 }
534
535 for (i = 0; i < rel_size; i++)
536 {
537 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
538 rels[i].r_info = BYTE_GET (erels[i].r_info);
539 }
540
541 free (erels);
542
543 relas = (Elf_Internal_Rela *) rels;
9c19a809 544 }
9ea033b2 545 else
9c19a809 546 {
9ea033b2
NC
547 Elf64_External_Rel * erels;
548
549 GET_DATA_ALLOC (rel_offset, rel_size, erels,
550 Elf64_External_Rel *, "relocs");
551
552 rel_size = rel_size / sizeof (Elf64_External_Rel);
553
554 rels = (Elf_Internal_Rel *)
555 malloc (rel_size * sizeof (Elf_Internal_Rel));
556
557 if (rels == NULL)
558 {
559 error(_("out of memory parsing relocs"));
560 return 0;
561 }
562
563 for (i = 0; i < rel_size; i++)
564 {
565 rels[i].r_offset = BYTE_GET8 (erels[i].r_offset);
566 rels[i].r_info = BYTE_GET8 (erels[i].r_info);
567 }
568
569 free (erels);
570
571 relas = (Elf_Internal_Rela *) rels;
9c19a809 572 }
252b5132
RH
573 }
574
575 if (is_rela)
576 printf
577 (_(" Offset Info Type Symbol's Value Symbol's Name Addend\n"));
578 else
579 printf
580 (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
581
582 for (i = 0; i < rel_size; i++)
583 {
9ea033b2
NC
584 const char * rtype;
585 bfd_vma offset;
586 bfd_vma info;
587 bfd_vma symtab_index;
588 bfd_vma type;
589
252b5132
RH
590 if (is_rela)
591 {
592 offset = relas [i].r_offset;
593 info = relas [i].r_info;
594 }
595 else
596 {
597 offset = rels [i].r_offset;
598 info = rels [i].r_info;
599 }
9ea033b2
NC
600
601 if (is_32bit_elf)
602 {
603 type = ELF32_R_TYPE (info);
604 symtab_index = ELF32_R_SYM (info);
605 }
606 else
607 {
608 type = ELF64_R_TYPE (info);
609 symtab_index = ELF64_R_SYM (info);
610 }
252b5132 611
9ea033b2
NC
612#ifdef _bfd_int64_low
613 printf (" %8.8lx %5.5lx ", _bfd_int64_low (offset), _bfd_int64_low (info));
614#else
615 printf (" %8.8lx %5.5lx ", offset, info);
616#endif
617
252b5132
RH
618 switch (elf_header.e_machine)
619 {
620 default:
621 rtype = NULL;
622 break;
623
624 case EM_CYGNUS_M32R:
9ea033b2 625 rtype = elf_m32r_reloc_type (type);
252b5132
RH
626 break;
627
628 case EM_386:
629 case EM_486:
9ea033b2 630 rtype = elf_i386_reloc_type (type);
252b5132
RH
631 break;
632
633 case EM_68K:
9ea033b2 634 rtype = elf_m68k_reloc_type (type);
252b5132
RH
635 break;
636
63fcb9e9 637 case EM_960:
9ea033b2 638 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
639 break;
640
9ea033b2
NC
641 case EM_OLD_SPARCV9:
642 case EM_SPARC32PLUS:
643 case EM_SPARCV9:
252b5132 644 case EM_SPARC:
9ea033b2 645 rtype = elf_sparc_reloc_type (type);
252b5132
RH
646 break;
647
648 case EM_CYGNUS_V850:
9ea033b2 649 rtype = v850_reloc_type (type);
252b5132
RH
650 break;
651
652 case EM_CYGNUS_D10V:
9ea033b2 653 rtype = elf_d10v_reloc_type (type);
252b5132
RH
654 break;
655
656 case EM_CYGNUS_D30V:
9ea033b2 657 rtype = elf_d30v_reloc_type (type);
252b5132
RH
658 break;
659
660 case EM_SH:
9ea033b2 661 rtype = elf_sh_reloc_type (type);
252b5132
RH
662 break;
663
664 case EM_CYGNUS_MN10300:
9ea033b2 665 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
666 break;
667
668 case EM_CYGNUS_MN10200:
9ea033b2 669 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
670 break;
671
672 case EM_CYGNUS_FR30:
9ea033b2 673 rtype = elf_fr30_reloc_type (type);
252b5132
RH
674 break;
675
676 case EM_MCORE:
9ea033b2 677 rtype = elf_mcore_reloc_type (type);
252b5132
RH
678 break;
679
680 case EM_PPC:
9ea033b2 681 rtype = elf_ppc_reloc_type (type);
252b5132
RH
682 break;
683
684 case EM_MIPS:
685 case EM_MIPS_RS4_BE:
9ea033b2 686 rtype = elf_mips_reloc_type (type);
252b5132
RH
687 break;
688
689 case EM_ALPHA:
9ea033b2 690 rtype = elf_alpha_reloc_type (type);
252b5132
RH
691 break;
692
693 case EM_ARM:
9ea033b2 694 rtype = elf_arm_reloc_type (type);
252b5132
RH
695 break;
696
697 case EM_CYGNUS_ARC:
9ea033b2 698 rtype = elf_arc_reloc_type (type);
252b5132
RH
699 break;
700
701 case EM_PARISC:
9ea033b2 702 rtype = elf32_hppa_reloc_type (type);
252b5132
RH
703 break;
704 }
705
706 if (rtype == NULL)
9ea033b2
NC
707#ifdef _bfd_int64_low
708 printf (_("unrecognised: %-7lx"), _bfd_int64_low (type));
709#else
710 printf (_("unrecognised: %-7lx"), type);
711#endif
252b5132
RH
712 else
713 printf ("%-21.21s", rtype);
714
19936277 715 if (symtab_index)
252b5132 716 {
19936277
NC
717 if (symtab != NULL)
718 {
719 if (symtab_index >= nsyms)
720 printf (" bad symbol index: %08lx", (unsigned long) symtab_index);
721 else
722 {
723 Elf_Internal_Sym * psym;
724
725 psym = symtab + symtab_index;
726
727 printf (" %08lx ", (unsigned long) psym->st_value);
728
729 if (psym->st_name == 0)
730 printf ("%-25.25s",
731 SECTION_NAME (section_headers + psym->st_shndx));
732 else if (strtab == NULL)
733 printf (_("<string table index %3ld>"), psym->st_name);
734 else
735 printf ("%-25.25s", strtab + psym->st_name);
736
737 if (is_rela)
738 printf (" + %lx", (unsigned long) relas [i].r_addend);
739 }
740 }
252b5132 741 }
1b228002
AS
742 else if (is_rela)
743 printf ("%34c%lx", ' ', (unsigned long) relas[i].r_addend);
252b5132
RH
744
745 putchar ('\n');
746 }
747
748 free (relas);
749
750 return 1;
751}
752
753static const char *
754get_mips_dynamic_type (type)
755 unsigned long type;
756{
757 switch (type)
758 {
759 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
760 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
761 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
762 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
763 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
764 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
765 case DT_MIPS_MSYM: return "MIPS_MSYM";
766 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
767 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
768 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
769 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
770 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
771 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
772 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
773 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
774 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
775 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
776 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
777 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
778 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
779 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
780 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
781 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
782 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
783 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
784 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
785 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
786 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
787 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
788 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
789 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
790 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
791 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
792 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
793 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
794 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
795 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
796 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
797 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
798 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
799 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
800 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
801 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
802 default:
803 return NULL;
804 }
805}
806
807static const char *
808get_dynamic_type (type)
809 unsigned long type;
810{
811 static char buff [32];
812
813 switch (type)
814 {
815 case DT_NULL: return "NULL";
816 case DT_NEEDED: return "NEEDED";
817 case DT_PLTRELSZ: return "PLTRELSZ";
818 case DT_PLTGOT: return "PLTGOT";
819 case DT_HASH: return "HASH";
820 case DT_STRTAB: return "STRTAB";
821 case DT_SYMTAB: return "SYMTAB";
822 case DT_RELA: return "RELA";
823 case DT_RELASZ: return "RELASZ";
824 case DT_RELAENT: return "RELAENT";
825 case DT_STRSZ: return "STRSZ";
826 case DT_SYMENT: return "SYMENT";
827 case DT_INIT: return "INIT";
828 case DT_FINI: return "FINI";
829 case DT_SONAME: return "SONAME";
830 case DT_RPATH: return "RPATH";
831 case DT_SYMBOLIC: return "SYMBOLIC";
832 case DT_REL: return "REL";
833 case DT_RELSZ: return "RELSZ";
834 case DT_RELENT: return "RELENT";
835 case DT_PLTREL: return "PLTREL";
836 case DT_DEBUG: return "DEBUG";
837 case DT_TEXTREL: return "TEXTREL";
838 case DT_JMPREL: return "JMPREL";
839 case DT_BIND_NOW: return "BIND_NOW";
840 case DT_INIT_ARRAY: return "INIT_ARRAY";
841 case DT_FINI_ARRAY: return "FINI_ARRAY";
842 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
843 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
844
845 case DT_PLTPADSZ: return "PLTPADSZ";
846 case DT_MOVEENT: return "MOVEENT";
847 case DT_MOVESZ: return "MOVESZ";
848 case DT_FEATURE_1: return "FEATURE_1";
849 case DT_POSFLAG_1: return "POSFLAG_1";
850 case DT_SYMINSZ: return "SYMINSZ";
851 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
852
853 case DT_ADDRRNGLO: return "ADDRRNGLO";
854 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
855
856 case DT_VERSYM: return "VERSYM";
857
858 case DT_RELACOUNT: return "RELACOUNT";
859 case DT_RELCOUNT: return "RELCOUNT";
860 case DT_FLAGS_1: return "FLAGS_1";
861 case DT_VERDEF: return "VERDEF";
862 case DT_VERDEFNUM: return "VERDEFNUM";
863 case DT_VERNEED: return "VERNEED";
864 case DT_VERNEEDNUM: return "VERNEEDNUM";
865
866 case DT_AUXILIARY: return "AUXILARY";
867 case DT_USED: return "USED";
868 case DT_FILTER: return "FILTER";
869
870 default:
871 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
872 {
873 const char * result;
874
875 switch (elf_header.e_machine)
876 {
877 case EM_MIPS:
878 case EM_MIPS_RS4_BE:
879 result = get_mips_dynamic_type (type);
880 break;
881 default:
882 result = NULL;
883 break;
884 }
885
886 if (result != NULL)
887 return result;
888
889 sprintf (buff, _("Processor Specific: %lx"), type);
890 }
891 else if ((type >= DT_LOOS) && (type <= DT_HIOS))
892 sprintf (buff, _("Operating System specific: %lx"), type);
893 else
894 sprintf (buff, _("<unknown>: %lx"), type);
895
896 return buff;
897 }
898}
899
900static char *
901get_file_type (e_type)
902 unsigned e_type;
903{
904 static char buff [32];
905
906 switch (e_type)
907 {
908 case ET_NONE: return _("NONE (None)");
909 case ET_REL: return _("REL (Relocatable file)");
910 case ET_EXEC: return _("EXEC (Executable file)");
911 case ET_DYN: return _("DYN (Shared object file)");
912 case ET_CORE: return _("CORE (Core file)");
913
914 default:
915 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
916 sprintf (buff, _("Processor Specific: (%x)"), e_type);
917 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
918 sprintf (buff, _("OS Specific: (%x)"), e_type);
919 else
920 sprintf (buff, _("<unknown>: %x"), e_type);
921 return buff;
922 }
923}
924
925static char *
926get_machine_name (e_machine)
927 unsigned e_machine;
928{
929 static char buff [32];
930
931 switch (e_machine)
932 {
933 case EM_NONE: return _("None");
934 case EM_M32: return "WE32100";
935 case EM_SPARC: return "Sparc";
936 case EM_386: return "Intel 80386";
937 case EM_68K: return "MC68000";
938 case EM_88K: return "MC88000";
939 case EM_486: return "Intel 80486";
940 case EM_860: return "Intel 80860";
941 case EM_MIPS: return "MIPS R3000 big-endian";
942 case EM_S370: return "Amdahl";
943 case EM_MIPS_RS4_BE: return "MIPS R4000 big-endian";
944 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
945 case EM_PARISC: return "HPPA";
946 case EM_PPC_OLD: return "Power PC (old)";
947 case EM_SPARC32PLUS: return "Sparc v8+" ;
948 case EM_960: return "Intel 90860";
949 case EM_PPC: return "PowerPC";
950 case EM_V800: return "NEC V800";
951 case EM_FR20: return "Fujitsu FR20";
952 case EM_RH32: return "TRW RH32";
953 case EM_MCORE: return "MCORE";
954 case EM_ARM: return "ARM";
955 case EM_OLD_ALPHA: return "Digital Alpha (old)";
956 case EM_SH: return "Hitachi SH";
957 case EM_SPARCV9: return "Sparc v9";
958 case EM_TRICORE: return "Siemens Tricore";
959 case EM_ARC: return "Argonaut RISC Core";
960 case EM_H8_300: return "Hitachi H8/300";
961 case EM_H8_300H: return "Hitachi H8/300H";
962 case EM_H8S: return "Hitachi H8S";
963 case EM_H8_500: return "Hitachi H8/500";
964 case EM_IA_64: return "Intel Merced";
965 case EM_MIPS_X: return "Stanford MIPS-X";
966 case EM_COLDFIRE: return "Motorola Coldfire";
967 case EM_68HC12: return "Motorola M68HC12";
968 case EM_ALPHA: return "Alpha";
969 case EM_CYGNUS_D10V: return "d10v";
970 case EM_CYGNUS_D30V: return "d30v";
971 case EM_CYGNUS_ARC: return "Arc";
972 case EM_CYGNUS_M32R: return "Mitsubishi M32r";
973 case EM_CYGNUS_V850: return "NEC v850";
974 case EM_CYGNUS_MN10300: return "mn10300";
975 case EM_CYGNUS_MN10200: return "mn10200";
976 case EM_CYGNUS_FR30: return "Fujitsu FR30";
977
978 default:
979 sprintf (buff, _("<unknown>: %x"), e_machine);
980 return buff;
981 }
982}
983
984static char *
985get_machine_flags (e_flags, e_machine)
986 unsigned e_flags;
987 unsigned e_machine;
988{
989 static char buf [1024];
990
991 buf[0] = '\0';
992 if (e_flags)
993 {
994 switch (e_machine)
995 {
996 default:
997 break;
998
33c63f9d
CM
999 case EM_68K:
1000 if (e_flags & EF_CPU32)
1001 strcat (buf, ", cpu32");
1002 break;
1003
252b5132
RH
1004 case EM_PPC:
1005 if (e_flags & EF_PPC_EMB)
1006 strcat (buf, ", emb");
1007
1008 if (e_flags & EF_PPC_RELOCATABLE)
1009 strcat (buf, ", relocatable");
1010
1011 if (e_flags & EF_PPC_RELOCATABLE_LIB)
1012 strcat (buf, ", relocatable-lib");
1013 break;
1014
1015 case EM_CYGNUS_V850:
1016 switch (e_flags & EF_V850_ARCH)
1017 {
1018 case E_V850E_ARCH:
1019 strcat (buf, ", v850e");
1020 break;
1021 case E_V850EA_ARCH:
1022 strcat (buf, ", v850ea");
1023 break;
1024 case E_V850_ARCH:
1025 strcat (buf, ", v850");
1026 break;
1027 default:
1028 strcat (buf, ", unknown v850 architecture variant");
1029 break;
1030 }
1031 break;
1032
1033 case EM_CYGNUS_M32R:
1034 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
1035 strcat (buf, ", m32r");
1036
1037 break;
1038
1039 case EM_MIPS:
1040 case EM_MIPS_RS4_BE:
1041 if (e_flags & EF_MIPS_NOREORDER)
1042 strcat (buf, ", noreorder");
1043
1044 if (e_flags & EF_MIPS_PIC)
1045 strcat (buf, ", pic");
1046
1047 if (e_flags & EF_MIPS_CPIC)
1048 strcat (buf, ", cpic");
1049
1050 if (e_flags & EF_MIPS_ABI2)
1051 strcat (buf, ", abi2");
1052
1053 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1)
1054 strcat (buf, ", mips1");
1055
1056 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2)
1057 strcat (buf, ", mips2");
1058
1059 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_3)
1060 strcat (buf, ", mips3");
1061
1062 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
1063 strcat (buf, ", mips4");
1064 break;
1065 }
1066 }
1067
1068 return buf;
1069}
1070
252b5132
RH
1071static const char *
1072get_mips_segment_type (type)
1073 unsigned long type;
1074{
1075 switch (type)
1076 {
1077 case PT_MIPS_REGINFO:
1078 return "REGINFO";
1079 case PT_MIPS_RTPROC:
1080 return "RTPROC";
1081 case PT_MIPS_OPTIONS:
1082 return "OPTIONS";
1083 default:
1084 break;
1085 }
1086
1087 return NULL;
1088}
1089
1090static const char *
1091get_segment_type (p_type)
1092 unsigned long p_type;
1093{
1094 static char buff [32];
1095
1096 switch (p_type)
1097 {
1098 case PT_NULL: return "NULL";
1099 case PT_LOAD: return "LOAD";
1100 case PT_DYNAMIC: return "DYNAMIC";
1101 case PT_INTERP: return "INTERP";
1102 case PT_NOTE: return "NOTE";
1103 case PT_SHLIB: return "SHLIB";
1104 case PT_PHDR: return "PHDR";
1105
1106 default:
1107 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
1108 {
1109 const char * result;
1110
1111 switch (elf_header.e_machine)
1112 {
1113 case EM_MIPS:
1114 case EM_MIPS_RS4_BE:
1115 result = get_mips_segment_type (p_type);
1116 break;
1117 default:
1118 result = NULL;
1119 break;
1120 }
1121
1122 if (result != NULL)
1123 return result;
1124
1125 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
1126 }
1127 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
1128 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
1129 else
1130 sprintf (buff, _("<unknown>: %lx"), p_type);
1131
1132 return buff;
1133 }
1134}
1135
1136static const char *
1137get_mips_section_type_name (sh_type)
1138 unsigned int sh_type;
1139{
1140 switch (sh_type)
1141 {
1142 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1143 case SHT_MIPS_MSYM: return "MIPS_MSYM";
1144 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1145 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
1146 case SHT_MIPS_UCODE: return "MIPS_UCODE";
1147 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
1148 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
1149 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
1150 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
1151 case SHT_MIPS_RELD: return "MIPS_RELD";
1152 case SHT_MIPS_IFACE: return "MIPS_IFACE";
1153 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
1154 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1155 case SHT_MIPS_SHDR: return "MIPS_SHDR";
1156 case SHT_MIPS_FDESC: return "MIPS_FDESC";
1157 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
1158 case SHT_MIPS_DENSE: return "MIPS_DENSE";
1159 case SHT_MIPS_PDESC: return "MIPS_PDESC";
1160 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
1161 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
1162 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
1163 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
1164 case SHT_MIPS_LINE: return "MIPS_LINE";
1165 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
1166 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
1167 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
1168 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
1169 case SHT_MIPS_DWARF: return "MIPS_DWARF";
1170 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
1171 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1172 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
1173 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
1174 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
1175 case SHT_MIPS_XLATE: return "MIPS_XLATE";
1176 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
1177 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
1178 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
1179 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
1180 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
1181 default:
1182 break;
1183 }
1184 return NULL;
1185}
1186
1187static const char *
1188get_section_type_name (sh_type)
1189 unsigned int sh_type;
1190{
1191 static char buff [32];
1192
1193 switch (sh_type)
1194 {
1195 case SHT_NULL: return "NULL";
1196 case SHT_PROGBITS: return "PROGBITS";
1197 case SHT_SYMTAB: return "SYMTAB";
1198 case SHT_STRTAB: return "STRTAB";
1199 case SHT_RELA: return "RELA";
1200 case SHT_HASH: return "HASH";
1201 case SHT_DYNAMIC: return "DYNAMIC";
1202 case SHT_NOTE: return "NOTE";
1203 case SHT_NOBITS: return "NOBITS";
1204 case SHT_REL: return "REL";
1205 case SHT_SHLIB: return "SHLIB";
1206 case SHT_DYNSYM: return "DYNSYM";
1207 case SHT_GNU_verdef: return "VERDEF";
1208 case SHT_GNU_verneed: return "VERNEED";
1209 case SHT_GNU_versym: return "VERSYM";
1210 case 0x6ffffff0: return "VERSYM";
1211 case 0x6ffffffc: return "VERDEF";
1212 case 0x7ffffffd: return "AUXILIARY";
1213 case 0x7fffffff: return "FILTER";
1214
1215 default:
1216 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
1217 {
1218 const char * result;
1219
1220 switch (elf_header.e_machine)
1221 {
1222 case EM_MIPS:
1223 case EM_MIPS_RS4_BE:
1224 result = get_mips_section_type_name (sh_type);
1225 break;
1226 default:
1227 result = NULL;
1228 break;
1229 }
1230
1231 if (result != NULL)
1232 return result;
1233
1234 sprintf (buff, "SHT_LOPROC+%x", sh_type - SHT_LOPROC);
1235 }
1236 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
1237 sprintf (buff, "SHT_LOOS+%x", sh_type - SHT_LOOS);
1238 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
1239 sprintf (buff, "SHT_LOUSER+%x", sh_type - SHT_LOUSER);
1240 else
1241 sprintf (buff, _("<unknown>: %x"), sh_type);
1242
1243 return buff;
1244 }
1245}
1246
1247struct option options [] =
1248{
1249 {"all", no_argument, 0, 'a'},
1250 {"file-header", no_argument, 0, 'h'},
1251 {"program-headers", no_argument, 0, 'l'},
1252 {"headers", no_argument, 0, 'e'},
1253 {"histogram", no_argument, & do_histogram, 1},
1254 {"segments", no_argument, 0, 'l'},
1255 {"sections", no_argument, 0, 'S'},
1256 {"section-headers", no_argument, 0, 'S'},
1257 {"symbols", no_argument, 0, 's'},
1258 {"syms", no_argument, 0, 's'},
1259 {"relocs", no_argument, 0, 'r'},
1260 {"dynamic", no_argument, 0, 'd'},
1261 {"version-info", no_argument, 0, 'V'},
1262 {"use-dynamic", no_argument, 0, 'D'},
1263 {"hex-dump", required_argument, 0, 'x'},
1264 {"debug-dump", optional_argument, 0, 'w'},
1265#ifdef SUPPORT_DISASSEMBLY
1266 {"instruction-dump", required_argument, 0, 'i'},
1267#endif
1268
1269 {"version", no_argument, 0, 'v'},
1270 {"help", no_argument, 0, 'H'},
1271 {0, no_argument, 0, 0}
1272};
1273
1274static void
1275usage ()
1276{
1277 fprintf (stdout, _("Usage: readelf {options} elf-file(s)\n"));
1278 fprintf (stdout, _(" Options are:\n"));
1279 fprintf (stdout, _(" -a or --all Equivalent to: -h -l -S -s -r -d -V --histogram\n"));
1280 fprintf (stdout, _(" -h or --file-header Display the ELF file header\n"));
1281 fprintf (stdout, _(" -l or --program-headers or --segments\n"));
1282 fprintf (stdout, _(" Display the program headers\n"));
1283 fprintf (stdout, _(" -S or --section-headers or --sections\n"));
1284 fprintf (stdout, _(" Display the sections' header\n"));
1285 fprintf (stdout, _(" -e or --headers Equivalent to: -h -l -S\n"));
1286 fprintf (stdout, _(" -s or --syms or --symbols Display the symbol table\n"));
1287 fprintf (stdout, _(" -r or --relocs Display the relocations (if present)\n"));
1288 fprintf (stdout, _(" -d or --dynamic Display the dynamic segment (if present)\n"));
1289 fprintf (stdout, _(" -V or --version-info Display the version sections (if present)\n"));
1290 fprintf (stdout, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n"));
1291 fprintf (stdout, _(" -x <number> or --hex-dump=<number>\n"));
1292 fprintf (stdout, _(" Dump the contents of section <number>\n"));
1293 fprintf (stdout, _(" -w[liapr] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges]\n"));
1294 fprintf (stdout, _(" Display the contents of DWARF2 debug sections\n"));
1295#ifdef SUPPORT_DISASSEMBLY
1296 fprintf (stdout, _(" -i <number> or --instruction-dump=<number>\n"));
1297 fprintf (stdout, _(" Disassemble the contents of section <number>\n"));
1298#endif
1299 fprintf (stdout, _(" --histogram Display histogram of bucket list lengths\n"));
1300 fprintf (stdout, _(" -v or --version Display the version number of readelf\n"));
1301 fprintf (stdout, _(" -H or --help Display this information\n"));
1302 fprintf (stdout, _("Report bugs to bug-gnu-utils@gnu.org\n"));
1303
1304 exit (0);
1305}
1306
1307static void
1308request_dump (section, type)
1309 unsigned int section;
1310 char type;
1311{
1312 if (section >= num_dump_sects)
1313 {
1314 char * new_dump_sects;
1315
1316 new_dump_sects = (char *) calloc (section + 1, 1);
1317
1318 if (new_dump_sects == NULL)
1319 error (_("Out of memory allocating dump request table."));
1320 else
1321 {
1322 /* Copy current flag settings. */
1323 memcpy (new_dump_sects, dump_sects, num_dump_sects);
1324
1325 free (dump_sects);
1326
1327 dump_sects = new_dump_sects;
1328 num_dump_sects = section + 1;
1329 }
1330 }
1331
1332 if (dump_sects)
1333 dump_sects [section] |= type;
1334
1335 return;
1336}
1337
1338static void
1339parse_args (argc, argv)
1340 int argc;
1341 char ** argv;
1342{
1343 int c;
1344
1345 if (argc < 2)
1346 usage ();
1347
1348 while ((c = getopt_long
1349 (argc, argv, "ersahldSDw::x:i:vV", options, NULL)) != EOF)
1350 {
1351 char * cp;
1352 int section;
1353
1354 switch (c)
1355 {
1356 case 0:
1357 /* Long options. */
1358 break;
1359 case 'H':
1360 usage ();
1361 break;
1362
1363 case 'a':
1364 do_syms ++;
1365 do_reloc ++;
1366 do_dynamic ++;
1367 do_header ++;
1368 do_sections ++;
1369 do_segments ++;
1370 do_version ++;
1371 do_histogram ++;
1372 break;
1373 case 'e':
1374 do_header ++;
1375 do_sections ++;
1376 do_segments ++;
1377 break;
1378 case 'D':
1379 do_using_dynamic ++;
1380 break;
1381 case 'r':
1382 do_reloc ++;
1383 break;
1384 case 'h':
1385 do_header ++;
1386 break;
1387 case 'l':
1388 do_segments ++;
1389 break;
1390 case 's':
1391 do_syms ++;
1392 break;
1393 case 'S':
1394 do_sections ++;
1395 break;
1396 case 'd':
1397 do_dynamic ++;
1398 break;
1399 case 'x':
1400 do_dump ++;
1401 section = strtoul (optarg, & cp, 0);
1402 if (! * cp && section >= 0)
1403 {
1404 request_dump (section, HEX_DUMP);
1405 break;
1406 }
1407 goto oops;
1408 case 'w':
1409 do_dump ++;
1410 if (optarg == 0)
1411 do_debugging = 1;
1412 else
1413 {
1414 do_debugging = 0;
1415 switch (optarg[0])
1416 {
1417 case 'i':
1418 case 'I':
1419 do_debug_info = 1;
1420 break;
1421
1422 case 'a':
1423 case 'A':
1424 do_debug_abbrevs = 1;
1425 break;
1426
1427 case 'l':
1428 case 'L':
1429 do_debug_lines = 1;
1430 break;
1431
1432 case 'p':
1433 case 'P':
1434 do_debug_pubnames = 1;
1435 break;
1436
1437 case 'r':
1438 case 'R':
1439 do_debug_aranges = 1;
1440 break;
1441
1442 default:
1443 warn (_("Unrecognised debug option '%s'\n"), optarg);
1444 break;
1445 }
1446 }
1447 break;
1448#ifdef SUPPORT_DISASSEMBLY
1449 case 'i':
1450 do_dump ++;
1451 section = strtoul (optarg, & cp, 0);
1452 if (! * cp && section >= 0)
1453 {
1454 request_dump (section, DISASS_DUMP);
1455 break;
1456 }
1457 goto oops;
1458#endif
1459 case 'v':
1460 print_version (program_name);
1461 break;
1462 case 'V':
1463 do_version ++;
1464 break;
1465 default:
1466 oops:
1467 /* xgettext:c-format */
1468 error (_("Invalid option '-%c'\n"), c);
1469 /* Drop through. */
1470 case '?':
1471 usage ();
1472 }
1473 }
1474
1475 if (!do_dynamic && !do_syms && !do_reloc && !do_sections
1476 && !do_segments && !do_header && !do_dump && !do_version
1477 && !do_histogram && !do_debugging)
1478 usage ();
1479 else if (argc < 3)
1480 {
1481 warn (_("Nothing to do.\n"));
1482 usage();
1483 }
1484}
1485
1486static const char *
1487get_elf_class (elf_class)
1488 unsigned char elf_class;
1489{
ab5e7794
NC
1490 static char buff [32];
1491
252b5132
RH
1492 switch (elf_class)
1493 {
1494 case ELFCLASSNONE: return _("none");
1495 case ELFCLASS32: return _("ELF32");
1496 case ELFCLASS64: return _("ELF64");
ab5e7794 1497 default:
789be9f7 1498 sprintf (buff, _("<unknown: %x>"), elf_class);
ab5e7794 1499 return buff;
252b5132
RH
1500 }
1501}
1502
1503static const char *
1504get_data_encoding (encoding)
1505 unsigned char encoding;
1506{
ab5e7794
NC
1507 static char buff [32];
1508
252b5132
RH
1509 switch (encoding)
1510 {
1511 case ELFDATANONE: return _("none");
33c63f9d
CM
1512 case ELFDATA2LSB: return _("2's complement, little endian");
1513 case ELFDATA2MSB: return _("2's complement, big endian");
ab5e7794 1514 default:
789be9f7 1515 sprintf (buff, _("<unknown: %x>"), encoding);
ab5e7794 1516 return buff;
252b5132
RH
1517 }
1518}
1519
1520static const char *
1521get_osabi_name (osabi)
1522 unsigned char osabi;
1523{
ab5e7794
NC
1524 static char buff [32];
1525
252b5132
RH
1526 switch (osabi)
1527 {
1528 case ELFOSABI_SYSV: return _("UNIX - System V");
1529 case ELFOSABI_HPUX: return _("UNIX - HP-UX");
1530 case ELFOSABI_STANDALONE: return _("Standalone App");
ab5e7794 1531 default:
789be9f7 1532 sprintf (buff, _("<unknown: %x>"), osabi);
ab5e7794 1533 return buff;
252b5132
RH
1534 }
1535}
1536
1537/* Decode the data held in 'elf_header'. */
1538static int
1539process_file_header ()
1540{
1541 if ( elf_header.e_ident [EI_MAG0] != ELFMAG0
1542 || elf_header.e_ident [EI_MAG1] != ELFMAG1
1543 || elf_header.e_ident [EI_MAG2] != ELFMAG2
1544 || elf_header.e_ident [EI_MAG3] != ELFMAG3)
1545 {
1546 error
1547 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
1548 return 0;
1549 }
1550
1551 if (do_header)
1552 {
1553 int i;
1554
1555 printf (_("ELF Header:\n"));
1556 printf (_(" Magic: "));
1557 for (i = 0; i < EI_NIDENT; i ++)
1558 printf ("%2.2x ", elf_header.e_ident [i]);
1559 printf ("\n");
1560 printf (_(" Class: %s\n"),
1561 get_elf_class (elf_header.e_ident [EI_CLASS]));
1562 printf (_(" Data: %s\n"),
1563 get_data_encoding (elf_header.e_ident [EI_DATA]));
1564 printf (_(" Version: %d %s\n"),
1565 elf_header.e_ident [EI_VERSION],
789be9f7
ILT
1566 (elf_header.e_ident [EI_VERSION] == EV_CURRENT
1567 ? "(current)"
1568 : (elf_header.e_ident [EI_VERSION] != EV_NONE
1569 ? "<unknown: %lx>"
1570 : "")));
252b5132
RH
1571 printf (_(" OS/ABI: %s\n"),
1572 get_osabi_name (elf_header.e_ident [EI_OSABI]));
1573 printf (_(" ABI Version: %d\n"),
1574 elf_header.e_ident [EI_ABIVERSION]);
1575 printf (_(" Type: %s\n"),
1576 get_file_type (elf_header.e_type));
1577 printf (_(" Machine: %s\n"),
1578 get_machine_name (elf_header.e_machine));
1579 printf (_(" Version: 0x%lx\n"),
1580 (unsigned long) elf_header.e_version);
252b5132
RH
1581 printf (_(" Entry point address: 0x%lx\n"),
1582 (unsigned long) elf_header.e_entry);
1583 printf (_(" Start of program headers: %ld (bytes into file)\n"),
1584 (long) elf_header.e_phoff);
1585 printf (_(" Start of section headers: %ld (bytes into file)\n"),
1586 (long) elf_header.e_shoff);
1587 printf (_(" Flags: 0x%lx%s\n"),
1588 (unsigned long) elf_header.e_flags,
1589 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
1590 printf (_(" Size of this header: %ld (bytes)\n"),
1591 (long) elf_header.e_ehsize);
1592 printf (_(" Size of program headers: %ld (bytes)\n"),
1593 (long) elf_header.e_phentsize);
1594 printf (_(" Number of program headers: %ld\n"),
1595 (long) elf_header.e_phnum);
1596 printf (_(" Size of section headers: %ld (bytes)\n"),
1597 (long) elf_header.e_shentsize);
1598 printf (_(" Number of section headers: %ld\n"),
1599 (long) elf_header.e_shnum);
1600 printf (_(" Section header string table index: %ld\n"),
1601 (long) elf_header.e_shstrndx);
1602 }
9ea033b2
NC
1603
1604 return 1;
1605}
1606
252b5132 1607
9ea033b2
NC
1608static int
1609get_32bit_program_headers (file, program_headers)
1610 FILE * file;
1611 Elf_Internal_Phdr * program_headers;
1612{
1613 Elf32_External_Phdr * phdrs;
1614 Elf32_External_Phdr * external;
1615 Elf32_Internal_Phdr * internal;
1616 unsigned int i;
252b5132 1617
9ea033b2
NC
1618 GET_DATA_ALLOC (elf_header.e_phoff,
1619 elf_header.e_phentsize * elf_header.e_phnum,
1620 phdrs, Elf32_External_Phdr *, "program headers");
1621
1622 for (i = 0, internal = program_headers, external = phdrs;
1623 i < elf_header.e_phnum;
1624 i ++, internal ++, external ++)
252b5132 1625 {
9ea033b2
NC
1626 internal->p_type = BYTE_GET (external->p_type);
1627 internal->p_offset = BYTE_GET (external->p_offset);
1628 internal->p_vaddr = BYTE_GET (external->p_vaddr);
1629 internal->p_paddr = BYTE_GET (external->p_paddr);
1630 internal->p_filesz = BYTE_GET (external->p_filesz);
1631 internal->p_memsz = BYTE_GET (external->p_memsz);
1632 internal->p_flags = BYTE_GET (external->p_flags);
1633 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
1634 }
1635
9ea033b2
NC
1636 free (phdrs);
1637
252b5132
RH
1638 return 1;
1639}
1640
9ea033b2
NC
1641static int
1642get_64bit_program_headers (file, program_headers)
1643 FILE * file;
1644 Elf_Internal_Phdr * program_headers;
1645{
1646 Elf64_External_Phdr * phdrs;
1647 Elf64_External_Phdr * external;
1648 Elf64_Internal_Phdr * internal;
1649 unsigned int i;
1650
1651 GET_DATA_ALLOC (elf_header.e_phoff,
1652 elf_header.e_phentsize * elf_header.e_phnum,
1653 phdrs, Elf64_External_Phdr *, "program headers");
1654
1655 for (i = 0, internal = program_headers, external = phdrs;
1656 i < elf_header.e_phnum;
1657 i ++, internal ++, external ++)
1658 {
1659 internal->p_type = BYTE_GET (external->p_type);
1660 internal->p_flags = BYTE_GET (external->p_flags);
1661 internal->p_offset = BYTE_GET8 (external->p_offset);
1662 internal->p_vaddr = BYTE_GET8 (external->p_vaddr);
1663 internal->p_paddr = BYTE_GET8 (external->p_paddr);
1664 internal->p_filesz = BYTE_GET8 (external->p_filesz);
1665 internal->p_memsz = BYTE_GET8 (external->p_memsz);
1666 internal->p_align = BYTE_GET8 (external->p_align);
1667 }
1668
1669 free (phdrs);
1670
1671 return 1;
1672}
252b5132
RH
1673
1674static int
1675process_program_headers (file)
1676 FILE * file;
1677{
9ea033b2
NC
1678 Elf_Internal_Phdr * program_headers;
1679 Elf_Internal_Phdr * segment;
1680 unsigned int i;
252b5132
RH
1681
1682 if (elf_header.e_phnum == 0)
1683 {
1684 if (do_segments)
1685 printf (_("\nThere are no program headers in this file.\n"));
1686 return 1;
1687 }
1688
1689 if (do_segments && !do_header)
1690 {
1691 printf (_("\nElf file is %s\n"), get_file_type (elf_header.e_type));
1692 printf (_("Entry point 0x%lx\n"), (unsigned long) elf_header.e_entry);
1693 printf (_("There are %d program headers, starting at offset %lx:\n"),
1694 elf_header.e_phnum, (unsigned long) elf_header.e_phoff);
1695 }
1696
9ea033b2
NC
1697 program_headers = (Elf_Internal_Phdr *) malloc
1698 (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
252b5132
RH
1699
1700 if (program_headers == NULL)
1701 {
1702 error (_("Out of memory\n"));
1703 return 0;
1704 }
1705
9ea033b2
NC
1706 if (is_32bit_elf)
1707 i = get_32bit_program_headers (file, program_headers);
1708 else
1709 i = get_64bit_program_headers (file, program_headers);
1710
1711 if (i == 0)
252b5132 1712 {
9ea033b2
NC
1713 free (program_headers);
1714 return 0;
252b5132 1715 }
9ea033b2 1716
252b5132
RH
1717 if (do_segments)
1718 {
1719 printf
1720 (_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
1721 printf
1722 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
1723 }
1724
1725 loadaddr = -1;
1726 dynamic_addr = 0;
1b228002 1727 dynamic_size = 0;
252b5132
RH
1728
1729 for (i = 0, segment = program_headers;
1730 i < elf_header.e_phnum;
1731 i ++, segment ++)
1732 {
1733 if (do_segments)
1734 {
1735 printf (" %-11.11s ", get_segment_type (segment->p_type));
1736 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
1737 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
1738 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
1739 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
1740 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
1741 printf ("%c%c%c ",
1742 (segment->p_flags & PF_R ? 'R' : ' '),
1743 (segment->p_flags & PF_W ? 'W' : ' '),
1744 (segment->p_flags & PF_X ? 'E' : ' '));
1745 printf ("%#lx", (unsigned long) segment->p_align);
1746 }
1747
1748 switch (segment->p_type)
1749 {
1750 case PT_LOAD:
1751 if (loadaddr == -1)
1752 loadaddr = (segment->p_vaddr & 0xfffff000)
1753 - (segment->p_offset & 0xfffff000);
1754 break;
1755
1756 case PT_DYNAMIC:
1757 if (dynamic_addr)
1758 error (_("more than one dynamic segment\n"));
1759
1760 dynamic_addr = segment->p_offset;
1761 dynamic_size = segment->p_filesz;
1762 break;
1763
1764 case PT_INTERP:
1765 if (fseek (file, segment->p_offset, SEEK_SET))
1766 error (_("Unable to find program interpreter name\n"));
1767 else
1768 {
1769 program_interpreter[0] = 0;
1770 fscanf (file, "%63s", program_interpreter);
1771
1772 if (do_segments)
1773 printf (_("\n [Requesting program interpreter: %s]"),
1774 program_interpreter);
1775 }
1776 break;
1777 }
1778
1779 if (do_segments)
1780 putc ('\n', stdout);
1781 }
1782
1783 if (loadaddr == -1)
1784 {
1785 /* Very strange. */
1786 loadaddr = 0;
1787 }
1788
1789 if (do_segments && section_headers != NULL)
1790 {
1791 printf (_("\n Section to Segment mapping:\n"));
1792 printf (_(" Segment Sections...\n"));
1793
1794 assert (string_table != NULL);
1795
1796 for (i = 0; i < elf_header.e_phnum; i++)
1797 {
9ea033b2
NC
1798 int j;
1799 Elf_Internal_Shdr * section;
252b5132
RH
1800
1801 segment = program_headers + i;
1802 section = section_headers;
1803
1804 printf (" %2.2d ", i);
1805
1806 for (j = 0; j < elf_header.e_shnum; j++, section ++)
1807 {
1808 if (section->sh_size > 0
1809 /* Compare allocated sections by VMA, unallocated
1810 sections by file offset. */
1811 && (section->sh_flags & SHF_ALLOC
1812 ? (section->sh_addr >= segment->p_vaddr
1813 && section->sh_addr + section->sh_size
1814 <= segment->p_vaddr + segment->p_memsz)
1815 : (section->sh_offset >= segment->p_offset
1816 && (section->sh_offset + section->sh_size
1817 <= segment->p_offset + segment->p_filesz))))
1818 printf ("%s ", SECTION_NAME (section));
1819 }
1820
1821 putc ('\n',stdout);
1822 }
1823 }
1824
1825 free (program_headers);
1826
1827 return 1;
1828}
1829
1830
1831static int
9ea033b2 1832get_32bit_section_headers (file)
252b5132
RH
1833 FILE * file;
1834{
1835 Elf32_External_Shdr * shdrs;
1836 Elf32_Internal_Shdr * internal;
1837 unsigned int i;
1838
1839 GET_DATA_ALLOC (elf_header.e_shoff,
1840 elf_header.e_shentsize * elf_header.e_shnum,
1841 shdrs, Elf32_External_Shdr *, "section headers");
1842
9ea033b2
NC
1843 section_headers = (Elf_Internal_Shdr *) malloc
1844 (elf_header.e_shnum * sizeof (Elf_Internal_Shdr));
252b5132
RH
1845
1846 if (section_headers == NULL)
1847 {
1848 error (_("Out of memory\n"));
1849 return 0;
1850 }
1851
1852 for (i = 0, internal = section_headers;
1853 i < elf_header.e_shnum;
1854 i ++, internal ++)
1855 {
1856 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
1857 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
1858 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
1859 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
1860 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
1861 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
1862 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
1863 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
1864 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
1865 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
1866 }
1867
1868 free (shdrs);
1869
1870 return 1;
1871}
1872
9ea033b2
NC
1873static int
1874get_64bit_section_headers (file)
1875 FILE * file;
1876{
1877 Elf64_External_Shdr * shdrs;
1878 Elf64_Internal_Shdr * internal;
1879 unsigned int i;
1880
1881 GET_DATA_ALLOC (elf_header.e_shoff,
1882 elf_header.e_shentsize * elf_header.e_shnum,
1883 shdrs, Elf64_External_Shdr *, "section headers");
1884
1885 section_headers = (Elf_Internal_Shdr *) malloc
1886 (elf_header.e_shnum * sizeof (Elf_Internal_Shdr));
1887
1888 if (section_headers == NULL)
1889 {
1890 error (_("Out of memory\n"));
1891 return 0;
1892 }
1893
1894 for (i = 0, internal = section_headers;
1895 i < elf_header.e_shnum;
1896 i ++, internal ++)
1897 {
1898 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
1899 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
1900 internal->sh_flags = BYTE_GET8 (shdrs[i].sh_flags);
1901 internal->sh_addr = BYTE_GET8 (shdrs[i].sh_addr);
1902 internal->sh_size = BYTE_GET8 (shdrs[i].sh_size);
1903 internal->sh_entsize = BYTE_GET8 (shdrs[i].sh_entsize);
1904 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
1905 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
1906 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
1907 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
1908 }
1909
1910 free (shdrs);
1911
1912 return 1;
1913}
1914
252b5132 1915static Elf_Internal_Sym *
9ea033b2 1916get_32bit_elf_symbols (file, offset, number)
252b5132
RH
1917 FILE * file;
1918 unsigned long offset;
1919 unsigned long number;
1920{
1921 Elf32_External_Sym * esyms;
1922 Elf_Internal_Sym * isyms;
1923 Elf_Internal_Sym * psym;
1924 unsigned int j;
1925
1926 GET_DATA_ALLOC (offset, number * sizeof (Elf32_External_Sym),
1927 esyms, Elf32_External_Sym *, "symbols");
1928
1929 isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
1930
1931 if (isyms == NULL)
1932 {
1933 error (_("Out of memory\n"));
1934 free (esyms);
1935
1936 return NULL;
1937 }
1938
1939 for (j = 0, psym = isyms;
1940 j < number;
1941 j ++, psym ++)
1942 {
1943 psym->st_name = BYTE_GET (esyms[j].st_name);
1944 psym->st_value = BYTE_GET (esyms[j].st_value);
1945 psym->st_size = BYTE_GET (esyms[j].st_size);
1946 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
1947 psym->st_info = BYTE_GET (esyms[j].st_info);
1948 psym->st_other = BYTE_GET (esyms[j].st_other);
1949 }
1950
1951 free (esyms);
1952
1953 return isyms;
1954}
1955
9ea033b2
NC
1956static Elf_Internal_Sym *
1957get_64bit_elf_symbols (file, offset, number)
1958 FILE * file;
1959 unsigned long offset;
1960 unsigned long number;
1961{
1962 Elf64_External_Sym * esyms;
1963 Elf_Internal_Sym * isyms;
1964 Elf_Internal_Sym * psym;
1965 unsigned int j;
1966
1967 GET_DATA_ALLOC (offset, number * sizeof (Elf64_External_Sym),
1968 esyms, Elf64_External_Sym *, "symbols");
1969
1970 isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
1971
1972 if (isyms == NULL)
1973 {
1974 error (_("Out of memory\n"));
1975 free (esyms);
1976
1977 return NULL;
1978 }
1979
1980 for (j = 0, psym = isyms;
1981 j < number;
1982 j ++, psym ++)
1983 {
1984 psym->st_name = BYTE_GET (esyms[j].st_name);
1985 psym->st_info = BYTE_GET (esyms[j].st_info);
1986 psym->st_other = BYTE_GET (esyms[j].st_other);
1987 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
1988 psym->st_value = BYTE_GET8 (esyms[j].st_value);
1989 psym->st_size = BYTE_GET8 (esyms[j].st_size);
1990 }
1991
1992 free (esyms);
1993
1994 return isyms;
1995}
1996
252b5132
RH
1997static int
1998process_section_headers (file)
1999 FILE * file;
2000{
9ea033b2
NC
2001 Elf_Internal_Shdr * section;
2002 int i;
252b5132
RH
2003
2004 section_headers = NULL;
2005
2006 if (elf_header.e_shnum == 0)
2007 {
2008 if (do_sections)
2009 printf (_("\nThere are no sections in this file.\n"));
2010
2011 return 1;
2012 }
2013
2014 if (do_sections && !do_header)
9ea033b2 2015 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
2016 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
2017
9ea033b2
NC
2018 if (is_32bit_elf)
2019 {
2020 if (! get_32bit_section_headers (file))
2021 return 0;
2022 }
2023 else if (! get_64bit_section_headers (file))
252b5132
RH
2024 return 0;
2025
2026 /* Read in the string table, so that we have names to display. */
2027 section = section_headers + elf_header.e_shstrndx;
2028
2029 if (section->sh_size != 0)
2030 {
2031 unsigned long string_table_offset;
2032
2033 string_table_offset = section->sh_offset;
2034
2035 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2036 string_table, char *, "string table");
2037 }
2038
2039 /* Scan the sections for the dynamic symbol table
2040 and dynamic string table and debug sections. */
2041 dynamic_symbols = NULL;
2042 dynamic_strings = NULL;
2043 dynamic_syminfo = NULL;
9ea033b2 2044
252b5132
RH
2045 for (i = 0, section = section_headers;
2046 i < elf_header.e_shnum;
2047 i ++, section ++)
2048 {
2049 char * name = SECTION_NAME (section);
2050
2051 if (section->sh_type == SHT_DYNSYM)
2052 {
2053 if (dynamic_symbols != NULL)
2054 {
2055 error (_("File contains multiple dynamic symbol tables\n"));
2056 continue;
2057 }
2058
19936277 2059 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ea033b2 2060 dynamic_symbols =
19936277 2061 GET_ELF_SYMBOLS (file, section->sh_offset, num_dynamic_syms);
252b5132
RH
2062 }
2063 else if (section->sh_type == SHT_STRTAB
2064 && strcmp (name, ".dynstr") == 0)
2065 {
2066 if (dynamic_strings != NULL)
2067 {
2068 error (_("File contains multiple dynamic string tables\n"));
2069 continue;
2070 }
2071
2072 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2073 dynamic_strings, char *, "dynamic strings");
2074 }
2075 else if ((do_debugging || do_debug_info || do_debug_abbrevs
2076 || do_debug_lines || do_debug_pubnames || do_debug_aranges)
2077 && strncmp (name, ".debug_", 7) == 0)
2078 {
2079 name += 7;
2080
2081 if (do_debugging
2082 || (do_debug_info && (strcmp (name, "info") == 0))
2083 || (do_debug_abbrevs && (strcmp (name, "abbrev") == 0))
2084 || (do_debug_lines && (strcmp (name, "line") == 0))
2085 || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
2086 || (do_debug_aranges && (strcmp (name, "aranges") == 0))
2087 )
2088 request_dump (i, DEBUG_DUMP);
2089 }
2090 }
2091
2092 if (! do_sections)
2093 return 1;
2094
2095 printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
2096 printf
2097 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
2098
2099 for (i = 0, section = section_headers;
2100 i < elf_header.e_shnum;
2101 i ++, section ++)
2102 {
2103 printf (" [%2d] %-17.17s %-15.15s ",
2104 i,
2105 SECTION_NAME (section),
2106 get_section_type_name (section->sh_type));
2107
2108 printf ( "%8.8lx %6.6lx %6.6lx %2.2lx",
2109 (unsigned long) section->sh_addr,
2110 (unsigned long) section->sh_offset,
2111 (unsigned long) section->sh_size,
2112 (unsigned long) section->sh_entsize);
2113
2114 printf (" %c%c%c %2ld %3lx %ld\n",
2115 (section->sh_flags & SHF_WRITE ? 'W' : ' '),
2116 (section->sh_flags & SHF_ALLOC ? 'A' : ' '),
2117 (section->sh_flags & SHF_EXECINSTR ? 'X' : ' '),
2118 (unsigned long) section->sh_link,
2119 (unsigned long) section->sh_info,
2120 (unsigned long) section->sh_addralign);
2121 }
2122
2123 return 1;
2124}
2125
2126/* Process the reloc section. */
2127static int
2128process_relocs (file)
2129 FILE * file;
2130{
2131 unsigned long rel_size;
2132 unsigned long rel_offset;
2133
2134
2135 if (!do_reloc)
2136 return 1;
2137
2138 if (do_using_dynamic)
2139 {
9c19a809
NC
2140 int is_rela;
2141
252b5132
RH
2142 rel_size = 0;
2143 rel_offset = 0;
2144
2145 if (dynamic_info[DT_REL])
2146 {
2147 rel_offset = dynamic_info[DT_REL];
2148 rel_size = dynamic_info[DT_RELSZ];
9c19a809 2149 is_rela = FALSE;
252b5132
RH
2150 }
2151 else if (dynamic_info [DT_RELA])
2152 {
2153 rel_offset = dynamic_info[DT_RELA];
2154 rel_size = dynamic_info[DT_RELASZ];
9c19a809 2155 is_rela = TRUE;
252b5132
RH
2156 }
2157 else if (dynamic_info[DT_JMPREL])
2158 {
2159 rel_offset = dynamic_info[DT_JMPREL];
2160 rel_size = dynamic_info[DT_PLTRELSZ];
19936277 2161
aa903cfb
AS
2162 switch (dynamic_info[DT_PLTREL])
2163 {
2164 case DT_REL:
2165 is_rela = FALSE;
2166 break;
2167 case DT_RELA:
2168 is_rela = TRUE;
2169 break;
2170 default:
2171 is_rela = UNKNOWN;
2172 break;
2173 }
252b5132
RH
2174 }
2175
2176 if (rel_size)
2177 {
2178 printf
2179 (_("\nRelocation section at offset 0x%lx contains %ld bytes:\n"),
2180 rel_offset, rel_size);
2181
2182 dump_relocations (file, rel_offset - loadaddr, rel_size,
19936277 2183 dynamic_symbols, num_dynamic_syms, dynamic_strings, is_rela);
252b5132
RH
2184 }
2185 else
2186 printf (_("\nThere are no dynamic relocations in this file.\n"));
2187 }
2188 else
2189 {
2190 Elf32_Internal_Shdr * section;
2191 unsigned long i;
2192 int found = 0;
2193
2194 for (i = 0, section = section_headers;
2195 i < elf_header.e_shnum;
2196 i++, section ++)
2197 {
2198 if ( section->sh_type != SHT_RELA
2199 && section->sh_type != SHT_REL)
2200 continue;
2201
2202 rel_offset = section->sh_offset;
2203 rel_size = section->sh_size;
2204
2205 if (rel_size)
2206 {
2207 Elf32_Internal_Shdr * strsec;
2208 Elf32_Internal_Shdr * symsec;
2209 Elf_Internal_Sym * symtab;
2210 char * strtab;
9c19a809 2211 int is_rela;
19936277 2212 unsigned long nsyms;
9c19a809 2213
252b5132
RH
2214 printf (_("\nRelocation section "));
2215
2216 if (string_table == NULL)
19936277 2217 printf ("%d", section->sh_name);
252b5132 2218 else
19936277 2219 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
2220
2221 printf (_(" at offset 0x%lx contains %lu entries:\n"),
2222 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
2223
2224 symsec = section_headers + section->sh_link;
2225
19936277
NC
2226 nsyms = symsec->sh_size / symsec->sh_entsize;
2227 symtab = GET_ELF_SYMBOLS (file, symsec->sh_offset, nsyms);
252b5132
RH
2228
2229 if (symtab == NULL)
2230 continue;
2231
2232 strsec = section_headers + symsec->sh_link;
2233
2234 GET_DATA_ALLOC (strsec->sh_offset, strsec->sh_size, strtab,
2235 char *, "string table");
aa903cfb
AS
2236
2237 is_rela = section->sh_type == SHT_RELA;
252b5132 2238
19936277 2239 dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela);
252b5132
RH
2240
2241 free (strtab);
2242 free (symtab);
2243
2244 found = 1;
2245 }
2246 }
2247
2248 if (! found)
2249 printf (_("\nThere are no relocations in this file.\n"));
2250 }
2251
2252 return 1;
2253}
2254
2255
2256static void
2257dynamic_segment_mips_val (entry)
2258 Elf_Internal_Dyn * entry;
2259{
2260 switch (entry->d_tag)
2261 {
2262 case DT_MIPS_FLAGS:
2263 if (entry->d_un.d_val == 0)
2264 printf ("NONE\n");
2265 else
2266 {
2267 static const char * opts[] =
2268 {
2269 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
2270 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
2271 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
2272 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
2273 "RLD_ORDER_SAFE"
2274 };
2275 unsigned int cnt;
2276 int first = 1;
2277 for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
2278 if (entry->d_un.d_val & (1 << cnt))
2279 {
2280 printf ("%s%s", first ? "" : " ", opts[cnt]);
2281 first = 0;
2282 }
2283 puts ("");
2284 }
2285 break;
2286
2287 case DT_MIPS_IVERSION:
2288 if (dynamic_strings != NULL)
2289 printf ("Interface Version: %s\n",
2290 dynamic_strings + entry->d_un.d_val);
2291 else
2292 printf ("%ld\n", (long) entry->d_un.d_ptr);
2293 break;
2294
2295 case DT_MIPS_TIME_STAMP:
2296 {
2297 char timebuf[20];
2298 time_t time = entry->d_un.d_val;
2299 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
2300 printf ("Time Stamp: %s\n", timebuf);
2301 }
2302 break;
2303
2304 case DT_MIPS_RLD_VERSION:
2305 case DT_MIPS_LOCAL_GOTNO:
2306 case DT_MIPS_CONFLICTNO:
2307 case DT_MIPS_LIBLISTNO:
2308 case DT_MIPS_SYMTABNO:
2309 case DT_MIPS_UNREFEXTNO:
2310 case DT_MIPS_HIPAGENO:
2311 case DT_MIPS_DELTA_CLASS_NO:
2312 case DT_MIPS_DELTA_INSTANCE_NO:
2313 case DT_MIPS_DELTA_RELOC_NO:
2314 case DT_MIPS_DELTA_SYM_NO:
2315 case DT_MIPS_DELTA_CLASSSYM_NO:
2316 case DT_MIPS_COMPACT_SIZE:
2317 printf ("%ld\n", (long) entry->d_un.d_ptr);
2318 break;
2319
2320 default:
2321 printf ("%#lx\n", (long) entry->d_un.d_ptr);
2322 }
2323}
2324
252b5132 2325static int
9ea033b2 2326get_32bit_dynamic_segment (file)
252b5132
RH
2327 FILE * file;
2328{
9ea033b2
NC
2329 Elf32_External_Dyn * edyn;
2330 Elf_Internal_Dyn * entry;
2331 bfd_size_type i;
2332
2333 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
2334 edyn, Elf32_External_Dyn *, "dynamic segment");
2335
2336 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
2337 how large this .dynamic is now. We can do this even before the byte
2338 swapping since the DT_NULL tag is recognizable. */
2339 dynamic_size = 0;
2340 while (*(Elf32_Word *) edyn [dynamic_size++].d_tag != DT_NULL)
2341 ;
252b5132 2342
9ea033b2
NC
2343 dynamic_segment = (Elf_Internal_Dyn *)
2344 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
2345
2346 if (dynamic_segment == NULL)
252b5132 2347 {
9ea033b2
NC
2348 error (_("Out of memory\n"));
2349 free (edyn);
2350 return 0;
2351 }
252b5132 2352
9ea033b2
NC
2353 for (i = 0, entry = dynamic_segment;
2354 i < dynamic_size;
2355 i ++, entry ++)
2356 {
2357 entry->d_tag = BYTE_GET (edyn [i].d_tag);
2358 entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
252b5132
RH
2359 }
2360
9ea033b2
NC
2361 free (edyn);
2362
2363 return 1;
2364}
2365
2366static int
2367get_64bit_dynamic_segment (file)
2368 FILE * file;
2369{
2370 Elf64_External_Dyn * edyn;
2371 Elf_Internal_Dyn * entry;
2372 bfd_size_type i;
2373
252b5132 2374 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
9ea033b2 2375 edyn, Elf64_External_Dyn *, "dynamic segment");
252b5132
RH
2376
2377 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
9ea033b2 2378 how large this .dynamic is now. We can do this even before the byte
252b5132
RH
2379 swapping since the DT_NULL tag is recognizable. */
2380 dynamic_size = 0;
9ea033b2 2381 while (*(bfd_vma *) edyn [dynamic_size ++].d_tag != DT_NULL)
252b5132
RH
2382 ;
2383
2384 dynamic_segment = (Elf_Internal_Dyn *)
2385 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
2386
2387 if (dynamic_segment == NULL)
2388 {
2389 error (_("Out of memory\n"));
2390 free (edyn);
2391 return 0;
2392 }
2393
2394 for (i = 0, entry = dynamic_segment;
2395 i < dynamic_size;
2396 i ++, entry ++)
2397 {
9ea033b2
NC
2398 entry->d_tag = BYTE_GET8 (edyn [i].d_tag);
2399 entry->d_un.d_val = BYTE_GET8 (edyn [i].d_un.d_val);
252b5132
RH
2400 }
2401
2402 free (edyn);
2403
9ea033b2
NC
2404 return 1;
2405}
2406
2407/* Parse and display the contents of the dynamic segment. */
2408static int
2409process_dynamic_segment (file)
2410 FILE * file;
2411{
2412 Elf_Internal_Dyn * entry;
2413 bfd_size_type i;
2414
2415 if (dynamic_size == 0)
2416 {
2417 if (do_dynamic)
2418 printf (_("\nThere is no dynamic segment in this file.\n"));
2419
2420 return 1;
2421 }
2422
2423 if (is_32bit_elf)
2424 {
2425 if (! get_32bit_dynamic_segment (file))
2426 return 0;
2427 }
2428 else if (! get_64bit_dynamic_segment (file))
2429 return 0;
2430
252b5132
RH
2431 /* Find the appropriate symbol table. */
2432 if (dynamic_symbols == NULL)
2433 {
2434 for (i = 0, entry = dynamic_segment;
2435 i < dynamic_size;
2436 ++i, ++ entry)
2437 {
2438 unsigned long offset;
252b5132
RH
2439
2440 if (entry->d_tag != DT_SYMTAB)
2441 continue;
2442
2443 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
2444
2445 /* Since we do not know how big the symbol table is,
2446 we default to reading in the entire file (!) and
2447 processing that. This is overkill, I know, but it
2448 should work. */
252b5132
RH
2449 offset = entry->d_un.d_val - loadaddr;
2450
2451 if (fseek (file, 0, SEEK_END))
2452 error (_("Unable to seek to end of file!"));
2453
9ea033b2 2454 if (is_32bit_elf)
19936277 2455 num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
9ea033b2 2456 else
19936277 2457 num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf64_External_Sym);
252b5132 2458
19936277 2459 if (num_dynamic_syms < 1)
252b5132
RH
2460 {
2461 error (_("Unable to determine the number of symbols to load\n"));
2462 continue;
2463 }
2464
19936277 2465 dynamic_symbols = GET_ELF_SYMBOLS (file, offset, num_dynamic_syms);
252b5132
RH
2466 }
2467 }
2468
2469 /* Similarly find a string table. */
2470 if (dynamic_strings == NULL)
2471 {
2472 for (i = 0, entry = dynamic_segment;
2473 i < dynamic_size;
2474 ++i, ++ entry)
2475 {
2476 unsigned long offset;
2477 long str_tab_len;
2478
2479 if (entry->d_tag != DT_STRTAB)
2480 continue;
2481
2482 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
2483
2484 /* Since we do not know how big the string table is,
2485 we default to reading in the entire file (!) and
2486 processing that. This is overkill, I know, but it
2487 should work. */
2488
2489 offset = entry->d_un.d_val - loadaddr;
2490 if (fseek (file, 0, SEEK_END))
2491 error (_("Unable to seek to end of file\n"));
2492 str_tab_len = ftell (file) - offset;
2493
2494 if (str_tab_len < 1)
2495 {
2496 error
2497 (_("Unable to determine the length of the dynamic string table\n"));
2498 continue;
2499 }
2500
2501 GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
2502 "dynamic string table");
2503
2504 break;
2505 }
2506 }
2507
2508 /* And find the syminfo section if available. */
2509 if (dynamic_syminfo == NULL)
2510 {
2511 unsigned int syminsz = 0;
2512
2513 for (i = 0, entry = dynamic_segment;
2514 i < dynamic_size;
2515 ++i, ++ entry)
2516 {
2517 if (entry->d_tag == DT_SYMINENT)
2518 {
2519 /* Note: these braces are necessary to avoid a syntax
2520 error from the SunOS4 C compiler. */
2521 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
2522 }
2523 else if (entry->d_tag == DT_SYMINSZ)
2524 syminsz = entry->d_un.d_val;
2525 else if (entry->d_tag == DT_SYMINFO)
2526 dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
2527 }
2528
2529 if (dynamic_syminfo_offset != 0 && syminsz != 0)
2530 {
9ea033b2
NC
2531 Elf_External_Syminfo * extsyminfo;
2532 Elf_Internal_Syminfo * syminfo;
252b5132
RH
2533
2534 /* There is a syminfo section. Read the data. */
2535 GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
2536 Elf_External_Syminfo *, "symbol information");
2537
2538 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
2539 if (dynamic_syminfo == NULL)
2540 {
2541 error (_("Out of memory\n"));
2542 return 0;
2543 }
2544
2545 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
2546 for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
2547 ++i, ++syminfo)
2548 {
2549 syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
2550 syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
2551 }
2552
2553 free (extsyminfo);
2554 }
2555 }
2556
2557 if (do_dynamic && dynamic_addr)
789be9f7
ILT
2558 printf (_("\nDynamic segment at offset 0x%x contains %ld entries:\n"),
2559 dynamic_addr, (long) dynamic_size);
252b5132
RH
2560 if (do_dynamic)
2561 printf (_(" Tag Type Name/Value\n"));
2562
2563 for (i = 0, entry = dynamic_segment;
2564 i < dynamic_size;
2565 i++, entry ++)
2566 {
2567 if (do_dynamic)
2568 printf (_(" 0x%-8.8lx (%s)%*s"),
2569 (unsigned long) entry->d_tag,
2570 get_dynamic_type (entry->d_tag),
2571 27 - strlen (get_dynamic_type (entry->d_tag)),
2572 " ");
2573
2574 switch (entry->d_tag)
2575 {
2576 case DT_AUXILIARY:
2577 case DT_FILTER:
2578 if (do_dynamic)
2579 {
2580 if (entry->d_tag == DT_AUXILIARY)
2581 printf (_("Auxiliary library"));
2582 else
2583 printf (_("Filter library"));
2584
2585 if (dynamic_strings)
2586 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
2587 else
2588 printf (": %#lx\n", (long) entry->d_un.d_val);
2589 }
2590 break;
2591
2592 case DT_FEATURE_1:
2593 if (do_dynamic)
2594 {
2595 printf (_("Flags:"));
2596 if (entry->d_un.d_val == 0)
2597 printf (_(" None\n"));
2598 else
2599 {
2600 unsigned long int val = entry->d_un.d_val;
2601 if (val & DTF_1_PARINIT)
2602 {
2603 printf (" PARINIT");
2604 val ^= DTF_1_PARINIT;
2605 }
2606 if (val != 0)
2607 printf (" %lx", val);
2608 puts ("");
2609 }
2610 }
2611 break;
2612
2613 case DT_POSFLAG_1:
2614 if (do_dynamic)
2615 {
2616 printf (_("Flags:"));
2617 if (entry->d_un.d_val == 0)
2618 printf (_(" None\n"));
2619 else
2620 {
2621 unsigned long int val = entry->d_un.d_val;
2622 if (val & DF_P1_LAZYLOAD)
2623 {
2624 printf (" LAZYLOAD");
2625 val ^= DF_P1_LAZYLOAD;
2626 }
2627 if (val & DF_P1_GROUPPERM)
2628 {
2629 printf (" GROUPPERM");
2630 val ^= DF_P1_GROUPPERM;
2631 }
2632 if (val != 0)
2633 printf (" %lx", val);
2634 puts ("");
2635 }
2636 }
2637 break;
2638
2639 case DT_FLAGS_1:
2640 if (do_dynamic)
2641 {
2642 printf (_("Flags:"));
2643 if (entry->d_un.d_val == 0)
2644 printf (_(" None\n"));
2645 else
2646 {
2647 unsigned long int val = entry->d_un.d_val;
2648 if (val & DF_1_NOW)
2649 {
2650 printf (" NOW");
2651 val ^= DF_1_NOW;
2652 }
2653 if (val & DF_1_GLOBAL)
2654 {
2655 printf (" GLOBAL");
2656 val ^= DF_1_GLOBAL;
2657 }
2658 if (val & DF_1_GROUP)
2659 {
2660 printf (" GROUP");
2661 val ^= DF_1_GROUP;
2662 }
2663 if (val & DF_1_NODELETE)
2664 {
2665 printf (" NODELETE");
2666 val ^= DF_1_NODELETE;
2667 }
2668 if (val & DF_1_LOADFLTR)
2669 {
2670 printf (" LOADFLTR");
2671 val ^= DF_1_LOADFLTR;
2672 }
2673 if (val & DF_1_INITFIRST)
2674 {
2675 printf (" INITFIRST");
2676 val ^= DF_1_INITFIRST;
2677 }
2678 if (val & DF_1_NOOPEN)
2679 {
2680 printf (" NOOPEN");
2681 val ^= DF_1_NOOPEN;
2682 }
2683 if (val & DF_1_ORIGIN)
2684 {
2685 printf (" ORIGIN");
2686 val ^= DF_1_ORIGIN;
2687 }
2688 if (val & DF_1_DIRECT)
2689 {
2690 printf (" DIRECT");
2691 val ^= DF_1_DIRECT;
2692 }
2693 if (val & DF_1_TRANS)
2694 {
2695 printf (" TRANS");
2696 val ^= DF_1_TRANS;
2697 }
2698 if (val & DF_1_INTERPOSE)
2699 {
2700 printf (" INTERPOSE");
2701 val ^= DF_1_INTERPOSE;
2702 }
2703 if (val != 0)
2704 printf (" %lx", val);
2705 puts ("");
2706 }
2707 }
2708 break;
2709
2710 case DT_PLTREL:
2711 if (do_dynamic)
2712 puts (get_dynamic_type (entry->d_un.d_val));
2713 break;
2714
2715 case DT_NULL :
2716 case DT_NEEDED :
2717 case DT_PLTGOT :
2718 case DT_HASH :
2719 case DT_STRTAB :
2720 case DT_SYMTAB :
2721 case DT_RELA :
2722 case DT_INIT :
2723 case DT_FINI :
2724 case DT_SONAME :
2725 case DT_RPATH :
2726 case DT_SYMBOLIC:
2727 case DT_REL :
2728 case DT_DEBUG :
2729 case DT_TEXTREL :
2730 case DT_JMPREL :
2731 dynamic_info[entry->d_tag] = entry->d_un.d_val;
2732
2733 if (do_dynamic)
2734 {
2735 char * name;
2736
2737 if (dynamic_strings == NULL)
2738 name = NULL;
2739 else
2740 name = dynamic_strings + entry->d_un.d_val;
2741
2742 if (name)
2743 {
2744 switch (entry->d_tag)
2745 {
2746 case DT_NEEDED:
2747 printf (_("Shared library: [%s]"), name);
2748
2749 if (strcmp (name, program_interpreter))
2750 printf ("\n");
2751 else
2752 printf (_(" program interpreter\n"));
2753 break;
2754
2755 case DT_SONAME:
2756 printf (_("Library soname: [%s]\n"), name);
2757 break;
2758
2759 case DT_RPATH:
2760 printf (_("Library rpath: [%s]\n"), name);
2761 break;
2762
2763 default:
2764 printf ("%#lx\n", (long) entry->d_un.d_val);
2765 }
2766 }
2767 else
2768 printf ("%#lx\n", (long) entry->d_un.d_val);
2769 }
2770 break;
2771
2772 case DT_PLTRELSZ:
2773 case DT_RELASZ :
2774 case DT_STRSZ :
2775 case DT_RELSZ :
2776 case DT_RELAENT :
2777 case DT_SYMENT :
2778 case DT_RELENT :
2779 case DT_PLTPADSZ:
2780 case DT_MOVEENT :
2781 case DT_MOVESZ :
2782 case DT_INIT_ARRAYSZ:
2783 case DT_FINI_ARRAYSZ:
2784 if (do_dynamic)
2785 printf ("%lu (bytes)\n", (unsigned long) entry->d_un.d_val);
2786 break;
2787
2788 case DT_VERDEFNUM:
2789 case DT_VERNEEDNUM:
2790 case DT_RELACOUNT:
2791 case DT_RELCOUNT:
2792 if (do_dynamic)
2793 printf ("%lu\n", (unsigned long) entry->d_un.d_val);
2794 break;
2795
2796 case DT_SYMINSZ:
2797 case DT_SYMINENT:
2798 case DT_SYMINFO:
2799 case DT_USED:
2800 case DT_INIT_ARRAY:
2801 case DT_FINI_ARRAY:
2802 if (do_dynamic)
2803 {
2804 if (dynamic_strings != NULL && entry->d_tag == DT_USED)
2805 {
2806 char * name;
2807
2808 name = dynamic_strings + entry->d_un.d_val;
2809
2810 if (* name)
2811 {
2812 printf (_("Not needed object: [%s]\n"), name);
2813 break;
2814 }
2815 }
2816
2817 printf ("%#lx\n", (long) entry->d_un.d_val);
2818 }
2819 break;
2820
2821 case DT_BIND_NOW:
2822 /* The value of this entry is ignored. */
2823 break;
2824
2825 default:
2826 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
2827 version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
2828 entry->d_un.d_val;
2829
2830 if (do_dynamic)
2831 {
2832 switch (elf_header.e_machine)
2833 {
2834 case EM_MIPS:
2835 case EM_MIPS_RS4_BE:
2836 dynamic_segment_mips_val (entry);
2837 break;
2838 default:
2839 printf ("%#lx\n", (long) entry->d_un.d_ptr);
2840 }
2841 }
2842 break;
2843 }
2844 }
2845
2846 return 1;
2847}
2848
2849static char *
2850get_ver_flags (flags)
2851 unsigned int flags;
2852{
2853 static char buff [32];
2854
2855 buff[0] = 0;
2856
2857 if (flags == 0)
2858 return _("none");
2859
2860 if (flags & VER_FLG_BASE)
2861 strcat (buff, "BASE ");
2862
2863 if (flags & VER_FLG_WEAK)
2864 {
2865 if (flags & VER_FLG_BASE)
2866 strcat (buff, "| ");
2867
2868 strcat (buff, "WEAK ");
2869 }
2870
2871 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
2872 strcat (buff, "| <unknown>");
2873
2874 return buff;
2875}
2876
2877/* Display the contents of the version sections. */
2878static int
2879process_version_sections (file)
2880 FILE * file;
2881{
2882 Elf32_Internal_Shdr * section;
2883 unsigned i;
2884 int found = 0;
2885
2886 if (! do_version)
2887 return 1;
2888
2889 for (i = 0, section = section_headers;
2890 i < elf_header.e_shnum;
2891 i++, section ++)
2892 {
2893 switch (section->sh_type)
2894 {
2895 case SHT_GNU_verdef:
2896 {
2897 Elf_External_Verdef * edefs;
2898 unsigned int idx;
2899 unsigned int cnt;
2900
2901 found = 1;
2902
2903 printf
2904 (_("\nVersion definition section '%s' contains %ld entries:\n"),
2905 SECTION_NAME (section), section->sh_info);
2906
2907 printf (_(" Addr: 0x"));
2908 printf_vma (section->sh_addr);
2909 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 2910 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
2911 SECTION_NAME (section_headers + section->sh_link));
2912
2913 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2914 edefs, Elf_External_Verdef *,
2915 "version definition section");
2916
2917 for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
2918 {
2919 char * vstart;
2920 Elf_External_Verdef * edef;
2921 Elf_Internal_Verdef ent;
2922 Elf_External_Verdaux * eaux;
2923 Elf_Internal_Verdaux aux;
2924 int j;
2925 int isum;
2926
2927 vstart = ((char *) edefs) + idx;
2928
2929 edef = (Elf_External_Verdef *) vstart;
2930
2931 ent.vd_version = BYTE_GET (edef->vd_version);
2932 ent.vd_flags = BYTE_GET (edef->vd_flags);
2933 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
2934 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
2935 ent.vd_hash = BYTE_GET (edef->vd_hash);
2936 ent.vd_aux = BYTE_GET (edef->vd_aux);
2937 ent.vd_next = BYTE_GET (edef->vd_next);
2938
2939 printf (_(" %#06x: Rev: %d Flags: %s"),
2940 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
2941
2942 printf (_(" Index: %d Cnt: %d "),
2943 ent.vd_ndx, ent.vd_cnt);
2944
2945 vstart += ent.vd_aux;
2946
2947 eaux = (Elf_External_Verdaux *) vstart;
2948
2949 aux.vda_name = BYTE_GET (eaux->vda_name);
2950 aux.vda_next = BYTE_GET (eaux->vda_next);
2951
2952 if (dynamic_strings)
2953 printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
2954 else
2955 printf (_("Name index: %ld\n"), aux.vda_name);
2956
2957 isum = idx + ent.vd_aux;
2958
2959 for (j = 1; j < ent.vd_cnt; j ++)
2960 {
2961 isum += aux.vda_next;
2962 vstart += aux.vda_next;
2963
2964 eaux = (Elf_External_Verdaux *) vstart;
2965
2966 aux.vda_name = BYTE_GET (eaux->vda_name);
2967 aux.vda_next = BYTE_GET (eaux->vda_next);
2968
2969 if (dynamic_strings)
2970 printf (_(" %#06x: Parent %d: %s\n"),
2971 isum, j, dynamic_strings + aux.vda_name);
2972 else
2973 printf (_(" %#06x: Parent %d, name index: %ld\n"),
2974 isum, j, aux.vda_name);
2975 }
2976
2977 idx += ent.vd_next;
2978 }
2979
2980 free (edefs);
2981 }
2982 break;
2983
2984 case SHT_GNU_verneed:
2985 {
2986 Elf_External_Verneed * eneed;
2987 unsigned int idx;
2988 unsigned int cnt;
2989
2990 found = 1;
2991
2992 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
2993 SECTION_NAME (section), section->sh_info);
2994
2995 printf (_(" Addr: 0x"));
2996 printf_vma (section->sh_addr);
2997 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
1b228002 2998 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
2999 SECTION_NAME (section_headers + section->sh_link));
3000
3001 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
3002 eneed, Elf_External_Verneed *,
3003 "version need section");
3004
3005 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
3006 {
3007 Elf_External_Verneed * entry;
3008 Elf_Internal_Verneed ent;
3009 int j;
3010 int isum;
3011 char * vstart;
3012
3013 vstart = ((char *) eneed) + idx;
3014
3015 entry = (Elf_External_Verneed *) vstart;
3016
3017 ent.vn_version = BYTE_GET (entry->vn_version);
3018 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
3019 ent.vn_file = BYTE_GET (entry->vn_file);
3020 ent.vn_aux = BYTE_GET (entry->vn_aux);
3021 ent.vn_next = BYTE_GET (entry->vn_next);
3022
3023 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
3024
3025 if (dynamic_strings)
3026 printf (_(" File: %s"), dynamic_strings + ent.vn_file);
3027 else
3028 printf (_(" File: %lx"), ent.vn_file);
3029
3030 printf (_(" Cnt: %d\n"), ent.vn_cnt);
3031
3032 vstart += ent.vn_aux;
3033
3034 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
3035 {
3036 Elf_External_Vernaux * eaux;
3037 Elf_Internal_Vernaux aux;
3038
3039 eaux = (Elf_External_Vernaux *) vstart;
3040
3041 aux.vna_hash = BYTE_GET (eaux->vna_hash);
3042 aux.vna_flags = BYTE_GET (eaux->vna_flags);
3043 aux.vna_other = BYTE_GET (eaux->vna_other);
3044 aux.vna_name = BYTE_GET (eaux->vna_name);
3045 aux.vna_next = BYTE_GET (eaux->vna_next);
3046
3047 if (dynamic_strings)
3048 printf (_(" %#06x: Name: %s"),
3049 isum, dynamic_strings + aux.vna_name);
3050 else
3051 printf (_(" %#06x: Name index: %lx"),
3052 isum, aux.vna_name);
3053
3054 printf (_(" Flags: %s Version: %d\n"),
3055 get_ver_flags (aux.vna_flags), aux.vna_other);
3056
3057 isum += aux.vna_next;
3058 vstart += aux.vna_next;
3059 }
3060
3061 idx += ent.vn_next;
3062 }
3063
3064 free (eneed);
3065 }
3066 break;
3067
3068 case SHT_GNU_versym:
3069 {
3070 Elf32_Internal_Shdr * link_section;
3071 int total;
3072 int cnt;
3073 unsigned char * edata;
3074 unsigned short * data;
3075 char * strtab;
3076 Elf_Internal_Sym * symbols;
3077 Elf32_Internal_Shdr * string_sec;
3078
3079 link_section = section_headers + section->sh_link;
3080 total = section->sh_size / section->sh_entsize;
3081
3082 found = 1;
3083
9ea033b2
NC
3084 symbols = GET_ELF_SYMBOLS (file, link_section->sh_offset,
3085 link_section->sh_size / link_section->sh_entsize);
252b5132
RH
3086
3087 string_sec = section_headers + link_section->sh_link;
3088
3089 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
3090 strtab, char *, "version string table");
3091
3092 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
3093 SECTION_NAME (section), total);
3094
3095 printf (_(" Addr: "));
3096 printf_vma (section->sh_addr);
3097 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 3098 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
3099 SECTION_NAME (link_section));
3100
3101 GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
3102 - loadaddr,
3103 total * sizeof (short), edata,
3104 unsigned char *, "version symbol data");
3105
3106 data = (unsigned short *) malloc (total * sizeof (short));
3107
3108 for (cnt = total; cnt --;)
3109 data [cnt] = byte_get (edata + cnt * sizeof (short),
3110 sizeof (short));
3111
3112 free (edata);
3113
3114 for (cnt = 0; cnt < total; cnt += 4)
3115 {
3116 int j, nn;
3117
3118 printf (" %03x:", cnt);
3119
3120 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
3121 switch (data [cnt + j])
3122 {
3123 case 0:
3124 fputs (_(" 0 (*local*) "), stdout);
3125 break;
3126
3127 case 1:
3128 fputs (_(" 1 (*global*) "), stdout);
3129 break;
3130
3131 default:
3132 nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
3133 data [cnt + j] & 0x8000 ? 'h' : ' ');
3134
3135 if (symbols [cnt + j].st_shndx < SHN_LORESERVE
3136 && section_headers[symbols [cnt + j].st_shndx].sh_type
3137 == SHT_NOBITS)
3138 {
3139 /* We must test both. */
3140 Elf_Internal_Verneed ivn;
3141 unsigned long offset;
3142
3143 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
3144 - loadaddr;
3145
3146 do
3147 {
3148 Elf_External_Verneed evn;
3149 Elf_External_Vernaux evna;
3150 Elf_Internal_Vernaux ivna;
3151 unsigned long vna_off;
3152
3153 GET_DATA (offset, evn, "version need");
3154
3155 ivn.vn_aux = BYTE_GET (evn.vn_aux);
3156 ivn.vn_next = BYTE_GET (evn.vn_next);
3157
3158 vna_off = offset + ivn.vn_aux;
3159
3160 do
3161 {
3162 GET_DATA (vna_off, evna,
3163 "version need aux (1)");
3164
3165 ivna.vna_next = BYTE_GET (evna.vna_next);
3166 ivna.vna_other = BYTE_GET (evna.vna_other);
3167
3168 vna_off += ivna.vna_next;
3169 }
3170 while (ivna.vna_other != data [cnt + j]
3171 && ivna.vna_next != 0);
3172
3173 if (ivna.vna_other == data [cnt + j])
3174 {
3175 ivna.vna_name = BYTE_GET (evna.vna_name);
3176
3177 nn += printf ("(%s%-*s",
3178 strtab + ivna.vna_name,
3179 12 - strlen (strtab
3180 + ivna.vna_name),
3181 ")");
3182 break;
3183 }
3184 else if (ivn.vn_next == 0)
3185 {
3186 if (data [cnt + j] != 0x8001)
3187 {
3188 Elf_Internal_Verdef ivd;
3189 Elf_External_Verdef evd;
3190
3191 offset = version_info
3192 [DT_VERSIONTAGIDX (DT_VERDEF)]
3193 - loadaddr;
3194
3195 do
3196 {
3197 GET_DATA (offset, evd,
3198 "version definition");
3199
3200 ivd.vd_next = BYTE_GET (evd.vd_next);
3201 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
3202
3203 offset += ivd.vd_next;
3204 }
3205 while (ivd.vd_ndx
3206 != (data [cnt + j] & 0x7fff)
3207 && ivd.vd_next != 0);
3208
3209 if (ivd.vd_ndx
3210 == (data [cnt + j] & 0x7fff))
3211 {
3212 Elf_External_Verdaux evda;
3213 Elf_Internal_Verdaux ivda;
3214
3215 ivd.vd_aux = BYTE_GET (evd.vd_aux);
3216
3217 GET_DATA (offset + ivd.vd_aux, evda,
3218 "version definition aux");
3219
3220 ivda.vda_name =
3221 BYTE_GET (evda.vda_name);
3222
3223 nn +=
3224 printf ("(%s%-*s",
3225 strtab + ivda.vda_name,
3226 12
3227 - strlen (strtab
3228 + ivda.vda_name),
3229 ")");
3230 }
3231 }
3232
3233 break;
3234 }
3235 else
3236 offset += ivn.vn_next;
3237 }
3238 while (ivn.vn_next);
3239 }
3240 else if (symbols [cnt + j].st_shndx == SHN_UNDEF)
3241 {
3242 Elf_Internal_Verneed ivn;
3243 unsigned long offset;
3244
3245 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
3246 - loadaddr;
3247
3248 do
3249 {
3250 Elf_Internal_Vernaux ivna;
3251 Elf_External_Verneed evn;
3252 Elf_External_Vernaux evna;
3253 unsigned long a_off;
3254
3255 GET_DATA (offset, evn, "version need");
3256
3257 ivn.vn_aux = BYTE_GET (evn.vn_aux);
3258 ivn.vn_next = BYTE_GET (evn.vn_next);
3259
3260 a_off = offset + ivn.vn_aux;
3261
3262 do
3263 {
3264 GET_DATA (a_off, evna,
3265 "version need aux (2)");
3266
3267 ivna.vna_next = BYTE_GET (evna.vna_next);
3268 ivna.vna_other = BYTE_GET (evna.vna_other);
3269
3270 a_off += ivna.vna_next;
3271 }
3272 while (ivna.vna_other != data [cnt + j]
3273 && ivna.vna_next != 0);
3274
3275 if (ivna.vna_other == data [cnt + j])
3276 {
3277 ivna.vna_name = BYTE_GET (evna.vna_name);
3278
3279 nn += printf ("(%s%-*s",
3280 strtab + ivna.vna_name,
3281 12 - strlen (strtab
3282 + ivna.vna_name),
3283 ")");
3284 break;
3285 }
3286
3287 offset += ivn.vn_next;
3288 }
3289 while (ivn.vn_next);
3290 }
3291 else if (data [cnt + j] != 0x8001)
3292 {
3293 Elf_Internal_Verdef ivd;
3294 Elf_External_Verdef evd;
3295 unsigned long offset;
3296
3297 offset = version_info
3298 [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
3299
3300 do
3301 {
3302 GET_DATA (offset, evd, "version def");
3303
3304 ivd.vd_next = BYTE_GET (evd.vd_next);
3305 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
3306
3307 offset += ivd.vd_next;
3308 }
3309 while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
3310 && ivd.vd_next != 0);
3311
3312 if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
3313 {
3314 Elf_External_Verdaux evda;
3315 Elf_Internal_Verdaux ivda;
3316
3317 ivd.vd_aux = BYTE_GET (evd.vd_aux);
3318
3319 GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
3320 evda, "version def aux");
3321
3322 ivda.vda_name = BYTE_GET (evda.vda_name);
3323
3324 nn += printf ("(%s%-*s",
3325 strtab + ivda.vda_name,
3326 12 - strlen (strtab
3327 + ivda.vda_name),
3328 ")");
3329 }
3330 }
3331
3332 if (nn < 18)
3333 printf ("%*c", 18 - nn, ' ');
3334 }
3335
3336 putchar ('\n');
3337 }
3338
3339 free (data);
3340 free (strtab);
3341 free (symbols);
3342 }
3343 break;
3344
3345 default:
3346 break;
3347 }
3348 }
3349
3350 if (! found)
3351 printf (_("\nNo version information found in this file.\n"));
3352
3353 return 1;
3354}
3355
3356static char *
3357get_symbol_binding (binding)
3358 unsigned int binding;
3359{
3360 static char buff [32];
3361
3362 switch (binding)
3363 {
3364 case STB_LOCAL: return _("LOCAL");
3365 case STB_GLOBAL: return _("GLOBAL");
3366 case STB_WEAK: return _("WEAK");
3367 default:
3368 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
3369 sprintf (buff, _("<processor specific>: %d"), binding);
3370 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3371 sprintf (buff, _("<OS specific>: %d"), binding);
3372 else
3373 sprintf (buff, _("<unknown>: %d"), binding);
3374 return buff;
3375 }
3376}
3377
3378static char *
3379get_symbol_type (type)
3380 unsigned int type;
3381{
3382 static char buff [32];
3383
3384 switch (type)
3385 {
3386 case STT_NOTYPE: return _("NOTYPE");
3387 case STT_OBJECT: return _("OBJECT");
3388 case STT_FUNC: return _("FUNC");
3389 case STT_SECTION: return _("SECTION");
3390 case STT_FILE: return _("FILE");
3391 default:
3392 if (type >= STT_LOPROC && type <= STT_HIPROC)
3393 sprintf (buff, _("<processor specific>: %d"), type);
3394 else if (type >= STT_LOOS && type <= STT_HIOS)
3395 sprintf (buff, _("<OS specific>: %d"), type);
3396 else
3397 sprintf (buff, _("<unknown>: %d"), type);
3398 return buff;
3399 }
3400}
3401
3402static char *
3403get_symbol_index_type (type)
3404 unsigned int type;
3405{
3406 switch (type)
3407 {
3408 case SHN_UNDEF: return "UND";
3409 case SHN_ABS: return "ABS";
3410 case SHN_COMMON: return "COM";
3411 default:
3412 if (type >= SHN_LOPROC && type <= SHN_HIPROC)
3413 return "PRC";
3414 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
3415 return "RSV";
3416 else if (type >= SHN_LOOS && type <= SHN_HIOS)
3417 return "OS ";
3418 else
3419 {
3420 static char buff [32];
3421
3422 sprintf (buff, "%3d", type);
3423 return buff;
3424 }
3425 }
3426}
3427
3428
3429static int *
3430get_dynamic_data (file, number)
3431 FILE * file;
3432 unsigned int number;
3433{
3434 char * e_data;
3435 int * i_data;
3436
3437 e_data = (char *) malloc (number * 4);
3438
3439 if (e_data == NULL)
3440 {
3441 error (_("Out of memory\n"));
3442 return NULL;
3443 }
3444
3445 if (fread (e_data, 4, number, file) != number)
3446 {
3447 error (_("Unable to read in dynamic data\n"));
3448 return NULL;
3449 }
3450
3451 i_data = (int *) malloc (number * sizeof (* i_data));
3452
3453 if (i_data == NULL)
3454 {
3455 error (_("Out of memory\n"));
3456 free (e_data);
3457 return NULL;
3458 }
3459
3460 while (number--)
3461 i_data [number] = byte_get (e_data + number * 4, 4);
3462
3463 free (e_data);
3464
3465 return i_data;
3466}
3467
3468/* Dump the symbol table */
3469static int
3470process_symbol_table (file)
3471 FILE * file;
3472{
3473 Elf32_Internal_Shdr * section;
3474 char nb [4];
3475 char nc [4];
3476 int nbuckets;
3477 int nchains;
3478 int * buckets = NULL;
3479 int * chains = NULL;
3480
3481 if (! do_syms && !do_histogram)
3482 return 1;
3483
3484 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
3485 || do_histogram))
3486 {
3487 if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
3488 {
3489 error (_("Unable to seek to start of dynamic information"));
3490 return 0;
3491 }
3492
3493 if (fread (nb, sizeof (nb), 1, file) != 1)
3494 {
3495 error (_("Failed to read in number of buckets\n"));
3496 return 0;
3497 }
3498
3499 if (fread (nc, sizeof (nc), 1, file) != 1)
3500 {
3501 error (_("Failed to read in number of chains\n"));
3502 return 0;
3503 }
3504
3505 nbuckets = byte_get (nb, 4);
3506 nchains = byte_get (nc, 4);
3507
3508 buckets = get_dynamic_data (file, nbuckets);
3509 chains = get_dynamic_data (file, nchains);
3510
3511 if (buckets == NULL || chains == NULL)
3512 return 0;
3513 }
3514
3515 if (do_syms
3516 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
3517 {
3518 int hn;
3519 int si;
3520
3521 printf (_("\nSymbol table for image:\n"));
3522 printf (_(" Num Buc: Value Size Type Bind Ot Ndx Name\n"));
3523
3524 for (hn = 0; hn < nbuckets; hn++)
3525 {
3526 if (! buckets [hn])
3527 continue;
3528
3529 for (si = buckets [hn]; si; si = chains [si])
3530 {
3531 Elf_Internal_Sym * psym;
3532
3533 psym = dynamic_symbols + si;
3534
3535 printf (" %3d %3d: %8lx %5ld %6s %6s %2d ",
3536 si, hn,
3537 (unsigned long) psym->st_value,
3538 (unsigned long) psym->st_size,
3539 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3540 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3541 psym->st_other);
3542
3543 printf ("%3.3s", get_symbol_index_type (psym->st_shndx));
3544
3545 printf (" %s\n", dynamic_strings + psym->st_name);
3546 }
3547 }
3548 }
3549 else if (do_syms && !do_using_dynamic)
3550 {
3551 unsigned int i;
3552
3553 for (i = 0, section = section_headers;
3554 i < elf_header.e_shnum;
3555 i++, section++)
3556 {
3557 unsigned int si;
3558 char * strtab;
3559 Elf_Internal_Sym * symtab;
3560 Elf_Internal_Sym * psym;
3561
3562
3563 if ( section->sh_type != SHT_SYMTAB
3564 && section->sh_type != SHT_DYNSYM)
3565 continue;
3566
3567 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
3568 SECTION_NAME (section),
3569 (unsigned long) (section->sh_size / section->sh_entsize));
3570 fputs (_(" Num: Value Size Type Bind Ot Ndx Name\n"),
3571 stdout);
3572
9ea033b2 3573 symtab = GET_ELF_SYMBOLS (file, section->sh_offset,
252b5132
RH
3574 section->sh_size / section->sh_entsize);
3575 if (symtab == NULL)
3576 continue;
3577
3578 if (section->sh_link == elf_header.e_shstrndx)
3579 strtab = string_table;
3580 else
3581 {
3582 Elf32_Internal_Shdr * string_sec;
3583
3584 string_sec = section_headers + section->sh_link;
3585
3586 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
3587 strtab, char *, "string table");
3588 }
3589
3590 for (si = 0, psym = symtab;
3591 si < section->sh_size / section->sh_entsize;
3592 si ++, psym ++)
3593 {
3594 printf (" %3d: %8lx %5ld %-7s %-6s %2d ",
3595 si,
3596 (unsigned long) psym->st_value,
3597 (unsigned long) psym->st_size,
3598 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3599 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3600 psym->st_other);
3601
1b228002 3602 printf ("%4s", get_symbol_index_type (psym->st_shndx));
252b5132
RH
3603
3604 printf (" %s", strtab + psym->st_name);
3605
3606 if (section->sh_type == SHT_DYNSYM &&
3607 version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
3608 {
3609 unsigned char data[2];
3610 unsigned short vers_data;
3611 unsigned long offset;
3612 int is_nobits;
3613 int check_def;
3614
3615 offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
3616 - loadaddr;
3617
3618 GET_DATA (offset + si * sizeof (vers_data), data,
3619 "version data");
3620
3621 vers_data = byte_get (data, 2);
3622
3623 is_nobits = psym->st_shndx < SHN_LORESERVE ?
3624 (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
3625 : 0;
3626
3627 check_def = (psym->st_shndx != SHN_UNDEF);
3628
3629 if ((vers_data & 0x8000) || vers_data > 1)
3630 {
3631 if (is_nobits || ! check_def)
3632 {
3633 Elf_External_Verneed evn;
3634 Elf_Internal_Verneed ivn;
3635 Elf_Internal_Vernaux ivna;
3636
3637 /* We must test both. */
3638 offset = version_info
3639 [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
3640
3641 GET_DATA (offset, evn, "version need");
3642
3643 ivn.vn_aux = BYTE_GET (evn.vn_aux);
3644 ivn.vn_next = BYTE_GET (evn.vn_next);
3645
3646 do
3647 {
3648 unsigned long vna_off;
3649
3650 vna_off = offset + ivn.vn_aux;
3651
3652 do
3653 {
3654 Elf_External_Vernaux evna;
3655
3656 GET_DATA (vna_off, evna,
3657 "version need aux (3)");
3658
3659 ivna.vna_other = BYTE_GET (evna.vna_other);
3660 ivna.vna_next = BYTE_GET (evna.vna_next);
3661 ivna.vna_name = BYTE_GET (evna.vna_name);
3662
3663 vna_off += ivna.vna_next;
3664 }
3665 while (ivna.vna_other != vers_data
3666 && ivna.vna_next != 0);
3667
3668 if (ivna.vna_other == vers_data)
3669 break;
3670
3671 offset += ivn.vn_next;
3672 }
3673 while (ivn.vn_next != 0);
3674
3675 if (ivna.vna_other == vers_data)
3676 {
3677 printf ("@%s (%d)",
3678 strtab + ivna.vna_name, ivna.vna_other);
3679 check_def = 0;
3680 }
3681 else if (! is_nobits)
3682 error (_("bad dynamic symbol"));
3683 else
3684 check_def = 1;
3685 }
3686
3687 if (check_def)
3688 {
3689 if (vers_data != 0x8001)
3690 {
3691 Elf_Internal_Verdef ivd;
3692 Elf_Internal_Verdaux ivda;
3693 Elf_External_Verdaux evda;
3694 unsigned long offset;
3695
3696 offset =
3697 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
3698 - loadaddr;
3699
3700 do
3701 {
3702 Elf_External_Verdef evd;
3703
3704 GET_DATA (offset, evd, "version def");
3705
3706 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
3707 ivd.vd_aux = BYTE_GET (evd.vd_aux);
3708 ivd.vd_next = BYTE_GET (evd.vd_next);
3709
3710 offset += ivd.vd_next;
3711 }
3712 while (ivd.vd_ndx != (vers_data & 0x7fff)
3713 && ivd.vd_next != 0);
3714
3715 offset -= ivd.vd_next;
3716 offset += ivd.vd_aux;
3717
3718 GET_DATA (offset, evda, "version def aux");
3719
3720 ivda.vda_name = BYTE_GET (evda.vda_name);
3721
3722 if (psym->st_name != ivda.vda_name)
3723 printf ((vers_data & 0x8000)
3724 ? "@%s" : "@@%s",
3725 strtab + ivda.vda_name);
3726 }
3727 }
3728 }
3729 }
3730
3731 putchar ('\n');
3732 }
3733
3734 free (symtab);
3735 if (strtab != string_table)
3736 free (strtab);
3737 }
3738 }
3739 else if (do_syms)
3740 printf
3741 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
3742
3743 if (do_histogram && buckets != NULL)
3744 {
3745 int *lengths;
3746 int *counts;
3747 int hn;
3748 int si;
3749 int maxlength = 0;
3750 int nzero_counts = 0;
3751 int nsyms = 0;
3752
3753 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
3754 nbuckets);
3755 printf (_(" Length Number %% of total Coverage\n"));
3756
3757 lengths = (int *) calloc (nbuckets, sizeof (int));
3758 if (lengths == NULL)
3759 {
3760 error (_("Out of memory"));
3761 return 0;
3762 }
3763 for (hn = 0; hn < nbuckets; ++hn)
3764 {
3765 if (! buckets [hn])
3766 continue;
3767
3768 for (si = buckets[hn]; si; si = chains[si])
3769 {
3770 ++nsyms;
3771 if (maxlength < ++lengths[hn])
3772 ++maxlength;
3773 }
3774 }
3775
3776 counts = (int *) calloc (maxlength + 1, sizeof (int));
3777 if (counts == NULL)
3778 {
3779 error (_("Out of memory"));
3780 return 0;
3781 }
3782
3783 for (hn = 0; hn < nbuckets; ++hn)
3784 ++ counts [lengths [hn]];
3785
3786 printf (" 0 %-10d (%5.1f%%)\n",
3787 counts[0], (counts[0] * 100.0) / nbuckets);
3788 for (si = 1; si <= maxlength; ++si)
3789 {
3790 nzero_counts += counts[si] * si;
3791 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
3792 si, counts[si], (counts[si] * 100.0) / nbuckets,
3793 (nzero_counts * 100.0) / nsyms);
3794 }
3795
3796 free (counts);
3797 free (lengths);
3798 }
3799
3800 if (buckets != NULL)
3801 {
3802 free (buckets);
3803 free (chains);
3804 }
3805
3806 return 1;
3807}
3808
3809static int
3810process_syminfo (file)
3811 FILE * file;
3812{
3813 int i;
3814
3815 if (dynamic_syminfo == NULL
3816 || !do_dynamic)
3817 /* No syminfo, this is ok. */
3818 return 1;
3819
3820 /* There better should be a dynamic symbol section. */
3821 if (dynamic_symbols == NULL || dynamic_strings == NULL)
3822 return 0;
3823
3824 if (dynamic_addr)
3825 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
3826 dynamic_syminfo_offset, dynamic_syminfo_nent);
3827
3828 printf (_(" Num: Name BoundTo Flags\n"));
3829 for (i = 0; i < dynamic_syminfo_nent; ++i)
3830 {
3831 unsigned short int flags = dynamic_syminfo[i].si_flags;
3832
3833 printf ("%4d: %-30s ", i,
3834 dynamic_strings + dynamic_symbols[i].st_name);
3835
3836 switch (dynamic_syminfo[i].si_boundto)
3837 {
3838 case SYMINFO_BT_SELF:
3839 fputs ("SELF ", stdout);
3840 break;
3841 case SYMINFO_BT_PARENT:
3842 fputs ("PARENT ", stdout);
3843 break;
3844 default:
3845 if (dynamic_syminfo[i].si_boundto > 0
3846 && dynamic_syminfo[i].si_boundto < dynamic_size)
3847 printf ("%-10s ",
3848 dynamic_strings
3849 + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
3850 else
3851 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
3852 break;
3853 }
3854
3855 if (flags & SYMINFO_FLG_DIRECT)
3856 printf (" DIRECT");
3857 if (flags & SYMINFO_FLG_PASSTHRU)
3858 printf (" PASSTHRU");
3859 if (flags & SYMINFO_FLG_COPY)
3860 printf (" COPY");
3861 if (flags & SYMINFO_FLG_LAZYLOAD)
3862 printf (" LAZYLOAD");
3863
3864 puts ("");
3865 }
3866
3867 return 1;
3868}
3869
3870#ifdef SUPPORT_DISASSEMBLY
3871static void
3872disassemble_section (section, file)
3873 Elf32_Internal_Shdr * section;
3874 FILE * file;
3875{
3876 printf (_("\nAssembly dump of section %s\n"),
3877 SECTION_NAME (section));
3878
3879 /* XXX -- to be done --- XXX */
3880
3881 return 1;
3882}
3883#endif
3884
3885static int
3886dump_section (section, file)
3887 Elf32_Internal_Shdr * section;
3888 FILE * file;
3889{
9ea033b2
NC
3890 bfd_size_type bytes;
3891 bfd_vma addr;
252b5132
RH
3892 unsigned char * data;
3893 unsigned char * start;
3894
3895 bytes = section->sh_size;
3896
3897 if (bytes == 0)
3898 {
3899 printf (_("\nSection '%s' has no data to dump.\n"),
3900 SECTION_NAME (section));
3901 return 0;
3902 }
3903 else
3904 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
3905
3906 addr = section->sh_addr;
3907
3908 GET_DATA_ALLOC (section->sh_offset, bytes, start, unsigned char *,
3909 "section data");
3910
3911 data = start;
3912
3913 while (bytes)
3914 {
3915 int j;
3916 int k;
3917 int lbytes;
3918
3919 lbytes = (bytes > 16 ? 16 : bytes);
3920
148d3c43 3921 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132
RH
3922
3923 switch (elf_header.e_ident [EI_DATA])
3924 {
9ea033b2 3925 default:
252b5132
RH
3926 case ELFDATA2LSB:
3927 for (j = 15; j >= 0; j --)
3928 {
3929 if (j < lbytes)
3930 printf ("%2.2x", data [j]);
3931 else
3932 printf (" ");
3933
3934 if (!(j & 0x3))
3935 printf (" ");
3936 }
3937 break;
3938
3939 case ELFDATA2MSB:
3940 for (j = 0; j < 16; j++)
3941 {
3942 if (j < lbytes)
3943 printf ("%2.2x", data [j]);
3944 else
3945 printf (" ");
3946
3947 if ((j & 3) == 3)
3948 printf (" ");
3949 }
3950 break;
3951 }
3952
3953 for (j = 0; j < lbytes; j++)
3954 {
3955 k = data [j];
3956 if (k >= ' ' && k < 0x80)
3957 printf ("%c", k);
3958 else
3959 printf (".");
3960 }
3961
3962 putchar ('\n');
3963
3964 data += lbytes;
3965 addr += lbytes;
3966 bytes -= lbytes;
3967 }
3968
3969 free (start);
3970
3971 return 1;
3972}
3973
3974
3975static unsigned long int
3976read_leb128 (data, length_return, sign)
3977 unsigned char * data;
3978 int * length_return;
3979 int sign;
3980{
3981 unsigned long int result = 0;
3982 unsigned int num_read = 0;
3983 int shift = 0;
3984 unsigned char byte;
3985
3986 do
3987 {
3988 byte = * data ++;
3989 num_read ++;
3990
3991 result |= (byte & 0x7f) << shift;
3992
3993 shift += 7;
3994
3995 }
3996 while (byte & 0x80);
3997
3998 if (length_return != NULL)
3999 * length_return = num_read;
4000
4001 if (sign && (shift < 32) && (byte & 0x40))
4002 result |= -1 << shift;
4003
4004 return result;
4005}
4006
4007typedef struct State_Machine_Registers
4008{
4009 unsigned long address;
4010 unsigned int file;
4011 unsigned int line;
4012 unsigned int column;
4013 int is_stmt;
4014 int basic_block;
4015 int end_sequence;
4016/* This variable hold the number of the last entry seen
4017 in the File Table. */
4018 unsigned int last_file_entry;
4019} SMR;
4020
4021static SMR state_machine_regs;
4022
4023static void
4024reset_state_machine (is_stmt)
4025 int is_stmt;
4026{
4027 state_machine_regs.address = 0;
4028 state_machine_regs.file = 1;
4029 state_machine_regs.line = 1;
4030 state_machine_regs.column = 0;
4031 state_machine_regs.is_stmt = is_stmt;
4032 state_machine_regs.basic_block = 0;
4033 state_machine_regs.end_sequence = 0;
4034 state_machine_regs.last_file_entry = 0;
4035}
4036
4037/* Handled an extend line op. Returns true if this is the end
4038 of sequence. */
4039static int
4040process_extended_line_op (data, is_stmt)
4041 unsigned char * data;
4042 int is_stmt;
4043{
4044 unsigned char op_code;
4045 int bytes_read;
4046 unsigned int len;
4047 unsigned char * name;
4048 unsigned long adr;
4049
4050 len = read_leb128 (data, & bytes_read, 0);
4051 data += bytes_read;
4052
4053 if (len == 0)
4054 {
4055 warn (_("badly formed extended line op encountered!"));
4056 return bytes_read;
4057 }
4058
4059 len += bytes_read;
4060 op_code = * data ++;
4061
4062 printf (_(" Extended opcode %d: "), op_code);
4063
4064 switch (op_code)
4065 {
4066 case DW_LNE_end_sequence:
4067 printf (_("End of Sequence\n\n"));
4068 reset_state_machine (is_stmt);
4069 break;
4070
4071 case DW_LNE_set_address:
4072 /* XXX - assumption here that address size is 4! */
4073 adr = byte_get (data, 4);
4074 printf (_("set Address to 0x%lx\n"), adr);
4075 state_machine_regs.address = adr;
4076 break;
4077
4078 case DW_LNE_define_file:
4079 printf (_(" define new File Table entry\n"));
4080 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
4081
4082 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
4083 name = data;
4084 data += strlen (data) + 1;
4085 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4086 data += bytes_read;
4087 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4088 data += bytes_read;
4089 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4090 printf (_("%s\n\n"), name);
4091 break;
4092
4093 default:
4094 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
4095 break;
4096 }
4097
4098 return len;
4099}
4100
4101
4102static int
4103display_debug_lines (section, start, file)
4104 Elf32_Internal_Shdr * section;
4105 unsigned char * start;
4106 FILE * file;
4107{
4108 DWARF2_External_LineInfo * external;
4109 DWARF2_Internal_LineInfo info;
4110 unsigned char * standard_opcodes;
4111 unsigned char * data = start;
4112 unsigned char * end = start + section->sh_size;
4113 unsigned char * end_of_sequence;
4114 int i;
4115
4116 printf (_("\nDump of debug contents of section %s:\n\n"),
4117 SECTION_NAME (section));
4118
4119 while (data < end)
4120 {
4121 external = (DWARF2_External_LineInfo *) data;
4122
4123 /* Check the length of the block. */
4124 info.li_length = BYTE_GET (external->li_length);
4125 if (info.li_length > section->sh_size)
4126 {
4127 warn
4128 (_("The line info appears to be corrupt - the section is too small\n"));
4129 return 0;
4130 }
4131
4132 /* Check its version number. */
4133 info.li_version = BYTE_GET (external->li_version);
4134 if (info.li_version != 2)
4135 {
4136 warn (_("Only DWARF version 2 line info is currently supported.\n"));
4137 return 0;
4138 }
4139
4140 info.li_prologue_length = BYTE_GET (external->li_prologue_length);
4141 info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
4142 info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
4143 info.li_line_base = BYTE_GET (external->li_line_base);
4144 info.li_line_range = BYTE_GET (external->li_line_range);
4145 info.li_opcode_base = BYTE_GET (external->li_opcode_base);
4146
4147 /* Sign extend the line base field. */
4148 info.li_line_base <<= 24;
4149 info.li_line_base >>= 24;
4150
4151 printf (_(" Length: %ld\n"), info.li_length);
4152 printf (_(" DWARF Version: %d\n"), info.li_version);
4153 printf (_(" Prolgue Length: %d\n"), info.li_prologue_length);
4154 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
4155 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
4156 printf (_(" Line Base: %d\n"), info.li_line_base);
4157 printf (_(" Line Range: %d\n"), info.li_line_range);
4158 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
4159
4160 end_of_sequence = data + info.li_length + sizeof (info.li_length);
4161
4162 reset_state_machine (info.li_default_is_stmt);
4163
4164 /* Display the contents of the Opcodes table. */
4165 standard_opcodes = data + sizeof (* external);
4166
4167 printf (_("\n Opcodes:\n"));
4168
4169 for (i = 1; i < info.li_opcode_base; i++)
4170 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i]);
4171
4172 /* Display the contents of the Directory table. */
4173 data = standard_opcodes + info.li_opcode_base - 1;
4174
4175 if (* data == 0)
4176 printf (_("\n The Directory Table is empty.\n"));
4177 else
4178 {
4179 printf (_("\n The Directory Table:\n"));
4180
4181 while (* data != 0)
4182 {
4183 printf (_(" %s\n"), data);
4184
4185 data += strlen (data) + 1;
4186 }
4187 }
4188
4189 /* Skip the NUL at the end of the table. */
4190 data ++;
4191
4192 /* Display the contents of the File Name table. */
4193 if (* data == 0)
4194 printf (_("\n The File Name Table is empty.\n"));
4195 else
4196 {
4197 printf (_("\n The File Name Table:\n"));
4198 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
4199
4200 while (* data != 0)
4201 {
4202 char * name;
4203 int bytes_read;
4204
4205 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
4206 name = data;
4207
4208 data += strlen (data) + 1;
4209
4210 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4211 data += bytes_read;
4212 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4213 data += bytes_read;
4214 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4215 data += bytes_read;
4216 printf (_("%s\n"), name);
4217 }
4218 }
4219
4220 /* Skip the NUL at the end of the table. */
4221 data ++;
4222
4223 /* Now display the statements. */
4224 printf (_("\n Line Number Statements:\n"));
4225
4226
4227 while (data < end_of_sequence)
4228 {
4229 unsigned char op_code;
4230 int adv;
4231 int bytes_read;
4232
4233 op_code = * data ++;
4234
4235 switch (op_code)
4236 {
4237 case DW_LNS_extended_op:
4238 data += process_extended_line_op (data, info.li_default_is_stmt);
4239 break;
4240
4241 case DW_LNS_copy:
4242 printf (_(" Copy\n"));
4243 break;
4244
4245 case DW_LNS_advance_pc:
4246 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
4247 data += bytes_read;
4248 state_machine_regs.address += adv;
4249 printf (_(" Advance PC by %d to %lx\n"), adv,
4250 state_machine_regs.address);
4251 break;
4252
4253 case DW_LNS_advance_line:
4254 adv = read_leb128 (data, & bytes_read, 1);
4255 data += bytes_read;
4256 state_machine_regs.line += adv;
4257 printf (_(" Advance Line by %d to %d\n"), adv,
4258 state_machine_regs.line);
4259 break;
4260
4261 case DW_LNS_set_file:
4262 adv = read_leb128 (data, & bytes_read, 0);
4263 data += bytes_read;
4264 printf (_(" Set File Name to entry %d in the File Name Table\n"),
4265 adv);
4266 state_machine_regs.file = adv;
4267 break;
4268
4269 case DW_LNS_set_column:
4270 adv = read_leb128 (data, & bytes_read, 0);
4271 data += bytes_read;
4272 printf (_(" Set column to %d\n"), adv);
4273 state_machine_regs.column = adv;
4274 break;
4275
4276 case DW_LNS_negate_stmt:
4277 adv = state_machine_regs.is_stmt;
4278 adv = ! adv;
4279 printf (_(" Set is_stmt to %d\n"), adv);
4280 state_machine_regs.is_stmt = adv;
4281 break;
4282
4283 case DW_LNS_set_basic_block:
4284 printf (_(" Set basic block\n"));
4285 state_machine_regs.basic_block = 1;
4286 break;
4287
4288 case DW_LNS_const_add_pc:
4289 adv = (255 - info.li_opcode_base) / info.li_line_range;
4290 state_machine_regs.address += adv;
4291 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
4292 state_machine_regs.address);
4293 break;
4294
4295 case DW_LNS_fixed_advance_pc:
4296 adv = byte_get (data, 2);
4297 data += 2;
4298 state_machine_regs.address += adv;
4299 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
4300 adv, state_machine_regs.address);
4301 break;
4302
4303 default:
4304 op_code -= info.li_opcode_base;
4305 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
4306 state_machine_regs.address += adv;
4307 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
4308 op_code, adv, state_machine_regs.address);
4309 adv += (op_code % info.li_line_range) + info.li_line_base;
4310 state_machine_regs.line += adv;
4311 printf (_(" and Line by %d to %d\n"),
4312 adv, state_machine_regs.line);
4313 break;
4314 }
4315 }
4316 printf ("\n");
4317 }
4318
4319 return 1;
4320}
4321
4322static int
4323display_debug_pubnames (section, start, file)
4324 Elf32_Internal_Shdr * section;
4325 unsigned char * start;
4326 FILE * file;
4327{
4328 DWARF2_External_PubNames * external;
4329 DWARF2_Internal_PubNames pubnames;
4330 unsigned char * end;
4331
4332 end = start + section->sh_size;
4333
4334 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
4335
4336 while (start < end)
4337 {
4338 unsigned char * data;
4339 unsigned long offset;
4340
4341 external = (DWARF2_External_PubNames *) start;
4342
4343 pubnames.pn_length = BYTE_GET (external->pn_length);
4344 pubnames.pn_version = BYTE_GET (external->pn_version);
4345 pubnames.pn_offset = BYTE_GET (external->pn_offset);
4346 pubnames.pn_size = BYTE_GET (external->pn_size);
4347
4348 data = start + sizeof (* external);
4349 start += pubnames.pn_length + sizeof (external->pn_length);
4350
4351 if (pubnames.pn_version != 2)
4352 {
4353 warn (_("Only DWARF 2 pubnames are currently supported"));
4354 continue;
4355 }
4356
4357 printf (_(" Length: %ld\n"),
4358 pubnames.pn_length);
4359 printf (_(" Version: %d\n"),
4360 pubnames.pn_version);
4361 printf (_(" Offset into .debug_info section: %ld\n"),
4362 pubnames.pn_offset);
4363 printf (_(" Size of area in .debug_info section: %ld\n"),
4364 pubnames.pn_size);
4365
4366 printf (_("\n Offset\tName\n"));
4367
4368 do
4369 {
4370 offset = byte_get (data, 4);
4371
4372 if (offset != 0)
4373 {
4374 data += 4;
4375 printf (" %ld\t\t%s\n", offset, data);
4376 data += strlen (data) + 1;
4377 }
4378 }
4379 while (offset != 0);
4380 }
4381
4382 printf ("\n");
4383 return 1;
4384}
4385
4386static char *
4387get_TAG_name (tag)
4388 unsigned long tag;
4389{
4390 switch (tag)
4391 {
4392 case DW_TAG_padding: return "DW_TAG_padding";
4393 case DW_TAG_array_type: return "DW_TAG_array_type";
4394 case DW_TAG_class_type: return "DW_TAG_class_type";
4395 case DW_TAG_entry_point: return "DW_TAG_entry_point";
4396 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
4397 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
4398 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
4399 case DW_TAG_label: return "DW_TAG_label";
4400 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
4401 case DW_TAG_member: return "DW_TAG_member";
4402 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
4403 case DW_TAG_reference_type: return "DW_TAG_reference_type";
4404 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
4405 case DW_TAG_string_type: return "DW_TAG_string_type";
4406 case DW_TAG_structure_type: return "DW_TAG_structure_type";
4407 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
4408 case DW_TAG_typedef: return "DW_TAG_typedef";
4409 case DW_TAG_union_type: return "DW_TAG_union_type";
4410 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
4411 case DW_TAG_variant: return "DW_TAG_variant";
4412 case DW_TAG_common_block: return "DW_TAG_common_block";
4413 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
4414 case DW_TAG_inheritance: return "DW_TAG_inheritance";
4415 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
4416 case DW_TAG_module: return "DW_TAG_module";
4417 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
4418 case DW_TAG_set_type: return "DW_TAG_set_type";
4419 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
4420 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
4421 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
4422 case DW_TAG_base_type: return "DW_TAG_base_type";
4423 case DW_TAG_catch_block: return "DW_TAG_catch_block";
4424 case DW_TAG_const_type: return "DW_TAG_const_type";
4425 case DW_TAG_constant: return "DW_TAG_constant";
4426 case DW_TAG_enumerator: return "DW_TAG_enumerator";
4427 case DW_TAG_file_type: return "DW_TAG_file_type";
4428 case DW_TAG_friend: return "DW_TAG_friend";
4429 case DW_TAG_namelist: return "DW_TAG_namelist";
4430 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
4431 case DW_TAG_packed_type: return "DW_TAG_packed_type";
4432 case DW_TAG_subprogram: return "DW_TAG_subprogram";
4433 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
4434 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
4435 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
4436 case DW_TAG_try_block: return "DW_TAG_try_block";
4437 case DW_TAG_variant_part: return "DW_TAG_variant_part";
4438 case DW_TAG_variable: return "DW_TAG_variable";
4439 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
4440 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
4441 case DW_TAG_format_label: return "DW_TAG_format_label";
4442 case DW_TAG_function_template: return "DW_TAG_function_template";
4443 case DW_TAG_class_template: return "DW_TAG_class_template";
4444 default:
4445 {
4446 static char buffer [100];
4447
4448 sprintf (buffer, _("Unknown TAG value: %lx"), tag);
4449 return buffer;
4450 }
4451 }
4452}
4453
4454static char *
4455get_AT_name (attribute)
4456 unsigned long attribute;
4457{
4458 switch (attribute)
4459 {
4460 case DW_AT_sibling: return "DW_AT_sibling";
4461 case DW_AT_location: return "DW_AT_location";
4462 case DW_AT_name: return "DW_AT_name";
4463 case DW_AT_ordering: return "DW_AT_ordering";
4464 case DW_AT_subscr_data: return "DW_AT_subscr_data";
4465 case DW_AT_byte_size: return "DW_AT_byte_size";
4466 case DW_AT_bit_offset: return "DW_AT_bit_offset";
4467 case DW_AT_bit_size: return "DW_AT_bit_size";
4468 case DW_AT_element_list: return "DW_AT_element_list";
4469 case DW_AT_stmt_list: return "DW_AT_stmt_list";
4470 case DW_AT_low_pc: return "DW_AT_low_pc";
4471 case DW_AT_high_pc: return "DW_AT_high_pc";
4472 case DW_AT_language: return "DW_AT_language";
4473 case DW_AT_member: return "DW_AT_member";
4474 case DW_AT_discr: return "DW_AT_discr";
4475 case DW_AT_discr_value: return "DW_AT_discr_value";
4476 case DW_AT_visibility: return "DW_AT_visibility";
4477 case DW_AT_import: return "DW_AT_import";
4478 case DW_AT_string_length: return "DW_AT_string_length";
4479 case DW_AT_common_reference: return "DW_AT_common_reference";
4480 case DW_AT_comp_dir: return "DW_AT_comp_dir";
4481 case DW_AT_const_value: return "DW_AT_const_value";
4482 case DW_AT_containing_type: return "DW_AT_containing_type";
4483 case DW_AT_default_value: return "DW_AT_default_value";
4484 case DW_AT_inline: return "DW_AT_inline";
4485 case DW_AT_is_optional: return "DW_AT_is_optional";
4486 case DW_AT_lower_bound: return "DW_AT_lower_bound";
4487 case DW_AT_producer: return "DW_AT_producer";
4488 case DW_AT_prototyped: return "DW_AT_prototyped";
4489 case DW_AT_return_addr: return "DW_AT_return_addr";
4490 case DW_AT_start_scope: return "DW_AT_start_scope";
4491 case DW_AT_stride_size: return "DW_AT_stride_size";
4492 case DW_AT_upper_bound: return "DW_AT_upper_bound";
4493 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
4494 case DW_AT_accessibility: return "DW_AT_accessibility";
4495 case DW_AT_address_class: return "DW_AT_address_class";
4496 case DW_AT_artificial: return "DW_AT_artificial";
4497 case DW_AT_base_types: return "DW_AT_base_types";
4498 case DW_AT_calling_convention: return "DW_AT_calling_convention";
4499 case DW_AT_count: return "DW_AT_count";
4500 case DW_AT_data_member_location: return "DW_AT_data_member_location";
4501 case DW_AT_decl_column: return "DW_AT_decl_column";
4502 case DW_AT_decl_file: return "DW_AT_decl_file";
4503 case DW_AT_decl_line: return "DW_AT_decl_line";
4504 case DW_AT_declaration: return "DW_AT_declaration";
4505 case DW_AT_discr_list: return "DW_AT_discr_list";
4506 case DW_AT_encoding: return "DW_AT_encoding";
4507 case DW_AT_external: return "DW_AT_external";
4508 case DW_AT_frame_base: return "DW_AT_frame_base";
4509 case DW_AT_friend: return "DW_AT_friend";
4510 case DW_AT_identifier_case: return "DW_AT_identifier_case";
4511 case DW_AT_macro_info: return "DW_AT_macro_info";
4512 case DW_AT_namelist_items: return "DW_AT_namelist_items";
4513 case DW_AT_priority: return "DW_AT_priority";
4514 case DW_AT_segment: return "DW_AT_segment";
4515 case DW_AT_specification: return "DW_AT_specification";
4516 case DW_AT_static_link: return "DW_AT_static_link";
4517 case DW_AT_type: return "DW_AT_type";
4518 case DW_AT_use_location: return "DW_AT_use_location";
4519 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
4520 case DW_AT_virtuality: return "DW_AT_virtuality";
4521 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
4522 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
4523 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
4524 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
4525 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
4526 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
4527 case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
4528 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
4529 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
4530 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
4531 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
4532 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
4533 case DW_AT_sf_names: return "DW_AT_sf_names";
4534 case DW_AT_src_info: return "DW_AT_src_info";
4535 case DW_AT_mac_info: return "DW_AT_mac_info";
4536 case DW_AT_src_coords: return "DW_AT_src_coords";
4537 case DW_AT_body_begin: return "DW_AT_body_begin";
4538 case DW_AT_body_end: return "DW_AT_body_end";
4539 default:
4540 {
4541 static char buffer [100];
4542
4543 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
4544 return buffer;
4545 }
4546 }
4547}
4548
4549static char *
4550get_FORM_name (form)
4551 unsigned long form;
4552{
4553 switch (form)
4554 {
4555 case DW_FORM_addr: return "DW_FORM_addr";
4556 case DW_FORM_block2: return "DW_FORM_block2";
4557 case DW_FORM_block4: return "DW_FORM_block4";
4558 case DW_FORM_data2: return "DW_FORM_data2";
4559 case DW_FORM_data4: return "DW_FORM_data4";
4560 case DW_FORM_data8: return "DW_FORM_data8";
4561 case DW_FORM_string: return "DW_FORM_string";
4562 case DW_FORM_block: return "DW_FORM_block";
4563 case DW_FORM_block1: return "DW_FORM_block1";
4564 case DW_FORM_data1: return "DW_FORM_data1";
4565 case DW_FORM_flag: return "DW_FORM_flag";
4566 case DW_FORM_sdata: return "DW_FORM_sdata";
4567 case DW_FORM_strp: return "DW_FORM_strp";
4568 case DW_FORM_udata: return "DW_FORM_udata";
4569 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
4570 case DW_FORM_ref1: return "DW_FORM_ref1";
4571 case DW_FORM_ref2: return "DW_FORM_ref2";
4572 case DW_FORM_ref4: return "DW_FORM_ref4";
4573 case DW_FORM_ref8: return "DW_FORM_ref8";
4574 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
4575 case DW_FORM_indirect: return "DW_FORM_indirect";
4576 default:
4577 {
4578 static char buffer [100];
4579
4580 sprintf (buffer, _("Unknown FORM value: %lx"), form);
4581 return buffer;
4582 }
4583 }
4584}
4585
4586/* FIXME: There are better and more effiecint ways to handle
4587 these structures. For now though, I just want something that
4588 is simple to implement. */
4589typedef struct abbrev_attr
4590{
4591 unsigned long attribute;
4592 unsigned long form;
4593 struct abbrev_attr * next;
4594}
4595abbrev_attr;
4596
4597typedef struct abbrev_entry
4598{
4599 unsigned long entry;
4600 unsigned long tag;
4601 int children;
4602 struct abbrev_attr * first_attr;
4603 struct abbrev_attr * last_attr;
4604 struct abbrev_entry * next;
4605}
4606abbrev_entry;
4607
4608static abbrev_entry * first_abbrev = NULL;
4609static abbrev_entry * last_abbrev = NULL;
4610
4611static void
4612free_abbrevs PARAMS ((void))
4613{
4614 abbrev_entry * abbrev;
4615
4616 for (abbrev = first_abbrev; abbrev;)
4617 {
4618 abbrev_entry * next = abbrev->next;
4619 abbrev_attr * attr;
4620
4621 for (attr = abbrev->first_attr; attr;)
4622 {
4623 abbrev_attr * next = attr->next;
4624
4625 free (attr);
4626 attr = next;
4627 }
4628
4629 free (abbrev);
4630 abbrev = next;
4631 }
4632
4633 last_abbrev = first_abbrev = NULL;
4634}
4635
4636static void
4637add_abbrev (number, tag, children)
4638 unsigned long number;
4639 unsigned long tag;
4640 int children;
4641{
4642 abbrev_entry * entry;
4643
4644 entry = (abbrev_entry *) malloc (sizeof (* entry));
4645
4646 if (entry == NULL)
4647 /* ugg */
4648 return;
4649
4650 entry->entry = number;
4651 entry->tag = tag;
4652 entry->children = children;
4653 entry->first_attr = NULL;
4654 entry->last_attr = NULL;
4655 entry->next = NULL;
4656
4657 if (first_abbrev == NULL)
4658 first_abbrev = entry;
4659 else
4660 last_abbrev->next = entry;
4661
4662 last_abbrev = entry;
4663}
4664
4665static void
4666add_abbrev_attr (attribute, form)
4667 unsigned long attribute;
4668 unsigned long form;
4669{
4670 abbrev_attr * attr;
4671
4672 attr = (abbrev_attr *) malloc (sizeof (* attr));
4673
4674 if (attr == NULL)
4675 /* ugg */
4676 return;
4677
4678 attr->attribute = attribute;
4679 attr->form = form;
4680 attr->next = NULL;
4681
4682 if (last_abbrev->first_attr == NULL)
4683 last_abbrev->first_attr = attr;
4684 else
4685 last_abbrev->last_attr->next = attr;
4686
4687 last_abbrev->last_attr = attr;
4688}
4689
4690/* Processes the (partial) contents of a .debug_abbrev section.
4691 Returns NULL if the end of the section was encountered.
4692 Returns the address after the last byte read if the end of
4693 an abbreviation set was found. */
4694
4695static unsigned char *
4696process_abbrev_section (start, end)
4697 unsigned char * start;
4698 unsigned char * end;
4699{
4700 if (first_abbrev != NULL)
4701 return NULL;
4702
4703 while (start < end)
4704 {
4705 int bytes_read;
4706 unsigned long entry;
4707 unsigned long tag;
4708 unsigned long attribute;
4709 int children;
4710
4711 entry = read_leb128 (start, & bytes_read, 0);
4712 start += bytes_read;
4713
4714 if (entry == 0)
4715 return start;
4716
4717 tag = read_leb128 (start, & bytes_read, 0);
4718 start += bytes_read;
4719
4720 children = * start ++;
4721
4722 add_abbrev (entry, tag, children);
4723
4724 do
4725 {
4726 unsigned long form;
4727
4728 attribute = read_leb128 (start, & bytes_read, 0);
4729 start += bytes_read;
4730
4731 form = read_leb128 (start, & bytes_read, 0);
4732 start += bytes_read;
4733
4734 if (attribute != 0)
4735 add_abbrev_attr (attribute, form);
4736 }
4737 while (attribute != 0);
4738 }
4739
4740 return NULL;
4741}
4742
4743
4744static int
4745display_debug_abbrev (section, start, file)
4746 Elf32_Internal_Shdr * section;
4747 unsigned char * start;
4748 FILE * file;
4749{
4750 abbrev_entry * entry;
4751 unsigned char * end = start + section->sh_size;
4752
4753 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
4754
4755 do
4756 {
4757 start = process_abbrev_section (start, end);
4758
4759 printf (_(" Number TAG\n"));
4760
4761 for (entry = first_abbrev; entry; entry = entry->next)
4762 {
4763 abbrev_attr * attr;
4764
4765 printf (_(" %ld %s [%s]\n"),
4766 entry->entry,
4767 get_TAG_name (entry->tag),
4768 entry->children ? _("has children") : _("no children"));
4769
4770 for (attr = entry->first_attr; attr; attr = attr->next)
4771 {
4772 printf (_(" %-18s %s\n"),
4773 get_AT_name (attr->attribute),
4774 get_FORM_name (attr->form));
4775 }
4776 }
4777 }
4778 while (start);
4779
4780 printf ("\n");
4781
4782 return 1;
4783}
4784
4785
4786static unsigned char *
4787display_block (data, length)
4788 unsigned char * data;
4789 unsigned long length;
4790{
4791 printf (_(" %lu byte block: "), length);
4792
4793 while (length --)
148d3c43 4794 printf ("%lx ", (unsigned long) byte_get (data ++, 1));
252b5132
RH
4795
4796 return data;
4797}
4798
4799static void
4800decode_location_expression (data, pointer_size)
4801 unsigned char * data;
4802 unsigned int pointer_size;
4803{
4804 unsigned char op;
4805 int bytes_read;
148d3c43 4806 unsigned long uvalue;
252b5132
RH
4807
4808 op = * data ++;
4809
4810 switch (op)
4811 {
148d3c43
AS
4812 case DW_OP_addr:
4813 printf ("DW_OP_addr: %lx", (unsigned long) byte_get (data, pointer_size));
4814 break;
4815 case DW_OP_deref:
4816 printf ("DW_OP_deref");
4817 break;
4818 case DW_OP_const1u:
4819 printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data, 1));
4820 break;
4821 case DW_OP_const1s:
4822 printf ("DW_OP_const1s: %ld", (long) byte_get (data, 1));
4823 break;
4824 case DW_OP_const2u:
4825 printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
4826 break;
4827 case DW_OP_const2s:
4828 printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
4829 break;
4830 case DW_OP_const4u:
4831 printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
4832 break;
4833 case DW_OP_const4s:
4834 printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
4835 break;
4836 case DW_OP_const8u:
4837 printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
4838 (unsigned long) byte_get (data + 4, 4));
4839 break;
4840 case DW_OP_const8s:
4841 printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
4842 (long) byte_get (data + 4, 4));
4843 break;
4844 case DW_OP_constu:
4845 printf ("DW_OP_constu: %lu", read_leb128 (data, NULL, 0));
4846 break;
4847 case DW_OP_consts:
4848 printf ("DW_OP_consts: %ld", read_leb128 (data, NULL, 1));
4849 break;
4850 case DW_OP_dup:
4851 printf ("DW_OP_dup");
4852 break;
4853 case DW_OP_drop:
4854 printf ("DW_OP_drop");
4855 break;
4856 case DW_OP_over:
4857 printf ("DW_OP_over");
4858 break;
4859 case DW_OP_pick:
4860 printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data, 1));
4861 break;
4862 case DW_OP_swap:
4863 printf ("DW_OP_swap");
4864 break;
4865 case DW_OP_rot:
4866 printf ("DW_OP_rot");
4867 break;
4868 case DW_OP_xderef:
4869 printf ("DW_OP_xderef");
4870 break;
4871 case DW_OP_abs:
4872 printf ("DW_OP_abs");
4873 break;
4874 case DW_OP_and:
4875 printf ("DW_OP_and");
4876 break;
4877 case DW_OP_div:
4878 printf ("DW_OP_div");
4879 break;
4880 case DW_OP_minus:
4881 printf ("DW_OP_minus");
4882 break;
4883 case DW_OP_mod:
4884 printf ("DW_OP_mod");
4885 break;
4886 case DW_OP_mul:
4887 printf ("DW_OP_mul");
4888 break;
4889 case DW_OP_neg:
4890 printf ("DW_OP_neg");
4891 break;
4892 case DW_OP_not:
4893 printf ("DW_OP_not");
4894 break;
4895 case DW_OP_or:
4896 printf ("DW_OP_or");
4897 break;
4898 case DW_OP_plus:
4899 printf ("DW_OP_plus");
4900 break;
4901 case DW_OP_plus_uconst:
4902 printf ("DW_OP_plus_uconst: %lu", read_leb128 (data, NULL, 0));
4903 break;
4904 case DW_OP_shl:
4905 printf ("DW_OP_shl");
4906 break;
4907 case DW_OP_shr:
4908 printf ("DW_OP_shr");
4909 break;
4910 case DW_OP_shra:
4911 printf ("DW_OP_shra");
4912 break;
4913 case DW_OP_xor:
4914 printf ("DW_OP_xor");
4915 break;
4916 case DW_OP_bra:
789be9f7 4917 printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
148d3c43
AS
4918 break;
4919 case DW_OP_eq:
4920 printf ("DW_OP_eq");
4921 break;
4922 case DW_OP_ge:
4923 printf ("DW_OP_ge");
4924 break;
4925 case DW_OP_gt:
4926 printf ("DW_OP_gt");
4927 break;
4928 case DW_OP_le:
4929 printf ("DW_OP_le");
4930 break;
4931 case DW_OP_lt:
4932 printf ("DW_OP_lt");
4933 break;
4934 case DW_OP_ne:
4935 printf ("DW_OP_ne");
4936 break;
4937 case DW_OP_skip:
4938 printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
4939 break;
4940 case DW_OP_lit0:
4941 printf ("DW_OP_lit0");
4942 break;
4943 case DW_OP_lit1:
4944 printf ("DW_OP_lit1");
4945 break;
4946 case DW_OP_lit2:
4947 printf ("DW_OP_lit2");
4948 break;
4949 case DW_OP_lit3:
4950 printf ("DW_OP_lit3");
4951 break;
4952 case DW_OP_lit4:
4953 printf ("DW_OP_lit4");
4954 break;
4955 case DW_OP_lit5:
4956 printf ("DW_OP_lit5");
4957 break;
4958 case DW_OP_lit6:
4959 printf ("DW_OP_lit6");
4960 break;
4961 case DW_OP_lit7:
4962 printf ("DW_OP_lit7");
4963 break;
4964 case DW_OP_lit8:
4965 printf ("DW_OP_lit8");
4966 break;
4967 case DW_OP_lit9:
4968 printf ("DW_OP_lit9");
4969 break;
4970 case DW_OP_lit10:
4971 printf ("DW_OP_lit10");
4972 break;
4973 case DW_OP_lit11:
4974 printf ("DW_OP_lit11");
4975 break;
4976 case DW_OP_lit12:
4977 printf ("DW_OP_lit12");
4978 break;
4979 case DW_OP_lit13:
4980 printf ("DW_OP_lit13");
4981 break;
4982 case DW_OP_lit14:
4983 printf ("DW_OP_lit14");
4984 break;
4985 case DW_OP_lit15:
4986 printf ("DW_OP_lit15");
4987 break;
4988 case DW_OP_lit16:
4989 printf ("DW_OP_lit16");
4990 break;
4991 case DW_OP_lit17:
4992 printf ("DW_OP_lit17");
4993 break;
4994 case DW_OP_lit18:
4995 printf ("DW_OP_lit18");
4996 break;
4997 case DW_OP_lit19:
4998 printf ("DW_OP_lit19");
4999 break;
5000 case DW_OP_lit20:
5001 printf ("DW_OP_lit20");
5002 break;
5003 case DW_OP_lit21:
5004 printf ("DW_OP_lit21");
5005 break;
5006 case DW_OP_lit22:
5007 printf ("DW_OP_lit22");
5008 break;
5009 case DW_OP_lit23:
5010 printf ("DW_OP_lit23");
5011 break;
5012 case DW_OP_lit24:
5013 printf ("DW_OP_lit24");
5014 break;
5015 case DW_OP_lit25:
5016 printf ("DW_OP_lit25");
5017 break;
5018 case DW_OP_lit26:
5019 printf ("DW_OP_lit26");
5020 break;
5021 case DW_OP_lit27:
5022 printf ("DW_OP_lit27");
5023 break;
5024 case DW_OP_lit28:
5025 printf ("DW_OP_lit28");
5026 break;
5027 case DW_OP_lit29:
5028 printf ("DW_OP_lit29");
5029 break;
5030 case DW_OP_lit30:
5031 printf ("DW_OP_lit30");
5032 break;
5033 case DW_OP_lit31:
5034 printf ("DW_OP_lit31");
5035 break;
5036 case DW_OP_reg0:
5037 printf ("DW_OP_reg0");
5038 break;
5039 case DW_OP_reg1:
5040 printf ("DW_OP_reg1");
5041 break;
5042 case DW_OP_reg2:
5043 printf ("DW_OP_reg2");
5044 break;
5045 case DW_OP_reg3:
5046 printf ("DW_OP_reg3");
5047 break;
5048 case DW_OP_reg4:
5049 printf ("DW_OP_reg4");
5050 break;
5051 case DW_OP_reg5:
5052 printf ("DW_OP_reg5");
5053 break;
5054 case DW_OP_reg6:
5055 printf ("DW_OP_reg6");
5056 break;
5057 case DW_OP_reg7:
5058 printf ("DW_OP_reg7");
5059 break;
5060 case DW_OP_reg8:
5061 printf ("DW_OP_reg8");
5062 break;
5063 case DW_OP_reg9:
5064 printf ("DW_OP_reg9");
5065 break;
5066 case DW_OP_reg10:
5067 printf ("DW_OP_reg10");
5068 break;
5069 case DW_OP_reg11:
5070 printf ("DW_OP_reg11");
5071 break;
5072 case DW_OP_reg12:
5073 printf ("DW_OP_reg12");
5074 break;
5075 case DW_OP_reg13:
5076 printf ("DW_OP_reg13");
5077 break;
5078 case DW_OP_reg14:
5079 printf ("DW_OP_reg14");
5080 break;
5081 case DW_OP_reg15:
5082 printf ("DW_OP_reg15");
5083 break;
5084 case DW_OP_reg16:
5085 printf ("DW_OP_reg16");
5086 break;
5087 case DW_OP_reg17:
5088 printf ("DW_OP_reg17");
5089 break;
5090 case DW_OP_reg18:
5091 printf ("DW_OP_reg18");
5092 break;
5093 case DW_OP_reg19:
5094 printf ("DW_OP_reg19");
5095 break;
5096 case DW_OP_reg20:
5097 printf ("DW_OP_reg20");
5098 break;
5099 case DW_OP_reg21:
5100 printf ("DW_OP_reg21");
5101 break;
5102 case DW_OP_reg22:
5103 printf ("DW_OP_reg22");
5104 break;
5105 case DW_OP_reg23:
5106 printf ("DW_OP_reg23");
5107 break;
5108 case DW_OP_reg24:
5109 printf ("DW_OP_reg24");
5110 break;
5111 case DW_OP_reg25:
5112 printf ("DW_OP_reg25");
5113 break;
5114 case DW_OP_reg26:
5115 printf ("DW_OP_reg26");
5116 break;
5117 case DW_OP_reg27:
5118 printf ("DW_OP_reg27");
5119 break;
5120 case DW_OP_reg28:
5121 printf ("DW_OP_reg28");
5122 break;
5123 case DW_OP_reg29:
5124 printf ("DW_OP_reg29");
5125 break;
5126 case DW_OP_reg30:
5127 printf ("DW_OP_reg30");
5128 break;
5129 case DW_OP_reg31:
5130 printf ("DW_OP_reg31");
5131 break;
5132 case DW_OP_breg0:
5133 printf ("DW_OP_breg0: %ld", read_leb128 (data, NULL, 1));
5134 break;
5135 case DW_OP_breg1:
5136 printf ("DW_OP_breg1: %ld", read_leb128 (data, NULL, 1));
5137 break;
5138 case DW_OP_breg2:
5139 printf ("DW_OP_breg2: %ld", read_leb128 (data, NULL, 1));
5140 break;
5141 case DW_OP_breg3:
5142 printf ("DW_OP_breg3: %ld", read_leb128 (data, NULL, 1));
5143 break;
5144 case DW_OP_breg4:
5145 printf ("DW_OP_breg4: %ld", read_leb128 (data, NULL, 1));
5146 break;
5147 case DW_OP_breg5:
5148 printf ("DW_OP_breg5: %ld", read_leb128 (data, NULL, 1));
5149 break;
5150 case DW_OP_breg6:
5151 printf ("DW_OP_breg6: %ld", read_leb128 (data, NULL, 1));
5152 break;
5153 case DW_OP_breg7:
5154 printf ("DW_OP_breg7: %ld", read_leb128 (data, NULL, 1));
5155 break;
5156 case DW_OP_breg8:
5157 printf ("DW_OP_breg8: %ld", read_leb128 (data, NULL, 1));
5158 break;
5159 case DW_OP_breg9:
5160 printf ("DW_OP_breg9: %ld", read_leb128 (data, NULL, 1));
5161 break;
5162 case DW_OP_breg10:
5163 printf ("DW_OP_breg10: %ld", read_leb128 (data, NULL, 1));
5164 break;
5165 case DW_OP_breg11:
5166 printf ("DW_OP_breg11: %ld", read_leb128 (data, NULL, 1));
5167 break;
5168 case DW_OP_breg12:
5169 printf ("DW_OP_breg12: %ld", read_leb128 (data, NULL, 1));
5170 break;
5171 case DW_OP_breg13:
5172 printf ("DW_OP_breg13: %ld", read_leb128 (data, NULL, 1));
5173 break;
5174 case DW_OP_breg14:
5175 printf ("DW_OP_breg14: %ld", read_leb128 (data, NULL, 1));
5176 break;
5177 case DW_OP_breg15:
5178 printf ("DW_OP_breg15: %ld", read_leb128 (data, NULL, 1));
5179 break;
5180 case DW_OP_breg16:
5181 printf ("DW_OP_breg16: %ld", read_leb128 (data, NULL, 1));
5182 break;
5183 case DW_OP_breg17:
5184 printf ("DW_OP_breg17: %ld", read_leb128 (data, NULL, 1));
5185 break;
5186 case DW_OP_breg18:
5187 printf ("DW_OP_breg18: %ld", read_leb128 (data, NULL, 1));
5188 break;
5189 case DW_OP_breg19:
5190 printf ("DW_OP_breg19: %ld", read_leb128 (data, NULL, 1));
5191 break;
5192 case DW_OP_breg20:
5193 printf ("DW_OP_breg20: %ld", read_leb128 (data, NULL, 1));
5194 break;
5195 case DW_OP_breg21:
5196 printf ("DW_OP_breg21: %ld", read_leb128 (data, NULL, 1));
5197 break;
5198 case DW_OP_breg22:
5199 printf ("DW_OP_breg22: %ld", read_leb128 (data, NULL, 1));
5200 break;
5201 case DW_OP_breg23:
5202 printf ("DW_OP_breg23: %ld", read_leb128 (data, NULL, 1));
5203 break;
5204 case DW_OP_breg24:
5205 printf ("DW_OP_breg24: %ld", read_leb128 (data, NULL, 1));
5206 break;
5207 case DW_OP_breg25:
5208 printf ("DW_OP_breg25: %ld", read_leb128 (data, NULL, 1));
5209 break;
5210 case DW_OP_breg26:
5211 printf ("DW_OP_breg26: %ld", read_leb128 (data, NULL, 1));
5212 break;
5213 case DW_OP_breg27:
5214 printf ("DW_OP_breg27: %ld", read_leb128 (data, NULL, 1));
5215 break;
5216 case DW_OP_breg28:
5217 printf ("DW_OP_breg28: %ld", read_leb128 (data, NULL, 1));
5218 break;
5219 case DW_OP_breg29:
5220 printf ("DW_OP_breg29: %ld", read_leb128 (data, NULL, 1));
5221 break;
5222 case DW_OP_breg30:
5223 printf ("DW_OP_breg30: %ld", read_leb128 (data, NULL, 1));
5224 break;
5225 case DW_OP_breg31:
5226 printf ("DW_OP_breg31: %ld", read_leb128 (data, NULL, 1));
5227 break;
5228 case DW_OP_regx:
5229 printf ("DW_OP_regx: %lu", read_leb128 (data, NULL, 0));
5230 break;
5231 case DW_OP_fbreg:
5232 printf ("DW_OP_fbreg: %ld", read_leb128 (data, NULL, 1));
5233 break;
5234 case DW_OP_bregx:
5235 uvalue = read_leb128 (data, &bytes_read, 0);
5236 printf ("DW_OP_bregx: %lu %ld", uvalue,
5237 read_leb128 (data + bytes_read, NULL, 1));
5238 break;
5239 case DW_OP_piece:
5240 printf ("DW_OP_piece: %lu", read_leb128 (data, NULL, 0));
5241 break;
5242 case DW_OP_deref_size:
5243 printf ("DW_OP_deref_size: %ld", (long) byte_get (data, 1));
5244 break;
5245 case DW_OP_xderef_size:
5246 printf ("DW_OP_xderef_size: %ld", (long) byte_get (data, 1));
5247 break;
5248 case DW_OP_nop:
5249 printf ("DW_OP_nop");
5250 break;
252b5132
RH
5251
5252 default:
5253 if (op >= DW_OP_lo_user
5254 && op <= DW_OP_hi_user)
5255 printf (_("(User defined location op)"));
5256 else
5257 printf (_("(Unknown location op)"));
5258 break;
5259 }
5260}
5261
5262
5263static unsigned char *
5264read_and_display_attr (attribute, form, data, pointer_size)
5265 unsigned long attribute;
5266 unsigned long form;
5267 unsigned char * data;
5268 unsigned long pointer_size;
5269{
5270 unsigned long uvalue;
5271 unsigned char * block_start;
5272 int bytes_read;
5273 int is_ref = 0;
5274
5275 printf (" %-18s:", get_AT_name (attribute));
5276
5277 switch (form)
5278 {
5279 case DW_FORM_ref_addr:
5280 case DW_FORM_ref1:
5281 case DW_FORM_ref2:
5282 case DW_FORM_ref4:
5283 case DW_FORM_ref8:
5284 case DW_FORM_ref_udata:
5285 is_ref = 1;
5286 }
5287
5288 switch (form)
5289 {
5290 case DW_FORM_ref_addr:
5291 case DW_FORM_addr:
5292 uvalue = byte_get (data, pointer_size);
5293 printf (is_ref ? " <%x>" : " %#x", uvalue);
5294 data += pointer_size;
5295 break;
5296
5297 case DW_FORM_ref1:
5298 case DW_FORM_flag:
5299 case DW_FORM_data1:
5300 uvalue = byte_get (data ++, 1);
5301 printf (is_ref ? " <%x>" : " %d", uvalue);
5302 break;
5303
5304 case DW_FORM_ref2:
5305 case DW_FORM_data2:
5306 uvalue = byte_get (data, 2);
5307 data += 2;
5308 printf (is_ref ? " <%x>" : " %d", uvalue);
5309 break;
5310
5311 case DW_FORM_ref4:
5312 case DW_FORM_data4:
5313 uvalue = byte_get (data, 4);
5314 data += 4;
5315 printf (is_ref ? " <%x>" : " %d", uvalue);
5316 break;
5317
5318 case DW_FORM_ref8:
5319 case DW_FORM_data8:
5320 uvalue = byte_get (data, 4);
5321 printf (" %lx", uvalue);
148d3c43 5322 printf (" %lx", (unsigned long) byte_get (data + 4, 4));
252b5132
RH
5323 data += 8;
5324 break;
5325
5326 case DW_FORM_string:
5327 printf (" %s", data);
5328 data += strlen (data) + 1;
5329 break;
5330
5331 case DW_FORM_sdata:
5332 uvalue = read_leb128 (data, & bytes_read, 1);
5333 data += bytes_read;
5334 printf (" %ld", (long) uvalue);
5335 break;
5336
5337 case DW_FORM_ref_udata:
5338 case DW_FORM_udata:
5339 uvalue = read_leb128 (data, & bytes_read, 0);
5340 data += bytes_read;
5341 printf (is_ref ? " <%lx>" : " %ld", uvalue);
5342 break;
5343
5344 case DW_FORM_block:
5345 uvalue = read_leb128 (data, & bytes_read, 0);
5346 block_start = data + bytes_read;
5347 data = display_block (block_start, uvalue);
5348 uvalue = * block_start;
5349 break;
5350
5351 case DW_FORM_block1:
5352 uvalue = byte_get (data, 1);
5353 block_start = data + 1;
5354 data = display_block (block_start, uvalue);
5355 uvalue = * block_start;
5356 break;
5357
5358 case DW_FORM_block2:
5359 uvalue = byte_get (data, 2);
5360 block_start = data + 2;
5361 data = display_block (block_start, uvalue);
5362 uvalue = * block_start;
5363 break;
5364
5365 case DW_FORM_block4:
5366 uvalue = byte_get (data, 4);
5367 block_start = data + 4;
5368 data = display_block (block_start, uvalue);
5369 uvalue = * block_start;
5370 break;
5371
5372 case DW_FORM_strp:
5373 case DW_FORM_indirect:
5374 warn (_("Unable to handle FORM: %d"), form);
5375 break;
5376
5377 default:
5378 warn (_("Unrecognised form: %d"), form);
5379 break;
5380 }
5381
5382 /* For some attributes we can display futher information. */
5383
5384 printf ("\t");
5385
5386 switch (attribute)
5387 {
5388 case DW_AT_inline:
5389 switch (uvalue)
5390 {
5391 case DW_INL_not_inlined: printf (_("(not inlined)")); break;
5392 case DW_INL_inlined: printf (_("(inlined)")); break;
5393 case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
5394 case DW_INL_declared_inlined: printf (_("(declared as inline and inlined)")); break;
5395 default: printf (_(" (Unknown inline attribute value: %lx)"), uvalue); break;
5396 }
5397 break;
5398
5399 case DW_AT_frame_base:
5400 if (uvalue >= DW_OP_reg0 && uvalue <= DW_OP_reg31)
5401 printf ("(reg %ld)", uvalue - DW_OP_reg0);
5402 break;
5403
5404 case DW_AT_language:
5405 switch (uvalue)
5406 {
5407 case DW_LANG_C: printf ("(non-ANSI C)"); break;
5408 case DW_LANG_C89: printf ("(ANSI C)"); break;
5409 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
5410 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
5411 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
5412 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
5413 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
5414 case DW_LANG_Ada83: printf ("(Ada)"); break;
5415 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
5416 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
5417 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
5418 default: printf ("(Unknown: %lx)", uvalue); break;
5419 }
5420 break;
5421
5422 case DW_AT_encoding:
5423 switch (uvalue)
5424 {
5425 case DW_ATE_void: printf ("(void)"); break;
5426 case DW_ATE_address: printf ("(machine address)"); break;
5427 case DW_ATE_boolean: printf ("(boolean)"); break;
5428 case DW_ATE_complex_float: printf ("(complex float)"); break;
5429 case DW_ATE_float: printf ("(float)"); break;
5430 case DW_ATE_signed: printf ("(signed)"); break;
5431 case DW_ATE_signed_char: printf ("(signed char)"); break;
5432 case DW_ATE_unsigned: printf ("(unsigned)"); break;
5433 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
5434 default:
5435 if (uvalue >= DW_ATE_lo_user
5436 && uvalue <= DW_ATE_hi_user)
5437 printf ("(user defined type)");
5438 else
5439 printf ("(unknown type)");
5440 break;
5441 }
5442 break;
5443
5444 case DW_AT_accessibility:
5445 switch (uvalue)
5446 {
5447 case DW_ACCESS_public: printf ("(public)"); break;
5448 case DW_ACCESS_protected: printf ("(protected)"); break;
5449 case DW_ACCESS_private: printf ("(private)"); break;
5450 default: printf ("(unknown accessibility)"); break;
5451 }
5452 break;
5453
5454 case DW_AT_visibility:
5455 switch (uvalue)
5456 {
5457 case DW_VIS_local: printf ("(local)"); break;
5458 case DW_VIS_exported: printf ("(exported)"); break;
5459 case DW_VIS_qualified: printf ("(qualified)"); break;
5460 default: printf ("(unknown visibility)"); break;
5461 }
5462 break;
5463
5464 case DW_AT_virtuality:
5465 switch (uvalue)
5466 {
5467 case DW_VIRTUALITY_none: printf ("(none)"); break;
5468 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
5469 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
5470 default: printf ("(unknown virtuality)"); break;
5471 }
5472 break;
5473
5474 case DW_AT_identifier_case:
5475 switch (uvalue)
5476 {
5477 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
5478 case DW_ID_up_case: printf ("(up_case)"); break;
5479 case DW_ID_down_case: printf ("(down_case)"); break;
5480 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
5481 default: printf ("(unknown case)"); break;
5482 }
5483 break;
5484
5485 case DW_AT_calling_convention:
5486 switch (uvalue)
5487 {
5488 case DW_CC_normal: printf ("(normal)"); break;
5489 case DW_CC_program: printf ("(program)"); break;
5490 case DW_CC_nocall: printf ("(nocall)"); break;
5491 default:
5492 if (uvalue >= DW_CC_lo_user
5493 && uvalue <= DW_CC_hi_user)
5494 printf ("(user defined)");
5495 else
5496 printf ("(unknown convention)");
5497 }
5498 break;
5499
5500 case DW_AT_location:
5501 case DW_AT_data_member_location:
5502 case DW_AT_vtable_elem_location:
5503 printf ("(");
5504 decode_location_expression (block_start, pointer_size);
5505 printf (")");
5506 break;
5507
5508 default:
5509 break;
5510 }
5511
5512 printf ("\n");
5513 return data;
5514}
5515
5516static int
5517display_debug_info (section, start, file)
5518 Elf32_Internal_Shdr * section;
5519 unsigned char * start;
5520 FILE * file;
5521{
5522 unsigned char * end = start + section->sh_size;
5523 unsigned char * section_begin = start;
5524
5525 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
5526
5527 while (start < end)
5528 {
5529 DWARF2_External_CompUnit * external;
5530 DWARF2_Internal_CompUnit compunit;
5531 unsigned char * tags;
5532 int i;
5533 int level;
5534
5535 external = (DWARF2_External_CompUnit *) start;
5536
5537 compunit.cu_length = BYTE_GET (external->cu_length);
5538 compunit.cu_version = BYTE_GET (external->cu_version);
5539 compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
5540 compunit.cu_pointer_size = BYTE_GET (external->cu_pointer_size);
5541
5542 tags = start + sizeof (* external);
5543 start += compunit.cu_length + sizeof (external->cu_length);
5544
5545 if (compunit.cu_version != 2)
5546 {
5547 warn (_("Only version 2 DWARF debug information is currently supported.\n"));
5548 continue;
5549 }
5550
5551 printf (_(" Compilation Unit:\n"));
5552 printf (_(" Length: %ld\n"), compunit.cu_length);
5553 printf (_(" Version: %d\n"), compunit.cu_version);
5554 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
5555 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
5556
5557 if (first_abbrev != NULL)
5558 free_abbrevs ();
5559
5560 /* Read in the abbrevs used by this compilation unit. */
5561
5562 {
5563 Elf32_Internal_Shdr * sec;
5564 unsigned char * begin;
5565
5566 /* Locate the .debug_abbrev section and process it. */
5567 for (i = 0, sec = section_headers;
5568 i < elf_header.e_shnum;
5569 i ++, sec ++)
5570 if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
5571 break;
5572
5573 if (i == -1 || sec->sh_size == 0)
5574 {
5575 warn (_("Unable to locate .debug_abbrev section!\n"));
5576 return 0;
5577 }
5578
5579 GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, unsigned char *,
5580 "debug_abbrev section data");
5581
5582 process_abbrev_section (begin + compunit.cu_abbrev_offset,
5583 begin + sec->sh_size);
5584
5585 free (begin);
5586 }
5587
5588 level = 0;
5589 while (tags < start)
5590 {
5591 int bytes_read;
5592 int abbrev_number;
5593 abbrev_entry * entry;
5594 abbrev_attr * attr;
5595
5596 abbrev_number = read_leb128 (tags, & bytes_read, 0);
5597 tags += bytes_read;
5598
5599 /* A null DIE marks the end of a list of children. */
5600 if (abbrev_number == 0)
5601 {
5602 --level;
5603 continue;
5604 }
5605
5606 /* Scan through the abbreviation list until we reach the
5607 correct entry. */
5608 for (entry = first_abbrev;
5609 entry && entry->entry != abbrev_number;
5610 entry = entry->next)
5611 continue;
5612
5613 if (entry == NULL)
5614 {
5615 warn (_("Unable to locate entry %d in the abbreviation table\n"),
5616 abbrev_number);
5617 return 0;
5618 }
5619
5620 printf (_(" <%d><%x>: Abbrev Number: %d (%s)\n"),
5621 level, tags - section_begin - bytes_read,
5622 abbrev_number,
5623 get_TAG_name (entry->tag));
5624
5625 for (attr = entry->first_attr; attr; attr = attr->next)
5626 tags = read_and_display_attr (attr->attribute,
5627 attr->form,
5628 tags,
5629 compunit.cu_pointer_size);
5630
5631 if (entry->children)
5632 ++level;
5633 }
5634 }
5635
5636 printf ("\n");
5637
5638 return 1;
5639}
5640
5641static int
5642display_debug_aranges (section, start, file)
5643 Elf32_Internal_Shdr * section;
5644 unsigned char * start;
5645 FILE * file;
5646{
5647 unsigned char * end = start + section->sh_size;
5648
5649 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
5650
5651 while (start < end)
5652 {
5653 DWARF2_External_ARange * external;
5654 DWARF2_Internal_ARange arange;
5655 unsigned char * ranges;
5656 unsigned long length;
5657 unsigned long address;
5658
5659 external = (DWARF2_External_ARange *) start;
5660
5661 arange.ar_length = BYTE_GET (external->ar_length);
5662 arange.ar_version = BYTE_GET (external->ar_version);
5663 arange.ar_info_offset = BYTE_GET (external->ar_info_offset);
5664 arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
5665 arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
5666
5667 printf (_(" Length: %ld\n"), arange.ar_length);
5668 printf (_(" Version: %d\n"), arange.ar_version);
5669 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
5670 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
5671 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
5672
5673 printf (_("\n Address Length\n"));
5674
5675 ranges = start + sizeof (* external);
5676
5677 for (;;)
5678 {
5679 address = byte_get (ranges, arange.ar_pointer_size);
5680
5681 if (address == 0)
5682 break;
5683
5684 ranges += arange.ar_pointer_size;
5685
5686 length = byte_get (ranges, arange.ar_pointer_size);
5687
5688 ranges += arange.ar_pointer_size;
5689
5690 printf (" %8.8lx %lu\n", address, length);
5691 }
5692
5693 start += arange.ar_length + sizeof (external->ar_length);
5694 }
5695
5696 printf ("\n");
5697
5698 return 1;
5699}
5700
5701
5702static int
5703display_debug_not_supported (section, start, file)
5704 Elf32_Internal_Shdr * section;
5705 unsigned char * start;
5706 FILE * file;
5707{
5708 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
5709 SECTION_NAME (section));
5710
5711 return 1;
5712}
5713
5714 /* A structure containing the name of a debug section and a pointer
5715 to a function that can decode it. */
5716struct
5717{
5718 char * name;
5719 int (* display) PARAMS((Elf32_Internal_Shdr *, unsigned char *, FILE *));
5720}
5721debug_displays[] =
5722{
5723 { ".debug_info", display_debug_info },
5724 { ".debug_abbrev", display_debug_abbrev },
5725 { ".debug_line", display_debug_lines },
5726 { ".debug_aranges", display_debug_aranges },
5727 { ".debug_pubnames", display_debug_pubnames },
5728 { ".debug_macinfo", display_debug_not_supported },
5729 { ".debug_frame", display_debug_not_supported },
5730 { ".debug_str", display_debug_not_supported },
5731 { ".debug_static_func", display_debug_not_supported },
5732 { ".debug_static_vars", display_debug_not_supported },
5733 { ".debug_types", display_debug_not_supported },
5734 { ".debug_weaknames", display_debug_not_supported }
5735};
5736
5737static int
5738display_debug_section (section, file)
5739 Elf32_Internal_Shdr * section;
5740 FILE * file;
5741{
5742 char * name = SECTION_NAME (section);
5743 bfd_size_type length;
5744 unsigned char * start;
5745 int i;
5746
5747 length = section->sh_size;
5748 if (length == 0)
5749 {
5750 printf (_("\nSection '%s' has no debugging data.\n"), name);
5751 return 0;
5752 }
5753
5754 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
5755 "debug section data");
5756
5757 /* See if we know how to display the contents of this section. */
5758 for (i = NUM_ELEM (debug_displays); i--;)
5759 if (strcmp (debug_displays[i].name, name) == 0)
5760 {
5761 debug_displays[i].display (section, start, file);
5762 break;
5763 }
5764
5765 if (i == -1)
5766 printf (_("Unrecognised debug section: %s\n"), name);
5767
5768 free (start);
5769
5770 /* If we loaded in the abbrev section at some point,
5771 we must release it here. */
5772 if (first_abbrev != NULL)
5773 free_abbrevs ();
5774
5775 return 1;
5776}
5777
5778static int
5779process_section_contents (file)
5780 FILE * file;
5781{
5782 Elf32_Internal_Shdr * section;
5783 unsigned int i;
5784
5785 if (! do_dump)
5786 return 1;
5787
5788 for (i = 0, section = section_headers;
5789 i < elf_header.e_shnum
5790 && i < num_dump_sects;
5791 i ++, section ++)
5792 {
5793#ifdef SUPPORT_DISASSEMBLY
5794 if (dump_sects[i] & DISASS_DUMP)
5795 disassemble_section (section, file);
5796#endif
5797 if (dump_sects[i] & HEX_DUMP)
5798 dump_section (section, file);
5799
5800 if (dump_sects[i] & DEBUG_DUMP)
5801 display_debug_section (section, file);
5802 }
5803
5804 if (i < num_dump_sects)
5805 warn (_("Some sections were not dumped because they do not exist!\n"));
5806
5807 return 1;
5808}
5809
5810static void
5811process_mips_fpe_exception (mask)
5812 int mask;
5813{
5814 if (mask)
5815 {
5816 int first = 1;
5817 if (mask & OEX_FPU_INEX)
5818 fputs ("INEX", stdout), first = 0;
5819 if (mask & OEX_FPU_UFLO)
5820 printf ("%sUFLO", first ? "" : "|"), first = 0;
5821 if (mask & OEX_FPU_OFLO)
5822 printf ("%sOFLO", first ? "" : "|"), first = 0;
5823 if (mask & OEX_FPU_DIV0)
5824 printf ("%sDIV0", first ? "" : "|"), first = 0;
5825 if (mask & OEX_FPU_INVAL)
5826 printf ("%sINVAL", first ? "" : "|");
5827 }
5828 else
5829 fputs ("0", stdout);
5830}
5831
5832static int
5833process_mips_specific (file)
9ea033b2 5834 FILE * file;
252b5132 5835{
9ea033b2 5836 Elf_Internal_Dyn * entry;
252b5132
RH
5837 size_t liblist_offset = 0;
5838 size_t liblistno = 0;
5839 size_t conflictsno = 0;
5840 size_t options_offset = 0;
5841 size_t conflicts_offset = 0;
5842
5843 /* We have a lot of special sections. Thanks SGI! */
5844 if (dynamic_segment == NULL)
5845 /* No information available. */
5846 return 0;
5847
5848 for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
5849 switch (entry->d_tag)
5850 {
5851 case DT_MIPS_LIBLIST:
5852 liblist_offset = entry->d_un.d_val - loadaddr;
5853 break;
5854 case DT_MIPS_LIBLISTNO:
5855 liblistno = entry->d_un.d_val;
5856 break;
5857 case DT_MIPS_OPTIONS:
5858 options_offset = entry->d_un.d_val - loadaddr;
5859 break;
5860 case DT_MIPS_CONFLICT:
5861 conflicts_offset = entry->d_un.d_val - loadaddr;
5862 break;
5863 case DT_MIPS_CONFLICTNO:
5864 conflictsno = entry->d_un.d_val;
5865 break;
5866 default:
5867 break;
5868 }
5869
5870 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
5871 {
9ea033b2 5872 Elf32_External_Lib * elib;
252b5132
RH
5873 size_t cnt;
5874
5875 GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
5876 elib, Elf32_External_Lib *, "liblist");
5877
5878 printf ("\nSection '.liblist' contains %d entries:\n", liblistno);
5879 fputs (" Library Time Stamp Checksum Version Flags\n",
5880 stdout);
5881
5882 for (cnt = 0; cnt < liblistno; ++cnt)
5883 {
5884 Elf32_Lib liblist;
5885 time_t time;
5886 char timebuf[20];
5887
5888 liblist.l_name = BYTE_GET (elib[cnt].l_name);
5889 time = BYTE_GET (elib[cnt].l_time_stamp);
5890 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
5891 liblist.l_version = BYTE_GET (elib[cnt].l_version);
5892 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
5893
5894 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
5895
5896 printf ("%3d: %-20s %s %#10lx %-7ld", cnt,
5897 dynamic_strings + liblist.l_name, timebuf,
5898 liblist.l_checksum, liblist.l_version);
5899
5900 if (liblist.l_flags == 0)
5901 puts (" NONE");
5902 else
5903 {
5904 static const struct
5905 {
5906 const char *name;
5907 int bit;
5908 } l_flags_vals[] =
5909 {
5910 { " EXACT_MATCH", LL_EXACT_MATCH },
5911 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
5912 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
5913 { " EXPORTS", LL_EXPORTS },
5914 { " DELAY_LOAD", LL_DELAY_LOAD },
5915 { " DELTA", LL_DELTA }
5916 };
5917 int flags = liblist.l_flags;
5918 int fcnt;
5919
5920 for (fcnt = 0;
5921 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
5922 ++fcnt)
5923 if ((flags & l_flags_vals[fcnt].bit) != 0)
5924 {
5925 fputs (l_flags_vals[fcnt].name, stdout);
5926 flags ^= l_flags_vals[fcnt].bit;
5927 }
5928 if (flags != 0)
5929 printf (" %#x", (unsigned int) flags);
5930
5931 puts ("");
5932 }
5933 }
5934
5935 free (elib);
5936 }
5937
5938 if (options_offset != 0)
5939 {
9ea033b2
NC
5940 Elf_External_Options * eopt;
5941 Elf_Internal_Shdr * sect = section_headers;
5942 Elf_Internal_Options * iopt;
5943 Elf_Internal_Options * option;
252b5132
RH
5944 size_t offset;
5945 int cnt;
5946
5947 /* Find the section header so that we get the size. */
5948 while (sect->sh_type != SHT_MIPS_OPTIONS)
5949 ++sect;
5950
5951 GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
5952 Elf_External_Options *, "options");
5953
5954 iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
5955 * sizeof (*iopt));
5956 if (iopt == NULL)
5957 {
5958 error (_("Out of memory"));
5959 return 0;
5960 }
5961
5962 offset = cnt = 0;
5963 option = iopt;
5964 while (offset < sect->sh_size)
5965 {
9ea033b2 5966 Elf_External_Options * eoption;
252b5132
RH
5967
5968 eoption = (Elf_External_Options *) ((char *) eopt + offset);
5969
5970 option->kind = BYTE_GET (eoption->kind);
5971 option->size = BYTE_GET (eoption->size);
5972 option->section = BYTE_GET (eoption->section);
5973 option->info = BYTE_GET (eoption->info);
5974
5975 offset += option->size;
5976 ++option;
5977 ++cnt;
5978 }
5979
5980 printf (_("\nSection '%s' contains %d entries:\n"),
5981 string_table + sect->sh_name, cnt);
5982
5983 option = iopt;
5984 while (cnt-- > 0)
5985 {
5986 size_t len;
5987
5988 switch (option->kind)
5989 {
5990 case ODK_NULL:
5991 /* This shouldn't happen. */
5992 printf (" NULL %d %lx", option->section, option->info);
5993 break;
5994 case ODK_REGINFO:
5995 printf (" REGINFO ");
5996 if (elf_header.e_machine == EM_MIPS)
5997 {
5998 /* 32bit form. */
5999 Elf32_External_RegInfo *ereg;
6000 Elf32_RegInfo reginfo;
6001
6002 ereg = (Elf32_External_RegInfo *) (option + 1);
6003 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
6004 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
6005 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
6006 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
6007 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
6008 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
6009
6010 printf ("GPR %08lx GP 0x%lx\n",
6011 reginfo.ri_gprmask,
6012 (unsigned long) reginfo.ri_gp_value);
6013 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
6014 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
6015 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
6016 }
6017 else
6018 {
6019 /* 64 bit form. */
9ea033b2 6020 Elf64_External_RegInfo * ereg;
252b5132
RH
6021 Elf64_Internal_RegInfo reginfo;
6022
6023 ereg = (Elf64_External_RegInfo *) (option + 1);
9ea033b2 6024 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
252b5132
RH
6025 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
6026 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
6027 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
6028 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
9ea033b2 6029 reginfo.ri_gp_value = BYTE_GET8 (ereg->ri_gp_value);
252b5132
RH
6030
6031 printf ("GPR %08lx GP 0x",
6032 reginfo.ri_gprmask);
6033 printf_vma (reginfo.ri_gp_value);
6034 printf ("\n");
6035
6036 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
6037 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
6038 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
6039 }
6040 ++option;
6041 continue;
6042 case ODK_EXCEPTIONS:
6043 fputs (" EXCEPTIONS fpe_min(", stdout);
6044 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
6045 fputs (") fpe_max(", stdout);
6046 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
6047 fputs (")", stdout);
6048
6049 if (option->info & OEX_PAGE0)
6050 fputs (" PAGE0", stdout);
6051 if (option->info & OEX_SMM)
6052 fputs (" SMM", stdout);
6053 if (option->info & OEX_FPDBUG)
6054 fputs (" FPDBUG", stdout);
6055 if (option->info & OEX_DISMISS)
6056 fputs (" DISMISS", stdout);
6057 break;
6058 case ODK_PAD:
6059 fputs (" PAD ", stdout);
6060 if (option->info & OPAD_PREFIX)
6061 fputs (" PREFIX", stdout);
6062 if (option->info & OPAD_POSTFIX)
6063 fputs (" POSTFIX", stdout);
6064 if (option->info & OPAD_SYMBOL)
6065 fputs (" SYMBOL", stdout);
6066 break;
6067 case ODK_HWPATCH:
6068 fputs (" HWPATCH ", stdout);
6069 if (option->info & OHW_R4KEOP)
6070 fputs (" R4KEOP", stdout);
6071 if (option->info & OHW_R8KPFETCH)
6072 fputs (" R8KPFETCH", stdout);
6073 if (option->info & OHW_R5KEOP)
6074 fputs (" R5KEOP", stdout);
6075 if (option->info & OHW_R5KCVTL)
6076 fputs (" R5KCVTL", stdout);
6077 break;
6078 case ODK_FILL:
6079 fputs (" FILL ", stdout);
6080 /* XXX Print content of info word? */
6081 break;
6082 case ODK_TAGS:
6083 fputs (" TAGS ", stdout);
6084 /* XXX Print content of info word? */
6085 break;
6086 case ODK_HWAND:
6087 fputs (" HWAND ", stdout);
6088 if (option->info & OHWA0_R4KEOP_CHECKED)
6089 fputs (" R4KEOP_CHECKED", stdout);
6090 if (option->info & OHWA0_R4KEOP_CLEAN)
6091 fputs (" R4KEOP_CLEAN", stdout);
6092 break;
6093 case ODK_HWOR:
6094 fputs (" HWOR ", stdout);
6095 if (option->info & OHWA0_R4KEOP_CHECKED)
6096 fputs (" R4KEOP_CHECKED", stdout);
6097 if (option->info & OHWA0_R4KEOP_CLEAN)
6098 fputs (" R4KEOP_CLEAN", stdout);
6099 break;
6100 case ODK_GP_GROUP:
6101 printf (" GP_GROUP %#06lx self-contained %#06lx",
6102 option->info & OGP_GROUP,
6103 (option->info & OGP_SELF) >> 16);
6104 break;
6105 case ODK_IDENT:
6106 printf (" IDENT %#06lx self-contained %#06lx",
6107 option->info & OGP_GROUP,
6108 (option->info & OGP_SELF) >> 16);
6109 break;
6110 default:
6111 /* This shouldn't happen. */
6112 printf (" %3d ??? %d %lx",
6113 option->kind, option->section, option->info);
6114 break;
6115 }
6116
6117 len = sizeof (*eopt);
6118 while (len < option->size)
6119 if (((char *) option)[len] >= ' '
6120 && ((char *) option)[len] < 0x7f)
6121 printf ("%c", ((char *) option)[len++]);
6122 else
6123 printf ("\\%03o", ((char *) option)[len++]);
6124
6125 fputs ("\n", stdout);
6126 ++option;
6127 }
6128
6129 free (eopt);
6130 }
6131
6132 if (conflicts_offset != 0 && conflictsno != 0)
6133 {
9ea033b2
NC
6134 Elf32_External_Conflict * econf32;
6135 Elf64_External_Conflict * econf64;
6136 Elf32_Conflict * iconf;
252b5132
RH
6137 size_t cnt;
6138
6139 if (dynamic_symbols == NULL)
6140 {
6141 error (_("conflict list with without table"));
6142 return 0;
6143 }
6144
6145 iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (*iconf));
6146 if (iconf == NULL)
6147 {
6148 error (_("Out of memory"));
6149 return 0;
6150 }
6151
9ea033b2 6152 if (is_32bit_elf)
252b5132
RH
6153 {
6154 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf32),
6155 econf32, Elf32_External_Conflict *, "conflict");
6156
6157 for (cnt = 0; cnt < conflictsno; ++cnt)
6158 iconf[cnt] = BYTE_GET (econf32[cnt]);
6159 }
6160 else
6161 {
6162 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf64),
6163 econf64, Elf64_External_Conflict *, "conflict");
6164
6165 for (cnt = 0; cnt < conflictsno; ++cnt)
6166 iconf[cnt] = BYTE_GET (econf64[cnt]);
6167 }
6168
6169 printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
6170 puts (_(" Num: Index Value Name"));
6171
6172 for (cnt = 0; cnt < conflictsno; ++cnt)
6173 {
19936277 6174 Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
252b5132
RH
6175
6176 printf ("%5u: %8lu %#10lx %s\n",
6177 cnt, iconf[cnt], (unsigned long) psym->st_value,
6178 dynamic_strings + psym->st_name);
6179 }
6180
6181
6182 free (iconf);
6183 }
6184
6185 return 1;
6186}
6187
6188static int
6189process_arch_specific (file)
9ea033b2 6190 FILE * file;
252b5132
RH
6191{
6192 switch (elf_header.e_machine)
6193 {
6194 case EM_MIPS:
6195 case EM_MIPS_RS4_BE:
6196 return process_mips_specific (file);
6197 break;
6198 default:
6199 break;
6200 }
6201 return 1;
6202}
6203
6204static int
6205get_file_header (file)
6206 FILE * file;
6207{
9ea033b2
NC
6208 /* Read in the identity array. */
6209 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
6210 return 0;
6211
9ea033b2
NC
6212 /* Determine how to read the rest of the header. */
6213 switch (elf_header.e_ident [EI_DATA])
6214 {
6215 default: /* fall through */
6216 case ELFDATANONE: /* fall through */
6217 case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
6218 case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
6219 }
6220
6221 /* For now we only support 32 bit and 64 bit ELF files. */
6222 is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
6223
6224 /* Read in the rest of the header. */
6225 if (is_32bit_elf)
6226 {
6227 Elf32_External_Ehdr ehdr32;
252b5132 6228
9ea033b2
NC
6229 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
6230 return 0;
6231
6232 elf_header.e_type = BYTE_GET (ehdr32.e_type);
6233 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
6234 elf_header.e_version = BYTE_GET (ehdr32.e_version);
6235 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
6236 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
6237 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
6238 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
6239 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
6240 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
6241 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
6242 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
6243 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
6244 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
6245 }
252b5132 6246 else
9ea033b2
NC
6247 {
6248 Elf64_External_Ehdr ehdr64;
6249
6250 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
6251 return 0;
6252
6253 elf_header.e_type = BYTE_GET (ehdr64.e_type);
6254 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
6255 elf_header.e_version = BYTE_GET (ehdr64.e_version);
6256 elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry);
6257 elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff);
6258 elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff);
6259 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
6260 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
6261 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
6262 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
6263 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
6264 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
6265 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
6266 }
252b5132
RH
6267
6268 return 1;
6269}
6270
6271static void
6272process_file (file_name)
6273 char * file_name;
6274{
6275 FILE * file;
6276 struct stat statbuf;
6277 unsigned int i;
6278
6279 if (stat (file_name, & statbuf) < 0)
6280 {
6281 error (_("Cannot stat input file %s.\n"), file_name);
6282 return;
6283 }
6284
6285 file = fopen (file_name, "rb");
6286 if (file == NULL)
6287 {
6288 error (_("Input file %s not found.\n"), file_name);
6289 return;
6290 }
6291
6292 if (! get_file_header (file))
6293 {
6294 error (_("%s: Failed to read file header\n"), file_name);
6295 fclose (file);
6296 return;
6297 }
6298
6299 /* Initialise per file variables. */
6300 for (i = NUM_ELEM (version_info); i--;)
6301 version_info[i] = 0;
6302
6303 for (i = NUM_ELEM (dynamic_info); i--;)
6304 dynamic_info[i] = 0;
6305
6306 /* Process the file. */
6307 if (show_name)
6308 printf (_("\nFile: %s\n"), file_name);
6309
6310 if (! process_file_header ())
6311 {
6312 fclose (file);
6313 return;
6314 }
6315
6316 process_section_headers (file);
6317
6318 process_program_headers (file);
6319
6320 process_dynamic_segment (file);
6321
6322 process_relocs (file);
6323
6324 process_symbol_table (file);
6325
6326 process_syminfo (file);
6327
6328 process_version_sections (file);
6329
6330 process_section_contents (file);
6331
6332 process_arch_specific (file);
6333
6334 fclose (file);
6335
6336 if (section_headers)
6337 {
6338 free (section_headers);
6339 section_headers = NULL;
6340 }
6341
6342 if (string_table)
6343 {
6344 free (string_table);
6345 string_table = NULL;
6346 }
6347
6348 if (dynamic_strings)
6349 {
6350 free (dynamic_strings);
6351 dynamic_strings = NULL;
6352 }
6353
6354 if (dynamic_symbols)
6355 {
6356 free (dynamic_symbols);
6357 dynamic_symbols = NULL;
19936277 6358 num_dynamic_syms = 0;
252b5132
RH
6359 }
6360
6361 if (dynamic_syminfo)
6362 {
6363 free (dynamic_syminfo);
6364 dynamic_syminfo = NULL;
6365 }
6366}
6367
6368#ifdef SUPPORT_DISASSEMBLY
6369/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2
NC
6370 fix this so that we insert symbolic addresses here, esp for GOT/PLT
6371 symbols */
252b5132
RH
6372
6373void
6374print_address (unsigned int addr, FILE * outfile)
6375{
6376 fprintf (outfile,"0x%8.8x", addr);
6377}
6378
6379/* Needed by the i386 disassembler. */
6380void
6381db_task_printsym (unsigned int addr)
6382{
6383 print_address (addr, stderr);
6384}
6385#endif
6386
6387int
6388main (argc, argv)
6389 int argc;
6390 char ** argv;
6391{
6392#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
6393 setlocale (LC_MESSAGES, "");
6394#endif
6395 bindtextdomain (PACKAGE, LOCALEDIR);
6396 textdomain (PACKAGE);
6397
6398 parse_args (argc, argv);
6399
6400 if (optind < (argc - 1))
6401 show_name = 1;
6402
6403 while (optind < argc)
6404 process_file (argv [optind ++]);
6405
6406 if (dump_sects != NULL)
6407 free (dump_sects);
6408
6409 return 0;
6410}
This page took 0.322417 seconds and 4 git commands to generate.