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