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