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