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