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