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