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