]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
* Makefile.in: Revert 2001-06-17.
[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
7036c0e1
AJ
82char * program_name = "readelf";
83unsigned int dynamic_addr;
84bfd_size_type dynamic_size;
85unsigned int rela_addr;
86unsigned int rela_size;
87char * dynamic_strings;
252b5132 88char * string_table;
d40ac9bd 89unsigned long string_table_length;
19936277 90unsigned long num_dynamic_syms;
7036c0e1 91Elf_Internal_Sym * dynamic_symbols;
252b5132 92Elf_Internal_Syminfo * dynamic_syminfo;
7036c0e1 93unsigned long dynamic_syminfo_offset;
252b5132 94unsigned int dynamic_syminfo_nent;
7036c0e1
AJ
95char program_interpreter [64];
96int dynamic_info[DT_JMPREL + 1];
97int version_info[16];
98int loadaddr = 0;
252b5132
RH
99Elf_Internal_Ehdr elf_header;
100Elf_Internal_Shdr * section_headers;
101Elf_Internal_Dyn * dynamic_segment;
7036c0e1
AJ
102int show_name;
103int do_dynamic;
104int do_syms;
105int do_reloc;
106int do_sections;
107int do_segments;
4d6ed7c8 108int do_unwind;
7036c0e1
AJ
109int do_using_dynamic;
110int do_header;
111int do_dump;
112int do_version;
252b5132
RH
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));
7036c0e1
AJ
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));
7036c0e1 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 202#ifdef SUPPORT_DISASSEMBLY
7036c0e1 203static int disassemble_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
252b5132 204#endif
7036c0e1
AJ
205static int dump_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
206static int display_debug_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
252b5132
RH
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));
7036c0e1 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 234static int process_corefile_note_segments PARAMS ((FILE *));
7036c0e1 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
7036c0e1 245#define SECTION_NAME(X) ((X) == NULL ? "<none>" : \
d40ac9bd
NC
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
7036c0e1 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
7036c0e1 262#define BYTE_GET8(field) byte_get (field, -8)
a952a375 263#else
7036c0e1 264#define BYTE_GET8(field) byte_get (field, 8)
a952a375 265#endif
252b5132 266
7036c0e1 267#define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
252b5132
RH
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; \
7036c0e1
AJ
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); \
252b5132 288 var = NULL; \
7036c0e1 289 return 0; \
252b5132
RH
290 }
291
292
7036c0e1 293#define GET_DATA(offset, var, reason) \
252b5132 294 if (fseek (file, offset, SEEK_SET)) \
7036c0e1 295 { \
252b5132
RH
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 {
7036c0e1
AJ
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";
1270 case EM_MIPS: return "MIPS R3000";
1271 case EM_S370: return "IBM System/370";
1272 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1273 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
7036c0e1 1274 case EM_PARISC: return "HPPA";
252b5132 1275 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1
AJ
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";
252b5132 1282 case EM_MCORE: return "MCORE";
7036c0e1
AJ
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";
7036c0e1 1297 case EM_ALPHA: return "Alpha";
252b5132
RH
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";
7036c0e1
AJ
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";
7036c0e1
AJ
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";
93ebe586 1330 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
7036c0e1
AJ
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;
7036c0e1
AJ
3059 unsigned long i;
3060 int found = 0;
252b5132
RH
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;
7036c0e1 3205
4d6ed7c8
NC
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;
7036c0e1
AJ
4523 int total;
4524 int cnt;
4525 unsigned char * edata;
4526 unsigned short * data;
4527 char * strtab;
4528 Elf_Internal_Sym * symbols;
252b5132
RH
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",
7036c0e1 7205 (unsigned long)(saved_start - section_start), length, cie_id,
31b6fca6
RH
7206 fc->augmentation, fc->code_factor, fc->data_factor,
7207 fc->ra);
7208 else
7209 {
7210 printf ("\n%08lx %08lx %08lx CIE\n",
7036c0e1 7211 (unsigned long)(saved_start - section_start), length, cie_id);
31b6fca6
RH
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')
7036c0e1 7238 q++;
31b6fca6
RH
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;
584da044
NC
7258
7259 fc = & fde_fc;
c47d488e
DD
7260 memset (fc, 0, sizeof (Frame_Chunk));
7261
31b6fca6 7262 look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
c47d488e 7263
31b6fca6
RH
7264 for (cie=chunks; cie ; cie = cie->next)
7265 if (cie->chunk_start == look_for)
7266 break;
c47d488e 7267
c47d488e
DD
7268 if (!cie)
7269 {
31b6fca6
RH
7270 warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
7271 cie_id, saved_start);
c47d488e
DD
7272 start = block_end;
7273 fc->ncols = 0;
a98cc2b2 7274 fc->col_type = (short int *) xmalloc (sizeof (short int));
c47d488e 7275 fc->col_offset = (int *) xmalloc (sizeof (int));
584da044 7276 frame_need_space (fc, max_regs - 1);
c47d488e
DD
7277 cie = fc;
7278 fc->augmentation = "";
31b6fca6 7279 fc->fde_encoding = 0;
c47d488e
DD
7280 }
7281 else
7282 {
7283 fc->ncols = cie->ncols;
a98cc2b2 7284 fc->col_type = (short int *) xmalloc (fc->ncols * sizeof (short int));
c47d488e 7285 fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
a98cc2b2 7286 memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
c47d488e
DD
7287 memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
7288 fc->augmentation = cie->augmentation;
7289 fc->code_factor = cie->code_factor;
7290 fc->data_factor = cie->data_factor;
7291 fc->cfa_reg = cie->cfa_reg;
7292 fc->cfa_offset = cie->cfa_offset;
7293 fc->ra = cie->ra;
7294 frame_need_space (fc, max_regs-1);
31b6fca6 7295 fc->fde_encoding = cie->fde_encoding;
c47d488e
DD
7296 }
7297
31b6fca6
RH
7298 if (fc->fde_encoding)
7299 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
7300
7301 fc->pc_begin = byte_get (start, encoded_ptr_size);
7302 start += encoded_ptr_size;
7303 fc->pc_range = byte_get (start, encoded_ptr_size);
7304 start += encoded_ptr_size;
7305
c47d488e
DD
7306 if (cie->augmentation[0] == 'z')
7307 {
31b6fca6
RH
7308 augmentation_data_len = LEB ();
7309 augmentation_data = start;
7310 start += augmentation_data_len;
c47d488e
DD
7311 }
7312
31b6fca6 7313 printf ("\n%08lx %08lx %08lx FDE cie=%08x pc=%08lx..%08lx\n",
7036c0e1 7314 (unsigned long)(saved_start - section_start), length, cie_id,
31b6fca6 7315 cie->chunk_start - section_start, fc->pc_begin,
c47d488e 7316 fc->pc_begin + fc->pc_range);
31b6fca6
RH
7317 if (! do_debug_frames_interp && augmentation_data_len)
7318 {
7319 unsigned long i;
7320 printf (" Augmentation data: ");
7321 for (i = 0; i < augmentation_data_len; ++i)
7322 printf (" %02x", augmentation_data[i]);
7323 putchar ('\n');
7324 putchar ('\n');
7325 }
c47d488e
DD
7326 }
7327
7328 /* At this point, fc is the current chunk, cie (if any) is set, and we're
7329 about to interpret instructions for the chunk. */
7330
31b6fca6 7331 if (do_debug_frames_interp)
a98cc2b2
AH
7332 {
7333 /* Start by making a pass over the chunk, allocating storage
7334 and taking note of what registers are used. */
584da044 7335 unsigned char * tmp = start;
a98cc2b2 7336
a98cc2b2
AH
7337 while (start < block_end)
7338 {
7339 unsigned op, opa;
7340 unsigned long reg;
7036c0e1 7341
584da044 7342 op = * start ++;
a98cc2b2
AH
7343 opa = op & 0x3f;
7344 if (op & 0xc0)
7345 op &= 0xc0;
7036c0e1 7346
a98cc2b2
AH
7347 /* Warning: if you add any more cases to this switch, be
7348 sure to add them to the corresponding switch below. */
7349 switch (op)
7350 {
7351 case DW_CFA_advance_loc:
7352 break;
7353 case DW_CFA_offset:
7354 LEB ();
7355 frame_need_space (fc, opa);
7356 fc->col_type[opa] = DW_CFA_undefined;
7357 break;
7358 case DW_CFA_restore:
7359 frame_need_space (fc, opa);
7360 fc->col_type[opa] = DW_CFA_undefined;
7361 break;
7362 case DW_CFA_set_loc:
31b6fca6 7363 start += encoded_ptr_size;
a98cc2b2
AH
7364 break;
7365 case DW_CFA_advance_loc1:
7366 start += 1;
7367 break;
7368 case DW_CFA_advance_loc2:
7369 start += 2;
7370 break;
7371 case DW_CFA_advance_loc4:
7372 start += 4;
7373 break;
7374 case DW_CFA_offset_extended:
7375 reg = LEB (); LEB ();
7376 frame_need_space (fc, reg);
7377 fc->col_type[reg] = DW_CFA_undefined;
7378 break;
7379 case DW_CFA_restore_extended:
7380 reg = LEB ();
7381 frame_need_space (fc, reg);
7382 fc->col_type[reg] = DW_CFA_undefined;
7383 break;
7384 case DW_CFA_undefined:
7385 reg = LEB ();
7386 frame_need_space (fc, reg);
7387 fc->col_type[reg] = DW_CFA_undefined;
7388 break;
7389 case DW_CFA_same_value:
7390 reg = LEB ();
7391 frame_need_space (fc, reg);
7392 fc->col_type[reg] = DW_CFA_undefined;
7393 break;
7394 case DW_CFA_register:
7395 reg = LEB (); LEB ();
7396 frame_need_space (fc, reg);
7397 fc->col_type[reg] = DW_CFA_undefined;
7398 break;
7399 case DW_CFA_def_cfa:
7400 LEB (); LEB ();
7401 break;
7402 case DW_CFA_def_cfa_register:
7403 LEB ();
7404 break;
7405 case DW_CFA_def_cfa_offset:
7406 LEB ();
7407 break;
7408#ifndef DW_CFA_GNU_args_size
7409#define DW_CFA_GNU_args_size 0x2e
7410#endif
7411 case DW_CFA_GNU_args_size:
7412 LEB ();
7036c0e1 7413 break;
a98cc2b2
AH
7414#ifndef DW_CFA_GNU_negative_offset_extended
7415#define DW_CFA_GNU_negative_offset_extended 0x2f
7416#endif
7417 case DW_CFA_GNU_negative_offset_extended:
7036c0e1 7418 reg = LEB (); LEB ();
a98cc2b2
AH
7419 frame_need_space (fc, reg);
7420 fc->col_type[reg] = DW_CFA_undefined;
7036c0e1 7421
a98cc2b2
AH
7422 default:
7423 break;
7424 }
7425 }
7426 start = tmp;
7427 }
7428
7429 /* Now we know what registers are used, make a second pass over
7430 the chunk, this time actually printing out the info. */
7431
c47d488e
DD
7432 while (start < block_end)
7433 {
7434 unsigned op, opa;
7435 unsigned long ul, reg, roffs;
7436 long l, ofs;
7437 bfd_vma vma;
7438
7439 op = * start ++;
7440 opa = op & 0x3f;
7441 if (op & 0xc0)
7442 op &= 0xc0;
7443
a98cc2b2
AH
7444 /* Warning: if you add any more cases to this switch, be
7445 sure to add them to the corresponding switch above. */
c47d488e
DD
7446 switch (op)
7447 {
7448 case DW_CFA_advance_loc:
31b6fca6
RH
7449 if (do_debug_frames_interp)
7450 frame_display_row (fc, &need_col_headers, &max_regs);
7451 else
7452 printf (" DW_CFA_advance_loc: %d to %08lx\n",
7453 opa * fc->code_factor,
7454 fc->pc_begin + opa * fc->code_factor);
c47d488e
DD
7455 fc->pc_begin += opa * fc->code_factor;
7456 break;
7457
7458 case DW_CFA_offset:
c47d488e 7459 roffs = LEB ();
31b6fca6 7460 if (! do_debug_frames_interp)
7036c0e1 7461 printf (" DW_CFA_offset: r%d at cfa%+ld\n",
31b6fca6 7462 opa, roffs * fc->data_factor);
c47d488e
DD
7463 fc->col_type[opa] = DW_CFA_offset;
7464 fc->col_offset[opa] = roffs * fc->data_factor;
7465 break;
7466
7467 case DW_CFA_restore:
31b6fca6
RH
7468 if (! do_debug_frames_interp)
7469 printf (" DW_CFA_restore: r%d\n", opa);
c47d488e
DD
7470 fc->col_type[opa] = cie->col_type[opa];
7471 fc->col_offset[opa] = cie->col_offset[opa];
7472 break;
7473
7474 case DW_CFA_set_loc:
31b6fca6
RH
7475 vma = byte_get (start, encoded_ptr_size);
7476 start += encoded_ptr_size;
7477 if (do_debug_frames_interp)
7478 frame_display_row (fc, &need_col_headers, &max_regs);
7479 else
7036c0e1 7480 printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
c47d488e
DD
7481 fc->pc_begin = vma;
7482 break;
7483
7484 case DW_CFA_advance_loc1:
c47d488e 7485 ofs = byte_get (start, 1); start += 1;
31b6fca6
RH
7486 if (do_debug_frames_interp)
7487 frame_display_row (fc, &need_col_headers, &max_regs);
7488 else
7036c0e1 7489 printf (" DW_CFA_advance_loc1: %ld to %08lx\n",
31b6fca6
RH
7490 ofs * fc->code_factor,
7491 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
7492 fc->pc_begin += ofs * fc->code_factor;
7493 break;
7494
7495 case DW_CFA_advance_loc2:
c47d488e 7496 ofs = byte_get (start, 2); start += 2;
31b6fca6
RH
7497 if (do_debug_frames_interp)
7498 frame_display_row (fc, &need_col_headers, &max_regs);
7499 else
7036c0e1 7500 printf (" DW_CFA_advance_loc2: %ld to %08lx\n",
31b6fca6
RH
7501 ofs * fc->code_factor,
7502 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
7503 fc->pc_begin += ofs * fc->code_factor;
7504 break;
7505
7506 case DW_CFA_advance_loc4:
c47d488e 7507 ofs = byte_get (start, 4); start += 4;
31b6fca6
RH
7508 if (do_debug_frames_interp)
7509 frame_display_row (fc, &need_col_headers, &max_regs);
7510 else
7036c0e1 7511 printf (" DW_CFA_advance_loc4: %ld to %08lx\n",
31b6fca6
RH
7512 ofs * fc->code_factor,
7513 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
7514 fc->pc_begin += ofs * fc->code_factor;
7515 break;
7516
7517 case DW_CFA_offset_extended:
7518 reg = LEB ();
7519 roffs = LEB ();
31b6fca6 7520 if (! do_debug_frames_interp)
7036c0e1 7521 printf (" DW_CFA_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 7522 reg, roffs * fc->data_factor);
c47d488e
DD
7523 fc->col_type[reg] = DW_CFA_offset;
7524 fc->col_offset[reg] = roffs * fc->data_factor;
7525 break;
7526
7527 case DW_CFA_restore_extended:
7528 reg = LEB ();
31b6fca6 7529 if (! do_debug_frames_interp)
7036c0e1 7530 printf (" DW_CFA_restore_extended: r%ld\n", reg);
c47d488e
DD
7531 fc->col_type[reg] = cie->col_type[reg];
7532 fc->col_offset[reg] = cie->col_offset[reg];
7533 break;
7534
7535 case DW_CFA_undefined:
7536 reg = LEB ();
31b6fca6 7537 if (! do_debug_frames_interp)
7036c0e1 7538 printf (" DW_CFA_undefined: r%ld\n", reg);
c47d488e
DD
7539 fc->col_type[reg] = DW_CFA_undefined;
7540 fc->col_offset[reg] = 0;
7541 break;
7542
7543 case DW_CFA_same_value:
7544 reg = LEB ();
31b6fca6 7545 if (! do_debug_frames_interp)
7036c0e1 7546 printf (" DW_CFA_same_value: r%ld\n", reg);
c47d488e
DD
7547 fc->col_type[reg] = DW_CFA_same_value;
7548 fc->col_offset[reg] = 0;
7549 break;
7550
7551 case DW_CFA_register:
7552 reg = LEB ();
7553 roffs = LEB ();
31b6fca6 7554 if (! do_debug_frames_interp)
7036c0e1 7555 printf (" DW_CFA_register: r%ld\n", reg);
c47d488e
DD
7556 fc->col_type[reg] = DW_CFA_register;
7557 fc->col_offset[reg] = roffs;
7558 break;
7559
7560 case DW_CFA_remember_state:
31b6fca6
RH
7561 if (! do_debug_frames_interp)
7562 printf (" DW_CFA_remember_state\n");
c47d488e
DD
7563 rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
7564 rs->ncols = fc->ncols;
a98cc2b2 7565 rs->col_type = (short int *) xmalloc (rs->ncols * sizeof (short int));
c47d488e
DD
7566 rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
7567 memcpy (rs->col_type, fc->col_type, rs->ncols);
7568 memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
7569 rs->next = remembered_state;
7570 remembered_state = rs;
7571 break;
7572
7573 case DW_CFA_restore_state:
31b6fca6
RH
7574 if (! do_debug_frames_interp)
7575 printf (" DW_CFA_restore_state\n");
c47d488e
DD
7576 rs = remembered_state;
7577 remembered_state = rs->next;
7578 frame_need_space (fc, rs->ncols-1);
7579 memcpy (fc->col_type, rs->col_type, rs->ncols);
7580 memcpy (fc->col_offset, rs->col_offset, rs->ncols * sizeof (int));
7581 free (rs->col_type);
7582 free (rs->col_offset);
7583 free (rs);
7584 break;
7585
7586 case DW_CFA_def_cfa:
7587 fc->cfa_reg = LEB ();
7588 fc->cfa_offset = LEB ();
31b6fca6
RH
7589 if (! do_debug_frames_interp)
7590 printf (" DW_CFA_def_cfa: r%d ofs %d\n",
7591 fc->cfa_reg, fc->cfa_offset);
c47d488e
DD
7592 break;
7593
7594 case DW_CFA_def_cfa_register:
7595 fc->cfa_reg = LEB ();
31b6fca6
RH
7596 if (! do_debug_frames_interp)
7597 printf (" DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
c47d488e
DD
7598 break;
7599
7600 case DW_CFA_def_cfa_offset:
7601 fc->cfa_offset = LEB ();
31b6fca6
RH
7602 if (! do_debug_frames_interp)
7603 printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
c47d488e
DD
7604 break;
7605
7606 case DW_CFA_nop:
31b6fca6
RH
7607 if (! do_debug_frames_interp)
7608 printf (" DW_CFA_nop\n");
c47d488e
DD
7609 break;
7610
7611#ifndef DW_CFA_GNU_window_save
7612#define DW_CFA_GNU_window_save 0x2d
7613#endif
7614 case DW_CFA_GNU_window_save:
31b6fca6
RH
7615 if (! do_debug_frames_interp)
7616 printf (" DW_CFA_GNU_window_save\n");
c47d488e
DD
7617 break;
7618
c47d488e
DD
7619 case DW_CFA_GNU_args_size:
7620 ul = LEB ();
31b6fca6 7621 if (! do_debug_frames_interp)
7036c0e1 7622 printf (" DW_CFA_GNU_args_size: %ld\n", ul);
c47d488e
DD
7623 break;
7624
c47d488e
DD
7625 case DW_CFA_GNU_negative_offset_extended:
7626 reg = LEB ();
7627 l = - LEB ();
7628 frame_need_space (fc, reg);
31b6fca6 7629 if (! do_debug_frames_interp)
7036c0e1 7630 printf (" DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 7631 reg, l * fc->data_factor);
c47d488e
DD
7632 fc->col_type[reg] = DW_CFA_offset;
7633 fc->col_offset[reg] = l * fc->data_factor;
7634 break;
7635
7636 default:
7637 fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
7638 start = block_end;
7639 }
7640 }
7641
31b6fca6
RH
7642 if (do_debug_frames_interp)
7643 frame_display_row (fc, &need_col_headers, &max_regs);
c47d488e
DD
7644
7645 start = block_end;
7646 }
7647
7648 printf ("\n");
7649
7650 return 1;
7651}
7652
7653#undef GET
7654#undef LEB
7655#undef SLEB
252b5132
RH
7656
7657static int
7658display_debug_not_supported (section, start, file)
7659 Elf32_Internal_Shdr * section;
b4c96d0d
ILT
7660 unsigned char * start ATTRIBUTE_UNUSED;
7661 FILE * file ATTRIBUTE_UNUSED;
252b5132
RH
7662{
7663 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
7664 SECTION_NAME (section));
7665
7666 return 1;
7667}
7668
3590ea00
NC
7669/* Pre-scan the .debug_info section to record the size of address.
7670 When dumping the .debug_line, we use that size information, assuming
7671 that all compilation units have the same address size. */
7672static int
7673prescan_debug_info (section, start, file)
7674 Elf32_Internal_Shdr * section ATTRIBUTE_UNUSED;
7675 unsigned char * start;
7676 FILE * file ATTRIBUTE_UNUSED;
7677{
7678 DWARF2_External_CompUnit * external;
7679
7680 external = (DWARF2_External_CompUnit *) start;
7681
7682 debug_line_pointer_size = BYTE_GET (external->cu_pointer_size);
7683 return 0;
7684}
7685
252b5132 7686 /* A structure containing the name of a debug section and a pointer
3590ea00
NC
7687 to a function that can decode it. The third field is a prescan
7688 function to be run over the section before displaying any of the
7689 sections. */
252b5132
RH
7690struct
7691{
7692 char * name;
3590ea00
NC
7693 int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
7694 int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
252b5132
RH
7695}
7696debug_displays[] =
7697{
3590ea00
NC
7698 { ".debug_info", display_debug_info, prescan_debug_info },
7699 { ".debug_abbrev", display_debug_abbrev, NULL },
7700 { ".debug_line", display_debug_lines, NULL },
7701 { ".debug_aranges", display_debug_aranges, NULL },
7702 { ".debug_pubnames", display_debug_pubnames, NULL },
c47d488e
DD
7703 { ".debug_frame", display_debug_frames, NULL },
7704 { ".eh_frame", display_debug_frames, NULL },
3590ea00 7705 { ".debug_macinfo", display_debug_not_supported, NULL },
3590ea00
NC
7706 { ".debug_str", display_debug_not_supported, NULL },
7707 { ".debug_static_func", display_debug_not_supported, NULL },
7708 { ".debug_static_vars", display_debug_not_supported, NULL },
7709 { ".debug_types", display_debug_not_supported, NULL },
7710 { ".debug_weaknames", display_debug_not_supported, NULL }
252b5132
RH
7711};
7712
7713static int
7714display_debug_section (section, file)
7715 Elf32_Internal_Shdr * section;
7716 FILE * file;
7717{
7718 char * name = SECTION_NAME (section);
7719 bfd_size_type length;
7720 unsigned char * start;
7721 int i;
7722
7723 length = section->sh_size;
7724 if (length == 0)
7725 {
7726 printf (_("\nSection '%s' has no debugging data.\n"), name);
7727 return 0;
7728 }
7729
7730 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
7731 "debug section data");
7732
7733 /* See if we know how to display the contents of this section. */
09fd7e38 7734 if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
7036c0e1 7735 name = ".debug_info";
584da044 7736
252b5132
RH
7737 for (i = NUM_ELEM (debug_displays); i--;)
7738 if (strcmp (debug_displays[i].name, name) == 0)
7739 {
7740 debug_displays[i].display (section, start, file);
7741 break;
7742 }
7743
7744 if (i == -1)
7745 printf (_("Unrecognised debug section: %s\n"), name);
7746
7747 free (start);
7748
7749 /* If we loaded in the abbrev section at some point,
7750 we must release it here. */
7751 if (first_abbrev != NULL)
7752 free_abbrevs ();
7753
7754 return 1;
7755}
7756
7757static int
7758process_section_contents (file)
7759 FILE * file;
7760{
3590ea00 7761 Elf32_Internal_Shdr * section;
7036c0e1 7762 unsigned int i;
252b5132
RH
7763
7764 if (! do_dump)
7765 return 1;
7766
3590ea00
NC
7767 /* Pre-scan the debug sections to find some debug information not
7768 present in some of them. For the .debug_line, we must find out the
7769 size of address (specified in .debug_info and .debug_aranges). */
7770 for (i = 0, section = section_headers;
7771 i < elf_header.e_shnum && i < num_dump_sects;
7772 i ++, section ++)
7773 {
7774 char * name = SECTION_NAME (section);
7775 int j;
7776
7777 if (section->sh_size == 0)
7778 continue;
7779
7780 /* See if there is some pre-scan operation for this section. */
7781 for (j = NUM_ELEM (debug_displays); j--;)
7782 if (strcmp (debug_displays[j].name, name) == 0)
7783 {
7784 if (debug_displays[j].prescan != NULL)
7785 {
7786 bfd_size_type length;
7787 unsigned char * start;
7788
7789 length = section->sh_size;
7790 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
7791 "debug section data");
7792
7793 debug_displays[j].prescan (section, start, file);
7794 free (start);
7795 }
103f02d3 7796
3590ea00
NC
7797 break;
7798 }
7799 }
7800
252b5132 7801 for (i = 0, section = section_headers;
3590ea00 7802 i < elf_header.e_shnum && i < num_dump_sects;
252b5132
RH
7803 i ++, section ++)
7804 {
7805#ifdef SUPPORT_DISASSEMBLY
7806 if (dump_sects[i] & DISASS_DUMP)
7807 disassemble_section (section, file);
7808#endif
7809 if (dump_sects[i] & HEX_DUMP)
7810 dump_section (section, file);
7811
7812 if (dump_sects[i] & DEBUG_DUMP)
7813 display_debug_section (section, file);
7814 }
7815
7816 if (i < num_dump_sects)
7817 warn (_("Some sections were not dumped because they do not exist!\n"));
7818
7819 return 1;
7820}
7821
7822static void
7823process_mips_fpe_exception (mask)
7824 int mask;
7825{
7826 if (mask)
7827 {
7828 int first = 1;
7829 if (mask & OEX_FPU_INEX)
7830 fputs ("INEX", stdout), first = 0;
7831 if (mask & OEX_FPU_UFLO)
7832 printf ("%sUFLO", first ? "" : "|"), first = 0;
7833 if (mask & OEX_FPU_OFLO)
7834 printf ("%sOFLO", first ? "" : "|"), first = 0;
7835 if (mask & OEX_FPU_DIV0)
7836 printf ("%sDIV0", first ? "" : "|"), first = 0;
7837 if (mask & OEX_FPU_INVAL)
7838 printf ("%sINVAL", first ? "" : "|");
7839 }
7840 else
7841 fputs ("0", stdout);
7842}
7843
7844static int
7845process_mips_specific (file)
9ea033b2 7846 FILE * file;
252b5132 7847{
9ea033b2 7848 Elf_Internal_Dyn * entry;
252b5132
RH
7849 size_t liblist_offset = 0;
7850 size_t liblistno = 0;
7851 size_t conflictsno = 0;
7852 size_t options_offset = 0;
7853 size_t conflicts_offset = 0;
7854
7855 /* We have a lot of special sections. Thanks SGI! */
7856 if (dynamic_segment == NULL)
7857 /* No information available. */
7858 return 0;
7859
7860 for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
7861 switch (entry->d_tag)
7862 {
7863 case DT_MIPS_LIBLIST:
7864 liblist_offset = entry->d_un.d_val - loadaddr;
7865 break;
7866 case DT_MIPS_LIBLISTNO:
7867 liblistno = entry->d_un.d_val;
7868 break;
7869 case DT_MIPS_OPTIONS:
7870 options_offset = entry->d_un.d_val - loadaddr;
7871 break;
7872 case DT_MIPS_CONFLICT:
7873 conflicts_offset = entry->d_un.d_val - loadaddr;
7874 break;
7875 case DT_MIPS_CONFLICTNO:
7876 conflictsno = entry->d_un.d_val;
7877 break;
7878 default:
7879 break;
7880 }
7881
7882 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
7883 {
9ea033b2 7884 Elf32_External_Lib * elib;
252b5132
RH
7885 size_t cnt;
7886
7887 GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
7888 elib, Elf32_External_Lib *, "liblist");
7889
16062207
ILT
7890 printf ("\nSection '.liblist' contains %lu entries:\n",
7891 (unsigned long) liblistno);
252b5132
RH
7892 fputs (" Library Time Stamp Checksum Version Flags\n",
7893 stdout);
7894
7895 for (cnt = 0; cnt < liblistno; ++cnt)
7896 {
7897 Elf32_Lib liblist;
7898 time_t time;
7899 char timebuf[20];
50da7a9c 7900 struct tm * tmp;
252b5132
RH
7901
7902 liblist.l_name = BYTE_GET (elib[cnt].l_name);
7903 time = BYTE_GET (elib[cnt].l_time_stamp);
7904 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
7905 liblist.l_version = BYTE_GET (elib[cnt].l_version);
7906 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
7907
50da7a9c
NC
7908 tmp = gmtime (&time);
7909 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
7910 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7911 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132 7912
16062207 7913 printf ("%3lu: %-20s %s %#10lx %-7ld", (unsigned long) cnt,
252b5132
RH
7914 dynamic_strings + liblist.l_name, timebuf,
7915 liblist.l_checksum, liblist.l_version);
7916
7917 if (liblist.l_flags == 0)
7918 puts (" NONE");
7919 else
7920 {
7921 static const struct
7922 {
30800947 7923 const char * name;
252b5132 7924 int bit;
30800947
NC
7925 }
7926 l_flags_vals[] =
7927 {
7928 { " EXACT_MATCH", LL_EXACT_MATCH },
7929 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
7930 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
7931 { " EXPORTS", LL_EXPORTS },
7932 { " DELAY_LOAD", LL_DELAY_LOAD },
7933 { " DELTA", LL_DELTA }
7934 };
252b5132 7935 int flags = liblist.l_flags;
b4c96d0d 7936 size_t fcnt;
252b5132
RH
7937
7938 for (fcnt = 0;
7939 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
7940 ++fcnt)
7941 if ((flags & l_flags_vals[fcnt].bit) != 0)
7942 {
7943 fputs (l_flags_vals[fcnt].name, stdout);
7944 flags ^= l_flags_vals[fcnt].bit;
7945 }
7946 if (flags != 0)
7947 printf (" %#x", (unsigned int) flags);
7948
7949 puts ("");
7950 }
7951 }
7952
7953 free (elib);
7954 }
7955
7956 if (options_offset != 0)
7957 {
9ea033b2 7958 Elf_External_Options * eopt;
d1133906 7959 Elf_Internal_Shdr * sect = section_headers;
9ea033b2
NC
7960 Elf_Internal_Options * iopt;
7961 Elf_Internal_Options * option;
252b5132
RH
7962 size_t offset;
7963 int cnt;
7964
7965 /* Find the section header so that we get the size. */
7966 while (sect->sh_type != SHT_MIPS_OPTIONS)
d1133906 7967 ++ sect;
252b5132
RH
7968
7969 GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
7970 Elf_External_Options *, "options");
7971
7972 iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
584da044 7973 * sizeof (* iopt));
252b5132
RH
7974 if (iopt == NULL)
7975 {
7976 error (_("Out of memory"));
7977 return 0;
7978 }
7979
7980 offset = cnt = 0;
7981 option = iopt;
76da6bbe 7982
252b5132
RH
7983 while (offset < sect->sh_size)
7984 {
9ea033b2 7985 Elf_External_Options * eoption;
252b5132
RH
7986
7987 eoption = (Elf_External_Options *) ((char *) eopt + offset);
7988
7989 option->kind = BYTE_GET (eoption->kind);
7990 option->size = BYTE_GET (eoption->size);
7991 option->section = BYTE_GET (eoption->section);
7992 option->info = BYTE_GET (eoption->info);
7993
7994 offset += option->size;
76da6bbe 7995
252b5132
RH
7996 ++option;
7997 ++cnt;
7998 }
7999
8000 printf (_("\nSection '%s' contains %d entries:\n"),
d40ac9bd 8001 SECTION_NAME (sect), cnt);
252b5132
RH
8002
8003 option = iopt;
76da6bbe 8004
252b5132
RH
8005 while (cnt-- > 0)
8006 {
8007 size_t len;
8008
8009 switch (option->kind)
8010 {
8011 case ODK_NULL:
8012 /* This shouldn't happen. */
8013 printf (" NULL %d %lx", option->section, option->info);
8014 break;
8015 case ODK_REGINFO:
8016 printf (" REGINFO ");
8017 if (elf_header.e_machine == EM_MIPS)
8018 {
8019 /* 32bit form. */
584da044
NC
8020 Elf32_External_RegInfo * ereg;
8021 Elf32_RegInfo reginfo;
252b5132
RH
8022
8023 ereg = (Elf32_External_RegInfo *) (option + 1);
8024 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8025 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8026 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8027 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8028 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8029 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
8030
8031 printf ("GPR %08lx GP 0x%lx\n",
8032 reginfo.ri_gprmask,
8033 (unsigned long) reginfo.ri_gp_value);
8034 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
8035 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8036 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8037 }
8038 else
8039 {
8040 /* 64 bit form. */
9ea033b2 8041 Elf64_External_RegInfo * ereg;
252b5132
RH
8042 Elf64_Internal_RegInfo reginfo;
8043
8044 ereg = (Elf64_External_RegInfo *) (option + 1);
9ea033b2 8045 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
252b5132
RH
8046 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8047 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8048 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8049 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
9ea033b2 8050 reginfo.ri_gp_value = BYTE_GET8 (ereg->ri_gp_value);
252b5132
RH
8051
8052 printf ("GPR %08lx GP 0x",
8053 reginfo.ri_gprmask);
8054 printf_vma (reginfo.ri_gp_value);
8055 printf ("\n");
8056
8057 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
8058 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8059 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8060 }
8061 ++option;
8062 continue;
8063 case ODK_EXCEPTIONS:
8064 fputs (" EXCEPTIONS fpe_min(", stdout);
8065 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
8066 fputs (") fpe_max(", stdout);
8067 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
8068 fputs (")", stdout);
8069
8070 if (option->info & OEX_PAGE0)
8071 fputs (" PAGE0", stdout);
8072 if (option->info & OEX_SMM)
8073 fputs (" SMM", stdout);
8074 if (option->info & OEX_FPDBUG)
8075 fputs (" FPDBUG", stdout);
8076 if (option->info & OEX_DISMISS)
8077 fputs (" DISMISS", stdout);
8078 break;
8079 case ODK_PAD:
8080 fputs (" PAD ", stdout);
8081 if (option->info & OPAD_PREFIX)
8082 fputs (" PREFIX", stdout);
8083 if (option->info & OPAD_POSTFIX)
8084 fputs (" POSTFIX", stdout);
8085 if (option->info & OPAD_SYMBOL)
8086 fputs (" SYMBOL", stdout);
8087 break;
8088 case ODK_HWPATCH:
8089 fputs (" HWPATCH ", stdout);
8090 if (option->info & OHW_R4KEOP)
8091 fputs (" R4KEOP", stdout);
8092 if (option->info & OHW_R8KPFETCH)
8093 fputs (" R8KPFETCH", stdout);
8094 if (option->info & OHW_R5KEOP)
8095 fputs (" R5KEOP", stdout);
8096 if (option->info & OHW_R5KCVTL)
8097 fputs (" R5KCVTL", stdout);
8098 break;
8099 case ODK_FILL:
8100 fputs (" FILL ", stdout);
8101 /* XXX Print content of info word? */
8102 break;
8103 case ODK_TAGS:
8104 fputs (" TAGS ", stdout);
8105 /* XXX Print content of info word? */
8106 break;
8107 case ODK_HWAND:
8108 fputs (" HWAND ", stdout);
8109 if (option->info & OHWA0_R4KEOP_CHECKED)
8110 fputs (" R4KEOP_CHECKED", stdout);
8111 if (option->info & OHWA0_R4KEOP_CLEAN)
8112 fputs (" R4KEOP_CLEAN", stdout);
8113 break;
8114 case ODK_HWOR:
8115 fputs (" HWOR ", stdout);
8116 if (option->info & OHWA0_R4KEOP_CHECKED)
8117 fputs (" R4KEOP_CHECKED", stdout);
8118 if (option->info & OHWA0_R4KEOP_CLEAN)
8119 fputs (" R4KEOP_CLEAN", stdout);
8120 break;
8121 case ODK_GP_GROUP:
8122 printf (" GP_GROUP %#06lx self-contained %#06lx",
8123 option->info & OGP_GROUP,
8124 (option->info & OGP_SELF) >> 16);
8125 break;
8126 case ODK_IDENT:
8127 printf (" IDENT %#06lx self-contained %#06lx",
8128 option->info & OGP_GROUP,
8129 (option->info & OGP_SELF) >> 16);
8130 break;
8131 default:
8132 /* This shouldn't happen. */
8133 printf (" %3d ??? %d %lx",
8134 option->kind, option->section, option->info);
8135 break;
8136 }
8137
584da044 8138 len = sizeof (* eopt);
252b5132
RH
8139 while (len < option->size)
8140 if (((char *) option)[len] >= ' '
8141 && ((char *) option)[len] < 0x7f)
8142 printf ("%c", ((char *) option)[len++]);
8143 else
8144 printf ("\\%03o", ((char *) option)[len++]);
8145
8146 fputs ("\n", stdout);
8147 ++option;
8148 }
8149
8150 free (eopt);
8151 }
8152
8153 if (conflicts_offset != 0 && conflictsno != 0)
8154 {
9ea033b2
NC
8155 Elf32_External_Conflict * econf32;
8156 Elf64_External_Conflict * econf64;
8157 Elf32_Conflict * iconf;
252b5132
RH
8158 size_t cnt;
8159
8160 if (dynamic_symbols == NULL)
8161 {
8162 error (_("conflict list with without table"));
8163 return 0;
8164 }
8165
584da044 8166 iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (* iconf));
252b5132
RH
8167 if (iconf == NULL)
8168 {
8169 error (_("Out of memory"));
8170 return 0;
8171 }
8172
9ea033b2 8173 if (is_32bit_elf)
252b5132 8174 {
584da044 8175 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (* econf32),
252b5132
RH
8176 econf32, Elf32_External_Conflict *, "conflict");
8177
8178 for (cnt = 0; cnt < conflictsno; ++cnt)
8179 iconf[cnt] = BYTE_GET (econf32[cnt]);
8180 }
8181 else
8182 {
584da044 8183 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (* econf64),
252b5132
RH
8184 econf64, Elf64_External_Conflict *, "conflict");
8185
8186 for (cnt = 0; cnt < conflictsno; ++cnt)
8187 iconf[cnt] = BYTE_GET (econf64[cnt]);
8188 }
8189
8190 printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
8191 puts (_(" Num: Index Value Name"));
8192
8193 for (cnt = 0; cnt < conflictsno; ++cnt)
8194 {
19936277 8195 Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
252b5132 8196
16062207 8197 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963
NC
8198 print_vma (psym->st_value, FULL_HEX);
8199 printf (" %s\n", dynamic_strings + psym->st_name);
252b5132
RH
8200 }
8201
252b5132
RH
8202 free (iconf);
8203 }
8204
8205 return 1;
8206}
8207
779fe533
NC
8208static char *
8209get_note_type (e_type)
8210 unsigned e_type;
8211{
8212 static char buff[64];
103f02d3 8213
779fe533
NC
8214 switch (e_type)
8215 {
8216 case NT_PRSTATUS: return _("NT_PRSTATUS (prstatus structure)");
8217 case NT_FPREGSET: return _("NT_FPREGSET (floating point registers)");
8218 case NT_PRPSINFO: return _("NT_PRPSINFO (prpsinfo structure)");
8219 case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
d1133906 8220 case NT_PRXFPREG: return _("NT_PRXFPREG (user_xfpregs structure)");
779fe533
NC
8221 case NT_PSTATUS: return _("NT_PSTATUS (pstatus structure)");
8222 case NT_FPREGS: return _("NT_FPREGS (floating point registers)");
8223 case NT_PSINFO: return _("NT_PSINFO (psinfo structure)");
8224 case NT_LWPSTATUS: return _("NT_LWPSTATUS (lwpstatus_t structure)");
8225 case NT_LWPSINFO: return _("NT_LWPSINFO (lwpsinfo_t structure)");
7bea2f73 8226 case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus strcuture)");
779fe533
NC
8227 default:
8228 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
8229 return buff;
8230 }
8231}
8232
6d118b09
NC
8233/* Note that by the ELF standard, the name field is already null byte
8234 terminated, and namesz includes the terminating null byte.
8235 I.E. the value of namesz for the name "FSF" is 4.
8236
8237 If the value of namesz is zero, there is no name present. */
779fe533
NC
8238static int
8239process_note (pnote)
6d118b09 8240 Elf32_Internal_Note * pnote;
779fe533 8241{
103f02d3 8242 printf (" %s\t\t0x%08lx\t%s\n",
6d118b09 8243 pnote->namesz ? pnote->namedata : "(NONE)",
7036c0e1 8244 pnote->descsz, get_note_type (pnote->type));
779fe533
NC
8245 return 1;
8246}
8247
6d118b09 8248
779fe533
NC
8249static int
8250process_corefile_note_segment (file, offset, length)
8251 FILE * file;
f7a99963
NC
8252 bfd_vma offset;
8253 bfd_vma length;
779fe533
NC
8254{
8255 Elf_External_Note * pnotes;
8256 Elf_External_Note * external;
779fe533 8257 int res = 1;
103f02d3 8258
779fe533
NC
8259 if (length <= 0)
8260 return 0;
103f02d3 8261
779fe533
NC
8262 GET_DATA_ALLOC (offset, length, pnotes, Elf_External_Note *, "notes");
8263
103f02d3 8264 external = pnotes;
103f02d3 8265
305c7206 8266 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 8267 (unsigned long) offset, (unsigned long) length);
779fe533 8268 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 8269
6d118b09 8270 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 8271 {
6d118b09
NC
8272 Elf32_Internal_Note inote;
8273 char * temp = NULL;
8274
8275 inote.type = BYTE_GET (external->type);
8276 inote.namesz = BYTE_GET (external->namesz);
8277 inote.namedata = external->name;
8278 inote.descsz = BYTE_GET (external->descsz);
8279 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
8280 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 8281
6d118b09
NC
8282 external = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
8283
8284 /* Verify that name is null terminated. It appears that at least
8285 one version of Linux (RedHat 6.0) generates corefiles that don't
8286 comply with the ELF spec by failing to include the null byte in
8287 namesz. */
8288 if (inote.namedata[inote.namesz] != '\0')
8289 {
8290 temp = malloc (inote.namesz + 1);
76da6bbe 8291
6d118b09
NC
8292 if (temp == NULL)
8293 {
8294 error (_("Out of memory\n"));
8295 res = 0;
8296 break;
8297 }
76da6bbe 8298
6d118b09
NC
8299 strncpy (temp, inote.namedata, inote.namesz);
8300 temp[inote.namesz] = 0;
76da6bbe 8301
6d118b09
NC
8302 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
8303 inote.namedata = temp;
8304 }
8305
8306 res &= process_note (& inote);
103f02d3 8307
6d118b09
NC
8308 if (temp != NULL)
8309 {
8310 free (temp);
8311 temp = NULL;
8312 }
779fe533
NC
8313 }
8314
8315 free (pnotes);
103f02d3 8316
779fe533
NC
8317 return res;
8318}
8319
8320static int
8321process_corefile_note_segments (file)
8322 FILE * file;
8323{
8324 Elf_Internal_Phdr * program_headers;
8325 Elf_Internal_Phdr * segment;
8326 unsigned int i;
8327 int res = 1;
103f02d3 8328
779fe533
NC
8329 program_headers = (Elf_Internal_Phdr *) malloc
8330 (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
8331
8332 if (program_headers == NULL)
8333 {
8334 error (_("Out of memory\n"));
8335 return 0;
8336 }
8337
8338 if (is_32bit_elf)
8339 i = get_32bit_program_headers (file, program_headers);
8340 else
8341 i = get_64bit_program_headers (file, program_headers);
8342
8343 if (i == 0)
8344 {
8345 free (program_headers);
8346 return 0;
8347 }
103f02d3 8348
779fe533
NC
8349 for (i = 0, segment = program_headers;
8350 i < elf_header.e_phnum;
8351 i ++, segment ++)
8352 {
8353 if (segment->p_type == PT_NOTE)
103f02d3 8354 res &= process_corefile_note_segment (file,
30800947
NC
8355 (bfd_vma) segment->p_offset,
8356 (bfd_vma) segment->p_filesz);
779fe533 8357 }
103f02d3 8358
779fe533
NC
8359 free (program_headers);
8360
8361 return res;
8362}
8363
8364static int
8365process_corefile_contents (file)
8366 FILE * file;
8367{
8368 /* If we have not been asked to display the notes then do nothing. */
8369 if (! do_notes)
8370 return 1;
103f02d3 8371
779fe533
NC
8372 /* If file is not a core file then exit. */
8373 if (elf_header.e_type != ET_CORE)
8374 return 1;
103f02d3 8375
779fe533
NC
8376 /* No program headers means no NOTE segment. */
8377 if (elf_header.e_phnum == 0)
8378 {
8379 printf (_("No note segments present in the core file.\n"));
8380 return 1;
8381 }
8382
8383 return process_corefile_note_segments (file);
8384}
8385
252b5132
RH
8386static int
8387process_arch_specific (file)
9ea033b2 8388 FILE * file;
252b5132 8389{
a952a375
NC
8390 if (! do_arch)
8391 return 1;
8392
252b5132
RH
8393 switch (elf_header.e_machine)
8394 {
8395 case EM_MIPS:
4fe85591 8396 case EM_MIPS_RS3_LE:
252b5132
RH
8397 return process_mips_specific (file);
8398 break;
8399 default:
8400 break;
8401 }
8402 return 1;
8403}
8404
8405static int
8406get_file_header (file)
8407 FILE * file;
8408{
9ea033b2
NC
8409 /* Read in the identity array. */
8410 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
8411 return 0;
8412
9ea033b2
NC
8413 /* Determine how to read the rest of the header. */
8414 switch (elf_header.e_ident [EI_DATA])
8415 {
8416 default: /* fall through */
8417 case ELFDATANONE: /* fall through */
8418 case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
8419 case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
8420 }
8421
8422 /* For now we only support 32 bit and 64 bit ELF files. */
8423 is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
8424
8425 /* Read in the rest of the header. */
8426 if (is_32bit_elf)
8427 {
8428 Elf32_External_Ehdr ehdr32;
252b5132 8429
9ea033b2
NC
8430 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
8431 return 0;
103f02d3 8432
9ea033b2
NC
8433 elf_header.e_type = BYTE_GET (ehdr32.e_type);
8434 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
8435 elf_header.e_version = BYTE_GET (ehdr32.e_version);
8436 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
8437 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
8438 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
8439 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
8440 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
8441 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
8442 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
8443 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
8444 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
8445 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
8446 }
252b5132 8447 else
9ea033b2
NC
8448 {
8449 Elf64_External_Ehdr ehdr64;
a952a375
NC
8450
8451 /* If we have been compiled with sizeof (bfd_vma) == 4, then
8452 we will not be able to cope with the 64bit data found in
8453 64 ELF files. Detect this now and abort before we start
8454 overwritting things. */
8455 if (sizeof (bfd_vma) < 8)
8456 {
8457 error (_("This instance of readelf has been built without support for a\n"));
8458 error (_("64 bit data type and so it cannot read 64 bit ELF files.\n"));
8459 return 0;
8460 }
103f02d3 8461
9ea033b2
NC
8462 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
8463 return 0;
103f02d3 8464
9ea033b2
NC
8465 elf_header.e_type = BYTE_GET (ehdr64.e_type);
8466 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
8467 elf_header.e_version = BYTE_GET (ehdr64.e_version);
8468 elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry);
8469 elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff);
8470 elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff);
8471 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
8472 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
8473 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
8474 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
8475 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
8476 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
8477 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
8478 }
252b5132
RH
8479
8480 return 1;
8481}
8482
8483static void
8484process_file (file_name)
8485 char * file_name;
8486{
8487 FILE * file;
8488 struct stat statbuf;
8489 unsigned int i;
8490
8491 if (stat (file_name, & statbuf) < 0)
8492 {
8493 error (_("Cannot stat input file %s.\n"), file_name);
8494 return;
8495 }
8496
8497 file = fopen (file_name, "rb");
8498 if (file == NULL)
8499 {
8500 error (_("Input file %s not found.\n"), file_name);
8501 return;
8502 }
8503
8504 if (! get_file_header (file))
8505 {
8506 error (_("%s: Failed to read file header\n"), file_name);
8507 fclose (file);
8508 return;
8509 }
8510
8511 /* Initialise per file variables. */
8512 for (i = NUM_ELEM (version_info); i--;)
8513 version_info[i] = 0;
8514
8515 for (i = NUM_ELEM (dynamic_info); i--;)
8516 dynamic_info[i] = 0;
8517
8518 /* Process the file. */
8519 if (show_name)
8520 printf (_("\nFile: %s\n"), file_name);
8521
8522 if (! process_file_header ())
8523 {
8524 fclose (file);
8525 return;
8526 }
8527
8528 process_section_headers (file);
8529
8530 process_program_headers (file);
8531
8532 process_dynamic_segment (file);
8533
8534 process_relocs (file);
8535
4d6ed7c8
NC
8536 process_unwind (file);
8537
252b5132
RH
8538 process_symbol_table (file);
8539
8540 process_syminfo (file);
8541
8542 process_version_sections (file);
8543
8544 process_section_contents (file);
103f02d3 8545
779fe533 8546 process_corefile_contents (file);
103f02d3 8547
252b5132
RH
8548 process_arch_specific (file);
8549
8550 fclose (file);
8551
8552 if (section_headers)
8553 {
8554 free (section_headers);
8555 section_headers = NULL;
8556 }
8557
8558 if (string_table)
8559 {
8560 free (string_table);
8561 string_table = NULL;
d40ac9bd 8562 string_table_length = 0;
252b5132
RH
8563 }
8564
8565 if (dynamic_strings)
8566 {
8567 free (dynamic_strings);
8568 dynamic_strings = NULL;
8569 }
8570
8571 if (dynamic_symbols)
8572 {
8573 free (dynamic_symbols);
8574 dynamic_symbols = NULL;
19936277 8575 num_dynamic_syms = 0;
252b5132
RH
8576 }
8577
8578 if (dynamic_syminfo)
8579 {
8580 free (dynamic_syminfo);
8581 dynamic_syminfo = NULL;
8582 }
8583}
8584
8585#ifdef SUPPORT_DISASSEMBLY
8586/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2
NC
8587 fix this so that we insert symbolic addresses here, esp for GOT/PLT
8588 symbols */
252b5132
RH
8589
8590void
8591print_address (unsigned int addr, FILE * outfile)
8592{
8593 fprintf (outfile,"0x%8.8x", addr);
8594}
8595
8596/* Needed by the i386 disassembler. */
8597void
8598db_task_printsym (unsigned int addr)
8599{
8600 print_address (addr, stderr);
8601}
8602#endif
8603
8604int
8605main (argc, argv)
8606 int argc;
8607 char ** argv;
8608{
8609#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
8610 setlocale (LC_MESSAGES, "");
8611#endif
8612 bindtextdomain (PACKAGE, LOCALEDIR);
8613 textdomain (PACKAGE);
8614
8615 parse_args (argc, argv);
8616
8617 if (optind < (argc - 1))
8618 show_name = 1;
8619
8620 while (optind < argc)
8621 process_file (argv [optind ++]);
8622
8623 if (dump_sects != NULL)
8624 free (dump_sects);
8625
8626 return 0;
8627}