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