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