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