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