]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
* merge.c (struct sec_merge_hash_entry): Add u.entsize and u.suffix
[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
e58d53af
L
3414 if (!do_unwind)
3415 return 1;
3416
f1467e33
L
3417 if (elf_header.e_machine != EM_IA_64)
3418 {
3419 printf (_("\nThere are no unwind sections in this file.\n"));
3420 return 1;
3421 }
3422
4d6ed7c8
NC
3423 memset (& aux, 0, sizeof (aux));
3424
3425 addr_size = is_32bit_elf ? 4 : 8;
3426
4d6ed7c8
NC
3427 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
3428 {
3429 if (sec->sh_type == SHT_SYMTAB)
3430 {
3431 aux.nsyms = sec->sh_size / sec->sh_entsize;
3432 aux.symtab = GET_ELF_SYMBOLS (file, sec->sh_offset, aux.nsyms);
3433
3434 strsec = section_headers + sec->sh_link;
3435 aux.strtab_size = strsec->sh_size;
3436 GET_DATA_ALLOC (strsec->sh_offset, aux.strtab_size,
78f4a3f7 3437 aux.strtab, char *, "string table");
4d6ed7c8
NC
3438 }
3439 else if (sec->sh_type == SHT_IA_64_UNWIND)
3440 unwsec = sec;
3441 else if (strcmp (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info) == 0)
3442 {
3443 aux.info_size = sec->sh_size;
3444 aux.info_addr = sec->sh_addr;
ecd03389 3445 GET_DATA_ALLOC (sec->sh_offset, aux.info_size, aux.info,
4d6ed7c8
NC
3446 char *, "unwind info");
3447 }
3448 }
3449
3450 if (unwsec)
3451 {
3452 printf (_("\nUnwind section "));
3453
3454 if (string_table == NULL)
3455 printf ("%d", unwsec->sh_name);
3456 else
3457 printf ("'%s'", SECTION_NAME (unwsec));
3458
3459 printf (_(" at offset 0x%lx contains %lu entries:\n"),
88ec60c7 3460 unwsec->sh_offset, (unsigned long) (unwsec->sh_size / (3 * addr_size)));
4d6ed7c8
NC
3461
3462 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
3463
3464 if (aux.table_len > 0)
3465 dump_ia64_unwind (& aux);
3466 }
3467 else
3468 printf (_("\nThere are no unwind sections in this file.\n"));
3469
3470 if (aux.table)
3471 free ((char *) aux.table);
3472 if (aux.info)
3473 free ((char *) aux.info);
3474 if (aux.symtab)
3475 free (aux.symtab);
3476 if (aux.strtab)
3477 free ((char *) aux.strtab);
3478
3479 return 1;
3480}
3481
252b5132
RH
3482static void
3483dynamic_segment_mips_val (entry)
3484 Elf_Internal_Dyn * entry;
3485{
3486 switch (entry->d_tag)
3487 {
3488 case DT_MIPS_FLAGS:
3489 if (entry->d_un.d_val == 0)
3490 printf ("NONE\n");
3491 else
3492 {
3493 static const char * opts[] =
3494 {
3495 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
3496 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
3497 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
3498 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
3499 "RLD_ORDER_SAFE"
3500 };
3501 unsigned int cnt;
3502 int first = 1;
3503 for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
3504 if (entry->d_un.d_val & (1 << cnt))
3505 {
3506 printf ("%s%s", first ? "" : " ", opts[cnt]);
3507 first = 0;
3508 }
3509 puts ("");
3510 }
3511 break;
103f02d3 3512
252b5132
RH
3513 case DT_MIPS_IVERSION:
3514 if (dynamic_strings != NULL)
3515 printf ("Interface Version: %s\n",
3516 dynamic_strings + entry->d_un.d_val);
3517 else
3518 printf ("%ld\n", (long) entry->d_un.d_ptr);
3519 break;
103f02d3 3520
252b5132
RH
3521 case DT_MIPS_TIME_STAMP:
3522 {
3523 char timebuf[20];
50da7a9c
NC
3524 struct tm * tmp;
3525
252b5132 3526 time_t time = entry->d_un.d_val;
50da7a9c
NC
3527 tmp = gmtime (&time);
3528 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
3529 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
3530 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
3531 printf ("Time Stamp: %s\n", timebuf);
3532 }
3533 break;
103f02d3 3534
252b5132
RH
3535 case DT_MIPS_RLD_VERSION:
3536 case DT_MIPS_LOCAL_GOTNO:
3537 case DT_MIPS_CONFLICTNO:
3538 case DT_MIPS_LIBLISTNO:
3539 case DT_MIPS_SYMTABNO:
3540 case DT_MIPS_UNREFEXTNO:
3541 case DT_MIPS_HIPAGENO:
3542 case DT_MIPS_DELTA_CLASS_NO:
3543 case DT_MIPS_DELTA_INSTANCE_NO:
3544 case DT_MIPS_DELTA_RELOC_NO:
3545 case DT_MIPS_DELTA_SYM_NO:
3546 case DT_MIPS_DELTA_CLASSSYM_NO:
3547 case DT_MIPS_COMPACT_SIZE:
3548 printf ("%ld\n", (long) entry->d_un.d_ptr);
3549 break;
103f02d3
UD
3550
3551 default:
3552 printf ("%#lx\n", (long) entry->d_un.d_ptr);
3553 }
3554}
3555
3556
3557static void
3558dynamic_segment_parisc_val (entry)
3559 Elf_Internal_Dyn * entry;
3560{
3561 switch (entry->d_tag)
3562 {
3563 case DT_HP_DLD_FLAGS:
3564 {
3565 static struct
3566 {
3567 long int bit;
5e220199
NC
3568 const char * str;
3569 }
3570 flags[] =
3571 {
3572 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
3573 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
3574 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
3575 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
3576 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
3577 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
3578 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
3579 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
3580 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
3581 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
3582 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" }
3583 };
103f02d3 3584 int first = 1;
5e220199 3585 size_t cnt;
f7a99963 3586 bfd_vma val = entry->d_un.d_val;
103f02d3
UD
3587
3588 for (cnt = 0; cnt < sizeof (flags) / sizeof (flags[0]); ++cnt)
3589 if (val & flags[cnt].bit)
30800947
NC
3590 {
3591 if (! first)
3592 putchar (' ');
3593 fputs (flags[cnt].str, stdout);
3594 first = 0;
3595 val ^= flags[cnt].bit;
3596 }
76da6bbe 3597
103f02d3 3598 if (val != 0 || first)
f7a99963
NC
3599 {
3600 if (! first)
3601 putchar (' ');
3602 print_vma (val, HEX);
3603 }
103f02d3
UD
3604 }
3605 break;
76da6bbe 3606
252b5132 3607 default:
f7a99963
NC
3608 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
3609 break;
252b5132
RH
3610 }
3611}
3612
252b5132 3613static int
9ea033b2 3614get_32bit_dynamic_segment (file)
252b5132
RH
3615 FILE * file;
3616{
9ea033b2
NC
3617 Elf32_External_Dyn * edyn;
3618 Elf_Internal_Dyn * entry;
3619 bfd_size_type i;
103f02d3 3620
9ea033b2
NC
3621 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
3622 edyn, Elf32_External_Dyn *, "dynamic segment");
103f02d3 3623
9ea033b2
NC
3624 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
3625 how large this .dynamic is now. We can do this even before the byte
3626 swapping since the DT_NULL tag is recognizable. */
3627 dynamic_size = 0;
3628 while (*(Elf32_Word *) edyn [dynamic_size++].d_tag != DT_NULL)
3629 ;
252b5132 3630
9ea033b2
NC
3631 dynamic_segment = (Elf_Internal_Dyn *)
3632 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
3633
3634 if (dynamic_segment == NULL)
252b5132 3635 {
9ea033b2
NC
3636 error (_("Out of memory\n"));
3637 free (edyn);
3638 return 0;
3639 }
252b5132 3640
9ea033b2
NC
3641 for (i = 0, entry = dynamic_segment;
3642 i < dynamic_size;
3643 i ++, entry ++)
3644 {
3645 entry->d_tag = BYTE_GET (edyn [i].d_tag);
3646 entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
252b5132
RH
3647 }
3648
9ea033b2
NC
3649 free (edyn);
3650
3651 return 1;
3652}
3653
3654static int
3655get_64bit_dynamic_segment (file)
3656 FILE * file;
3657{
3658 Elf64_External_Dyn * edyn;
3659 Elf_Internal_Dyn * entry;
3660 bfd_size_type i;
103f02d3 3661
252b5132 3662 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
9ea033b2 3663 edyn, Elf64_External_Dyn *, "dynamic segment");
103f02d3 3664
252b5132 3665 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
9ea033b2 3666 how large this .dynamic is now. We can do this even before the byte
252b5132
RH
3667 swapping since the DT_NULL tag is recognizable. */
3668 dynamic_size = 0;
9ea033b2 3669 while (*(bfd_vma *) edyn [dynamic_size ++].d_tag != DT_NULL)
252b5132
RH
3670 ;
3671
3672 dynamic_segment = (Elf_Internal_Dyn *)
3673 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
3674
3675 if (dynamic_segment == NULL)
3676 {
3677 error (_("Out of memory\n"));
3678 free (edyn);
3679 return 0;
3680 }
3681
3682 for (i = 0, entry = dynamic_segment;
3683 i < dynamic_size;
3684 i ++, entry ++)
3685 {
9ea033b2
NC
3686 entry->d_tag = BYTE_GET8 (edyn [i].d_tag);
3687 entry->d_un.d_val = BYTE_GET8 (edyn [i].d_un.d_val);
252b5132
RH
3688 }
3689
3690 free (edyn);
3691
9ea033b2
NC
3692 return 1;
3693}
3694
d1133906
NC
3695static const char *
3696get_dynamic_flags (flags)
3697 bfd_vma flags;
3698{
3699 static char buff [64];
3700 while (flags)
3701 {
3702 bfd_vma flag;
3703
3704 flag = flags & - flags;
3705 flags &= ~ flag;
3706
3707 switch (flag)
3708 {
3709 case DF_ORIGIN: strcat (buff, "ORIGIN "); break;
3710 case DF_SYMBOLIC: strcat (buff, "SYMBOLIC "); break;
3711 case DF_TEXTREL: strcat (buff, "TEXTREL "); break;
3712 case DF_BIND_NOW: strcat (buff, "BIND_NOW "); break;
305c7206 3713 default: strcat (buff, "unknown "); break;
d1133906
NC
3714 }
3715 }
305c7206 3716 return buff;
d1133906
NC
3717}
3718
9ea033b2
NC
3719/* Parse and display the contents of the dynamic segment. */
3720static int
3721process_dynamic_segment (file)
3722 FILE * file;
3723{
3724 Elf_Internal_Dyn * entry;
3725 bfd_size_type i;
3726
3727 if (dynamic_size == 0)
3728 {
3729 if (do_dynamic)
3730 printf (_("\nThere is no dynamic segment in this file.\n"));
3731
3732 return 1;
3733 }
3734
3735 if (is_32bit_elf)
3736 {
3737 if (! get_32bit_dynamic_segment (file))
3738 return 0;
3739 }
3740 else if (! get_64bit_dynamic_segment (file))
3741 return 0;
3742
252b5132
RH
3743 /* Find the appropriate symbol table. */
3744 if (dynamic_symbols == NULL)
3745 {
3746 for (i = 0, entry = dynamic_segment;
3747 i < dynamic_size;
3748 ++i, ++ entry)
3749 {
3750 unsigned long offset;
252b5132
RH
3751
3752 if (entry->d_tag != DT_SYMTAB)
3753 continue;
3754
3755 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
3756
3757 /* Since we do not know how big the symbol table is,
3758 we default to reading in the entire file (!) and
3759 processing that. This is overkill, I know, but it
3760 should work. */
252b5132
RH
3761 offset = entry->d_un.d_val - loadaddr;
3762
3763 if (fseek (file, 0, SEEK_END))
3764 error (_("Unable to seek to end of file!"));
3765
9ea033b2 3766 if (is_32bit_elf)
19936277 3767 num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
9ea033b2 3768 else
19936277 3769 num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf64_External_Sym);
252b5132 3770
19936277 3771 if (num_dynamic_syms < 1)
252b5132
RH
3772 {
3773 error (_("Unable to determine the number of symbols to load\n"));
3774 continue;
3775 }
3776
19936277 3777 dynamic_symbols = GET_ELF_SYMBOLS (file, offset, num_dynamic_syms);
252b5132
RH
3778 }
3779 }
3780
3781 /* Similarly find a string table. */
3782 if (dynamic_strings == NULL)
3783 {
3784 for (i = 0, entry = dynamic_segment;
3785 i < dynamic_size;
3786 ++i, ++ entry)
3787 {
3788 unsigned long offset;
3789 long str_tab_len;
3790
3791 if (entry->d_tag != DT_STRTAB)
3792 continue;
3793
3794 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
3795
3796 /* Since we do not know how big the string table is,
3797 we default to reading in the entire file (!) and
3798 processing that. This is overkill, I know, but it
3799 should work. */
3800
3801 offset = entry->d_un.d_val - loadaddr;
3802 if (fseek (file, 0, SEEK_END))
3803 error (_("Unable to seek to end of file\n"));
3804 str_tab_len = ftell (file) - offset;
3805
3806 if (str_tab_len < 1)
3807 {
3808 error
3809 (_("Unable to determine the length of the dynamic string table\n"));
3810 continue;
3811 }
3812
3813 GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
3814 "dynamic string table");
3815
3816 break;
3817 }
3818 }
3819
3820 /* And find the syminfo section if available. */
3821 if (dynamic_syminfo == NULL)
3822 {
3823 unsigned int syminsz = 0;
3824
3825 for (i = 0, entry = dynamic_segment;
3826 i < dynamic_size;
3827 ++i, ++ entry)
3828 {
3829 if (entry->d_tag == DT_SYMINENT)
3830 {
3831 /* Note: these braces are necessary to avoid a syntax
3832 error from the SunOS4 C compiler. */
3833 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
3834 }
3835 else if (entry->d_tag == DT_SYMINSZ)
3836 syminsz = entry->d_un.d_val;
3837 else if (entry->d_tag == DT_SYMINFO)
3838 dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
3839 }
3840
3841 if (dynamic_syminfo_offset != 0 && syminsz != 0)
3842 {
9ea033b2
NC
3843 Elf_External_Syminfo * extsyminfo;
3844 Elf_Internal_Syminfo * syminfo;
252b5132
RH
3845
3846 /* There is a syminfo section. Read the data. */
3847 GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
3848 Elf_External_Syminfo *, "symbol information");
3849
3850 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
3851 if (dynamic_syminfo == NULL)
3852 {
3853 error (_("Out of memory\n"));
3854 return 0;
3855 }
3856
3857 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
3858 for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
3859 ++i, ++syminfo)
3860 {
3861 syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
3862 syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
3863 }
3864
3865 free (extsyminfo);
3866 }
3867 }
3868
3869 if (do_dynamic && dynamic_addr)
789be9f7
ILT
3870 printf (_("\nDynamic segment at offset 0x%x contains %ld entries:\n"),
3871 dynamic_addr, (long) dynamic_size);
252b5132
RH
3872 if (do_dynamic)
3873 printf (_(" Tag Type Name/Value\n"));
3874
3875 for (i = 0, entry = dynamic_segment;
3876 i < dynamic_size;
3877 i++, entry ++)
3878 {
3879 if (do_dynamic)
f7a99963 3880 {
f3485b74 3881 const char * dtype;
e699b9ff 3882
f7a99963
NC
3883 putchar (' ');
3884 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
3885 dtype = get_dynamic_type (entry->d_tag);
3886 printf (" (%s)%*s", dtype,
3887 ((is_32bit_elf ? 27 : 19)
3888 - (int) strlen (dtype)),
f7a99963
NC
3889 " ");
3890 }
252b5132
RH
3891
3892 switch (entry->d_tag)
3893 {
d1133906
NC
3894 case DT_FLAGS:
3895 if (do_dynamic)
305c7206 3896 printf ("%s", get_dynamic_flags (entry->d_un.d_val));
d1133906 3897 break;
76da6bbe 3898
252b5132
RH
3899 case DT_AUXILIARY:
3900 case DT_FILTER:
019148e4
L
3901 case DT_CONFIG:
3902 case DT_DEPAUDIT:
3903 case DT_AUDIT:
252b5132
RH
3904 if (do_dynamic)
3905 {
019148e4
L
3906 switch (entry->d_tag)
3907 {
3908 case DT_AUXILIARY:
3909 printf (_("Auxiliary library"));
3910 break;
3911
3912 case DT_FILTER:
3913 printf (_("Filter library"));
3914 break;
3915
3916 case DT_CONFIG:
3917 printf (_("Configuration file"));
3918 break;
3919
3920 case DT_DEPAUDIT:
3921 printf (_("Dependency audit library"));
3922 break;
3923
3924 case DT_AUDIT:
3925 printf (_("Audit library"));
3926 break;
3927 }
252b5132
RH
3928
3929 if (dynamic_strings)
3930 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
3931 else
f7a99963
NC
3932 {
3933 printf (": ");
3934 print_vma (entry->d_un.d_val, PREFIX_HEX);
3935 putchar ('\n');
3936 }
252b5132
RH
3937 }
3938 break;
3939
dcefbbbd 3940 case DT_FEATURE:
252b5132
RH
3941 if (do_dynamic)
3942 {
3943 printf (_("Flags:"));
3944 if (entry->d_un.d_val == 0)
3945 printf (_(" None\n"));
3946 else
3947 {
3948 unsigned long int val = entry->d_un.d_val;
3949 if (val & DTF_1_PARINIT)
3950 {
3951 printf (" PARINIT");
3952 val ^= DTF_1_PARINIT;
3953 }
dcefbbbd
L
3954 if (val & DTF_1_CONFEXP)
3955 {
3956 printf (" CONFEXP");
3957 val ^= DTF_1_CONFEXP;
3958 }
252b5132
RH
3959 if (val != 0)
3960 printf (" %lx", val);
3961 puts ("");
3962 }
3963 }
3964 break;
3965
3966 case DT_POSFLAG_1:
3967 if (do_dynamic)
3968 {
3969 printf (_("Flags:"));
3970 if (entry->d_un.d_val == 0)
3971 printf (_(" None\n"));
3972 else
3973 {
3974 unsigned long int val = entry->d_un.d_val;
3975 if (val & DF_P1_LAZYLOAD)
3976 {
3977 printf (" LAZYLOAD");
3978 val ^= DF_P1_LAZYLOAD;
3979 }
3980 if (val & DF_P1_GROUPPERM)
3981 {
3982 printf (" GROUPPERM");
3983 val ^= DF_P1_GROUPPERM;
3984 }
3985 if (val != 0)
3986 printf (" %lx", val);
3987 puts ("");
3988 }
3989 }
3990 break;
3991
3992 case DT_FLAGS_1:
3993 if (do_dynamic)
3994 {
3995 printf (_("Flags:"));
3996 if (entry->d_un.d_val == 0)
3997 printf (_(" None\n"));
3998 else
3999 {
4000 unsigned long int val = entry->d_un.d_val;
4001 if (val & DF_1_NOW)
4002 {
4003 printf (" NOW");
4004 val ^= DF_1_NOW;
4005 }
4006 if (val & DF_1_GLOBAL)
4007 {
4008 printf (" GLOBAL");
4009 val ^= DF_1_GLOBAL;
4010 }
4011 if (val & DF_1_GROUP)
4012 {
4013 printf (" GROUP");
4014 val ^= DF_1_GROUP;
4015 }
4016 if (val & DF_1_NODELETE)
4017 {
4018 printf (" NODELETE");
4019 val ^= DF_1_NODELETE;
4020 }
4021 if (val & DF_1_LOADFLTR)
4022 {
4023 printf (" LOADFLTR");
4024 val ^= DF_1_LOADFLTR;
4025 }
4026 if (val & DF_1_INITFIRST)
4027 {
4028 printf (" INITFIRST");
4029 val ^= DF_1_INITFIRST;
4030 }
4031 if (val & DF_1_NOOPEN)
4032 {
4033 printf (" NOOPEN");
4034 val ^= DF_1_NOOPEN;
4035 }
4036 if (val & DF_1_ORIGIN)
4037 {
4038 printf (" ORIGIN");
4039 val ^= DF_1_ORIGIN;
4040 }
4041 if (val & DF_1_DIRECT)
4042 {
4043 printf (" DIRECT");
4044 val ^= DF_1_DIRECT;
4045 }
4046 if (val & DF_1_TRANS)
4047 {
4048 printf (" TRANS");
4049 val ^= DF_1_TRANS;
4050 }
4051 if (val & DF_1_INTERPOSE)
4052 {
4053 printf (" INTERPOSE");
4054 val ^= DF_1_INTERPOSE;
4055 }
f7db6139 4056 if (val & DF_1_NODEFLIB)
dcefbbbd 4057 {
f7db6139
L
4058 printf (" NODEFLIB");
4059 val ^= DF_1_NODEFLIB;
dcefbbbd
L
4060 }
4061 if (val & DF_1_NODUMP)
4062 {
4063 printf (" NODUMP");
4064 val ^= DF_1_NODUMP;
4065 }
4066 if (val & DF_1_CONLFAT)
4067 {
4068 printf (" CONLFAT");
4069 val ^= DF_1_CONLFAT;
4070 }
252b5132
RH
4071 if (val != 0)
4072 printf (" %lx", val);
4073 puts ("");
4074 }
4075 }
4076 break;
4077
4078 case DT_PLTREL:
4079 if (do_dynamic)
4080 puts (get_dynamic_type (entry->d_un.d_val));
4081 break;
4082
4083 case DT_NULL :
4084 case DT_NEEDED :
4085 case DT_PLTGOT :
4086 case DT_HASH :
4087 case DT_STRTAB :
4088 case DT_SYMTAB :
4089 case DT_RELA :
4090 case DT_INIT :
4091 case DT_FINI :
4092 case DT_SONAME :
4093 case DT_RPATH :
4094 case DT_SYMBOLIC:
4095 case DT_REL :
4096 case DT_DEBUG :
4097 case DT_TEXTREL :
4098 case DT_JMPREL :
019148e4 4099 case DT_RUNPATH :
252b5132
RH
4100 dynamic_info[entry->d_tag] = entry->d_un.d_val;
4101
4102 if (do_dynamic)
4103 {
4104 char * name;
4105
4106 if (dynamic_strings == NULL)
4107 name = NULL;
4108 else
4109 name = dynamic_strings + entry->d_un.d_val;
4110
4111 if (name)
4112 {
4113 switch (entry->d_tag)
4114 {
4115 case DT_NEEDED:
4116 printf (_("Shared library: [%s]"), name);
4117
f7a99963
NC
4118 if (strcmp (name, program_interpreter) == 0)
4119 printf (_(" program interpreter"));
252b5132
RH
4120 break;
4121
4122 case DT_SONAME:
f7a99963 4123 printf (_("Library soname: [%s]"), name);
252b5132
RH
4124 break;
4125
4126 case DT_RPATH:
f7a99963 4127 printf (_("Library rpath: [%s]"), name);
252b5132
RH
4128 break;
4129
019148e4
L
4130 case DT_RUNPATH:
4131 printf (_("Library runpath: [%s]"), name);
4132 break;
4133
252b5132 4134 default:
f7a99963
NC
4135 print_vma (entry->d_un.d_val, PREFIX_HEX);
4136 break;
252b5132
RH
4137 }
4138 }
4139 else
f7a99963
NC
4140 print_vma (entry->d_un.d_val, PREFIX_HEX);
4141
4142 putchar ('\n');
252b5132
RH
4143 }
4144 break;
4145
4146 case DT_PLTRELSZ:
4147 case DT_RELASZ :
4148 case DT_STRSZ :
4149 case DT_RELSZ :
4150 case DT_RELAENT :
4151 case DT_SYMENT :
4152 case DT_RELENT :
4153 case DT_PLTPADSZ:
4154 case DT_MOVEENT :
4155 case DT_MOVESZ :
4156 case DT_INIT_ARRAYSZ:
4157 case DT_FINI_ARRAYSZ:
4158 if (do_dynamic)
f7a99963
NC
4159 {
4160 print_vma (entry->d_un.d_val, UNSIGNED);
4161 printf (" (bytes)\n");
4162 }
252b5132
RH
4163 break;
4164
4165 case DT_VERDEFNUM:
4166 case DT_VERNEEDNUM:
4167 case DT_RELACOUNT:
4168 case DT_RELCOUNT:
4169 if (do_dynamic)
f7a99963
NC
4170 {
4171 print_vma (entry->d_un.d_val, UNSIGNED);
4172 putchar ('\n');
4173 }
252b5132
RH
4174 break;
4175
4176 case DT_SYMINSZ:
4177 case DT_SYMINENT:
4178 case DT_SYMINFO:
4179 case DT_USED:
4180 case DT_INIT_ARRAY:
4181 case DT_FINI_ARRAY:
4182 if (do_dynamic)
4183 {
4184 if (dynamic_strings != NULL && entry->d_tag == DT_USED)
4185 {
4186 char * name;
4187
4188 name = dynamic_strings + entry->d_un.d_val;
4189
4190 if (* name)
4191 {
4192 printf (_("Not needed object: [%s]\n"), name);
4193 break;
4194 }
4195 }
103f02d3 4196
f7a99963
NC
4197 print_vma (entry->d_un.d_val, PREFIX_HEX);
4198 putchar ('\n');
252b5132
RH
4199 }
4200 break;
4201
4202 case DT_BIND_NOW:
4203 /* The value of this entry is ignored. */
4204 break;
103f02d3 4205
252b5132
RH
4206 default:
4207 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
4208 version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
4209 entry->d_un.d_val;
4210
4211 if (do_dynamic)
4212 {
4213 switch (elf_header.e_machine)
4214 {
4215 case EM_MIPS:
4216 case EM_MIPS_RS4_BE:
4217 dynamic_segment_mips_val (entry);
4218 break;
103f02d3
UD
4219 case EM_PARISC:
4220 dynamic_segment_parisc_val (entry);
4221 break;
252b5132 4222 default:
f7a99963
NC
4223 print_vma (entry->d_un.d_val, PREFIX_HEX);
4224 putchar ('\n');
252b5132
RH
4225 }
4226 }
4227 break;
4228 }
4229 }
4230
4231 return 1;
4232}
4233
4234static char *
4235get_ver_flags (flags)
4236 unsigned int flags;
4237{
4238 static char buff [32];
4239
4240 buff[0] = 0;
4241
4242 if (flags == 0)
4243 return _("none");
4244
4245 if (flags & VER_FLG_BASE)
4246 strcat (buff, "BASE ");
4247
4248 if (flags & VER_FLG_WEAK)
4249 {
4250 if (flags & VER_FLG_BASE)
4251 strcat (buff, "| ");
4252
4253 strcat (buff, "WEAK ");
4254 }
4255
4256 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
4257 strcat (buff, "| <unknown>");
4258
4259 return buff;
4260}
4261
4262/* Display the contents of the version sections. */
4263static int
4264process_version_sections (file)
4265 FILE * file;
4266{
4267 Elf32_Internal_Shdr * section;
4268 unsigned i;
4269 int found = 0;
4270
4271 if (! do_version)
4272 return 1;
4273
4274 for (i = 0, section = section_headers;
4275 i < elf_header.e_shnum;
4276 i++, section ++)
4277 {
4278 switch (section->sh_type)
4279 {
4280 case SHT_GNU_verdef:
4281 {
4282 Elf_External_Verdef * edefs;
4283 unsigned int idx;
4284 unsigned int cnt;
4285
4286 found = 1;
4287
4288 printf
4289 (_("\nVersion definition section '%s' contains %ld entries:\n"),
4290 SECTION_NAME (section), section->sh_info);
4291
4292 printf (_(" Addr: 0x"));
4293 printf_vma (section->sh_addr);
4294 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 4295 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
4296 SECTION_NAME (section_headers + section->sh_link));
4297
4298 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
4299 edefs, Elf_External_Verdef *,
4300 "version definition section");
4301
4302 for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
4303 {
4304 char * vstart;
4305 Elf_External_Verdef * edef;
4306 Elf_Internal_Verdef ent;
4307 Elf_External_Verdaux * eaux;
4308 Elf_Internal_Verdaux aux;
4309 int j;
4310 int isum;
103f02d3 4311
252b5132
RH
4312 vstart = ((char *) edefs) + idx;
4313
4314 edef = (Elf_External_Verdef *) vstart;
4315
4316 ent.vd_version = BYTE_GET (edef->vd_version);
4317 ent.vd_flags = BYTE_GET (edef->vd_flags);
4318 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
4319 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
4320 ent.vd_hash = BYTE_GET (edef->vd_hash);
4321 ent.vd_aux = BYTE_GET (edef->vd_aux);
4322 ent.vd_next = BYTE_GET (edef->vd_next);
4323
4324 printf (_(" %#06x: Rev: %d Flags: %s"),
4325 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
4326
4327 printf (_(" Index: %d Cnt: %d "),
4328 ent.vd_ndx, ent.vd_cnt);
4329
4330 vstart += ent.vd_aux;
4331
4332 eaux = (Elf_External_Verdaux *) vstart;
4333
4334 aux.vda_name = BYTE_GET (eaux->vda_name);
4335 aux.vda_next = BYTE_GET (eaux->vda_next);
4336
4337 if (dynamic_strings)
4338 printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
4339 else
4340 printf (_("Name index: %ld\n"), aux.vda_name);
4341
4342 isum = idx + ent.vd_aux;
4343
4344 for (j = 1; j < ent.vd_cnt; j ++)
4345 {
4346 isum += aux.vda_next;
4347 vstart += aux.vda_next;
4348
4349 eaux = (Elf_External_Verdaux *) vstart;
4350
4351 aux.vda_name = BYTE_GET (eaux->vda_name);
4352 aux.vda_next = BYTE_GET (eaux->vda_next);
4353
4354 if (dynamic_strings)
4355 printf (_(" %#06x: Parent %d: %s\n"),
4356 isum, j, dynamic_strings + aux.vda_name);
4357 else
4358 printf (_(" %#06x: Parent %d, name index: %ld\n"),
4359 isum, j, aux.vda_name);
4360 }
4361
4362 idx += ent.vd_next;
4363 }
4364
4365 free (edefs);
4366 }
4367 break;
103f02d3 4368
252b5132
RH
4369 case SHT_GNU_verneed:
4370 {
4371 Elf_External_Verneed * eneed;
4372 unsigned int idx;
4373 unsigned int cnt;
4374
4375 found = 1;
4376
4377 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
4378 SECTION_NAME (section), section->sh_info);
4379
4380 printf (_(" Addr: 0x"));
4381 printf_vma (section->sh_addr);
4382 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
1b228002 4383 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
4384 SECTION_NAME (section_headers + section->sh_link));
4385
4386 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
4387 eneed, Elf_External_Verneed *,
4388 "version need section");
4389
4390 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
4391 {
4392 Elf_External_Verneed * entry;
4393 Elf_Internal_Verneed ent;
4394 int j;
4395 int isum;
4396 char * vstart;
4397
4398 vstart = ((char *) eneed) + idx;
4399
4400 entry = (Elf_External_Verneed *) vstart;
4401
4402 ent.vn_version = BYTE_GET (entry->vn_version);
4403 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
4404 ent.vn_file = BYTE_GET (entry->vn_file);
4405 ent.vn_aux = BYTE_GET (entry->vn_aux);
4406 ent.vn_next = BYTE_GET (entry->vn_next);
4407
4408 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
4409
4410 if (dynamic_strings)
4411 printf (_(" File: %s"), dynamic_strings + ent.vn_file);
4412 else
4413 printf (_(" File: %lx"), ent.vn_file);
4414
4415 printf (_(" Cnt: %d\n"), ent.vn_cnt);
4416
4417 vstart += ent.vn_aux;
4418
4419 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
4420 {
4421 Elf_External_Vernaux * eaux;
4422 Elf_Internal_Vernaux aux;
4423
4424 eaux = (Elf_External_Vernaux *) vstart;
4425
4426 aux.vna_hash = BYTE_GET (eaux->vna_hash);
4427 aux.vna_flags = BYTE_GET (eaux->vna_flags);
4428 aux.vna_other = BYTE_GET (eaux->vna_other);
4429 aux.vna_name = BYTE_GET (eaux->vna_name);
4430 aux.vna_next = BYTE_GET (eaux->vna_next);
4431
4432 if (dynamic_strings)
4433 printf (_(" %#06x: Name: %s"),
4434 isum, dynamic_strings + aux.vna_name);
4435 else
4436 printf (_(" %#06x: Name index: %lx"),
4437 isum, aux.vna_name);
4438
4439 printf (_(" Flags: %s Version: %d\n"),
4440 get_ver_flags (aux.vna_flags), aux.vna_other);
4441
4442 isum += aux.vna_next;
4443 vstart += aux.vna_next;
4444 }
4445
4446 idx += ent.vn_next;
4447 }
103f02d3 4448
252b5132
RH
4449 free (eneed);
4450 }
4451 break;
4452
4453 case SHT_GNU_versym:
4454 {
4455 Elf32_Internal_Shdr * link_section;
4456 int total;
4457 int cnt;
4458 unsigned char * edata;
4459 unsigned short * data;
4460 char * strtab;
4461 Elf_Internal_Sym * symbols;
4462 Elf32_Internal_Shdr * string_sec;
4463
4464 link_section = section_headers + section->sh_link;
4465 total = section->sh_size / section->sh_entsize;
4466
4467 found = 1;
4468
9ea033b2
NC
4469 symbols = GET_ELF_SYMBOLS (file, link_section->sh_offset,
4470 link_section->sh_size / link_section->sh_entsize);
252b5132
RH
4471
4472 string_sec = section_headers + link_section->sh_link;
4473
4474 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
4475 strtab, char *, "version string table");
4476
4477 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
4478 SECTION_NAME (section), total);
4479
4480 printf (_(" Addr: "));
4481 printf_vma (section->sh_addr);
4482 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 4483 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
4484 SECTION_NAME (link_section));
4485
4486 GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
4487 - loadaddr,
4488 total * sizeof (short), edata,
4489 unsigned char *, "version symbol data");
4490
4491 data = (unsigned short *) malloc (total * sizeof (short));
4492
4493 for (cnt = total; cnt --;)
4494 data [cnt] = byte_get (edata + cnt * sizeof (short),
4495 sizeof (short));
4496
4497 free (edata);
4498
4499 for (cnt = 0; cnt < total; cnt += 4)
4500 {
4501 int j, nn;
00d93f34 4502 int check_def, check_need;
f3485b74 4503 char * name;
252b5132
RH
4504
4505 printf (" %03x:", cnt);
4506
4507 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
4508 switch (data [cnt + j])
4509 {
4510 case 0:
4511 fputs (_(" 0 (*local*) "), stdout);
4512 break;
4513
4514 case 1:
4515 fputs (_(" 1 (*global*) "), stdout);
4516 break;
4517
4518 default:
4519 nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
4520 data [cnt + j] & 0x8000 ? 'h' : ' ');
4521
00d93f34
JJ
4522 check_def = 1;
4523 check_need = 1;
4524 if (symbols [cnt + j].st_shndx >= SHN_LORESERVE
4525 || section_headers[symbols [cnt + j].st_shndx].sh_type
4526 != SHT_NOBITS)
252b5132 4527 {
00d93f34
JJ
4528 if (symbols [cnt + j].st_shndx == SHN_UNDEF)
4529 check_def = 0;
4530 else
4531 check_need = 0;
252b5132 4532 }
00d93f34
JJ
4533
4534 if (check_need
4535 && version_info [DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132
RH
4536 {
4537 Elf_Internal_Verneed ivn;
4538 unsigned long offset;
4539
4540 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
4541 - loadaddr;
4542
4543 do
4544 {
dd27201e 4545 Elf_Internal_Vernaux ivna;
252b5132
RH
4546 Elf_External_Verneed evn;
4547 Elf_External_Vernaux evna;
dd27201e 4548 unsigned long a_off;
252b5132
RH
4549
4550 GET_DATA (offset, evn, "version need");
4551
4552 ivn.vn_aux = BYTE_GET (evn.vn_aux);
4553 ivn.vn_next = BYTE_GET (evn.vn_next);
4554
4555 a_off = offset + ivn.vn_aux;
4556
4557 do
4558 {
4559 GET_DATA (a_off, evna,
4560 "version need aux (2)");
4561
4562 ivna.vna_next = BYTE_GET (evna.vna_next);
4563 ivna.vna_other = BYTE_GET (evna.vna_other);
4564
4565 a_off += ivna.vna_next;
4566 }
4567 while (ivna.vna_other != data [cnt + j]
4568 && ivna.vna_next != 0);
4569
4570 if (ivna.vna_other == data [cnt + j])
4571 {
4572 ivna.vna_name = BYTE_GET (evna.vna_name);
4573
16062207 4574 name = strtab + ivna.vna_name;
252b5132 4575 nn += printf ("(%s%-*s",
16062207
ILT
4576 name,
4577 12 - (int) strlen (name),
252b5132 4578 ")");
00d93f34 4579 check_def = 0;
252b5132
RH
4580 break;
4581 }
4582
4583 offset += ivn.vn_next;
4584 }
4585 while (ivn.vn_next);
4586 }
00d93f34
JJ
4587
4588 if (check_def && data [cnt + j] != 0x8001
4589 && version_info [DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132
RH
4590 {
4591 Elf_Internal_Verdef ivd;
4592 Elf_External_Verdef evd;
4593 unsigned long offset;
4594
4595 offset = version_info
4596 [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
4597
4598 do
4599 {
4600 GET_DATA (offset, evd, "version def");
4601
4602 ivd.vd_next = BYTE_GET (evd.vd_next);
4603 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
4604
4605 offset += ivd.vd_next;
4606 }
4607 while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
4608 && ivd.vd_next != 0);
4609
4610 if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
4611 {
4612 Elf_External_Verdaux evda;
4613 Elf_Internal_Verdaux ivda;
4614
4615 ivd.vd_aux = BYTE_GET (evd.vd_aux);
4616
4617 GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
4618 evda, "version def aux");
4619
4620 ivda.vda_name = BYTE_GET (evda.vda_name);
4621
16062207 4622 name = strtab + ivda.vda_name;
252b5132 4623 nn += printf ("(%s%-*s",
16062207
ILT
4624 name,
4625 12 - (int) strlen (name),
252b5132
RH
4626 ")");
4627 }
4628 }
4629
4630 if (nn < 18)
4631 printf ("%*c", 18 - nn, ' ');
4632 }
4633
4634 putchar ('\n');
4635 }
4636
4637 free (data);
4638 free (strtab);
4639 free (symbols);
4640 }
4641 break;
103f02d3 4642
252b5132
RH
4643 default:
4644 break;
4645 }
4646 }
4647
4648 if (! found)
4649 printf (_("\nNo version information found in this file.\n"));
4650
4651 return 1;
4652}
4653
d1133906 4654static const char *
252b5132
RH
4655get_symbol_binding (binding)
4656 unsigned int binding;
4657{
4658 static char buff [32];
4659
4660 switch (binding)
4661 {
103f02d3
UD
4662 case STB_LOCAL: return "LOCAL";
4663 case STB_GLOBAL: return "GLOBAL";
4664 case STB_WEAK: return "WEAK";
252b5132
RH
4665 default:
4666 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
4667 sprintf (buff, _("<processor specific>: %d"), binding);
4668 else if (binding >= STB_LOOS && binding <= STB_HIOS)
4669 sprintf (buff, _("<OS specific>: %d"), binding);
4670 else
4671 sprintf (buff, _("<unknown>: %d"), binding);
4672 return buff;
4673 }
4674}
4675
d1133906 4676static const char *
252b5132
RH
4677get_symbol_type (type)
4678 unsigned int type;
4679{
4680 static char buff [32];
4681
4682 switch (type)
4683 {
103f02d3
UD
4684 case STT_NOTYPE: return "NOTYPE";
4685 case STT_OBJECT: return "OBJECT";
4686 case STT_FUNC: return "FUNC";
4687 case STT_SECTION: return "SECTION";
4688 case STT_FILE: return "FILE";
d1133906 4689 case STT_COMMON: return "COMMON";
252b5132
RH
4690 default:
4691 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
4692 {
4693 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
4694 return "THUMB_FUNC";
4695
351b4b40 4696 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
4697 return "REGISTER";
4698
4699 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
4700 return "PARISC_MILLI";
4701
df75f1af
NC
4702 sprintf (buff, _("<processor specific>: %d"), type);
4703 }
252b5132 4704 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
4705 {
4706 if (elf_header.e_machine == EM_PARISC)
4707 {
4708 if (type == STT_HP_OPAQUE)
4709 return "HP_OPAQUE";
4710 if (type == STT_HP_STUB)
4711 return "HP_STUB";
4712 }
4713
4714 sprintf (buff, _("<OS specific>: %d"), type);
4715 }
252b5132
RH
4716 else
4717 sprintf (buff, _("<unknown>: %d"), type);
4718 return buff;
4719 }
4720}
4721
d1133906
NC
4722static const char *
4723get_symbol_visibility (visibility)
4724 unsigned int visibility;
4725{
4726 switch (visibility)
4727 {
4728 case STV_DEFAULT: return "DEFAULT";
4729 case STV_INTERNAL: return "INTERNAL";
4730 case STV_HIDDEN: return "HIDDEN";
4731 case STV_PROTECTED: return "PROTECTED";
4732 default: abort ();
4733 }
4734}
4735
4736static const char *
252b5132
RH
4737get_symbol_index_type (type)
4738 unsigned int type;
4739{
4740 switch (type)
4741 {
4742 case SHN_UNDEF: return "UND";
4743 case SHN_ABS: return "ABS";
4744 case SHN_COMMON: return "COM";
4745 default:
4746 if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4747 return "PRC";
4748 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
4749 return "RSV";
4750 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4751 return "OS ";
4752 else
4753 {
4754 static char buff [32];
4755
4756 sprintf (buff, "%3d", type);
4757 return buff;
4758 }
4759 }
4760}
4761
252b5132
RH
4762static int *
4763get_dynamic_data (file, number)
4764 FILE * file;
4765 unsigned int number;
4766{
3c9f43b1 4767 unsigned char * e_data;
252b5132
RH
4768 int * i_data;
4769
3c9f43b1 4770 e_data = (unsigned char *) malloc (number * 4);
252b5132
RH
4771
4772 if (e_data == NULL)
4773 {
4774 error (_("Out of memory\n"));
4775 return NULL;
4776 }
4777
4778 if (fread (e_data, 4, number, file) != number)
4779 {
4780 error (_("Unable to read in dynamic data\n"));
4781 return NULL;
4782 }
4783
4784 i_data = (int *) malloc (number * sizeof (* i_data));
4785
4786 if (i_data == NULL)
4787 {
4788 error (_("Out of memory\n"));
4789 free (e_data);
4790 return NULL;
4791 }
4792
4793 while (number--)
4794 i_data [number] = byte_get (e_data + number * 4, 4);
4795
4796 free (e_data);
4797
4798 return i_data;
4799}
4800
4801/* Dump the symbol table */
4802static int
4803process_symbol_table (file)
4804 FILE * file;
4805{
4806 Elf32_Internal_Shdr * section;
3c9f43b1
AM
4807 unsigned char nb [4];
4808 unsigned char nc [4];
b4c96d0d 4809 int nbuckets = 0;
5e220199 4810 int nchains = 0;
252b5132
RH
4811 int * buckets = NULL;
4812 int * chains = NULL;
4813
4814 if (! do_syms && !do_histogram)
4815 return 1;
4816
4817 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
4818 || do_histogram))
4819 {
4820 if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
4821 {
4822 error (_("Unable to seek to start of dynamic information"));
4823 return 0;
4824 }
4825
4826 if (fread (nb, sizeof (nb), 1, file) != 1)
4827 {
4828 error (_("Failed to read in number of buckets\n"));
4829 return 0;
4830 }
4831
4832 if (fread (nc, sizeof (nc), 1, file) != 1)
4833 {
4834 error (_("Failed to read in number of chains\n"));
4835 return 0;
4836 }
4837
4838 nbuckets = byte_get (nb, 4);
4839 nchains = byte_get (nc, 4);
4840
4841 buckets = get_dynamic_data (file, nbuckets);
4842 chains = get_dynamic_data (file, nchains);
4843
4844 if (buckets == NULL || chains == NULL)
4845 return 0;
4846 }
4847
4848 if (do_syms
4849 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
4850 {
4851 int hn;
4852 int si;
4853
4854 printf (_("\nSymbol table for image:\n"));
f7a99963 4855 if (is_32bit_elf)
ca47b30c 4856 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 4857 else
ca47b30c 4858 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
252b5132
RH
4859
4860 for (hn = 0; hn < nbuckets; hn++)
4861 {
4862 if (! buckets [hn])
4863 continue;
4864
f7a99963 4865 for (si = buckets [hn]; si < nchains && si > 0; si = chains [si])
252b5132
RH
4866 {
4867 Elf_Internal_Sym * psym;
4868
4869 psym = dynamic_symbols + si;
4870
f7a99963
NC
4871 printf (" %3d %3d: ", si, hn);
4872 print_vma (psym->st_value, LONG_HEX);
4873 putchar (' ' );
d1133906 4874 print_vma (psym->st_size, DEC_5);
76da6bbe 4875
d1133906
NC
4876 printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
4877 printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
4878 printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
d1133906 4879 printf (" %3.3s", get_symbol_index_type (psym->st_shndx));
252b5132
RH
4880 printf (" %s\n", dynamic_strings + psym->st_name);
4881 }
4882 }
4883 }
4884 else if (do_syms && !do_using_dynamic)
4885 {
4886 unsigned int i;
4887
4888 for (i = 0, section = section_headers;
4889 i < elf_header.e_shnum;
4890 i++, section++)
4891 {
4892 unsigned int si;
4893 char * strtab;
4894 Elf_Internal_Sym * symtab;
4895 Elf_Internal_Sym * psym;
4896
4897
4898 if ( section->sh_type != SHT_SYMTAB
4899 && section->sh_type != SHT_DYNSYM)
4900 continue;
4901
4902 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
4903 SECTION_NAME (section),
4904 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 4905 if (is_32bit_elf)
ca47b30c 4906 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 4907 else
ca47b30c 4908 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 4909
9ea033b2 4910 symtab = GET_ELF_SYMBOLS (file, section->sh_offset,
252b5132
RH
4911 section->sh_size / section->sh_entsize);
4912 if (symtab == NULL)
4913 continue;
4914
4915 if (section->sh_link == elf_header.e_shstrndx)
4916 strtab = string_table;
4917 else
4918 {
4919 Elf32_Internal_Shdr * string_sec;
4920
4921 string_sec = section_headers + section->sh_link;
4922
4923 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
4924 strtab, char *, "string table");
4925 }
4926
4927 for (si = 0, psym = symtab;
4928 si < section->sh_size / section->sh_entsize;
4929 si ++, psym ++)
4930 {
5e220199 4931 printf ("%6d: ", si);
f7a99963
NC
4932 print_vma (psym->st_value, LONG_HEX);
4933 putchar (' ');
4934 print_vma (psym->st_size, DEC_5);
d1133906
NC
4935 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
4936 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
4937 printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
d1133906 4938 printf (" %4s", get_symbol_index_type (psym->st_shndx));
252b5132
RH
4939 printf (" %s", strtab + psym->st_name);
4940
4941 if (section->sh_type == SHT_DYNSYM &&
4942 version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
4943 {
4944 unsigned char data[2];
4945 unsigned short vers_data;
4946 unsigned long offset;
4947 int is_nobits;
4948 int check_def;
4949
4950 offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
4951 - loadaddr;
4952
4953 GET_DATA (offset + si * sizeof (vers_data), data,
4954 "version data");
4955
4956 vers_data = byte_get (data, 2);
4957
4958 is_nobits = psym->st_shndx < SHN_LORESERVE ?
4959 (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
4960 : 0;
4961
4962 check_def = (psym->st_shndx != SHN_UNDEF);
4963
4964 if ((vers_data & 0x8000) || vers_data > 1)
4965 {
00d93f34
JJ
4966 if (version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
4967 && (is_nobits || ! check_def))
252b5132
RH
4968 {
4969 Elf_External_Verneed evn;
4970 Elf_Internal_Verneed ivn;
4971 Elf_Internal_Vernaux ivna;
4972
4973 /* We must test both. */
4974 offset = version_info
4975 [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
4976
252b5132
RH
4977 do
4978 {
4979 unsigned long vna_off;
4980
dd27201e
L
4981 GET_DATA (offset, evn, "version need");
4982
4983 ivn.vn_aux = BYTE_GET (evn.vn_aux);
4984 ivn.vn_next = BYTE_GET (evn.vn_next);
4985
252b5132
RH
4986 vna_off = offset + ivn.vn_aux;
4987
4988 do
4989 {
4990 Elf_External_Vernaux evna;
4991
4992 GET_DATA (vna_off, evna,
4993 "version need aux (3)");
4994
4995 ivna.vna_other = BYTE_GET (evna.vna_other);
4996 ivna.vna_next = BYTE_GET (evna.vna_next);
4997 ivna.vna_name = BYTE_GET (evna.vna_name);
4998
4999 vna_off += ivna.vna_next;
5000 }
5001 while (ivna.vna_other != vers_data
5002 && ivna.vna_next != 0);
5003
5004 if (ivna.vna_other == vers_data)
5005 break;
5006
5007 offset += ivn.vn_next;
5008 }
5009 while (ivn.vn_next != 0);
5010
5011 if (ivna.vna_other == vers_data)
5012 {
5013 printf ("@%s (%d)",
5014 strtab + ivna.vna_name, ivna.vna_other);
5015 check_def = 0;
5016 }
5017 else if (! is_nobits)
5018 error (_("bad dynamic symbol"));
5019 else
5020 check_def = 1;
5021 }
5022
5023 if (check_def)
5024 {
00d93f34
JJ
5025 if (vers_data != 0x8001
5026 && version_info [DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132
RH
5027 {
5028 Elf_Internal_Verdef ivd;
5029 Elf_Internal_Verdaux ivda;
5030 Elf_External_Verdaux evda;
5031 unsigned long offset;
5032
5033 offset =
5034 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
5035 - loadaddr;
5036
5037 do
5038 {
5039 Elf_External_Verdef evd;
5040
5041 GET_DATA (offset, evd, "version def");
5042
5043 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
5044 ivd.vd_aux = BYTE_GET (evd.vd_aux);
5045 ivd.vd_next = BYTE_GET (evd.vd_next);
5046
5047 offset += ivd.vd_next;
5048 }
5049 while (ivd.vd_ndx != (vers_data & 0x7fff)
5050 && ivd.vd_next != 0);
5051
5052 offset -= ivd.vd_next;
5053 offset += ivd.vd_aux;
5054
5055 GET_DATA (offset, evda, "version def aux");
5056
5057 ivda.vda_name = BYTE_GET (evda.vda_name);
5058
5059 if (psym->st_name != ivda.vda_name)
5060 printf ((vers_data & 0x8000)
5061 ? "@%s" : "@@%s",
5062 strtab + ivda.vda_name);
5063 }
5064 }
5065 }
5066 }
5067
5068 putchar ('\n');
5069 }
5070
5071 free (symtab);
5072 if (strtab != string_table)
5073 free (strtab);
5074 }
5075 }
5076 else if (do_syms)
5077 printf
5078 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
5079
5080 if (do_histogram && buckets != NULL)
5081 {
584da044
NC
5082 int * lengths;
5083 int * counts;
5084 int hn;
5085 int si;
5086 int maxlength = 0;
5087 int nzero_counts = 0;
5088 int nsyms = 0;
252b5132
RH
5089
5090 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
5091 nbuckets);
5092 printf (_(" Length Number %% of total Coverage\n"));
5093
5094 lengths = (int *) calloc (nbuckets, sizeof (int));
5095 if (lengths == NULL)
5096 {
5097 error (_("Out of memory"));
5098 return 0;
5099 }
5100 for (hn = 0; hn < nbuckets; ++hn)
5101 {
5102 if (! buckets [hn])
5103 continue;
5104
f7a99963 5105 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 5106 {
f7a99963 5107 ++ nsyms;
252b5132 5108 if (maxlength < ++lengths[hn])
f7a99963 5109 ++ maxlength;
252b5132
RH
5110 }
5111 }
5112
5113 counts = (int *) calloc (maxlength + 1, sizeof (int));
5114 if (counts == NULL)
5115 {
5116 error (_("Out of memory"));
5117 return 0;
5118 }
5119
5120 for (hn = 0; hn < nbuckets; ++hn)
30800947 5121 ++ counts [lengths [hn]];
252b5132 5122
103f02d3 5123 if (nbuckets > 0)
252b5132 5124 {
103f02d3
UD
5125 printf (" 0 %-10d (%5.1f%%)\n",
5126 counts[0], (counts[0] * 100.0) / nbuckets);
5127 for (si = 1; si <= maxlength; ++si)
5128 {
5129 nzero_counts += counts[si] * si;
5130 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
5131 si, counts[si], (counts[si] * 100.0) / nbuckets,
5132 (nzero_counts * 100.0) / nsyms);
5133 }
252b5132
RH
5134 }
5135
5136 free (counts);
5137 free (lengths);
5138 }
5139
5140 if (buckets != NULL)
5141 {
5142 free (buckets);
5143 free (chains);
5144 }
5145
5146 return 1;
5147}
5148
5149static int
5150process_syminfo (file)
b4c96d0d 5151 FILE * file ATTRIBUTE_UNUSED;
252b5132 5152{
b4c96d0d 5153 unsigned int i;
252b5132
RH
5154
5155 if (dynamic_syminfo == NULL
5156 || !do_dynamic)
5157 /* No syminfo, this is ok. */
5158 return 1;
5159
5160 /* There better should be a dynamic symbol section. */
5161 if (dynamic_symbols == NULL || dynamic_strings == NULL)
5162 return 0;
5163
5164 if (dynamic_addr)
5165 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
5166 dynamic_syminfo_offset, dynamic_syminfo_nent);
5167
5168 printf (_(" Num: Name BoundTo Flags\n"));
5169 for (i = 0; i < dynamic_syminfo_nent; ++i)
5170 {
5171 unsigned short int flags = dynamic_syminfo[i].si_flags;
5172
5173 printf ("%4d: %-30s ", i,
5174 dynamic_strings + dynamic_symbols[i].st_name);
5175
5176 switch (dynamic_syminfo[i].si_boundto)
5177 {
5178 case SYMINFO_BT_SELF:
5179 fputs ("SELF ", stdout);
5180 break;
5181 case SYMINFO_BT_PARENT:
5182 fputs ("PARENT ", stdout);
5183 break;
5184 default:
5185 if (dynamic_syminfo[i].si_boundto > 0
5186 && dynamic_syminfo[i].si_boundto < dynamic_size)
5187 printf ("%-10s ",
5188 dynamic_strings
5189 + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
5190 else
5191 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
5192 break;
5193 }
5194
5195 if (flags & SYMINFO_FLG_DIRECT)
5196 printf (" DIRECT");
5197 if (flags & SYMINFO_FLG_PASSTHRU)
5198 printf (" PASSTHRU");
5199 if (flags & SYMINFO_FLG_COPY)
5200 printf (" COPY");
5201 if (flags & SYMINFO_FLG_LAZYLOAD)
5202 printf (" LAZYLOAD");
5203
5204 puts ("");
5205 }
5206
5207 return 1;
5208}
5209
5210#ifdef SUPPORT_DISASSEMBLY
5211static void
5212disassemble_section (section, file)
5213 Elf32_Internal_Shdr * section;
5214 FILE * file;
5215{
5216 printf (_("\nAssembly dump of section %s\n"),
5217 SECTION_NAME (section));
5218
5219 /* XXX -- to be done --- XXX */
5220
5221 return 1;
5222}
5223#endif
5224
5225static int
5226dump_section (section, file)
5227 Elf32_Internal_Shdr * section;
5228 FILE * file;
5229{
9ea033b2
NC
5230 bfd_size_type bytes;
5231 bfd_vma addr;
252b5132
RH
5232 unsigned char * data;
5233 unsigned char * start;
5234
5235 bytes = section->sh_size;
5236
5237 if (bytes == 0)
5238 {
5239 printf (_("\nSection '%s' has no data to dump.\n"),
5240 SECTION_NAME (section));
5241 return 0;
5242 }
5243 else
5244 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
5245
5246 addr = section->sh_addr;
5247
5248 GET_DATA_ALLOC (section->sh_offset, bytes, start, unsigned char *,
5249 "section data");
5250
5251 data = start;
5252
5253 while (bytes)
5254 {
5255 int j;
5256 int k;
5257 int lbytes;
5258
5259 lbytes = (bytes > 16 ? 16 : bytes);
5260
148d3c43 5261 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132
RH
5262
5263 switch (elf_header.e_ident [EI_DATA])
5264 {
9ea033b2 5265 default:
252b5132
RH
5266 case ELFDATA2LSB:
5267 for (j = 15; j >= 0; j --)
5268 {
5269 if (j < lbytes)
5270 printf ("%2.2x", data [j]);
5271 else
5272 printf (" ");
5273
5274 if (!(j & 0x3))
5275 printf (" ");
5276 }
5277 break;
5278
5279 case ELFDATA2MSB:
5280 for (j = 0; j < 16; j++)
5281 {
5282 if (j < lbytes)
5283 printf ("%2.2x", data [j]);
5284 else
5285 printf (" ");
5286
5287 if ((j & 3) == 3)
5288 printf (" ");
5289 }
5290 break;
5291 }
5292
5293 for (j = 0; j < lbytes; j++)
5294 {
5295 k = data [j];
5296 if (k >= ' ' && k < 0x80)
5297 printf ("%c", k);
5298 else
5299 printf (".");
5300 }
5301
5302 putchar ('\n');
5303
5304 data += lbytes;
5305 addr += lbytes;
5306 bytes -= lbytes;
5307 }
5308
5309 free (start);
5310
5311 return 1;
5312}
5313
5314
5315static unsigned long int
5316read_leb128 (data, length_return, sign)
5317 unsigned char * data;
5318 int * length_return;
5319 int sign;
5320{
5321 unsigned long int result = 0;
5322 unsigned int num_read = 0;
5323 int shift = 0;
5324 unsigned char byte;
5325
5326 do
5327 {
5328 byte = * data ++;
5329 num_read ++;
5330
5331 result |= (byte & 0x7f) << shift;
5332
5333 shift += 7;
5334
5335 }
5336 while (byte & 0x80);
5337
5338 if (length_return != NULL)
5339 * length_return = num_read;
5340
5341 if (sign && (shift < 32) && (byte & 0x40))
5342 result |= -1 << shift;
5343
5344 return result;
5345}
5346
5347typedef struct State_Machine_Registers
5348{
5349 unsigned long address;
5350 unsigned int file;
5351 unsigned int line;
5352 unsigned int column;
5353 int is_stmt;
5354 int basic_block;
5355 int end_sequence;
5356/* This variable hold the number of the last entry seen
5357 in the File Table. */
5358 unsigned int last_file_entry;
5359} SMR;
5360
5361static SMR state_machine_regs;
5362
5363static void
5364reset_state_machine (is_stmt)
5365 int is_stmt;
5366{
5367 state_machine_regs.address = 0;
5368 state_machine_regs.file = 1;
5369 state_machine_regs.line = 1;
5370 state_machine_regs.column = 0;
5371 state_machine_regs.is_stmt = is_stmt;
5372 state_machine_regs.basic_block = 0;
5373 state_machine_regs.end_sequence = 0;
5374 state_machine_regs.last_file_entry = 0;
5375}
5376
5377/* Handled an extend line op. Returns true if this is the end
5378 of sequence. */
5379static int
3590ea00 5380process_extended_line_op (data, is_stmt, pointer_size)
252b5132
RH
5381 unsigned char * data;
5382 int is_stmt;
3590ea00 5383 int pointer_size;
252b5132
RH
5384{
5385 unsigned char op_code;
5386 int bytes_read;
5387 unsigned int len;
5388 unsigned char * name;
5389 unsigned long adr;
103f02d3 5390
252b5132
RH
5391 len = read_leb128 (data, & bytes_read, 0);
5392 data += bytes_read;
5393
5394 if (len == 0)
5395 {
5396 warn (_("badly formed extended line op encountered!"));
5397 return bytes_read;
5398 }
5399
5400 len += bytes_read;
5401 op_code = * data ++;
5402
5403 printf (_(" Extended opcode %d: "), op_code);
103f02d3 5404
252b5132
RH
5405 switch (op_code)
5406 {
5407 case DW_LNE_end_sequence:
5408 printf (_("End of Sequence\n\n"));
5409 reset_state_machine (is_stmt);
5410 break;
5411
5412 case DW_LNE_set_address:
3590ea00 5413 adr = byte_get (data, pointer_size);
252b5132
RH
5414 printf (_("set Address to 0x%lx\n"), adr);
5415 state_machine_regs.address = adr;
5416 break;
5417
5418 case DW_LNE_define_file:
5419 printf (_(" define new File Table entry\n"));
5420 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
103f02d3 5421
252b5132
RH
5422 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
5423 name = data;
3c9f43b1 5424 data += strlen ((char *) data) + 1;
252b5132
RH
5425 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5426 data += bytes_read;
5427 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5428 data += bytes_read;
5429 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5430 printf (_("%s\n\n"), name);
5431 break;
5432
5433 default:
5434 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
5435 break;
5436 }
5437
5438 return len;
5439}
5440
3590ea00
NC
5441/* Size of pointers in the .debug_line section. This information is not
5442 really present in that section. It's obtained before dumping the debug
5443 sections by doing some pre-scan of the .debug_info section. */
5444static int debug_line_pointer_size = 4;
252b5132
RH
5445
5446static int
5447display_debug_lines (section, start, file)
5448 Elf32_Internal_Shdr * section;
5449 unsigned char * start;
b4c96d0d 5450 FILE * file ATTRIBUTE_UNUSED;
252b5132
RH
5451{
5452 DWARF2_External_LineInfo * external;
5453 DWARF2_Internal_LineInfo info;
5454 unsigned char * standard_opcodes;
5455 unsigned char * data = start;
5456 unsigned char * end = start + section->sh_size;
5457 unsigned char * end_of_sequence;
5458 int i;
5459
5460 printf (_("\nDump of debug contents of section %s:\n\n"),
5461 SECTION_NAME (section));
5462
5463 while (data < end)
5464 {
5465 external = (DWARF2_External_LineInfo *) data;
5466
5467 /* Check the length of the block. */
5468 info.li_length = BYTE_GET (external->li_length);
b612ab9c 5469 if (info.li_length + sizeof (external->li_length) > section->sh_size)
252b5132
RH
5470 {
5471 warn
5472 (_("The line info appears to be corrupt - the section is too small\n"));
5473 return 0;
5474 }
103f02d3 5475
252b5132
RH
5476 /* Check its version number. */
5477 info.li_version = BYTE_GET (external->li_version);
5478 if (info.li_version != 2)
5479 {
5480 warn (_("Only DWARF version 2 line info is currently supported.\n"));
5481 return 0;
5482 }
103f02d3 5483
252b5132
RH
5484 info.li_prologue_length = BYTE_GET (external->li_prologue_length);
5485 info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
5486 info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
5487 info.li_line_base = BYTE_GET (external->li_line_base);
5488 info.li_line_range = BYTE_GET (external->li_line_range);
5489 info.li_opcode_base = BYTE_GET (external->li_opcode_base);
103f02d3 5490
252b5132
RH
5491 /* Sign extend the line base field. */
5492 info.li_line_base <<= 24;
5493 info.li_line_base >>= 24;
103f02d3 5494
252b5132
RH
5495 printf (_(" Length: %ld\n"), info.li_length);
5496 printf (_(" DWARF Version: %d\n"), info.li_version);
ff94ebf2 5497 printf (_(" Prologue Length: %d\n"), info.li_prologue_length);
252b5132
RH
5498 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
5499 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
5500 printf (_(" Line Base: %d\n"), info.li_line_base);
5501 printf (_(" Line Range: %d\n"), info.li_line_range);
5502 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
5503
b612ab9c 5504 end_of_sequence = data + info.li_length + sizeof (external->li_length);
252b5132
RH
5505
5506 reset_state_machine (info.li_default_is_stmt);
103f02d3 5507
252b5132
RH
5508 /* Display the contents of the Opcodes table. */
5509 standard_opcodes = data + sizeof (* external);
103f02d3 5510
252b5132 5511 printf (_("\n Opcodes:\n"));
103f02d3 5512
252b5132 5513 for (i = 1; i < info.li_opcode_base; i++)
7a4b7442 5514 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
103f02d3 5515
252b5132
RH
5516 /* Display the contents of the Directory table. */
5517 data = standard_opcodes + info.li_opcode_base - 1;
103f02d3 5518
252b5132
RH
5519 if (* data == 0)
5520 printf (_("\n The Directory Table is empty.\n"));
5521 else
5522 {
5523 printf (_("\n The Directory Table:\n"));
103f02d3 5524
252b5132
RH
5525 while (* data != 0)
5526 {
5527 printf (_(" %s\n"), data);
103f02d3 5528
3c9f43b1 5529 data += strlen ((char *) data) + 1;
252b5132
RH
5530 }
5531 }
103f02d3 5532
252b5132
RH
5533 /* Skip the NUL at the end of the table. */
5534 data ++;
103f02d3 5535
252b5132
RH
5536 /* Display the contents of the File Name table. */
5537 if (* data == 0)
5538 printf (_("\n The File Name Table is empty.\n"));
5539 else
5540 {
5541 printf (_("\n The File Name Table:\n"));
5542 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
103f02d3 5543
252b5132
RH
5544 while (* data != 0)
5545 {
3c9f43b1 5546 unsigned char * name;
252b5132 5547 int bytes_read;
103f02d3 5548
252b5132
RH
5549 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
5550 name = data;
103f02d3 5551
3c9f43b1 5552 data += strlen ((char *) data) + 1;
103f02d3 5553
252b5132
RH
5554 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5555 data += bytes_read;
5556 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5557 data += bytes_read;
5558 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5559 data += bytes_read;
5560 printf (_("%s\n"), name);
5561 }
5562 }
103f02d3 5563
252b5132
RH
5564 /* Skip the NUL at the end of the table. */
5565 data ++;
103f02d3 5566
252b5132
RH
5567 /* Now display the statements. */
5568 printf (_("\n Line Number Statements:\n"));
103f02d3
UD
5569
5570
252b5132
RH
5571 while (data < end_of_sequence)
5572 {
5573 unsigned char op_code;
5574 int adv;
5575 int bytes_read;
103f02d3 5576
252b5132 5577 op_code = * data ++;
103f02d3 5578
252b5132
RH
5579 switch (op_code)
5580 {
5581 case DW_LNS_extended_op:
3590ea00
NC
5582 data += process_extended_line_op (data, info.li_default_is_stmt,
5583 debug_line_pointer_size);
252b5132 5584 break;
103f02d3 5585
252b5132
RH
5586 case DW_LNS_copy:
5587 printf (_(" Copy\n"));
5588 break;
103f02d3 5589
252b5132
RH
5590 case DW_LNS_advance_pc:
5591 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
5592 data += bytes_read;
5593 state_machine_regs.address += adv;
5594 printf (_(" Advance PC by %d to %lx\n"), adv,
5595 state_machine_regs.address);
5596 break;
103f02d3 5597
252b5132
RH
5598 case DW_LNS_advance_line:
5599 adv = read_leb128 (data, & bytes_read, 1);
5600 data += bytes_read;
5601 state_machine_regs.line += adv;
5602 printf (_(" Advance Line by %d to %d\n"), adv,
5603 state_machine_regs.line);
5604 break;
103f02d3 5605
252b5132
RH
5606 case DW_LNS_set_file:
5607 adv = read_leb128 (data, & bytes_read, 0);
5608 data += bytes_read;
5609 printf (_(" Set File Name to entry %d in the File Name Table\n"),
5610 adv);
5611 state_machine_regs.file = adv;
5612 break;
103f02d3 5613
252b5132
RH
5614 case DW_LNS_set_column:
5615 adv = read_leb128 (data, & bytes_read, 0);
5616 data += bytes_read;
5617 printf (_(" Set column to %d\n"), adv);
5618 state_machine_regs.column = adv;
5619 break;
103f02d3 5620
252b5132
RH
5621 case DW_LNS_negate_stmt:
5622 adv = state_machine_regs.is_stmt;
5623 adv = ! adv;
5624 printf (_(" Set is_stmt to %d\n"), adv);
5625 state_machine_regs.is_stmt = adv;
5626 break;
103f02d3 5627
252b5132
RH
5628 case DW_LNS_set_basic_block:
5629 printf (_(" Set basic block\n"));
5630 state_machine_regs.basic_block = 1;
5631 break;
103f02d3 5632
252b5132 5633 case DW_LNS_const_add_pc:
2366453a
NC
5634 adv = (((255 - info.li_opcode_base) / info.li_line_range)
5635 * info.li_min_insn_length);
252b5132
RH
5636 state_machine_regs.address += adv;
5637 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
5638 state_machine_regs.address);
5639 break;
103f02d3 5640
252b5132
RH
5641 case DW_LNS_fixed_advance_pc:
5642 adv = byte_get (data, 2);
5643 data += 2;
5644 state_machine_regs.address += adv;
5645 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
5646 adv, state_machine_regs.address);
5647 break;
103f02d3 5648
252b5132
RH
5649 default:
5650 op_code -= info.li_opcode_base;
5651 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
5652 state_machine_regs.address += adv;
5653 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
5654 op_code, adv, state_machine_regs.address);
75d74c48 5655 adv = (op_code % info.li_line_range) + info.li_line_base;
252b5132
RH
5656 state_machine_regs.line += adv;
5657 printf (_(" and Line by %d to %d\n"),
5658 adv, state_machine_regs.line);
5659 break;
5660 }
5661 }
5662 printf ("\n");
5663 }
103f02d3 5664
252b5132
RH
5665 return 1;
5666}
5667
5668static int
5669display_debug_pubnames (section, start, file)
5670 Elf32_Internal_Shdr * section;
5671 unsigned char * start;
b4c96d0d 5672 FILE * file ATTRIBUTE_UNUSED;
252b5132
RH
5673{
5674 DWARF2_External_PubNames * external;
5675 DWARF2_Internal_PubNames pubnames;
5676 unsigned char * end;
5677
5678 end = start + section->sh_size;
5679
5680 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
5681
5682 while (start < end)
5683 {
5684 unsigned char * data;
5685 unsigned long offset;
5686
5687 external = (DWARF2_External_PubNames *) start;
5688
5689 pubnames.pn_length = BYTE_GET (external->pn_length);
5690 pubnames.pn_version = BYTE_GET (external->pn_version);
5691 pubnames.pn_offset = BYTE_GET (external->pn_offset);
5692 pubnames.pn_size = BYTE_GET (external->pn_size);
5693
5694 data = start + sizeof (* external);
5695 start += pubnames.pn_length + sizeof (external->pn_length);
5696
5697 if (pubnames.pn_version != 2)
5698 {
3f215a10
NC
5699 static int warned = 0;
5700
5701 if (! warned)
5702 {
5703 warn (_("Only DWARF 2 pubnames are currently supported\n"));
5704 warned = 1;
5705 }
76da6bbe 5706
252b5132
RH
5707 continue;
5708 }
5709
5710 printf (_(" Length: %ld\n"),
5711 pubnames.pn_length);
5712 printf (_(" Version: %d\n"),
5713 pubnames.pn_version);
5714 printf (_(" Offset into .debug_info section: %ld\n"),
5715 pubnames.pn_offset);
5716 printf (_(" Size of area in .debug_info section: %ld\n"),
5717 pubnames.pn_size);
5718
5719 printf (_("\n Offset\tName\n"));
5720
5721 do
5722 {
5723 offset = byte_get (data, 4);
5724
5725 if (offset != 0)
5726 {
5727 data += 4;
5728 printf (" %ld\t\t%s\n", offset, data);
3c9f43b1 5729 data += strlen ((char *) data) + 1;
252b5132
RH
5730 }
5731 }
5732 while (offset != 0);
5733 }
5734
5735 printf ("\n");
5736 return 1;
5737}
5738
5739static char *
5740get_TAG_name (tag)
5741 unsigned long tag;
5742{
5743 switch (tag)
5744 {
5745 case DW_TAG_padding: return "DW_TAG_padding";
5746 case DW_TAG_array_type: return "DW_TAG_array_type";
5747 case DW_TAG_class_type: return "DW_TAG_class_type";
5748 case DW_TAG_entry_point: return "DW_TAG_entry_point";
5749 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
5750 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
5751 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
5752 case DW_TAG_label: return "DW_TAG_label";
5753 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
5754 case DW_TAG_member: return "DW_TAG_member";
5755 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
5756 case DW_TAG_reference_type: return "DW_TAG_reference_type";
5757 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
5758 case DW_TAG_string_type: return "DW_TAG_string_type";
5759 case DW_TAG_structure_type: return "DW_TAG_structure_type";
5760 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
5761 case DW_TAG_typedef: return "DW_TAG_typedef";
5762 case DW_TAG_union_type: return "DW_TAG_union_type";
5763 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
5764 case DW_TAG_variant: return "DW_TAG_variant";
5765 case DW_TAG_common_block: return "DW_TAG_common_block";
5766 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
5767 case DW_TAG_inheritance: return "DW_TAG_inheritance";
5768 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
5769 case DW_TAG_module: return "DW_TAG_module";
5770 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
5771 case DW_TAG_set_type: return "DW_TAG_set_type";
5772 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
5773 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
5774 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
5775 case DW_TAG_base_type: return "DW_TAG_base_type";
5776 case DW_TAG_catch_block: return "DW_TAG_catch_block";
5777 case DW_TAG_const_type: return "DW_TAG_const_type";
5778 case DW_TAG_constant: return "DW_TAG_constant";
5779 case DW_TAG_enumerator: return "DW_TAG_enumerator";
5780 case DW_TAG_file_type: return "DW_TAG_file_type";
5781 case DW_TAG_friend: return "DW_TAG_friend";
5782 case DW_TAG_namelist: return "DW_TAG_namelist";
5783 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
5784 case DW_TAG_packed_type: return "DW_TAG_packed_type";
5785 case DW_TAG_subprogram: return "DW_TAG_subprogram";
5786 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
5787 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
5788 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
5789 case DW_TAG_try_block: return "DW_TAG_try_block";
5790 case DW_TAG_variant_part: return "DW_TAG_variant_part";
5791 case DW_TAG_variable: return "DW_TAG_variable";
5792 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
5793 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
5794 case DW_TAG_format_label: return "DW_TAG_format_label";
5795 case DW_TAG_function_template: return "DW_TAG_function_template";
5796 case DW_TAG_class_template: return "DW_TAG_class_template";
5797 default:
5798 {
5799 static char buffer [100];
5800
5801 sprintf (buffer, _("Unknown TAG value: %lx"), tag);
5802 return buffer;
5803 }
5804 }
5805}
5806
5807static char *
5808get_AT_name (attribute)
5809 unsigned long attribute;
5810{
5811 switch (attribute)
5812 {
5813 case DW_AT_sibling: return "DW_AT_sibling";
5814 case DW_AT_location: return "DW_AT_location";
5815 case DW_AT_name: return "DW_AT_name";
5816 case DW_AT_ordering: return "DW_AT_ordering";
5817 case DW_AT_subscr_data: return "DW_AT_subscr_data";
5818 case DW_AT_byte_size: return "DW_AT_byte_size";
5819 case DW_AT_bit_offset: return "DW_AT_bit_offset";
5820 case DW_AT_bit_size: return "DW_AT_bit_size";
5821 case DW_AT_element_list: return "DW_AT_element_list";
5822 case DW_AT_stmt_list: return "DW_AT_stmt_list";
5823 case DW_AT_low_pc: return "DW_AT_low_pc";
5824 case DW_AT_high_pc: return "DW_AT_high_pc";
5825 case DW_AT_language: return "DW_AT_language";
5826 case DW_AT_member: return "DW_AT_member";
5827 case DW_AT_discr: return "DW_AT_discr";
5828 case DW_AT_discr_value: return "DW_AT_discr_value";
5829 case DW_AT_visibility: return "DW_AT_visibility";
5830 case DW_AT_import: return "DW_AT_import";
5831 case DW_AT_string_length: return "DW_AT_string_length";
5832 case DW_AT_common_reference: return "DW_AT_common_reference";
5833 case DW_AT_comp_dir: return "DW_AT_comp_dir";
5834 case DW_AT_const_value: return "DW_AT_const_value";
5835 case DW_AT_containing_type: return "DW_AT_containing_type";
5836 case DW_AT_default_value: return "DW_AT_default_value";
5837 case DW_AT_inline: return "DW_AT_inline";
5838 case DW_AT_is_optional: return "DW_AT_is_optional";
5839 case DW_AT_lower_bound: return "DW_AT_lower_bound";
5840 case DW_AT_producer: return "DW_AT_producer";
5841 case DW_AT_prototyped: return "DW_AT_prototyped";
5842 case DW_AT_return_addr: return "DW_AT_return_addr";
5843 case DW_AT_start_scope: return "DW_AT_start_scope";
5844 case DW_AT_stride_size: return "DW_AT_stride_size";
5845 case DW_AT_upper_bound: return "DW_AT_upper_bound";
5846 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
5847 case DW_AT_accessibility: return "DW_AT_accessibility";
5848 case DW_AT_address_class: return "DW_AT_address_class";
5849 case DW_AT_artificial: return "DW_AT_artificial";
5850 case DW_AT_base_types: return "DW_AT_base_types";
5851 case DW_AT_calling_convention: return "DW_AT_calling_convention";
5852 case DW_AT_count: return "DW_AT_count";
5853 case DW_AT_data_member_location: return "DW_AT_data_member_location";
5854 case DW_AT_decl_column: return "DW_AT_decl_column";
5855 case DW_AT_decl_file: return "DW_AT_decl_file";
5856 case DW_AT_decl_line: return "DW_AT_decl_line";
5857 case DW_AT_declaration: return "DW_AT_declaration";
5858 case DW_AT_discr_list: return "DW_AT_discr_list";
5859 case DW_AT_encoding: return "DW_AT_encoding";
5860 case DW_AT_external: return "DW_AT_external";
5861 case DW_AT_frame_base: return "DW_AT_frame_base";
5862 case DW_AT_friend: return "DW_AT_friend";
5863 case DW_AT_identifier_case: return "DW_AT_identifier_case";
5864 case DW_AT_macro_info: return "DW_AT_macro_info";
5865 case DW_AT_namelist_items: return "DW_AT_namelist_items";
5866 case DW_AT_priority: return "DW_AT_priority";
5867 case DW_AT_segment: return "DW_AT_segment";
5868 case DW_AT_specification: return "DW_AT_specification";
5869 case DW_AT_static_link: return "DW_AT_static_link";
5870 case DW_AT_type: return "DW_AT_type";
5871 case DW_AT_use_location: return "DW_AT_use_location";
5872 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
5873 case DW_AT_virtuality: return "DW_AT_virtuality";
5874 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
5875 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
5876 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
5877 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
5878 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
5879 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
5880 case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
5881 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
5882 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
5883 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
5884 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
5885 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
5886 case DW_AT_sf_names: return "DW_AT_sf_names";
5887 case DW_AT_src_info: return "DW_AT_src_info";
5888 case DW_AT_mac_info: return "DW_AT_mac_info";
5889 case DW_AT_src_coords: return "DW_AT_src_coords";
5890 case DW_AT_body_begin: return "DW_AT_body_begin";
5891 case DW_AT_body_end: return "DW_AT_body_end";
5892 default:
5893 {
5894 static char buffer [100];
5895
5896 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
5897 return buffer;
5898 }
5899 }
5900}
5901
5902static char *
5903get_FORM_name (form)
5904 unsigned long form;
5905{
5906 switch (form)
5907 {
5908 case DW_FORM_addr: return "DW_FORM_addr";
5909 case DW_FORM_block2: return "DW_FORM_block2";
5910 case DW_FORM_block4: return "DW_FORM_block4";
5911 case DW_FORM_data2: return "DW_FORM_data2";
5912 case DW_FORM_data4: return "DW_FORM_data4";
5913 case DW_FORM_data8: return "DW_FORM_data8";
5914 case DW_FORM_string: return "DW_FORM_string";
5915 case DW_FORM_block: return "DW_FORM_block";
5916 case DW_FORM_block1: return "DW_FORM_block1";
5917 case DW_FORM_data1: return "DW_FORM_data1";
5918 case DW_FORM_flag: return "DW_FORM_flag";
5919 case DW_FORM_sdata: return "DW_FORM_sdata";
5920 case DW_FORM_strp: return "DW_FORM_strp";
5921 case DW_FORM_udata: return "DW_FORM_udata";
5922 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
5923 case DW_FORM_ref1: return "DW_FORM_ref1";
5924 case DW_FORM_ref2: return "DW_FORM_ref2";
5925 case DW_FORM_ref4: return "DW_FORM_ref4";
5926 case DW_FORM_ref8: return "DW_FORM_ref8";
5927 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
5928 case DW_FORM_indirect: return "DW_FORM_indirect";
5929 default:
5930 {
5931 static char buffer [100];
5932
5933 sprintf (buffer, _("Unknown FORM value: %lx"), form);
5934 return buffer;
5935 }
5936 }
5937}
5938
5939/* FIXME: There are better and more effiecint ways to handle
5940 these structures. For now though, I just want something that
5941 is simple to implement. */
5942typedef struct abbrev_attr
5943{
5944 unsigned long attribute;
5945 unsigned long form;
5946 struct abbrev_attr * next;
5947}
5948abbrev_attr;
5949
5950typedef struct abbrev_entry
5951{
5952 unsigned long entry;
5953 unsigned long tag;
5954 int children;
5955 struct abbrev_attr * first_attr;
5956 struct abbrev_attr * last_attr;
5957 struct abbrev_entry * next;
5958}
5959abbrev_entry;
5960
5961static abbrev_entry * first_abbrev = NULL;
5962static abbrev_entry * last_abbrev = NULL;
5963
5964static void
5965free_abbrevs PARAMS ((void))
5966{
5967 abbrev_entry * abbrev;
5968
5969 for (abbrev = first_abbrev; abbrev;)
5970 {
5971 abbrev_entry * next = abbrev->next;
5972 abbrev_attr * attr;
5973
5974 for (attr = abbrev->first_attr; attr;)
5975 {
5976 abbrev_attr * next = attr->next;
5977
5978 free (attr);
5979 attr = next;
5980 }
5981
5982 free (abbrev);
5983 abbrev = next;
5984 }
5985
5986 last_abbrev = first_abbrev = NULL;
5987}
5988
5989static void
5990add_abbrev (number, tag, children)
5991 unsigned long number;
5992 unsigned long tag;
5993 int children;
5994{
5995 abbrev_entry * entry;
5996
5997 entry = (abbrev_entry *) malloc (sizeof (* entry));
5998
5999 if (entry == NULL)
6000 /* ugg */
6001 return;
6002
6003 entry->entry = number;
6004 entry->tag = tag;
6005 entry->children = children;
6006 entry->first_attr = NULL;
6007 entry->last_attr = NULL;
6008 entry->next = NULL;
6009
6010 if (first_abbrev == NULL)
6011 first_abbrev = entry;
6012 else
6013 last_abbrev->next = entry;
6014
6015 last_abbrev = entry;
6016}
6017
6018static void
6019add_abbrev_attr (attribute, form)
6020 unsigned long attribute;
6021 unsigned long form;
6022{
6023 abbrev_attr * attr;
6024
6025 attr = (abbrev_attr *) malloc (sizeof (* attr));
6026
6027 if (attr == NULL)
6028 /* ugg */
6029 return;
6030
6031 attr->attribute = attribute;
6032 attr->form = form;
6033 attr->next = NULL;
6034
6035 if (last_abbrev->first_attr == NULL)
6036 last_abbrev->first_attr = attr;
6037 else
6038 last_abbrev->last_attr->next = attr;
6039
6040 last_abbrev->last_attr = attr;
6041}
6042
6043/* Processes the (partial) contents of a .debug_abbrev section.
6044 Returns NULL if the end of the section was encountered.
6045 Returns the address after the last byte read if the end of
6046 an abbreviation set was found. */
6047
6048static unsigned char *
6049process_abbrev_section (start, end)
6050 unsigned char * start;
6051 unsigned char * end;
6052{
6053 if (first_abbrev != NULL)
6054 return NULL;
6055
6056 while (start < end)
6057 {
6058 int bytes_read;
6059 unsigned long entry;
6060 unsigned long tag;
6061 unsigned long attribute;
6062 int children;
6063
6064 entry = read_leb128 (start, & bytes_read, 0);
6065 start += bytes_read;
6066
a3f779db
NC
6067 /* A single zero is supposed to end the section according
6068 to the standard. If there's more, then signal that to
6069 the caller. */
252b5132 6070 if (entry == 0)
a3f779db 6071 return start == end ? NULL : start;
252b5132
RH
6072
6073 tag = read_leb128 (start, & bytes_read, 0);
6074 start += bytes_read;
6075
6076 children = * start ++;
6077
6078 add_abbrev (entry, tag, children);
6079
6080 do
6081 {
6082 unsigned long form;
6083
6084 attribute = read_leb128 (start, & bytes_read, 0);
6085 start += bytes_read;
6086
6087 form = read_leb128 (start, & bytes_read, 0);
6088 start += bytes_read;
6089
6090 if (attribute != 0)
6091 add_abbrev_attr (attribute, form);
6092 }
6093 while (attribute != 0);
6094 }
6095
6096 return NULL;
6097}
6098
6099
6100static int
6101display_debug_abbrev (section, start, file)
6102 Elf32_Internal_Shdr * section;
6103 unsigned char * start;
b4c96d0d 6104 FILE * file ATTRIBUTE_UNUSED;
252b5132 6105{
584da044 6106 abbrev_entry * entry;
252b5132
RH
6107 unsigned char * end = start + section->sh_size;
6108
6109 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
6110
6111 do
6112 {
6113 start = process_abbrev_section (start, end);
6114
6115 printf (_(" Number TAG\n"));
6116
6117 for (entry = first_abbrev; entry; entry = entry->next)
6118 {
6119 abbrev_attr * attr;
6120
6121 printf (_(" %ld %s [%s]\n"),
6122 entry->entry,
6123 get_TAG_name (entry->tag),
6124 entry->children ? _("has children") : _("no children"));
6125
6126 for (attr = entry->first_attr; attr; attr = attr->next)
6127 {
6128 printf (_(" %-18s %s\n"),
6129 get_AT_name (attr->attribute),
6130 get_FORM_name (attr->form));
6131 }
6132 }
6133 }
6134 while (start);
6135
6136 printf ("\n");
6137
6138 return 1;
6139}
6140
6141
6142static unsigned char *
6143display_block (data, length)
6144 unsigned char * data;
6145 unsigned long length;
6146{
6147 printf (_(" %lu byte block: "), length);
6148
6149 while (length --)
148d3c43 6150 printf ("%lx ", (unsigned long) byte_get (data ++, 1));
252b5132
RH
6151
6152 return data;
6153}
6154
6155static void
eb6bd4d3 6156decode_location_expression (data, pointer_size, length)
252b5132
RH
6157 unsigned char * data;
6158 unsigned int pointer_size;
584da044 6159 unsigned long length;
252b5132 6160{
584da044
NC
6161 unsigned op;
6162 int bytes_read;
6163 unsigned long uvalue;
6164 unsigned char * end = data + length;
252b5132 6165
eb6bd4d3 6166 while (data < end)
252b5132 6167 {
eb6bd4d3 6168 op = * data ++;
252b5132 6169
eb6bd4d3
JM
6170 switch (op)
6171 {
6172 case DW_OP_addr:
6173 printf ("DW_OP_addr: %lx",
6174 (unsigned long) byte_get (data, pointer_size));
6175 data += pointer_size;
6176 break;
6177 case DW_OP_deref:
6178 printf ("DW_OP_deref");
6179 break;
6180 case DW_OP_const1u:
6181 printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
6182 break;
6183 case DW_OP_const1s:
6184 printf ("DW_OP_const1s: %ld", (long) byte_get (data++, 1));
6185 break;
6186 case DW_OP_const2u:
6187 printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
6188 data += 2;
6189 break;
6190 case DW_OP_const2s:
6191 printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
6192 data += 2;
6193 break;
6194 case DW_OP_const4u:
6195 printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
6196 data += 4;
6197 break;
6198 case DW_OP_const4s:
6199 printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
6200 data += 4;
6201 break;
6202 case DW_OP_const8u:
6203 printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
6204 (unsigned long) byte_get (data + 4, 4));
6205 data += 8;
6206 break;
6207 case DW_OP_const8s:
6208 printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
6209 (long) byte_get (data + 4, 4));
6210 data += 8;
6211 break;
6212 case DW_OP_constu:
6213 printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
6214 data += bytes_read;
6215 break;
6216 case DW_OP_consts:
6217 printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
6218 data += bytes_read;
6219 break;
6220 case DW_OP_dup:
6221 printf ("DW_OP_dup");
6222 break;
6223 case DW_OP_drop:
6224 printf ("DW_OP_drop");
6225 break;
6226 case DW_OP_over:
6227 printf ("DW_OP_over");
6228 break;
6229 case DW_OP_pick:
6230 printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
6231 break;
6232 case DW_OP_swap:
6233 printf ("DW_OP_swap");
6234 break;
6235 case DW_OP_rot:
6236 printf ("DW_OP_rot");
6237 break;
6238 case DW_OP_xderef:
6239 printf ("DW_OP_xderef");
6240 break;
6241 case DW_OP_abs:
6242 printf ("DW_OP_abs");
6243 break;
6244 case DW_OP_and:
6245 printf ("DW_OP_and");
6246 break;
6247 case DW_OP_div:
6248 printf ("DW_OP_div");
6249 break;
6250 case DW_OP_minus:
6251 printf ("DW_OP_minus");
6252 break;
6253 case DW_OP_mod:
6254 printf ("DW_OP_mod");
6255 break;
6256 case DW_OP_mul:
6257 printf ("DW_OP_mul");
6258 break;
6259 case DW_OP_neg:
6260 printf ("DW_OP_neg");
6261 break;
6262 case DW_OP_not:
6263 printf ("DW_OP_not");
6264 break;
6265 case DW_OP_or:
6266 printf ("DW_OP_or");
6267 break;
6268 case DW_OP_plus:
6269 printf ("DW_OP_plus");
6270 break;
6271 case DW_OP_plus_uconst:
6272 printf ("DW_OP_plus_uconst: %lu",
6273 read_leb128 (data, &bytes_read, 0));
6274 data += bytes_read;
6275 break;
6276 case DW_OP_shl:
6277 printf ("DW_OP_shl");
6278 break;
6279 case DW_OP_shr:
6280 printf ("DW_OP_shr");
6281 break;
6282 case DW_OP_shra:
6283 printf ("DW_OP_shra");
6284 break;
6285 case DW_OP_xor:
6286 printf ("DW_OP_xor");
6287 break;
6288 case DW_OP_bra:
6289 printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
6290 data += 2;
6291 break;
6292 case DW_OP_eq:
6293 printf ("DW_OP_eq");
6294 break;
6295 case DW_OP_ge:
6296 printf ("DW_OP_ge");
6297 break;
6298 case DW_OP_gt:
6299 printf ("DW_OP_gt");
6300 break;
6301 case DW_OP_le:
6302 printf ("DW_OP_le");
6303 break;
6304 case DW_OP_lt:
6305 printf ("DW_OP_lt");
6306 break;
6307 case DW_OP_ne:
6308 printf ("DW_OP_ne");
6309 break;
6310 case DW_OP_skip:
6311 printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
6312 data += 2;
6313 break;
6314
6315 case DW_OP_lit0:
6316 case DW_OP_lit1:
6317 case DW_OP_lit2:
6318 case DW_OP_lit3:
6319 case DW_OP_lit4:
6320 case DW_OP_lit5:
6321 case DW_OP_lit6:
6322 case DW_OP_lit7:
6323 case DW_OP_lit8:
6324 case DW_OP_lit9:
6325 case DW_OP_lit10:
6326 case DW_OP_lit11:
6327 case DW_OP_lit12:
6328 case DW_OP_lit13:
6329 case DW_OP_lit14:
6330 case DW_OP_lit15:
6331 case DW_OP_lit16:
6332 case DW_OP_lit17:
6333 case DW_OP_lit18:
6334 case DW_OP_lit19:
6335 case DW_OP_lit20:
6336 case DW_OP_lit21:
6337 case DW_OP_lit22:
6338 case DW_OP_lit23:
6339 case DW_OP_lit24:
6340 case DW_OP_lit25:
6341 case DW_OP_lit26:
6342 case DW_OP_lit27:
6343 case DW_OP_lit28:
6344 case DW_OP_lit29:
6345 case DW_OP_lit30:
6346 case DW_OP_lit31:
6347 printf ("DW_OP_lit%d", op - DW_OP_lit0);
6348 break;
6349
6350 case DW_OP_reg0:
6351 case DW_OP_reg1:
6352 case DW_OP_reg2:
6353 case DW_OP_reg3:
6354 case DW_OP_reg4:
6355 case DW_OP_reg5:
6356 case DW_OP_reg6:
6357 case DW_OP_reg7:
6358 case DW_OP_reg8:
6359 case DW_OP_reg9:
6360 case DW_OP_reg10:
6361 case DW_OP_reg11:
6362 case DW_OP_reg12:
6363 case DW_OP_reg13:
6364 case DW_OP_reg14:
6365 case DW_OP_reg15:
6366 case DW_OP_reg16:
6367 case DW_OP_reg17:
6368 case DW_OP_reg18:
6369 case DW_OP_reg19:
6370 case DW_OP_reg20:
6371 case DW_OP_reg21:
6372 case DW_OP_reg22:
6373 case DW_OP_reg23:
6374 case DW_OP_reg24:
6375 case DW_OP_reg25:
6376 case DW_OP_reg26:
6377 case DW_OP_reg27:
6378 case DW_OP_reg28:
6379 case DW_OP_reg29:
6380 case DW_OP_reg30:
6381 case DW_OP_reg31:
6382 printf ("DW_OP_reg%d", op - DW_OP_reg0);
6383 break;
6384
6385 case DW_OP_breg0:
6386 case DW_OP_breg1:
6387 case DW_OP_breg2:
6388 case DW_OP_breg3:
6389 case DW_OP_breg4:
6390 case DW_OP_breg5:
6391 case DW_OP_breg6:
6392 case DW_OP_breg7:
6393 case DW_OP_breg8:
6394 case DW_OP_breg9:
6395 case DW_OP_breg10:
6396 case DW_OP_breg11:
6397 case DW_OP_breg12:
6398 case DW_OP_breg13:
6399 case DW_OP_breg14:
6400 case DW_OP_breg15:
6401 case DW_OP_breg16:
6402 case DW_OP_breg17:
6403 case DW_OP_breg18:
6404 case DW_OP_breg19:
6405 case DW_OP_breg20:
6406 case DW_OP_breg21:
6407 case DW_OP_breg22:
6408 case DW_OP_breg23:
6409 case DW_OP_breg24:
6410 case DW_OP_breg25:
6411 case DW_OP_breg26:
6412 case DW_OP_breg27:
6413 case DW_OP_breg28:
6414 case DW_OP_breg29:
6415 case DW_OP_breg30:
6416 case DW_OP_breg31:
6417 printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
6418 read_leb128 (data, &bytes_read, 1));
6419 data += bytes_read;
6420 break;
6421
6422 case DW_OP_regx:
6423 printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
6424 data += bytes_read;
6425 break;
6426 case DW_OP_fbreg:
6427 printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
6428 data += bytes_read;
6429 break;
6430 case DW_OP_bregx:
6431 uvalue = read_leb128 (data, &bytes_read, 0);
6432 data += bytes_read;
6433 printf ("DW_OP_bregx: %lu %ld", uvalue,
6434 read_leb128 (data, &bytes_read, 1));
6435 data += bytes_read;
6436 break;
6437 case DW_OP_piece:
6438 printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
6439 data += bytes_read;
6440 break;
6441 case DW_OP_deref_size:
6442 printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
6443 break;
6444 case DW_OP_xderef_size:
6445 printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
6446 break;
6447 case DW_OP_nop:
6448 printf ("DW_OP_nop");
6449 break;
6450
6451 default:
6452 if (op >= DW_OP_lo_user
6453 && op <= DW_OP_hi_user)
6454 printf (_("(User defined location op)"));
6455 else
6456 printf (_("(Unknown location op)"));
6457 /* No way to tell where the next op is, so just bail. */
6458 return;
6459 }
252b5132
RH
6460 }
6461}
6462
6463
6464static unsigned char *
1fa37306 6465read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
252b5132
RH
6466 unsigned long attribute;
6467 unsigned long form;
6468 unsigned char * data;
1fa37306 6469 unsigned long cu_offset;
252b5132
RH
6470 unsigned long pointer_size;
6471{
b4c96d0d
ILT
6472 unsigned long uvalue = 0;
6473 unsigned char * block_start = NULL;
252b5132 6474 int bytes_read;
252b5132
RH
6475
6476 printf (" %-18s:", get_AT_name (attribute));
6477
252b5132
RH
6478 switch (form)
6479 {
60bcf0fa
NC
6480 default:
6481 break;
76da6bbe 6482
252b5132
RH
6483 case DW_FORM_ref_addr:
6484 case DW_FORM_addr:
6485 uvalue = byte_get (data, pointer_size);
252b5132
RH
6486 data += pointer_size;
6487 break;
6488
6489 case DW_FORM_ref1:
6490 case DW_FORM_flag:
6491 case DW_FORM_data1:
6492 uvalue = byte_get (data ++, 1);
252b5132
RH
6493 break;
6494
6495 case DW_FORM_ref2:
6496 case DW_FORM_data2:
6497 uvalue = byte_get (data, 2);
6498 data += 2;
252b5132
RH
6499 break;
6500
6501 case DW_FORM_ref4:
6502 case DW_FORM_data4:
6503 uvalue = byte_get (data, 4);
6504 data += 4;
1fa37306
JM
6505 break;
6506
6507 case DW_FORM_sdata:
6508 uvalue = read_leb128 (data, & bytes_read, 1);
6509 data += bytes_read;
6510 break;
6511
6512 case DW_FORM_ref_udata:
6513 case DW_FORM_udata:
6514 uvalue = read_leb128 (data, & bytes_read, 0);
6515 data += bytes_read;
6516 break;
6517 }
6518
6519 switch (form)
6520 {
6521 case DW_FORM_ref_addr:
6522 printf (" <#%lx>", uvalue);
6523 break;
76da6bbe 6524
1fa37306
JM
6525 case DW_FORM_ref1:
6526 case DW_FORM_ref2:
6527 case DW_FORM_ref4:
6528 case DW_FORM_ref_udata:
6529 printf (" <%lx>", uvalue + cu_offset);
6530 break;
6531
6532 case DW_FORM_addr:
6533 printf (" %#lx", uvalue);
6534
6535 case DW_FORM_flag:
6536 case DW_FORM_data1:
6537 case DW_FORM_data2:
6538 case DW_FORM_data4:
6539 case DW_FORM_sdata:
6540 case DW_FORM_udata:
6541 printf (" %ld", uvalue);
252b5132
RH
6542 break;
6543
6544 case DW_FORM_ref8:
6545 case DW_FORM_data8:
6546 uvalue = byte_get (data, 4);
6547 printf (" %lx", uvalue);
148d3c43 6548 printf (" %lx", (unsigned long) byte_get (data + 4, 4));
252b5132
RH
6549 data += 8;
6550 break;
6551
6552 case DW_FORM_string:
6553 printf (" %s", data);
3c9f43b1 6554 data += strlen ((char *) data) + 1;
252b5132
RH
6555 break;
6556
252b5132
RH
6557 case DW_FORM_block:
6558 uvalue = read_leb128 (data, & bytes_read, 0);
6559 block_start = data + bytes_read;
6560 data = display_block (block_start, uvalue);
252b5132
RH
6561 break;
6562
6563 case DW_FORM_block1:
6564 uvalue = byte_get (data, 1);
6565 block_start = data + 1;
6566 data = display_block (block_start, uvalue);
252b5132
RH
6567 break;
6568
6569 case DW_FORM_block2:
6570 uvalue = byte_get (data, 2);
6571 block_start = data + 2;
6572 data = display_block (block_start, uvalue);
252b5132
RH
6573 break;
6574
6575 case DW_FORM_block4:
6576 uvalue = byte_get (data, 4);
6577 block_start = data + 4;
6578 data = display_block (block_start, uvalue);
252b5132
RH
6579 break;
6580
6581 case DW_FORM_strp:
6582 case DW_FORM_indirect:
6583 warn (_("Unable to handle FORM: %d"), form);
6584 break;
6585
6586 default:
6587 warn (_("Unrecognised form: %d"), form);
6588 break;
6589 }
6590
6591 /* For some attributes we can display futher information. */
6592
6593 printf ("\t");
6594
6595 switch (attribute)
6596 {
6597 case DW_AT_inline:
6598 switch (uvalue)
6599 {
6600 case DW_INL_not_inlined: printf (_("(not inlined)")); break;
6601 case DW_INL_inlined: printf (_("(inlined)")); break;
6602 case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
6603 case DW_INL_declared_inlined: printf (_("(declared as inline and inlined)")); break;
6604 default: printf (_(" (Unknown inline attribute value: %lx)"), uvalue); break;
6605 }
6606 break;
6607
252b5132
RH
6608 case DW_AT_language:
6609 switch (uvalue)
6610 {
6611 case DW_LANG_C: printf ("(non-ANSI C)"); break;
6612 case DW_LANG_C89: printf ("(ANSI C)"); break;
6613 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
6614 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
6615 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
6616 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
6617 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
6618 case DW_LANG_Ada83: printf ("(Ada)"); break;
6619 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
6620 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
6621 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
6622 default: printf ("(Unknown: %lx)", uvalue); break;
6623 }
6624 break;
6625
6626 case DW_AT_encoding:
6627 switch (uvalue)
6628 {
6629 case DW_ATE_void: printf ("(void)"); break;
6630 case DW_ATE_address: printf ("(machine address)"); break;
6631 case DW_ATE_boolean: printf ("(boolean)"); break;
6632 case DW_ATE_complex_float: printf ("(complex float)"); break;
6633 case DW_ATE_float: printf ("(float)"); break;
6634 case DW_ATE_signed: printf ("(signed)"); break;
6635 case DW_ATE_signed_char: printf ("(signed char)"); break;
6636 case DW_ATE_unsigned: printf ("(unsigned)"); break;
6637 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
6638 default:
6639 if (uvalue >= DW_ATE_lo_user
6640 && uvalue <= DW_ATE_hi_user)
6641 printf ("(user defined type)");
6642 else
6643 printf ("(unknown type)");
6644 break;
6645 }
6646 break;
6647
6648 case DW_AT_accessibility:
6649 switch (uvalue)
6650 {
6651 case DW_ACCESS_public: printf ("(public)"); break;
6652 case DW_ACCESS_protected: printf ("(protected)"); break;
6653 case DW_ACCESS_private: printf ("(private)"); break;
6654 default: printf ("(unknown accessibility)"); break;
6655 }
6656 break;
6657
6658 case DW_AT_visibility:
6659 switch (uvalue)
6660 {
6661 case DW_VIS_local: printf ("(local)"); break;
6662 case DW_VIS_exported: printf ("(exported)"); break;
6663 case DW_VIS_qualified: printf ("(qualified)"); break;
6664 default: printf ("(unknown visibility)"); break;
6665 }
6666 break;
6667
6668 case DW_AT_virtuality:
6669 switch (uvalue)
6670 {
6671 case DW_VIRTUALITY_none: printf ("(none)"); break;
6672 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
6673 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
6674 default: printf ("(unknown virtuality)"); break;
6675 }
6676 break;
6677
6678 case DW_AT_identifier_case:
6679 switch (uvalue)
6680 {
6681 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
6682 case DW_ID_up_case: printf ("(up_case)"); break;
6683 case DW_ID_down_case: printf ("(down_case)"); break;
6684 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
6685 default: printf ("(unknown case)"); break;
6686 }
6687 break;
6688
6689 case DW_AT_calling_convention:
6690 switch (uvalue)
6691 {
6692 case DW_CC_normal: printf ("(normal)"); break;
6693 case DW_CC_program: printf ("(program)"); break;
6694 case DW_CC_nocall: printf ("(nocall)"); break;
6695 default:
6696 if (uvalue >= DW_CC_lo_user
6697 && uvalue <= DW_CC_hi_user)
6698 printf ("(user defined)");
6699 else
6700 printf ("(unknown convention)");
6701 }
6702 break;
6703
eb6bd4d3 6704 case DW_AT_frame_base:
252b5132
RH
6705 case DW_AT_location:
6706 case DW_AT_data_member_location:
6707 case DW_AT_vtable_elem_location:
eb6bd4d3
JM
6708 if (block_start)
6709 {
6710 printf ("(");
6711 decode_location_expression (block_start, pointer_size, uvalue);
6712 printf (")");
6713 }
252b5132
RH
6714 break;
6715
6716 default:
6717 break;
6718 }
6719
6720 printf ("\n");
6721 return data;
6722}
6723
6724static int
6725display_debug_info (section, start, file)
6726 Elf32_Internal_Shdr * section;
6727 unsigned char * start;
6728 FILE * file;
6729{
6730 unsigned char * end = start + section->sh_size;
6731 unsigned char * section_begin = start;
6732
6733 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
6734
6735 while (start < end)
6736 {
6737 DWARF2_External_CompUnit * external;
6738 DWARF2_Internal_CompUnit compunit;
6739 unsigned char * tags;
6740 int i;
6741 int level;
1fa37306 6742 unsigned long cu_offset;
252b5132
RH
6743
6744 external = (DWARF2_External_CompUnit *) start;
6745
6746 compunit.cu_length = BYTE_GET (external->cu_length);
6747 compunit.cu_version = BYTE_GET (external->cu_version);
6748 compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
6749 compunit.cu_pointer_size = BYTE_GET (external->cu_pointer_size);
6750
6751 tags = start + sizeof (* external);
1fa37306 6752 cu_offset = start - section_begin;
252b5132
RH
6753 start += compunit.cu_length + sizeof (external->cu_length);
6754
09fd7e38
JM
6755 printf (_(" Compilation Unit @ %lx:\n"), cu_offset);
6756 printf (_(" Length: %ld\n"), compunit.cu_length);
6757 printf (_(" Version: %d\n"), compunit.cu_version);
6758 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
6759 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
6760
252b5132
RH
6761 if (compunit.cu_version != 2)
6762 {
6763 warn (_("Only version 2 DWARF debug information is currently supported.\n"));
6764 continue;
6765 }
6766
252b5132
RH
6767 if (first_abbrev != NULL)
6768 free_abbrevs ();
6769
6770 /* Read in the abbrevs used by this compilation unit. */
6771
6772 {
6773 Elf32_Internal_Shdr * sec;
6774 unsigned char * begin;
6775
6776 /* Locate the .debug_abbrev section and process it. */
6777 for (i = 0, sec = section_headers;
6778 i < elf_header.e_shnum;
6779 i ++, sec ++)
6780 if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
6781 break;
6782
6783 if (i == -1 || sec->sh_size == 0)
6784 {
6785 warn (_("Unable to locate .debug_abbrev section!\n"));
6786 return 0;
6787 }
6788
6789 GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, unsigned char *,
6790 "debug_abbrev section data");
6791
6792 process_abbrev_section (begin + compunit.cu_abbrev_offset,
6793 begin + sec->sh_size);
6794
6795 free (begin);
6796 }
6797
6798 level = 0;
6799 while (tags < start)
6800 {
6801 int bytes_read;
b4c96d0d 6802 unsigned long abbrev_number;
252b5132
RH
6803 abbrev_entry * entry;
6804 abbrev_attr * attr;
6805
6806 abbrev_number = read_leb128 (tags, & bytes_read, 0);
6807 tags += bytes_read;
6808
6809 /* A null DIE marks the end of a list of children. */
6810 if (abbrev_number == 0)
6811 {
6812 --level;
6813 continue;
6814 }
6815
6816 /* Scan through the abbreviation list until we reach the
6817 correct entry. */
6818 for (entry = first_abbrev;
6819 entry && entry->entry != abbrev_number;
6820 entry = entry->next)
6821 continue;
6822
6823 if (entry == NULL)
6824 {
b4c96d0d 6825 warn (_("Unable to locate entry %lu in the abbreviation table\n"),
252b5132
RH
6826 abbrev_number);
6827 return 0;
6828 }
6829
b4c96d0d 6830 printf (_(" <%d><%x>: Abbrev Number: %lu (%s)\n"),
252b5132
RH
6831 level, tags - section_begin - bytes_read,
6832 abbrev_number,
6833 get_TAG_name (entry->tag));
6834
6835 for (attr = entry->first_attr; attr; attr = attr->next)
6836 tags = read_and_display_attr (attr->attribute,
6837 attr->form,
1fa37306 6838 tags, cu_offset,
252b5132
RH
6839 compunit.cu_pointer_size);
6840
6841 if (entry->children)
6842 ++level;
6843 }
6844 }
6845
6846 printf ("\n");
6847
6848 return 1;
6849}
6850
6851static int
6852display_debug_aranges (section, start, file)
6853 Elf32_Internal_Shdr * section;
6854 unsigned char * start;
b4c96d0d 6855 FILE * file ATTRIBUTE_UNUSED;
252b5132
RH
6856{
6857 unsigned char * end = start + section->sh_size;
6858
6859 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
6860
6861 while (start < end)
6862 {
6863 DWARF2_External_ARange * external;
6864 DWARF2_Internal_ARange arange;
6865 unsigned char * ranges;
6866 unsigned long length;
6867 unsigned long address;
7a4b7442 6868 int excess;
252b5132
RH
6869
6870 external = (DWARF2_External_ARange *) start;
6871
6872 arange.ar_length = BYTE_GET (external->ar_length);
6873 arange.ar_version = BYTE_GET (external->ar_version);
6874 arange.ar_info_offset = BYTE_GET (external->ar_info_offset);
6875 arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
6876 arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
6877
3f215a10
NC
6878 if (arange.ar_version != 2)
6879 {
6880 warn (_("Only DWARF 2 aranges are currently supported.\n"));
6881 break;
6882 }
6883
252b5132
RH
6884 printf (_(" Length: %ld\n"), arange.ar_length);
6885 printf (_(" Version: %d\n"), arange.ar_version);
6886 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
6887 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
6888 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
6889
6890 printf (_("\n Address Length\n"));
6891
6892 ranges = start + sizeof (* external);
6893
7a4b7442 6894 /* Must pad to an alignment boundary that is twice the pointer size. */
584da044 6895 excess = sizeof (* external) % (2 * arange.ar_pointer_size);
7a4b7442
NC
6896 if (excess)
6897 ranges += (2 * arange.ar_pointer_size) - excess;
6898
252b5132
RH
6899 for (;;)
6900 {
6901 address = byte_get (ranges, arange.ar_pointer_size);
6902
252b5132
RH
6903 ranges += arange.ar_pointer_size;
6904
6905 length = byte_get (ranges, arange.ar_pointer_size);
6906
6907 ranges += arange.ar_pointer_size;
6908
7a4b7442
NC
6909 /* A pair of zeros marks the end of the list. */
6910 if (address == 0 && length == 0)
6911 break;
103f02d3 6912
252b5132
RH
6913 printf (" %8.8lx %lu\n", address, length);
6914 }
6915
6916 start += arange.ar_length + sizeof (external->ar_length);
6917 }
6918
6919 printf ("\n");
6920
6921 return 1;
6922}
6923
c47d488e
DD
6924typedef struct Frame_Chunk
6925{
584da044
NC
6926 struct Frame_Chunk * next;
6927 unsigned char * chunk_start;
6928 int ncols;
a98cc2b2 6929 /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */
584da044
NC
6930 short int * col_type;
6931 int * col_offset;
6932 char * augmentation;
6933 unsigned int code_factor;
6934 unsigned int data_factor;
6935 unsigned long pc_begin;
6936 unsigned long pc_range;
6937 int cfa_reg;
6938 int cfa_offset;
6939 int ra;
c47d488e
DD
6940}
6941Frame_Chunk;
6942
a98cc2b2
AH
6943/* A marker for a col_type that means this column was never referenced
6944 in the frame info. */
6945#define DW_CFA_unreferenced (-1)
6946
c47d488e
DD
6947static void
6948frame_need_space (fc, reg)
584da044 6949 Frame_Chunk * fc;
c47d488e
DD
6950 int reg;
6951{
6952 int prev = fc->ncols;
6953
6954 if (reg < fc->ncols)
6955 return;
584da044 6956
c47d488e 6957 fc->ncols = reg + 1;
a98cc2b2
AH
6958 fc->col_type = (short int *) xrealloc (fc->col_type,
6959 fc->ncols * sizeof (short int));
c47d488e
DD
6960 fc->col_offset = (int *) xrealloc (fc->col_offset,
6961 fc->ncols * sizeof (int));
6962
6963 while (prev < fc->ncols)
6964 {
a98cc2b2 6965 fc->col_type[prev] = DW_CFA_unreferenced;
c47d488e
DD
6966 fc->col_offset[prev] = 0;
6967 prev++;
6968 }
6969}
6970
6971static void
6972frame_display_row (fc, need_col_headers, max_regs)
584da044
NC
6973 Frame_Chunk * fc;
6974 int * need_col_headers;
6975 int * max_regs;
c47d488e
DD
6976{
6977 int r;
6978 char tmp[100];
6979
584da044
NC
6980 if (* max_regs < fc->ncols)
6981 * max_regs = fc->ncols;
6982
6983 if (* need_col_headers)
c47d488e 6984 {
584da044
NC
6985 * need_col_headers = 0;
6986
c47d488e 6987 printf (" LOC CFA ");
584da044
NC
6988
6989 for (r = 0; r < * max_regs; r++)
a98cc2b2
AH
6990 if (fc->col_type[r] != DW_CFA_unreferenced)
6991 {
6992 if (r == fc->ra)
6993 printf ("ra ");
6994 else
6995 printf ("r%-4d", r);
6996 }
584da044 6997
c47d488e
DD
6998 printf ("\n");
6999 }
584da044 7000
c47d488e
DD
7001 printf ("%08x ", (unsigned int) fc->pc_begin);
7002 sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
7003 printf ("%-8s ", tmp);
584da044
NC
7004
7005 for (r = 0; r < fc->ncols; r++)
c47d488e 7006 {
a98cc2b2 7007 if (fc->col_type[r] != DW_CFA_unreferenced)
c47d488e 7008 {
a98cc2b2
AH
7009 switch (fc->col_type[r])
7010 {
7011 case DW_CFA_undefined:
7012 strcpy (tmp, "u");
7013 break;
7014 case DW_CFA_same_value:
7015 strcpy (tmp, "s");
7016 break;
7017 case DW_CFA_offset:
7018 sprintf (tmp, "c%+d", fc->col_offset[r]);
7019 break;
7020 case DW_CFA_register:
7021 sprintf (tmp, "r%d", fc->col_offset[r]);
7022 break;
7023 default:
7024 strcpy (tmp, "n/a");
7025 break;
7026 }
7027 printf ("%-5s", tmp);
c47d488e 7028 }
c47d488e
DD
7029 }
7030 printf ("\n");
7031}
7032
7033#define GET(N) byte_get (start, N); start += N
584da044
NC
7034#define LEB() read_leb128 (start, & length_return, 0); start += length_return
7035#define SLEB() read_leb128 (start, & length_return, 1); start += length_return
c47d488e
DD
7036
7037static int
7038display_debug_frames (section, start, file)
7039 Elf32_Internal_Shdr * section;
7040 unsigned char * start;
7041 FILE * file ATTRIBUTE_UNUSED;
7042{
7043 unsigned char * end = start + section->sh_size;
584da044
NC
7044 unsigned char * section_start = start;
7045 Frame_Chunk * chunks = 0;
7046 Frame_Chunk * remembered_state = 0;
7047 Frame_Chunk * rs;
7048 int is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
7049 int length_return;
7050 int max_regs = 0;
c47d488e
DD
7051
7052 printf (_("The section %s contains:\n"), SECTION_NAME (section));
7053
7054 while (start < end)
7055 {
584da044
NC
7056 unsigned char * saved_start;
7057 unsigned char * block_end;
7058 unsigned long length;
7059 unsigned long cie_id;
7060 Frame_Chunk * fc;
7061 Frame_Chunk * cie;
7062 int need_col_headers = 1;
c47d488e
DD
7063
7064 saved_start = start;
7065 length = byte_get (start, 4); start += 4;
7066
7067 if (length == 0)
7068 return 1;
7069
7070 block_end = saved_start + length + 4;
7071 cie_id = byte_get (start, 4); start += 4;
7072
7073 printf ("\n%08x %08lx %08lx ", saved_start - section_start, length, cie_id);
7074
7075 if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
7076 {
7077 fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
7078 memset (fc, 0, sizeof (Frame_Chunk));
7079
7080 fc->next = chunks;
7081 chunks = fc;
7082 fc->chunk_start = saved_start;
7083 fc->ncols = 0;
a98cc2b2 7084 fc->col_type = (short int *) xmalloc (sizeof (short int));
c47d488e
DD
7085 fc->col_offset = (int *) xmalloc (sizeof (int));
7086 frame_need_space (fc, max_regs-1);
7087
7088 start ++; /* version */
7089 fc->augmentation = start;
584da044
NC
7090
7091 while (* start)
7092 start++;
7093
7094 start++; /* skip past NUL */
7095
c47d488e
DD
7096 if (fc->augmentation[0] == 'z')
7097 {
7098 int xtra;
7099 fc->code_factor = LEB ();
7100 fc->data_factor = SLEB ();
7101 fc->ra = byte_get (start, 1); start += 1;
7102 xtra = LEB ();
7103 printf ("skipping %d extra bytes\n", xtra);
7104 start += xtra;
7105 }
7106 else if (strcmp (fc->augmentation, "eh") == 0)
7107 {
7108 start += 4;
7109 fc->code_factor = LEB ();
7110 fc->data_factor = SLEB ();
7111 fc->ra = byte_get (start, 1); start += 1;
7112 }
7113 else
7114 {
7115 fc->code_factor = LEB ();
7116 fc->data_factor = SLEB ();
7117 fc->ra = byte_get (start, 1); start += 1;
7118 }
7119 cie = fc;
7120 printf ("CIE \"%s\" cf=%d df=%d ra=%d\n",
7121 fc->augmentation, fc->code_factor, fc->data_factor, fc->ra);
7122
7123 frame_need_space (fc, fc->ra);
7124 }
7125 else
7126 {
584da044 7127 unsigned char * look_for;
c47d488e 7128 static Frame_Chunk fde_fc;
584da044
NC
7129
7130 fc = & fde_fc;
c47d488e
DD
7131 memset (fc, 0, sizeof (Frame_Chunk));
7132
7133 look_for = is_eh ? start-4-cie_id : (unsigned char *) cie_id;
7134
7135 fc->pc_begin = byte_get (start, 4); start += 4;
7136 fc->pc_range = byte_get (start, 4); start += 4;
7137
7138 for (cie=chunks; cie && (cie->chunk_start != look_for); cie = cie->next);
7139 if (!cie)
7140 {
7141 warn ("Invalid CIE pointer %08x in FDE at %08x\n", cie_id, saved_start);
7142 start = block_end;
7143 fc->ncols = 0;
a98cc2b2 7144 fc->col_type = (short int *) xmalloc (sizeof (short int));
c47d488e 7145 fc->col_offset = (int *) xmalloc (sizeof (int));
584da044 7146 frame_need_space (fc, max_regs - 1);
c47d488e
DD
7147 cie = fc;
7148 fc->augmentation = "";
7149 }
7150 else
7151 {
7152 fc->ncols = cie->ncols;
a98cc2b2 7153 fc->col_type = (short int *) xmalloc (fc->ncols * sizeof (short int));
c47d488e 7154 fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
a98cc2b2 7155 memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
c47d488e
DD
7156 memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
7157 fc->augmentation = cie->augmentation;
7158 fc->code_factor = cie->code_factor;
7159 fc->data_factor = cie->data_factor;
7160 fc->cfa_reg = cie->cfa_reg;
7161 fc->cfa_offset = cie->cfa_offset;
7162 fc->ra = cie->ra;
7163 frame_need_space (fc, max_regs-1);
7164 }
7165
7166 if (cie->augmentation[0] == 'z')
7167 {
7168 unsigned long l = LEB ();
7169 start += l;
7170 }
7171
7172 printf ("FDE cie=%08x pc=%08lx..%08lx\n",
7173 cie->chunk_start-section_start, fc->pc_begin,
7174 fc->pc_begin + fc->pc_range);
7175 }
7176
7177 /* At this point, fc is the current chunk, cie (if any) is set, and we're
7178 about to interpret instructions for the chunk. */
7179
7180 /* This exists for readelf maintainers. */
7181#define FDEBUG 0
7182
a98cc2b2
AH
7183 {
7184 /* Start by making a pass over the chunk, allocating storage
7185 and taking note of what registers are used. */
584da044 7186 unsigned char * tmp = start;
a98cc2b2 7187
a98cc2b2
AH
7188 while (start < block_end)
7189 {
7190 unsigned op, opa;
7191 unsigned long reg;
7192 bfd_vma vma;
7193
584da044 7194 op = * start ++;
a98cc2b2
AH
7195 opa = op & 0x3f;
7196 if (op & 0xc0)
7197 op &= 0xc0;
7198
7199 /* Warning: if you add any more cases to this switch, be
7200 sure to add them to the corresponding switch below. */
7201 switch (op)
7202 {
7203 case DW_CFA_advance_loc:
7204 break;
7205 case DW_CFA_offset:
7206 LEB ();
7207 frame_need_space (fc, opa);
7208 fc->col_type[opa] = DW_CFA_undefined;
7209 break;
7210 case DW_CFA_restore:
7211 frame_need_space (fc, opa);
7212 fc->col_type[opa] = DW_CFA_undefined;
7213 break;
7214 case DW_CFA_set_loc:
7215 start += sizeof (vma);
7216 break;
7217 case DW_CFA_advance_loc1:
7218 start += 1;
7219 break;
7220 case DW_CFA_advance_loc2:
7221 start += 2;
7222 break;
7223 case DW_CFA_advance_loc4:
7224 start += 4;
7225 break;
7226 case DW_CFA_offset_extended:
7227 reg = LEB (); LEB ();
7228 frame_need_space (fc, reg);
7229 fc->col_type[reg] = DW_CFA_undefined;
7230 break;
7231 case DW_CFA_restore_extended:
7232 reg = LEB ();
7233 frame_need_space (fc, reg);
7234 fc->col_type[reg] = DW_CFA_undefined;
7235 break;
7236 case DW_CFA_undefined:
7237 reg = LEB ();
7238 frame_need_space (fc, reg);
7239 fc->col_type[reg] = DW_CFA_undefined;
7240 break;
7241 case DW_CFA_same_value:
7242 reg = LEB ();
7243 frame_need_space (fc, reg);
7244 fc->col_type[reg] = DW_CFA_undefined;
7245 break;
7246 case DW_CFA_register:
7247 reg = LEB (); LEB ();
7248 frame_need_space (fc, reg);
7249 fc->col_type[reg] = DW_CFA_undefined;
7250 break;
7251 case DW_CFA_def_cfa:
7252 LEB (); LEB ();
7253 break;
7254 case DW_CFA_def_cfa_register:
7255 LEB ();
7256 break;
7257 case DW_CFA_def_cfa_offset:
7258 LEB ();
7259 break;
7260#ifndef DW_CFA_GNU_args_size
7261#define DW_CFA_GNU_args_size 0x2e
7262#endif
7263 case DW_CFA_GNU_args_size:
7264 LEB ();
7265 break;
7266#ifndef DW_CFA_GNU_negative_offset_extended
7267#define DW_CFA_GNU_negative_offset_extended 0x2f
7268#endif
7269 case DW_CFA_GNU_negative_offset_extended:
7270 reg = LEB (); LEB ();
7271 frame_need_space (fc, reg);
7272 fc->col_type[reg] = DW_CFA_undefined;
7273
7274 default:
7275 break;
7276 }
7277 }
7278 start = tmp;
7279 }
7280
7281 /* Now we know what registers are used, make a second pass over
7282 the chunk, this time actually printing out the info. */
7283
c47d488e
DD
7284 while (start < block_end)
7285 {
7286 unsigned op, opa;
7287 unsigned long ul, reg, roffs;
7288 long l, ofs;
7289 bfd_vma vma;
7290
7291 op = * start ++;
7292 opa = op & 0x3f;
7293 if (op & 0xc0)
7294 op &= 0xc0;
7295
a98cc2b2
AH
7296 /* Warning: if you add any more cases to this switch, be
7297 sure to add them to the corresponding switch above. */
c47d488e
DD
7298 switch (op)
7299 {
7300 case DW_CFA_advance_loc:
7301 frame_display_row (fc, &need_col_headers, &max_regs);
7302#if FDEBUG
7303 printf (" DW_CFA_advance_loc: %08x = %08x + %d*%d\n",
7304 fc->pc_begin + opa * fc->code_factor, fc->pc_begin, opa, fc->code_factor);
7305#endif
7306 fc->pc_begin += opa * fc->code_factor;
7307 break;
7308
7309 case DW_CFA_offset:
c47d488e
DD
7310 roffs = LEB ();
7311#if FDEBUG
7312 printf (" DW_CFA_offset: r%d = cfa[%d*%d]\n", opa, roffs, fc->data_factor);
7313#endif
7314 fc->col_type[opa] = DW_CFA_offset;
7315 fc->col_offset[opa] = roffs * fc->data_factor;
7316 break;
7317
7318 case DW_CFA_restore:
c47d488e
DD
7319#if FDEBUG
7320 printf (" DW_CFA_restore: r%d\n", opa);
7321#endif
7322 fc->col_type[opa] = cie->col_type[opa];
7323 fc->col_offset[opa] = cie->col_offset[opa];
7324 break;
7325
7326 case DW_CFA_set_loc:
7327 frame_display_row (fc, &need_col_headers, &max_regs);
7328 vma = byte_get (start, sizeof (vma)); start += sizeof (vma);
7329#if FDEBUG
7330 printf (" DW_CFA_set_loc: %08x\n", vma);
7331#endif
7332 fc->pc_begin = vma;
7333 break;
7334
7335 case DW_CFA_advance_loc1:
7336 frame_display_row (fc, &need_col_headers, &max_regs);
7337 ofs = byte_get (start, 1); start += 1;
7338#if FDEBUG
7339 printf (" DW_CFA_advance_loc1: %08x = %08x + %d*%d\n",
7340 fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
7341#endif
7342 fc->pc_begin += ofs * fc->code_factor;
7343 break;
7344
7345 case DW_CFA_advance_loc2:
7346 frame_display_row (fc, &need_col_headers, &max_regs);
7347 ofs = byte_get (start, 2); start += 2;
7348#if FDEBUG
7349 printf (" DW_CFA_advance_loc2: %08x = %08x + %d*%d\n",
7350 fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
7351#endif
7352 fc->pc_begin += ofs * fc->code_factor;
7353 break;
7354
7355 case DW_CFA_advance_loc4:
7356 frame_display_row (fc, &need_col_headers, &max_regs);
7357 ofs = byte_get (start, 4); start += 4;
7358#if FDEBUG
7359 printf (" DW_CFA_advance_loc4: %08x = %08x + %d*%d\n",
7360 fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
7361#endif
7362 fc->pc_begin += ofs * fc->code_factor;
7363 break;
7364
7365 case DW_CFA_offset_extended:
7366 reg = LEB ();
7367 roffs = LEB ();
c47d488e
DD
7368#if FDEBUG
7369 printf (" DW_CFA_offset_extended: r%d = cfa[%d*%d]\n", reg, roffs, fc->data_factor);
7370#endif
7371 fc->col_type[reg] = DW_CFA_offset;
7372 fc->col_offset[reg] = roffs * fc->data_factor;
7373 break;
7374
7375 case DW_CFA_restore_extended:
7376 reg = LEB ();
c47d488e
DD
7377#if FDEBUG
7378 printf (" DW_CFA_restore_extended: r%d\n", reg);
7379#endif
7380 fc->col_type[reg] = cie->col_type[reg];
7381 fc->col_offset[reg] = cie->col_offset[reg];
7382 break;
7383
7384 case DW_CFA_undefined:
7385 reg = LEB ();
c47d488e
DD
7386#if FDEBUG
7387 printf (" DW_CFA_undefined: r%d\n", reg);
7388#endif
7389 fc->col_type[reg] = DW_CFA_undefined;
7390 fc->col_offset[reg] = 0;
7391 break;
7392
7393 case DW_CFA_same_value:
7394 reg = LEB ();
c47d488e
DD
7395#if FDEBUG
7396 printf (" DW_CFA_same_value: r%d\n", reg);
7397#endif
7398 fc->col_type[reg] = DW_CFA_same_value;
7399 fc->col_offset[reg] = 0;
7400 break;
7401
7402 case DW_CFA_register:
7403 reg = LEB ();
7404 roffs = LEB ();
c47d488e 7405#if FDEBUG
a98cc2b2 7406 printf (" DW_CFA_register: r%d\n", reg);
c47d488e
DD
7407#endif
7408 fc->col_type[reg] = DW_CFA_register;
7409 fc->col_offset[reg] = roffs;
7410 break;
7411
7412 case DW_CFA_remember_state:
7413#if FDEBUG
7414 printf (" DW_CFA_remember_state\n");
7415#endif
7416 rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
7417 rs->ncols = fc->ncols;
a98cc2b2 7418 rs->col_type = (short int *) xmalloc (rs->ncols * sizeof (short int));
c47d488e
DD
7419 rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
7420 memcpy (rs->col_type, fc->col_type, rs->ncols);
7421 memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
7422 rs->next = remembered_state;
7423 remembered_state = rs;
7424 break;
7425
7426 case DW_CFA_restore_state:
7427#if FDEBUG
7428 printf (" DW_CFA_restore_state\n");
7429#endif
7430 rs = remembered_state;
7431 remembered_state = rs->next;
7432 frame_need_space (fc, rs->ncols-1);
7433 memcpy (fc->col_type, rs->col_type, rs->ncols);
7434 memcpy (fc->col_offset, rs->col_offset, rs->ncols * sizeof (int));
7435 free (rs->col_type);
7436 free (rs->col_offset);
7437 free (rs);
7438 break;
7439
7440 case DW_CFA_def_cfa:
7441 fc->cfa_reg = LEB ();
7442 fc->cfa_offset = LEB ();
7443#if FDEBUG
7444 printf (" DW_CFA_def_cfa: reg %d ofs %d\n", fc->cfa_reg, fc->cfa_offset);
7445#endif
7446 break;
7447
7448 case DW_CFA_def_cfa_register:
7449 fc->cfa_reg = LEB ();
7450#if FDEBUG
7451 printf (" DW_CFA_def_cfa_reg: %d\n", fc->cfa_reg);
7452#endif
7453 break;
7454
7455 case DW_CFA_def_cfa_offset:
7456 fc->cfa_offset = LEB ();
7457#if FDEBUG
7458 printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
7459#endif
7460 break;
7461
7462 case DW_CFA_nop:
7463#if FDEBUG
7464 printf (" DW_CFA_nop\n");
7465#endif
7466 break;
7467
7468#ifndef DW_CFA_GNU_window_save
7469#define DW_CFA_GNU_window_save 0x2d
7470#endif
7471 case DW_CFA_GNU_window_save:
7472#if FDEBUG
7473 printf (" DW_CFA_GNU_window_save\n");
7474#endif
7475 break;
7476
7477#ifndef DW_CFA_GNU_args_size
7478#define DW_CFA_GNU_args_size 0x2e
7479#endif
7480 case DW_CFA_GNU_args_size:
7481 ul = LEB ();
7482#if FDEBUG
7483 printf (" DW_CFA_GNU_args_size: %d\n", ul);
7484#endif
7485 break;
7486
7487#ifndef DW_CFA_GNU_negative_offset_extended
7488#define DW_CFA_GNU_negative_offset_extended 0x2f
7489#endif
7490 case DW_CFA_GNU_negative_offset_extended:
7491 reg = LEB ();
7492 l = - LEB ();
7493 frame_need_space (fc, reg);
7494#if FDEBUG
7495 printf (" DW_CFA_GNU_negative_offset_extended: r%d = cfa[%d*%d]\n", reg, l, fc->data_factor);
7496#endif
7497 fc->col_type[reg] = DW_CFA_offset;
7498 fc->col_offset[reg] = l * fc->data_factor;
7499 break;
7500
7501 default:
7502 fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
7503 start = block_end;
7504 }
7505 }
7506
7507 frame_display_row (fc, &need_col_headers, &max_regs);
7508
7509 start = block_end;
7510 }
7511
7512 printf ("\n");
7513
7514 return 1;
7515}
7516
7517#undef GET
7518#undef LEB
7519#undef SLEB
252b5132
RH
7520
7521static int
7522display_debug_not_supported (section, start, file)
7523 Elf32_Internal_Shdr * section;
b4c96d0d
ILT
7524 unsigned char * start ATTRIBUTE_UNUSED;
7525 FILE * file ATTRIBUTE_UNUSED;
252b5132
RH
7526{
7527 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
7528 SECTION_NAME (section));
7529
7530 return 1;
7531}
7532
3590ea00
NC
7533/* Pre-scan the .debug_info section to record the size of address.
7534 When dumping the .debug_line, we use that size information, assuming
7535 that all compilation units have the same address size. */
7536static int
7537prescan_debug_info (section, start, file)
7538 Elf32_Internal_Shdr * section ATTRIBUTE_UNUSED;
7539 unsigned char * start;
7540 FILE * file ATTRIBUTE_UNUSED;
7541{
7542 DWARF2_External_CompUnit * external;
7543
7544 external = (DWARF2_External_CompUnit *) start;
7545
7546 debug_line_pointer_size = BYTE_GET (external->cu_pointer_size);
7547 return 0;
7548}
7549
252b5132 7550 /* A structure containing the name of a debug section and a pointer
3590ea00
NC
7551 to a function that can decode it. The third field is a prescan
7552 function to be run over the section before displaying any of the
7553 sections. */
252b5132
RH
7554struct
7555{
7556 char * name;
3590ea00
NC
7557 int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
7558 int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
252b5132
RH
7559}
7560debug_displays[] =
7561{
3590ea00
NC
7562 { ".debug_info", display_debug_info, prescan_debug_info },
7563 { ".debug_abbrev", display_debug_abbrev, NULL },
7564 { ".debug_line", display_debug_lines, NULL },
7565 { ".debug_aranges", display_debug_aranges, NULL },
7566 { ".debug_pubnames", display_debug_pubnames, NULL },
c47d488e
DD
7567 { ".debug_frame", display_debug_frames, NULL },
7568 { ".eh_frame", display_debug_frames, NULL },
3590ea00
NC
7569 { ".debug_macinfo", display_debug_not_supported, NULL },
7570 { ".debug_frame", display_debug_not_supported, NULL },
7571 { ".debug_str", display_debug_not_supported, NULL },
7572 { ".debug_static_func", display_debug_not_supported, NULL },
7573 { ".debug_static_vars", display_debug_not_supported, NULL },
7574 { ".debug_types", display_debug_not_supported, NULL },
7575 { ".debug_weaknames", display_debug_not_supported, NULL }
252b5132
RH
7576};
7577
7578static int
7579display_debug_section (section, file)
7580 Elf32_Internal_Shdr * section;
7581 FILE * file;
7582{
7583 char * name = SECTION_NAME (section);
7584 bfd_size_type length;
7585 unsigned char * start;
7586 int i;
7587
7588 length = section->sh_size;
7589 if (length == 0)
7590 {
7591 printf (_("\nSection '%s' has no debugging data.\n"), name);
7592 return 0;
7593 }
7594
7595 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
7596 "debug section data");
7597
7598 /* See if we know how to display the contents of this section. */
09fd7e38
JM
7599 if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
7600 name = ".debug_info";
584da044 7601
252b5132
RH
7602 for (i = NUM_ELEM (debug_displays); i--;)
7603 if (strcmp (debug_displays[i].name, name) == 0)
7604 {
7605 debug_displays[i].display (section, start, file);
7606 break;
7607 }
7608
7609 if (i == -1)
7610 printf (_("Unrecognised debug section: %s\n"), name);
7611
7612 free (start);
7613
7614 /* If we loaded in the abbrev section at some point,
7615 we must release it here. */
7616 if (first_abbrev != NULL)
7617 free_abbrevs ();
7618
7619 return 1;
7620}
7621
7622static int
7623process_section_contents (file)
7624 FILE * file;
7625{
3590ea00
NC
7626 Elf32_Internal_Shdr * section;
7627 unsigned int i;
252b5132
RH
7628
7629 if (! do_dump)
7630 return 1;
7631
3590ea00
NC
7632 /* Pre-scan the debug sections to find some debug information not
7633 present in some of them. For the .debug_line, we must find out the
7634 size of address (specified in .debug_info and .debug_aranges). */
7635 for (i = 0, section = section_headers;
7636 i < elf_header.e_shnum && i < num_dump_sects;
7637 i ++, section ++)
7638 {
7639 char * name = SECTION_NAME (section);
7640 int j;
7641
7642 if (section->sh_size == 0)
7643 continue;
7644
7645 /* See if there is some pre-scan operation for this section. */
7646 for (j = NUM_ELEM (debug_displays); j--;)
7647 if (strcmp (debug_displays[j].name, name) == 0)
7648 {
7649 if (debug_displays[j].prescan != NULL)
7650 {
7651 bfd_size_type length;
7652 unsigned char * start;
7653
7654 length = section->sh_size;
7655 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
7656 "debug section data");
7657
7658 debug_displays[j].prescan (section, start, file);
7659 free (start);
7660 }
103f02d3 7661
3590ea00
NC
7662 break;
7663 }
7664 }
7665
252b5132 7666 for (i = 0, section = section_headers;
3590ea00 7667 i < elf_header.e_shnum && i < num_dump_sects;
252b5132
RH
7668 i ++, section ++)
7669 {
7670#ifdef SUPPORT_DISASSEMBLY
7671 if (dump_sects[i] & DISASS_DUMP)
7672 disassemble_section (section, file);
7673#endif
7674 if (dump_sects[i] & HEX_DUMP)
7675 dump_section (section, file);
7676
7677 if (dump_sects[i] & DEBUG_DUMP)
7678 display_debug_section (section, file);
7679 }
7680
7681 if (i < num_dump_sects)
7682 warn (_("Some sections were not dumped because they do not exist!\n"));
7683
7684 return 1;
7685}
7686
7687static void
7688process_mips_fpe_exception (mask)
7689 int mask;
7690{
7691 if (mask)
7692 {
7693 int first = 1;
7694 if (mask & OEX_FPU_INEX)
7695 fputs ("INEX", stdout), first = 0;
7696 if (mask & OEX_FPU_UFLO)
7697 printf ("%sUFLO", first ? "" : "|"), first = 0;
7698 if (mask & OEX_FPU_OFLO)
7699 printf ("%sOFLO", first ? "" : "|"), first = 0;
7700 if (mask & OEX_FPU_DIV0)
7701 printf ("%sDIV0", first ? "" : "|"), first = 0;
7702 if (mask & OEX_FPU_INVAL)
7703 printf ("%sINVAL", first ? "" : "|");
7704 }
7705 else
7706 fputs ("0", stdout);
7707}
7708
7709static int
7710process_mips_specific (file)
9ea033b2 7711 FILE * file;
252b5132 7712{
9ea033b2 7713 Elf_Internal_Dyn * entry;
252b5132
RH
7714 size_t liblist_offset = 0;
7715 size_t liblistno = 0;
7716 size_t conflictsno = 0;
7717 size_t options_offset = 0;
7718 size_t conflicts_offset = 0;
7719
7720 /* We have a lot of special sections. Thanks SGI! */
7721 if (dynamic_segment == NULL)
7722 /* No information available. */
7723 return 0;
7724
7725 for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
7726 switch (entry->d_tag)
7727 {
7728 case DT_MIPS_LIBLIST:
7729 liblist_offset = entry->d_un.d_val - loadaddr;
7730 break;
7731 case DT_MIPS_LIBLISTNO:
7732 liblistno = entry->d_un.d_val;
7733 break;
7734 case DT_MIPS_OPTIONS:
7735 options_offset = entry->d_un.d_val - loadaddr;
7736 break;
7737 case DT_MIPS_CONFLICT:
7738 conflicts_offset = entry->d_un.d_val - loadaddr;
7739 break;
7740 case DT_MIPS_CONFLICTNO:
7741 conflictsno = entry->d_un.d_val;
7742 break;
7743 default:
7744 break;
7745 }
7746
7747 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
7748 {
9ea033b2 7749 Elf32_External_Lib * elib;
252b5132
RH
7750 size_t cnt;
7751
7752 GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
7753 elib, Elf32_External_Lib *, "liblist");
7754
16062207
ILT
7755 printf ("\nSection '.liblist' contains %lu entries:\n",
7756 (unsigned long) liblistno);
252b5132
RH
7757 fputs (" Library Time Stamp Checksum Version Flags\n",
7758 stdout);
7759
7760 for (cnt = 0; cnt < liblistno; ++cnt)
7761 {
7762 Elf32_Lib liblist;
7763 time_t time;
7764 char timebuf[20];
50da7a9c 7765 struct tm * tmp;
252b5132
RH
7766
7767 liblist.l_name = BYTE_GET (elib[cnt].l_name);
7768 time = BYTE_GET (elib[cnt].l_time_stamp);
7769 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
7770 liblist.l_version = BYTE_GET (elib[cnt].l_version);
7771 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
7772
50da7a9c
NC
7773 tmp = gmtime (&time);
7774 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
7775 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7776 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132 7777
16062207 7778 printf ("%3lu: %-20s %s %#10lx %-7ld", (unsigned long) cnt,
252b5132
RH
7779 dynamic_strings + liblist.l_name, timebuf,
7780 liblist.l_checksum, liblist.l_version);
7781
7782 if (liblist.l_flags == 0)
7783 puts (" NONE");
7784 else
7785 {
7786 static const struct
7787 {
30800947 7788 const char * name;
252b5132 7789 int bit;
30800947
NC
7790 }
7791 l_flags_vals[] =
7792 {
7793 { " EXACT_MATCH", LL_EXACT_MATCH },
7794 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
7795 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
7796 { " EXPORTS", LL_EXPORTS },
7797 { " DELAY_LOAD", LL_DELAY_LOAD },
7798 { " DELTA", LL_DELTA }
7799 };
252b5132 7800 int flags = liblist.l_flags;
b4c96d0d 7801 size_t fcnt;
252b5132
RH
7802
7803 for (fcnt = 0;
7804 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
7805 ++fcnt)
7806 if ((flags & l_flags_vals[fcnt].bit) != 0)
7807 {
7808 fputs (l_flags_vals[fcnt].name, stdout);
7809 flags ^= l_flags_vals[fcnt].bit;
7810 }
7811 if (flags != 0)
7812 printf (" %#x", (unsigned int) flags);
7813
7814 puts ("");
7815 }
7816 }
7817
7818 free (elib);
7819 }
7820
7821 if (options_offset != 0)
7822 {
9ea033b2 7823 Elf_External_Options * eopt;
d1133906 7824 Elf_Internal_Shdr * sect = section_headers;
9ea033b2
NC
7825 Elf_Internal_Options * iopt;
7826 Elf_Internal_Options * option;
252b5132
RH
7827 size_t offset;
7828 int cnt;
7829
7830 /* Find the section header so that we get the size. */
7831 while (sect->sh_type != SHT_MIPS_OPTIONS)
d1133906 7832 ++ sect;
252b5132
RH
7833
7834 GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
7835 Elf_External_Options *, "options");
7836
7837 iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
584da044 7838 * sizeof (* iopt));
252b5132
RH
7839 if (iopt == NULL)
7840 {
7841 error (_("Out of memory"));
7842 return 0;
7843 }
7844
7845 offset = cnt = 0;
7846 option = iopt;
76da6bbe 7847
252b5132
RH
7848 while (offset < sect->sh_size)
7849 {
9ea033b2 7850 Elf_External_Options * eoption;
252b5132
RH
7851
7852 eoption = (Elf_External_Options *) ((char *) eopt + offset);
7853
7854 option->kind = BYTE_GET (eoption->kind);
7855 option->size = BYTE_GET (eoption->size);
7856 option->section = BYTE_GET (eoption->section);
7857 option->info = BYTE_GET (eoption->info);
7858
7859 offset += option->size;
76da6bbe 7860
252b5132
RH
7861 ++option;
7862 ++cnt;
7863 }
7864
7865 printf (_("\nSection '%s' contains %d entries:\n"),
d40ac9bd 7866 SECTION_NAME (sect), cnt);
252b5132
RH
7867
7868 option = iopt;
76da6bbe 7869
252b5132
RH
7870 while (cnt-- > 0)
7871 {
7872 size_t len;
7873
7874 switch (option->kind)
7875 {
7876 case ODK_NULL:
7877 /* This shouldn't happen. */
7878 printf (" NULL %d %lx", option->section, option->info);
7879 break;
7880 case ODK_REGINFO:
7881 printf (" REGINFO ");
7882 if (elf_header.e_machine == EM_MIPS)
7883 {
7884 /* 32bit form. */
584da044
NC
7885 Elf32_External_RegInfo * ereg;
7886 Elf32_RegInfo reginfo;
252b5132
RH
7887
7888 ereg = (Elf32_External_RegInfo *) (option + 1);
7889 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
7890 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
7891 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
7892 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
7893 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
7894 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
7895
7896 printf ("GPR %08lx GP 0x%lx\n",
7897 reginfo.ri_gprmask,
7898 (unsigned long) reginfo.ri_gp_value);
7899 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
7900 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
7901 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
7902 }
7903 else
7904 {
7905 /* 64 bit form. */
9ea033b2 7906 Elf64_External_RegInfo * ereg;
252b5132
RH
7907 Elf64_Internal_RegInfo reginfo;
7908
7909 ereg = (Elf64_External_RegInfo *) (option + 1);
9ea033b2 7910 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
252b5132
RH
7911 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
7912 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
7913 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
7914 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
9ea033b2 7915 reginfo.ri_gp_value = BYTE_GET8 (ereg->ri_gp_value);
252b5132
RH
7916
7917 printf ("GPR %08lx GP 0x",
7918 reginfo.ri_gprmask);
7919 printf_vma (reginfo.ri_gp_value);
7920 printf ("\n");
7921
7922 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
7923 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
7924 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
7925 }
7926 ++option;
7927 continue;
7928 case ODK_EXCEPTIONS:
7929 fputs (" EXCEPTIONS fpe_min(", stdout);
7930 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
7931 fputs (") fpe_max(", stdout);
7932 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
7933 fputs (")", stdout);
7934
7935 if (option->info & OEX_PAGE0)
7936 fputs (" PAGE0", stdout);
7937 if (option->info & OEX_SMM)
7938 fputs (" SMM", stdout);
7939 if (option->info & OEX_FPDBUG)
7940 fputs (" FPDBUG", stdout);
7941 if (option->info & OEX_DISMISS)
7942 fputs (" DISMISS", stdout);
7943 break;
7944 case ODK_PAD:
7945 fputs (" PAD ", stdout);
7946 if (option->info & OPAD_PREFIX)
7947 fputs (" PREFIX", stdout);
7948 if (option->info & OPAD_POSTFIX)
7949 fputs (" POSTFIX", stdout);
7950 if (option->info & OPAD_SYMBOL)
7951 fputs (" SYMBOL", stdout);
7952 break;
7953 case ODK_HWPATCH:
7954 fputs (" HWPATCH ", stdout);
7955 if (option->info & OHW_R4KEOP)
7956 fputs (" R4KEOP", stdout);
7957 if (option->info & OHW_R8KPFETCH)
7958 fputs (" R8KPFETCH", stdout);
7959 if (option->info & OHW_R5KEOP)
7960 fputs (" R5KEOP", stdout);
7961 if (option->info & OHW_R5KCVTL)
7962 fputs (" R5KCVTL", stdout);
7963 break;
7964 case ODK_FILL:
7965 fputs (" FILL ", stdout);
7966 /* XXX Print content of info word? */
7967 break;
7968 case ODK_TAGS:
7969 fputs (" TAGS ", stdout);
7970 /* XXX Print content of info word? */
7971 break;
7972 case ODK_HWAND:
7973 fputs (" HWAND ", stdout);
7974 if (option->info & OHWA0_R4KEOP_CHECKED)
7975 fputs (" R4KEOP_CHECKED", stdout);
7976 if (option->info & OHWA0_R4KEOP_CLEAN)
7977 fputs (" R4KEOP_CLEAN", stdout);
7978 break;
7979 case ODK_HWOR:
7980 fputs (" HWOR ", stdout);
7981 if (option->info & OHWA0_R4KEOP_CHECKED)
7982 fputs (" R4KEOP_CHECKED", stdout);
7983 if (option->info & OHWA0_R4KEOP_CLEAN)
7984 fputs (" R4KEOP_CLEAN", stdout);
7985 break;
7986 case ODK_GP_GROUP:
7987 printf (" GP_GROUP %#06lx self-contained %#06lx",
7988 option->info & OGP_GROUP,
7989 (option->info & OGP_SELF) >> 16);
7990 break;
7991 case ODK_IDENT:
7992 printf (" IDENT %#06lx self-contained %#06lx",
7993 option->info & OGP_GROUP,
7994 (option->info & OGP_SELF) >> 16);
7995 break;
7996 default:
7997 /* This shouldn't happen. */
7998 printf (" %3d ??? %d %lx",
7999 option->kind, option->section, option->info);
8000 break;
8001 }
8002
584da044 8003 len = sizeof (* eopt);
252b5132
RH
8004 while (len < option->size)
8005 if (((char *) option)[len] >= ' '
8006 && ((char *) option)[len] < 0x7f)
8007 printf ("%c", ((char *) option)[len++]);
8008 else
8009 printf ("\\%03o", ((char *) option)[len++]);
8010
8011 fputs ("\n", stdout);
8012 ++option;
8013 }
8014
8015 free (eopt);
8016 }
8017
8018 if (conflicts_offset != 0 && conflictsno != 0)
8019 {
9ea033b2
NC
8020 Elf32_External_Conflict * econf32;
8021 Elf64_External_Conflict * econf64;
8022 Elf32_Conflict * iconf;
252b5132
RH
8023 size_t cnt;
8024
8025 if (dynamic_symbols == NULL)
8026 {
8027 error (_("conflict list with without table"));
8028 return 0;
8029 }
8030
584da044 8031 iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (* iconf));
252b5132
RH
8032 if (iconf == NULL)
8033 {
8034 error (_("Out of memory"));
8035 return 0;
8036 }
8037
9ea033b2 8038 if (is_32bit_elf)
252b5132 8039 {
584da044 8040 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (* econf32),
252b5132
RH
8041 econf32, Elf32_External_Conflict *, "conflict");
8042
8043 for (cnt = 0; cnt < conflictsno; ++cnt)
8044 iconf[cnt] = BYTE_GET (econf32[cnt]);
8045 }
8046 else
8047 {
584da044 8048 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (* econf64),
252b5132
RH
8049 econf64, Elf64_External_Conflict *, "conflict");
8050
8051 for (cnt = 0; cnt < conflictsno; ++cnt)
8052 iconf[cnt] = BYTE_GET (econf64[cnt]);
8053 }
8054
8055 printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
8056 puts (_(" Num: Index Value Name"));
8057
8058 for (cnt = 0; cnt < conflictsno; ++cnt)
8059 {
19936277 8060 Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
252b5132 8061
16062207 8062 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963
NC
8063 print_vma (psym->st_value, FULL_HEX);
8064 printf (" %s\n", dynamic_strings + psym->st_name);
252b5132
RH
8065 }
8066
252b5132
RH
8067 free (iconf);
8068 }
8069
8070 return 1;
8071}
8072
779fe533
NC
8073static char *
8074get_note_type (e_type)
8075 unsigned e_type;
8076{
8077 static char buff[64];
103f02d3 8078
779fe533
NC
8079 switch (e_type)
8080 {
8081 case NT_PRSTATUS: return _("NT_PRSTATUS (prstatus structure)");
8082 case NT_FPREGSET: return _("NT_FPREGSET (floating point registers)");
8083 case NT_PRPSINFO: return _("NT_PRPSINFO (prpsinfo structure)");
8084 case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
d1133906 8085 case NT_PRXFPREG: return _("NT_PRXFPREG (user_xfpregs structure)");
779fe533
NC
8086 case NT_PSTATUS: return _("NT_PSTATUS (pstatus structure)");
8087 case NT_FPREGS: return _("NT_FPREGS (floating point registers)");
8088 case NT_PSINFO: return _("NT_PSINFO (psinfo structure)");
8089 case NT_LWPSTATUS: return _("NT_LWPSTATUS (lwpstatus_t structure)");
8090 case NT_LWPSINFO: return _("NT_LWPSINFO (lwpsinfo_t structure)");
7bea2f73 8091 case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus strcuture)");
779fe533
NC
8092 default:
8093 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
8094 return buff;
8095 }
8096}
8097
6d118b09
NC
8098/* Note that by the ELF standard, the name field is already null byte
8099 terminated, and namesz includes the terminating null byte.
8100 I.E. the value of namesz for the name "FSF" is 4.
8101
8102 If the value of namesz is zero, there is no name present. */
779fe533
NC
8103static int
8104process_note (pnote)
6d118b09 8105 Elf32_Internal_Note * pnote;
779fe533 8106{
103f02d3 8107 printf (" %s\t\t0x%08lx\t%s\n",
6d118b09
NC
8108 pnote->namesz ? pnote->namedata : "(NONE)",
8109 pnote->descsz, get_note_type (pnote->type));
779fe533
NC
8110 return 1;
8111}
8112
6d118b09 8113
779fe533
NC
8114static int
8115process_corefile_note_segment (file, offset, length)
8116 FILE * file;
f7a99963
NC
8117 bfd_vma offset;
8118 bfd_vma length;
779fe533
NC
8119{
8120 Elf_External_Note * pnotes;
8121 Elf_External_Note * external;
779fe533 8122 int res = 1;
103f02d3 8123
779fe533
NC
8124 if (length <= 0)
8125 return 0;
103f02d3 8126
779fe533
NC
8127 GET_DATA_ALLOC (offset, length, pnotes, Elf_External_Note *, "notes");
8128
103f02d3 8129 external = pnotes;
103f02d3 8130
305c7206 8131 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 8132 (unsigned long) offset, (unsigned long) length);
779fe533 8133 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 8134
6d118b09 8135 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 8136 {
6d118b09
NC
8137 Elf32_Internal_Note inote;
8138 char * temp = NULL;
8139
8140 inote.type = BYTE_GET (external->type);
8141 inote.namesz = BYTE_GET (external->namesz);
8142 inote.namedata = external->name;
8143 inote.descsz = BYTE_GET (external->descsz);
8144 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
8145 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 8146
6d118b09
NC
8147 external = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
8148
8149 /* Verify that name is null terminated. It appears that at least
8150 one version of Linux (RedHat 6.0) generates corefiles that don't
8151 comply with the ELF spec by failing to include the null byte in
8152 namesz. */
8153 if (inote.namedata[inote.namesz] != '\0')
8154 {
8155 temp = malloc (inote.namesz + 1);
76da6bbe 8156
6d118b09
NC
8157 if (temp == NULL)
8158 {
8159 error (_("Out of memory\n"));
8160 res = 0;
8161 break;
8162 }
76da6bbe 8163
6d118b09
NC
8164 strncpy (temp, inote.namedata, inote.namesz);
8165 temp[inote.namesz] = 0;
76da6bbe 8166
6d118b09
NC
8167 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
8168 inote.namedata = temp;
8169 }
8170
8171 res &= process_note (& inote);
103f02d3 8172
6d118b09
NC
8173 if (temp != NULL)
8174 {
8175 free (temp);
8176 temp = NULL;
8177 }
779fe533
NC
8178 }
8179
8180 free (pnotes);
103f02d3 8181
779fe533
NC
8182 return res;
8183}
8184
8185static int
8186process_corefile_note_segments (file)
8187 FILE * file;
8188{
8189 Elf_Internal_Phdr * program_headers;
8190 Elf_Internal_Phdr * segment;
8191 unsigned int i;
8192 int res = 1;
103f02d3 8193
779fe533
NC
8194 program_headers = (Elf_Internal_Phdr *) malloc
8195 (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
8196
8197 if (program_headers == NULL)
8198 {
8199 error (_("Out of memory\n"));
8200 return 0;
8201 }
8202
8203 if (is_32bit_elf)
8204 i = get_32bit_program_headers (file, program_headers);
8205 else
8206 i = get_64bit_program_headers (file, program_headers);
8207
8208 if (i == 0)
8209 {
8210 free (program_headers);
8211 return 0;
8212 }
103f02d3 8213
779fe533
NC
8214 for (i = 0, segment = program_headers;
8215 i < elf_header.e_phnum;
8216 i ++, segment ++)
8217 {
8218 if (segment->p_type == PT_NOTE)
103f02d3 8219 res &= process_corefile_note_segment (file,
30800947
NC
8220 (bfd_vma) segment->p_offset,
8221 (bfd_vma) segment->p_filesz);
779fe533 8222 }
103f02d3 8223
779fe533
NC
8224 free (program_headers);
8225
8226 return res;
8227}
8228
8229static int
8230process_corefile_contents (file)
8231 FILE * file;
8232{
8233 /* If we have not been asked to display the notes then do nothing. */
8234 if (! do_notes)
8235 return 1;
103f02d3 8236
779fe533
NC
8237 /* If file is not a core file then exit. */
8238 if (elf_header.e_type != ET_CORE)
8239 return 1;
103f02d3 8240
779fe533
NC
8241 /* No program headers means no NOTE segment. */
8242 if (elf_header.e_phnum == 0)
8243 {
8244 printf (_("No note segments present in the core file.\n"));
8245 return 1;
8246 }
8247
8248 return process_corefile_note_segments (file);
8249}
8250
252b5132
RH
8251static int
8252process_arch_specific (file)
9ea033b2 8253 FILE * file;
252b5132 8254{
a952a375
NC
8255 if (! do_arch)
8256 return 1;
8257
252b5132
RH
8258 switch (elf_header.e_machine)
8259 {
8260 case EM_MIPS:
8261 case EM_MIPS_RS4_BE:
8262 return process_mips_specific (file);
8263 break;
8264 default:
8265 break;
8266 }
8267 return 1;
8268}
8269
8270static int
8271get_file_header (file)
8272 FILE * file;
8273{
9ea033b2
NC
8274 /* Read in the identity array. */
8275 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
8276 return 0;
8277
9ea033b2
NC
8278 /* Determine how to read the rest of the header. */
8279 switch (elf_header.e_ident [EI_DATA])
8280 {
8281 default: /* fall through */
8282 case ELFDATANONE: /* fall through */
8283 case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
8284 case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
8285 }
8286
8287 /* For now we only support 32 bit and 64 bit ELF files. */
8288 is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
8289
8290 /* Read in the rest of the header. */
8291 if (is_32bit_elf)
8292 {
8293 Elf32_External_Ehdr ehdr32;
252b5132 8294
9ea033b2
NC
8295 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
8296 return 0;
103f02d3 8297
9ea033b2
NC
8298 elf_header.e_type = BYTE_GET (ehdr32.e_type);
8299 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
8300 elf_header.e_version = BYTE_GET (ehdr32.e_version);
8301 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
8302 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
8303 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
8304 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
8305 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
8306 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
8307 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
8308 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
8309 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
8310 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
8311 }
252b5132 8312 else
9ea033b2
NC
8313 {
8314 Elf64_External_Ehdr ehdr64;
a952a375
NC
8315
8316 /* If we have been compiled with sizeof (bfd_vma) == 4, then
8317 we will not be able to cope with the 64bit data found in
8318 64 ELF files. Detect this now and abort before we start
8319 overwritting things. */
8320 if (sizeof (bfd_vma) < 8)
8321 {
8322 error (_("This instance of readelf has been built without support for a\n"));
8323 error (_("64 bit data type and so it cannot read 64 bit ELF files.\n"));
8324 return 0;
8325 }
103f02d3 8326
9ea033b2
NC
8327 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
8328 return 0;
103f02d3 8329
9ea033b2
NC
8330 elf_header.e_type = BYTE_GET (ehdr64.e_type);
8331 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
8332 elf_header.e_version = BYTE_GET (ehdr64.e_version);
8333 elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry);
8334 elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff);
8335 elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff);
8336 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
8337 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
8338 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
8339 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
8340 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
8341 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
8342 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
8343 }
252b5132
RH
8344
8345 return 1;
8346}
8347
8348static void
8349process_file (file_name)
8350 char * file_name;
8351{
8352 FILE * file;
8353 struct stat statbuf;
8354 unsigned int i;
8355
8356 if (stat (file_name, & statbuf) < 0)
8357 {
8358 error (_("Cannot stat input file %s.\n"), file_name);
8359 return;
8360 }
8361
8362 file = fopen (file_name, "rb");
8363 if (file == NULL)
8364 {
8365 error (_("Input file %s not found.\n"), file_name);
8366 return;
8367 }
8368
8369 if (! get_file_header (file))
8370 {
8371 error (_("%s: Failed to read file header\n"), file_name);
8372 fclose (file);
8373 return;
8374 }
8375
8376 /* Initialise per file variables. */
8377 for (i = NUM_ELEM (version_info); i--;)
8378 version_info[i] = 0;
8379
8380 for (i = NUM_ELEM (dynamic_info); i--;)
8381 dynamic_info[i] = 0;
8382
8383 /* Process the file. */
8384 if (show_name)
8385 printf (_("\nFile: %s\n"), file_name);
8386
8387 if (! process_file_header ())
8388 {
8389 fclose (file);
8390 return;
8391 }
8392
8393 process_section_headers (file);
8394
8395 process_program_headers (file);
8396
8397 process_dynamic_segment (file);
8398
8399 process_relocs (file);
8400
4d6ed7c8
NC
8401 process_unwind (file);
8402
252b5132
RH
8403 process_symbol_table (file);
8404
8405 process_syminfo (file);
8406
8407 process_version_sections (file);
8408
8409 process_section_contents (file);
103f02d3 8410
779fe533 8411 process_corefile_contents (file);
103f02d3 8412
252b5132
RH
8413 process_arch_specific (file);
8414
8415 fclose (file);
8416
8417 if (section_headers)
8418 {
8419 free (section_headers);
8420 section_headers = NULL;
8421 }
8422
8423 if (string_table)
8424 {
8425 free (string_table);
8426 string_table = NULL;
d40ac9bd 8427 string_table_length = 0;
252b5132
RH
8428 }
8429
8430 if (dynamic_strings)
8431 {
8432 free (dynamic_strings);
8433 dynamic_strings = NULL;
8434 }
8435
8436 if (dynamic_symbols)
8437 {
8438 free (dynamic_symbols);
8439 dynamic_symbols = NULL;
19936277 8440 num_dynamic_syms = 0;
252b5132
RH
8441 }
8442
8443 if (dynamic_syminfo)
8444 {
8445 free (dynamic_syminfo);
8446 dynamic_syminfo = NULL;
8447 }
8448}
8449
8450#ifdef SUPPORT_DISASSEMBLY
8451/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2
NC
8452 fix this so that we insert symbolic addresses here, esp for GOT/PLT
8453 symbols */
252b5132
RH
8454
8455void
8456print_address (unsigned int addr, FILE * outfile)
8457{
8458 fprintf (outfile,"0x%8.8x", addr);
8459}
8460
8461/* Needed by the i386 disassembler. */
8462void
8463db_task_printsym (unsigned int addr)
8464{
8465 print_address (addr, stderr);
8466}
8467#endif
8468
8469int
8470main (argc, argv)
8471 int argc;
8472 char ** argv;
8473{
8474#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
8475 setlocale (LC_MESSAGES, "");
8476#endif
8477 bindtextdomain (PACKAGE, LOCALEDIR);
8478 textdomain (PACKAGE);
8479
8480 parse_args (argc, argv);
8481
8482 if (optind < (argc - 1))
8483 show_name = 1;
8484
8485 while (optind < argc)
8486 process_file (argv [optind ++]);
8487
8488 if (dump_sects != NULL)
8489 free (dump_sects);
8490
8491 return 0;
8492}