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