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