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