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