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