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