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