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