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