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