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