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