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