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