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