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