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