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