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