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