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