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