]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
1999-06-12 David O'Brien <obrien@freebsd.org>
[thirdparty/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
NC
1497 default:
1498 sprintf (buff, _("<unknown: %lx>"), elf_class);
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
NC
1514 default:
1515 sprintf (buff, _("<unknown: %lx>"), encoding);
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
NC
1531 default:
1532 sprintf (buff, _("<unknown: %lx>"), osabi);
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],
1566 elf_header.e_ident [EI_VERSION] == EV_CURRENT ? "(current)" :
ab5e7794
NC
1567 elf_header.e_ident [EI_VERSION] != EV_NONE ? "<unknown: %lx>" : "",
1568 elf_header.e_ident [EI_VERSION]);
252b5132
RH
1569 printf (_(" OS/ABI: %s\n"),
1570 get_osabi_name (elf_header.e_ident [EI_OSABI]));
1571 printf (_(" ABI Version: %d\n"),
1572 elf_header.e_ident [EI_ABIVERSION]);
1573 printf (_(" Type: %s\n"),
1574 get_file_type (elf_header.e_type));
1575 printf (_(" Machine: %s\n"),
1576 get_machine_name (elf_header.e_machine));
1577 printf (_(" Version: 0x%lx\n"),
1578 (unsigned long) elf_header.e_version);
252b5132
RH
1579 printf (_(" Entry point address: 0x%lx\n"),
1580 (unsigned long) elf_header.e_entry);
1581 printf (_(" Start of program headers: %ld (bytes into file)\n"),
1582 (long) elf_header.e_phoff);
1583 printf (_(" Start of section headers: %ld (bytes into file)\n"),
1584 (long) elf_header.e_shoff);
1585 printf (_(" Flags: 0x%lx%s\n"),
1586 (unsigned long) elf_header.e_flags,
1587 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
1588 printf (_(" Size of this header: %ld (bytes)\n"),
1589 (long) elf_header.e_ehsize);
1590 printf (_(" Size of program headers: %ld (bytes)\n"),
1591 (long) elf_header.e_phentsize);
1592 printf (_(" Number of program headers: %ld\n"),
1593 (long) elf_header.e_phnum);
1594 printf (_(" Size of section headers: %ld (bytes)\n"),
1595 (long) elf_header.e_shentsize);
1596 printf (_(" Number of section headers: %ld\n"),
1597 (long) elf_header.e_shnum);
1598 printf (_(" Section header string table index: %ld\n"),
1599 (long) elf_header.e_shstrndx);
1600 }
9ea033b2
NC
1601
1602 return 1;
1603}
1604
252b5132 1605
9ea033b2
NC
1606static int
1607get_32bit_program_headers (file, program_headers)
1608 FILE * file;
1609 Elf_Internal_Phdr * program_headers;
1610{
1611 Elf32_External_Phdr * phdrs;
1612 Elf32_External_Phdr * external;
1613 Elf32_Internal_Phdr * internal;
1614 unsigned int i;
252b5132 1615
9ea033b2
NC
1616 GET_DATA_ALLOC (elf_header.e_phoff,
1617 elf_header.e_phentsize * elf_header.e_phnum,
1618 phdrs, Elf32_External_Phdr *, "program headers");
1619
1620 for (i = 0, internal = program_headers, external = phdrs;
1621 i < elf_header.e_phnum;
1622 i ++, internal ++, external ++)
252b5132 1623 {
9ea033b2
NC
1624 internal->p_type = BYTE_GET (external->p_type);
1625 internal->p_offset = BYTE_GET (external->p_offset);
1626 internal->p_vaddr = BYTE_GET (external->p_vaddr);
1627 internal->p_paddr = BYTE_GET (external->p_paddr);
1628 internal->p_filesz = BYTE_GET (external->p_filesz);
1629 internal->p_memsz = BYTE_GET (external->p_memsz);
1630 internal->p_flags = BYTE_GET (external->p_flags);
1631 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
1632 }
1633
9ea033b2
NC
1634 free (phdrs);
1635
252b5132
RH
1636 return 1;
1637}
1638
9ea033b2
NC
1639static int
1640get_64bit_program_headers (file, program_headers)
1641 FILE * file;
1642 Elf_Internal_Phdr * program_headers;
1643{
1644 Elf64_External_Phdr * phdrs;
1645 Elf64_External_Phdr * external;
1646 Elf64_Internal_Phdr * internal;
1647 unsigned int i;
1648
1649 GET_DATA_ALLOC (elf_header.e_phoff,
1650 elf_header.e_phentsize * elf_header.e_phnum,
1651 phdrs, Elf64_External_Phdr *, "program headers");
1652
1653 for (i = 0, internal = program_headers, external = phdrs;
1654 i < elf_header.e_phnum;
1655 i ++, internal ++, external ++)
1656 {
1657 internal->p_type = BYTE_GET (external->p_type);
1658 internal->p_flags = BYTE_GET (external->p_flags);
1659 internal->p_offset = BYTE_GET8 (external->p_offset);
1660 internal->p_vaddr = BYTE_GET8 (external->p_vaddr);
1661 internal->p_paddr = BYTE_GET8 (external->p_paddr);
1662 internal->p_filesz = BYTE_GET8 (external->p_filesz);
1663 internal->p_memsz = BYTE_GET8 (external->p_memsz);
1664 internal->p_align = BYTE_GET8 (external->p_align);
1665 }
1666
1667 free (phdrs);
1668
1669 return 1;
1670}
252b5132
RH
1671
1672static int
1673process_program_headers (file)
1674 FILE * file;
1675{
9ea033b2
NC
1676 Elf_Internal_Phdr * program_headers;
1677 Elf_Internal_Phdr * segment;
1678 unsigned int i;
252b5132
RH
1679
1680 if (elf_header.e_phnum == 0)
1681 {
1682 if (do_segments)
1683 printf (_("\nThere are no program headers in this file.\n"));
1684 return 1;
1685 }
1686
1687 if (do_segments && !do_header)
1688 {
1689 printf (_("\nElf file is %s\n"), get_file_type (elf_header.e_type));
1690 printf (_("Entry point 0x%lx\n"), (unsigned long) elf_header.e_entry);
1691 printf (_("There are %d program headers, starting at offset %lx:\n"),
1692 elf_header.e_phnum, (unsigned long) elf_header.e_phoff);
1693 }
1694
9ea033b2
NC
1695 program_headers = (Elf_Internal_Phdr *) malloc
1696 (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
252b5132
RH
1697
1698 if (program_headers == NULL)
1699 {
1700 error (_("Out of memory\n"));
1701 return 0;
1702 }
1703
9ea033b2
NC
1704 if (is_32bit_elf)
1705 i = get_32bit_program_headers (file, program_headers);
1706 else
1707 i = get_64bit_program_headers (file, program_headers);
1708
1709 if (i == 0)
252b5132 1710 {
9ea033b2
NC
1711 free (program_headers);
1712 return 0;
252b5132 1713 }
9ea033b2 1714
252b5132
RH
1715 if (do_segments)
1716 {
1717 printf
1718 (_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
1719 printf
1720 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
1721 }
1722
1723 loadaddr = -1;
1724 dynamic_addr = 0;
1b228002 1725 dynamic_size = 0;
252b5132
RH
1726
1727 for (i = 0, segment = program_headers;
1728 i < elf_header.e_phnum;
1729 i ++, segment ++)
1730 {
1731 if (do_segments)
1732 {
1733 printf (" %-11.11s ", get_segment_type (segment->p_type));
1734 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
1735 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
1736 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
1737 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
1738 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
1739 printf ("%c%c%c ",
1740 (segment->p_flags & PF_R ? 'R' : ' '),
1741 (segment->p_flags & PF_W ? 'W' : ' '),
1742 (segment->p_flags & PF_X ? 'E' : ' '));
1743 printf ("%#lx", (unsigned long) segment->p_align);
1744 }
1745
1746 switch (segment->p_type)
1747 {
1748 case PT_LOAD:
1749 if (loadaddr == -1)
1750 loadaddr = (segment->p_vaddr & 0xfffff000)
1751 - (segment->p_offset & 0xfffff000);
1752 break;
1753
1754 case PT_DYNAMIC:
1755 if (dynamic_addr)
1756 error (_("more than one dynamic segment\n"));
1757
1758 dynamic_addr = segment->p_offset;
1759 dynamic_size = segment->p_filesz;
1760 break;
1761
1762 case PT_INTERP:
1763 if (fseek (file, segment->p_offset, SEEK_SET))
1764 error (_("Unable to find program interpreter name\n"));
1765 else
1766 {
1767 program_interpreter[0] = 0;
1768 fscanf (file, "%63s", program_interpreter);
1769
1770 if (do_segments)
1771 printf (_("\n [Requesting program interpreter: %s]"),
1772 program_interpreter);
1773 }
1774 break;
1775 }
1776
1777 if (do_segments)
1778 putc ('\n', stdout);
1779 }
1780
1781 if (loadaddr == -1)
1782 {
1783 /* Very strange. */
1784 loadaddr = 0;
1785 }
1786
1787 if (do_segments && section_headers != NULL)
1788 {
1789 printf (_("\n Section to Segment mapping:\n"));
1790 printf (_(" Segment Sections...\n"));
1791
1792 assert (string_table != NULL);
1793
1794 for (i = 0; i < elf_header.e_phnum; i++)
1795 {
9ea033b2
NC
1796 int j;
1797 Elf_Internal_Shdr * section;
252b5132
RH
1798
1799 segment = program_headers + i;
1800 section = section_headers;
1801
1802 printf (" %2.2d ", i);
1803
1804 for (j = 0; j < elf_header.e_shnum; j++, section ++)
1805 {
1806 if (section->sh_size > 0
1807 /* Compare allocated sections by VMA, unallocated
1808 sections by file offset. */
1809 && (section->sh_flags & SHF_ALLOC
1810 ? (section->sh_addr >= segment->p_vaddr
1811 && section->sh_addr + section->sh_size
1812 <= segment->p_vaddr + segment->p_memsz)
1813 : (section->sh_offset >= segment->p_offset
1814 && (section->sh_offset + section->sh_size
1815 <= segment->p_offset + segment->p_filesz))))
1816 printf ("%s ", SECTION_NAME (section));
1817 }
1818
1819 putc ('\n',stdout);
1820 }
1821 }
1822
1823 free (program_headers);
1824
1825 return 1;
1826}
1827
1828
1829static int
9ea033b2 1830get_32bit_section_headers (file)
252b5132
RH
1831 FILE * file;
1832{
1833 Elf32_External_Shdr * shdrs;
1834 Elf32_Internal_Shdr * internal;
1835 unsigned int i;
1836
1837 GET_DATA_ALLOC (elf_header.e_shoff,
1838 elf_header.e_shentsize * elf_header.e_shnum,
1839 shdrs, Elf32_External_Shdr *, "section headers");
1840
9ea033b2
NC
1841 section_headers = (Elf_Internal_Shdr *) malloc
1842 (elf_header.e_shnum * sizeof (Elf_Internal_Shdr));
252b5132
RH
1843
1844 if (section_headers == NULL)
1845 {
1846 error (_("Out of memory\n"));
1847 return 0;
1848 }
1849
1850 for (i = 0, internal = section_headers;
1851 i < elf_header.e_shnum;
1852 i ++, internal ++)
1853 {
1854 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
1855 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
1856 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
1857 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
1858 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
1859 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
1860 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
1861 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
1862 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
1863 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
1864 }
1865
1866 free (shdrs);
1867
1868 return 1;
1869}
1870
9ea033b2
NC
1871static int
1872get_64bit_section_headers (file)
1873 FILE * file;
1874{
1875 Elf64_External_Shdr * shdrs;
1876 Elf64_Internal_Shdr * internal;
1877 unsigned int i;
1878
1879 GET_DATA_ALLOC (elf_header.e_shoff,
1880 elf_header.e_shentsize * elf_header.e_shnum,
1881 shdrs, Elf64_External_Shdr *, "section headers");
1882
1883 section_headers = (Elf_Internal_Shdr *) malloc
1884 (elf_header.e_shnum * sizeof (Elf_Internal_Shdr));
1885
1886 if (section_headers == NULL)
1887 {
1888 error (_("Out of memory\n"));
1889 return 0;
1890 }
1891
1892 for (i = 0, internal = section_headers;
1893 i < elf_header.e_shnum;
1894 i ++, internal ++)
1895 {
1896 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
1897 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
1898 internal->sh_flags = BYTE_GET8 (shdrs[i].sh_flags);
1899 internal->sh_addr = BYTE_GET8 (shdrs[i].sh_addr);
1900 internal->sh_size = BYTE_GET8 (shdrs[i].sh_size);
1901 internal->sh_entsize = BYTE_GET8 (shdrs[i].sh_entsize);
1902 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
1903 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
1904 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
1905 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
1906 }
1907
1908 free (shdrs);
1909
1910 return 1;
1911}
1912
252b5132 1913static Elf_Internal_Sym *
9ea033b2 1914get_32bit_elf_symbols (file, offset, number)
252b5132
RH
1915 FILE * file;
1916 unsigned long offset;
1917 unsigned long number;
1918{
1919 Elf32_External_Sym * esyms;
1920 Elf_Internal_Sym * isyms;
1921 Elf_Internal_Sym * psym;
1922 unsigned int j;
1923
1924 GET_DATA_ALLOC (offset, number * sizeof (Elf32_External_Sym),
1925 esyms, Elf32_External_Sym *, "symbols");
1926
1927 isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
1928
1929 if (isyms == NULL)
1930 {
1931 error (_("Out of memory\n"));
1932 free (esyms);
1933
1934 return NULL;
1935 }
1936
1937 for (j = 0, psym = isyms;
1938 j < number;
1939 j ++, psym ++)
1940 {
1941 psym->st_name = BYTE_GET (esyms[j].st_name);
1942 psym->st_value = BYTE_GET (esyms[j].st_value);
1943 psym->st_size = BYTE_GET (esyms[j].st_size);
1944 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
1945 psym->st_info = BYTE_GET (esyms[j].st_info);
1946 psym->st_other = BYTE_GET (esyms[j].st_other);
1947 }
1948
1949 free (esyms);
1950
1951 return isyms;
1952}
1953
9ea033b2
NC
1954static Elf_Internal_Sym *
1955get_64bit_elf_symbols (file, offset, number)
1956 FILE * file;
1957 unsigned long offset;
1958 unsigned long number;
1959{
1960 Elf64_External_Sym * esyms;
1961 Elf_Internal_Sym * isyms;
1962 Elf_Internal_Sym * psym;
1963 unsigned int j;
1964
1965 GET_DATA_ALLOC (offset, number * sizeof (Elf64_External_Sym),
1966 esyms, Elf64_External_Sym *, "symbols");
1967
1968 isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
1969
1970 if (isyms == NULL)
1971 {
1972 error (_("Out of memory\n"));
1973 free (esyms);
1974
1975 return NULL;
1976 }
1977
1978 for (j = 0, psym = isyms;
1979 j < number;
1980 j ++, psym ++)
1981 {
1982 psym->st_name = BYTE_GET (esyms[j].st_name);
1983 psym->st_info = BYTE_GET (esyms[j].st_info);
1984 psym->st_other = BYTE_GET (esyms[j].st_other);
1985 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
1986 psym->st_value = BYTE_GET8 (esyms[j].st_value);
1987 psym->st_size = BYTE_GET8 (esyms[j].st_size);
1988 }
1989
1990 free (esyms);
1991
1992 return isyms;
1993}
1994
252b5132
RH
1995static int
1996process_section_headers (file)
1997 FILE * file;
1998{
9ea033b2
NC
1999 Elf_Internal_Shdr * section;
2000 int i;
252b5132
RH
2001
2002 section_headers = NULL;
2003
2004 if (elf_header.e_shnum == 0)
2005 {
2006 if (do_sections)
2007 printf (_("\nThere are no sections in this file.\n"));
2008
2009 return 1;
2010 }
2011
2012 if (do_sections && !do_header)
9ea033b2 2013 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
2014 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
2015
9ea033b2
NC
2016 if (is_32bit_elf)
2017 {
2018 if (! get_32bit_section_headers (file))
2019 return 0;
2020 }
2021 else if (! get_64bit_section_headers (file))
252b5132
RH
2022 return 0;
2023
2024 /* Read in the string table, so that we have names to display. */
2025 section = section_headers + elf_header.e_shstrndx;
2026
2027 if (section->sh_size != 0)
2028 {
2029 unsigned long string_table_offset;
2030
2031 string_table_offset = section->sh_offset;
2032
2033 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2034 string_table, char *, "string table");
2035 }
2036
2037 /* Scan the sections for the dynamic symbol table
2038 and dynamic string table and debug sections. */
2039 dynamic_symbols = NULL;
2040 dynamic_strings = NULL;
2041 dynamic_syminfo = NULL;
9ea033b2 2042
252b5132
RH
2043 for (i = 0, section = section_headers;
2044 i < elf_header.e_shnum;
2045 i ++, section ++)
2046 {
2047 char * name = SECTION_NAME (section);
2048
2049 if (section->sh_type == SHT_DYNSYM)
2050 {
2051 if (dynamic_symbols != NULL)
2052 {
2053 error (_("File contains multiple dynamic symbol tables\n"));
2054 continue;
2055 }
2056
19936277 2057 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ea033b2 2058 dynamic_symbols =
19936277 2059 GET_ELF_SYMBOLS (file, section->sh_offset, num_dynamic_syms);
252b5132
RH
2060 }
2061 else if (section->sh_type == SHT_STRTAB
2062 && strcmp (name, ".dynstr") == 0)
2063 {
2064 if (dynamic_strings != NULL)
2065 {
2066 error (_("File contains multiple dynamic string tables\n"));
2067 continue;
2068 }
2069
2070 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2071 dynamic_strings, char *, "dynamic strings");
2072 }
2073 else if ((do_debugging || do_debug_info || do_debug_abbrevs
2074 || do_debug_lines || do_debug_pubnames || do_debug_aranges)
2075 && strncmp (name, ".debug_", 7) == 0)
2076 {
2077 name += 7;
2078
2079 if (do_debugging
2080 || (do_debug_info && (strcmp (name, "info") == 0))
2081 || (do_debug_abbrevs && (strcmp (name, "abbrev") == 0))
2082 || (do_debug_lines && (strcmp (name, "line") == 0))
2083 || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
2084 || (do_debug_aranges && (strcmp (name, "aranges") == 0))
2085 )
2086 request_dump (i, DEBUG_DUMP);
2087 }
2088 }
2089
2090 if (! do_sections)
2091 return 1;
2092
2093 printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
2094 printf
2095 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
2096
2097 for (i = 0, section = section_headers;
2098 i < elf_header.e_shnum;
2099 i ++, section ++)
2100 {
2101 printf (" [%2d] %-17.17s %-15.15s ",
2102 i,
2103 SECTION_NAME (section),
2104 get_section_type_name (section->sh_type));
2105
2106 printf ( "%8.8lx %6.6lx %6.6lx %2.2lx",
2107 (unsigned long) section->sh_addr,
2108 (unsigned long) section->sh_offset,
2109 (unsigned long) section->sh_size,
2110 (unsigned long) section->sh_entsize);
2111
2112 printf (" %c%c%c %2ld %3lx %ld\n",
2113 (section->sh_flags & SHF_WRITE ? 'W' : ' '),
2114 (section->sh_flags & SHF_ALLOC ? 'A' : ' '),
2115 (section->sh_flags & SHF_EXECINSTR ? 'X' : ' '),
2116 (unsigned long) section->sh_link,
2117 (unsigned long) section->sh_info,
2118 (unsigned long) section->sh_addralign);
2119 }
2120
2121 return 1;
2122}
2123
2124/* Process the reloc section. */
2125static int
2126process_relocs (file)
2127 FILE * file;
2128{
2129 unsigned long rel_size;
2130 unsigned long rel_offset;
2131
2132
2133 if (!do_reloc)
2134 return 1;
2135
2136 if (do_using_dynamic)
2137 {
9c19a809
NC
2138 int is_rela;
2139
252b5132
RH
2140 rel_size = 0;
2141 rel_offset = 0;
2142
2143 if (dynamic_info[DT_REL])
2144 {
2145 rel_offset = dynamic_info[DT_REL];
2146 rel_size = dynamic_info[DT_RELSZ];
9c19a809 2147 is_rela = FALSE;
252b5132
RH
2148 }
2149 else if (dynamic_info [DT_RELA])
2150 {
2151 rel_offset = dynamic_info[DT_RELA];
2152 rel_size = dynamic_info[DT_RELASZ];
9c19a809 2153 is_rela = TRUE;
252b5132
RH
2154 }
2155 else if (dynamic_info[DT_JMPREL])
2156 {
2157 rel_offset = dynamic_info[DT_JMPREL];
2158 rel_size = dynamic_info[DT_PLTRELSZ];
19936277 2159
aa903cfb
AS
2160 switch (dynamic_info[DT_PLTREL])
2161 {
2162 case DT_REL:
2163 is_rela = FALSE;
2164 break;
2165 case DT_RELA:
2166 is_rela = TRUE;
2167 break;
2168 default:
2169 is_rela = UNKNOWN;
2170 break;
2171 }
252b5132
RH
2172 }
2173
2174 if (rel_size)
2175 {
2176 printf
2177 (_("\nRelocation section at offset 0x%lx contains %ld bytes:\n"),
2178 rel_offset, rel_size);
2179
2180 dump_relocations (file, rel_offset - loadaddr, rel_size,
19936277 2181 dynamic_symbols, num_dynamic_syms, dynamic_strings, is_rela);
252b5132
RH
2182 }
2183 else
2184 printf (_("\nThere are no dynamic relocations in this file.\n"));
2185 }
2186 else
2187 {
2188 Elf32_Internal_Shdr * section;
2189 unsigned long i;
2190 int found = 0;
2191
2192 for (i = 0, section = section_headers;
2193 i < elf_header.e_shnum;
2194 i++, section ++)
2195 {
2196 if ( section->sh_type != SHT_RELA
2197 && section->sh_type != SHT_REL)
2198 continue;
2199
2200 rel_offset = section->sh_offset;
2201 rel_size = section->sh_size;
2202
2203 if (rel_size)
2204 {
2205 Elf32_Internal_Shdr * strsec;
2206 Elf32_Internal_Shdr * symsec;
2207 Elf_Internal_Sym * symtab;
2208 char * strtab;
9c19a809 2209 int is_rela;
19936277 2210 unsigned long nsyms;
9c19a809 2211
252b5132
RH
2212 printf (_("\nRelocation section "));
2213
2214 if (string_table == NULL)
19936277 2215 printf ("%d", section->sh_name);
252b5132 2216 else
19936277 2217 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
2218
2219 printf (_(" at offset 0x%lx contains %lu entries:\n"),
2220 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
2221
2222 symsec = section_headers + section->sh_link;
2223
19936277
NC
2224 nsyms = symsec->sh_size / symsec->sh_entsize;
2225 symtab = GET_ELF_SYMBOLS (file, symsec->sh_offset, nsyms);
252b5132
RH
2226
2227 if (symtab == NULL)
2228 continue;
2229
2230 strsec = section_headers + symsec->sh_link;
2231
2232 GET_DATA_ALLOC (strsec->sh_offset, strsec->sh_size, strtab,
2233 char *, "string table");
aa903cfb
AS
2234
2235 is_rela = section->sh_type == SHT_RELA;
252b5132 2236
19936277 2237 dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela);
252b5132
RH
2238
2239 free (strtab);
2240 free (symtab);
2241
2242 found = 1;
2243 }
2244 }
2245
2246 if (! found)
2247 printf (_("\nThere are no relocations in this file.\n"));
2248 }
2249
2250 return 1;
2251}
2252
2253
2254static void
2255dynamic_segment_mips_val (entry)
2256 Elf_Internal_Dyn * entry;
2257{
2258 switch (entry->d_tag)
2259 {
2260 case DT_MIPS_FLAGS:
2261 if (entry->d_un.d_val == 0)
2262 printf ("NONE\n");
2263 else
2264 {
2265 static const char * opts[] =
2266 {
2267 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
2268 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
2269 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
2270 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
2271 "RLD_ORDER_SAFE"
2272 };
2273 unsigned int cnt;
2274 int first = 1;
2275 for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
2276 if (entry->d_un.d_val & (1 << cnt))
2277 {
2278 printf ("%s%s", first ? "" : " ", opts[cnt]);
2279 first = 0;
2280 }
2281 puts ("");
2282 }
2283 break;
2284
2285 case DT_MIPS_IVERSION:
2286 if (dynamic_strings != NULL)
2287 printf ("Interface Version: %s\n",
2288 dynamic_strings + entry->d_un.d_val);
2289 else
2290 printf ("%ld\n", (long) entry->d_un.d_ptr);
2291 break;
2292
2293 case DT_MIPS_TIME_STAMP:
2294 {
2295 char timebuf[20];
2296 time_t time = entry->d_un.d_val;
2297 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
2298 printf ("Time Stamp: %s\n", timebuf);
2299 }
2300 break;
2301
2302 case DT_MIPS_RLD_VERSION:
2303 case DT_MIPS_LOCAL_GOTNO:
2304 case DT_MIPS_CONFLICTNO:
2305 case DT_MIPS_LIBLISTNO:
2306 case DT_MIPS_SYMTABNO:
2307 case DT_MIPS_UNREFEXTNO:
2308 case DT_MIPS_HIPAGENO:
2309 case DT_MIPS_DELTA_CLASS_NO:
2310 case DT_MIPS_DELTA_INSTANCE_NO:
2311 case DT_MIPS_DELTA_RELOC_NO:
2312 case DT_MIPS_DELTA_SYM_NO:
2313 case DT_MIPS_DELTA_CLASSSYM_NO:
2314 case DT_MIPS_COMPACT_SIZE:
2315 printf ("%ld\n", (long) entry->d_un.d_ptr);
2316 break;
2317
2318 default:
2319 printf ("%#lx\n", (long) entry->d_un.d_ptr);
2320 }
2321}
2322
252b5132 2323static int
9ea033b2 2324get_32bit_dynamic_segment (file)
252b5132
RH
2325 FILE * file;
2326{
9ea033b2
NC
2327 Elf32_External_Dyn * edyn;
2328 Elf_Internal_Dyn * entry;
2329 bfd_size_type i;
2330
2331 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
2332 edyn, Elf32_External_Dyn *, "dynamic segment");
2333
2334 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
2335 how large this .dynamic is now. We can do this even before the byte
2336 swapping since the DT_NULL tag is recognizable. */
2337 dynamic_size = 0;
2338 while (*(Elf32_Word *) edyn [dynamic_size++].d_tag != DT_NULL)
2339 ;
252b5132 2340
9ea033b2
NC
2341 dynamic_segment = (Elf_Internal_Dyn *)
2342 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
2343
2344 if (dynamic_segment == NULL)
252b5132 2345 {
9ea033b2
NC
2346 error (_("Out of memory\n"));
2347 free (edyn);
2348 return 0;
2349 }
252b5132 2350
9ea033b2
NC
2351 for (i = 0, entry = dynamic_segment;
2352 i < dynamic_size;
2353 i ++, entry ++)
2354 {
2355 entry->d_tag = BYTE_GET (edyn [i].d_tag);
2356 entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
252b5132
RH
2357 }
2358
9ea033b2
NC
2359 free (edyn);
2360
2361 return 1;
2362}
2363
2364static int
2365get_64bit_dynamic_segment (file)
2366 FILE * file;
2367{
2368 Elf64_External_Dyn * edyn;
2369 Elf_Internal_Dyn * entry;
2370 bfd_size_type i;
2371
252b5132 2372 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
9ea033b2 2373 edyn, Elf64_External_Dyn *, "dynamic segment");
252b5132
RH
2374
2375 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
9ea033b2 2376 how large this .dynamic is now. We can do this even before the byte
252b5132
RH
2377 swapping since the DT_NULL tag is recognizable. */
2378 dynamic_size = 0;
9ea033b2 2379 while (*(bfd_vma *) edyn [dynamic_size ++].d_tag != DT_NULL)
252b5132
RH
2380 ;
2381
2382 dynamic_segment = (Elf_Internal_Dyn *)
2383 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
2384
2385 if (dynamic_segment == NULL)
2386 {
2387 error (_("Out of memory\n"));
2388 free (edyn);
2389 return 0;
2390 }
2391
2392 for (i = 0, entry = dynamic_segment;
2393 i < dynamic_size;
2394 i ++, entry ++)
2395 {
9ea033b2
NC
2396 entry->d_tag = BYTE_GET8 (edyn [i].d_tag);
2397 entry->d_un.d_val = BYTE_GET8 (edyn [i].d_un.d_val);
252b5132
RH
2398 }
2399
2400 free (edyn);
2401
9ea033b2
NC
2402 return 1;
2403}
2404
2405/* Parse and display the contents of the dynamic segment. */
2406static int
2407process_dynamic_segment (file)
2408 FILE * file;
2409{
2410 Elf_Internal_Dyn * entry;
2411 bfd_size_type i;
2412
2413 if (dynamic_size == 0)
2414 {
2415 if (do_dynamic)
2416 printf (_("\nThere is no dynamic segment in this file.\n"));
2417
2418 return 1;
2419 }
2420
2421 if (is_32bit_elf)
2422 {
2423 if (! get_32bit_dynamic_segment (file))
2424 return 0;
2425 }
2426 else if (! get_64bit_dynamic_segment (file))
2427 return 0;
2428
252b5132
RH
2429 /* Find the appropriate symbol table. */
2430 if (dynamic_symbols == NULL)
2431 {
2432 for (i = 0, entry = dynamic_segment;
2433 i < dynamic_size;
2434 ++i, ++ entry)
2435 {
2436 unsigned long offset;
252b5132
RH
2437
2438 if (entry->d_tag != DT_SYMTAB)
2439 continue;
2440
2441 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
2442
2443 /* Since we do not know how big the symbol table is,
2444 we default to reading in the entire file (!) and
2445 processing that. This is overkill, I know, but it
2446 should work. */
252b5132
RH
2447 offset = entry->d_un.d_val - loadaddr;
2448
2449 if (fseek (file, 0, SEEK_END))
2450 error (_("Unable to seek to end of file!"));
2451
9ea033b2 2452 if (is_32bit_elf)
19936277 2453 num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
9ea033b2 2454 else
19936277 2455 num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf64_External_Sym);
252b5132 2456
19936277 2457 if (num_dynamic_syms < 1)
252b5132
RH
2458 {
2459 error (_("Unable to determine the number of symbols to load\n"));
2460 continue;
2461 }
2462
19936277 2463 dynamic_symbols = GET_ELF_SYMBOLS (file, offset, num_dynamic_syms);
252b5132
RH
2464 }
2465 }
2466
2467 /* Similarly find a string table. */
2468 if (dynamic_strings == NULL)
2469 {
2470 for (i = 0, entry = dynamic_segment;
2471 i < dynamic_size;
2472 ++i, ++ entry)
2473 {
2474 unsigned long offset;
2475 long str_tab_len;
2476
2477 if (entry->d_tag != DT_STRTAB)
2478 continue;
2479
2480 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
2481
2482 /* Since we do not know how big the string table is,
2483 we default to reading in the entire file (!) and
2484 processing that. This is overkill, I know, but it
2485 should work. */
2486
2487 offset = entry->d_un.d_val - loadaddr;
2488 if (fseek (file, 0, SEEK_END))
2489 error (_("Unable to seek to end of file\n"));
2490 str_tab_len = ftell (file) - offset;
2491
2492 if (str_tab_len < 1)
2493 {
2494 error
2495 (_("Unable to determine the length of the dynamic string table\n"));
2496 continue;
2497 }
2498
2499 GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
2500 "dynamic string table");
2501
2502 break;
2503 }
2504 }
2505
2506 /* And find the syminfo section if available. */
2507 if (dynamic_syminfo == NULL)
2508 {
2509 unsigned int syminsz = 0;
2510
2511 for (i = 0, entry = dynamic_segment;
2512 i < dynamic_size;
2513 ++i, ++ entry)
2514 {
2515 if (entry->d_tag == DT_SYMINENT)
2516 {
2517 /* Note: these braces are necessary to avoid a syntax
2518 error from the SunOS4 C compiler. */
2519 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
2520 }
2521 else if (entry->d_tag == DT_SYMINSZ)
2522 syminsz = entry->d_un.d_val;
2523 else if (entry->d_tag == DT_SYMINFO)
2524 dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
2525 }
2526
2527 if (dynamic_syminfo_offset != 0 && syminsz != 0)
2528 {
9ea033b2
NC
2529 Elf_External_Syminfo * extsyminfo;
2530 Elf_Internal_Syminfo * syminfo;
252b5132
RH
2531
2532 /* There is a syminfo section. Read the data. */
2533 GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
2534 Elf_External_Syminfo *, "symbol information");
2535
2536 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
2537 if (dynamic_syminfo == NULL)
2538 {
2539 error (_("Out of memory\n"));
2540 return 0;
2541 }
2542
2543 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
2544 for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
2545 ++i, ++syminfo)
2546 {
2547 syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
2548 syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
2549 }
2550
2551 free (extsyminfo);
2552 }
2553 }
2554
2555 if (do_dynamic && dynamic_addr)
2556 printf (_("\nDynamic segment at offset 0x%x contains %d entries:\n"),
2557 dynamic_addr, dynamic_size);
2558 if (do_dynamic)
2559 printf (_(" Tag Type Name/Value\n"));
2560
2561 for (i = 0, entry = dynamic_segment;
2562 i < dynamic_size;
2563 i++, entry ++)
2564 {
2565 if (do_dynamic)
2566 printf (_(" 0x%-8.8lx (%s)%*s"),
2567 (unsigned long) entry->d_tag,
2568 get_dynamic_type (entry->d_tag),
2569 27 - strlen (get_dynamic_type (entry->d_tag)),
2570 " ");
2571
2572 switch (entry->d_tag)
2573 {
2574 case DT_AUXILIARY:
2575 case DT_FILTER:
2576 if (do_dynamic)
2577 {
2578 if (entry->d_tag == DT_AUXILIARY)
2579 printf (_("Auxiliary library"));
2580 else
2581 printf (_("Filter library"));
2582
2583 if (dynamic_strings)
2584 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
2585 else
2586 printf (": %#lx\n", (long) entry->d_un.d_val);
2587 }
2588 break;
2589
2590 case DT_FEATURE_1:
2591 if (do_dynamic)
2592 {
2593 printf (_("Flags:"));
2594 if (entry->d_un.d_val == 0)
2595 printf (_(" None\n"));
2596 else
2597 {
2598 unsigned long int val = entry->d_un.d_val;
2599 if (val & DTF_1_PARINIT)
2600 {
2601 printf (" PARINIT");
2602 val ^= DTF_1_PARINIT;
2603 }
2604 if (val != 0)
2605 printf (" %lx", val);
2606 puts ("");
2607 }
2608 }
2609 break;
2610
2611 case DT_POSFLAG_1:
2612 if (do_dynamic)
2613 {
2614 printf (_("Flags:"));
2615 if (entry->d_un.d_val == 0)
2616 printf (_(" None\n"));
2617 else
2618 {
2619 unsigned long int val = entry->d_un.d_val;
2620 if (val & DF_P1_LAZYLOAD)
2621 {
2622 printf (" LAZYLOAD");
2623 val ^= DF_P1_LAZYLOAD;
2624 }
2625 if (val & DF_P1_GROUPPERM)
2626 {
2627 printf (" GROUPPERM");
2628 val ^= DF_P1_GROUPPERM;
2629 }
2630 if (val != 0)
2631 printf (" %lx", val);
2632 puts ("");
2633 }
2634 }
2635 break;
2636
2637 case DT_FLAGS_1:
2638 if (do_dynamic)
2639 {
2640 printf (_("Flags:"));
2641 if (entry->d_un.d_val == 0)
2642 printf (_(" None\n"));
2643 else
2644 {
2645 unsigned long int val = entry->d_un.d_val;
2646 if (val & DF_1_NOW)
2647 {
2648 printf (" NOW");
2649 val ^= DF_1_NOW;
2650 }
2651 if (val & DF_1_GLOBAL)
2652 {
2653 printf (" GLOBAL");
2654 val ^= DF_1_GLOBAL;
2655 }
2656 if (val & DF_1_GROUP)
2657 {
2658 printf (" GROUP");
2659 val ^= DF_1_GROUP;
2660 }
2661 if (val & DF_1_NODELETE)
2662 {
2663 printf (" NODELETE");
2664 val ^= DF_1_NODELETE;
2665 }
2666 if (val & DF_1_LOADFLTR)
2667 {
2668 printf (" LOADFLTR");
2669 val ^= DF_1_LOADFLTR;
2670 }
2671 if (val & DF_1_INITFIRST)
2672 {
2673 printf (" INITFIRST");
2674 val ^= DF_1_INITFIRST;
2675 }
2676 if (val & DF_1_NOOPEN)
2677 {
2678 printf (" NOOPEN");
2679 val ^= DF_1_NOOPEN;
2680 }
2681 if (val & DF_1_ORIGIN)
2682 {
2683 printf (" ORIGIN");
2684 val ^= DF_1_ORIGIN;
2685 }
2686 if (val & DF_1_DIRECT)
2687 {
2688 printf (" DIRECT");
2689 val ^= DF_1_DIRECT;
2690 }
2691 if (val & DF_1_TRANS)
2692 {
2693 printf (" TRANS");
2694 val ^= DF_1_TRANS;
2695 }
2696 if (val & DF_1_INTERPOSE)
2697 {
2698 printf (" INTERPOSE");
2699 val ^= DF_1_INTERPOSE;
2700 }
2701 if (val != 0)
2702 printf (" %lx", val);
2703 puts ("");
2704 }
2705 }
2706 break;
2707
2708 case DT_PLTREL:
2709 if (do_dynamic)
2710 puts (get_dynamic_type (entry->d_un.d_val));
2711 break;
2712
2713 case DT_NULL :
2714 case DT_NEEDED :
2715 case DT_PLTGOT :
2716 case DT_HASH :
2717 case DT_STRTAB :
2718 case DT_SYMTAB :
2719 case DT_RELA :
2720 case DT_INIT :
2721 case DT_FINI :
2722 case DT_SONAME :
2723 case DT_RPATH :
2724 case DT_SYMBOLIC:
2725 case DT_REL :
2726 case DT_DEBUG :
2727 case DT_TEXTREL :
2728 case DT_JMPREL :
2729 dynamic_info[entry->d_tag] = entry->d_un.d_val;
2730
2731 if (do_dynamic)
2732 {
2733 char * name;
2734
2735 if (dynamic_strings == NULL)
2736 name = NULL;
2737 else
2738 name = dynamic_strings + entry->d_un.d_val;
2739
2740 if (name)
2741 {
2742 switch (entry->d_tag)
2743 {
2744 case DT_NEEDED:
2745 printf (_("Shared library: [%s]"), name);
2746
2747 if (strcmp (name, program_interpreter))
2748 printf ("\n");
2749 else
2750 printf (_(" program interpreter\n"));
2751 break;
2752
2753 case DT_SONAME:
2754 printf (_("Library soname: [%s]\n"), name);
2755 break;
2756
2757 case DT_RPATH:
2758 printf (_("Library rpath: [%s]\n"), name);
2759 break;
2760
2761 default:
2762 printf ("%#lx\n", (long) entry->d_un.d_val);
2763 }
2764 }
2765 else
2766 printf ("%#lx\n", (long) entry->d_un.d_val);
2767 }
2768 break;
2769
2770 case DT_PLTRELSZ:
2771 case DT_RELASZ :
2772 case DT_STRSZ :
2773 case DT_RELSZ :
2774 case DT_RELAENT :
2775 case DT_SYMENT :
2776 case DT_RELENT :
2777 case DT_PLTPADSZ:
2778 case DT_MOVEENT :
2779 case DT_MOVESZ :
2780 case DT_INIT_ARRAYSZ:
2781 case DT_FINI_ARRAYSZ:
2782 if (do_dynamic)
2783 printf ("%lu (bytes)\n", (unsigned long) entry->d_un.d_val);
2784 break;
2785
2786 case DT_VERDEFNUM:
2787 case DT_VERNEEDNUM:
2788 case DT_RELACOUNT:
2789 case DT_RELCOUNT:
2790 if (do_dynamic)
2791 printf ("%lu\n", (unsigned long) entry->d_un.d_val);
2792 break;
2793
2794 case DT_SYMINSZ:
2795 case DT_SYMINENT:
2796 case DT_SYMINFO:
2797 case DT_USED:
2798 case DT_INIT_ARRAY:
2799 case DT_FINI_ARRAY:
2800 if (do_dynamic)
2801 {
2802 if (dynamic_strings != NULL && entry->d_tag == DT_USED)
2803 {
2804 char * name;
2805
2806 name = dynamic_strings + entry->d_un.d_val;
2807
2808 if (* name)
2809 {
2810 printf (_("Not needed object: [%s]\n"), name);
2811 break;
2812 }
2813 }
2814
2815 printf ("%#lx\n", (long) entry->d_un.d_val);
2816 }
2817 break;
2818
2819 case DT_BIND_NOW:
2820 /* The value of this entry is ignored. */
2821 break;
2822
2823 default:
2824 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
2825 version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
2826 entry->d_un.d_val;
2827
2828 if (do_dynamic)
2829 {
2830 switch (elf_header.e_machine)
2831 {
2832 case EM_MIPS:
2833 case EM_MIPS_RS4_BE:
2834 dynamic_segment_mips_val (entry);
2835 break;
2836 default:
2837 printf ("%#lx\n", (long) entry->d_un.d_ptr);
2838 }
2839 }
2840 break;
2841 }
2842 }
2843
2844 return 1;
2845}
2846
2847static char *
2848get_ver_flags (flags)
2849 unsigned int flags;
2850{
2851 static char buff [32];
2852
2853 buff[0] = 0;
2854
2855 if (flags == 0)
2856 return _("none");
2857
2858 if (flags & VER_FLG_BASE)
2859 strcat (buff, "BASE ");
2860
2861 if (flags & VER_FLG_WEAK)
2862 {
2863 if (flags & VER_FLG_BASE)
2864 strcat (buff, "| ");
2865
2866 strcat (buff, "WEAK ");
2867 }
2868
2869 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
2870 strcat (buff, "| <unknown>");
2871
2872 return buff;
2873}
2874
2875/* Display the contents of the version sections. */
2876static int
2877process_version_sections (file)
2878 FILE * file;
2879{
2880 Elf32_Internal_Shdr * section;
2881 unsigned i;
2882 int found = 0;
2883
2884 if (! do_version)
2885 return 1;
2886
2887 for (i = 0, section = section_headers;
2888 i < elf_header.e_shnum;
2889 i++, section ++)
2890 {
2891 switch (section->sh_type)
2892 {
2893 case SHT_GNU_verdef:
2894 {
2895 Elf_External_Verdef * edefs;
2896 unsigned int idx;
2897 unsigned int cnt;
2898
2899 found = 1;
2900
2901 printf
2902 (_("\nVersion definition section '%s' contains %ld entries:\n"),
2903 SECTION_NAME (section), section->sh_info);
2904
2905 printf (_(" Addr: 0x"));
2906 printf_vma (section->sh_addr);
2907 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 2908 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
2909 SECTION_NAME (section_headers + section->sh_link));
2910
2911 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2912 edefs, Elf_External_Verdef *,
2913 "version definition section");
2914
2915 for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
2916 {
2917 char * vstart;
2918 Elf_External_Verdef * edef;
2919 Elf_Internal_Verdef ent;
2920 Elf_External_Verdaux * eaux;
2921 Elf_Internal_Verdaux aux;
2922 int j;
2923 int isum;
2924
2925 vstart = ((char *) edefs) + idx;
2926
2927 edef = (Elf_External_Verdef *) vstart;
2928
2929 ent.vd_version = BYTE_GET (edef->vd_version);
2930 ent.vd_flags = BYTE_GET (edef->vd_flags);
2931 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
2932 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
2933 ent.vd_hash = BYTE_GET (edef->vd_hash);
2934 ent.vd_aux = BYTE_GET (edef->vd_aux);
2935 ent.vd_next = BYTE_GET (edef->vd_next);
2936
2937 printf (_(" %#06x: Rev: %d Flags: %s"),
2938 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
2939
2940 printf (_(" Index: %d Cnt: %d "),
2941 ent.vd_ndx, ent.vd_cnt);
2942
2943 vstart += ent.vd_aux;
2944
2945 eaux = (Elf_External_Verdaux *) vstart;
2946
2947 aux.vda_name = BYTE_GET (eaux->vda_name);
2948 aux.vda_next = BYTE_GET (eaux->vda_next);
2949
2950 if (dynamic_strings)
2951 printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
2952 else
2953 printf (_("Name index: %ld\n"), aux.vda_name);
2954
2955 isum = idx + ent.vd_aux;
2956
2957 for (j = 1; j < ent.vd_cnt; j ++)
2958 {
2959 isum += aux.vda_next;
2960 vstart += aux.vda_next;
2961
2962 eaux = (Elf_External_Verdaux *) vstart;
2963
2964 aux.vda_name = BYTE_GET (eaux->vda_name);
2965 aux.vda_next = BYTE_GET (eaux->vda_next);
2966
2967 if (dynamic_strings)
2968 printf (_(" %#06x: Parent %d: %s\n"),
2969 isum, j, dynamic_strings + aux.vda_name);
2970 else
2971 printf (_(" %#06x: Parent %d, name index: %ld\n"),
2972 isum, j, aux.vda_name);
2973 }
2974
2975 idx += ent.vd_next;
2976 }
2977
2978 free (edefs);
2979 }
2980 break;
2981
2982 case SHT_GNU_verneed:
2983 {
2984 Elf_External_Verneed * eneed;
2985 unsigned int idx;
2986 unsigned int cnt;
2987
2988 found = 1;
2989
2990 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
2991 SECTION_NAME (section), section->sh_info);
2992
2993 printf (_(" Addr: 0x"));
2994 printf_vma (section->sh_addr);
2995 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
1b228002 2996 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
2997 SECTION_NAME (section_headers + section->sh_link));
2998
2999 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
3000 eneed, Elf_External_Verneed *,
3001 "version need section");
3002
3003 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
3004 {
3005 Elf_External_Verneed * entry;
3006 Elf_Internal_Verneed ent;
3007 int j;
3008 int isum;
3009 char * vstart;
3010
3011 vstart = ((char *) eneed) + idx;
3012
3013 entry = (Elf_External_Verneed *) vstart;
3014
3015 ent.vn_version = BYTE_GET (entry->vn_version);
3016 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
3017 ent.vn_file = BYTE_GET (entry->vn_file);
3018 ent.vn_aux = BYTE_GET (entry->vn_aux);
3019 ent.vn_next = BYTE_GET (entry->vn_next);
3020
3021 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
3022
3023 if (dynamic_strings)
3024 printf (_(" File: %s"), dynamic_strings + ent.vn_file);
3025 else
3026 printf (_(" File: %lx"), ent.vn_file);
3027
3028 printf (_(" Cnt: %d\n"), ent.vn_cnt);
3029
3030 vstart += ent.vn_aux;
3031
3032 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
3033 {
3034 Elf_External_Vernaux * eaux;
3035 Elf_Internal_Vernaux aux;
3036
3037 eaux = (Elf_External_Vernaux *) vstart;
3038
3039 aux.vna_hash = BYTE_GET (eaux->vna_hash);
3040 aux.vna_flags = BYTE_GET (eaux->vna_flags);
3041 aux.vna_other = BYTE_GET (eaux->vna_other);
3042 aux.vna_name = BYTE_GET (eaux->vna_name);
3043 aux.vna_next = BYTE_GET (eaux->vna_next);
3044
3045 if (dynamic_strings)
3046 printf (_(" %#06x: Name: %s"),
3047 isum, dynamic_strings + aux.vna_name);
3048 else
3049 printf (_(" %#06x: Name index: %lx"),
3050 isum, aux.vna_name);
3051
3052 printf (_(" Flags: %s Version: %d\n"),
3053 get_ver_flags (aux.vna_flags), aux.vna_other);
3054
3055 isum += aux.vna_next;
3056 vstart += aux.vna_next;
3057 }
3058
3059 idx += ent.vn_next;
3060 }
3061
3062 free (eneed);
3063 }
3064 break;
3065
3066 case SHT_GNU_versym:
3067 {
3068 Elf32_Internal_Shdr * link_section;
3069 int total;
3070 int cnt;
3071 unsigned char * edata;
3072 unsigned short * data;
3073 char * strtab;
3074 Elf_Internal_Sym * symbols;
3075 Elf32_Internal_Shdr * string_sec;
3076
3077 link_section = section_headers + section->sh_link;
3078 total = section->sh_size / section->sh_entsize;
3079
3080 found = 1;
3081
9ea033b2
NC
3082 symbols = GET_ELF_SYMBOLS (file, link_section->sh_offset,
3083 link_section->sh_size / link_section->sh_entsize);
252b5132
RH
3084
3085 string_sec = section_headers + link_section->sh_link;
3086
3087 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
3088 strtab, char *, "version string table");
3089
3090 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
3091 SECTION_NAME (section), total);
3092
3093 printf (_(" Addr: "));
3094 printf_vma (section->sh_addr);
3095 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 3096 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
3097 SECTION_NAME (link_section));
3098
3099 GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
3100 - loadaddr,
3101 total * sizeof (short), edata,
3102 unsigned char *, "version symbol data");
3103
3104 data = (unsigned short *) malloc (total * sizeof (short));
3105
3106 for (cnt = total; cnt --;)
3107 data [cnt] = byte_get (edata + cnt * sizeof (short),
3108 sizeof (short));
3109
3110 free (edata);
3111
3112 for (cnt = 0; cnt < total; cnt += 4)
3113 {
3114 int j, nn;
3115
3116 printf (" %03x:", cnt);
3117
3118 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
3119 switch (data [cnt + j])
3120 {
3121 case 0:
3122 fputs (_(" 0 (*local*) "), stdout);
3123 break;
3124
3125 case 1:
3126 fputs (_(" 1 (*global*) "), stdout);
3127 break;
3128
3129 default:
3130 nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
3131 data [cnt + j] & 0x8000 ? 'h' : ' ');
3132
3133 if (symbols [cnt + j].st_shndx < SHN_LORESERVE
3134 && section_headers[symbols [cnt + j].st_shndx].sh_type
3135 == SHT_NOBITS)
3136 {
3137 /* We must test both. */
3138 Elf_Internal_Verneed ivn;
3139 unsigned long offset;
3140
3141 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
3142 - loadaddr;
3143
3144 do
3145 {
3146 Elf_External_Verneed evn;
3147 Elf_External_Vernaux evna;
3148 Elf_Internal_Vernaux ivna;
3149 unsigned long vna_off;
3150
3151 GET_DATA (offset, evn, "version need");
3152
3153 ivn.vn_aux = BYTE_GET (evn.vn_aux);
3154 ivn.vn_next = BYTE_GET (evn.vn_next);
3155
3156 vna_off = offset + ivn.vn_aux;
3157
3158 do
3159 {
3160 GET_DATA (vna_off, evna,
3161 "version need aux (1)");
3162
3163 ivna.vna_next = BYTE_GET (evna.vna_next);
3164 ivna.vna_other = BYTE_GET (evna.vna_other);
3165
3166 vna_off += ivna.vna_next;
3167 }
3168 while (ivna.vna_other != data [cnt + j]
3169 && ivna.vna_next != 0);
3170
3171 if (ivna.vna_other == data [cnt + j])
3172 {
3173 ivna.vna_name = BYTE_GET (evna.vna_name);
3174
3175 nn += printf ("(%s%-*s",
3176 strtab + ivna.vna_name,
3177 12 - strlen (strtab
3178 + ivna.vna_name),
3179 ")");
3180 break;
3181 }
3182 else if (ivn.vn_next == 0)
3183 {
3184 if (data [cnt + j] != 0x8001)
3185 {
3186 Elf_Internal_Verdef ivd;
3187 Elf_External_Verdef evd;
3188
3189 offset = version_info
3190 [DT_VERSIONTAGIDX (DT_VERDEF)]
3191 - loadaddr;
3192
3193 do
3194 {
3195 GET_DATA (offset, evd,
3196 "version definition");
3197
3198 ivd.vd_next = BYTE_GET (evd.vd_next);
3199 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
3200
3201 offset += ivd.vd_next;
3202 }
3203 while (ivd.vd_ndx
3204 != (data [cnt + j] & 0x7fff)
3205 && ivd.vd_next != 0);
3206
3207 if (ivd.vd_ndx
3208 == (data [cnt + j] & 0x7fff))
3209 {
3210 Elf_External_Verdaux evda;
3211 Elf_Internal_Verdaux ivda;
3212
3213 ivd.vd_aux = BYTE_GET (evd.vd_aux);
3214
3215 GET_DATA (offset + ivd.vd_aux, evda,
3216 "version definition aux");
3217
3218 ivda.vda_name =
3219 BYTE_GET (evda.vda_name);
3220
3221 nn +=
3222 printf ("(%s%-*s",
3223 strtab + ivda.vda_name,
3224 12
3225 - strlen (strtab
3226 + ivda.vda_name),
3227 ")");
3228 }
3229 }
3230
3231 break;
3232 }
3233 else
3234 offset += ivn.vn_next;
3235 }
3236 while (ivn.vn_next);
3237 }
3238 else if (symbols [cnt + j].st_shndx == SHN_UNDEF)
3239 {
3240 Elf_Internal_Verneed ivn;
3241 unsigned long offset;
3242
3243 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
3244 - loadaddr;
3245
3246 do
3247 {
3248 Elf_Internal_Vernaux ivna;
3249 Elf_External_Verneed evn;
3250 Elf_External_Vernaux evna;
3251 unsigned long a_off;
3252
3253 GET_DATA (offset, evn, "version need");
3254
3255 ivn.vn_aux = BYTE_GET (evn.vn_aux);
3256 ivn.vn_next = BYTE_GET (evn.vn_next);
3257
3258 a_off = offset + ivn.vn_aux;
3259
3260 do
3261 {
3262 GET_DATA (a_off, evna,
3263 "version need aux (2)");
3264
3265 ivna.vna_next = BYTE_GET (evna.vna_next);
3266 ivna.vna_other = BYTE_GET (evna.vna_other);
3267
3268 a_off += ivna.vna_next;
3269 }
3270 while (ivna.vna_other != data [cnt + j]
3271 && ivna.vna_next != 0);
3272
3273 if (ivna.vna_other == data [cnt + j])
3274 {
3275 ivna.vna_name = BYTE_GET (evna.vna_name);
3276
3277 nn += printf ("(%s%-*s",
3278 strtab + ivna.vna_name,
3279 12 - strlen (strtab
3280 + ivna.vna_name),
3281 ")");
3282 break;
3283 }
3284
3285 offset += ivn.vn_next;
3286 }
3287 while (ivn.vn_next);
3288 }
3289 else if (data [cnt + j] != 0x8001)
3290 {
3291 Elf_Internal_Verdef ivd;
3292 Elf_External_Verdef evd;
3293 unsigned long offset;
3294
3295 offset = version_info
3296 [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
3297
3298 do
3299 {
3300 GET_DATA (offset, evd, "version def");
3301
3302 ivd.vd_next = BYTE_GET (evd.vd_next);
3303 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
3304
3305 offset += ivd.vd_next;
3306 }
3307 while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
3308 && ivd.vd_next != 0);
3309
3310 if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
3311 {
3312 Elf_External_Verdaux evda;
3313 Elf_Internal_Verdaux ivda;
3314
3315 ivd.vd_aux = BYTE_GET (evd.vd_aux);
3316
3317 GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
3318 evda, "version def aux");
3319
3320 ivda.vda_name = BYTE_GET (evda.vda_name);
3321
3322 nn += printf ("(%s%-*s",
3323 strtab + ivda.vda_name,
3324 12 - strlen (strtab
3325 + ivda.vda_name),
3326 ")");
3327 }
3328 }
3329
3330 if (nn < 18)
3331 printf ("%*c", 18 - nn, ' ');
3332 }
3333
3334 putchar ('\n');
3335 }
3336
3337 free (data);
3338 free (strtab);
3339 free (symbols);
3340 }
3341 break;
3342
3343 default:
3344 break;
3345 }
3346 }
3347
3348 if (! found)
3349 printf (_("\nNo version information found in this file.\n"));
3350
3351 return 1;
3352}
3353
3354static char *
3355get_symbol_binding (binding)
3356 unsigned int binding;
3357{
3358 static char buff [32];
3359
3360 switch (binding)
3361 {
3362 case STB_LOCAL: return _("LOCAL");
3363 case STB_GLOBAL: return _("GLOBAL");
3364 case STB_WEAK: return _("WEAK");
3365 default:
3366 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
3367 sprintf (buff, _("<processor specific>: %d"), binding);
3368 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3369 sprintf (buff, _("<OS specific>: %d"), binding);
3370 else
3371 sprintf (buff, _("<unknown>: %d"), binding);
3372 return buff;
3373 }
3374}
3375
3376static char *
3377get_symbol_type (type)
3378 unsigned int type;
3379{
3380 static char buff [32];
3381
3382 switch (type)
3383 {
3384 case STT_NOTYPE: return _("NOTYPE");
3385 case STT_OBJECT: return _("OBJECT");
3386 case STT_FUNC: return _("FUNC");
3387 case STT_SECTION: return _("SECTION");
3388 case STT_FILE: return _("FILE");
3389 default:
3390 if (type >= STT_LOPROC && type <= STT_HIPROC)
3391 sprintf (buff, _("<processor specific>: %d"), type);
3392 else if (type >= STT_LOOS && type <= STT_HIOS)
3393 sprintf (buff, _("<OS specific>: %d"), type);
3394 else
3395 sprintf (buff, _("<unknown>: %d"), type);
3396 return buff;
3397 }
3398}
3399
3400static char *
3401get_symbol_index_type (type)
3402 unsigned int type;
3403{
3404 switch (type)
3405 {
3406 case SHN_UNDEF: return "UND";
3407 case SHN_ABS: return "ABS";
3408 case SHN_COMMON: return "COM";
3409 default:
3410 if (type >= SHN_LOPROC && type <= SHN_HIPROC)
3411 return "PRC";
3412 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
3413 return "RSV";
3414 else if (type >= SHN_LOOS && type <= SHN_HIOS)
3415 return "OS ";
3416 else
3417 {
3418 static char buff [32];
3419
3420 sprintf (buff, "%3d", type);
3421 return buff;
3422 }
3423 }
3424}
3425
3426
3427static int *
3428get_dynamic_data (file, number)
3429 FILE * file;
3430 unsigned int number;
3431{
3432 char * e_data;
3433 int * i_data;
3434
3435 e_data = (char *) malloc (number * 4);
3436
3437 if (e_data == NULL)
3438 {
3439 error (_("Out of memory\n"));
3440 return NULL;
3441 }
3442
3443 if (fread (e_data, 4, number, file) != number)
3444 {
3445 error (_("Unable to read in dynamic data\n"));
3446 return NULL;
3447 }
3448
3449 i_data = (int *) malloc (number * sizeof (* i_data));
3450
3451 if (i_data == NULL)
3452 {
3453 error (_("Out of memory\n"));
3454 free (e_data);
3455 return NULL;
3456 }
3457
3458 while (number--)
3459 i_data [number] = byte_get (e_data + number * 4, 4);
3460
3461 free (e_data);
3462
3463 return i_data;
3464}
3465
3466/* Dump the symbol table */
3467static int
3468process_symbol_table (file)
3469 FILE * file;
3470{
3471 Elf32_Internal_Shdr * section;
3472 char nb [4];
3473 char nc [4];
3474 int nbuckets;
3475 int nchains;
3476 int * buckets = NULL;
3477 int * chains = NULL;
3478
3479 if (! do_syms && !do_histogram)
3480 return 1;
3481
3482 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
3483 || do_histogram))
3484 {
3485 if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
3486 {
3487 error (_("Unable to seek to start of dynamic information"));
3488 return 0;
3489 }
3490
3491 if (fread (nb, sizeof (nb), 1, file) != 1)
3492 {
3493 error (_("Failed to read in number of buckets\n"));
3494 return 0;
3495 }
3496
3497 if (fread (nc, sizeof (nc), 1, file) != 1)
3498 {
3499 error (_("Failed to read in number of chains\n"));
3500 return 0;
3501 }
3502
3503 nbuckets = byte_get (nb, 4);
3504 nchains = byte_get (nc, 4);
3505
3506 buckets = get_dynamic_data (file, nbuckets);
3507 chains = get_dynamic_data (file, nchains);
3508
3509 if (buckets == NULL || chains == NULL)
3510 return 0;
3511 }
3512
3513 if (do_syms
3514 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
3515 {
3516 int hn;
3517 int si;
3518
3519 printf (_("\nSymbol table for image:\n"));
3520 printf (_(" Num Buc: Value Size Type Bind Ot Ndx Name\n"));
3521
3522 for (hn = 0; hn < nbuckets; hn++)
3523 {
3524 if (! buckets [hn])
3525 continue;
3526
3527 for (si = buckets [hn]; si; si = chains [si])
3528 {
3529 Elf_Internal_Sym * psym;
3530
3531 psym = dynamic_symbols + si;
3532
3533 printf (" %3d %3d: %8lx %5ld %6s %6s %2d ",
3534 si, hn,
3535 (unsigned long) psym->st_value,
3536 (unsigned long) psym->st_size,
3537 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3538 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3539 psym->st_other);
3540
3541 printf ("%3.3s", get_symbol_index_type (psym->st_shndx));
3542
3543 printf (" %s\n", dynamic_strings + psym->st_name);
3544 }
3545 }
3546 }
3547 else if (do_syms && !do_using_dynamic)
3548 {
3549 unsigned int i;
3550
3551 for (i = 0, section = section_headers;
3552 i < elf_header.e_shnum;
3553 i++, section++)
3554 {
3555 unsigned int si;
3556 char * strtab;
3557 Elf_Internal_Sym * symtab;
3558 Elf_Internal_Sym * psym;
3559
3560
3561 if ( section->sh_type != SHT_SYMTAB
3562 && section->sh_type != SHT_DYNSYM)
3563 continue;
3564
3565 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
3566 SECTION_NAME (section),
3567 (unsigned long) (section->sh_size / section->sh_entsize));
3568 fputs (_(" Num: Value Size Type Bind Ot Ndx Name\n"),
3569 stdout);
3570
9ea033b2 3571 symtab = GET_ELF_SYMBOLS (file, section->sh_offset,
252b5132
RH
3572 section->sh_size / section->sh_entsize);
3573 if (symtab == NULL)
3574 continue;
3575
3576 if (section->sh_link == elf_header.e_shstrndx)
3577 strtab = string_table;
3578 else
3579 {
3580 Elf32_Internal_Shdr * string_sec;
3581
3582 string_sec = section_headers + section->sh_link;
3583
3584 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
3585 strtab, char *, "string table");
3586 }
3587
3588 for (si = 0, psym = symtab;
3589 si < section->sh_size / section->sh_entsize;
3590 si ++, psym ++)
3591 {
3592 printf (" %3d: %8lx %5ld %-7s %-6s %2d ",
3593 si,
3594 (unsigned long) psym->st_value,
3595 (unsigned long) psym->st_size,
3596 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3597 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3598 psym->st_other);
3599
1b228002 3600 printf ("%4s", get_symbol_index_type (psym->st_shndx));
252b5132
RH
3601
3602 printf (" %s", strtab + psym->st_name);
3603
3604 if (section->sh_type == SHT_DYNSYM &&
3605 version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
3606 {
3607 unsigned char data[2];
3608 unsigned short vers_data;
3609 unsigned long offset;
3610 int is_nobits;
3611 int check_def;
3612
3613 offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
3614 - loadaddr;
3615
3616 GET_DATA (offset + si * sizeof (vers_data), data,
3617 "version data");
3618
3619 vers_data = byte_get (data, 2);
3620
3621 is_nobits = psym->st_shndx < SHN_LORESERVE ?
3622 (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
3623 : 0;
3624
3625 check_def = (psym->st_shndx != SHN_UNDEF);
3626
3627 if ((vers_data & 0x8000) || vers_data > 1)
3628 {
3629 if (is_nobits || ! check_def)
3630 {
3631 Elf_External_Verneed evn;
3632 Elf_Internal_Verneed ivn;
3633 Elf_Internal_Vernaux ivna;
3634
3635 /* We must test both. */
3636 offset = version_info
3637 [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
3638
3639 GET_DATA (offset, evn, "version need");
3640
3641 ivn.vn_aux = BYTE_GET (evn.vn_aux);
3642 ivn.vn_next = BYTE_GET (evn.vn_next);
3643
3644 do
3645 {
3646 unsigned long vna_off;
3647
3648 vna_off = offset + ivn.vn_aux;
3649
3650 do
3651 {
3652 Elf_External_Vernaux evna;
3653
3654 GET_DATA (vna_off, evna,
3655 "version need aux (3)");
3656
3657 ivna.vna_other = BYTE_GET (evna.vna_other);
3658 ivna.vna_next = BYTE_GET (evna.vna_next);
3659 ivna.vna_name = BYTE_GET (evna.vna_name);
3660
3661 vna_off += ivna.vna_next;
3662 }
3663 while (ivna.vna_other != vers_data
3664 && ivna.vna_next != 0);
3665
3666 if (ivna.vna_other == vers_data)
3667 break;
3668
3669 offset += ivn.vn_next;
3670 }
3671 while (ivn.vn_next != 0);
3672
3673 if (ivna.vna_other == vers_data)
3674 {
3675 printf ("@%s (%d)",
3676 strtab + ivna.vna_name, ivna.vna_other);
3677 check_def = 0;
3678 }
3679 else if (! is_nobits)
3680 error (_("bad dynamic symbol"));
3681 else
3682 check_def = 1;
3683 }
3684
3685 if (check_def)
3686 {
3687 if (vers_data != 0x8001)
3688 {
3689 Elf_Internal_Verdef ivd;
3690 Elf_Internal_Verdaux ivda;
3691 Elf_External_Verdaux evda;
3692 unsigned long offset;
3693
3694 offset =
3695 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
3696 - loadaddr;
3697
3698 do
3699 {
3700 Elf_External_Verdef evd;
3701
3702 GET_DATA (offset, evd, "version def");
3703
3704 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
3705 ivd.vd_aux = BYTE_GET (evd.vd_aux);
3706 ivd.vd_next = BYTE_GET (evd.vd_next);
3707
3708 offset += ivd.vd_next;
3709 }
3710 while (ivd.vd_ndx != (vers_data & 0x7fff)
3711 && ivd.vd_next != 0);
3712
3713 offset -= ivd.vd_next;
3714 offset += ivd.vd_aux;
3715
3716 GET_DATA (offset, evda, "version def aux");
3717
3718 ivda.vda_name = BYTE_GET (evda.vda_name);
3719
3720 if (psym->st_name != ivda.vda_name)
3721 printf ((vers_data & 0x8000)
3722 ? "@%s" : "@@%s",
3723 strtab + ivda.vda_name);
3724 }
3725 }
3726 }
3727 }
3728
3729 putchar ('\n');
3730 }
3731
3732 free (symtab);
3733 if (strtab != string_table)
3734 free (strtab);
3735 }
3736 }
3737 else if (do_syms)
3738 printf
3739 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
3740
3741 if (do_histogram && buckets != NULL)
3742 {
3743 int *lengths;
3744 int *counts;
3745 int hn;
3746 int si;
3747 int maxlength = 0;
3748 int nzero_counts = 0;
3749 int nsyms = 0;
3750
3751 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
3752 nbuckets);
3753 printf (_(" Length Number %% of total Coverage\n"));
3754
3755 lengths = (int *) calloc (nbuckets, sizeof (int));
3756 if (lengths == NULL)
3757 {
3758 error (_("Out of memory"));
3759 return 0;
3760 }
3761 for (hn = 0; hn < nbuckets; ++hn)
3762 {
3763 if (! buckets [hn])
3764 continue;
3765
3766 for (si = buckets[hn]; si; si = chains[si])
3767 {
3768 ++nsyms;
3769 if (maxlength < ++lengths[hn])
3770 ++maxlength;
3771 }
3772 }
3773
3774 counts = (int *) calloc (maxlength + 1, sizeof (int));
3775 if (counts == NULL)
3776 {
3777 error (_("Out of memory"));
3778 return 0;
3779 }
3780
3781 for (hn = 0; hn < nbuckets; ++hn)
3782 ++ counts [lengths [hn]];
3783
3784 printf (" 0 %-10d (%5.1f%%)\n",
3785 counts[0], (counts[0] * 100.0) / nbuckets);
3786 for (si = 1; si <= maxlength; ++si)
3787 {
3788 nzero_counts += counts[si] * si;
3789 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
3790 si, counts[si], (counts[si] * 100.0) / nbuckets,
3791 (nzero_counts * 100.0) / nsyms);
3792 }
3793
3794 free (counts);
3795 free (lengths);
3796 }
3797
3798 if (buckets != NULL)
3799 {
3800 free (buckets);
3801 free (chains);
3802 }
3803
3804 return 1;
3805}
3806
3807static int
3808process_syminfo (file)
3809 FILE * file;
3810{
3811 int i;
3812
3813 if (dynamic_syminfo == NULL
3814 || !do_dynamic)
3815 /* No syminfo, this is ok. */
3816 return 1;
3817
3818 /* There better should be a dynamic symbol section. */
3819 if (dynamic_symbols == NULL || dynamic_strings == NULL)
3820 return 0;
3821
3822 if (dynamic_addr)
3823 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
3824 dynamic_syminfo_offset, dynamic_syminfo_nent);
3825
3826 printf (_(" Num: Name BoundTo Flags\n"));
3827 for (i = 0; i < dynamic_syminfo_nent; ++i)
3828 {
3829 unsigned short int flags = dynamic_syminfo[i].si_flags;
3830
3831 printf ("%4d: %-30s ", i,
3832 dynamic_strings + dynamic_symbols[i].st_name);
3833
3834 switch (dynamic_syminfo[i].si_boundto)
3835 {
3836 case SYMINFO_BT_SELF:
3837 fputs ("SELF ", stdout);
3838 break;
3839 case SYMINFO_BT_PARENT:
3840 fputs ("PARENT ", stdout);
3841 break;
3842 default:
3843 if (dynamic_syminfo[i].si_boundto > 0
3844 && dynamic_syminfo[i].si_boundto < dynamic_size)
3845 printf ("%-10s ",
3846 dynamic_strings
3847 + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
3848 else
3849 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
3850 break;
3851 }
3852
3853 if (flags & SYMINFO_FLG_DIRECT)
3854 printf (" DIRECT");
3855 if (flags & SYMINFO_FLG_PASSTHRU)
3856 printf (" PASSTHRU");
3857 if (flags & SYMINFO_FLG_COPY)
3858 printf (" COPY");
3859 if (flags & SYMINFO_FLG_LAZYLOAD)
3860 printf (" LAZYLOAD");
3861
3862 puts ("");
3863 }
3864
3865 return 1;
3866}
3867
3868#ifdef SUPPORT_DISASSEMBLY
3869static void
3870disassemble_section (section, file)
3871 Elf32_Internal_Shdr * section;
3872 FILE * file;
3873{
3874 printf (_("\nAssembly dump of section %s\n"),
3875 SECTION_NAME (section));
3876
3877 /* XXX -- to be done --- XXX */
3878
3879 return 1;
3880}
3881#endif
3882
3883static int
3884dump_section (section, file)
3885 Elf32_Internal_Shdr * section;
3886 FILE * file;
3887{
9ea033b2
NC
3888 bfd_size_type bytes;
3889 bfd_vma addr;
252b5132
RH
3890 unsigned char * data;
3891 unsigned char * start;
3892
3893 bytes = section->sh_size;
3894
3895 if (bytes == 0)
3896 {
3897 printf (_("\nSection '%s' has no data to dump.\n"),
3898 SECTION_NAME (section));
3899 return 0;
3900 }
3901 else
3902 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
3903
3904 addr = section->sh_addr;
3905
3906 GET_DATA_ALLOC (section->sh_offset, bytes, start, unsigned char *,
3907 "section data");
3908
3909 data = start;
3910
3911 while (bytes)
3912 {
3913 int j;
3914 int k;
3915 int lbytes;
3916
3917 lbytes = (bytes > 16 ? 16 : bytes);
3918
148d3c43 3919 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132
RH
3920
3921 switch (elf_header.e_ident [EI_DATA])
3922 {
9ea033b2 3923 default:
252b5132
RH
3924 case ELFDATA2LSB:
3925 for (j = 15; j >= 0; j --)
3926 {
3927 if (j < lbytes)
3928 printf ("%2.2x", data [j]);
3929 else
3930 printf (" ");
3931
3932 if (!(j & 0x3))
3933 printf (" ");
3934 }
3935 break;
3936
3937 case ELFDATA2MSB:
3938 for (j = 0; j < 16; j++)
3939 {
3940 if (j < lbytes)
3941 printf ("%2.2x", data [j]);
3942 else
3943 printf (" ");
3944
3945 if ((j & 3) == 3)
3946 printf (" ");
3947 }
3948 break;
3949 }
3950
3951 for (j = 0; j < lbytes; j++)
3952 {
3953 k = data [j];
3954 if (k >= ' ' && k < 0x80)
3955 printf ("%c", k);
3956 else
3957 printf (".");
3958 }
3959
3960 putchar ('\n');
3961
3962 data += lbytes;
3963 addr += lbytes;
3964 bytes -= lbytes;
3965 }
3966
3967 free (start);
3968
3969 return 1;
3970}
3971
3972
3973static unsigned long int
3974read_leb128 (data, length_return, sign)
3975 unsigned char * data;
3976 int * length_return;
3977 int sign;
3978{
3979 unsigned long int result = 0;
3980 unsigned int num_read = 0;
3981 int shift = 0;
3982 unsigned char byte;
3983
3984 do
3985 {
3986 byte = * data ++;
3987 num_read ++;
3988
3989 result |= (byte & 0x7f) << shift;
3990
3991 shift += 7;
3992
3993 }
3994 while (byte & 0x80);
3995
3996 if (length_return != NULL)
3997 * length_return = num_read;
3998
3999 if (sign && (shift < 32) && (byte & 0x40))
4000 result |= -1 << shift;
4001
4002 return result;
4003}
4004
4005typedef struct State_Machine_Registers
4006{
4007 unsigned long address;
4008 unsigned int file;
4009 unsigned int line;
4010 unsigned int column;
4011 int is_stmt;
4012 int basic_block;
4013 int end_sequence;
4014/* This variable hold the number of the last entry seen
4015 in the File Table. */
4016 unsigned int last_file_entry;
4017} SMR;
4018
4019static SMR state_machine_regs;
4020
4021static void
4022reset_state_machine (is_stmt)
4023 int is_stmt;
4024{
4025 state_machine_regs.address = 0;
4026 state_machine_regs.file = 1;
4027 state_machine_regs.line = 1;
4028 state_machine_regs.column = 0;
4029 state_machine_regs.is_stmt = is_stmt;
4030 state_machine_regs.basic_block = 0;
4031 state_machine_regs.end_sequence = 0;
4032 state_machine_regs.last_file_entry = 0;
4033}
4034
4035/* Handled an extend line op. Returns true if this is the end
4036 of sequence. */
4037static int
4038process_extended_line_op (data, is_stmt)
4039 unsigned char * data;
4040 int is_stmt;
4041{
4042 unsigned char op_code;
4043 int bytes_read;
4044 unsigned int len;
4045 unsigned char * name;
4046 unsigned long adr;
4047
4048 len = read_leb128 (data, & bytes_read, 0);
4049 data += bytes_read;
4050
4051 if (len == 0)
4052 {
4053 warn (_("badly formed extended line op encountered!"));
4054 return bytes_read;
4055 }
4056
4057 len += bytes_read;
4058 op_code = * data ++;
4059
4060 printf (_(" Extended opcode %d: "), op_code);
4061
4062 switch (op_code)
4063 {
4064 case DW_LNE_end_sequence:
4065 printf (_("End of Sequence\n\n"));
4066 reset_state_machine (is_stmt);
4067 break;
4068
4069 case DW_LNE_set_address:
4070 /* XXX - assumption here that address size is 4! */
4071 adr = byte_get (data, 4);
4072 printf (_("set Address to 0x%lx\n"), adr);
4073 state_machine_regs.address = adr;
4074 break;
4075
4076 case DW_LNE_define_file:
4077 printf (_(" define new File Table entry\n"));
4078 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
4079
4080 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
4081 name = data;
4082 data += strlen (data) + 1;
4083 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4084 data += bytes_read;
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 printf (_("%s\n\n"), name);
4089 break;
4090
4091 default:
4092 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
4093 break;
4094 }
4095
4096 return len;
4097}
4098
4099
4100static int
4101display_debug_lines (section, start, file)
4102 Elf32_Internal_Shdr * section;
4103 unsigned char * start;
4104 FILE * file;
4105{
4106 DWARF2_External_LineInfo * external;
4107 DWARF2_Internal_LineInfo info;
4108 unsigned char * standard_opcodes;
4109 unsigned char * data = start;
4110 unsigned char * end = start + section->sh_size;
4111 unsigned char * end_of_sequence;
4112 int i;
4113
4114 printf (_("\nDump of debug contents of section %s:\n\n"),
4115 SECTION_NAME (section));
4116
4117 while (data < end)
4118 {
4119 external = (DWARF2_External_LineInfo *) data;
4120
4121 /* Check the length of the block. */
4122 info.li_length = BYTE_GET (external->li_length);
4123 if (info.li_length > section->sh_size)
4124 {
4125 warn
4126 (_("The line info appears to be corrupt - the section is too small\n"));
4127 return 0;
4128 }
4129
4130 /* Check its version number. */
4131 info.li_version = BYTE_GET (external->li_version);
4132 if (info.li_version != 2)
4133 {
4134 warn (_("Only DWARF version 2 line info is currently supported.\n"));
4135 return 0;
4136 }
4137
4138 info.li_prologue_length = BYTE_GET (external->li_prologue_length);
4139 info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
4140 info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
4141 info.li_line_base = BYTE_GET (external->li_line_base);
4142 info.li_line_range = BYTE_GET (external->li_line_range);
4143 info.li_opcode_base = BYTE_GET (external->li_opcode_base);
4144
4145 /* Sign extend the line base field. */
4146 info.li_line_base <<= 24;
4147 info.li_line_base >>= 24;
4148
4149 printf (_(" Length: %ld\n"), info.li_length);
4150 printf (_(" DWARF Version: %d\n"), info.li_version);
4151 printf (_(" Prolgue Length: %d\n"), info.li_prologue_length);
4152 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
4153 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
4154 printf (_(" Line Base: %d\n"), info.li_line_base);
4155 printf (_(" Line Range: %d\n"), info.li_line_range);
4156 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
4157
4158 end_of_sequence = data + info.li_length + sizeof (info.li_length);
4159
4160 reset_state_machine (info.li_default_is_stmt);
4161
4162 /* Display the contents of the Opcodes table. */
4163 standard_opcodes = data + sizeof (* external);
4164
4165 printf (_("\n Opcodes:\n"));
4166
4167 for (i = 1; i < info.li_opcode_base; i++)
4168 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i]);
4169
4170 /* Display the contents of the Directory table. */
4171 data = standard_opcodes + info.li_opcode_base - 1;
4172
4173 if (* data == 0)
4174 printf (_("\n The Directory Table is empty.\n"));
4175 else
4176 {
4177 printf (_("\n The Directory Table:\n"));
4178
4179 while (* data != 0)
4180 {
4181 printf (_(" %s\n"), data);
4182
4183 data += strlen (data) + 1;
4184 }
4185 }
4186
4187 /* Skip the NUL at the end of the table. */
4188 data ++;
4189
4190 /* Display the contents of the File Name table. */
4191 if (* data == 0)
4192 printf (_("\n The File Name Table is empty.\n"));
4193 else
4194 {
4195 printf (_("\n The File Name Table:\n"));
4196 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
4197
4198 while (* data != 0)
4199 {
4200 char * name;
4201 int bytes_read;
4202
4203 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
4204 name = data;
4205
4206 data += strlen (data) + 1;
4207
4208 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4209 data += bytes_read;
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 (_("%s\n"), name);
4215 }
4216 }
4217
4218 /* Skip the NUL at the end of the table. */
4219 data ++;
4220
4221 /* Now display the statements. */
4222 printf (_("\n Line Number Statements:\n"));
4223
4224
4225 while (data < end_of_sequence)
4226 {
4227 unsigned char op_code;
4228 int adv;
4229 int bytes_read;
4230
4231 op_code = * data ++;
4232
4233 switch (op_code)
4234 {
4235 case DW_LNS_extended_op:
4236 data += process_extended_line_op (data, info.li_default_is_stmt);
4237 break;
4238
4239 case DW_LNS_copy:
4240 printf (_(" Copy\n"));
4241 break;
4242
4243 case DW_LNS_advance_pc:
4244 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
4245 data += bytes_read;
4246 state_machine_regs.address += adv;
4247 printf (_(" Advance PC by %d to %lx\n"), adv,
4248 state_machine_regs.address);
4249 break;
4250
4251 case DW_LNS_advance_line:
4252 adv = read_leb128 (data, & bytes_read, 1);
4253 data += bytes_read;
4254 state_machine_regs.line += adv;
4255 printf (_(" Advance Line by %d to %d\n"), adv,
4256 state_machine_regs.line);
4257 break;
4258
4259 case DW_LNS_set_file:
4260 adv = read_leb128 (data, & bytes_read, 0);
4261 data += bytes_read;
4262 printf (_(" Set File Name to entry %d in the File Name Table\n"),
4263 adv);
4264 state_machine_regs.file = adv;
4265 break;
4266
4267 case DW_LNS_set_column:
4268 adv = read_leb128 (data, & bytes_read, 0);
4269 data += bytes_read;
4270 printf (_(" Set column to %d\n"), adv);
4271 state_machine_regs.column = adv;
4272 break;
4273
4274 case DW_LNS_negate_stmt:
4275 adv = state_machine_regs.is_stmt;
4276 adv = ! adv;
4277 printf (_(" Set is_stmt to %d\n"), adv);
4278 state_machine_regs.is_stmt = adv;
4279 break;
4280
4281 case DW_LNS_set_basic_block:
4282 printf (_(" Set basic block\n"));
4283 state_machine_regs.basic_block = 1;
4284 break;
4285
4286 case DW_LNS_const_add_pc:
4287 adv = (255 - info.li_opcode_base) / info.li_line_range;
4288 state_machine_regs.address += adv;
4289 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
4290 state_machine_regs.address);
4291 break;
4292
4293 case DW_LNS_fixed_advance_pc:
4294 adv = byte_get (data, 2);
4295 data += 2;
4296 state_machine_regs.address += adv;
4297 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
4298 adv, state_machine_regs.address);
4299 break;
4300
4301 default:
4302 op_code -= info.li_opcode_base;
4303 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
4304 state_machine_regs.address += adv;
4305 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
4306 op_code, adv, state_machine_regs.address);
4307 adv += (op_code % info.li_line_range) + info.li_line_base;
4308 state_machine_regs.line += adv;
4309 printf (_(" and Line by %d to %d\n"),
4310 adv, state_machine_regs.line);
4311 break;
4312 }
4313 }
4314 printf ("\n");
4315 }
4316
4317 return 1;
4318}
4319
4320static int
4321display_debug_pubnames (section, start, file)
4322 Elf32_Internal_Shdr * section;
4323 unsigned char * start;
4324 FILE * file;
4325{
4326 DWARF2_External_PubNames * external;
4327 DWARF2_Internal_PubNames pubnames;
4328 unsigned char * end;
4329
4330 end = start + section->sh_size;
4331
4332 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
4333
4334 while (start < end)
4335 {
4336 unsigned char * data;
4337 unsigned long offset;
4338
4339 external = (DWARF2_External_PubNames *) start;
4340
4341 pubnames.pn_length = BYTE_GET (external->pn_length);
4342 pubnames.pn_version = BYTE_GET (external->pn_version);
4343 pubnames.pn_offset = BYTE_GET (external->pn_offset);
4344 pubnames.pn_size = BYTE_GET (external->pn_size);
4345
4346 data = start + sizeof (* external);
4347 start += pubnames.pn_length + sizeof (external->pn_length);
4348
4349 if (pubnames.pn_version != 2)
4350 {
4351 warn (_("Only DWARF 2 pubnames are currently supported"));
4352 continue;
4353 }
4354
4355 printf (_(" Length: %ld\n"),
4356 pubnames.pn_length);
4357 printf (_(" Version: %d\n"),
4358 pubnames.pn_version);
4359 printf (_(" Offset into .debug_info section: %ld\n"),
4360 pubnames.pn_offset);
4361 printf (_(" Size of area in .debug_info section: %ld\n"),
4362 pubnames.pn_size);
4363
4364 printf (_("\n Offset\tName\n"));
4365
4366 do
4367 {
4368 offset = byte_get (data, 4);
4369
4370 if (offset != 0)
4371 {
4372 data += 4;
4373 printf (" %ld\t\t%s\n", offset, data);
4374 data += strlen (data) + 1;
4375 }
4376 }
4377 while (offset != 0);
4378 }
4379
4380 printf ("\n");
4381 return 1;
4382}
4383
4384static char *
4385get_TAG_name (tag)
4386 unsigned long tag;
4387{
4388 switch (tag)
4389 {
4390 case DW_TAG_padding: return "DW_TAG_padding";
4391 case DW_TAG_array_type: return "DW_TAG_array_type";
4392 case DW_TAG_class_type: return "DW_TAG_class_type";
4393 case DW_TAG_entry_point: return "DW_TAG_entry_point";
4394 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
4395 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
4396 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
4397 case DW_TAG_label: return "DW_TAG_label";
4398 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
4399 case DW_TAG_member: return "DW_TAG_member";
4400 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
4401 case DW_TAG_reference_type: return "DW_TAG_reference_type";
4402 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
4403 case DW_TAG_string_type: return "DW_TAG_string_type";
4404 case DW_TAG_structure_type: return "DW_TAG_structure_type";
4405 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
4406 case DW_TAG_typedef: return "DW_TAG_typedef";
4407 case DW_TAG_union_type: return "DW_TAG_union_type";
4408 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
4409 case DW_TAG_variant: return "DW_TAG_variant";
4410 case DW_TAG_common_block: return "DW_TAG_common_block";
4411 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
4412 case DW_TAG_inheritance: return "DW_TAG_inheritance";
4413 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
4414 case DW_TAG_module: return "DW_TAG_module";
4415 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
4416 case DW_TAG_set_type: return "DW_TAG_set_type";
4417 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
4418 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
4419 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
4420 case DW_TAG_base_type: return "DW_TAG_base_type";
4421 case DW_TAG_catch_block: return "DW_TAG_catch_block";
4422 case DW_TAG_const_type: return "DW_TAG_const_type";
4423 case DW_TAG_constant: return "DW_TAG_constant";
4424 case DW_TAG_enumerator: return "DW_TAG_enumerator";
4425 case DW_TAG_file_type: return "DW_TAG_file_type";
4426 case DW_TAG_friend: return "DW_TAG_friend";
4427 case DW_TAG_namelist: return "DW_TAG_namelist";
4428 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
4429 case DW_TAG_packed_type: return "DW_TAG_packed_type";
4430 case DW_TAG_subprogram: return "DW_TAG_subprogram";
4431 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
4432 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
4433 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
4434 case DW_TAG_try_block: return "DW_TAG_try_block";
4435 case DW_TAG_variant_part: return "DW_TAG_variant_part";
4436 case DW_TAG_variable: return "DW_TAG_variable";
4437 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
4438 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
4439 case DW_TAG_format_label: return "DW_TAG_format_label";
4440 case DW_TAG_function_template: return "DW_TAG_function_template";
4441 case DW_TAG_class_template: return "DW_TAG_class_template";
4442 default:
4443 {
4444 static char buffer [100];
4445
4446 sprintf (buffer, _("Unknown TAG value: %lx"), tag);
4447 return buffer;
4448 }
4449 }
4450}
4451
4452static char *
4453get_AT_name (attribute)
4454 unsigned long attribute;
4455{
4456 switch (attribute)
4457 {
4458 case DW_AT_sibling: return "DW_AT_sibling";
4459 case DW_AT_location: return "DW_AT_location";
4460 case DW_AT_name: return "DW_AT_name";
4461 case DW_AT_ordering: return "DW_AT_ordering";
4462 case DW_AT_subscr_data: return "DW_AT_subscr_data";
4463 case DW_AT_byte_size: return "DW_AT_byte_size";
4464 case DW_AT_bit_offset: return "DW_AT_bit_offset";
4465 case DW_AT_bit_size: return "DW_AT_bit_size";
4466 case DW_AT_element_list: return "DW_AT_element_list";
4467 case DW_AT_stmt_list: return "DW_AT_stmt_list";
4468 case DW_AT_low_pc: return "DW_AT_low_pc";
4469 case DW_AT_high_pc: return "DW_AT_high_pc";
4470 case DW_AT_language: return "DW_AT_language";
4471 case DW_AT_member: return "DW_AT_member";
4472 case DW_AT_discr: return "DW_AT_discr";
4473 case DW_AT_discr_value: return "DW_AT_discr_value";
4474 case DW_AT_visibility: return "DW_AT_visibility";
4475 case DW_AT_import: return "DW_AT_import";
4476 case DW_AT_string_length: return "DW_AT_string_length";
4477 case DW_AT_common_reference: return "DW_AT_common_reference";
4478 case DW_AT_comp_dir: return "DW_AT_comp_dir";
4479 case DW_AT_const_value: return "DW_AT_const_value";
4480 case DW_AT_containing_type: return "DW_AT_containing_type";
4481 case DW_AT_default_value: return "DW_AT_default_value";
4482 case DW_AT_inline: return "DW_AT_inline";
4483 case DW_AT_is_optional: return "DW_AT_is_optional";
4484 case DW_AT_lower_bound: return "DW_AT_lower_bound";
4485 case DW_AT_producer: return "DW_AT_producer";
4486 case DW_AT_prototyped: return "DW_AT_prototyped";
4487 case DW_AT_return_addr: return "DW_AT_return_addr";
4488 case DW_AT_start_scope: return "DW_AT_start_scope";
4489 case DW_AT_stride_size: return "DW_AT_stride_size";
4490 case DW_AT_upper_bound: return "DW_AT_upper_bound";
4491 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
4492 case DW_AT_accessibility: return "DW_AT_accessibility";
4493 case DW_AT_address_class: return "DW_AT_address_class";
4494 case DW_AT_artificial: return "DW_AT_artificial";
4495 case DW_AT_base_types: return "DW_AT_base_types";
4496 case DW_AT_calling_convention: return "DW_AT_calling_convention";
4497 case DW_AT_count: return "DW_AT_count";
4498 case DW_AT_data_member_location: return "DW_AT_data_member_location";
4499 case DW_AT_decl_column: return "DW_AT_decl_column";
4500 case DW_AT_decl_file: return "DW_AT_decl_file";
4501 case DW_AT_decl_line: return "DW_AT_decl_line";
4502 case DW_AT_declaration: return "DW_AT_declaration";
4503 case DW_AT_discr_list: return "DW_AT_discr_list";
4504 case DW_AT_encoding: return "DW_AT_encoding";
4505 case DW_AT_external: return "DW_AT_external";
4506 case DW_AT_frame_base: return "DW_AT_frame_base";
4507 case DW_AT_friend: return "DW_AT_friend";
4508 case DW_AT_identifier_case: return "DW_AT_identifier_case";
4509 case DW_AT_macro_info: return "DW_AT_macro_info";
4510 case DW_AT_namelist_items: return "DW_AT_namelist_items";
4511 case DW_AT_priority: return "DW_AT_priority";
4512 case DW_AT_segment: return "DW_AT_segment";
4513 case DW_AT_specification: return "DW_AT_specification";
4514 case DW_AT_static_link: return "DW_AT_static_link";
4515 case DW_AT_type: return "DW_AT_type";
4516 case DW_AT_use_location: return "DW_AT_use_location";
4517 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
4518 case DW_AT_virtuality: return "DW_AT_virtuality";
4519 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
4520 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
4521 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
4522 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
4523 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
4524 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
4525 case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
4526 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
4527 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
4528 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
4529 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
4530 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
4531 case DW_AT_sf_names: return "DW_AT_sf_names";
4532 case DW_AT_src_info: return "DW_AT_src_info";
4533 case DW_AT_mac_info: return "DW_AT_mac_info";
4534 case DW_AT_src_coords: return "DW_AT_src_coords";
4535 case DW_AT_body_begin: return "DW_AT_body_begin";
4536 case DW_AT_body_end: return "DW_AT_body_end";
4537 default:
4538 {
4539 static char buffer [100];
4540
4541 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
4542 return buffer;
4543 }
4544 }
4545}
4546
4547static char *
4548get_FORM_name (form)
4549 unsigned long form;
4550{
4551 switch (form)
4552 {
4553 case DW_FORM_addr: return "DW_FORM_addr";
4554 case DW_FORM_block2: return "DW_FORM_block2";
4555 case DW_FORM_block4: return "DW_FORM_block4";
4556 case DW_FORM_data2: return "DW_FORM_data2";
4557 case DW_FORM_data4: return "DW_FORM_data4";
4558 case DW_FORM_data8: return "DW_FORM_data8";
4559 case DW_FORM_string: return "DW_FORM_string";
4560 case DW_FORM_block: return "DW_FORM_block";
4561 case DW_FORM_block1: return "DW_FORM_block1";
4562 case DW_FORM_data1: return "DW_FORM_data1";
4563 case DW_FORM_flag: return "DW_FORM_flag";
4564 case DW_FORM_sdata: return "DW_FORM_sdata";
4565 case DW_FORM_strp: return "DW_FORM_strp";
4566 case DW_FORM_udata: return "DW_FORM_udata";
4567 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
4568 case DW_FORM_ref1: return "DW_FORM_ref1";
4569 case DW_FORM_ref2: return "DW_FORM_ref2";
4570 case DW_FORM_ref4: return "DW_FORM_ref4";
4571 case DW_FORM_ref8: return "DW_FORM_ref8";
4572 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
4573 case DW_FORM_indirect: return "DW_FORM_indirect";
4574 default:
4575 {
4576 static char buffer [100];
4577
4578 sprintf (buffer, _("Unknown FORM value: %lx"), form);
4579 return buffer;
4580 }
4581 }
4582}
4583
4584/* FIXME: There are better and more effiecint ways to handle
4585 these structures. For now though, I just want something that
4586 is simple to implement. */
4587typedef struct abbrev_attr
4588{
4589 unsigned long attribute;
4590 unsigned long form;
4591 struct abbrev_attr * next;
4592}
4593abbrev_attr;
4594
4595typedef struct abbrev_entry
4596{
4597 unsigned long entry;
4598 unsigned long tag;
4599 int children;
4600 struct abbrev_attr * first_attr;
4601 struct abbrev_attr * last_attr;
4602 struct abbrev_entry * next;
4603}
4604abbrev_entry;
4605
4606static abbrev_entry * first_abbrev = NULL;
4607static abbrev_entry * last_abbrev = NULL;
4608
4609static void
4610free_abbrevs PARAMS ((void))
4611{
4612 abbrev_entry * abbrev;
4613
4614 for (abbrev = first_abbrev; abbrev;)
4615 {
4616 abbrev_entry * next = abbrev->next;
4617 abbrev_attr * attr;
4618
4619 for (attr = abbrev->first_attr; attr;)
4620 {
4621 abbrev_attr * next = attr->next;
4622
4623 free (attr);
4624 attr = next;
4625 }
4626
4627 free (abbrev);
4628 abbrev = next;
4629 }
4630
4631 last_abbrev = first_abbrev = NULL;
4632}
4633
4634static void
4635add_abbrev (number, tag, children)
4636 unsigned long number;
4637 unsigned long tag;
4638 int children;
4639{
4640 abbrev_entry * entry;
4641
4642 entry = (abbrev_entry *) malloc (sizeof (* entry));
4643
4644 if (entry == NULL)
4645 /* ugg */
4646 return;
4647
4648 entry->entry = number;
4649 entry->tag = tag;
4650 entry->children = children;
4651 entry->first_attr = NULL;
4652 entry->last_attr = NULL;
4653 entry->next = NULL;
4654
4655 if (first_abbrev == NULL)
4656 first_abbrev = entry;
4657 else
4658 last_abbrev->next = entry;
4659
4660 last_abbrev = entry;
4661}
4662
4663static void
4664add_abbrev_attr (attribute, form)
4665 unsigned long attribute;
4666 unsigned long form;
4667{
4668 abbrev_attr * attr;
4669
4670 attr = (abbrev_attr *) malloc (sizeof (* attr));
4671
4672 if (attr == NULL)
4673 /* ugg */
4674 return;
4675
4676 attr->attribute = attribute;
4677 attr->form = form;
4678 attr->next = NULL;
4679
4680 if (last_abbrev->first_attr == NULL)
4681 last_abbrev->first_attr = attr;
4682 else
4683 last_abbrev->last_attr->next = attr;
4684
4685 last_abbrev->last_attr = attr;
4686}
4687
4688/* Processes the (partial) contents of a .debug_abbrev section.
4689 Returns NULL if the end of the section was encountered.
4690 Returns the address after the last byte read if the end of
4691 an abbreviation set was found. */
4692
4693static unsigned char *
4694process_abbrev_section (start, end)
4695 unsigned char * start;
4696 unsigned char * end;
4697{
4698 if (first_abbrev != NULL)
4699 return NULL;
4700
4701 while (start < end)
4702 {
4703 int bytes_read;
4704 unsigned long entry;
4705 unsigned long tag;
4706 unsigned long attribute;
4707 int children;
4708
4709 entry = read_leb128 (start, & bytes_read, 0);
4710 start += bytes_read;
4711
4712 if (entry == 0)
4713 return start;
4714
4715 tag = read_leb128 (start, & bytes_read, 0);
4716 start += bytes_read;
4717
4718 children = * start ++;
4719
4720 add_abbrev (entry, tag, children);
4721
4722 do
4723 {
4724 unsigned long form;
4725
4726 attribute = read_leb128 (start, & bytes_read, 0);
4727 start += bytes_read;
4728
4729 form = read_leb128 (start, & bytes_read, 0);
4730 start += bytes_read;
4731
4732 if (attribute != 0)
4733 add_abbrev_attr (attribute, form);
4734 }
4735 while (attribute != 0);
4736 }
4737
4738 return NULL;
4739}
4740
4741
4742static int
4743display_debug_abbrev (section, start, file)
4744 Elf32_Internal_Shdr * section;
4745 unsigned char * start;
4746 FILE * file;
4747{
4748 abbrev_entry * entry;
4749 unsigned char * end = start + section->sh_size;
4750
4751 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
4752
4753 do
4754 {
4755 start = process_abbrev_section (start, end);
4756
4757 printf (_(" Number TAG\n"));
4758
4759 for (entry = first_abbrev; entry; entry = entry->next)
4760 {
4761 abbrev_attr * attr;
4762
4763 printf (_(" %ld %s [%s]\n"),
4764 entry->entry,
4765 get_TAG_name (entry->tag),
4766 entry->children ? _("has children") : _("no children"));
4767
4768 for (attr = entry->first_attr; attr; attr = attr->next)
4769 {
4770 printf (_(" %-18s %s\n"),
4771 get_AT_name (attr->attribute),
4772 get_FORM_name (attr->form));
4773 }
4774 }
4775 }
4776 while (start);
4777
4778 printf ("\n");
4779
4780 return 1;
4781}
4782
4783
4784static unsigned char *
4785display_block (data, length)
4786 unsigned char * data;
4787 unsigned long length;
4788{
4789 printf (_(" %lu byte block: "), length);
4790
4791 while (length --)
148d3c43 4792 printf ("%lx ", (unsigned long) byte_get (data ++, 1));
252b5132
RH
4793
4794 return data;
4795}
4796
4797static void
4798decode_location_expression (data, pointer_size)
4799 unsigned char * data;
4800 unsigned int pointer_size;
4801{
4802 unsigned char op;
4803 int bytes_read;
148d3c43 4804 unsigned long uvalue;
252b5132
RH
4805
4806 op = * data ++;
4807
4808 switch (op)
4809 {
148d3c43
AS
4810 case DW_OP_addr:
4811 printf ("DW_OP_addr: %lx", (unsigned long) byte_get (data, pointer_size));
4812 break;
4813 case DW_OP_deref:
4814 printf ("DW_OP_deref");
4815 break;
4816 case DW_OP_const1u:
4817 printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data, 1));
4818 break;
4819 case DW_OP_const1s:
4820 printf ("DW_OP_const1s: %ld", (long) byte_get (data, 1));
4821 break;
4822 case DW_OP_const2u:
4823 printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
4824 break;
4825 case DW_OP_const2s:
4826 printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
4827 break;
4828 case DW_OP_const4u:
4829 printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
4830 break;
4831 case DW_OP_const4s:
4832 printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
4833 break;
4834 case DW_OP_const8u:
4835 printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
4836 (unsigned long) byte_get (data + 4, 4));
4837 break;
4838 case DW_OP_const8s:
4839 printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
4840 (long) byte_get (data + 4, 4));
4841 break;
4842 case DW_OP_constu:
4843 printf ("DW_OP_constu: %lu", read_leb128 (data, NULL, 0));
4844 break;
4845 case DW_OP_consts:
4846 printf ("DW_OP_consts: %ld", read_leb128 (data, NULL, 1));
4847 break;
4848 case DW_OP_dup:
4849 printf ("DW_OP_dup");
4850 break;
4851 case DW_OP_drop:
4852 printf ("DW_OP_drop");
4853 break;
4854 case DW_OP_over:
4855 printf ("DW_OP_over");
4856 break;
4857 case DW_OP_pick:
4858 printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data, 1));
4859 break;
4860 case DW_OP_swap:
4861 printf ("DW_OP_swap");
4862 break;
4863 case DW_OP_rot:
4864 printf ("DW_OP_rot");
4865 break;
4866 case DW_OP_xderef:
4867 printf ("DW_OP_xderef");
4868 break;
4869 case DW_OP_abs:
4870 printf ("DW_OP_abs");
4871 break;
4872 case DW_OP_and:
4873 printf ("DW_OP_and");
4874 break;
4875 case DW_OP_div:
4876 printf ("DW_OP_div");
4877 break;
4878 case DW_OP_minus:
4879 printf ("DW_OP_minus");
4880 break;
4881 case DW_OP_mod:
4882 printf ("DW_OP_mod");
4883 break;
4884 case DW_OP_mul:
4885 printf ("DW_OP_mul");
4886 break;
4887 case DW_OP_neg:
4888 printf ("DW_OP_neg");
4889 break;
4890 case DW_OP_not:
4891 printf ("DW_OP_not");
4892 break;
4893 case DW_OP_or:
4894 printf ("DW_OP_or");
4895 break;
4896 case DW_OP_plus:
4897 printf ("DW_OP_plus");
4898 break;
4899 case DW_OP_plus_uconst:
4900 printf ("DW_OP_plus_uconst: %lu", read_leb128 (data, NULL, 0));
4901 break;
4902 case DW_OP_shl:
4903 printf ("DW_OP_shl");
4904 break;
4905 case DW_OP_shr:
4906 printf ("DW_OP_shr");
4907 break;
4908 case DW_OP_shra:
4909 printf ("DW_OP_shra");
4910 break;
4911 case DW_OP_xor:
4912 printf ("DW_OP_xor");
4913 break;
4914 case DW_OP_bra:
4915 printf ("DW_OP_bra: %ld", byte_get (data, 2));
4916 break;
4917 case DW_OP_eq:
4918 printf ("DW_OP_eq");
4919 break;
4920 case DW_OP_ge:
4921 printf ("DW_OP_ge");
4922 break;
4923 case DW_OP_gt:
4924 printf ("DW_OP_gt");
4925 break;
4926 case DW_OP_le:
4927 printf ("DW_OP_le");
4928 break;
4929 case DW_OP_lt:
4930 printf ("DW_OP_lt");
4931 break;
4932 case DW_OP_ne:
4933 printf ("DW_OP_ne");
4934 break;
4935 case DW_OP_skip:
4936 printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
4937 break;
4938 case DW_OP_lit0:
4939 printf ("DW_OP_lit0");
4940 break;
4941 case DW_OP_lit1:
4942 printf ("DW_OP_lit1");
4943 break;
4944 case DW_OP_lit2:
4945 printf ("DW_OP_lit2");
4946 break;
4947 case DW_OP_lit3:
4948 printf ("DW_OP_lit3");
4949 break;
4950 case DW_OP_lit4:
4951 printf ("DW_OP_lit4");
4952 break;
4953 case DW_OP_lit5:
4954 printf ("DW_OP_lit5");
4955 break;
4956 case DW_OP_lit6:
4957 printf ("DW_OP_lit6");
4958 break;
4959 case DW_OP_lit7:
4960 printf ("DW_OP_lit7");
4961 break;
4962 case DW_OP_lit8:
4963 printf ("DW_OP_lit8");
4964 break;
4965 case DW_OP_lit9:
4966 printf ("DW_OP_lit9");
4967 break;
4968 case DW_OP_lit10:
4969 printf ("DW_OP_lit10");
4970 break;
4971 case DW_OP_lit11:
4972 printf ("DW_OP_lit11");
4973 break;
4974 case DW_OP_lit12:
4975 printf ("DW_OP_lit12");
4976 break;
4977 case DW_OP_lit13:
4978 printf ("DW_OP_lit13");
4979 break;
4980 case DW_OP_lit14:
4981 printf ("DW_OP_lit14");
4982 break;
4983 case DW_OP_lit15:
4984 printf ("DW_OP_lit15");
4985 break;
4986 case DW_OP_lit16:
4987 printf ("DW_OP_lit16");
4988 break;
4989 case DW_OP_lit17:
4990 printf ("DW_OP_lit17");
4991 break;
4992 case DW_OP_lit18:
4993 printf ("DW_OP_lit18");
4994 break;
4995 case DW_OP_lit19:
4996 printf ("DW_OP_lit19");
4997 break;
4998 case DW_OP_lit20:
4999 printf ("DW_OP_lit20");
5000 break;
5001 case DW_OP_lit21:
5002 printf ("DW_OP_lit21");
5003 break;
5004 case DW_OP_lit22:
5005 printf ("DW_OP_lit22");
5006 break;
5007 case DW_OP_lit23:
5008 printf ("DW_OP_lit23");
5009 break;
5010 case DW_OP_lit24:
5011 printf ("DW_OP_lit24");
5012 break;
5013 case DW_OP_lit25:
5014 printf ("DW_OP_lit25");
5015 break;
5016 case DW_OP_lit26:
5017 printf ("DW_OP_lit26");
5018 break;
5019 case DW_OP_lit27:
5020 printf ("DW_OP_lit27");
5021 break;
5022 case DW_OP_lit28:
5023 printf ("DW_OP_lit28");
5024 break;
5025 case DW_OP_lit29:
5026 printf ("DW_OP_lit29");
5027 break;
5028 case DW_OP_lit30:
5029 printf ("DW_OP_lit30");
5030 break;
5031 case DW_OP_lit31:
5032 printf ("DW_OP_lit31");
5033 break;
5034 case DW_OP_reg0:
5035 printf ("DW_OP_reg0");
5036 break;
5037 case DW_OP_reg1:
5038 printf ("DW_OP_reg1");
5039 break;
5040 case DW_OP_reg2:
5041 printf ("DW_OP_reg2");
5042 break;
5043 case DW_OP_reg3:
5044 printf ("DW_OP_reg3");
5045 break;
5046 case DW_OP_reg4:
5047 printf ("DW_OP_reg4");
5048 break;
5049 case DW_OP_reg5:
5050 printf ("DW_OP_reg5");
5051 break;
5052 case DW_OP_reg6:
5053 printf ("DW_OP_reg6");
5054 break;
5055 case DW_OP_reg7:
5056 printf ("DW_OP_reg7");
5057 break;
5058 case DW_OP_reg8:
5059 printf ("DW_OP_reg8");
5060 break;
5061 case DW_OP_reg9:
5062 printf ("DW_OP_reg9");
5063 break;
5064 case DW_OP_reg10:
5065 printf ("DW_OP_reg10");
5066 break;
5067 case DW_OP_reg11:
5068 printf ("DW_OP_reg11");
5069 break;
5070 case DW_OP_reg12:
5071 printf ("DW_OP_reg12");
5072 break;
5073 case DW_OP_reg13:
5074 printf ("DW_OP_reg13");
5075 break;
5076 case DW_OP_reg14:
5077 printf ("DW_OP_reg14");
5078 break;
5079 case DW_OP_reg15:
5080 printf ("DW_OP_reg15");
5081 break;
5082 case DW_OP_reg16:
5083 printf ("DW_OP_reg16");
5084 break;
5085 case DW_OP_reg17:
5086 printf ("DW_OP_reg17");
5087 break;
5088 case DW_OP_reg18:
5089 printf ("DW_OP_reg18");
5090 break;
5091 case DW_OP_reg19:
5092 printf ("DW_OP_reg19");
5093 break;
5094 case DW_OP_reg20:
5095 printf ("DW_OP_reg20");
5096 break;
5097 case DW_OP_reg21:
5098 printf ("DW_OP_reg21");
5099 break;
5100 case DW_OP_reg22:
5101 printf ("DW_OP_reg22");
5102 break;
5103 case DW_OP_reg23:
5104 printf ("DW_OP_reg23");
5105 break;
5106 case DW_OP_reg24:
5107 printf ("DW_OP_reg24");
5108 break;
5109 case DW_OP_reg25:
5110 printf ("DW_OP_reg25");
5111 break;
5112 case DW_OP_reg26:
5113 printf ("DW_OP_reg26");
5114 break;
5115 case DW_OP_reg27:
5116 printf ("DW_OP_reg27");
5117 break;
5118 case DW_OP_reg28:
5119 printf ("DW_OP_reg28");
5120 break;
5121 case DW_OP_reg29:
5122 printf ("DW_OP_reg29");
5123 break;
5124 case DW_OP_reg30:
5125 printf ("DW_OP_reg30");
5126 break;
5127 case DW_OP_reg31:
5128 printf ("DW_OP_reg31");
5129 break;
5130 case DW_OP_breg0:
5131 printf ("DW_OP_breg0: %ld", read_leb128 (data, NULL, 1));
5132 break;
5133 case DW_OP_breg1:
5134 printf ("DW_OP_breg1: %ld", read_leb128 (data, NULL, 1));
5135 break;
5136 case DW_OP_breg2:
5137 printf ("DW_OP_breg2: %ld", read_leb128 (data, NULL, 1));
5138 break;
5139 case DW_OP_breg3:
5140 printf ("DW_OP_breg3: %ld", read_leb128 (data, NULL, 1));
5141 break;
5142 case DW_OP_breg4:
5143 printf ("DW_OP_breg4: %ld", read_leb128 (data, NULL, 1));
5144 break;
5145 case DW_OP_breg5:
5146 printf ("DW_OP_breg5: %ld", read_leb128 (data, NULL, 1));
5147 break;
5148 case DW_OP_breg6:
5149 printf ("DW_OP_breg6: %ld", read_leb128 (data, NULL, 1));
5150 break;
5151 case DW_OP_breg7:
5152 printf ("DW_OP_breg7: %ld", read_leb128 (data, NULL, 1));
5153 break;
5154 case DW_OP_breg8:
5155 printf ("DW_OP_breg8: %ld", read_leb128 (data, NULL, 1));
5156 break;
5157 case DW_OP_breg9:
5158 printf ("DW_OP_breg9: %ld", read_leb128 (data, NULL, 1));
5159 break;
5160 case DW_OP_breg10:
5161 printf ("DW_OP_breg10: %ld", read_leb128 (data, NULL, 1));
5162 break;
5163 case DW_OP_breg11:
5164 printf ("DW_OP_breg11: %ld", read_leb128 (data, NULL, 1));
5165 break;
5166 case DW_OP_breg12:
5167 printf ("DW_OP_breg12: %ld", read_leb128 (data, NULL, 1));
5168 break;
5169 case DW_OP_breg13:
5170 printf ("DW_OP_breg13: %ld", read_leb128 (data, NULL, 1));
5171 break;
5172 case DW_OP_breg14:
5173 printf ("DW_OP_breg14: %ld", read_leb128 (data, NULL, 1));
5174 break;
5175 case DW_OP_breg15:
5176 printf ("DW_OP_breg15: %ld", read_leb128 (data, NULL, 1));
5177 break;
5178 case DW_OP_breg16:
5179 printf ("DW_OP_breg16: %ld", read_leb128 (data, NULL, 1));
5180 break;
5181 case DW_OP_breg17:
5182 printf ("DW_OP_breg17: %ld", read_leb128 (data, NULL, 1));
5183 break;
5184 case DW_OP_breg18:
5185 printf ("DW_OP_breg18: %ld", read_leb128 (data, NULL, 1));
5186 break;
5187 case DW_OP_breg19:
5188 printf ("DW_OP_breg19: %ld", read_leb128 (data, NULL, 1));
5189 break;
5190 case DW_OP_breg20:
5191 printf ("DW_OP_breg20: %ld", read_leb128 (data, NULL, 1));
5192 break;
5193 case DW_OP_breg21:
5194 printf ("DW_OP_breg21: %ld", read_leb128 (data, NULL, 1));
5195 break;
5196 case DW_OP_breg22:
5197 printf ("DW_OP_breg22: %ld", read_leb128 (data, NULL, 1));
5198 break;
5199 case DW_OP_breg23:
5200 printf ("DW_OP_breg23: %ld", read_leb128 (data, NULL, 1));
5201 break;
5202 case DW_OP_breg24:
5203 printf ("DW_OP_breg24: %ld", read_leb128 (data, NULL, 1));
5204 break;
5205 case DW_OP_breg25:
5206 printf ("DW_OP_breg25: %ld", read_leb128 (data, NULL, 1));
5207 break;
5208 case DW_OP_breg26:
5209 printf ("DW_OP_breg26: %ld", read_leb128 (data, NULL, 1));
5210 break;
5211 case DW_OP_breg27:
5212 printf ("DW_OP_breg27: %ld", read_leb128 (data, NULL, 1));
5213 break;
5214 case DW_OP_breg28:
5215 printf ("DW_OP_breg28: %ld", read_leb128 (data, NULL, 1));
5216 break;
5217 case DW_OP_breg29:
5218 printf ("DW_OP_breg29: %ld", read_leb128 (data, NULL, 1));
5219 break;
5220 case DW_OP_breg30:
5221 printf ("DW_OP_breg30: %ld", read_leb128 (data, NULL, 1));
5222 break;
5223 case DW_OP_breg31:
5224 printf ("DW_OP_breg31: %ld", read_leb128 (data, NULL, 1));
5225 break;
5226 case DW_OP_regx:
5227 printf ("DW_OP_regx: %lu", read_leb128 (data, NULL, 0));
5228 break;
5229 case DW_OP_fbreg:
5230 printf ("DW_OP_fbreg: %ld", read_leb128 (data, NULL, 1));
5231 break;
5232 case DW_OP_bregx:
5233 uvalue = read_leb128 (data, &bytes_read, 0);
5234 printf ("DW_OP_bregx: %lu %ld", uvalue,
5235 read_leb128 (data + bytes_read, NULL, 1));
5236 break;
5237 case DW_OP_piece:
5238 printf ("DW_OP_piece: %lu", read_leb128 (data, NULL, 0));
5239 break;
5240 case DW_OP_deref_size:
5241 printf ("DW_OP_deref_size: %ld", (long) byte_get (data, 1));
5242 break;
5243 case DW_OP_xderef_size:
5244 printf ("DW_OP_xderef_size: %ld", (long) byte_get (data, 1));
5245 break;
5246 case DW_OP_nop:
5247 printf ("DW_OP_nop");
5248 break;
252b5132
RH
5249
5250 default:
5251 if (op >= DW_OP_lo_user
5252 && op <= DW_OP_hi_user)
5253 printf (_("(User defined location op)"));
5254 else
5255 printf (_("(Unknown location op)"));
5256 break;
5257 }
5258}
5259
5260
5261static unsigned char *
5262read_and_display_attr (attribute, form, data, pointer_size)
5263 unsigned long attribute;
5264 unsigned long form;
5265 unsigned char * data;
5266 unsigned long pointer_size;
5267{
5268 unsigned long uvalue;
5269 unsigned char * block_start;
5270 int bytes_read;
5271 int is_ref = 0;
5272
5273 printf (" %-18s:", get_AT_name (attribute));
5274
5275 switch (form)
5276 {
5277 case DW_FORM_ref_addr:
5278 case DW_FORM_ref1:
5279 case DW_FORM_ref2:
5280 case DW_FORM_ref4:
5281 case DW_FORM_ref8:
5282 case DW_FORM_ref_udata:
5283 is_ref = 1;
5284 }
5285
5286 switch (form)
5287 {
5288 case DW_FORM_ref_addr:
5289 case DW_FORM_addr:
5290 uvalue = byte_get (data, pointer_size);
5291 printf (is_ref ? " <%x>" : " %#x", uvalue);
5292 data += pointer_size;
5293 break;
5294
5295 case DW_FORM_ref1:
5296 case DW_FORM_flag:
5297 case DW_FORM_data1:
5298 uvalue = byte_get (data ++, 1);
5299 printf (is_ref ? " <%x>" : " %d", uvalue);
5300 break;
5301
5302 case DW_FORM_ref2:
5303 case DW_FORM_data2:
5304 uvalue = byte_get (data, 2);
5305 data += 2;
5306 printf (is_ref ? " <%x>" : " %d", uvalue);
5307 break;
5308
5309 case DW_FORM_ref4:
5310 case DW_FORM_data4:
5311 uvalue = byte_get (data, 4);
5312 data += 4;
5313 printf (is_ref ? " <%x>" : " %d", uvalue);
5314 break;
5315
5316 case DW_FORM_ref8:
5317 case DW_FORM_data8:
5318 uvalue = byte_get (data, 4);
5319 printf (" %lx", uvalue);
148d3c43 5320 printf (" %lx", (unsigned long) byte_get (data + 4, 4));
252b5132
RH
5321 data += 8;
5322 break;
5323
5324 case DW_FORM_string:
5325 printf (" %s", data);
5326 data += strlen (data) + 1;
5327 break;
5328
5329 case DW_FORM_sdata:
5330 uvalue = read_leb128 (data, & bytes_read, 1);
5331 data += bytes_read;
5332 printf (" %ld", (long) uvalue);
5333 break;
5334
5335 case DW_FORM_ref_udata:
5336 case DW_FORM_udata:
5337 uvalue = read_leb128 (data, & bytes_read, 0);
5338 data += bytes_read;
5339 printf (is_ref ? " <%lx>" : " %ld", uvalue);
5340 break;
5341
5342 case DW_FORM_block:
5343 uvalue = read_leb128 (data, & bytes_read, 0);
5344 block_start = data + bytes_read;
5345 data = display_block (block_start, uvalue);
5346 uvalue = * block_start;
5347 break;
5348
5349 case DW_FORM_block1:
5350 uvalue = byte_get (data, 1);
5351 block_start = data + 1;
5352 data = display_block (block_start, uvalue);
5353 uvalue = * block_start;
5354 break;
5355
5356 case DW_FORM_block2:
5357 uvalue = byte_get (data, 2);
5358 block_start = data + 2;
5359 data = display_block (block_start, uvalue);
5360 uvalue = * block_start;
5361 break;
5362
5363 case DW_FORM_block4:
5364 uvalue = byte_get (data, 4);
5365 block_start = data + 4;
5366 data = display_block (block_start, uvalue);
5367 uvalue = * block_start;
5368 break;
5369
5370 case DW_FORM_strp:
5371 case DW_FORM_indirect:
5372 warn (_("Unable to handle FORM: %d"), form);
5373 break;
5374
5375 default:
5376 warn (_("Unrecognised form: %d"), form);
5377 break;
5378 }
5379
5380 /* For some attributes we can display futher information. */
5381
5382 printf ("\t");
5383
5384 switch (attribute)
5385 {
5386 case DW_AT_inline:
5387 switch (uvalue)
5388 {
5389 case DW_INL_not_inlined: printf (_("(not inlined)")); break;
5390 case DW_INL_inlined: printf (_("(inlined)")); break;
5391 case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
5392 case DW_INL_declared_inlined: printf (_("(declared as inline and inlined)")); break;
5393 default: printf (_(" (Unknown inline attribute value: %lx)"), uvalue); break;
5394 }
5395 break;
5396
5397 case DW_AT_frame_base:
5398 if (uvalue >= DW_OP_reg0 && uvalue <= DW_OP_reg31)
5399 printf ("(reg %ld)", uvalue - DW_OP_reg0);
5400 break;
5401
5402 case DW_AT_language:
5403 switch (uvalue)
5404 {
5405 case DW_LANG_C: printf ("(non-ANSI C)"); break;
5406 case DW_LANG_C89: printf ("(ANSI C)"); break;
5407 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
5408 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
5409 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
5410 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
5411 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
5412 case DW_LANG_Ada83: printf ("(Ada)"); break;
5413 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
5414 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
5415 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
5416 default: printf ("(Unknown: %lx)", uvalue); break;
5417 }
5418 break;
5419
5420 case DW_AT_encoding:
5421 switch (uvalue)
5422 {
5423 case DW_ATE_void: printf ("(void)"); break;
5424 case DW_ATE_address: printf ("(machine address)"); break;
5425 case DW_ATE_boolean: printf ("(boolean)"); break;
5426 case DW_ATE_complex_float: printf ("(complex float)"); break;
5427 case DW_ATE_float: printf ("(float)"); break;
5428 case DW_ATE_signed: printf ("(signed)"); break;
5429 case DW_ATE_signed_char: printf ("(signed char)"); break;
5430 case DW_ATE_unsigned: printf ("(unsigned)"); break;
5431 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
5432 default:
5433 if (uvalue >= DW_ATE_lo_user
5434 && uvalue <= DW_ATE_hi_user)
5435 printf ("(user defined type)");
5436 else
5437 printf ("(unknown type)");
5438 break;
5439 }
5440 break;
5441
5442 case DW_AT_accessibility:
5443 switch (uvalue)
5444 {
5445 case DW_ACCESS_public: printf ("(public)"); break;
5446 case DW_ACCESS_protected: printf ("(protected)"); break;
5447 case DW_ACCESS_private: printf ("(private)"); break;
5448 default: printf ("(unknown accessibility)"); break;
5449 }
5450 break;
5451
5452 case DW_AT_visibility:
5453 switch (uvalue)
5454 {
5455 case DW_VIS_local: printf ("(local)"); break;
5456 case DW_VIS_exported: printf ("(exported)"); break;
5457 case DW_VIS_qualified: printf ("(qualified)"); break;
5458 default: printf ("(unknown visibility)"); break;
5459 }
5460 break;
5461
5462 case DW_AT_virtuality:
5463 switch (uvalue)
5464 {
5465 case DW_VIRTUALITY_none: printf ("(none)"); break;
5466 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
5467 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
5468 default: printf ("(unknown virtuality)"); break;
5469 }
5470 break;
5471
5472 case DW_AT_identifier_case:
5473 switch (uvalue)
5474 {
5475 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
5476 case DW_ID_up_case: printf ("(up_case)"); break;
5477 case DW_ID_down_case: printf ("(down_case)"); break;
5478 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
5479 default: printf ("(unknown case)"); break;
5480 }
5481 break;
5482
5483 case DW_AT_calling_convention:
5484 switch (uvalue)
5485 {
5486 case DW_CC_normal: printf ("(normal)"); break;
5487 case DW_CC_program: printf ("(program)"); break;
5488 case DW_CC_nocall: printf ("(nocall)"); break;
5489 default:
5490 if (uvalue >= DW_CC_lo_user
5491 && uvalue <= DW_CC_hi_user)
5492 printf ("(user defined)");
5493 else
5494 printf ("(unknown convention)");
5495 }
5496 break;
5497
5498 case DW_AT_location:
5499 case DW_AT_data_member_location:
5500 case DW_AT_vtable_elem_location:
5501 printf ("(");
5502 decode_location_expression (block_start, pointer_size);
5503 printf (")");
5504 break;
5505
5506 default:
5507 break;
5508 }
5509
5510 printf ("\n");
5511 return data;
5512}
5513
5514static int
5515display_debug_info (section, start, file)
5516 Elf32_Internal_Shdr * section;
5517 unsigned char * start;
5518 FILE * file;
5519{
5520 unsigned char * end = start + section->sh_size;
5521 unsigned char * section_begin = start;
5522
5523 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
5524
5525 while (start < end)
5526 {
5527 DWARF2_External_CompUnit * external;
5528 DWARF2_Internal_CompUnit compunit;
5529 unsigned char * tags;
5530 int i;
5531 int level;
5532
5533 external = (DWARF2_External_CompUnit *) start;
5534
5535 compunit.cu_length = BYTE_GET (external->cu_length);
5536 compunit.cu_version = BYTE_GET (external->cu_version);
5537 compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
5538 compunit.cu_pointer_size = BYTE_GET (external->cu_pointer_size);
5539
5540 tags = start + sizeof (* external);
5541 start += compunit.cu_length + sizeof (external->cu_length);
5542
5543 if (compunit.cu_version != 2)
5544 {
5545 warn (_("Only version 2 DWARF debug information is currently supported.\n"));
5546 continue;
5547 }
5548
5549 printf (_(" Compilation Unit:\n"));
5550 printf (_(" Length: %ld\n"), compunit.cu_length);
5551 printf (_(" Version: %d\n"), compunit.cu_version);
5552 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
5553 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
5554
5555 if (first_abbrev != NULL)
5556 free_abbrevs ();
5557
5558 /* Read in the abbrevs used by this compilation unit. */
5559
5560 {
5561 Elf32_Internal_Shdr * sec;
5562 unsigned char * begin;
5563
5564 /* Locate the .debug_abbrev section and process it. */
5565 for (i = 0, sec = section_headers;
5566 i < elf_header.e_shnum;
5567 i ++, sec ++)
5568 if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
5569 break;
5570
5571 if (i == -1 || sec->sh_size == 0)
5572 {
5573 warn (_("Unable to locate .debug_abbrev section!\n"));
5574 return 0;
5575 }
5576
5577 GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, unsigned char *,
5578 "debug_abbrev section data");
5579
5580 process_abbrev_section (begin + compunit.cu_abbrev_offset,
5581 begin + sec->sh_size);
5582
5583 free (begin);
5584 }
5585
5586 level = 0;
5587 while (tags < start)
5588 {
5589 int bytes_read;
5590 int abbrev_number;
5591 abbrev_entry * entry;
5592 abbrev_attr * attr;
5593
5594 abbrev_number = read_leb128 (tags, & bytes_read, 0);
5595 tags += bytes_read;
5596
5597 /* A null DIE marks the end of a list of children. */
5598 if (abbrev_number == 0)
5599 {
5600 --level;
5601 continue;
5602 }
5603
5604 /* Scan through the abbreviation list until we reach the
5605 correct entry. */
5606 for (entry = first_abbrev;
5607 entry && entry->entry != abbrev_number;
5608 entry = entry->next)
5609 continue;
5610
5611 if (entry == NULL)
5612 {
5613 warn (_("Unable to locate entry %d in the abbreviation table\n"),
5614 abbrev_number);
5615 return 0;
5616 }
5617
5618 printf (_(" <%d><%x>: Abbrev Number: %d (%s)\n"),
5619 level, tags - section_begin - bytes_read,
5620 abbrev_number,
5621 get_TAG_name (entry->tag));
5622
5623 for (attr = entry->first_attr; attr; attr = attr->next)
5624 tags = read_and_display_attr (attr->attribute,
5625 attr->form,
5626 tags,
5627 compunit.cu_pointer_size);
5628
5629 if (entry->children)
5630 ++level;
5631 }
5632 }
5633
5634 printf ("\n");
5635
5636 return 1;
5637}
5638
5639static int
5640display_debug_aranges (section, start, file)
5641 Elf32_Internal_Shdr * section;
5642 unsigned char * start;
5643 FILE * file;
5644{
5645 unsigned char * end = start + section->sh_size;
5646
5647 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
5648
5649 while (start < end)
5650 {
5651 DWARF2_External_ARange * external;
5652 DWARF2_Internal_ARange arange;
5653 unsigned char * ranges;
5654 unsigned long length;
5655 unsigned long address;
5656
5657 external = (DWARF2_External_ARange *) start;
5658
5659 arange.ar_length = BYTE_GET (external->ar_length);
5660 arange.ar_version = BYTE_GET (external->ar_version);
5661 arange.ar_info_offset = BYTE_GET (external->ar_info_offset);
5662 arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
5663 arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
5664
5665 printf (_(" Length: %ld\n"), arange.ar_length);
5666 printf (_(" Version: %d\n"), arange.ar_version);
5667 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
5668 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
5669 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
5670
5671 printf (_("\n Address Length\n"));
5672
5673 ranges = start + sizeof (* external);
5674
5675 for (;;)
5676 {
5677 address = byte_get (ranges, arange.ar_pointer_size);
5678
5679 if (address == 0)
5680 break;
5681
5682 ranges += arange.ar_pointer_size;
5683
5684 length = byte_get (ranges, arange.ar_pointer_size);
5685
5686 ranges += arange.ar_pointer_size;
5687
5688 printf (" %8.8lx %lu\n", address, length);
5689 }
5690
5691 start += arange.ar_length + sizeof (external->ar_length);
5692 }
5693
5694 printf ("\n");
5695
5696 return 1;
5697}
5698
5699
5700static int
5701display_debug_not_supported (section, start, file)
5702 Elf32_Internal_Shdr * section;
5703 unsigned char * start;
5704 FILE * file;
5705{
5706 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
5707 SECTION_NAME (section));
5708
5709 return 1;
5710}
5711
5712 /* A structure containing the name of a debug section and a pointer
5713 to a function that can decode it. */
5714struct
5715{
5716 char * name;
5717 int (* display) PARAMS((Elf32_Internal_Shdr *, unsigned char *, FILE *));
5718}
5719debug_displays[] =
5720{
5721 { ".debug_info", display_debug_info },
5722 { ".debug_abbrev", display_debug_abbrev },
5723 { ".debug_line", display_debug_lines },
5724 { ".debug_aranges", display_debug_aranges },
5725 { ".debug_pubnames", display_debug_pubnames },
5726 { ".debug_macinfo", display_debug_not_supported },
5727 { ".debug_frame", display_debug_not_supported },
5728 { ".debug_str", display_debug_not_supported },
5729 { ".debug_static_func", display_debug_not_supported },
5730 { ".debug_static_vars", display_debug_not_supported },
5731 { ".debug_types", display_debug_not_supported },
5732 { ".debug_weaknames", display_debug_not_supported }
5733};
5734
5735static int
5736display_debug_section (section, file)
5737 Elf32_Internal_Shdr * section;
5738 FILE * file;
5739{
5740 char * name = SECTION_NAME (section);
5741 bfd_size_type length;
5742 unsigned char * start;
5743 int i;
5744
5745 length = section->sh_size;
5746 if (length == 0)
5747 {
5748 printf (_("\nSection '%s' has no debugging data.\n"), name);
5749 return 0;
5750 }
5751
5752 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
5753 "debug section data");
5754
5755 /* See if we know how to display the contents of this section. */
5756 for (i = NUM_ELEM (debug_displays); i--;)
5757 if (strcmp (debug_displays[i].name, name) == 0)
5758 {
5759 debug_displays[i].display (section, start, file);
5760 break;
5761 }
5762
5763 if (i == -1)
5764 printf (_("Unrecognised debug section: %s\n"), name);
5765
5766 free (start);
5767
5768 /* If we loaded in the abbrev section at some point,
5769 we must release it here. */
5770 if (first_abbrev != NULL)
5771 free_abbrevs ();
5772
5773 return 1;
5774}
5775
5776static int
5777process_section_contents (file)
5778 FILE * file;
5779{
5780 Elf32_Internal_Shdr * section;
5781 unsigned int i;
5782
5783 if (! do_dump)
5784 return 1;
5785
5786 for (i = 0, section = section_headers;
5787 i < elf_header.e_shnum
5788 && i < num_dump_sects;
5789 i ++, section ++)
5790 {
5791#ifdef SUPPORT_DISASSEMBLY
5792 if (dump_sects[i] & DISASS_DUMP)
5793 disassemble_section (section, file);
5794#endif
5795 if (dump_sects[i] & HEX_DUMP)
5796 dump_section (section, file);
5797
5798 if (dump_sects[i] & DEBUG_DUMP)
5799 display_debug_section (section, file);
5800 }
5801
5802 if (i < num_dump_sects)
5803 warn (_("Some sections were not dumped because they do not exist!\n"));
5804
5805 return 1;
5806}
5807
5808static void
5809process_mips_fpe_exception (mask)
5810 int mask;
5811{
5812 if (mask)
5813 {
5814 int first = 1;
5815 if (mask & OEX_FPU_INEX)
5816 fputs ("INEX", stdout), first = 0;
5817 if (mask & OEX_FPU_UFLO)
5818 printf ("%sUFLO", first ? "" : "|"), first = 0;
5819 if (mask & OEX_FPU_OFLO)
5820 printf ("%sOFLO", first ? "" : "|"), first = 0;
5821 if (mask & OEX_FPU_DIV0)
5822 printf ("%sDIV0", first ? "" : "|"), first = 0;
5823 if (mask & OEX_FPU_INVAL)
5824 printf ("%sINVAL", first ? "" : "|");
5825 }
5826 else
5827 fputs ("0", stdout);
5828}
5829
5830static int
5831process_mips_specific (file)
9ea033b2 5832 FILE * file;
252b5132 5833{
9ea033b2 5834 Elf_Internal_Dyn * entry;
252b5132
RH
5835 size_t liblist_offset = 0;
5836 size_t liblistno = 0;
5837 size_t conflictsno = 0;
5838 size_t options_offset = 0;
5839 size_t conflicts_offset = 0;
5840
5841 /* We have a lot of special sections. Thanks SGI! */
5842 if (dynamic_segment == NULL)
5843 /* No information available. */
5844 return 0;
5845
5846 for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
5847 switch (entry->d_tag)
5848 {
5849 case DT_MIPS_LIBLIST:
5850 liblist_offset = entry->d_un.d_val - loadaddr;
5851 break;
5852 case DT_MIPS_LIBLISTNO:
5853 liblistno = entry->d_un.d_val;
5854 break;
5855 case DT_MIPS_OPTIONS:
5856 options_offset = entry->d_un.d_val - loadaddr;
5857 break;
5858 case DT_MIPS_CONFLICT:
5859 conflicts_offset = entry->d_un.d_val - loadaddr;
5860 break;
5861 case DT_MIPS_CONFLICTNO:
5862 conflictsno = entry->d_un.d_val;
5863 break;
5864 default:
5865 break;
5866 }
5867
5868 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
5869 {
9ea033b2 5870 Elf32_External_Lib * elib;
252b5132
RH
5871 size_t cnt;
5872
5873 GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
5874 elib, Elf32_External_Lib *, "liblist");
5875
5876 printf ("\nSection '.liblist' contains %d entries:\n", liblistno);
5877 fputs (" Library Time Stamp Checksum Version Flags\n",
5878 stdout);
5879
5880 for (cnt = 0; cnt < liblistno; ++cnt)
5881 {
5882 Elf32_Lib liblist;
5883 time_t time;
5884 char timebuf[20];
5885
5886 liblist.l_name = BYTE_GET (elib[cnt].l_name);
5887 time = BYTE_GET (elib[cnt].l_time_stamp);
5888 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
5889 liblist.l_version = BYTE_GET (elib[cnt].l_version);
5890 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
5891
5892 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
5893
5894 printf ("%3d: %-20s %s %#10lx %-7ld", cnt,
5895 dynamic_strings + liblist.l_name, timebuf,
5896 liblist.l_checksum, liblist.l_version);
5897
5898 if (liblist.l_flags == 0)
5899 puts (" NONE");
5900 else
5901 {
5902 static const struct
5903 {
5904 const char *name;
5905 int bit;
5906 } l_flags_vals[] =
5907 {
5908 { " EXACT_MATCH", LL_EXACT_MATCH },
5909 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
5910 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
5911 { " EXPORTS", LL_EXPORTS },
5912 { " DELAY_LOAD", LL_DELAY_LOAD },
5913 { " DELTA", LL_DELTA }
5914 };
5915 int flags = liblist.l_flags;
5916 int fcnt;
5917
5918 for (fcnt = 0;
5919 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
5920 ++fcnt)
5921 if ((flags & l_flags_vals[fcnt].bit) != 0)
5922 {
5923 fputs (l_flags_vals[fcnt].name, stdout);
5924 flags ^= l_flags_vals[fcnt].bit;
5925 }
5926 if (flags != 0)
5927 printf (" %#x", (unsigned int) flags);
5928
5929 puts ("");
5930 }
5931 }
5932
5933 free (elib);
5934 }
5935
5936 if (options_offset != 0)
5937 {
9ea033b2
NC
5938 Elf_External_Options * eopt;
5939 Elf_Internal_Shdr * sect = section_headers;
5940 Elf_Internal_Options * iopt;
5941 Elf_Internal_Options * option;
252b5132
RH
5942 size_t offset;
5943 int cnt;
5944
5945 /* Find the section header so that we get the size. */
5946 while (sect->sh_type != SHT_MIPS_OPTIONS)
5947 ++sect;
5948
5949 GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
5950 Elf_External_Options *, "options");
5951
5952 iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
5953 * sizeof (*iopt));
5954 if (iopt == NULL)
5955 {
5956 error (_("Out of memory"));
5957 return 0;
5958 }
5959
5960 offset = cnt = 0;
5961 option = iopt;
5962 while (offset < sect->sh_size)
5963 {
9ea033b2 5964 Elf_External_Options * eoption;
252b5132
RH
5965
5966 eoption = (Elf_External_Options *) ((char *) eopt + offset);
5967
5968 option->kind = BYTE_GET (eoption->kind);
5969 option->size = BYTE_GET (eoption->size);
5970 option->section = BYTE_GET (eoption->section);
5971 option->info = BYTE_GET (eoption->info);
5972
5973 offset += option->size;
5974 ++option;
5975 ++cnt;
5976 }
5977
5978 printf (_("\nSection '%s' contains %d entries:\n"),
5979 string_table + sect->sh_name, cnt);
5980
5981 option = iopt;
5982 while (cnt-- > 0)
5983 {
5984 size_t len;
5985
5986 switch (option->kind)
5987 {
5988 case ODK_NULL:
5989 /* This shouldn't happen. */
5990 printf (" NULL %d %lx", option->section, option->info);
5991 break;
5992 case ODK_REGINFO:
5993 printf (" REGINFO ");
5994 if (elf_header.e_machine == EM_MIPS)
5995 {
5996 /* 32bit form. */
5997 Elf32_External_RegInfo *ereg;
5998 Elf32_RegInfo reginfo;
5999
6000 ereg = (Elf32_External_RegInfo *) (option + 1);
6001 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
6002 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
6003 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
6004 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
6005 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
6006 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
6007
6008 printf ("GPR %08lx GP 0x%lx\n",
6009 reginfo.ri_gprmask,
6010 (unsigned long) reginfo.ri_gp_value);
6011 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
6012 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
6013 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
6014 }
6015 else
6016 {
6017 /* 64 bit form. */
9ea033b2 6018 Elf64_External_RegInfo * ereg;
252b5132
RH
6019 Elf64_Internal_RegInfo reginfo;
6020
6021 ereg = (Elf64_External_RegInfo *) (option + 1);
9ea033b2 6022 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
252b5132
RH
6023 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
6024 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
6025 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
6026 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
9ea033b2 6027 reginfo.ri_gp_value = BYTE_GET8 (ereg->ri_gp_value);
252b5132
RH
6028
6029 printf ("GPR %08lx GP 0x",
6030 reginfo.ri_gprmask);
6031 printf_vma (reginfo.ri_gp_value);
6032 printf ("\n");
6033
6034 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
6035 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
6036 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
6037 }
6038 ++option;
6039 continue;
6040 case ODK_EXCEPTIONS:
6041 fputs (" EXCEPTIONS fpe_min(", stdout);
6042 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
6043 fputs (") fpe_max(", stdout);
6044 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
6045 fputs (")", stdout);
6046
6047 if (option->info & OEX_PAGE0)
6048 fputs (" PAGE0", stdout);
6049 if (option->info & OEX_SMM)
6050 fputs (" SMM", stdout);
6051 if (option->info & OEX_FPDBUG)
6052 fputs (" FPDBUG", stdout);
6053 if (option->info & OEX_DISMISS)
6054 fputs (" DISMISS", stdout);
6055 break;
6056 case ODK_PAD:
6057 fputs (" PAD ", stdout);
6058 if (option->info & OPAD_PREFIX)
6059 fputs (" PREFIX", stdout);
6060 if (option->info & OPAD_POSTFIX)
6061 fputs (" POSTFIX", stdout);
6062 if (option->info & OPAD_SYMBOL)
6063 fputs (" SYMBOL", stdout);
6064 break;
6065 case ODK_HWPATCH:
6066 fputs (" HWPATCH ", stdout);
6067 if (option->info & OHW_R4KEOP)
6068 fputs (" R4KEOP", stdout);
6069 if (option->info & OHW_R8KPFETCH)
6070 fputs (" R8KPFETCH", stdout);
6071 if (option->info & OHW_R5KEOP)
6072 fputs (" R5KEOP", stdout);
6073 if (option->info & OHW_R5KCVTL)
6074 fputs (" R5KCVTL", stdout);
6075 break;
6076 case ODK_FILL:
6077 fputs (" FILL ", stdout);
6078 /* XXX Print content of info word? */
6079 break;
6080 case ODK_TAGS:
6081 fputs (" TAGS ", stdout);
6082 /* XXX Print content of info word? */
6083 break;
6084 case ODK_HWAND:
6085 fputs (" HWAND ", stdout);
6086 if (option->info & OHWA0_R4KEOP_CHECKED)
6087 fputs (" R4KEOP_CHECKED", stdout);
6088 if (option->info & OHWA0_R4KEOP_CLEAN)
6089 fputs (" R4KEOP_CLEAN", stdout);
6090 break;
6091 case ODK_HWOR:
6092 fputs (" HWOR ", stdout);
6093 if (option->info & OHWA0_R4KEOP_CHECKED)
6094 fputs (" R4KEOP_CHECKED", stdout);
6095 if (option->info & OHWA0_R4KEOP_CLEAN)
6096 fputs (" R4KEOP_CLEAN", stdout);
6097 break;
6098 case ODK_GP_GROUP:
6099 printf (" GP_GROUP %#06lx self-contained %#06lx",
6100 option->info & OGP_GROUP,
6101 (option->info & OGP_SELF) >> 16);
6102 break;
6103 case ODK_IDENT:
6104 printf (" IDENT %#06lx self-contained %#06lx",
6105 option->info & OGP_GROUP,
6106 (option->info & OGP_SELF) >> 16);
6107 break;
6108 default:
6109 /* This shouldn't happen. */
6110 printf (" %3d ??? %d %lx",
6111 option->kind, option->section, option->info);
6112 break;
6113 }
6114
6115 len = sizeof (*eopt);
6116 while (len < option->size)
6117 if (((char *) option)[len] >= ' '
6118 && ((char *) option)[len] < 0x7f)
6119 printf ("%c", ((char *) option)[len++]);
6120 else
6121 printf ("\\%03o", ((char *) option)[len++]);
6122
6123 fputs ("\n", stdout);
6124 ++option;
6125 }
6126
6127 free (eopt);
6128 }
6129
6130 if (conflicts_offset != 0 && conflictsno != 0)
6131 {
9ea033b2
NC
6132 Elf32_External_Conflict * econf32;
6133 Elf64_External_Conflict * econf64;
6134 Elf32_Conflict * iconf;
252b5132
RH
6135 size_t cnt;
6136
6137 if (dynamic_symbols == NULL)
6138 {
6139 error (_("conflict list with without table"));
6140 return 0;
6141 }
6142
6143 iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (*iconf));
6144 if (iconf == NULL)
6145 {
6146 error (_("Out of memory"));
6147 return 0;
6148 }
6149
9ea033b2 6150 if (is_32bit_elf)
252b5132
RH
6151 {
6152 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf32),
6153 econf32, Elf32_External_Conflict *, "conflict");
6154
6155 for (cnt = 0; cnt < conflictsno; ++cnt)
6156 iconf[cnt] = BYTE_GET (econf32[cnt]);
6157 }
6158 else
6159 {
6160 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf64),
6161 econf64, Elf64_External_Conflict *, "conflict");
6162
6163 for (cnt = 0; cnt < conflictsno; ++cnt)
6164 iconf[cnt] = BYTE_GET (econf64[cnt]);
6165 }
6166
6167 printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
6168 puts (_(" Num: Index Value Name"));
6169
6170 for (cnt = 0; cnt < conflictsno; ++cnt)
6171 {
19936277 6172 Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
252b5132
RH
6173
6174 printf ("%5u: %8lu %#10lx %s\n",
6175 cnt, iconf[cnt], (unsigned long) psym->st_value,
6176 dynamic_strings + psym->st_name);
6177 }
6178
6179
6180 free (iconf);
6181 }
6182
6183 return 1;
6184}
6185
6186static int
6187process_arch_specific (file)
9ea033b2 6188 FILE * file;
252b5132
RH
6189{
6190 switch (elf_header.e_machine)
6191 {
6192 case EM_MIPS:
6193 case EM_MIPS_RS4_BE:
6194 return process_mips_specific (file);
6195 break;
6196 default:
6197 break;
6198 }
6199 return 1;
6200}
6201
6202static int
6203get_file_header (file)
6204 FILE * file;
6205{
9ea033b2
NC
6206 /* Read in the identity array. */
6207 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
6208 return 0;
6209
9ea033b2
NC
6210 /* Determine how to read the rest of the header. */
6211 switch (elf_header.e_ident [EI_DATA])
6212 {
6213 default: /* fall through */
6214 case ELFDATANONE: /* fall through */
6215 case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
6216 case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
6217 }
6218
6219 /* For now we only support 32 bit and 64 bit ELF files. */
6220 is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
6221
6222 /* Read in the rest of the header. */
6223 if (is_32bit_elf)
6224 {
6225 Elf32_External_Ehdr ehdr32;
252b5132 6226
9ea033b2
NC
6227 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
6228 return 0;
6229
6230 elf_header.e_type = BYTE_GET (ehdr32.e_type);
6231 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
6232 elf_header.e_version = BYTE_GET (ehdr32.e_version);
6233 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
6234 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
6235 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
6236 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
6237 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
6238 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
6239 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
6240 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
6241 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
6242 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
6243 }
252b5132 6244 else
9ea033b2
NC
6245 {
6246 Elf64_External_Ehdr ehdr64;
6247
6248 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
6249 return 0;
6250
6251 elf_header.e_type = BYTE_GET (ehdr64.e_type);
6252 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
6253 elf_header.e_version = BYTE_GET (ehdr64.e_version);
6254 elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry);
6255 elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff);
6256 elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff);
6257 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
6258 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
6259 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
6260 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
6261 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
6262 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
6263 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
6264 }
252b5132
RH
6265
6266 return 1;
6267}
6268
6269static void
6270process_file (file_name)
6271 char * file_name;
6272{
6273 FILE * file;
6274 struct stat statbuf;
6275 unsigned int i;
6276
6277 if (stat (file_name, & statbuf) < 0)
6278 {
6279 error (_("Cannot stat input file %s.\n"), file_name);
6280 return;
6281 }
6282
6283 file = fopen (file_name, "rb");
6284 if (file == NULL)
6285 {
6286 error (_("Input file %s not found.\n"), file_name);
6287 return;
6288 }
6289
6290 if (! get_file_header (file))
6291 {
6292 error (_("%s: Failed to read file header\n"), file_name);
6293 fclose (file);
6294 return;
6295 }
6296
6297 /* Initialise per file variables. */
6298 for (i = NUM_ELEM (version_info); i--;)
6299 version_info[i] = 0;
6300
6301 for (i = NUM_ELEM (dynamic_info); i--;)
6302 dynamic_info[i] = 0;
6303
6304 /* Process the file. */
6305 if (show_name)
6306 printf (_("\nFile: %s\n"), file_name);
6307
6308 if (! process_file_header ())
6309 {
6310 fclose (file);
6311 return;
6312 }
6313
6314 process_section_headers (file);
6315
6316 process_program_headers (file);
6317
6318 process_dynamic_segment (file);
6319
6320 process_relocs (file);
6321
6322 process_symbol_table (file);
6323
6324 process_syminfo (file);
6325
6326 process_version_sections (file);
6327
6328 process_section_contents (file);
6329
6330 process_arch_specific (file);
6331
6332 fclose (file);
6333
6334 if (section_headers)
6335 {
6336 free (section_headers);
6337 section_headers = NULL;
6338 }
6339
6340 if (string_table)
6341 {
6342 free (string_table);
6343 string_table = NULL;
6344 }
6345
6346 if (dynamic_strings)
6347 {
6348 free (dynamic_strings);
6349 dynamic_strings = NULL;
6350 }
6351
6352 if (dynamic_symbols)
6353 {
6354 free (dynamic_symbols);
6355 dynamic_symbols = NULL;
19936277 6356 num_dynamic_syms = 0;
252b5132
RH
6357 }
6358
6359 if (dynamic_syminfo)
6360 {
6361 free (dynamic_syminfo);
6362 dynamic_syminfo = NULL;
6363 }
6364}
6365
6366#ifdef SUPPORT_DISASSEMBLY
6367/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2
NC
6368 fix this so that we insert symbolic addresses here, esp for GOT/PLT
6369 symbols */
252b5132
RH
6370
6371void
6372print_address (unsigned int addr, FILE * outfile)
6373{
6374 fprintf (outfile,"0x%8.8x", addr);
6375}
6376
6377/* Needed by the i386 disassembler. */
6378void
6379db_task_printsym (unsigned int addr)
6380{
6381 print_address (addr, stderr);
6382}
6383#endif
6384
6385int
6386main (argc, argv)
6387 int argc;
6388 char ** argv;
6389{
6390#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
6391 setlocale (LC_MESSAGES, "");
6392#endif
6393 bindtextdomain (PACKAGE, LOCALEDIR);
6394 textdomain (PACKAGE);
6395
6396 parse_args (argc, argv);
6397
6398 if (optind < (argc - 1))
6399 show_name = 1;
6400
6401 while (optind < argc)
6402 process_file (argv [optind ++]);
6403
6404 if (dump_sects != NULL)
6405 free (dump_sects);
6406
6407 return 0;
6408}