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