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