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