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