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