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