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