* elf32-h8300.c (R_H8_DIR32A16): Fix name field.
[deliverable/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
cb44e358 2 Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 02111-1307, USA. */
23\f
24
25#include <assert.h>
00ed88bd 26#include <sys/types.h>
252b5132
RH
27#include <sys/stat.h>
28#include <stdio.h>
29#include <time.h>
30
a952a375 31#if __GNUC__ >= 2
19936277 32/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 33 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 34 Only do this if we believe that the compiler can support a 64 bit
a952a375 35 data type. For now we only rely on GCC being able to do this. */
19936277 36#define BFD64
a952a375
NC
37#endif
38
252b5132
RH
39#include "bfd.h"
40
41#include "elf/common.h"
42#include "elf/external.h"
43#include "elf/internal.h"
44#include "elf/dwarf2.h"
45
46/* The following headers use the elf/reloc-macros.h file to
47 automatically generate relocation recognition functions
48 such as elf_mips_reloc_type() */
49
50#define RELOC_MACROS_GEN_FUNC
51
252b5132 52#include "elf/alpha.h"
3b16e843 53#include "elf/arc.h"
252b5132 54#include "elf/arm.h"
3b16e843
NC
55#include "elf/avr.h"
56#include "elf/cris.h"
252b5132
RH
57#include "elf/d10v.h"
58#include "elf/d30v.h"
d172d4ba 59#include "elf/dlx.h"
252b5132 60#include "elf/fr30.h"
5c70f934 61#include "elf/frv.h"
3b16e843
NC
62#include "elf/h8.h"
63#include "elf/hppa.h"
64#include "elf/i386.h"
35b1837e 65#include "elf/i370.h"
3b16e843
NC
66#include "elf/i860.h"
67#include "elf/i960.h"
68#include "elf/ia64.h"
1e4cf259 69#include "elf/ip2k.h"
3b16e843
NC
70#include "elf/m32r.h"
71#include "elf/m68k.h"
75751cd9 72#include "elf/m68hc11.h"
252b5132 73#include "elf/mcore.h"
3b16e843 74#include "elf/mips.h"
3c3bdf30 75#include "elf/mmix.h"
3b16e843
NC
76#include "elf/mn10200.h"
77#include "elf/mn10300.h"
2469cfa2 78#include "elf/msp430.h"
3b16e843 79#include "elf/or32.h"
7d466069 80#include "elf/pj.h"
3b16e843 81#include "elf/ppc.h"
c833c019 82#include "elf/ppc64.h"
a85d7ed0 83#include "elf/s390.h"
3b16e843
NC
84#include "elf/sh.h"
85#include "elf/sparc.h"
86#include "elf/v850.h"
179d3252 87#include "elf/vax.h"
3b16e843 88#include "elf/x86-64.h"
93fbbb04 89#include "elf/xstormy16.h"
3b36097d 90#include "elf/iq2000.h"
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 {
488 error (_("Unable to seek to %x for %s\n"), offset, reason);
489 return NULL;
490 }
491
492 mvar = var;
493 if (mvar == NULL)
494 {
495 mvar = (PTR) malloc (size);
496
497 if (mvar == NULL)
498 {
499 error (_("Out of memory allocating %d bytes for %s\n"),
500 size, reason);
501 return NULL;
502 }
503 }
504
505 if (fread (mvar, size, 1, file) != 1)
506 {
507 error (_("Unable to read in %d bytes of %s\n"), size, reason);
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
NC
3769
3770 string_table_length = section->sh_size;
252b5132
RH
3771 }
3772
3773 /* Scan the sections for the dynamic symbol table
e3c8793a 3774 and dynamic string table and debug sections. */
252b5132
RH
3775 dynamic_symbols = NULL;
3776 dynamic_strings = NULL;
3777 dynamic_syminfo = NULL;
f1ef08cb 3778 symtab_shndx_hdr = NULL;
103f02d3 3779
252b5132
RH
3780 for (i = 0, section = section_headers;
3781 i < elf_header.e_shnum;
b34976b6 3782 i++, section++)
252b5132 3783 {
b34976b6 3784 char *name = SECTION_NAME (section);
252b5132
RH
3785
3786 if (section->sh_type == SHT_DYNSYM)
3787 {
3788 if (dynamic_symbols != NULL)
3789 {
3790 error (_("File contains multiple dynamic symbol tables\n"));
3791 continue;
3792 }
3793
19936277 3794 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 3795 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
3796 }
3797 else if (section->sh_type == SHT_STRTAB
3798 && strcmp (name, ".dynstr") == 0)
3799 {
3800 if (dynamic_strings != NULL)
3801 {
3802 error (_("File contains multiple dynamic string tables\n"));
3803 continue;
3804 }
3805
a6e9f9df
AM
3806 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
3807 section->sh_size,
3808 _("dynamic strings"));
252b5132 3809 }
9ad5cbcf
AM
3810 else if (section->sh_type == SHT_SYMTAB_SHNDX)
3811 {
3812 if (symtab_shndx_hdr != NULL)
3813 {
3814 error (_("File contains multiple symtab shndx tables\n"));
3815 continue;
3816 }
3817 symtab_shndx_hdr = section;
3818 }
252b5132 3819 else if ((do_debugging || do_debug_info || do_debug_abbrevs
31b6fca6 3820 || do_debug_lines || do_debug_pubnames || do_debug_aranges
a2f14207
DB
3821 || do_debug_frames || do_debug_macinfo || do_debug_str
3822 || do_debug_loc)
252b5132
RH
3823 && strncmp (name, ".debug_", 7) == 0)
3824 {
3825 name += 7;
3826
3827 if (do_debugging
3828 || (do_debug_info && (strcmp (name, "info") == 0))
3829 || (do_debug_abbrevs && (strcmp (name, "abbrev") == 0))
3830 || (do_debug_lines && (strcmp (name, "line") == 0))
3831 || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
3832 || (do_debug_aranges && (strcmp (name, "aranges") == 0))
c47d488e 3833 || (do_debug_frames && (strcmp (name, "frame") == 0))
e0c60db2 3834 || (do_debug_macinfo && (strcmp (name, "macinfo") == 0))
261a45ad 3835 || (do_debug_str && (strcmp (name, "str") == 0))
a2f14207 3836 || (do_debug_loc && (strcmp (name, "loc") == 0))
252b5132
RH
3837 )
3838 request_dump (i, DEBUG_DUMP);
3839 }
09fd7e38
JM
3840 /* linkonce section to be combined with .debug_info at link time. */
3841 else if ((do_debugging || do_debug_info)
3842 && strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
3843 request_dump (i, DEBUG_DUMP);
c47d488e
DD
3844 else if (do_debug_frames && strcmp (name, ".eh_frame") == 0)
3845 request_dump (i, DEBUG_DUMP);
252b5132
RH
3846 }
3847
3848 if (! do_sections)
3849 return 1;
3850
3a1a2036
NC
3851 if (elf_header.e_shnum > 1)
3852 printf (_("\nSection Headers:\n"));
3853 else
3854 printf (_("\nSection Header:\n"));
76da6bbe 3855
f7a99963
NC
3856 if (is_32bit_elf)
3857 printf
3858 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
d974e256
JJ
3859 else if (do_wide)
3860 printf
3861 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
f7a99963
NC
3862 else
3863 {
3864 printf (_(" [Nr] Name Type Address Offset\n"));
3865 printf (_(" Size EntSize Flags Link Info Align\n"));
3866 }
252b5132
RH
3867
3868 for (i = 0, section = section_headers;
3869 i < elf_header.e_shnum;
b34976b6 3870 i++, section++)
252b5132 3871 {
9ad5cbcf
AM
3872 printf (" [%2u] %-17.17s %-15.15s ",
3873 SECTION_HEADER_NUM (i),
252b5132
RH
3874 SECTION_NAME (section),
3875 get_section_type_name (section->sh_type));
3876
f7a99963
NC
3877 if (is_32bit_elf)
3878 {
3879 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 3880
f7a99963
NC
3881 printf ( " %6.6lx %6.6lx %2.2lx",
3882 (unsigned long) section->sh_offset,
3883 (unsigned long) section->sh_size,
3884 (unsigned long) section->sh_entsize);
d1133906
NC
3885
3886 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 3887
93ebe586 3888 printf ("%2ld %3lx %2ld\n",
f7a99963
NC
3889 (unsigned long) section->sh_link,
3890 (unsigned long) section->sh_info,
3891 (unsigned long) section->sh_addralign);
3892 }
d974e256
JJ
3893 else if (do_wide)
3894 {
3895 print_vma (section->sh_addr, LONG_HEX);
3896
3897 if ((long) section->sh_offset == section->sh_offset)
3898 printf (" %6.6lx", (unsigned long) section->sh_offset);
3899 else
3900 {
3901 putchar (' ');
3902 print_vma (section->sh_offset, LONG_HEX);
3903 }
3904
3905 if ((unsigned long) section->sh_size == section->sh_size)
3906 printf (" %6.6lx", (unsigned long) section->sh_size);
3907 else
3908 {
3909 putchar (' ');
3910 print_vma (section->sh_size, LONG_HEX);
3911 }
3912
3913 if ((unsigned long) section->sh_entsize == section->sh_entsize)
3914 printf (" %2.2lx", (unsigned long) section->sh_entsize);
3915 else
3916 {
3917 putchar (' ');
3918 print_vma (section->sh_entsize, LONG_HEX);
3919 }
3920
3921 printf (" %3s ", get_elf_section_flags (section->sh_flags));
3922
3923 printf ("%2ld %3lx ",
3924 (unsigned long) section->sh_link,
3925 (unsigned long) section->sh_info);
3926
3927 if ((unsigned long) section->sh_addralign == section->sh_addralign)
3928 printf ("%2ld\n", (unsigned long) section->sh_addralign);
3929 else
3930 {
3931 print_vma (section->sh_addralign, DEC);
3932 putchar ('\n');
3933 }
3934 }
f7a99963
NC
3935 else
3936 {
3937 putchar (' ');
3938 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
3939 if ((long) section->sh_offset == section->sh_offset)
3940 printf (" %8.8lx", (unsigned long) section->sh_offset);
3941 else
3942 {
3943 printf (" ");
3944 print_vma (section->sh_offset, LONG_HEX);
3945 }
f7a99963
NC
3946 printf ("\n ");
3947 print_vma (section->sh_size, LONG_HEX);
3948 printf (" ");
3949 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 3950
d1133906 3951 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 3952
f7a99963
NC
3953 printf (" %2ld %3lx %ld\n",
3954 (unsigned long) section->sh_link,
3955 (unsigned long) section->sh_info,
3956 (unsigned long) section->sh_addralign);
3957 }
252b5132
RH
3958 }
3959
e3c8793a
NC
3960 printf (_("Key to Flags:\n\
3961 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
3962 I (info), L (link order), G (group), x (unknown)\n\
3963 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
d1133906 3964
252b5132
RH
3965 return 1;
3966}
3967
566b0d53
L
3968struct
3969{
3970 const char *name;
3971 int reloc;
3972 int size;
3973 int rela;
3974} dynamic_relocations [] =
3975{
3976 { "REL", DT_REL, DT_RELSZ, FALSE },
3977 { "RELA", DT_RELA, DT_RELASZ, TRUE },
3978 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
3979};
3980
252b5132
RH
3981/* Process the reloc section. */
3982static int
3983process_relocs (file)
b34976b6 3984 FILE *file;
252b5132 3985{
b34976b6
AM
3986 unsigned long rel_size;
3987 unsigned long rel_offset;
252b5132
RH
3988
3989
3990 if (!do_reloc)
3991 return 1;
3992
3993 if (do_using_dynamic)
3994 {
566b0d53
L
3995 int is_rela;
3996 const char *name;
3997 int has_dynamic_reloc;
3998 unsigned int i;
3999
4000 has_dynamic_reloc = 0;
252b5132 4001
566b0d53 4002 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 4003 {
566b0d53
L
4004 is_rela = dynamic_relocations [i].rela;
4005 name = dynamic_relocations [i].name;
4006 rel_size = dynamic_info [dynamic_relocations [i].size];
4007 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 4008
566b0d53
L
4009 has_dynamic_reloc |= rel_size;
4010
4011 if (is_rela == UNKNOWN)
aa903cfb 4012 {
566b0d53
L
4013 if (dynamic_relocations [i].reloc == DT_JMPREL)
4014 switch (dynamic_info[DT_PLTREL])
4015 {
4016 case DT_REL:
4017 is_rela = FALSE;
4018 break;
4019 case DT_RELA:
4020 is_rela = TRUE;
4021 break;
4022 }
aa903cfb 4023 }
252b5132 4024
566b0d53
L
4025 if (rel_size)
4026 {
4027 printf
4028 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
4029 name, rel_offset, rel_size);
252b5132 4030
d93f0186
NC
4031 dump_relocations (file,
4032 offset_from_vma (file, rel_offset, rel_size),
4033 rel_size,
566b0d53
L
4034 dynamic_symbols, num_dynamic_syms,
4035 dynamic_strings, is_rela);
4036 }
252b5132 4037 }
566b0d53
L
4038
4039 if (! has_dynamic_reloc)
252b5132
RH
4040 printf (_("\nThere are no dynamic relocations in this file.\n"));
4041 }
4042 else
4043 {
b34976b6
AM
4044 Elf_Internal_Shdr *section;
4045 unsigned long i;
4046 int found = 0;
252b5132
RH
4047
4048 for (i = 0, section = section_headers;
4049 i < elf_header.e_shnum;
b34976b6 4050 i++, section++)
252b5132
RH
4051 {
4052 if ( section->sh_type != SHT_RELA
4053 && section->sh_type != SHT_REL)
4054 continue;
4055
4056 rel_offset = section->sh_offset;
4057 rel_size = section->sh_size;
4058
4059 if (rel_size)
4060 {
b34976b6
AM
4061 Elf_Internal_Shdr *strsec;
4062 Elf_Internal_Sym *symtab;
4063 char *strtab;
4064 int is_rela;
4065 unsigned long nsyms;
103f02d3 4066
252b5132
RH
4067 printf (_("\nRelocation section "));
4068
4069 if (string_table == NULL)
19936277 4070 printf ("%d", section->sh_name);
252b5132 4071 else
3a1a2036 4072 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
4073
4074 printf (_(" at offset 0x%lx contains %lu entries:\n"),
4075 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
4076
af3fc3bc
AM
4077 symtab = NULL;
4078 strtab = NULL;
4079 nsyms = 0;
4080 if (section->sh_link)
4081 {
b34976b6 4082 Elf_Internal_Shdr *symsec;
252b5132 4083
9ad5cbcf 4084 symsec = SECTION_HEADER (section->sh_link);
af3fc3bc 4085 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 4086 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 4087
af3fc3bc
AM
4088 if (symtab == NULL)
4089 continue;
252b5132 4090
9ad5cbcf 4091 strsec = SECTION_HEADER (symsec->sh_link);
103f02d3 4092
a6e9f9df
AM
4093 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
4094 strsec->sh_size,
4095 _("string table"));
af3fc3bc 4096 }
aa903cfb 4097 is_rela = section->sh_type == SHT_RELA;
252b5132 4098
af3fc3bc
AM
4099 dump_relocations (file, rel_offset, rel_size,
4100 symtab, nsyms, strtab, is_rela);
252b5132 4101
af3fc3bc
AM
4102 if (strtab)
4103 free (strtab);
4104 if (symtab)
4105 free (symtab);
252b5132
RH
4106
4107 found = 1;
4108 }
4109 }
4110
4111 if (! found)
4112 printf (_("\nThere are no relocations in this file.\n"));
4113 }
4114
4115 return 1;
4116}
4117
4d6ed7c8
NC
4118#include "unwind-ia64.h"
4119
4120/* An absolute address consists of a section and an offset. If the
4121 section is NULL, the offset itself is the address, otherwise, the
4122 address equals to LOAD_ADDRESS(section) + offset. */
4123
4124struct absaddr
4125 {
4126 unsigned short section;
4127 bfd_vma offset;
4128 };
4129
4130struct unw_aux_info
4131 {
4132 struct unw_table_entry
4133 {
b34976b6
AM
4134 struct absaddr start;
4135 struct absaddr end;
4136 struct absaddr info;
4d6ed7c8 4137 }
b34976b6
AM
4138 *table; /* Unwind table. */
4139 unsigned long table_len; /* Length of unwind table. */
4140 unsigned char *info; /* Unwind info. */
4141 unsigned long info_size; /* Size of unwind info. */
4142 bfd_vma info_addr; /* starting address of unwind info. */
4143 bfd_vma seg_base; /* Starting address of segment. */
4144 Elf_Internal_Sym *symtab; /* The symbol table. */
4145 unsigned long nsyms; /* Number of symbols. */
4146 char *strtab; /* The string table. */
4147 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
4148 };
4149
b34976b6
AM
4150static void find_symbol_for_address
4151 PARAMS ((struct unw_aux_info *, struct absaddr, const char **, bfd_vma *));
4152static void dump_ia64_unwind
4153 PARAMS ((struct unw_aux_info *));
4154static int slurp_ia64_unwind_table
4155 PARAMS ((FILE *, struct unw_aux_info *, Elf_Internal_Shdr *));
4d6ed7c8
NC
4156
4157static void
4158find_symbol_for_address (aux, addr, symname, offset)
4159 struct unw_aux_info *aux;
4160 struct absaddr addr;
4161 const char **symname;
4162 bfd_vma *offset;
4163{
4164 bfd_vma dist = (bfd_vma) 0x100000;
4165 Elf_Internal_Sym *sym, *best = NULL;
4166 unsigned long i;
4167
4168 for (i = 0, sym = aux->symtab; i < aux->nsyms; ++i, ++sym)
4169 {
4170 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
4171 && sym->st_name != 0
4172 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
4173 && addr.offset >= sym->st_value
4174 && addr.offset - sym->st_value < dist)
4175 {
4176 best = sym;
4177 dist = addr.offset - sym->st_value;
4178 if (!dist)
4179 break;
4180 }
4181 }
4182 if (best)
4183 {
4184 *symname = (best->st_name >= aux->strtab_size
4185 ? "<corrupt>" : aux->strtab + best->st_name);
4186 *offset = dist;
4187 return;
4188 }
4189 *symname = NULL;
4190 *offset = addr.offset;
4191}
4192
4193static void
4194dump_ia64_unwind (aux)
4195 struct unw_aux_info *aux;
4196{
4197 bfd_vma addr_size;
b34976b6 4198 struct unw_table_entry *tp;
4d6ed7c8 4199 int in_body;
7036c0e1 4200
4d6ed7c8
NC
4201 addr_size = is_32bit_elf ? 4 : 8;
4202
4203 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
4204 {
4205 bfd_vma stamp;
4206 bfd_vma offset;
b34976b6
AM
4207 const unsigned char *dp;
4208 const unsigned char *head;
4209 const char *procname;
4d6ed7c8
NC
4210
4211 find_symbol_for_address (aux, tp->start, &procname, &offset);
4212
4213 fputs ("\n<", stdout);
4214
4215 if (procname)
4216 {
4217 fputs (procname, stdout);
4218
4219 if (offset)
4220 printf ("+%lx", (unsigned long) offset);
4221 }
4222
4223 fputs (">: [", stdout);
4224 print_vma (tp->start.offset, PREFIX_HEX);
4225 fputc ('-', stdout);
4226 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 4227 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
4228 (unsigned long) (tp->info.offset - aux->seg_base));
4229
4230 head = aux->info + (tp->info.offset - aux->info_addr);
4231 stamp = BYTE_GET8 ((unsigned char *) head);
4232
86f55779 4233 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
4234 (unsigned) UNW_VER (stamp),
4235 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
4236 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
4237 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
4238 (unsigned long) (addr_size * UNW_LENGTH (stamp)));
4239
4240 if (UNW_VER (stamp) != 1)
4241 {
4242 printf ("\tUnknown version.\n");
4243 continue;
4244 }
4245
4246 in_body = 0;
4247 for (dp = head + 8; dp < head + 8 + addr_size * UNW_LENGTH (stamp);)
4248 dp = unw_decode (dp, in_body, & in_body);
4249 }
4250}
4251
4252static int
4253slurp_ia64_unwind_table (file, aux, sec)
4254 FILE *file;
4255 struct unw_aux_info *aux;
c8286bd1 4256 Elf_Internal_Shdr *sec;
4d6ed7c8
NC
4257{
4258 unsigned long size, addr_size, nrelas, i;
d93f0186 4259 Elf_Internal_Phdr *seg;
4d6ed7c8 4260 struct unw_table_entry *tep;
c8286bd1 4261 Elf_Internal_Shdr *relsec;
4d6ed7c8
NC
4262 Elf_Internal_Rela *rela, *rp;
4263 unsigned char *table, *tp;
4264 Elf_Internal_Sym *sym;
4265 const char *relname;
4d6ed7c8
NC
4266
4267 addr_size = is_32bit_elf ? 4 : 8;
4268
4269 /* First, find the starting address of the segment that includes
4270 this section: */
4271
4272 if (elf_header.e_phnum)
4273 {
d93f0186 4274 if (! get_program_headers (file))
4d6ed7c8 4275 return 0;
4d6ed7c8 4276
d93f0186
NC
4277 for (seg = program_headers;
4278 seg < program_headers + elf_header.e_phnum;
4279 ++seg)
4d6ed7c8
NC
4280 {
4281 if (seg->p_type != PT_LOAD)
4282 continue;
4283
4284 if (sec->sh_addr >= seg->p_vaddr
4285 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
4286 {
4287 aux->seg_base = seg->p_vaddr;
4288 break;
4289 }
4290 }
4d6ed7c8
NC
4291 }
4292
4293 /* Second, build the unwind table from the contents of the unwind section: */
4294 size = sec->sh_size;
a6e9f9df
AM
4295 table = (char *) get_data (NULL, file, sec->sh_offset,
4296 size, _("unwind table"));
4297 if (!table)
4298 return 0;
4d6ed7c8
NC
4299
4300 tep = aux->table = xmalloc (size / (3 * addr_size) * sizeof (aux->table[0]));
b34976b6 4301 for (tp = table; tp < table + size; tp += 3 * addr_size, ++tep)
4d6ed7c8
NC
4302 {
4303 tep->start.section = SHN_UNDEF;
4304 tep->end.section = SHN_UNDEF;
4305 tep->info.section = SHN_UNDEF;
4306 if (is_32bit_elf)
4307 {
4308 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
4309 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
4310 tep->info.offset = byte_get ((unsigned char *) tp + 8, 4);
4311 }
4312 else
4313 {
4314 tep->start.offset = BYTE_GET8 ((unsigned char *) tp + 0);
4315 tep->end.offset = BYTE_GET8 ((unsigned char *) tp + 8);
4316 tep->info.offset = BYTE_GET8 ((unsigned char *) tp + 16);
4317 }
4318 tep->start.offset += aux->seg_base;
4319 tep->end.offset += aux->seg_base;
4320 tep->info.offset += aux->seg_base;
4321 }
4322 free (table);
4323
4324 /* Third, apply any relocations to the unwind table: */
4325
4326 for (relsec = section_headers;
4327 relsec < section_headers + elf_header.e_shnum;
4328 ++relsec)
4329 {
4330 if (relsec->sh_type != SHT_RELA
9ad5cbcf 4331 || SECTION_HEADER (relsec->sh_info) != sec)
4d6ed7c8
NC
4332 continue;
4333
4334 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
4335 & rela, & nrelas))
4336 return 0;
4337
4338 for (rp = rela; rp < rela + nrelas; ++rp)
4339 {
4340 if (is_32bit_elf)
4341 {
4342 relname = elf_ia64_reloc_type (ELF32_R_TYPE (rp->r_info));
4343 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
4344
4345 if (ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
4346 {
e5fb9629 4347 warn (_("Skipping unexpected symbol type %u\n"),
4d6ed7c8
NC
4348 ELF32_ST_TYPE (sym->st_info));
4349 continue;
4350 }
4351 }
4352 else
4353 {
4354 relname = elf_ia64_reloc_type (ELF64_R_TYPE (rp->r_info));
4355 sym = aux->symtab + ELF64_R_SYM (rp->r_info);
4356
4357 if (ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
4358 {
e5fb9629 4359 warn (_("Skipping unexpected symbol type %u\n"),
4d6ed7c8
NC
4360 ELF64_ST_TYPE (sym->st_info));
4361 continue;
4362 }
4363 }
4364
4365 if (strncmp (relname, "R_IA64_SEGREL", 13) != 0)
4366 {
e5fb9629 4367 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
4368 continue;
4369 }
4370
4371 i = rp->r_offset / (3 * addr_size);
4372
4373 switch (rp->r_offset/addr_size % 3)
4374 {
4375 case 0:
4376 aux->table[i].start.section = sym->st_shndx;
4377 aux->table[i].start.offset += rp->r_addend;
4378 break;
4379 case 1:
4380 aux->table[i].end.section = sym->st_shndx;
4381 aux->table[i].end.offset += rp->r_addend;
4382 break;
4383 case 2:
4384 aux->table[i].info.section = sym->st_shndx;
4385 aux->table[i].info.offset += rp->r_addend;
4386 break;
4387 default:
4388 break;
4389 }
4390 }
4391
4392 free (rela);
4393 }
4394
4395 aux->table_len = size / (3 * addr_size);
4396 return 1;
4397}
4398
4399static int
4400process_unwind (file)
b34976b6 4401 FILE *file;
4d6ed7c8 4402{
c8286bd1 4403 Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
579f31ac 4404 unsigned long i, addr_size, unwcount = 0, unwstart = 0;
4d6ed7c8
NC
4405 struct unw_aux_info aux;
4406
e58d53af
L
4407 if (!do_unwind)
4408 return 1;
4409
f1467e33
L
4410 if (elf_header.e_machine != EM_IA_64)
4411 {
4412 printf (_("\nThere are no unwind sections in this file.\n"));
4413 return 1;
4414 }
4415
4d6ed7c8
NC
4416 memset (& aux, 0, sizeof (aux));
4417
4418 addr_size = is_32bit_elf ? 4 : 8;
4419
4d6ed7c8
NC
4420 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
4421 {
4422 if (sec->sh_type == SHT_SYMTAB)
4423 {
4424 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 4425 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 4426
9ad5cbcf 4427 strsec = SECTION_HEADER (sec->sh_link);
4d6ed7c8 4428 aux.strtab_size = strsec->sh_size;
a6e9f9df
AM
4429 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
4430 aux.strtab_size, _("string table"));
4d6ed7c8
NC
4431 }
4432 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
4433 unwcount++;
4434 }
4435
4436 if (!unwcount)
4437 printf (_("\nThere are no unwind sections in this file.\n"));
4438
4439 while (unwcount-- > 0)
4440 {
4441 char *suffix;
4442 size_t len, len2;
4443
4444 for (i = unwstart, sec = section_headers + unwstart;
4445 i < elf_header.e_shnum; ++i, ++sec)
4446 if (sec->sh_type == SHT_IA_64_UNWIND)
4447 {
4448 unwsec = sec;
4449 break;
4450 }
4451
4452 unwstart = i + 1;
4453 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
4454
4455 if (strncmp (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once,
4456 len) == 0)
4457 {
4458 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO */
4459 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
4460 suffix = SECTION_NAME (unwsec) + len;
4461 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
4462 ++i, ++sec)
4463 if (strncmp (SECTION_NAME (sec),
4464 ELF_STRING_ia64_unwind_info_once, len2) == 0
4465 && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
4466 break;
4467 }
4468 else
4469 {
4470 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
4471 .IA_64.unwind or BAR -> .IA_64.unwind_info */
4472 len = sizeof (ELF_STRING_ia64_unwind) - 1;
4473 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
4474 suffix = "";
4475 if (strncmp (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind,
4476 len) == 0)
4477 suffix = SECTION_NAME (unwsec) + len;
4478 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
4479 ++i, ++sec)
4480 if (strncmp (SECTION_NAME (sec),
4481 ELF_STRING_ia64_unwind_info, len2) == 0
4482 && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
4483 break;
4484 }
4485
4486 if (i == elf_header.e_shnum)
4487 {
4488 printf (_("\nCould not find unwind info section for "));
4489
4490 if (string_table == NULL)
4491 printf ("%d", unwsec->sh_name);
4492 else
3a1a2036 4493 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
4494 }
4495 else
4d6ed7c8
NC
4496 {
4497 aux.info_size = sec->sh_size;
4498 aux.info_addr = sec->sh_addr;
a6e9f9df
AM
4499 aux.info = (char *) get_data (NULL, file, sec->sh_offset,
4500 aux.info_size, _("unwind info"));
4d6ed7c8 4501
579f31ac 4502 printf (_("\nUnwind section "));
4d6ed7c8 4503
579f31ac
JJ
4504 if (string_table == NULL)
4505 printf ("%d", unwsec->sh_name);
4506 else
3a1a2036 4507 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 4508
579f31ac 4509 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 4510 (unsigned long) unwsec->sh_offset,
579f31ac 4511 (unsigned long) (unwsec->sh_size / (3 * addr_size)));
4d6ed7c8 4512
579f31ac 4513 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 4514
579f31ac
JJ
4515 if (aux.table_len > 0)
4516 dump_ia64_unwind (& aux);
4517
4518 if (aux.table)
4519 free ((char *) aux.table);
4520 if (aux.info)
4521 free ((char *) aux.info);
4522 aux.table = NULL;
4523 aux.info = NULL;
4524 }
4d6ed7c8 4525 }
4d6ed7c8 4526
4d6ed7c8
NC
4527 if (aux.symtab)
4528 free (aux.symtab);
4529 if (aux.strtab)
4530 free ((char *) aux.strtab);
4531
4532 return 1;
4533}
4534
252b5132
RH
4535static void
4536dynamic_segment_mips_val (entry)
b34976b6 4537 Elf_Internal_Dyn *entry;
252b5132
RH
4538{
4539 switch (entry->d_tag)
4540 {
4541 case DT_MIPS_FLAGS:
4542 if (entry->d_un.d_val == 0)
4543 printf ("NONE\n");
4544 else
4545 {
4546 static const char * opts[] =
4547 {
4548 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
4549 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
4550 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
4551 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
4552 "RLD_ORDER_SAFE"
4553 };
4554 unsigned int cnt;
4555 int first = 1;
b34976b6 4556 for (cnt = 0; cnt < NUM_ELEM (opts); ++cnt)
252b5132
RH
4557 if (entry->d_un.d_val & (1 << cnt))
4558 {
4559 printf ("%s%s", first ? "" : " ", opts[cnt]);
4560 first = 0;
4561 }
4562 puts ("");
4563 }
4564 break;
103f02d3 4565
252b5132
RH
4566 case DT_MIPS_IVERSION:
4567 if (dynamic_strings != NULL)
4568 printf ("Interface Version: %s\n",
4569 dynamic_strings + entry->d_un.d_val);
4570 else
4571 printf ("%ld\n", (long) entry->d_un.d_ptr);
4572 break;
103f02d3 4573
252b5132
RH
4574 case DT_MIPS_TIME_STAMP:
4575 {
4576 char timebuf[20];
b34976b6 4577 struct tm *tmp;
50da7a9c 4578
252b5132 4579 time_t time = entry->d_un.d_val;
50da7a9c
NC
4580 tmp = gmtime (&time);
4581 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
4582 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
4583 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
4584 printf ("Time Stamp: %s\n", timebuf);
4585 }
4586 break;
103f02d3 4587
252b5132
RH
4588 case DT_MIPS_RLD_VERSION:
4589 case DT_MIPS_LOCAL_GOTNO:
4590 case DT_MIPS_CONFLICTNO:
4591 case DT_MIPS_LIBLISTNO:
4592 case DT_MIPS_SYMTABNO:
4593 case DT_MIPS_UNREFEXTNO:
4594 case DT_MIPS_HIPAGENO:
4595 case DT_MIPS_DELTA_CLASS_NO:
4596 case DT_MIPS_DELTA_INSTANCE_NO:
4597 case DT_MIPS_DELTA_RELOC_NO:
4598 case DT_MIPS_DELTA_SYM_NO:
4599 case DT_MIPS_DELTA_CLASSSYM_NO:
4600 case DT_MIPS_COMPACT_SIZE:
4601 printf ("%ld\n", (long) entry->d_un.d_ptr);
4602 break;
103f02d3
UD
4603
4604 default:
4605 printf ("%#lx\n", (long) entry->d_un.d_ptr);
4606 }
4607}
4608
4609
4610static void
4611dynamic_segment_parisc_val (entry)
b34976b6 4612 Elf_Internal_Dyn *entry;
103f02d3
UD
4613{
4614 switch (entry->d_tag)
4615 {
4616 case DT_HP_DLD_FLAGS:
4617 {
4618 static struct
4619 {
4620 long int bit;
b34976b6 4621 const char *str;
5e220199
NC
4622 }
4623 flags[] =
4624 {
4625 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
4626 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
4627 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
4628 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
4629 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
4630 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
4631 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
4632 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
4633 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
4634 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
4635 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" }
4636 };
103f02d3 4637 int first = 1;
5e220199 4638 size_t cnt;
f7a99963 4639 bfd_vma val = entry->d_un.d_val;
103f02d3
UD
4640
4641 for (cnt = 0; cnt < sizeof (flags) / sizeof (flags[0]); ++cnt)
4642 if (val & flags[cnt].bit)
30800947
NC
4643 {
4644 if (! first)
4645 putchar (' ');
4646 fputs (flags[cnt].str, stdout);
4647 first = 0;
4648 val ^= flags[cnt].bit;
4649 }
76da6bbe 4650
103f02d3 4651 if (val != 0 || first)
f7a99963
NC
4652 {
4653 if (! first)
4654 putchar (' ');
4655 print_vma (val, HEX);
4656 }
103f02d3
UD
4657 }
4658 break;
76da6bbe 4659
252b5132 4660 default:
f7a99963
NC
4661 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
4662 break;
252b5132 4663 }
35b1837e 4664 putchar ('\n');
252b5132
RH
4665}
4666
ecc51f48
NC
4667static void
4668dynamic_segment_ia64_val (entry)
4669 Elf_Internal_Dyn *entry;
4670{
4671 switch (entry->d_tag)
4672 {
4673 case DT_IA_64_PLT_RESERVE:
bdf4d63a 4674 /* First 3 slots reserved. */
ecc51f48
NC
4675 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
4676 printf (" -- ");
4677 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
4678 break;
4679
4680 default:
4681 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
4682 break;
ecc51f48 4683 }
bdf4d63a 4684 putchar ('\n');
ecc51f48
NC
4685}
4686
252b5132 4687static int
9ea033b2 4688get_32bit_dynamic_segment (file)
b34976b6 4689 FILE *file;
252b5132 4690{
b34976b6
AM
4691 Elf32_External_Dyn *edyn;
4692 Elf_Internal_Dyn *entry;
4693 bfd_size_type i;
103f02d3 4694
a6e9f9df
AM
4695 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr,
4696 dynamic_size, _("dynamic segment"));
4697 if (!edyn)
4698 return 0;
103f02d3 4699
9ea033b2
NC
4700 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
4701 how large this .dynamic is now. We can do this even before the byte
4702 swapping since the DT_NULL tag is recognizable. */
4703 dynamic_size = 0;
b34976b6 4704 while (*(Elf32_Word *) edyn[dynamic_size++].d_tag != DT_NULL)
9ea033b2 4705 ;
252b5132 4706
9ea033b2
NC
4707 dynamic_segment = (Elf_Internal_Dyn *)
4708 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
4709
4710 if (dynamic_segment == NULL)
252b5132 4711 {
9ea033b2
NC
4712 error (_("Out of memory\n"));
4713 free (edyn);
4714 return 0;
4715 }
252b5132 4716
9ea033b2
NC
4717 for (i = 0, entry = dynamic_segment;
4718 i < dynamic_size;
b34976b6 4719 i++, entry++)
9ea033b2 4720 {
b34976b6
AM
4721 entry->d_tag = BYTE_GET (edyn[i].d_tag);
4722 entry->d_un.d_val = BYTE_GET (edyn[i].d_un.d_val);
252b5132
RH
4723 }
4724
9ea033b2
NC
4725 free (edyn);
4726
4727 return 1;
4728}
4729
4730static int
4731get_64bit_dynamic_segment (file)
b34976b6 4732 FILE *file;
9ea033b2 4733{
b34976b6
AM
4734 Elf64_External_Dyn *edyn;
4735 Elf_Internal_Dyn *entry;
4736 bfd_size_type i;
103f02d3 4737
a6e9f9df
AM
4738 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr,
4739 dynamic_size, _("dynamic segment"));
4740 if (!edyn)
4741 return 0;
103f02d3 4742
252b5132 4743 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
9ea033b2 4744 how large this .dynamic is now. We can do this even before the byte
252b5132
RH
4745 swapping since the DT_NULL tag is recognizable. */
4746 dynamic_size = 0;
b34976b6 4747 while (*(bfd_vma *) edyn[dynamic_size++].d_tag != DT_NULL)
252b5132
RH
4748 ;
4749
4750 dynamic_segment = (Elf_Internal_Dyn *)
4751 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
4752
4753 if (dynamic_segment == NULL)
4754 {
4755 error (_("Out of memory\n"));
4756 free (edyn);
4757 return 0;
4758 }
4759
4760 for (i = 0, entry = dynamic_segment;
4761 i < dynamic_size;
b34976b6 4762 i++, entry++)
252b5132 4763 {
b34976b6
AM
4764 entry->d_tag = BYTE_GET8 (edyn[i].d_tag);
4765 entry->d_un.d_val = BYTE_GET8 (edyn[i].d_un.d_val);
252b5132
RH
4766 }
4767
4768 free (edyn);
4769
9ea033b2
NC
4770 return 1;
4771}
4772
d1133906
NC
4773static const char *
4774get_dynamic_flags (flags)
4775 bfd_vma flags;
4776{
b34976b6 4777 static char buff[128];
13ae64f3
JJ
4778 char *p = buff;
4779
4780 *p = '\0';
d1133906
NC
4781 while (flags)
4782 {
4783 bfd_vma flag;
4784
4785 flag = flags & - flags;
4786 flags &= ~ flag;
4787
13ae64f3
JJ
4788 if (p != buff)
4789 *p++ = ' ';
4790
d1133906
NC
4791 switch (flag)
4792 {
b34976b6
AM
4793 case DF_ORIGIN: strcpy (p, "ORIGIN"); break;
4794 case DF_SYMBOLIC: strcpy (p, "SYMBOLIC"); break;
4795 case DF_TEXTREL: strcpy (p, "TEXTREL"); break;
4796 case DF_BIND_NOW: strcpy (p, "BIND_NOW"); break;
4797 case DF_STATIC_TLS: strcpy (p, "STATIC_TLS"); break;
4798 default: strcpy (p, "unknown"); break;
d1133906 4799 }
13ae64f3
JJ
4800
4801 p = strchr (p, '\0');
d1133906 4802 }
305c7206 4803 return buff;
d1133906
NC
4804}
4805
9ea033b2
NC
4806/* Parse and display the contents of the dynamic segment. */
4807static int
4808process_dynamic_segment (file)
b34976b6 4809 FILE *file;
9ea033b2 4810{
b34976b6
AM
4811 Elf_Internal_Dyn *entry;
4812 bfd_size_type i;
9ea033b2
NC
4813
4814 if (dynamic_size == 0)
4815 {
4816 if (do_dynamic)
4817 printf (_("\nThere is no dynamic segment in this file.\n"));
4818
4819 return 1;
4820 }
4821
4822 if (is_32bit_elf)
4823 {
4824 if (! get_32bit_dynamic_segment (file))
4825 return 0;
4826 }
4827 else if (! get_64bit_dynamic_segment (file))
4828 return 0;
4829
252b5132
RH
4830 /* Find the appropriate symbol table. */
4831 if (dynamic_symbols == NULL)
4832 {
4833 for (i = 0, entry = dynamic_segment;
4834 i < dynamic_size;
b34976b6 4835 ++i, ++entry)
252b5132 4836 {
c8286bd1 4837 Elf_Internal_Shdr section;
252b5132
RH
4838
4839 if (entry->d_tag != DT_SYMTAB)
4840 continue;
4841
4842 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
4843
4844 /* Since we do not know how big the symbol table is,
4845 we default to reading in the entire file (!) and
4846 processing that. This is overkill, I know, but it
e3c8793a 4847 should work. */
d93f0186 4848 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
4849
4850 if (fseek (file, 0, SEEK_END))
4851 error (_("Unable to seek to end of file!"));
4852
9ad5cbcf 4853 section.sh_size = ftell (file) - section.sh_offset;
9ea033b2 4854 if (is_32bit_elf)
9ad5cbcf 4855 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 4856 else
9ad5cbcf 4857 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 4858
9ad5cbcf 4859 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 4860 if (num_dynamic_syms < 1)
252b5132
RH
4861 {
4862 error (_("Unable to determine the number of symbols to load\n"));
4863 continue;
4864 }
4865
9ad5cbcf 4866 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
4867 }
4868 }
4869
4870 /* Similarly find a string table. */
4871 if (dynamic_strings == NULL)
4872 {
4873 for (i = 0, entry = dynamic_segment;
4874 i < dynamic_size;
b34976b6 4875 ++i, ++entry)
252b5132
RH
4876 {
4877 unsigned long offset;
b34976b6 4878 long str_tab_len;
252b5132
RH
4879
4880 if (entry->d_tag != DT_STRTAB)
4881 continue;
4882
4883 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
4884
4885 /* Since we do not know how big the string table is,
4886 we default to reading in the entire file (!) and
4887 processing that. This is overkill, I know, but it
e3c8793a 4888 should work. */
252b5132 4889
d93f0186 4890 offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
4891 if (fseek (file, 0, SEEK_END))
4892 error (_("Unable to seek to end of file\n"));
4893 str_tab_len = ftell (file) - offset;
4894
4895 if (str_tab_len < 1)
4896 {
4897 error
4898 (_("Unable to determine the length of the dynamic string table\n"));
4899 continue;
4900 }
4901
a6e9f9df
AM
4902 dynamic_strings = (char *) get_data (NULL, file, offset, str_tab_len,
4903 _("dynamic string table"));
252b5132
RH
4904 break;
4905 }
4906 }
4907
4908 /* And find the syminfo section if available. */
4909 if (dynamic_syminfo == NULL)
4910 {
3e8bba36 4911 unsigned long syminsz = 0;
252b5132
RH
4912
4913 for (i = 0, entry = dynamic_segment;
4914 i < dynamic_size;
b34976b6 4915 ++i, ++entry)
252b5132
RH
4916 {
4917 if (entry->d_tag == DT_SYMINENT)
4918 {
4919 /* Note: these braces are necessary to avoid a syntax
4920 error from the SunOS4 C compiler. */
4921 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
4922 }
4923 else if (entry->d_tag == DT_SYMINSZ)
4924 syminsz = entry->d_un.d_val;
4925 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
4926 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
4927 syminsz);
252b5132
RH
4928 }
4929
4930 if (dynamic_syminfo_offset != 0 && syminsz != 0)
4931 {
b34976b6
AM
4932 Elf_External_Syminfo *extsyminfo;
4933 Elf_Internal_Syminfo *syminfo;
252b5132
RH
4934
4935 /* There is a syminfo section. Read the data. */
a6e9f9df
AM
4936 extsyminfo = ((Elf_External_Syminfo *)
4937 get_data (NULL, file, dynamic_syminfo_offset,
4938 syminsz, _("symbol information")));
4939 if (!extsyminfo)
4940 return 0;
252b5132
RH
4941
4942 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
4943 if (dynamic_syminfo == NULL)
4944 {
4945 error (_("Out of memory\n"));
4946 return 0;
4947 }
4948
4949 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
4950 for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
4951 ++i, ++syminfo)
4952 {
4953 syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
4954 syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
4955 }
4956
4957 free (extsyminfo);
4958 }
4959 }
4960
4961 if (do_dynamic && dynamic_addr)
3e8bba36 4962 printf (_("\nDynamic segment at offset 0x%lx contains %ld entries:\n"),
789be9f7 4963 dynamic_addr, (long) dynamic_size);
252b5132
RH
4964 if (do_dynamic)
4965 printf (_(" Tag Type Name/Value\n"));
4966
4967 for (i = 0, entry = dynamic_segment;
4968 i < dynamic_size;
b34976b6 4969 i++, entry++)
252b5132
RH
4970 {
4971 if (do_dynamic)
f7a99963 4972 {
b34976b6 4973 const char *dtype;
e699b9ff 4974
f7a99963
NC
4975 putchar (' ');
4976 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
4977 dtype = get_dynamic_type (entry->d_tag);
4978 printf (" (%s)%*s", dtype,
4979 ((is_32bit_elf ? 27 : 19)
4980 - (int) strlen (dtype)),
f7a99963
NC
4981 " ");
4982 }
252b5132
RH
4983
4984 switch (entry->d_tag)
4985 {
d1133906
NC
4986 case DT_FLAGS:
4987 if (do_dynamic)
13ae64f3 4988 puts (get_dynamic_flags (entry->d_un.d_val));
d1133906 4989 break;
76da6bbe 4990
252b5132
RH
4991 case DT_AUXILIARY:
4992 case DT_FILTER:
019148e4
L
4993 case DT_CONFIG:
4994 case DT_DEPAUDIT:
4995 case DT_AUDIT:
252b5132
RH
4996 if (do_dynamic)
4997 {
019148e4 4998 switch (entry->d_tag)
b34976b6 4999 {
019148e4
L
5000 case DT_AUXILIARY:
5001 printf (_("Auxiliary library"));
5002 break;
5003
5004 case DT_FILTER:
5005 printf (_("Filter library"));
5006 break;
5007
b34976b6 5008 case DT_CONFIG:
019148e4
L
5009 printf (_("Configuration file"));
5010 break;
5011
5012 case DT_DEPAUDIT:
5013 printf (_("Dependency audit library"));
5014 break;
5015
5016 case DT_AUDIT:
5017 printf (_("Audit library"));
5018 break;
5019 }
252b5132
RH
5020
5021 if (dynamic_strings)
5022 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
5023 else
f7a99963
NC
5024 {
5025 printf (": ");
5026 print_vma (entry->d_un.d_val, PREFIX_HEX);
5027 putchar ('\n');
5028 }
252b5132
RH
5029 }
5030 break;
5031
dcefbbbd 5032 case DT_FEATURE:
252b5132
RH
5033 if (do_dynamic)
5034 {
5035 printf (_("Flags:"));
86f55779 5036
252b5132
RH
5037 if (entry->d_un.d_val == 0)
5038 printf (_(" None\n"));
5039 else
5040 {
5041 unsigned long int val = entry->d_un.d_val;
86f55779 5042
252b5132
RH
5043 if (val & DTF_1_PARINIT)
5044 {
5045 printf (" PARINIT");
5046 val ^= DTF_1_PARINIT;
5047 }
dcefbbbd
L
5048 if (val & DTF_1_CONFEXP)
5049 {
5050 printf (" CONFEXP");
5051 val ^= DTF_1_CONFEXP;
5052 }
252b5132
RH
5053 if (val != 0)
5054 printf (" %lx", val);
5055 puts ("");
5056 }
5057 }
5058 break;
5059
5060 case DT_POSFLAG_1:
5061 if (do_dynamic)
5062 {
5063 printf (_("Flags:"));
86f55779 5064
252b5132
RH
5065 if (entry->d_un.d_val == 0)
5066 printf (_(" None\n"));
5067 else
5068 {
5069 unsigned long int val = entry->d_un.d_val;
86f55779 5070
252b5132
RH
5071 if (val & DF_P1_LAZYLOAD)
5072 {
5073 printf (" LAZYLOAD");
5074 val ^= DF_P1_LAZYLOAD;
5075 }
5076 if (val & DF_P1_GROUPPERM)
5077 {
5078 printf (" GROUPPERM");
5079 val ^= DF_P1_GROUPPERM;
5080 }
5081 if (val != 0)
5082 printf (" %lx", val);
5083 puts ("");
5084 }
5085 }
5086 break;
5087
5088 case DT_FLAGS_1:
5089 if (do_dynamic)
5090 {
5091 printf (_("Flags:"));
5092 if (entry->d_un.d_val == 0)
5093 printf (_(" None\n"));
5094 else
5095 {
5096 unsigned long int val = entry->d_un.d_val;
86f55779 5097
252b5132
RH
5098 if (val & DF_1_NOW)
5099 {
5100 printf (" NOW");
5101 val ^= DF_1_NOW;
5102 }
5103 if (val & DF_1_GLOBAL)
5104 {
5105 printf (" GLOBAL");
5106 val ^= DF_1_GLOBAL;
5107 }
5108 if (val & DF_1_GROUP)
5109 {
5110 printf (" GROUP");
5111 val ^= DF_1_GROUP;
5112 }
5113 if (val & DF_1_NODELETE)
5114 {
5115 printf (" NODELETE");
5116 val ^= DF_1_NODELETE;
5117 }
5118 if (val & DF_1_LOADFLTR)
5119 {
5120 printf (" LOADFLTR");
5121 val ^= DF_1_LOADFLTR;
5122 }
5123 if (val & DF_1_INITFIRST)
5124 {
5125 printf (" INITFIRST");
5126 val ^= DF_1_INITFIRST;
5127 }
5128 if (val & DF_1_NOOPEN)
5129 {
5130 printf (" NOOPEN");
5131 val ^= DF_1_NOOPEN;
5132 }
5133 if (val & DF_1_ORIGIN)
5134 {
5135 printf (" ORIGIN");
5136 val ^= DF_1_ORIGIN;
5137 }
5138 if (val & DF_1_DIRECT)
5139 {
5140 printf (" DIRECT");
5141 val ^= DF_1_DIRECT;
5142 }
5143 if (val & DF_1_TRANS)
5144 {
5145 printf (" TRANS");
5146 val ^= DF_1_TRANS;
5147 }
5148 if (val & DF_1_INTERPOSE)
5149 {
5150 printf (" INTERPOSE");
5151 val ^= DF_1_INTERPOSE;
5152 }
f7db6139 5153 if (val & DF_1_NODEFLIB)
dcefbbbd 5154 {
f7db6139
L
5155 printf (" NODEFLIB");
5156 val ^= DF_1_NODEFLIB;
dcefbbbd
L
5157 }
5158 if (val & DF_1_NODUMP)
5159 {
5160 printf (" NODUMP");
5161 val ^= DF_1_NODUMP;
5162 }
5163 if (val & DF_1_CONLFAT)
5164 {
5165 printf (" CONLFAT");
5166 val ^= DF_1_CONLFAT;
5167 }
252b5132
RH
5168 if (val != 0)
5169 printf (" %lx", val);
5170 puts ("");
5171 }
5172 }
5173 break;
5174
5175 case DT_PLTREL:
566b0d53 5176 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
5177 if (do_dynamic)
5178 puts (get_dynamic_type (entry->d_un.d_val));
5179 break;
5180
5181 case DT_NULL :
5182 case DT_NEEDED :
5183 case DT_PLTGOT :
5184 case DT_HASH :
5185 case DT_STRTAB :
5186 case DT_SYMTAB :
5187 case DT_RELA :
5188 case DT_INIT :
5189 case DT_FINI :
5190 case DT_SONAME :
5191 case DT_RPATH :
5192 case DT_SYMBOLIC:
5193 case DT_REL :
5194 case DT_DEBUG :
5195 case DT_TEXTREL :
5196 case DT_JMPREL :
019148e4 5197 case DT_RUNPATH :
252b5132
RH
5198 dynamic_info[entry->d_tag] = entry->d_un.d_val;
5199
5200 if (do_dynamic)
5201 {
b34976b6 5202 char *name;
252b5132
RH
5203
5204 if (dynamic_strings == NULL)
5205 name = NULL;
5206 else
5207 name = dynamic_strings + entry->d_un.d_val;
5208
5209 if (name)
5210 {
5211 switch (entry->d_tag)
5212 {
5213 case DT_NEEDED:
5214 printf (_("Shared library: [%s]"), name);
5215
f7a99963
NC
5216 if (strcmp (name, program_interpreter) == 0)
5217 printf (_(" program interpreter"));
252b5132
RH
5218 break;
5219
5220 case DT_SONAME:
f7a99963 5221 printf (_("Library soname: [%s]"), name);
252b5132
RH
5222 break;
5223
5224 case DT_RPATH:
f7a99963 5225 printf (_("Library rpath: [%s]"), name);
252b5132
RH
5226 break;
5227
019148e4
L
5228 case DT_RUNPATH:
5229 printf (_("Library runpath: [%s]"), name);
5230 break;
5231
252b5132 5232 default:
f7a99963
NC
5233 print_vma (entry->d_un.d_val, PREFIX_HEX);
5234 break;
252b5132
RH
5235 }
5236 }
5237 else
f7a99963
NC
5238 print_vma (entry->d_un.d_val, PREFIX_HEX);
5239
5240 putchar ('\n');
252b5132
RH
5241 }
5242 break;
5243
5244 case DT_PLTRELSZ:
5245 case DT_RELASZ :
5246 case DT_STRSZ :
5247 case DT_RELSZ :
5248 case DT_RELAENT :
5249 case DT_SYMENT :
5250 case DT_RELENT :
566b0d53 5251 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
5252 case DT_PLTPADSZ:
5253 case DT_MOVEENT :
5254 case DT_MOVESZ :
5255 case DT_INIT_ARRAYSZ:
5256 case DT_FINI_ARRAYSZ:
047b2264
JJ
5257 case DT_GNU_CONFLICTSZ:
5258 case DT_GNU_LIBLISTSZ:
252b5132 5259 if (do_dynamic)
f7a99963
NC
5260 {
5261 print_vma (entry->d_un.d_val, UNSIGNED);
5262 printf (" (bytes)\n");
5263 }
252b5132
RH
5264 break;
5265
5266 case DT_VERDEFNUM:
5267 case DT_VERNEEDNUM:
5268 case DT_RELACOUNT:
5269 case DT_RELCOUNT:
5270 if (do_dynamic)
f7a99963
NC
5271 {
5272 print_vma (entry->d_un.d_val, UNSIGNED);
5273 putchar ('\n');
5274 }
252b5132
RH
5275 break;
5276
5277 case DT_SYMINSZ:
5278 case DT_SYMINENT:
5279 case DT_SYMINFO:
5280 case DT_USED:
5281 case DT_INIT_ARRAY:
5282 case DT_FINI_ARRAY:
5283 if (do_dynamic)
5284 {
5285 if (dynamic_strings != NULL && entry->d_tag == DT_USED)
5286 {
b34976b6 5287 char *name;
252b5132
RH
5288
5289 name = dynamic_strings + entry->d_un.d_val;
5290
b34976b6 5291 if (*name)
252b5132
RH
5292 {
5293 printf (_("Not needed object: [%s]\n"), name);
5294 break;
5295 }
5296 }
103f02d3 5297
f7a99963
NC
5298 print_vma (entry->d_un.d_val, PREFIX_HEX);
5299 putchar ('\n');
252b5132
RH
5300 }
5301 break;
5302
5303 case DT_BIND_NOW:
5304 /* The value of this entry is ignored. */
35b1837e
AM
5305 if (do_dynamic)
5306 putchar ('\n');
252b5132 5307 break;
103f02d3 5308
047b2264
JJ
5309 case DT_GNU_PRELINKED:
5310 if (do_dynamic)
5311 {
b34976b6 5312 struct tm *tmp;
047b2264
JJ
5313 time_t time = entry->d_un.d_val;
5314
5315 tmp = gmtime (&time);
5316 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
5317 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
5318 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
5319
5320 }
5321 break;
5322
252b5132
RH
5323 default:
5324 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 5325 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
5326 entry->d_un.d_val;
5327
5328 if (do_dynamic)
5329 {
5330 switch (elf_header.e_machine)
5331 {
5332 case EM_MIPS:
4fe85591 5333 case EM_MIPS_RS3_LE:
252b5132
RH
5334 dynamic_segment_mips_val (entry);
5335 break;
103f02d3
UD
5336 case EM_PARISC:
5337 dynamic_segment_parisc_val (entry);
5338 break;
ecc51f48
NC
5339 case EM_IA_64:
5340 dynamic_segment_ia64_val (entry);
5341 break;
252b5132 5342 default:
f7a99963
NC
5343 print_vma (entry->d_un.d_val, PREFIX_HEX);
5344 putchar ('\n');
252b5132
RH
5345 }
5346 }
5347 break;
5348 }
5349 }
5350
5351 return 1;
5352}
5353
5354static char *
5355get_ver_flags (flags)
5356 unsigned int flags;
5357{
b34976b6 5358 static char buff[32];
252b5132
RH
5359
5360 buff[0] = 0;
5361
5362 if (flags == 0)
5363 return _("none");
5364
5365 if (flags & VER_FLG_BASE)
5366 strcat (buff, "BASE ");
5367
5368 if (flags & VER_FLG_WEAK)
5369 {
5370 if (flags & VER_FLG_BASE)
5371 strcat (buff, "| ");
5372
5373 strcat (buff, "WEAK ");
5374 }
5375
5376 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
5377 strcat (buff, "| <unknown>");
5378
5379 return buff;
5380}
5381
5382/* Display the contents of the version sections. */
5383static int
5384process_version_sections (file)
b34976b6 5385 FILE *file;
252b5132 5386{
b34976b6
AM
5387 Elf_Internal_Shdr *section;
5388 unsigned i;
5389 int found = 0;
252b5132
RH
5390
5391 if (! do_version)
5392 return 1;
5393
5394 for (i = 0, section = section_headers;
5395 i < elf_header.e_shnum;
b34976b6 5396 i++, section++)
252b5132
RH
5397 {
5398 switch (section->sh_type)
5399 {
5400 case SHT_GNU_verdef:
5401 {
b34976b6
AM
5402 Elf_External_Verdef *edefs;
5403 unsigned int idx;
5404 unsigned int cnt;
252b5132
RH
5405
5406 found = 1;
5407
5408 printf
5409 (_("\nVersion definition section '%s' contains %ld entries:\n"),
5410 SECTION_NAME (section), section->sh_info);
5411
5412 printf (_(" Addr: 0x"));
5413 printf_vma (section->sh_addr);
5414 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 5415 (unsigned long) section->sh_offset, section->sh_link,
9ad5cbcf 5416 SECTION_NAME (SECTION_HEADER (section->sh_link)));
252b5132 5417
a6e9f9df
AM
5418 edefs = ((Elf_External_Verdef *)
5419 get_data (NULL, file, section->sh_offset,
5420 section->sh_size,
5421 _("version definition section")));
5422 if (!edefs)
5423 break;
252b5132 5424
b34976b6 5425 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 5426 {
b34976b6
AM
5427 char *vstart;
5428 Elf_External_Verdef *edef;
5429 Elf_Internal_Verdef ent;
5430 Elf_External_Verdaux *eaux;
5431 Elf_Internal_Verdaux aux;
5432 int j;
5433 int isum;
103f02d3 5434
252b5132
RH
5435 vstart = ((char *) edefs) + idx;
5436
5437 edef = (Elf_External_Verdef *) vstart;
5438
5439 ent.vd_version = BYTE_GET (edef->vd_version);
5440 ent.vd_flags = BYTE_GET (edef->vd_flags);
5441 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
5442 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
5443 ent.vd_hash = BYTE_GET (edef->vd_hash);
5444 ent.vd_aux = BYTE_GET (edef->vd_aux);
5445 ent.vd_next = BYTE_GET (edef->vd_next);
5446
5447 printf (_(" %#06x: Rev: %d Flags: %s"),
5448 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
5449
5450 printf (_(" Index: %d Cnt: %d "),
5451 ent.vd_ndx, ent.vd_cnt);
5452
5453 vstart += ent.vd_aux;
5454
5455 eaux = (Elf_External_Verdaux *) vstart;
5456
5457 aux.vda_name = BYTE_GET (eaux->vda_name);
5458 aux.vda_next = BYTE_GET (eaux->vda_next);
5459
5460 if (dynamic_strings)
5461 printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
5462 else
5463 printf (_("Name index: %ld\n"), aux.vda_name);
5464
5465 isum = idx + ent.vd_aux;
5466
b34976b6 5467 for (j = 1; j < ent.vd_cnt; j++)
252b5132
RH
5468 {
5469 isum += aux.vda_next;
5470 vstart += aux.vda_next;
5471
5472 eaux = (Elf_External_Verdaux *) vstart;
5473
5474 aux.vda_name = BYTE_GET (eaux->vda_name);
5475 aux.vda_next = BYTE_GET (eaux->vda_next);
5476
5477 if (dynamic_strings)
5478 printf (_(" %#06x: Parent %d: %s\n"),
5479 isum, j, dynamic_strings + aux.vda_name);
5480 else
5481 printf (_(" %#06x: Parent %d, name index: %ld\n"),
5482 isum, j, aux.vda_name);
5483 }
5484
5485 idx += ent.vd_next;
5486 }
5487
5488 free (edefs);
5489 }
5490 break;
103f02d3 5491
252b5132
RH
5492 case SHT_GNU_verneed:
5493 {
b34976b6
AM
5494 Elf_External_Verneed *eneed;
5495 unsigned int idx;
5496 unsigned int cnt;
252b5132
RH
5497
5498 found = 1;
5499
5500 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
5501 SECTION_NAME (section), section->sh_info);
5502
5503 printf (_(" Addr: 0x"));
5504 printf_vma (section->sh_addr);
5505 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
1b228002 5506 (unsigned long) section->sh_offset, section->sh_link,
9ad5cbcf 5507 SECTION_NAME (SECTION_HEADER (section->sh_link)));
252b5132 5508
a6e9f9df
AM
5509 eneed = ((Elf_External_Verneed *)
5510 get_data (NULL, file, section->sh_offset,
5511 section->sh_size, _("version need section")));
5512 if (!eneed)
5513 break;
252b5132
RH
5514
5515 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
5516 {
b34976b6
AM
5517 Elf_External_Verneed *entry;
5518 Elf_Internal_Verneed ent;
5519 int j;
5520 int isum;
5521 char *vstart;
252b5132
RH
5522
5523 vstart = ((char *) eneed) + idx;
5524
5525 entry = (Elf_External_Verneed *) vstart;
5526
5527 ent.vn_version = BYTE_GET (entry->vn_version);
5528 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
5529 ent.vn_file = BYTE_GET (entry->vn_file);
5530 ent.vn_aux = BYTE_GET (entry->vn_aux);
5531 ent.vn_next = BYTE_GET (entry->vn_next);
5532
5533 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
5534
5535 if (dynamic_strings)
5536 printf (_(" File: %s"), dynamic_strings + ent.vn_file);
5537 else
5538 printf (_(" File: %lx"), ent.vn_file);
5539
5540 printf (_(" Cnt: %d\n"), ent.vn_cnt);
5541
5542 vstart += ent.vn_aux;
5543
5544 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
5545 {
b34976b6
AM
5546 Elf_External_Vernaux *eaux;
5547 Elf_Internal_Vernaux aux;
252b5132
RH
5548
5549 eaux = (Elf_External_Vernaux *) vstart;
5550
5551 aux.vna_hash = BYTE_GET (eaux->vna_hash);
5552 aux.vna_flags = BYTE_GET (eaux->vna_flags);
5553 aux.vna_other = BYTE_GET (eaux->vna_other);
5554 aux.vna_name = BYTE_GET (eaux->vna_name);
5555 aux.vna_next = BYTE_GET (eaux->vna_next);
5556
5557 if (dynamic_strings)
5558 printf (_(" %#06x: Name: %s"),
5559 isum, dynamic_strings + aux.vna_name);
5560 else
5561 printf (_(" %#06x: Name index: %lx"),
5562 isum, aux.vna_name);
5563
5564 printf (_(" Flags: %s Version: %d\n"),
5565 get_ver_flags (aux.vna_flags), aux.vna_other);
5566
5567 isum += aux.vna_next;
5568 vstart += aux.vna_next;
5569 }
5570
5571 idx += ent.vn_next;
5572 }
103f02d3 5573
252b5132
RH
5574 free (eneed);
5575 }
5576 break;
5577
5578 case SHT_GNU_versym:
5579 {
b34976b6
AM
5580 Elf_Internal_Shdr *link_section;
5581 int total;
5582 int cnt;
5583 unsigned char *edata;
5584 unsigned short *data;
5585 char *strtab;
5586 Elf_Internal_Sym *symbols;
5587 Elf_Internal_Shdr *string_sec;
252b5132 5588
9ad5cbcf 5589 link_section = SECTION_HEADER (section->sh_link);
252b5132
RH
5590 total = section->sh_size / section->sh_entsize;
5591
5592 found = 1;
5593
9ad5cbcf 5594 symbols = GET_ELF_SYMBOLS (file, link_section);
252b5132 5595
9ad5cbcf 5596 string_sec = SECTION_HEADER (link_section->sh_link);
252b5132 5597
a6e9f9df
AM
5598 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
5599 string_sec->sh_size,
5600 _("version string table"));
5601 if (!strtab)
5602 break;
252b5132
RH
5603
5604 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
5605 SECTION_NAME (section), total);
5606
5607 printf (_(" Addr: "));
5608 printf_vma (section->sh_addr);
5609 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 5610 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
5611 SECTION_NAME (link_section));
5612
a6e9f9df
AM
5613 edata =
5614 ((unsigned char *)
5615 get_data (NULL, file,
d93f0186
NC
5616 offset_from_vma
5617 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
5618 total * sizeof (short)),
a6e9f9df
AM
5619 total * sizeof (short), _("version symbol data")));
5620 if (!edata)
5621 {
5622 free (strtab);
5623 break;
5624 }
252b5132
RH
5625
5626 data = (unsigned short *) malloc (total * sizeof (short));
5627
5628 for (cnt = total; cnt --;)
b34976b6
AM
5629 data[cnt] = byte_get (edata + cnt * sizeof (short),
5630 sizeof (short));
252b5132
RH
5631
5632 free (edata);
5633
5634 for (cnt = 0; cnt < total; cnt += 4)
5635 {
5636 int j, nn;
00d93f34 5637 int check_def, check_need;
b34976b6 5638 char *name;
252b5132
RH
5639
5640 printf (" %03x:", cnt);
5641
5642 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 5643 switch (data[cnt + j])
252b5132
RH
5644 {
5645 case 0:
5646 fputs (_(" 0 (*local*) "), stdout);
5647 break;
5648
5649 case 1:
5650 fputs (_(" 1 (*global*) "), stdout);
5651 break;
5652
5653 default:
b34976b6
AM
5654 nn = printf ("%4x%c", data[cnt + j] & 0x7fff,
5655 data[cnt + j] & 0x8000 ? 'h' : ' ');
252b5132 5656
00d93f34
JJ
5657 check_def = 1;
5658 check_need = 1;
b34976b6 5659 if (SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
00d93f34 5660 != SHT_NOBITS)
252b5132 5661 {
b34976b6 5662 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
5663 check_def = 0;
5664 else
5665 check_need = 0;
252b5132 5666 }
00d93f34
JJ
5667
5668 if (check_need
b34976b6 5669 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 5670 {
b34976b6
AM
5671 Elf_Internal_Verneed ivn;
5672 unsigned long offset;
252b5132 5673
d93f0186
NC
5674 offset = offset_from_vma
5675 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
5676 sizeof (Elf_External_Verneed));
252b5132 5677
b34976b6 5678 do
252b5132 5679 {
b34976b6
AM
5680 Elf_Internal_Vernaux ivna;
5681 Elf_External_Verneed evn;
5682 Elf_External_Vernaux evna;
5683 unsigned long a_off;
252b5132 5684
a6e9f9df
AM
5685 get_data (&evn, file, offset, sizeof (evn),
5686 _("version need"));
252b5132
RH
5687
5688 ivn.vn_aux = BYTE_GET (evn.vn_aux);
5689 ivn.vn_next = BYTE_GET (evn.vn_next);
5690
5691 a_off = offset + ivn.vn_aux;
5692
5693 do
5694 {
a6e9f9df
AM
5695 get_data (&evna, file, a_off, sizeof (evna),
5696 _("version need aux (2)"));
252b5132
RH
5697
5698 ivna.vna_next = BYTE_GET (evna.vna_next);
5699 ivna.vna_other = BYTE_GET (evna.vna_other);
5700
5701 a_off += ivna.vna_next;
5702 }
b34976b6 5703 while (ivna.vna_other != data[cnt + j]
252b5132
RH
5704 && ivna.vna_next != 0);
5705
b34976b6 5706 if (ivna.vna_other == data[cnt + j])
252b5132
RH
5707 {
5708 ivna.vna_name = BYTE_GET (evna.vna_name);
5709
16062207 5710 name = strtab + ivna.vna_name;
252b5132 5711 nn += printf ("(%s%-*s",
16062207
ILT
5712 name,
5713 12 - (int) strlen (name),
252b5132 5714 ")");
00d93f34 5715 check_def = 0;
252b5132
RH
5716 break;
5717 }
5718
5719 offset += ivn.vn_next;
5720 }
5721 while (ivn.vn_next);
5722 }
00d93f34 5723
b34976b6
AM
5724 if (check_def && data[cnt + j] != 0x8001
5725 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 5726 {
b34976b6
AM
5727 Elf_Internal_Verdef ivd;
5728 Elf_External_Verdef evd;
5729 unsigned long offset;
252b5132 5730
d93f0186
NC
5731 offset = offset_from_vma
5732 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
5733 sizeof evd);
252b5132
RH
5734
5735 do
5736 {
a6e9f9df
AM
5737 get_data (&evd, file, offset, sizeof (evd),
5738 _("version def"));
252b5132
RH
5739
5740 ivd.vd_next = BYTE_GET (evd.vd_next);
5741 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
5742
5743 offset += ivd.vd_next;
5744 }
b34976b6 5745 while (ivd.vd_ndx != (data[cnt + j] & 0x7fff)
252b5132
RH
5746 && ivd.vd_next != 0);
5747
b34976b6 5748 if (ivd.vd_ndx == (data[cnt + j] & 0x7fff))
252b5132 5749 {
b34976b6
AM
5750 Elf_External_Verdaux evda;
5751 Elf_Internal_Verdaux ivda;
252b5132
RH
5752
5753 ivd.vd_aux = BYTE_GET (evd.vd_aux);
5754
a6e9f9df
AM
5755 get_data (&evda, file,
5756 offset - ivd.vd_next + ivd.vd_aux,
5757 sizeof (evda), _("version def aux"));
252b5132
RH
5758
5759 ivda.vda_name = BYTE_GET (evda.vda_name);
5760
16062207 5761 name = strtab + ivda.vda_name;
252b5132 5762 nn += printf ("(%s%-*s",
16062207
ILT
5763 name,
5764 12 - (int) strlen (name),
252b5132
RH
5765 ")");
5766 }
5767 }
5768
5769 if (nn < 18)
5770 printf ("%*c", 18 - nn, ' ');
5771 }
5772
5773 putchar ('\n');
5774 }
5775
5776 free (data);
5777 free (strtab);
5778 free (symbols);
5779 }
5780 break;
103f02d3 5781
252b5132
RH
5782 default:
5783 break;
5784 }
5785 }
5786
5787 if (! found)
5788 printf (_("\nNo version information found in this file.\n"));
5789
5790 return 1;
5791}
5792
d1133906 5793static const char *
252b5132
RH
5794get_symbol_binding (binding)
5795 unsigned int binding;
5796{
b34976b6 5797 static char buff[32];
252b5132
RH
5798
5799 switch (binding)
5800 {
b34976b6
AM
5801 case STB_LOCAL: return "LOCAL";
5802 case STB_GLOBAL: return "GLOBAL";
5803 case STB_WEAK: return "WEAK";
252b5132
RH
5804 default:
5805 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
5806 sprintf (buff, _("<processor specific>: %d"), binding);
5807 else if (binding >= STB_LOOS && binding <= STB_HIOS)
5808 sprintf (buff, _("<OS specific>: %d"), binding);
5809 else
5810 sprintf (buff, _("<unknown>: %d"), binding);
5811 return buff;
5812 }
5813}
5814
d1133906 5815static const char *
252b5132
RH
5816get_symbol_type (type)
5817 unsigned int type;
5818{
b34976b6 5819 static char buff[32];
252b5132
RH
5820
5821 switch (type)
5822 {
b34976b6
AM
5823 case STT_NOTYPE: return "NOTYPE";
5824 case STT_OBJECT: return "OBJECT";
5825 case STT_FUNC: return "FUNC";
5826 case STT_SECTION: return "SECTION";
5827 case STT_FILE: return "FILE";
5828 case STT_COMMON: return "COMMON";
5829 case STT_TLS: return "TLS";
252b5132
RH
5830 default:
5831 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
5832 {
5833 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
5834 return "THUMB_FUNC";
5835
351b4b40 5836 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
5837 return "REGISTER";
5838
5839 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
5840 return "PARISC_MILLI";
5841
df75f1af
NC
5842 sprintf (buff, _("<processor specific>: %d"), type);
5843 }
252b5132 5844 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
5845 {
5846 if (elf_header.e_machine == EM_PARISC)
5847 {
5848 if (type == STT_HP_OPAQUE)
5849 return "HP_OPAQUE";
5850 if (type == STT_HP_STUB)
5851 return "HP_STUB";
5852 }
5853
5854 sprintf (buff, _("<OS specific>: %d"), type);
5855 }
252b5132
RH
5856 else
5857 sprintf (buff, _("<unknown>: %d"), type);
5858 return buff;
5859 }
5860}
5861
d1133906
NC
5862static const char *
5863get_symbol_visibility (visibility)
5864 unsigned int visibility;
5865{
5866 switch (visibility)
5867 {
b34976b6
AM
5868 case STV_DEFAULT: return "DEFAULT";
5869 case STV_INTERNAL: return "INTERNAL";
5870 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
5871 case STV_PROTECTED: return "PROTECTED";
5872 default: abort ();
5873 }
5874}
5875
5876static const char *
252b5132
RH
5877get_symbol_index_type (type)
5878 unsigned int type;
5879{
b34976b6 5880 static char buff[32];
5cf1065c 5881
252b5132
RH
5882 switch (type)
5883 {
b34976b6
AM
5884 case SHN_UNDEF: return "UND";
5885 case SHN_ABS: return "ABS";
5886 case SHN_COMMON: return "COM";
252b5132
RH
5887 default:
5888 if (type >= SHN_LOPROC && type <= SHN_HIPROC)
5cf1065c 5889 sprintf (buff, "PRC[0x%04x]", type);
252b5132 5890 else if (type >= SHN_LOOS && type <= SHN_HIOS)
5cf1065c 5891 sprintf (buff, "OS [0x%04x]", type);
9ad5cbcf 5892 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
5cf1065c 5893 sprintf (buff, "RSV[0x%04x]", type);
252b5132 5894 else
232e7cb8 5895 sprintf (buff, "%3d", type);
5cf1065c 5896 break;
252b5132 5897 }
5cf1065c
NC
5898
5899 return buff;
252b5132
RH
5900}
5901
252b5132
RH
5902static int *
5903get_dynamic_data (file, number)
b34976b6 5904 FILE *file;
252b5132
RH
5905 unsigned int number;
5906{
b34976b6
AM
5907 unsigned char *e_data;
5908 int *i_data;
252b5132 5909
3c9f43b1 5910 e_data = (unsigned char *) malloc (number * 4);
252b5132
RH
5911
5912 if (e_data == NULL)
5913 {
5914 error (_("Out of memory\n"));
5915 return NULL;
5916 }
5917
5918 if (fread (e_data, 4, number, file) != number)
5919 {
5920 error (_("Unable to read in dynamic data\n"));
5921 return NULL;
5922 }
5923
b34976b6 5924 i_data = (int *) malloc (number * sizeof (*i_data));
252b5132
RH
5925
5926 if (i_data == NULL)
5927 {
5928 error (_("Out of memory\n"));
5929 free (e_data);
5930 return NULL;
5931 }
5932
5933 while (number--)
b34976b6 5934 i_data[number] = byte_get (e_data + number * 4, 4);
252b5132
RH
5935
5936 free (e_data);
5937
5938 return i_data;
5939}
5940
e3c8793a 5941/* Dump the symbol table. */
252b5132
RH
5942static int
5943process_symbol_table (file)
b34976b6 5944 FILE *file;
252b5132 5945{
b34976b6
AM
5946 Elf_Internal_Shdr *section;
5947 unsigned char nb[4];
5948 unsigned char nc[4];
5949 int nbuckets = 0;
5950 int nchains = 0;
5951 int *buckets = NULL;
5952 int *chains = NULL;
252b5132
RH
5953
5954 if (! do_syms && !do_histogram)
5955 return 1;
5956
5957 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
5958 || do_histogram))
5959 {
d93f0186
NC
5960 if (fseek (file, offset_from_vma (file, dynamic_info[DT_HASH],
5961 sizeof nb + sizeof nc),
5962 SEEK_SET))
252b5132
RH
5963 {
5964 error (_("Unable to seek to start of dynamic information"));
5965 return 0;
5966 }
5967
5968 if (fread (nb, sizeof (nb), 1, file) != 1)
5969 {
5970 error (_("Failed to read in number of buckets\n"));
5971 return 0;
5972 }
5973
5974 if (fread (nc, sizeof (nc), 1, file) != 1)
5975 {
5976 error (_("Failed to read in number of chains\n"));
5977 return 0;
5978 }
5979
5980 nbuckets = byte_get (nb, 4);
5981 nchains = byte_get (nc, 4);
5982
5983 buckets = get_dynamic_data (file, nbuckets);
5984 chains = get_dynamic_data (file, nchains);
5985
5986 if (buckets == NULL || chains == NULL)
5987 return 0;
5988 }
5989
5990 if (do_syms
5991 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
5992 {
b34976b6
AM
5993 int hn;
5994 int si;
252b5132
RH
5995
5996 printf (_("\nSymbol table for image:\n"));
f7a99963 5997 if (is_32bit_elf)
ca47b30c 5998 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 5999 else
ca47b30c 6000 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
252b5132
RH
6001
6002 for (hn = 0; hn < nbuckets; hn++)
6003 {
b34976b6 6004 if (! buckets[hn])
252b5132
RH
6005 continue;
6006
b34976b6 6007 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
252b5132 6008 {
b34976b6 6009 Elf_Internal_Sym *psym;
252b5132
RH
6010
6011 psym = dynamic_symbols + si;
6012
f7a99963
NC
6013 printf (" %3d %3d: ", si, hn);
6014 print_vma (psym->st_value, LONG_HEX);
6015 putchar (' ' );
d1133906 6016 print_vma (psym->st_size, DEC_5);
76da6bbe 6017
d1133906
NC
6018 printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
6019 printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
6020 printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126
NC
6021 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
6022 print_symbol (25, dynamic_strings + psym->st_name);
6023 putchar ('\n');
252b5132
RH
6024 }
6025 }
6026 }
6027 else if (do_syms && !do_using_dynamic)
6028 {
b34976b6 6029 unsigned int i;
252b5132
RH
6030
6031 for (i = 0, section = section_headers;
6032 i < elf_header.e_shnum;
6033 i++, section++)
6034 {
b34976b6
AM
6035 unsigned int si;
6036 char *strtab;
6037 Elf_Internal_Sym *symtab;
6038 Elf_Internal_Sym *psym;
252b5132
RH
6039
6040
6041 if ( section->sh_type != SHT_SYMTAB
6042 && section->sh_type != SHT_DYNSYM)
6043 continue;
6044
6045 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
6046 SECTION_NAME (section),
6047 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 6048 if (is_32bit_elf)
ca47b30c 6049 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 6050 else
ca47b30c 6051 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 6052
9ad5cbcf 6053 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
6054 if (symtab == NULL)
6055 continue;
6056
6057 if (section->sh_link == elf_header.e_shstrndx)
6058 strtab = string_table;
6059 else
6060 {
b34976b6 6061 Elf_Internal_Shdr *string_sec;
252b5132 6062
9ad5cbcf 6063 string_sec = SECTION_HEADER (section->sh_link);
252b5132 6064
a6e9f9df
AM
6065 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
6066 string_sec->sh_size,
6067 _("string table"));
252b5132
RH
6068 }
6069
6070 for (si = 0, psym = symtab;
6071 si < section->sh_size / section->sh_entsize;
b34976b6 6072 si++, psym++)
252b5132 6073 {
5e220199 6074 printf ("%6d: ", si);
f7a99963
NC
6075 print_vma (psym->st_value, LONG_HEX);
6076 putchar (' ');
6077 print_vma (psym->st_size, DEC_5);
d1133906
NC
6078 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
6079 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
6080 printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126
NC
6081 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
6082 print_symbol (25, strtab + psym->st_name);
252b5132
RH
6083
6084 if (section->sh_type == SHT_DYNSYM &&
b34976b6 6085 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 6086 {
b34976b6
AM
6087 unsigned char data[2];
6088 unsigned short vers_data;
6089 unsigned long offset;
6090 int is_nobits;
6091 int check_def;
252b5132 6092
d93f0186
NC
6093 offset = offset_from_vma
6094 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
6095 sizeof data + si * sizeof (vers_data));
252b5132 6096
a6e9f9df
AM
6097 get_data (&data, file, offset + si * sizeof (vers_data),
6098 sizeof (data), _("version data"));
252b5132
RH
6099
6100 vers_data = byte_get (data, 2);
6101
9ad5cbcf
AM
6102 is_nobits = (SECTION_HEADER (psym->st_shndx)->sh_type
6103 == SHT_NOBITS);
252b5132
RH
6104
6105 check_def = (psym->st_shndx != SHN_UNDEF);
6106
6107 if ((vers_data & 0x8000) || vers_data > 1)
6108 {
b34976b6 6109 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 6110 && (is_nobits || ! check_def))
252b5132 6111 {
b34976b6
AM
6112 Elf_External_Verneed evn;
6113 Elf_Internal_Verneed ivn;
6114 Elf_Internal_Vernaux ivna;
252b5132
RH
6115
6116 /* We must test both. */
d93f0186
NC
6117 offset = offset_from_vma
6118 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
6119 sizeof evn);
252b5132 6120
252b5132
RH
6121 do
6122 {
b34976b6 6123 unsigned long vna_off;
252b5132 6124
a6e9f9df
AM
6125 get_data (&evn, file, offset, sizeof (evn),
6126 _("version need"));
dd27201e
L
6127
6128 ivn.vn_aux = BYTE_GET (evn.vn_aux);
6129 ivn.vn_next = BYTE_GET (evn.vn_next);
6130
252b5132
RH
6131 vna_off = offset + ivn.vn_aux;
6132
6133 do
6134 {
b34976b6 6135 Elf_External_Vernaux evna;
252b5132 6136
a6e9f9df
AM
6137 get_data (&evna, file, vna_off,
6138 sizeof (evna),
6139 _("version need aux (3)"));
252b5132
RH
6140
6141 ivna.vna_other = BYTE_GET (evna.vna_other);
6142 ivna.vna_next = BYTE_GET (evna.vna_next);
6143 ivna.vna_name = BYTE_GET (evna.vna_name);
6144
6145 vna_off += ivna.vna_next;
6146 }
6147 while (ivna.vna_other != vers_data
6148 && ivna.vna_next != 0);
6149
6150 if (ivna.vna_other == vers_data)
6151 break;
6152
6153 offset += ivn.vn_next;
6154 }
6155 while (ivn.vn_next != 0);
6156
6157 if (ivna.vna_other == vers_data)
6158 {
6159 printf ("@%s (%d)",
6160 strtab + ivna.vna_name, ivna.vna_other);
6161 check_def = 0;
6162 }
6163 else if (! is_nobits)
6164 error (_("bad dynamic symbol"));
6165 else
6166 check_def = 1;
6167 }
6168
6169 if (check_def)
6170 {
00d93f34 6171 if (vers_data != 0x8001
b34976b6 6172 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 6173 {
b34976b6
AM
6174 Elf_Internal_Verdef ivd;
6175 Elf_Internal_Verdaux ivda;
6176 Elf_External_Verdaux evda;
6177 unsigned long offset;
252b5132 6178
d93f0186
NC
6179 offset = offset_from_vma
6180 (file,
6181 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
6182 sizeof (Elf_External_Verdef));
252b5132
RH
6183
6184 do
6185 {
b34976b6 6186 Elf_External_Verdef evd;
252b5132 6187
a6e9f9df
AM
6188 get_data (&evd, file, offset, sizeof (evd),
6189 _("version def"));
252b5132 6190
b34976b6
AM
6191 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
6192 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
6193 ivd.vd_next = BYTE_GET (evd.vd_next);
6194
6195 offset += ivd.vd_next;
6196 }
6197 while (ivd.vd_ndx != (vers_data & 0x7fff)
6198 && ivd.vd_next != 0);
6199
6200 offset -= ivd.vd_next;
6201 offset += ivd.vd_aux;
6202
a6e9f9df
AM
6203 get_data (&evda, file, offset, sizeof (evda),
6204 _("version def aux"));
252b5132
RH
6205
6206 ivda.vda_name = BYTE_GET (evda.vda_name);
6207
6208 if (psym->st_name != ivda.vda_name)
6209 printf ((vers_data & 0x8000)
6210 ? "@%s" : "@@%s",
6211 strtab + ivda.vda_name);
6212 }
6213 }
6214 }
6215 }
6216
6217 putchar ('\n');
6218 }
6219
6220 free (symtab);
6221 if (strtab != string_table)
6222 free (strtab);
6223 }
6224 }
6225 else if (do_syms)
6226 printf
6227 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
6228
6229 if (do_histogram && buckets != NULL)
6230 {
b34976b6
AM
6231 int *lengths;
6232 int *counts;
6233 int hn;
6234 int si;
6235 int maxlength = 0;
6236 int nzero_counts = 0;
6237 int nsyms = 0;
252b5132
RH
6238
6239 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
6240 nbuckets);
6241 printf (_(" Length Number %% of total Coverage\n"));
6242
6243 lengths = (int *) calloc (nbuckets, sizeof (int));
6244 if (lengths == NULL)
6245 {
6246 error (_("Out of memory"));
6247 return 0;
6248 }
6249 for (hn = 0; hn < nbuckets; ++hn)
6250 {
b34976b6 6251 if (! buckets[hn])
252b5132
RH
6252 continue;
6253
f7a99963 6254 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 6255 {
b34976b6 6256 ++nsyms;
252b5132 6257 if (maxlength < ++lengths[hn])
b34976b6 6258 ++maxlength;
252b5132
RH
6259 }
6260 }
6261
6262 counts = (int *) calloc (maxlength + 1, sizeof (int));
6263 if (counts == NULL)
6264 {
6265 error (_("Out of memory"));
6266 return 0;
6267 }
6268
6269 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 6270 ++counts[lengths[hn]];
252b5132 6271
103f02d3 6272 if (nbuckets > 0)
252b5132 6273 {
103f02d3
UD
6274 printf (" 0 %-10d (%5.1f%%)\n",
6275 counts[0], (counts[0] * 100.0) / nbuckets);
6276 for (si = 1; si <= maxlength; ++si)
6277 {
6278 nzero_counts += counts[si] * si;
6279 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
6280 si, counts[si], (counts[si] * 100.0) / nbuckets,
6281 (nzero_counts * 100.0) / nsyms);
6282 }
252b5132
RH
6283 }
6284
6285 free (counts);
6286 free (lengths);
6287 }
6288
6289 if (buckets != NULL)
6290 {
6291 free (buckets);
6292 free (chains);
6293 }
6294
6295 return 1;
6296}
6297
6298static int
6299process_syminfo (file)
b34976b6 6300 FILE *file ATTRIBUTE_UNUSED;
252b5132 6301{
b4c96d0d 6302 unsigned int i;
252b5132
RH
6303
6304 if (dynamic_syminfo == NULL
6305 || !do_dynamic)
6306 /* No syminfo, this is ok. */
6307 return 1;
6308
6309 /* There better should be a dynamic symbol section. */
6310 if (dynamic_symbols == NULL || dynamic_strings == NULL)
6311 return 0;
6312
6313 if (dynamic_addr)
6314 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
6315 dynamic_syminfo_offset, dynamic_syminfo_nent);
6316
6317 printf (_(" Num: Name BoundTo Flags\n"));
6318 for (i = 0; i < dynamic_syminfo_nent; ++i)
6319 {
6320 unsigned short int flags = dynamic_syminfo[i].si_flags;
6321
31104126
NC
6322 printf ("%4d: ", i);
6323 print_symbol (30, dynamic_strings + dynamic_symbols[i].st_name);
6324 putchar (' ');
252b5132
RH
6325
6326 switch (dynamic_syminfo[i].si_boundto)
6327 {
6328 case SYMINFO_BT_SELF:
6329 fputs ("SELF ", stdout);
6330 break;
6331 case SYMINFO_BT_PARENT:
6332 fputs ("PARENT ", stdout);
6333 break;
6334 default:
6335 if (dynamic_syminfo[i].si_boundto > 0
6336 && dynamic_syminfo[i].si_boundto < dynamic_size)
31104126 6337 {
b34976b6
AM
6338 print_symbol (10,
6339 dynamic_strings
6340 + (dynamic_segment
6341 [dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
6342 putchar (' ' );
6343 }
252b5132
RH
6344 else
6345 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
6346 break;
6347 }
6348
6349 if (flags & SYMINFO_FLG_DIRECT)
6350 printf (" DIRECT");
6351 if (flags & SYMINFO_FLG_PASSTHRU)
6352 printf (" PASSTHRU");
6353 if (flags & SYMINFO_FLG_COPY)
6354 printf (" COPY");
6355 if (flags & SYMINFO_FLG_LAZYLOAD)
6356 printf (" LAZYLOAD");
6357
6358 puts ("");
6359 }
6360
6361 return 1;
6362}
6363
6364#ifdef SUPPORT_DISASSEMBLY
6365static void
6366disassemble_section (section, file)
b34976b6
AM
6367 Elf_Internal_Shdr *section;
6368 FILE *file;
252b5132
RH
6369{
6370 printf (_("\nAssembly dump of section %s\n"),
6371 SECTION_NAME (section));
6372
6373 /* XXX -- to be done --- XXX */
6374
6375 return 1;
6376}
6377#endif
6378
6379static int
6380dump_section (section, file)
b34976b6
AM
6381 Elf_Internal_Shdr *section;
6382 FILE *file;
252b5132 6383{
b34976b6
AM
6384 bfd_size_type bytes;
6385 bfd_vma addr;
6386 unsigned char *data;
6387 unsigned char *start;
252b5132
RH
6388
6389 bytes = section->sh_size;
6390
6391 if (bytes == 0)
6392 {
6393 printf (_("\nSection '%s' has no data to dump.\n"),
6394 SECTION_NAME (section));
6395 return 0;
6396 }
6397 else
6398 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
6399
6400 addr = section->sh_addr;
6401
a6e9f9df
AM
6402 start = (unsigned char *) get_data (NULL, file, section->sh_offset, bytes,
6403 _("section data"));
6404 if (!start)
6405 return 0;
252b5132
RH
6406
6407 data = start;
6408
6409 while (bytes)
6410 {
6411 int j;
6412 int k;
6413 int lbytes;
6414
6415 lbytes = (bytes > 16 ? 16 : bytes);
6416
148d3c43 6417 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132 6418
b34976b6 6419 switch (elf_header.e_ident[EI_DATA])
252b5132 6420 {
9ea033b2 6421 default:
252b5132
RH
6422 case ELFDATA2LSB:
6423 for (j = 15; j >= 0; j --)
6424 {
6425 if (j < lbytes)
b34976b6 6426 printf ("%2.2x", data[j]);
252b5132
RH
6427 else
6428 printf (" ");
6429
6430 if (!(j & 0x3))
6431 printf (" ");
6432 }
6433 break;
6434
6435 case ELFDATA2MSB:
6436 for (j = 0; j < 16; j++)
6437 {
6438 if (j < lbytes)
b34976b6 6439 printf ("%2.2x", data[j]);
252b5132
RH
6440 else
6441 printf (" ");
6442
6443 if ((j & 3) == 3)
6444 printf (" ");
6445 }
6446 break;
6447 }
6448
6449 for (j = 0; j < lbytes; j++)
6450 {
b34976b6 6451 k = data[j];
252b5132
RH
6452 if (k >= ' ' && k < 0x80)
6453 printf ("%c", k);
6454 else
6455 printf (".");
6456 }
6457
6458 putchar ('\n');
6459
6460 data += lbytes;
6461 addr += lbytes;
6462 bytes -= lbytes;
6463 }
6464
6465 free (start);
6466
6467 return 1;
6468}
6469
6470
6471static unsigned long int
6472read_leb128 (data, length_return, sign)
b34976b6
AM
6473 unsigned char *data;
6474 int *length_return;
6475 int sign;
252b5132
RH
6476{
6477 unsigned long int result = 0;
b34976b6
AM
6478 unsigned int num_read = 0;
6479 int shift = 0;
6480 unsigned char byte;
252b5132
RH
6481
6482 do
6483 {
b34976b6
AM
6484 byte = *data++;
6485 num_read++;
252b5132
RH
6486
6487 result |= (byte & 0x7f) << shift;
6488
6489 shift += 7;
6490
6491 }
6492 while (byte & 0x80);
6493
6494 if (length_return != NULL)
b34976b6 6495 *length_return = num_read;
252b5132
RH
6496
6497 if (sign && (shift < 32) && (byte & 0x40))
6498 result |= -1 << shift;
6499
6500 return result;
6501}
6502
6503typedef struct State_Machine_Registers
6504{
b34976b6
AM
6505 unsigned long address;
6506 unsigned int file;
6507 unsigned int line;
6508 unsigned int column;
6509 int is_stmt;
6510 int basic_block;
6511 int end_sequence;
252b5132
RH
6512/* This variable hold the number of the last entry seen
6513 in the File Table. */
b34976b6 6514 unsigned int last_file_entry;
252b5132
RH
6515} SMR;
6516
6517static SMR state_machine_regs;
6518
6519static void
6520reset_state_machine (is_stmt)
6521 int is_stmt;
6522{
6523 state_machine_regs.address = 0;
6524 state_machine_regs.file = 1;
6525 state_machine_regs.line = 1;
6526 state_machine_regs.column = 0;
6527 state_machine_regs.is_stmt = is_stmt;
6528 state_machine_regs.basic_block = 0;
6529 state_machine_regs.end_sequence = 0;
6530 state_machine_regs.last_file_entry = 0;
6531}
6532
6533/* Handled an extend line op. Returns true if this is the end
6534 of sequence. */
6535static int
3590ea00 6536process_extended_line_op (data, is_stmt, pointer_size)
b34976b6 6537 unsigned char *data;
252b5132 6538 int is_stmt;
3590ea00 6539 int pointer_size;
252b5132 6540{
b34976b6
AM
6541 unsigned char op_code;
6542 int bytes_read;
6543 unsigned int len;
6544 unsigned char *name;
6545 unsigned long adr;
103f02d3 6546
252b5132
RH
6547 len = read_leb128 (data, & bytes_read, 0);
6548 data += bytes_read;
6549
6550 if (len == 0)
6551 {
e5fb9629 6552 warn (_("badly formed extended line op encountered!\n"));
252b5132
RH
6553 return bytes_read;
6554 }
6555
6556 len += bytes_read;
b34976b6 6557 op_code = *data++;
252b5132
RH
6558
6559 printf (_(" Extended opcode %d: "), op_code);
103f02d3 6560
252b5132
RH
6561 switch (op_code)
6562 {
6563 case DW_LNE_end_sequence:
6564 printf (_("End of Sequence\n\n"));
6565 reset_state_machine (is_stmt);
6566 break;
6567
6568 case DW_LNE_set_address:
3590ea00 6569 adr = byte_get (data, pointer_size);
252b5132
RH
6570 printf (_("set Address to 0x%lx\n"), adr);
6571 state_machine_regs.address = adr;
6572 break;
6573
6574 case DW_LNE_define_file:
6575 printf (_(" define new File Table entry\n"));
6576 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
103f02d3 6577
b34976b6 6578 printf (_(" %d\t"), ++state_machine_regs.last_file_entry);
252b5132 6579 name = data;
3c9f43b1 6580 data += strlen ((char *) data) + 1;
252b5132
RH
6581 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6582 data += bytes_read;
6583 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6584 data += bytes_read;
6585 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6586 printf (_("%s\n\n"), name);
6587 break;
6588
6589 default:
6590 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
6591 break;
6592 }
6593
6594 return len;
6595}
6596
3590ea00
NC
6597/* Size of pointers in the .debug_line section. This information is not
6598 really present in that section. It's obtained before dumping the debug
6599 sections by doing some pre-scan of the .debug_info section. */
6600static int debug_line_pointer_size = 4;
252b5132
RH
6601
6602static int
6603display_debug_lines (section, start, file)
b34976b6
AM
6604 Elf_Internal_Shdr *section;
6605 unsigned char * start;
6606 FILE *file ATTRIBUTE_UNUSED;
252b5132 6607{
ee42cf8c 6608 unsigned char *hdrptr;
b34976b6
AM
6609 DWARF2_Internal_LineInfo info;
6610 unsigned char *standard_opcodes;
6611 unsigned char *data = start;
6612 unsigned char *end = start + section->sh_size;
6613 unsigned char *end_of_sequence;
6614 int i;
ee42cf8c
NC
6615 int offset_size;
6616 int initial_length_size;
252b5132
RH
6617
6618 printf (_("\nDump of debug contents of section %s:\n\n"),
6619 SECTION_NAME (section));
6620
6621 while (data < end)
6622 {
ee42cf8c 6623 hdrptr = data;
252b5132
RH
6624
6625 /* Check the length of the block. */
ee42cf8c
NC
6626 info.li_length = byte_get (hdrptr, 4);
6627 hdrptr += 4;
428409d5
NC
6628
6629 if (info.li_length == 0xffffffff)
6630 {
ee42cf8c
NC
6631 /* This section is 64-bit DWARF 3. */
6632 info.li_length = byte_get (hdrptr, 8);
6633 hdrptr += 8;
6634 offset_size = 8;
6635 initial_length_size = 12;
6636 }
6637 else
6638 {
6639 offset_size = 4;
6640 initial_length_size = 4;
428409d5
NC
6641 }
6642
ee42cf8c 6643 if (info.li_length + initial_length_size > section->sh_size)
252b5132
RH
6644 {
6645 warn
6646 (_("The line info appears to be corrupt - the section is too small\n"));
6647 return 0;
6648 }
103f02d3 6649
252b5132 6650 /* Check its version number. */
ee42cf8c
NC
6651 info.li_version = byte_get (hdrptr, 2);
6652 hdrptr += 2;
6653 if (info.li_version != 2 && info.li_version != 3)
252b5132 6654 {
ee42cf8c 6655 warn (_("Only DWARF version 2 and 3 line info is currently supported.\n"));
252b5132
RH
6656 return 0;
6657 }
103f02d3 6658
ee42cf8c
NC
6659 info.li_prologue_length = byte_get (hdrptr, offset_size);
6660 hdrptr += offset_size;
6661 info.li_min_insn_length = byte_get (hdrptr, 1);
6662 hdrptr++;
6663 info.li_default_is_stmt = byte_get (hdrptr, 1);
6664 hdrptr++;
6665 info.li_line_base = byte_get (hdrptr, 1);
6666 hdrptr++;
6667 info.li_line_range = byte_get (hdrptr, 1);
6668 hdrptr++;
6669 info.li_opcode_base = byte_get (hdrptr, 1);
6670 hdrptr++;
103f02d3 6671
252b5132
RH
6672 /* Sign extend the line base field. */
6673 info.li_line_base <<= 24;
6674 info.li_line_base >>= 24;
103f02d3 6675
252b5132
RH
6676 printf (_(" Length: %ld\n"), info.li_length);
6677 printf (_(" DWARF Version: %d\n"), info.li_version);
ff94ebf2 6678 printf (_(" Prologue Length: %d\n"), info.li_prologue_length);
252b5132
RH
6679 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
6680 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
6681 printf (_(" Line Base: %d\n"), info.li_line_base);
6682 printf (_(" Line Range: %d\n"), info.li_line_range);
6683 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
6684
ee42cf8c 6685 end_of_sequence = data + info.li_length + initial_length_size;
252b5132
RH
6686
6687 reset_state_machine (info.li_default_is_stmt);
103f02d3 6688
252b5132 6689 /* Display the contents of the Opcodes table. */
ee42cf8c 6690 standard_opcodes = hdrptr;
103f02d3 6691
252b5132 6692 printf (_("\n Opcodes:\n"));
103f02d3 6693
252b5132 6694 for (i = 1; i < info.li_opcode_base; i++)
7a4b7442 6695 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
103f02d3 6696
252b5132
RH
6697 /* Display the contents of the Directory table. */
6698 data = standard_opcodes + info.li_opcode_base - 1;
103f02d3 6699
b34976b6 6700 if (*data == 0)
252b5132
RH
6701 printf (_("\n The Directory Table is empty.\n"));
6702 else
6703 {
6704 printf (_("\n The Directory Table:\n"));
103f02d3 6705
b34976b6 6706 while (*data != 0)
252b5132
RH
6707 {
6708 printf (_(" %s\n"), data);
103f02d3 6709
3c9f43b1 6710 data += strlen ((char *) data) + 1;
252b5132
RH
6711 }
6712 }
103f02d3 6713
252b5132 6714 /* Skip the NUL at the end of the table. */
b34976b6 6715 data++;
103f02d3 6716
252b5132 6717 /* Display the contents of the File Name table. */
b34976b6 6718 if (*data == 0)
252b5132
RH
6719 printf (_("\n The File Name Table is empty.\n"));
6720 else
6721 {
6722 printf (_("\n The File Name Table:\n"));
6723 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
103f02d3 6724
b34976b6 6725 while (*data != 0)
252b5132 6726 {
b34976b6 6727 unsigned char *name;
252b5132 6728 int bytes_read;
103f02d3 6729
b34976b6 6730 printf (_(" %d\t"), ++state_machine_regs.last_file_entry);
252b5132 6731 name = data;
103f02d3 6732
3c9f43b1 6733 data += strlen ((char *) data) + 1;
103f02d3 6734
252b5132
RH
6735 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6736 data += bytes_read;
6737 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6738 data += bytes_read;
6739 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6740 data += bytes_read;
6741 printf (_("%s\n"), name);
6742 }
6743 }
103f02d3 6744
252b5132 6745 /* Skip the NUL at the end of the table. */
b34976b6 6746 data++;
103f02d3 6747
252b5132
RH
6748 /* Now display the statements. */
6749 printf (_("\n Line Number Statements:\n"));
103f02d3
UD
6750
6751
252b5132
RH
6752 while (data < end_of_sequence)
6753 {
6754 unsigned char op_code;
b34976b6
AM
6755 int adv;
6756 int bytes_read;
103f02d3 6757
b34976b6 6758 op_code = *data++;
103f02d3 6759
1a509dcc
GK
6760 if (op_code >= info.li_opcode_base)
6761 {
6762 op_code -= info.li_opcode_base;
6763 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
6764 state_machine_regs.address += adv;
6765 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
6766 op_code, adv, state_machine_regs.address);
6767 adv = (op_code % info.li_line_range) + info.li_line_base;
6768 state_machine_regs.line += adv;
6769 printf (_(" and Line by %d to %d\n"),
6770 adv, state_machine_regs.line);
53c7db4b
KH
6771 }
6772 else switch (op_code)
252b5132
RH
6773 {
6774 case DW_LNS_extended_op:
3590ea00 6775 data += process_extended_line_op (data, info.li_default_is_stmt,
53c7db4b 6776 debug_line_pointer_size);
252b5132 6777 break;
103f02d3 6778
252b5132
RH
6779 case DW_LNS_copy:
6780 printf (_(" Copy\n"));
6781 break;
103f02d3 6782
252b5132
RH
6783 case DW_LNS_advance_pc:
6784 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
6785 data += bytes_read;
6786 state_machine_regs.address += adv;
6787 printf (_(" Advance PC by %d to %lx\n"), adv,
6788 state_machine_regs.address);
6789 break;
103f02d3 6790
252b5132
RH
6791 case DW_LNS_advance_line:
6792 adv = read_leb128 (data, & bytes_read, 1);
6793 data += bytes_read;
6794 state_machine_regs.line += adv;
6795 printf (_(" Advance Line by %d to %d\n"), adv,
6796 state_machine_regs.line);
6797 break;
103f02d3 6798
252b5132
RH
6799 case DW_LNS_set_file:
6800 adv = read_leb128 (data, & bytes_read, 0);
6801 data += bytes_read;
6802 printf (_(" Set File Name to entry %d in the File Name Table\n"),
6803 adv);
6804 state_machine_regs.file = adv;
6805 break;
103f02d3 6806
252b5132
RH
6807 case DW_LNS_set_column:
6808 adv = read_leb128 (data, & bytes_read, 0);
6809 data += bytes_read;
6810 printf (_(" Set column to %d\n"), adv);
6811 state_machine_regs.column = adv;
6812 break;
103f02d3 6813
252b5132
RH
6814 case DW_LNS_negate_stmt:
6815 adv = state_machine_regs.is_stmt;
6816 adv = ! adv;
6817 printf (_(" Set is_stmt to %d\n"), adv);
6818 state_machine_regs.is_stmt = adv;
6819 break;
103f02d3 6820
252b5132
RH
6821 case DW_LNS_set_basic_block:
6822 printf (_(" Set basic block\n"));
6823 state_machine_regs.basic_block = 1;
6824 break;
103f02d3 6825
252b5132 6826 case DW_LNS_const_add_pc:
2366453a
NC
6827 adv = (((255 - info.li_opcode_base) / info.li_line_range)
6828 * info.li_min_insn_length);
252b5132
RH
6829 state_machine_regs.address += adv;
6830 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
6831 state_machine_regs.address);
6832 break;
103f02d3 6833
252b5132
RH
6834 case DW_LNS_fixed_advance_pc:
6835 adv = byte_get (data, 2);
6836 data += 2;
6837 state_machine_regs.address += adv;
6838 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
6839 adv, state_machine_regs.address);
6840 break;
103f02d3 6841
1a509dcc
GK
6842 case DW_LNS_set_prologue_end:
6843 printf (_(" Set prologue_end to true\n"));
6844 break;
53c7db4b 6845
1a509dcc
GK
6846 case DW_LNS_set_epilogue_begin:
6847 printf (_(" Set epilogue_begin to true\n"));
6848 break;
53c7db4b 6849
1a509dcc
GK
6850 case DW_LNS_set_isa:
6851 adv = read_leb128 (data, & bytes_read, 0);
6852 data += bytes_read;
6853 printf (_(" Set ISA to %d\n"), adv);
6854 break;
53c7db4b 6855
252b5132 6856 default:
1a509dcc
GK
6857 printf (_(" Unknown opcode %d with operands: "), op_code);
6858 {
6859 int i;
6860 for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
6861 {
6862 printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
6863 i == 1 ? "" : ", ");
6864 data += bytes_read;
6865 }
6866 putchar ('\n');
6867 }
252b5132
RH
6868 break;
6869 }
6870 }
1a509dcc 6871 putchar ('\n');
252b5132 6872 }
103f02d3 6873
252b5132
RH
6874 return 1;
6875}
6876
6877static int
6878display_debug_pubnames (section, start, file)
b34976b6
AM
6879 Elf_Internal_Shdr *section;
6880 unsigned char *start;
6881 FILE *file ATTRIBUTE_UNUSED;
252b5132 6882{
b34976b6
AM
6883 DWARF2_Internal_PubNames pubnames;
6884 unsigned char *end;
252b5132
RH
6885
6886 end = start + section->sh_size;
6887
6888 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
6889
6890 while (start < end)
6891 {
b34976b6
AM
6892 unsigned char *data;
6893 unsigned long offset;
ee42cf8c 6894 int offset_size, initial_length_size;
252b5132 6895
ee42cf8c 6896 data = start;
252b5132 6897
ee42cf8c
NC
6898 pubnames.pn_length = byte_get (data, 4);
6899 data += 4;
428409d5
NC
6900 if (pubnames.pn_length == 0xffffffff)
6901 {
ee42cf8c
NC
6902 pubnames.pn_length = byte_get (data, 8);
6903 data += 8;
6904 offset_size = 8;
6905 initial_length_size = 12;
6906 }
6907 else
6908 {
6909 offset_size = 4;
6910 initial_length_size = 4;
428409d5
NC
6911 }
6912
ee42cf8c
NC
6913 pubnames.pn_version = byte_get (data, 2);
6914 data += 2;
6915 pubnames.pn_offset = byte_get (data, offset_size);
6916 data += offset_size;
6917 pubnames.pn_size = byte_get (data, offset_size);
6918 data += offset_size;
6919
6920 start += pubnames.pn_length + initial_length_size;
6921
6922 if (pubnames.pn_version != 2 && pubnames.pn_version != 3)
252b5132 6923 {
3f215a10
NC
6924 static int warned = 0;
6925
6926 if (! warned)
6927 {
ee42cf8c 6928 warn (_("Only DWARF 2 and 3 pubnames are currently supported\n"));
3f215a10
NC
6929 warned = 1;
6930 }
76da6bbe 6931
252b5132
RH
6932 continue;
6933 }
6934
6935 printf (_(" Length: %ld\n"),
6936 pubnames.pn_length);
6937 printf (_(" Version: %d\n"),
6938 pubnames.pn_version);
6939 printf (_(" Offset into .debug_info section: %ld\n"),
6940 pubnames.pn_offset);
6941 printf (_(" Size of area in .debug_info section: %ld\n"),
6942 pubnames.pn_size);
6943
6944 printf (_("\n Offset\tName\n"));
6945
6946 do
6947 {
ee42cf8c 6948 offset = byte_get (data, offset_size);
252b5132
RH
6949
6950 if (offset != 0)
6951 {
ee42cf8c 6952 data += offset_size;
252b5132 6953 printf (" %ld\t\t%s\n", offset, data);
3c9f43b1 6954 data += strlen ((char *) data) + 1;
252b5132
RH
6955 }
6956 }
6957 while (offset != 0);
6958 }
6959
6960 printf ("\n");
6961 return 1;
6962}
6963
6964static char *
6965get_TAG_name (tag)
6966 unsigned long tag;
6967{
6968 switch (tag)
6969 {
b34976b6
AM
6970 case DW_TAG_padding: return "DW_TAG_padding";
6971 case DW_TAG_array_type: return "DW_TAG_array_type";
6972 case DW_TAG_class_type: return "DW_TAG_class_type";
6973 case DW_TAG_entry_point: return "DW_TAG_entry_point";
6974 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
6975 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
6976 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
6977 case DW_TAG_label: return "DW_TAG_label";
6978 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
6979 case DW_TAG_member: return "DW_TAG_member";
6980 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
6981 case DW_TAG_reference_type: return "DW_TAG_reference_type";
6982 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
6983 case DW_TAG_string_type: return "DW_TAG_string_type";
6984 case DW_TAG_structure_type: return "DW_TAG_structure_type";
6985 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
6986 case DW_TAG_typedef: return "DW_TAG_typedef";
6987 case DW_TAG_union_type: return "DW_TAG_union_type";
252b5132 6988 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
b34976b6
AM
6989 case DW_TAG_variant: return "DW_TAG_variant";
6990 case DW_TAG_common_block: return "DW_TAG_common_block";
6991 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
6992 case DW_TAG_inheritance: return "DW_TAG_inheritance";
6993 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
6994 case DW_TAG_module: return "DW_TAG_module";
6995 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
6996 case DW_TAG_set_type: return "DW_TAG_set_type";
6997 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
6998 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
6999 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
7000 case DW_TAG_base_type: return "DW_TAG_base_type";
7001 case DW_TAG_catch_block: return "DW_TAG_catch_block";
7002 case DW_TAG_const_type: return "DW_TAG_const_type";
7003 case DW_TAG_constant: return "DW_TAG_constant";
7004 case DW_TAG_enumerator: return "DW_TAG_enumerator";
7005 case DW_TAG_file_type: return "DW_TAG_file_type";
7006 case DW_TAG_friend: return "DW_TAG_friend";
7007 case DW_TAG_namelist: return "DW_TAG_namelist";
7008 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
7009 case DW_TAG_packed_type: return "DW_TAG_packed_type";
7010 case DW_TAG_subprogram: return "DW_TAG_subprogram";
7011 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
7012 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
7013 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
7014 case DW_TAG_try_block: return "DW_TAG_try_block";
7015 case DW_TAG_variant_part: return "DW_TAG_variant_part";
7016 case DW_TAG_variable: return "DW_TAG_variable";
7017 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
7018 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
7019 case DW_TAG_format_label: return "DW_TAG_format_label";
7020 case DW_TAG_function_template: return "DW_TAG_function_template";
7021 case DW_TAG_class_template: return "DW_TAG_class_template";
b811889f 7022 /* DWARF 2.1 values. */
b34976b6
AM
7023 case DW_TAG_dwarf_procedure: return "DW_TAG_dwarf_procedure";
7024 case DW_TAG_restrict_type: return "DW_TAG_restrict_type";
7025 case DW_TAG_interface_type: return "DW_TAG_interface_type";
7026 case DW_TAG_namespace: return "DW_TAG_namespace";
7027 case DW_TAG_imported_module: return "DW_TAG_imported_module";
7028 case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type";
7029 case DW_TAG_partial_unit: return "DW_TAG_partial_unit";
7030 case DW_TAG_imported_unit: return "DW_TAG_imported_unit";
84ad6ede
NC
7031 /* UPC values. */
7032 case DW_TAG_upc_shared_type: return "DW_TAG_upc_shared_type";
7033 case DW_TAG_upc_strict_type: return "DW_TAG_upc_strict_type";
7034 case DW_TAG_upc_relaxed_type: return "DW_TAG_upc_relaxed_type";
252b5132
RH
7035 default:
7036 {
b34976b6 7037 static char buffer[100];
252b5132
RH
7038
7039 sprintf (buffer, _("Unknown TAG value: %lx"), tag);
7040 return buffer;
7041 }
7042 }
7043}
7044
7045static char *
7046get_AT_name (attribute)
7047 unsigned long attribute;
7048{
7049 switch (attribute)
7050 {
b34976b6
AM
7051 case DW_AT_sibling: return "DW_AT_sibling";
7052 case DW_AT_location: return "DW_AT_location";
7053 case DW_AT_name: return "DW_AT_name";
7054 case DW_AT_ordering: return "DW_AT_ordering";
7055 case DW_AT_subscr_data: return "DW_AT_subscr_data";
7056 case DW_AT_byte_size: return "DW_AT_byte_size";
7057 case DW_AT_bit_offset: return "DW_AT_bit_offset";
7058 case DW_AT_bit_size: return "DW_AT_bit_size";
7059 case DW_AT_element_list: return "DW_AT_element_list";
7060 case DW_AT_stmt_list: return "DW_AT_stmt_list";
7061 case DW_AT_low_pc: return "DW_AT_low_pc";
7062 case DW_AT_high_pc: return "DW_AT_high_pc";
7063 case DW_AT_language: return "DW_AT_language";
7064 case DW_AT_member: return "DW_AT_member";
7065 case DW_AT_discr: return "DW_AT_discr";
7066 case DW_AT_discr_value: return "DW_AT_discr_value";
7067 case DW_AT_visibility: return "DW_AT_visibility";
7068 case DW_AT_import: return "DW_AT_import";
7069 case DW_AT_string_length: return "DW_AT_string_length";
7070 case DW_AT_common_reference: return "DW_AT_common_reference";
7071 case DW_AT_comp_dir: return "DW_AT_comp_dir";
7072 case DW_AT_const_value: return "DW_AT_const_value";
7073 case DW_AT_containing_type: return "DW_AT_containing_type";
7074 case DW_AT_default_value: return "DW_AT_default_value";
7075 case DW_AT_inline: return "DW_AT_inline";
7076 case DW_AT_is_optional: return "DW_AT_is_optional";
7077 case DW_AT_lower_bound: return "DW_AT_lower_bound";
7078 case DW_AT_producer: return "DW_AT_producer";
7079 case DW_AT_prototyped: return "DW_AT_prototyped";
7080 case DW_AT_return_addr: return "DW_AT_return_addr";
7081 case DW_AT_start_scope: return "DW_AT_start_scope";
7082 case DW_AT_stride_size: return "DW_AT_stride_size";
7083 case DW_AT_upper_bound: return "DW_AT_upper_bound";
7084 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
7085 case DW_AT_accessibility: return "DW_AT_accessibility";
7086 case DW_AT_address_class: return "DW_AT_address_class";
7087 case DW_AT_artificial: return "DW_AT_artificial";
7088 case DW_AT_base_types: return "DW_AT_base_types";
7089 case DW_AT_calling_convention: return "DW_AT_calling_convention";
7090 case DW_AT_count: return "DW_AT_count";
7091 case DW_AT_data_member_location: return "DW_AT_data_member_location";
7092 case DW_AT_decl_column: return "DW_AT_decl_column";
7093 case DW_AT_decl_file: return "DW_AT_decl_file";
7094 case DW_AT_decl_line: return "DW_AT_decl_line";
7095 case DW_AT_declaration: return "DW_AT_declaration";
7096 case DW_AT_discr_list: return "DW_AT_discr_list";
7097 case DW_AT_encoding: return "DW_AT_encoding";
7098 case DW_AT_external: return "DW_AT_external";
7099 case DW_AT_frame_base: return "DW_AT_frame_base";
7100 case DW_AT_friend: return "DW_AT_friend";
7101 case DW_AT_identifier_case: return "DW_AT_identifier_case";
7102 case DW_AT_macro_info: return "DW_AT_macro_info";
7103 case DW_AT_namelist_items: return "DW_AT_namelist_items";
7104 case DW_AT_priority: return "DW_AT_priority";
7105 case DW_AT_segment: return "DW_AT_segment";
7106 case DW_AT_specification: return "DW_AT_specification";
7107 case DW_AT_static_link: return "DW_AT_static_link";
7108 case DW_AT_type: return "DW_AT_type";
7109 case DW_AT_use_location: return "DW_AT_use_location";
7110 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
7111 case DW_AT_virtuality: return "DW_AT_virtuality";
7112 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
12ab83a9 7113 /* DWARF 2.1 values. */
b34976b6
AM
7114 case DW_AT_allocated: return "DW_AT_allocated";
7115 case DW_AT_associated: return "DW_AT_associated";
7116 case DW_AT_data_location: return "DW_AT_data_location";
7117 case DW_AT_stride: return "DW_AT_stride";
7118 case DW_AT_entry_pc: return "DW_AT_entry_pc";
7119 case DW_AT_use_UTF8: return "DW_AT_use_UTF8";
7120 case DW_AT_extension: return "DW_AT_extension";
7121 case DW_AT_ranges: return "DW_AT_ranges";
7122 case DW_AT_trampoline: return "DW_AT_trampoline";
7123 case DW_AT_call_column: return "DW_AT_call_column";
7124 case DW_AT_call_file: return "DW_AT_call_file";
7125 case DW_AT_call_line: return "DW_AT_call_line";
12ab83a9 7126 /* SGI/MIPS extensions. */
b34976b6
AM
7127 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
7128 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
7129 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
7130 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
252b5132 7131 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
b34976b6
AM
7132 case DW_AT_MIPS_software_pipeline_depth:
7133 return "DW_AT_MIPS_software_pipeline_depth";
7134 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
7135 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
7136 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
7137 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
7138 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
12ab83a9 7139 /* GNU extensions. */
b34976b6
AM
7140 case DW_AT_sf_names: return "DW_AT_sf_names";
7141 case DW_AT_src_info: return "DW_AT_src_info";
7142 case DW_AT_mac_info: return "DW_AT_mac_info";
7143 case DW_AT_src_coords: return "DW_AT_src_coords";
7144 case DW_AT_body_begin: return "DW_AT_body_begin";
7145 case DW_AT_body_end: return "DW_AT_body_end";
7146 case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
84ad6ede
NC
7147 /* UPC extension. */
7148 case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled";
252b5132
RH
7149 default:
7150 {
b34976b6 7151 static char buffer[100];
252b5132
RH
7152
7153 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
7154 return buffer;
7155 }
7156 }
7157}
7158
7159static char *
7160get_FORM_name (form)
7161 unsigned long form;
7162{
7163 switch (form)
7164 {
b34976b6
AM
7165 case DW_FORM_addr: return "DW_FORM_addr";
7166 case DW_FORM_block2: return "DW_FORM_block2";
7167 case DW_FORM_block4: return "DW_FORM_block4";
7168 case DW_FORM_data2: return "DW_FORM_data2";
7169 case DW_FORM_data4: return "DW_FORM_data4";
7170 case DW_FORM_data8: return "DW_FORM_data8";
7171 case DW_FORM_string: return "DW_FORM_string";
7172 case DW_FORM_block: return "DW_FORM_block";
7173 case DW_FORM_block1: return "DW_FORM_block1";
7174 case DW_FORM_data1: return "DW_FORM_data1";
7175 case DW_FORM_flag: return "DW_FORM_flag";
7176 case DW_FORM_sdata: return "DW_FORM_sdata";
7177 case DW_FORM_strp: return "DW_FORM_strp";
7178 case DW_FORM_udata: return "DW_FORM_udata";
7179 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
7180 case DW_FORM_ref1: return "DW_FORM_ref1";
7181 case DW_FORM_ref2: return "DW_FORM_ref2";
7182 case DW_FORM_ref4: return "DW_FORM_ref4";
7183 case DW_FORM_ref8: return "DW_FORM_ref8";
7184 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
7185 case DW_FORM_indirect: return "DW_FORM_indirect";
252b5132
RH
7186 default:
7187 {
b34976b6 7188 static char buffer[100];
252b5132
RH
7189
7190 sprintf (buffer, _("Unknown FORM value: %lx"), form);
7191 return buffer;
7192 }
7193 }
7194}
7195
7196/* FIXME: There are better and more effiecint ways to handle
7197 these structures. For now though, I just want something that
7198 is simple to implement. */
7199typedef struct abbrev_attr
7200{
b34976b6
AM
7201 unsigned long attribute;
7202 unsigned long form;
7203 struct abbrev_attr *next;
252b5132
RH
7204}
7205abbrev_attr;
7206
7207typedef struct abbrev_entry
7208{
b34976b6
AM
7209 unsigned long entry;
7210 unsigned long tag;
7211 int children;
7212 struct abbrev_attr *first_attr;
7213 struct abbrev_attr *last_attr;
7214 struct abbrev_entry *next;
252b5132
RH
7215}
7216abbrev_entry;
7217
b34976b6
AM
7218static abbrev_entry *first_abbrev = NULL;
7219static abbrev_entry *last_abbrev = NULL;
252b5132
RH
7220
7221static void
b34976b6 7222free_abbrevs ()
252b5132 7223{
b34976b6 7224 abbrev_entry *abbrev;
252b5132
RH
7225
7226 for (abbrev = first_abbrev; abbrev;)
7227 {
b34976b6
AM
7228 abbrev_entry *next = abbrev->next;
7229 abbrev_attr *attr;
252b5132
RH
7230
7231 for (attr = abbrev->first_attr; attr;)
7232 {
b34976b6 7233 abbrev_attr *next = attr->next;
252b5132
RH
7234
7235 free (attr);
7236 attr = next;
7237 }
7238
7239 free (abbrev);
7240 abbrev = next;
7241 }
7242
7243 last_abbrev = first_abbrev = NULL;
7244}
7245
7246static void
7247add_abbrev (number, tag, children)
7248 unsigned long number;
7249 unsigned long tag;
b34976b6 7250 int children;
252b5132 7251{
b34976b6 7252 abbrev_entry *entry;
252b5132 7253
b34976b6 7254 entry = (abbrev_entry *) malloc (sizeof (*entry));
252b5132
RH
7255
7256 if (entry == NULL)
7257 /* ugg */
7258 return;
7259
7260 entry->entry = number;
7261 entry->tag = tag;
7262 entry->children = children;
7263 entry->first_attr = NULL;
7264 entry->last_attr = NULL;
7265 entry->next = NULL;
7266
7267 if (first_abbrev == NULL)
7268 first_abbrev = entry;
7269 else
7270 last_abbrev->next = entry;
7271
7272 last_abbrev = entry;
7273}
7274
7275static void
7276add_abbrev_attr (attribute, form)
7277 unsigned long attribute;
7278 unsigned long form;
7279{
b34976b6 7280 abbrev_attr *attr;
252b5132 7281
b34976b6 7282 attr = (abbrev_attr *) malloc (sizeof (*attr));
252b5132
RH
7283
7284 if (attr == NULL)
7285 /* ugg */
7286 return;
7287
7288 attr->attribute = attribute;
7289 attr->form = form;
7290 attr->next = NULL;
7291
7292 if (last_abbrev->first_attr == NULL)
7293 last_abbrev->first_attr = attr;
7294 else
7295 last_abbrev->last_attr->next = attr;
7296
7297 last_abbrev->last_attr = attr;
7298}
7299
7300/* Processes the (partial) contents of a .debug_abbrev section.
7301 Returns NULL if the end of the section was encountered.
7302 Returns the address after the last byte read if the end of
7303 an abbreviation set was found. */
7304
7305static unsigned char *
7306process_abbrev_section (start, end)
b34976b6
AM
7307 unsigned char *start;
7308 unsigned char *end;
252b5132
RH
7309{
7310 if (first_abbrev != NULL)
7311 return NULL;
7312
7313 while (start < end)
7314 {
b34976b6 7315 int bytes_read;
252b5132
RH
7316 unsigned long entry;
7317 unsigned long tag;
7318 unsigned long attribute;
b34976b6 7319 int children;
252b5132
RH
7320
7321 entry = read_leb128 (start, & bytes_read, 0);
7322 start += bytes_read;
7323
a3f779db
NC
7324 /* A single zero is supposed to end the section according
7325 to the standard. If there's more, then signal that to
7326 the caller. */
252b5132 7327 if (entry == 0)
a3f779db 7328 return start == end ? NULL : start;
252b5132
RH
7329
7330 tag = read_leb128 (start, & bytes_read, 0);
7331 start += bytes_read;
7332
b34976b6 7333 children = *start++;
252b5132
RH
7334
7335 add_abbrev (entry, tag, children);
7336
7337 do
7338 {
7339 unsigned long form;
7340
7341 attribute = read_leb128 (start, & bytes_read, 0);
7342 start += bytes_read;
7343
7344 form = read_leb128 (start, & bytes_read, 0);
7345 start += bytes_read;
7346
7347 if (attribute != 0)
7348 add_abbrev_attr (attribute, form);
7349 }
7350 while (attribute != 0);
7351 }
7352
7353 return NULL;
7354}
7355
7356
e0c60db2
NC
7357static int
7358display_debug_macinfo (section, start, file)
b34976b6
AM
7359 Elf_Internal_Shdr *section;
7360 unsigned char *start;
7361 FILE *file ATTRIBUTE_UNUSED;
e0c60db2 7362{
b34976b6
AM
7363 unsigned char *end = start + section->sh_size;
7364 unsigned char *curr = start;
e0c60db2
NC
7365 unsigned int bytes_read;
7366 enum dwarf_macinfo_record_type op;
7367
7368 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
7369
7370 while (curr < end)
7371 {
7372 unsigned int lineno;
b34976b6 7373 const char *string;
e0c60db2 7374
b34976b6
AM
7375 op = *curr;
7376 curr++;
e0c60db2
NC
7377
7378 switch (op)
7379 {
7380 case DW_MACINFO_start_file:
7381 {
7382 unsigned int filenum;
7383
7384 lineno = read_leb128 (curr, & bytes_read, 0);
7385 curr += bytes_read;
7386 filenum = read_leb128 (curr, & bytes_read, 0);
7387 curr += bytes_read;
7388
7389 printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"), lineno, filenum);
7390 }
7391 break;
7392
7393 case DW_MACINFO_end_file:
7394 printf (_(" DW_MACINFO_end_file\n"));
7395 break;
7396
7397 case DW_MACINFO_define:
7398 lineno = read_leb128 (curr, & bytes_read, 0);
7399 curr += bytes_read;
7400 string = curr;
7401 curr += strlen (string) + 1;
7402 printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"), lineno, string);
7403 break;
7404
7405 case DW_MACINFO_undef:
7406 lineno = read_leb128 (curr, & bytes_read, 0);
7407 curr += bytes_read;
7408 string = curr;
7409 curr += strlen (string) + 1;
7410 printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"), lineno, string);
7411 break;
7412
7413 case DW_MACINFO_vendor_ext:
7414 {
7415 unsigned int constant;
7416
7417 constant = read_leb128 (curr, & bytes_read, 0);
7418 curr += bytes_read;
7419 string = curr;
7420 curr += strlen (string) + 1;
7421 printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"), constant, string);
7422 }
7423 break;
7424 }
7425 }
7426
7427 return 1;
7428}
0823fbca 7429
e0c60db2 7430
252b5132
RH
7431static int
7432display_debug_abbrev (section, start, file)
b34976b6
AM
7433 Elf_Internal_Shdr *section;
7434 unsigned char *start;
7435 FILE *file ATTRIBUTE_UNUSED;
252b5132 7436{
b34976b6
AM
7437 abbrev_entry *entry;
7438 unsigned char *end = start + section->sh_size;
252b5132
RH
7439
7440 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
7441
7442 do
7443 {
7444 start = process_abbrev_section (start, end);
7445
ef5cdfc7
JJ
7446 if (first_abbrev == NULL)
7447 continue;
7448
252b5132
RH
7449 printf (_(" Number TAG\n"));
7450
7451 for (entry = first_abbrev; entry; entry = entry->next)
7452 {
b34976b6 7453 abbrev_attr *attr;
252b5132
RH
7454
7455 printf (_(" %ld %s [%s]\n"),
7456 entry->entry,
7457 get_TAG_name (entry->tag),
7458 entry->children ? _("has children") : _("no children"));
7459
7460 for (attr = entry->first_attr; attr; attr = attr->next)
7461 {
7462 printf (_(" %-18s %s\n"),
7463 get_AT_name (attr->attribute),
7464 get_FORM_name (attr->form));
7465 }
7466 }
ef5cdfc7
JJ
7467
7468 free_abbrevs ();
252b5132
RH
7469 }
7470 while (start);
7471
7472 printf ("\n");
7473
7474 return 1;
7475}
7476
7477
7478static unsigned char *
7479display_block (data, length)
b34976b6
AM
7480 unsigned char *data;
7481 unsigned long length;
252b5132
RH
7482{
7483 printf (_(" %lu byte block: "), length);
7484
7485 while (length --)
b34976b6 7486 printf ("%lx ", (unsigned long) byte_get (data++, 1));
252b5132
RH
7487
7488 return data;
7489}
7490
7491static void
eb6bd4d3 7492decode_location_expression (data, pointer_size, length)
252b5132 7493 unsigned char * data;
b34976b6
AM
7494 unsigned int pointer_size;
7495 unsigned long length;
252b5132 7496{
b34976b6
AM
7497 unsigned op;
7498 int bytes_read;
7499 unsigned long uvalue;
7500 unsigned char *end = data + length;
252b5132 7501
eb6bd4d3 7502 while (data < end)
252b5132 7503 {
b34976b6 7504 op = *data++;
252b5132 7505
eb6bd4d3
JM
7506 switch (op)
7507 {
7508 case DW_OP_addr:
7509 printf ("DW_OP_addr: %lx",
7510 (unsigned long) byte_get (data, pointer_size));
7511 data += pointer_size;
7512 break;
7513 case DW_OP_deref:
7514 printf ("DW_OP_deref");
7515 break;
7516 case DW_OP_const1u:
7517 printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
7518 break;
7519 case DW_OP_const1s:
7520 printf ("DW_OP_const1s: %ld", (long) byte_get (data++, 1));
7521 break;
7522 case DW_OP_const2u:
7523 printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
7524 data += 2;
7525 break;
7526 case DW_OP_const2s:
7527 printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
7528 data += 2;
7529 break;
7530 case DW_OP_const4u:
7531 printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
7532 data += 4;
7533 break;
7534 case DW_OP_const4s:
7535 printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
7536 data += 4;
7537 break;
7538 case DW_OP_const8u:
7539 printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
7540 (unsigned long) byte_get (data + 4, 4));
7541 data += 8;
7542 break;
7543 case DW_OP_const8s:
7544 printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
7545 (long) byte_get (data + 4, 4));
7546 data += 8;
7547 break;
7548 case DW_OP_constu:
7549 printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
7550 data += bytes_read;
7551 break;
7552 case DW_OP_consts:
7553 printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
7554 data += bytes_read;
7555 break;
7556 case DW_OP_dup:
7557 printf ("DW_OP_dup");
7558 break;
7559 case DW_OP_drop:
7560 printf ("DW_OP_drop");
7561 break;
7562 case DW_OP_over:
7563 printf ("DW_OP_over");
7564 break;
7565 case DW_OP_pick:
7566 printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
7567 break;
7568 case DW_OP_swap:
7569 printf ("DW_OP_swap");
7570 break;
7571 case DW_OP_rot:
7572 printf ("DW_OP_rot");
7573 break;
7574 case DW_OP_xderef:
7575 printf ("DW_OP_xderef");
7576 break;
7577 case DW_OP_abs:
7578 printf ("DW_OP_abs");
7579 break;
7580 case DW_OP_and:
7581 printf ("DW_OP_and");
7582 break;
7583 case DW_OP_div:
7584 printf ("DW_OP_div");
7585 break;
7586 case DW_OP_minus:
7587 printf ("DW_OP_minus");
7588 break;
7589 case DW_OP_mod:
7590 printf ("DW_OP_mod");
7591 break;
7592 case DW_OP_mul:
7593 printf ("DW_OP_mul");
7594 break;
7595 case DW_OP_neg:
7596 printf ("DW_OP_neg");
7597 break;
7598 case DW_OP_not:
7599 printf ("DW_OP_not");
7600 break;
7601 case DW_OP_or:
7602 printf ("DW_OP_or");
7603 break;
7604 case DW_OP_plus:
7605 printf ("DW_OP_plus");
7606 break;
7607 case DW_OP_plus_uconst:
7608 printf ("DW_OP_plus_uconst: %lu",
7609 read_leb128 (data, &bytes_read, 0));
7610 data += bytes_read;
7611 break;
7612 case DW_OP_shl:
7613 printf ("DW_OP_shl");
7614 break;
7615 case DW_OP_shr:
7616 printf ("DW_OP_shr");
7617 break;
7618 case DW_OP_shra:
7619 printf ("DW_OP_shra");
7620 break;
7621 case DW_OP_xor:
7622 printf ("DW_OP_xor");
7623 break;
7624 case DW_OP_bra:
7625 printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
7626 data += 2;
7627 break;
7628 case DW_OP_eq:
7629 printf ("DW_OP_eq");
7630 break;
7631 case DW_OP_ge:
7632 printf ("DW_OP_ge");
7633 break;
7634 case DW_OP_gt:
7635 printf ("DW_OP_gt");
7636 break;
7637 case DW_OP_le:
7638 printf ("DW_OP_le");
7639 break;
7640 case DW_OP_lt:
7641 printf ("DW_OP_lt");
7642 break;
7643 case DW_OP_ne:
7644 printf ("DW_OP_ne");
7645 break;
7646 case DW_OP_skip:
7647 printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
7648 data += 2;
7649 break;
7650
7651 case DW_OP_lit0:
7652 case DW_OP_lit1:
7653 case DW_OP_lit2:
7654 case DW_OP_lit3:
7655 case DW_OP_lit4:
7656 case DW_OP_lit5:
7657 case DW_OP_lit6:
7658 case DW_OP_lit7:
7659 case DW_OP_lit8:
7660 case DW_OP_lit9:
7661 case DW_OP_lit10:
7662 case DW_OP_lit11:
7663 case DW_OP_lit12:
7664 case DW_OP_lit13:
7665 case DW_OP_lit14:
7666 case DW_OP_lit15:
7667 case DW_OP_lit16:
7668 case DW_OP_lit17:
7669 case DW_OP_lit18:
7670 case DW_OP_lit19:
7671 case DW_OP_lit20:
7672 case DW_OP_lit21:
7673 case DW_OP_lit22:
7674 case DW_OP_lit23:
7675 case DW_OP_lit24:
7676 case DW_OP_lit25:
7677 case DW_OP_lit26:
7678 case DW_OP_lit27:
7679 case DW_OP_lit28:
7680 case DW_OP_lit29:
7681 case DW_OP_lit30:
7682 case DW_OP_lit31:
7683 printf ("DW_OP_lit%d", op - DW_OP_lit0);
7684 break;
7685
7686 case DW_OP_reg0:
7687 case DW_OP_reg1:
7688 case DW_OP_reg2:
7689 case DW_OP_reg3:
7690 case DW_OP_reg4:
7691 case DW_OP_reg5:
7692 case DW_OP_reg6:
7693 case DW_OP_reg7:
7694 case DW_OP_reg8:
7695 case DW_OP_reg9:
7696 case DW_OP_reg10:
7697 case DW_OP_reg11:
7698 case DW_OP_reg12:
7699 case DW_OP_reg13:
7700 case DW_OP_reg14:
7701 case DW_OP_reg15:
7702 case DW_OP_reg16:
7703 case DW_OP_reg17:
7704 case DW_OP_reg18:
7705 case DW_OP_reg19:
7706 case DW_OP_reg20:
7707 case DW_OP_reg21:
7708 case DW_OP_reg22:
7709 case DW_OP_reg23:
7710 case DW_OP_reg24:
7711 case DW_OP_reg25:
7712 case DW_OP_reg26:
7713 case DW_OP_reg27:
7714 case DW_OP_reg28:
7715 case DW_OP_reg29:
7716 case DW_OP_reg30:
7717 case DW_OP_reg31:
7718 printf ("DW_OP_reg%d", op - DW_OP_reg0);
7719 break;
7720
7721 case DW_OP_breg0:
7722 case DW_OP_breg1:
7723 case DW_OP_breg2:
7724 case DW_OP_breg3:
7725 case DW_OP_breg4:
7726 case DW_OP_breg5:
7727 case DW_OP_breg6:
7728 case DW_OP_breg7:
7729 case DW_OP_breg8:
7730 case DW_OP_breg9:
7731 case DW_OP_breg10:
7732 case DW_OP_breg11:
7733 case DW_OP_breg12:
7734 case DW_OP_breg13:
7735 case DW_OP_breg14:
7736 case DW_OP_breg15:
7737 case DW_OP_breg16:
7738 case DW_OP_breg17:
7739 case DW_OP_breg18:
7740 case DW_OP_breg19:
7741 case DW_OP_breg20:
7742 case DW_OP_breg21:
7743 case DW_OP_breg22:
7744 case DW_OP_breg23:
7745 case DW_OP_breg24:
7746 case DW_OP_breg25:
7747 case DW_OP_breg26:
7748 case DW_OP_breg27:
7749 case DW_OP_breg28:
7750 case DW_OP_breg29:
7751 case DW_OP_breg30:
7752 case DW_OP_breg31:
7753 printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
7754 read_leb128 (data, &bytes_read, 1));
7755 data += bytes_read;
7756 break;
7757
7758 case DW_OP_regx:
7759 printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
7760 data += bytes_read;
7761 break;
7762 case DW_OP_fbreg:
7763 printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
7764 data += bytes_read;
7765 break;
7766 case DW_OP_bregx:
7767 uvalue = read_leb128 (data, &bytes_read, 0);
7768 data += bytes_read;
7769 printf ("DW_OP_bregx: %lu %ld", uvalue,
7770 read_leb128 (data, &bytes_read, 1));
7771 data += bytes_read;
7772 break;
7773 case DW_OP_piece:
7774 printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
7775 data += bytes_read;
7776 break;
7777 case DW_OP_deref_size:
7778 printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
7779 break;
7780 case DW_OP_xderef_size:
7781 printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
7782 break;
7783 case DW_OP_nop:
7784 printf ("DW_OP_nop");
7785 break;
7786
065c959b 7787 /* DWARF 3 extensions. */
12ab83a9
NC
7788 case DW_OP_push_object_address:
7789 printf ("DW_OP_push_object_address");
7790 break;
7791 case DW_OP_call2:
7792 printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2));
7793 data += 2;
7794 break;
7795 case DW_OP_call4:
7796 printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4));
7797 data += 4;
7798 break;
065c959b
NC
7799 case DW_OP_call_ref:
7800 printf ("DW_OP_call_ref");
7801 break;
7802
7803 /* GNU extensions. */
7804 case DW_OP_GNU_push_tls_address:
7805 printf ("DW_OP_GNU_push_tls_address");
12ab83a9
NC
7806 break;
7807
eb6bd4d3
JM
7808 default:
7809 if (op >= DW_OP_lo_user
7810 && op <= DW_OP_hi_user)
7811 printf (_("(User defined location op)"));
7812 else
7813 printf (_("(Unknown location op)"));
7814 /* No way to tell where the next op is, so just bail. */
7815 return;
7816 }
12ab83a9
NC
7817
7818 /* Separate the ops. */
3f7de0e7
NC
7819 if (data < end)
7820 printf ("; ");
252b5132
RH
7821 }
7822}
7823
b34976b6
AM
7824static const char *debug_loc_contents;
7825static bfd_vma debug_loc_size;
a2f14207
DB
7826
7827static void
7828load_debug_loc (file)
b34976b6 7829 FILE *file;
a2f14207 7830{
b34976b6
AM
7831 Elf_Internal_Shdr *sec;
7832 unsigned int i;
a2f14207
DB
7833
7834 /* If it is already loaded, do nothing. */
7835 if (debug_loc_contents != NULL)
7836 return;
7837
7838 /* Locate the .debug_loc section. */
7839 for (i = 0, sec = section_headers;
7840 i < elf_header.e_shnum;
b34976b6 7841 i++, sec++)
a2f14207
DB
7842 if (strcmp (SECTION_NAME (sec), ".debug_loc") == 0)
7843 break;
7844
7845 if (i == elf_header.e_shnum || sec->sh_size == 0)
7846 return;
7847
7848 debug_loc_size = sec->sh_size;
7849
7850 debug_loc_contents = ((char *)
7851 get_data (NULL, file, sec->sh_offset, sec->sh_size,
7852 _("debug_loc section data")));
7853}
7854
7855static void
7856free_debug_loc ()
7857{
7858 if (debug_loc_contents == NULL)
7859 return;
7860
7861 free ((char *) debug_loc_contents);
7862 debug_loc_contents = NULL;
7863 debug_loc_size = 0;
7864}
7865
a2f14207 7866
a2f14207
DB
7867static int
7868display_debug_loc (section, start, file)
b34976b6
AM
7869 Elf_Internal_Shdr *section;
7870 unsigned char *start;
7871 FILE *file ATTRIBUTE_UNUSED;
a2f14207
DB
7872{
7873 unsigned char *section_end;
7874 unsigned long bytes;
7875 unsigned char *section_begin = start;
7876 bfd_vma addr;
53c7db4b 7877
a2f14207
DB
7878 addr = section->sh_addr;
7879 bytes = section->sh_size;
7880 section_end = start + bytes;
065c959b 7881
a2f14207
DB
7882 if (bytes == 0)
7883 {
7884 printf (_("\nThe .debug_loc section is empty.\n"));
7885 return 0;
7886 }
065c959b 7887
a2f14207
DB
7888 printf (_("Contents of the .debug_loc section:\n\n"));
7889 printf (_("\n Offset Begin End Expression\n"));
065c959b 7890
a2f14207
DB
7891 while (start < section_end)
7892 {
7893 unsigned long begin;
7894 unsigned long end;
7895 unsigned short length;
7896 unsigned long offset;
7897
7898 offset = start - section_begin;
7899
7900 while (1)
7901 {
8dde85fc
NC
7902 /* Normally, the lists in the debug_loc section are related to a
7903 given compilation unit, and thus, we would use the pointer size
7904 of that compilation unit. However, since we are displaying it
7905 seperately here, we either have to store pointer sizes of all
7906 compilation units, or assume they don't change. We assume,
7907 like the debug_line display, that it doesn't change. */
a2f14207
DB
7908 begin = byte_get (start, debug_line_pointer_size);
7909 start += debug_line_pointer_size;
7910 end = byte_get (start, debug_line_pointer_size);
7911 start += debug_line_pointer_size;
53c7db4b 7912
a2f14207
DB
7913 if (begin == 0 && end == 0)
7914 break;
53c7db4b 7915
8dde85fc
NC
7916 /* For now, skip any base address specifiers. */
7917 if (begin == 0xffffffff)
7918 continue;
7919
a2f14207
DB
7920 begin += addr;
7921 end += addr;
53c7db4b 7922
a2f14207
DB
7923 length = byte_get (start, 2);
7924 start += 2;
53c7db4b 7925
a2f14207
DB
7926 printf (" %8.8lx %8.8lx %8.8lx (", offset, begin, end);
7927 decode_location_expression (start, debug_line_pointer_size, length);
7928 printf (")\n");
53c7db4b 7929
a2f14207
DB
7930 start += length;
7931 }
7932 printf ("\n");
7933 }
7934 return 1;
7935}
252b5132 7936
b34976b6
AM
7937static const char *debug_str_contents;
7938static bfd_vma debug_str_size;
261a45ad
NC
7939
7940static void
7941load_debug_str (file)
b34976b6 7942 FILE *file;
261a45ad 7943{
b34976b6
AM
7944 Elf_Internal_Shdr *sec;
7945 unsigned int i;
261a45ad
NC
7946
7947 /* If it is already loaded, do nothing. */
7948 if (debug_str_contents != NULL)
7949 return;
7950
7951 /* Locate the .debug_str section. */
7952 for (i = 0, sec = section_headers;
7953 i < elf_header.e_shnum;
b34976b6 7954 i++, sec++)
261a45ad
NC
7955 if (strcmp (SECTION_NAME (sec), ".debug_str") == 0)
7956 break;
7957
7958 if (i == elf_header.e_shnum || sec->sh_size == 0)
7959 return;
7960
7961 debug_str_size = sec->sh_size;
7962
7963 debug_str_contents = ((char *)
7964 get_data (NULL, file, sec->sh_offset, sec->sh_size,
7965 _("debug_str section data")));
7966}
7967
7968static void
7969free_debug_str ()
7970{
7971 if (debug_str_contents == NULL)
7972 return;
7973
7974 free ((char *) debug_str_contents);
7975 debug_str_contents = NULL;
7976 debug_str_size = 0;
7977}
7978
7979static const char *
7980fetch_indirect_string (offset)
7981 unsigned long offset;
7982{
7983 if (debug_str_contents == NULL)
7984 return _("<no .debug_str section>");
7985
7986 if (offset > debug_str_size)
7987 return _("<offset is too big>");
7988
7989 return debug_str_contents + offset;
7990}
7991
261a45ad
NC
7992static int
7993display_debug_str (section, start, file)
b34976b6
AM
7994 Elf_Internal_Shdr *section;
7995 unsigned char *start;
7996 FILE *file ATTRIBUTE_UNUSED;
261a45ad 7997{
b34976b6
AM
7998 unsigned long bytes;
7999 bfd_vma addr;
261a45ad
NC
8000
8001 addr = section->sh_addr;
8002 bytes = section->sh_size;
8003
8004 if (bytes == 0)
8005 {
8006 printf (_("\nThe .debug_str section is empty.\n"));
8007 return 0;
8008 }
8009
8010 printf (_("Contents of the .debug_str section:\n\n"));
8011
8012 while (bytes)
8013 {
8014 int j;
8015 int k;
8016 int lbytes;
8017
8018 lbytes = (bytes > 16 ? 16 : bytes);
8019
8020 printf (" 0x%8.8lx ", (unsigned long) addr);
8021
8022 for (j = 0; j < 16; j++)
8023 {
8024 if (j < lbytes)
b34976b6 8025 printf ("%2.2x", start[j]);
261a45ad
NC
8026 else
8027 printf (" ");
8028
8029 if ((j & 3) == 3)
8030 printf (" ");
8031 }
8032
8033 for (j = 0; j < lbytes; j++)
8034 {
b34976b6 8035 k = start[j];
261a45ad
NC
8036 if (k >= ' ' && k < 0x80)
8037 printf ("%c", k);
8038 else
8039 printf (".");
8040 }
8041
8042 putchar ('\n');
8043
8044 start += lbytes;
8045 addr += lbytes;
8046 bytes -= lbytes;
8047 }
8048
8049 return 1;
8050}
8051
252b5132 8052static unsigned char *
ee42cf8c
NC
8053read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size,
8054 offset_size, dwarf_version)
b34976b6
AM
8055 unsigned long attribute;
8056 unsigned long form;
8057 unsigned char *data;
8058 unsigned long cu_offset;
8059 unsigned long pointer_size;
ee42cf8c
NC
8060 unsigned long offset_size;
8061 int dwarf_version;
252b5132 8062{
b34976b6
AM
8063 unsigned long uvalue = 0;
8064 unsigned char *block_start = NULL;
8065 int bytes_read;
252b5132 8066
252b5132
RH
8067 switch (form)
8068 {
60bcf0fa
NC
8069 default:
8070 break;
76da6bbe 8071
252b5132 8072 case DW_FORM_ref_addr:
ee42cf8c
NC
8073 if (dwarf_version == 2)
8074 {
8075 uvalue = byte_get (data, pointer_size);
8076 data += pointer_size;
8077 }
8078 else if (dwarf_version == 3)
8079 {
8080 uvalue = byte_get (data, offset_size);
8081 data += offset_size;
8082 }
8083 else
8084 {
8085 error (_("Internal error: DWARF version is not 2 or 3.\n"));
8086 }
8087 break;
8088
252b5132
RH
8089 case DW_FORM_addr:
8090 uvalue = byte_get (data, pointer_size);
252b5132
RH
8091 data += pointer_size;
8092 break;
8093
ef5cdfc7 8094 case DW_FORM_strp:
ee42cf8c
NC
8095 uvalue = byte_get (data, offset_size);
8096 data += offset_size;
ef5cdfc7
JJ
8097 break;
8098
252b5132
RH
8099 case DW_FORM_ref1:
8100 case DW_FORM_flag:
8101 case DW_FORM_data1:
b34976b6 8102 uvalue = byte_get (data++, 1);
252b5132
RH
8103 break;
8104
8105 case DW_FORM_ref2:
8106 case DW_FORM_data2:
8107 uvalue = byte_get (data, 2);
8108 data += 2;
252b5132
RH
8109 break;
8110
8111 case DW_FORM_ref4:
8112 case DW_FORM_data4:
8113 uvalue = byte_get (data, 4);
8114 data += 4;
1fa37306
JM
8115 break;
8116
8117 case DW_FORM_sdata:
8118 uvalue = read_leb128 (data, & bytes_read, 1);
8119 data += bytes_read;
8120 break;
8121
8122 case DW_FORM_ref_udata:
8123 case DW_FORM_udata:
8124 uvalue = read_leb128 (data, & bytes_read, 0);
8125 data += bytes_read;
8126 break;
81766fca
RH
8127
8128 case DW_FORM_indirect:
8129 form = read_leb128 (data, & bytes_read, 0);
8130 data += bytes_read;
8131 printf (" %s", get_FORM_name (form));
8132 return read_and_display_attr_value (attribute, form, data, cu_offset,
ee42cf8c
NC
8133 pointer_size, offset_size,
8134 dwarf_version);
1fa37306
JM
8135 }
8136
8137 switch (form)
8138 {
8139 case DW_FORM_ref_addr:
8140 printf (" <#%lx>", uvalue);
8141 break;
76da6bbe 8142
1fa37306
JM
8143 case DW_FORM_ref1:
8144 case DW_FORM_ref2:
8145 case DW_FORM_ref4:
8146 case DW_FORM_ref_udata:
8147 printf (" <%lx>", uvalue + cu_offset);
8148 break;
8149
8150 case DW_FORM_addr:
8151 printf (" %#lx", uvalue);
8152
8153 case DW_FORM_flag:
8154 case DW_FORM_data1:
8155 case DW_FORM_data2:
8156 case DW_FORM_data4:
8157 case DW_FORM_sdata:
8158 case DW_FORM_udata:
8159 printf (" %ld", uvalue);
252b5132
RH
8160 break;
8161
8162 case DW_FORM_ref8:
8163 case DW_FORM_data8:
8164 uvalue = byte_get (data, 4);
8165 printf (" %lx", uvalue);
148d3c43 8166 printf (" %lx", (unsigned long) byte_get (data + 4, 4));
252b5132
RH
8167 data += 8;
8168 break;
8169
8170 case DW_FORM_string:
8171 printf (" %s", data);
3c9f43b1 8172 data += strlen ((char *) data) + 1;
252b5132
RH
8173 break;
8174
252b5132
RH
8175 case DW_FORM_block:
8176 uvalue = read_leb128 (data, & bytes_read, 0);
8177 block_start = data + bytes_read;
8178 data = display_block (block_start, uvalue);
252b5132
RH
8179 break;
8180
8181 case DW_FORM_block1:
8182 uvalue = byte_get (data, 1);
8183 block_start = data + 1;
8184 data = display_block (block_start, uvalue);
252b5132
RH
8185 break;
8186
8187 case DW_FORM_block2:
8188 uvalue = byte_get (data, 2);
8189 block_start = data + 2;
8190 data = display_block (block_start, uvalue);
252b5132
RH
8191 break;
8192
8193 case DW_FORM_block4:
8194 uvalue = byte_get (data, 4);
8195 block_start = data + 4;
8196 data = display_block (block_start, uvalue);
252b5132
RH
8197 break;
8198
8199 case DW_FORM_strp:
f1ef08cb
AM
8200 printf (_(" (indirect string, offset: 0x%lx): %s"),
8201 uvalue, fetch_indirect_string (uvalue));
ef5cdfc7
JJ
8202 break;
8203
252b5132 8204 case DW_FORM_indirect:
e3c8793a 8205 /* Handled above. */
252b5132
RH
8206 break;
8207
8208 default:
2c71103e 8209 warn (_("Unrecognized form: %d\n"), form);
252b5132
RH
8210 break;
8211 }
8212
8213 /* For some attributes we can display futher information. */
8214
8215 printf ("\t");
8216
8217 switch (attribute)
8218 {
8219 case DW_AT_inline:
8220 switch (uvalue)
8221 {
b34976b6
AM
8222 case DW_INL_not_inlined:
8223 printf (_("(not inlined)"));
8224 break;
8225 case DW_INL_inlined:
8226 printf (_("(inlined)"));
8227 break;
8228 case DW_INL_declared_not_inlined:
8229 printf (_("(declared as inline but ignored)"));
8230 break;
8231 case DW_INL_declared_inlined:
8232 printf (_("(declared as inline and inlined)"));
8233 break;
8234 default:
8235 printf (_(" (Unknown inline attribute value: %lx)"), uvalue);
8236 break;
252b5132
RH
8237 }
8238 break;
8239
252b5132
RH
8240 case DW_AT_language:
8241 switch (uvalue)
8242 {
b34976b6
AM
8243 case DW_LANG_C: printf ("(non-ANSI C)"); break;
8244 case DW_LANG_C89: printf ("(ANSI C)"); break;
8245 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
8246 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
8247 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
8248 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
8249 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
8250 case DW_LANG_Ada83: printf ("(Ada)"); break;
8251 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
8252 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
8253 /* DWARF 2.1 values. */
8254 case DW_LANG_C99: printf ("(ANSI C99)"); break;
8255 case DW_LANG_Ada95: printf ("(ADA 95)"); break;
8256 case DW_LANG_Fortran95: printf ("(Fortran 95)"); break;
b811889f 8257 /* MIPS extension. */
b34976b6 8258 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
84ad6ede
NC
8259 /* UPC extension. */
8260 case DW_LANG_Upc: printf ("(Unified Parallel C)"); break;
b34976b6
AM
8261 default:
8262 printf ("(Unknown: %lx)", uvalue);
8263 break;
252b5132
RH
8264 }
8265 break;
8266
8267 case DW_AT_encoding:
8268 switch (uvalue)
8269 {
b34976b6
AM
8270 case DW_ATE_void: printf ("(void)"); break;
8271 case DW_ATE_address: printf ("(machine address)"); break;
8272 case DW_ATE_boolean: printf ("(boolean)"); break;
8273 case DW_ATE_complex_float: printf ("(complex float)"); break;
8274 case DW_ATE_float: printf ("(float)"); break;
8275 case DW_ATE_signed: printf ("(signed)"); break;
8276 case DW_ATE_signed_char: printf ("(signed char)"); break;
8277 case DW_ATE_unsigned: printf ("(unsigned)"); break;
8278 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
b811889f 8279 /* DWARF 2.1 value. */
b34976b6 8280 case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
252b5132
RH
8281 default:
8282 if (uvalue >= DW_ATE_lo_user
8283 && uvalue <= DW_ATE_hi_user)
8284 printf ("(user defined type)");
8285 else
8286 printf ("(unknown type)");
8287 break;
8288 }
8289 break;
8290
8291 case DW_AT_accessibility:
8292 switch (uvalue)
8293 {
8294 case DW_ACCESS_public: printf ("(public)"); break;
8295 case DW_ACCESS_protected: printf ("(protected)"); break;
8296 case DW_ACCESS_private: printf ("(private)"); break;
b34976b6
AM
8297 default:
8298 printf ("(unknown accessibility)");
8299 break;
252b5132
RH
8300 }
8301 break;
8302
8303 case DW_AT_visibility:
8304 switch (uvalue)
8305 {
b34976b6
AM
8306 case DW_VIS_local: printf ("(local)"); break;
8307 case DW_VIS_exported: printf ("(exported)"); break;
8308 case DW_VIS_qualified: printf ("(qualified)"); break;
8309 default: printf ("(unknown visibility)"); break;
252b5132
RH
8310 }
8311 break;
8312
8313 case DW_AT_virtuality:
8314 switch (uvalue)
8315 {
8316 case DW_VIRTUALITY_none: printf ("(none)"); break;
8317 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
8318 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
b34976b6 8319 default: printf ("(unknown virtuality)"); break;
252b5132
RH
8320 }
8321 break;
8322
8323 case DW_AT_identifier_case:
8324 switch (uvalue)
8325 {
8326 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
8327 case DW_ID_up_case: printf ("(up_case)"); break;
8328 case DW_ID_down_case: printf ("(down_case)"); break;
8329 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
b34976b6 8330 default: printf ("(unknown case)"); break;
252b5132
RH
8331 }
8332 break;
8333
8334 case DW_AT_calling_convention:
8335 switch (uvalue)
8336 {
8337 case DW_CC_normal: printf ("(normal)"); break;
8338 case DW_CC_program: printf ("(program)"); break;
8339 case DW_CC_nocall: printf ("(nocall)"); break;
8340 default:
8341 if (uvalue >= DW_CC_lo_user
8342 && uvalue <= DW_CC_hi_user)
8343 printf ("(user defined)");
8344 else
8345 printf ("(unknown convention)");
8346 }
8347 break;
8348
12ab83a9
NC
8349 case DW_AT_ordering:
8350 switch (uvalue)
8351 {
8352 case -1: printf ("(undefined)"); break;
8353 case 0: printf ("(row major)"); break;
8354 case 1: printf ("(column major)"); break;
8355 }
8356 break;
8357
eb6bd4d3 8358 case DW_AT_frame_base:
252b5132
RH
8359 case DW_AT_location:
8360 case DW_AT_data_member_location:
8361 case DW_AT_vtable_elem_location:
12ab83a9
NC
8362 case DW_AT_allocated:
8363 case DW_AT_associated:
8364 case DW_AT_data_location:
8365 case DW_AT_stride:
8366 case DW_AT_upper_bound:
8367 case DW_AT_lower_bound:
eb6bd4d3
JM
8368 if (block_start)
8369 {
8370 printf ("(");
8371 decode_location_expression (block_start, pointer_size, uvalue);
8372 printf (")");
8373 }
ee42cf8c 8374 else if (form == DW_FORM_data4 || form == DW_FORM_data8)
a2f14207
DB
8375 {
8376 printf ("(");
8377 printf ("location list");
8378 printf (")");
8379 }
252b5132
RH
8380 break;
8381
8382 default:
8383 break;
8384 }
8385
81766fca
RH
8386 return data;
8387}
8388
8389static unsigned char *
ee42cf8c
NC
8390read_and_display_attr (attribute, form, data, cu_offset, pointer_size,
8391 offset_size, dwarf_version)
b34976b6
AM
8392 unsigned long attribute;
8393 unsigned long form;
8394 unsigned char *data;
8395 unsigned long cu_offset;
8396 unsigned long pointer_size;
ee42cf8c
NC
8397 unsigned long offset_size;
8398 int dwarf_version;
81766fca
RH
8399{
8400 printf (" %-18s:", get_AT_name (attribute));
8401 data = read_and_display_attr_value (attribute, form, data, cu_offset,
ee42cf8c 8402 pointer_size, offset_size, dwarf_version);
252b5132
RH
8403 printf ("\n");
8404 return data;
8405}
8406
8407static int
8408display_debug_info (section, start, file)
b34976b6
AM
8409 Elf_Internal_Shdr *section;
8410 unsigned char *start;
8411 FILE *file;
252b5132 8412{
b34976b6
AM
8413 unsigned char *end = start + section->sh_size;
8414 unsigned char *section_begin = start;
252b5132
RH
8415
8416 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
8417
261a45ad 8418 load_debug_str (file);
a2f14207 8419 load_debug_loc (file);
ef5cdfc7 8420
252b5132
RH
8421 while (start < end)
8422 {
b34976b6
AM
8423 DWARF2_Internal_CompUnit compunit;
8424 Elf_Internal_Shdr *relsec;
ee42cf8c
NC
8425 unsigned char *hdrptr;
8426 unsigned char *cu_abbrev_offset_ptr;
b34976b6
AM
8427 unsigned char *tags;
8428 unsigned int i;
8429 int level;
8430 unsigned long cu_offset;
ee42cf8c
NC
8431 int offset_size;
8432 int initial_length_size;
252b5132 8433
ee42cf8c 8434 hdrptr = start;
252b5132 8435
ee42cf8c
NC
8436 compunit.cu_length = byte_get (hdrptr, 4);
8437 hdrptr += 4;
252b5132 8438
428409d5
NC
8439 if (compunit.cu_length == 0xffffffff)
8440 {
ee42cf8c
NC
8441 compunit.cu_length = byte_get (hdrptr, 8);
8442 hdrptr += 8;
8443 offset_size = 8;
8444 initial_length_size = 12;
8445 }
8446 else
8447 {
8448 offset_size = 4;
8449 initial_length_size = 4;
428409d5
NC
8450 }
8451
ee42cf8c
NC
8452 compunit.cu_version = byte_get (hdrptr, 2);
8453 hdrptr += 2;
8454
adab8cdc 8455 /* Apply addends of RELA relocations. */
c0e047e0
AO
8456 for (relsec = section_headers;
8457 relsec < section_headers + elf_header.e_shnum;
8458 ++relsec)
8459 {
9ad5cbcf 8460 unsigned long nrelas;
c0e047e0 8461 Elf_Internal_Rela *rela, *rp;
c8286bd1 8462 Elf_Internal_Shdr *symsec;
c0e047e0
AO
8463 Elf_Internal_Sym *symtab;
8464 Elf_Internal_Sym *sym;
8465
8466 if (relsec->sh_type != SHT_RELA
09fc3b02
DJ
8467 || SECTION_HEADER (relsec->sh_info) != section
8468 || relsec->sh_size == 0)
c0e047e0
AO
8469 continue;
8470
8471 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
8472 & rela, & nrelas))
8473 return 0;
8474
9ad5cbcf
AM
8475 symsec = SECTION_HEADER (relsec->sh_link);
8476 symtab = GET_ELF_SYMBOLS (file, symsec);
c0e047e0
AO
8477
8478 for (rp = rela; rp < rela + nrelas; ++rp)
8479 {
adab8cdc
AO
8480 unsigned char *loc;
8481
8482 if (rp->r_offset >= (bfd_vma) (hdrptr - section_begin)
8483 && section->sh_size > (bfd_vma) offset_size
8484 && rp->r_offset <= section->sh_size - offset_size)
8485 loc = section_begin + rp->r_offset;
8486 else
c0e047e0 8487 continue;
0823fbca 8488
c0e047e0
AO
8489 if (is_32bit_elf)
8490 {
8491 sym = symtab + ELF32_R_SYM (rp->r_info);
8492
09fc3b02
DJ
8493 if (ELF32_R_SYM (rp->r_info) != 0
8494 && ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
c0e047e0 8495 {
e5fb9629 8496 warn (_("Skipping unexpected symbol type %u\n"),
c0e047e0
AO
8497 ELF32_ST_TYPE (sym->st_info));
8498 continue;
8499 }
8500 }
8501 else
8502 {
8503 sym = symtab + ELF64_R_SYM (rp->r_info);
8504
09fc3b02
DJ
8505 if (ELF64_R_SYM (rp->r_info) != 0
8506 && ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
c0e047e0 8507 {
e5fb9629 8508 warn (_("Skipping unexpected symbol type %u\n"),
c0e047e0
AO
8509 ELF64_ST_TYPE (sym->st_info));
8510 continue;
8511 }
8512 }
8513
adab8cdc 8514 byte_put (loc, rp->r_addend, offset_size);
c0e047e0
AO
8515 }
8516
8517 free (rela);
8518 break;
8519 }
8520
adab8cdc
AO
8521 cu_abbrev_offset_ptr = hdrptr;
8522 compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size);
8523 hdrptr += offset_size;
8524
8525 compunit.cu_pointer_size = byte_get (hdrptr, 1);
8526 hdrptr += 1;
8527
ee42cf8c 8528 tags = hdrptr;
1fa37306 8529 cu_offset = start - section_begin;
ee42cf8c 8530 start += compunit.cu_length + initial_length_size;
252b5132 8531
09fd7e38
JM
8532 printf (_(" Compilation Unit @ %lx:\n"), cu_offset);
8533 printf (_(" Length: %ld\n"), compunit.cu_length);
8534 printf (_(" Version: %d\n"), compunit.cu_version);
8535 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
8536 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
8537
ee42cf8c 8538 if (compunit.cu_version != 2 && compunit.cu_version != 3)
252b5132 8539 {
ee42cf8c 8540 warn (_("Only version 2 and 3 DWARF debug information is currently supported.\n"));
252b5132
RH
8541 continue;
8542 }
8543
261a45ad 8544 free_abbrevs ();
252b5132
RH
8545
8546 /* Read in the abbrevs used by this compilation unit. */
252b5132 8547 {
b34976b6
AM
8548 Elf_Internal_Shdr *sec;
8549 unsigned char *begin;
252b5132
RH
8550
8551 /* Locate the .debug_abbrev section and process it. */
8552 for (i = 0, sec = section_headers;
8553 i < elf_header.e_shnum;
b34976b6 8554 i++, sec++)
252b5132
RH
8555 if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
8556 break;
8557
ef5cdfc7 8558 if (i == elf_header.e_shnum || sec->sh_size == 0)
252b5132
RH
8559 {
8560 warn (_("Unable to locate .debug_abbrev section!\n"));
8561 return 0;
8562 }
8563
a6e9f9df 8564 begin = ((unsigned char *)
0823fbca 8565 get_data (NULL, file, sec->sh_offset, sec->sh_size,
a6e9f9df
AM
8566 _("debug_abbrev section data")));
8567 if (!begin)
8568 return 0;
252b5132
RH
8569
8570 process_abbrev_section (begin + compunit.cu_abbrev_offset,
8571 begin + sec->sh_size);
8572
8573 free (begin);
8574 }
8575
8576 level = 0;
8577 while (tags < start)
8578 {
b34976b6
AM
8579 int bytes_read;
8580 unsigned long abbrev_number;
8581 abbrev_entry *entry;
8582 abbrev_attr *attr;
252b5132
RH
8583
8584 abbrev_number = read_leb128 (tags, & bytes_read, 0);
8585 tags += bytes_read;
8586
8587 /* A null DIE marks the end of a list of children. */
8588 if (abbrev_number == 0)
8589 {
8590 --level;
8591 continue;
8592 }
8593
8594 /* Scan through the abbreviation list until we reach the
8595 correct entry. */
8596 for (entry = first_abbrev;
8597 entry && entry->entry != abbrev_number;
8598 entry = entry->next)
8599 continue;
8600
8601 if (entry == NULL)
8602 {
b4c96d0d 8603 warn (_("Unable to locate entry %lu in the abbreviation table\n"),
252b5132
RH
8604 abbrev_number);
8605 return 0;
8606 }
8607
410f7a12
L
8608 printf (_(" <%d><%lx>: Abbrev Number: %lu (%s)\n"),
8609 level,
8610 (unsigned long) (tags - section_begin - bytes_read),
252b5132
RH
8611 abbrev_number,
8612 get_TAG_name (entry->tag));
8613
8614 for (attr = entry->first_attr; attr; attr = attr->next)
8615 tags = read_and_display_attr (attr->attribute,
8616 attr->form,
1fa37306 8617 tags, cu_offset,
ee42cf8c
NC
8618 compunit.cu_pointer_size,
8619 offset_size,
8620 compunit.cu_version);
252b5132
RH
8621
8622 if (entry->children)
8623 ++level;
8624 }
8625 }
8626
261a45ad 8627 free_debug_str ();
a2f14207 8628 free_debug_loc ();
ef5cdfc7 8629
252b5132
RH
8630 printf ("\n");
8631
8632 return 1;
8633}
8634
8635static int
8636display_debug_aranges (section, start, file)
b34976b6
AM
8637 Elf_Internal_Shdr *section;
8638 unsigned char *start;
8639 FILE *file ATTRIBUTE_UNUSED;
252b5132 8640{
b34976b6 8641 unsigned char *end = start + section->sh_size;
252b5132
RH
8642
8643 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
8644
8645 while (start < end)
8646 {
ee42cf8c 8647 unsigned char *hdrptr;
b34976b6
AM
8648 DWARF2_Internal_ARange arange;
8649 unsigned char *ranges;
8650 unsigned long length;
8651 unsigned long address;
8652 int excess;
ee42cf8c
NC
8653 int offset_size;
8654 int initial_length_size;
252b5132 8655
ee42cf8c 8656 hdrptr = start;
252b5132 8657
ee42cf8c
NC
8658 arange.ar_length = byte_get (hdrptr, 4);
8659 hdrptr += 4;
252b5132 8660
e414a165
NC
8661 if (arange.ar_length == 0xffffffff)
8662 {
ee42cf8c
NC
8663 arange.ar_length = byte_get (hdrptr, 8);
8664 hdrptr += 8;
8665 offset_size = 8;
8666 initial_length_size = 12;
8667 }
8668 else
8669 {
8670 offset_size = 4;
8671 initial_length_size = 4;
e414a165
NC
8672 }
8673
ee42cf8c
NC
8674 arange.ar_version = byte_get (hdrptr, 2);
8675 hdrptr += 2;
8676
8677 arange.ar_info_offset = byte_get (hdrptr, offset_size);
8678 hdrptr += offset_size;
8679
8680 arange.ar_pointer_size = byte_get (hdrptr, 1);
8681 hdrptr += 1;
8682
8683 arange.ar_segment_size = byte_get (hdrptr, 1);
8684 hdrptr += 1;
8685
8686 if (arange.ar_version != 2 && arange.ar_version != 3)
3f215a10 8687 {
ee42cf8c 8688 warn (_("Only DWARF 2 and 3 aranges are currently supported.\n"));
3f215a10
NC
8689 break;
8690 }
8691
252b5132
RH
8692 printf (_(" Length: %ld\n"), arange.ar_length);
8693 printf (_(" Version: %d\n"), arange.ar_version);
8694 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
8695 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
8696 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
8697
8698 printf (_("\n Address Length\n"));
8699
ee42cf8c 8700 ranges = hdrptr;
252b5132 8701
7a4b7442 8702 /* Must pad to an alignment boundary that is twice the pointer size. */
ee42cf8c 8703 excess = (hdrptr - start) % (2 * arange.ar_pointer_size);
7a4b7442
NC
8704 if (excess)
8705 ranges += (2 * arange.ar_pointer_size) - excess;
8706
252b5132
RH
8707 for (;;)
8708 {
8709 address = byte_get (ranges, arange.ar_pointer_size);
8710
252b5132
RH
8711 ranges += arange.ar_pointer_size;
8712
8713 length = byte_get (ranges, arange.ar_pointer_size);
8714
8715 ranges += arange.ar_pointer_size;
8716
7a4b7442
NC
8717 /* A pair of zeros marks the end of the list. */
8718 if (address == 0 && length == 0)
8719 break;
103f02d3 8720
252b5132
RH
8721 printf (" %8.8lx %lu\n", address, length);
8722 }
8723
ee42cf8c 8724 start += arange.ar_length + initial_length_size;
252b5132
RH
8725 }
8726
8727 printf ("\n");
8728
8729 return 1;
8730}
8731
c47d488e
DD
8732typedef struct Frame_Chunk
8733{
b34976b6
AM
8734 struct Frame_Chunk *next;
8735 unsigned char *chunk_start;
8736 int ncols;
a98cc2b2 8737 /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */
b34976b6
AM
8738 short int *col_type;
8739 int *col_offset;
8740 char *augmentation;
8741 unsigned int code_factor;
8742 int data_factor;
8743 unsigned long pc_begin;
8744 unsigned long pc_range;
8745 int cfa_reg;
8746 int cfa_offset;
8747 int ra;
8748 unsigned char fde_encoding;
63044634 8749 unsigned char cfa_exp;
c47d488e
DD
8750}
8751Frame_Chunk;
8752
a98cc2b2
AH
8753/* A marker for a col_type that means this column was never referenced
8754 in the frame info. */
8755#define DW_CFA_unreferenced (-1)
8756
2863d58a
AM
8757static void frame_need_space PARAMS ((Frame_Chunk *, int));
8758static void frame_display_row PARAMS ((Frame_Chunk *, int *, int *));
8759static int size_of_encoded_value PARAMS ((int));
38fafa6d 8760static bfd_vma get_encoded_value PARAMS ((unsigned char *, int));
2863d58a 8761
c47d488e
DD
8762static void
8763frame_need_space (fc, reg)
b34976b6 8764 Frame_Chunk *fc;
c47d488e
DD
8765 int reg;
8766{
8767 int prev = fc->ncols;
8768
8769 if (reg < fc->ncols)
8770 return;
584da044 8771
c47d488e 8772 fc->ncols = reg + 1;
a98cc2b2
AH
8773 fc->col_type = (short int *) xrealloc (fc->col_type,
8774 fc->ncols * sizeof (short int));
c47d488e
DD
8775 fc->col_offset = (int *) xrealloc (fc->col_offset,
8776 fc->ncols * sizeof (int));
8777
8778 while (prev < fc->ncols)
8779 {
a98cc2b2 8780 fc->col_type[prev] = DW_CFA_unreferenced;
c47d488e
DD
8781 fc->col_offset[prev] = 0;
8782 prev++;
8783 }
8784}
8785
8786static void
8787frame_display_row (fc, need_col_headers, max_regs)
b34976b6
AM
8788 Frame_Chunk *fc;
8789 int *need_col_headers;
8790 int *max_regs;
c47d488e
DD
8791{
8792 int r;
8793 char tmp[100];
8794
b34976b6
AM
8795 if (*max_regs < fc->ncols)
8796 *max_regs = fc->ncols;
584da044 8797
b34976b6 8798 if (*need_col_headers)
c47d488e 8799 {
b34976b6 8800 *need_col_headers = 0;
584da044 8801
c47d488e 8802 printf (" LOC CFA ");
584da044 8803
b34976b6 8804 for (r = 0; r < *max_regs; r++)
a98cc2b2
AH
8805 if (fc->col_type[r] != DW_CFA_unreferenced)
8806 {
8807 if (r == fc->ra)
8808 printf ("ra ");
8809 else
8810 printf ("r%-4d", r);
8811 }
584da044 8812
c47d488e
DD
8813 printf ("\n");
8814 }
584da044 8815
31b6fca6 8816 printf ("%08lx ", fc->pc_begin);
63044634
RH
8817 if (fc->cfa_exp)
8818 strcpy (tmp, "exp");
8819 else
8820 sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
c47d488e 8821 printf ("%-8s ", tmp);
584da044
NC
8822
8823 for (r = 0; r < fc->ncols; r++)
c47d488e 8824 {
a98cc2b2 8825 if (fc->col_type[r] != DW_CFA_unreferenced)
c47d488e 8826 {
a98cc2b2
AH
8827 switch (fc->col_type[r])
8828 {
8829 case DW_CFA_undefined:
8830 strcpy (tmp, "u");
8831 break;
8832 case DW_CFA_same_value:
8833 strcpy (tmp, "s");
8834 break;
8835 case DW_CFA_offset:
8836 sprintf (tmp, "c%+d", fc->col_offset[r]);
8837 break;
8838 case DW_CFA_register:
8839 sprintf (tmp, "r%d", fc->col_offset[r]);
8840 break;
63044634
RH
8841 case DW_CFA_expression:
8842 strcpy (tmp, "exp");
8843 break;
a98cc2b2
AH
8844 default:
8845 strcpy (tmp, "n/a");
8846 break;
8847 }
8848 printf ("%-5s", tmp);
c47d488e 8849 }
c47d488e
DD
8850 }
8851 printf ("\n");
8852}
8853
31b6fca6
RH
8854static int
8855size_of_encoded_value (encoding)
8856 int encoding;
8857{
8858 switch (encoding & 0x7)
8859 {
8860 default: /* ??? */
8861 case 0: return is_32bit_elf ? 4 : 8;
8862 case 2: return 2;
8863 case 3: return 4;
8864 case 4: return 8;
8865 }
8866}
8867
38fafa6d
RH
8868static bfd_vma
8869get_encoded_value (data, encoding)
8870 unsigned char *data;
8871 int encoding;
8872{
8873 int size = size_of_encoded_value (encoding);
8874 if (encoding & DW_EH_PE_signed)
8875 return byte_get_signed (data, size);
8876 else
8877 return byte_get (data, size);
8878}
8879
c47d488e 8880#define GET(N) byte_get (start, N); start += N
584da044
NC
8881#define LEB() read_leb128 (start, & length_return, 0); start += length_return
8882#define SLEB() read_leb128 (start, & length_return, 1); start += length_return
c47d488e
DD
8883
8884static int
8885display_debug_frames (section, start, file)
b34976b6
AM
8886 Elf_Internal_Shdr *section;
8887 unsigned char *start;
8888 FILE *file ATTRIBUTE_UNUSED;
c47d488e 8889{
b34976b6
AM
8890 unsigned char *end = start + section->sh_size;
8891 unsigned char *section_start = start;
8892 Frame_Chunk *chunks = 0;
8893 Frame_Chunk *remembered_state = 0;
8894 Frame_Chunk *rs;
8895 int is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
8896 int length_return;
8897 int max_regs = 0;
8898 int addr_size = is_32bit_elf ? 4 : 8;
c47d488e
DD
8899
8900 printf (_("The section %s contains:\n"), SECTION_NAME (section));
8901
8902 while (start < end)
8903 {
b34976b6
AM
8904 unsigned char *saved_start;
8905 unsigned char *block_end;
8906 unsigned long length;
8907 unsigned long cie_id;
8908 Frame_Chunk *fc;
8909 Frame_Chunk *cie;
8910 int need_col_headers = 1;
8911 unsigned char *augmentation_data = NULL;
8912 unsigned long augmentation_data_len = 0;
8913 int encoded_ptr_size = addr_size;
ee42cf8c
NC
8914 int offset_size;
8915 int initial_length_size;
c47d488e
DD
8916
8917 saved_start = start;
8918 length = byte_get (start, 4); start += 4;
8919
8920 if (length == 0)
f1ef08cb
AM
8921 {
8922 printf ("\n%08lx ZERO terminator\n\n",
8923 (unsigned long)(saved_start - section_start));
8924 return 1;
8925 }
c47d488e 8926
428409d5
NC
8927 if (length == 0xffffffff)
8928 {
ee42cf8c
NC
8929 length = byte_get (start, 8);
8930 start += 8;
8931 offset_size = 8;
8932 initial_length_size = 12;
8933 }
8934 else
8935 {
8936 offset_size = 4;
8937 initial_length_size = 4;
428409d5
NC
8938 }
8939
ee42cf8c
NC
8940 block_end = saved_start + length + initial_length_size;
8941 cie_id = byte_get (start, offset_size); start += offset_size;
c47d488e 8942
c47d488e
DD
8943 if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
8944 {
31b6fca6
RH
8945 int version;
8946
c47d488e
DD
8947 fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
8948 memset (fc, 0, sizeof (Frame_Chunk));
8949
8950 fc->next = chunks;
8951 chunks = fc;
8952 fc->chunk_start = saved_start;
8953 fc->ncols = 0;
a98cc2b2 8954 fc->col_type = (short int *) xmalloc (sizeof (short int));
c47d488e
DD
8955 fc->col_offset = (int *) xmalloc (sizeof (int));
8956 frame_need_space (fc, max_regs-1);
8957
31b6fca6 8958 version = *start++;
584da044 8959
31b6fca6
RH
8960 fc->augmentation = start;
8961 start = strchr (start, '\0') + 1;
584da044 8962
c47d488e
DD
8963 if (fc->augmentation[0] == 'z')
8964 {
c47d488e
DD
8965 fc->code_factor = LEB ();
8966 fc->data_factor = SLEB ();
8967 fc->ra = byte_get (start, 1); start += 1;
31b6fca6
RH
8968 augmentation_data_len = LEB ();
8969 augmentation_data = start;
8970 start += augmentation_data_len;
c47d488e
DD
8971 }
8972 else if (strcmp (fc->augmentation, "eh") == 0)
8973 {
31b6fca6 8974 start += addr_size;
c47d488e
DD
8975 fc->code_factor = LEB ();
8976 fc->data_factor = SLEB ();
8977 fc->ra = byte_get (start, 1); start += 1;
8978 }
8979 else
8980 {
8981 fc->code_factor = LEB ();
8982 fc->data_factor = SLEB ();
8983 fc->ra = byte_get (start, 1); start += 1;
8984 }
8985 cie = fc;
31b6fca6
RH
8986
8987 if (do_debug_frames_interp)
8988 printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
7036c0e1 8989 (unsigned long)(saved_start - section_start), length, cie_id,
31b6fca6
RH
8990 fc->augmentation, fc->code_factor, fc->data_factor,
8991 fc->ra);
8992 else
8993 {
8994 printf ("\n%08lx %08lx %08lx CIE\n",
7036c0e1 8995 (unsigned long)(saved_start - section_start), length, cie_id);
31b6fca6
RH
8996 printf (" Version: %d\n", version);
8997 printf (" Augmentation: \"%s\"\n", fc->augmentation);
8998 printf (" Code alignment factor: %u\n", fc->code_factor);
8999 printf (" Data alignment factor: %d\n", fc->data_factor);
9000 printf (" Return address column: %d\n", fc->ra);
9001
9002 if (augmentation_data_len)
9003 {
9004 unsigned long i;
9005 printf (" Augmentation data: ");
9006 for (i = 0; i < augmentation_data_len; ++i)
9007 printf (" %02x", augmentation_data[i]);
9008 putchar ('\n');
9009 }
9010 putchar ('\n');
9011 }
9012
9013 if (augmentation_data_len)
9014 {
9015 unsigned char *p, *q;
9016 p = fc->augmentation + 1;
9017 q = augmentation_data;
9018
9019 while (1)
9020 {
9021 if (*p == 'L')
7036c0e1 9022 q++;
31b6fca6
RH
9023 else if (*p == 'P')
9024 q += 1 + size_of_encoded_value (*q);
9025 else if (*p == 'R')
9026 fc->fde_encoding = *q++;
9027 else
9028 break;
9029 p++;
9030 }
9031
9032 if (fc->fde_encoding)
9033 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
9034 }
c47d488e
DD
9035
9036 frame_need_space (fc, fc->ra);
9037 }
9038 else
9039 {
b34976b6 9040 unsigned char *look_for;
c47d488e 9041 static Frame_Chunk fde_fc;
584da044
NC
9042
9043 fc = & fde_fc;
c47d488e
DD
9044 memset (fc, 0, sizeof (Frame_Chunk));
9045
31b6fca6 9046 look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
c47d488e 9047
428409d5 9048 for (cie = chunks; cie ; cie = cie->next)
31b6fca6
RH
9049 if (cie->chunk_start == look_for)
9050 break;
c47d488e 9051
c47d488e
DD
9052 if (!cie)
9053 {
31b6fca6
RH
9054 warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
9055 cie_id, saved_start);
c47d488e
DD
9056 start = block_end;
9057 fc->ncols = 0;
a98cc2b2 9058 fc->col_type = (short int *) xmalloc (sizeof (short int));
c47d488e 9059 fc->col_offset = (int *) xmalloc (sizeof (int));
584da044 9060 frame_need_space (fc, max_regs - 1);
c47d488e
DD
9061 cie = fc;
9062 fc->augmentation = "";
31b6fca6 9063 fc->fde_encoding = 0;
c47d488e
DD
9064 }
9065 else
9066 {
9067 fc->ncols = cie->ncols;
a98cc2b2 9068 fc->col_type = (short int *) xmalloc (fc->ncols * sizeof (short int));
c47d488e 9069 fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
a98cc2b2 9070 memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
c47d488e
DD
9071 memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
9072 fc->augmentation = cie->augmentation;
9073 fc->code_factor = cie->code_factor;
9074 fc->data_factor = cie->data_factor;
9075 fc->cfa_reg = cie->cfa_reg;
9076 fc->cfa_offset = cie->cfa_offset;
9077 fc->ra = cie->ra;
9078 frame_need_space (fc, max_regs-1);
31b6fca6 9079 fc->fde_encoding = cie->fde_encoding;
c47d488e
DD
9080 }
9081
31b6fca6
RH
9082 if (fc->fde_encoding)
9083 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
9084
38fafa6d 9085 fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
f1ef08cb
AM
9086 if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
9087 fc->pc_begin += section->sh_addr + (start - section_start);
31b6fca6
RH
9088 start += encoded_ptr_size;
9089 fc->pc_range = byte_get (start, encoded_ptr_size);
9090 start += encoded_ptr_size;
9091
c47d488e
DD
9092 if (cie->augmentation[0] == 'z')
9093 {
31b6fca6
RH
9094 augmentation_data_len = LEB ();
9095 augmentation_data = start;
9096 start += augmentation_data_len;
c47d488e
DD
9097 }
9098
410f7a12 9099 printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
7036c0e1 9100 (unsigned long)(saved_start - section_start), length, cie_id,
410f7a12
L
9101 (unsigned long)(cie->chunk_start - section_start),
9102 fc->pc_begin, fc->pc_begin + fc->pc_range);
31b6fca6
RH
9103 if (! do_debug_frames_interp && augmentation_data_len)
9104 {
9105 unsigned long i;
9106 printf (" Augmentation data: ");
9107 for (i = 0; i < augmentation_data_len; ++i)
9108 printf (" %02x", augmentation_data[i]);
9109 putchar ('\n');
9110 putchar ('\n');
9111 }
c47d488e
DD
9112 }
9113
9114 /* At this point, fc is the current chunk, cie (if any) is set, and we're
9115 about to interpret instructions for the chunk. */
38fafa6d
RH
9116 /* ??? At present we need to do this always, since this sizes the
9117 fc->col_type and fc->col_offset arrays, which we write into always.
9118 We should probably split the interpreted and non-interpreted bits
9119 into two different routines, since there's so much that doesn't
9120 really overlap between them. */
9121 if (1 || do_debug_frames_interp)
53c7db4b
KH
9122 {
9123 /* Start by making a pass over the chunk, allocating storage
9124 and taking note of what registers are used. */
b34976b6 9125 unsigned char *tmp = start;
a98cc2b2 9126
53c7db4b
KH
9127 while (start < block_end)
9128 {
9129 unsigned op, opa;
63044634 9130 unsigned long reg, tmp;
7036c0e1 9131
b34976b6 9132 op = *start++;
53c7db4b
KH
9133 opa = op & 0x3f;
9134 if (op & 0xc0)
9135 op &= 0xc0;
7036c0e1 9136
53c7db4b
KH
9137 /* Warning: if you add any more cases to this switch, be
9138 sure to add them to the corresponding switch below. */
9139 switch (op)
9140 {
9141 case DW_CFA_advance_loc:
9142 break;
9143 case DW_CFA_offset:
9144 LEB ();
9145 frame_need_space (fc, opa);
9146 fc->col_type[opa] = DW_CFA_undefined;
9147 break;
9148 case DW_CFA_restore:
9149 frame_need_space (fc, opa);
9150 fc->col_type[opa] = DW_CFA_undefined;
9151 break;
9152 case DW_CFA_set_loc:
9153 start += encoded_ptr_size;
9154 break;
9155 case DW_CFA_advance_loc1:
9156 start += 1;
9157 break;
9158 case DW_CFA_advance_loc2:
9159 start += 2;
9160 break;
9161 case DW_CFA_advance_loc4:
9162 start += 4;
9163 break;
9164 case DW_CFA_offset_extended:
9165 reg = LEB (); LEB ();
9166 frame_need_space (fc, reg);
9167 fc->col_type[reg] = DW_CFA_undefined;
9168 break;
9169 case DW_CFA_restore_extended:
9170 reg = LEB ();
9171 frame_need_space (fc, reg);
9172 fc->col_type[reg] = DW_CFA_undefined;
9173 break;
9174 case DW_CFA_undefined:
9175 reg = LEB ();
9176 frame_need_space (fc, reg);
9177 fc->col_type[reg] = DW_CFA_undefined;
9178 break;
9179 case DW_CFA_same_value:
9180 reg = LEB ();
9181 frame_need_space (fc, reg);
9182 fc->col_type[reg] = DW_CFA_undefined;
9183 break;
9184 case DW_CFA_register:
9185 reg = LEB (); LEB ();
9186 frame_need_space (fc, reg);
9187 fc->col_type[reg] = DW_CFA_undefined;
9188 break;
9189 case DW_CFA_def_cfa:
9190 LEB (); LEB ();
9191 break;
9192 case DW_CFA_def_cfa_register:
9193 LEB ();
9194 break;
9195 case DW_CFA_def_cfa_offset:
9196 LEB ();
9197 break;
63044634
RH
9198 case DW_CFA_def_cfa_expression:
9199 tmp = LEB ();
9200 start += tmp;
9201 break;
9202 case DW_CFA_expression:
9203 reg = LEB ();
9204 tmp = LEB ();
9205 start += tmp;
9206 frame_need_space (fc, reg);
9207 fc->col_type[reg] = DW_CFA_undefined;
9208 break;
91a106e6
L
9209 case DW_CFA_offset_extended_sf:
9210 reg = LEB (); SLEB ();
9211 frame_need_space (fc, reg);
9212 fc->col_type[reg] = DW_CFA_undefined;
9213 break;
9214 case DW_CFA_def_cfa_sf:
9215 LEB (); SLEB ();
9216 break;
9217 case DW_CFA_def_cfa_offset_sf:
9218 SLEB ();
9219 break;
63044634
RH
9220 case DW_CFA_MIPS_advance_loc8:
9221 start += 8;
9222 break;
53c7db4b
KH
9223 case DW_CFA_GNU_args_size:
9224 LEB ();
9225 break;
53c7db4b
KH
9226 case DW_CFA_GNU_negative_offset_extended:
9227 reg = LEB (); LEB ();
9228 frame_need_space (fc, reg);
9229 fc->col_type[reg] = DW_CFA_undefined;
7036c0e1 9230
53c7db4b
KH
9231 default:
9232 break;
9233 }
9234 }
9235 start = tmp;
9236 }
a98cc2b2
AH
9237
9238 /* Now we know what registers are used, make a second pass over
9239 the chunk, this time actually printing out the info. */
9240
c47d488e
DD
9241 while (start < block_end)
9242 {
9243 unsigned op, opa;
9244 unsigned long ul, reg, roffs;
9245 long l, ofs;
9246 bfd_vma vma;
9247
b34976b6 9248 op = *start++;
c47d488e
DD
9249 opa = op & 0x3f;
9250 if (op & 0xc0)
9251 op &= 0xc0;
9252
53c7db4b
KH
9253 /* Warning: if you add any more cases to this switch, be
9254 sure to add them to the corresponding switch above. */
c47d488e
DD
9255 switch (op)
9256 {
9257 case DW_CFA_advance_loc:
31b6fca6 9258 if (do_debug_frames_interp)
53c7db4b 9259 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9260 else
53c7db4b
KH
9261 printf (" DW_CFA_advance_loc: %d to %08lx\n",
9262 opa * fc->code_factor,
31b6fca6 9263 fc->pc_begin + opa * fc->code_factor);
c47d488e
DD
9264 fc->pc_begin += opa * fc->code_factor;
9265 break;
9266
9267 case DW_CFA_offset:
c47d488e 9268 roffs = LEB ();
31b6fca6 9269 if (! do_debug_frames_interp)
53c7db4b 9270 printf (" DW_CFA_offset: r%d at cfa%+ld\n",
31b6fca6 9271 opa, roffs * fc->data_factor);
c47d488e
DD
9272 fc->col_type[opa] = DW_CFA_offset;
9273 fc->col_offset[opa] = roffs * fc->data_factor;
9274 break;
9275
9276 case DW_CFA_restore:
31b6fca6 9277 if (! do_debug_frames_interp)
53c7db4b 9278 printf (" DW_CFA_restore: r%d\n", opa);
c47d488e
DD
9279 fc->col_type[opa] = cie->col_type[opa];
9280 fc->col_offset[opa] = cie->col_offset[opa];
9281 break;
9282
9283 case DW_CFA_set_loc:
38fafa6d 9284 vma = get_encoded_value (start, fc->fde_encoding);
f1ef08cb
AM
9285 if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
9286 vma += section->sh_addr + (start - section_start);
31b6fca6
RH
9287 start += encoded_ptr_size;
9288 if (do_debug_frames_interp)
53c7db4b 9289 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9290 else
53c7db4b 9291 printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
c47d488e
DD
9292 fc->pc_begin = vma;
9293 break;
9294
9295 case DW_CFA_advance_loc1:
c47d488e 9296 ofs = byte_get (start, 1); start += 1;
31b6fca6 9297 if (do_debug_frames_interp)
53c7db4b 9298 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9299 else
53c7db4b
KH
9300 printf (" DW_CFA_advance_loc1: %ld to %08lx\n",
9301 ofs * fc->code_factor,
31b6fca6 9302 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
9303 fc->pc_begin += ofs * fc->code_factor;
9304 break;
9305
9306 case DW_CFA_advance_loc2:
c47d488e 9307 ofs = byte_get (start, 2); start += 2;
31b6fca6 9308 if (do_debug_frames_interp)
53c7db4b 9309 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9310 else
53c7db4b
KH
9311 printf (" DW_CFA_advance_loc2: %ld to %08lx\n",
9312 ofs * fc->code_factor,
31b6fca6 9313 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
9314 fc->pc_begin += ofs * fc->code_factor;
9315 break;
9316
9317 case DW_CFA_advance_loc4:
c47d488e 9318 ofs = byte_get (start, 4); start += 4;
31b6fca6 9319 if (do_debug_frames_interp)
53c7db4b 9320 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9321 else
53c7db4b
KH
9322 printf (" DW_CFA_advance_loc4: %ld to %08lx\n",
9323 ofs * fc->code_factor,
31b6fca6 9324 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
9325 fc->pc_begin += ofs * fc->code_factor;
9326 break;
9327
9328 case DW_CFA_offset_extended:
9329 reg = LEB ();
9330 roffs = LEB ();
31b6fca6 9331 if (! do_debug_frames_interp)
7036c0e1 9332 printf (" DW_CFA_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 9333 reg, roffs * fc->data_factor);
c47d488e
DD
9334 fc->col_type[reg] = DW_CFA_offset;
9335 fc->col_offset[reg] = roffs * fc->data_factor;
9336 break;
9337
9338 case DW_CFA_restore_extended:
9339 reg = LEB ();
31b6fca6 9340 if (! do_debug_frames_interp)
53c7db4b 9341 printf (" DW_CFA_restore_extended: r%ld\n", reg);
c47d488e
DD
9342 fc->col_type[reg] = cie->col_type[reg];
9343 fc->col_offset[reg] = cie->col_offset[reg];
9344 break;
9345
9346 case DW_CFA_undefined:
9347 reg = LEB ();
31b6fca6 9348 if (! do_debug_frames_interp)
53c7db4b 9349 printf (" DW_CFA_undefined: r%ld\n", reg);
c47d488e
DD
9350 fc->col_type[reg] = DW_CFA_undefined;
9351 fc->col_offset[reg] = 0;
9352 break;
9353
9354 case DW_CFA_same_value:
9355 reg = LEB ();
31b6fca6 9356 if (! do_debug_frames_interp)
53c7db4b 9357 printf (" DW_CFA_same_value: r%ld\n", reg);
c47d488e
DD
9358 fc->col_type[reg] = DW_CFA_same_value;
9359 fc->col_offset[reg] = 0;
9360 break;
9361
9362 case DW_CFA_register:
9363 reg = LEB ();
9364 roffs = LEB ();
31b6fca6 9365 if (! do_debug_frames_interp)
636fc387 9366 printf (" DW_CFA_register: r%ld in r%ld\n", reg, roffs);
c47d488e
DD
9367 fc->col_type[reg] = DW_CFA_register;
9368 fc->col_offset[reg] = roffs;
9369 break;
9370
9371 case DW_CFA_remember_state:
31b6fca6 9372 if (! do_debug_frames_interp)
53c7db4b 9373 printf (" DW_CFA_remember_state\n");
c47d488e
DD
9374 rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
9375 rs->ncols = fc->ncols;
a98cc2b2 9376 rs->col_type = (short int *) xmalloc (rs->ncols * sizeof (short int));
c47d488e
DD
9377 rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
9378 memcpy (rs->col_type, fc->col_type, rs->ncols);
9379 memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
9380 rs->next = remembered_state;
9381 remembered_state = rs;
9382 break;
9383
9384 case DW_CFA_restore_state:
31b6fca6 9385 if (! do_debug_frames_interp)
53c7db4b 9386 printf (" DW_CFA_restore_state\n");
c47d488e
DD
9387 rs = remembered_state;
9388 remembered_state = rs->next;
9389 frame_need_space (fc, rs->ncols-1);
9390 memcpy (fc->col_type, rs->col_type, rs->ncols);
9391 memcpy (fc->col_offset, rs->col_offset, rs->ncols * sizeof (int));
9392 free (rs->col_type);
9393 free (rs->col_offset);
9394 free (rs);
9395 break;
9396
9397 case DW_CFA_def_cfa:
9398 fc->cfa_reg = LEB ();
9399 fc->cfa_offset = LEB ();
63044634 9400 fc->cfa_exp = 0;
31b6fca6 9401 if (! do_debug_frames_interp)
53c7db4b 9402 printf (" DW_CFA_def_cfa: r%d ofs %d\n",
31b6fca6 9403 fc->cfa_reg, fc->cfa_offset);
c47d488e
DD
9404 break;
9405
9406 case DW_CFA_def_cfa_register:
9407 fc->cfa_reg = LEB ();
63044634 9408 fc->cfa_exp = 0;
31b6fca6 9409 if (! do_debug_frames_interp)
53c7db4b 9410 printf (" DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
c47d488e
DD
9411 break;
9412
9413 case DW_CFA_def_cfa_offset:
9414 fc->cfa_offset = LEB ();
31b6fca6 9415 if (! do_debug_frames_interp)
53c7db4b 9416 printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
c47d488e
DD
9417 break;
9418
9419 case DW_CFA_nop:
31b6fca6 9420 if (! do_debug_frames_interp)
53c7db4b 9421 printf (" DW_CFA_nop\n");
c47d488e
DD
9422 break;
9423
63044634
RH
9424 case DW_CFA_def_cfa_expression:
9425 ul = LEB ();
9426 if (! do_debug_frames_interp)
9427 {
9428 printf (" DW_CFA_def_cfa_expression (");
9429 decode_location_expression (start, addr_size, ul);
9430 printf (")\n");
9431 }
9432 fc->cfa_exp = 1;
9433 start += ul;
9434 break;
9435
9436 case DW_CFA_expression:
9437 reg = LEB ();
9438 ul = LEB ();
9439 if (! do_debug_frames_interp)
9440 {
9441 printf (" DW_CFA_expression: r%ld (", reg);
9442 decode_location_expression (start, addr_size, ul);
9443 printf (")\n");
9444 }
9445 fc->col_type[reg] = DW_CFA_expression;
9446 start += ul;
9447 break;
9448
91a106e6
L
9449 case DW_CFA_offset_extended_sf:
9450 reg = LEB ();
9451 l = SLEB ();
9452 frame_need_space (fc, reg);
9453 if (! do_debug_frames_interp)
9454 printf (" DW_CFA_offset_extended_sf: r%ld at cfa%+ld\n",
9455 reg, l * fc->data_factor);
9456 fc->col_type[reg] = DW_CFA_offset;
9457 fc->col_offset[reg] = l * fc->data_factor;
9458 break;
9459
9460 case DW_CFA_def_cfa_sf:
9461 fc->cfa_reg = LEB ();
9462 fc->cfa_offset = SLEB ();
63044634 9463 fc->cfa_exp = 0;
91a106e6
L
9464 if (! do_debug_frames_interp)
9465 printf (" DW_CFA_def_cfa_sf: r%d ofs %d\n",
9466 fc->cfa_reg, fc->cfa_offset);
9467 break;
9468
9469 case DW_CFA_def_cfa_offset_sf:
9470 fc->cfa_offset = SLEB ();
9471 if (! do_debug_frames_interp)
9472 printf (" DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset);
9473 break;
9474
63044634
RH
9475 case DW_CFA_MIPS_advance_loc8:
9476 ofs = byte_get (start, 8); start += 8;
9477 if (do_debug_frames_interp)
9478 frame_display_row (fc, &need_col_headers, &max_regs);
9479 else
9480 printf (" DW_CFA_MIPS_advance_loc8: %ld to %08lx\n",
9481 ofs * fc->code_factor,
9482 fc->pc_begin + ofs * fc->code_factor);
9483 fc->pc_begin += ofs * fc->code_factor;
9484 break;
9485
c47d488e 9486 case DW_CFA_GNU_window_save:
31b6fca6 9487 if (! do_debug_frames_interp)
53c7db4b 9488 printf (" DW_CFA_GNU_window_save\n");
c47d488e
DD
9489 break;
9490
c47d488e
DD
9491 case DW_CFA_GNU_args_size:
9492 ul = LEB ();
31b6fca6 9493 if (! do_debug_frames_interp)
53c7db4b 9494 printf (" DW_CFA_GNU_args_size: %ld\n", ul);
c47d488e
DD
9495 break;
9496
c47d488e
DD
9497 case DW_CFA_GNU_negative_offset_extended:
9498 reg = LEB ();
9499 l = - LEB ();
9500 frame_need_space (fc, reg);
31b6fca6 9501 if (! do_debug_frames_interp)
53c7db4b 9502 printf (" DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 9503 reg, l * fc->data_factor);
c47d488e
DD
9504 fc->col_type[reg] = DW_CFA_offset;
9505 fc->col_offset[reg] = l * fc->data_factor;
9506 break;
9507
9508 default:
9509 fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
9510 start = block_end;
9511 }
9512 }
9513
31b6fca6 9514 if (do_debug_frames_interp)
53c7db4b 9515 frame_display_row (fc, &need_col_headers, &max_regs);
c47d488e
DD
9516
9517 start = block_end;
9518 }
9519
9520 printf ("\n");
9521
9522 return 1;
9523}
9524
9525#undef GET
9526#undef LEB
9527#undef SLEB
252b5132
RH
9528
9529static int
9530display_debug_not_supported (section, start, file)
b34976b6
AM
9531 Elf_Internal_Shdr *section;
9532 unsigned char *start ATTRIBUTE_UNUSED;
9533 FILE *file ATTRIBUTE_UNUSED;
252b5132
RH
9534{
9535 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
9536 SECTION_NAME (section));
9537
9538 return 1;
9539}
9540
3590ea00
NC
9541/* Pre-scan the .debug_info section to record the size of address.
9542 When dumping the .debug_line, we use that size information, assuming
9543 that all compilation units have the same address size. */
9544static int
9545prescan_debug_info (section, start, file)
b34976b6
AM
9546 Elf_Internal_Shdr *section ATTRIBUTE_UNUSED;
9547 unsigned char *start;
9548 FILE *file ATTRIBUTE_UNUSED;
3590ea00 9549{
ee42cf8c
NC
9550 unsigned long length;
9551
9552 /* Read the first 4 bytes. For a 32-bit DWARF section, this will
9553 be the length. For a 64-bit DWARF section, it'll be the escape
9554 code 0xffffffff followed by an 8 byte length. For the purposes
9555 of this prescan, we don't care about the actual length, but the
9556 presence of the escape bytes does affect the location of the byte
9557 which describes the address size. */
9558 length = byte_get (start, 4);
3590ea00 9559
ee42cf8c
NC
9560 if (length == 0xffffffff)
9561 {
9562 /* For 64-bit DWARF, the 1-byte address_size field is 22 bytes
9563 from the start of the section. This is computed as follows:
3590ea00 9564
ee42cf8c
NC
9565 unit_length: 12 bytes
9566 version: 2 bytes
9567 debug_abbrev_offset: 8 bytes
9568 -----------------------------
9569 Total: 22 bytes */
9570
9571 debug_line_pointer_size = byte_get (start + 22, 1);
9572 }
9573 else
9574 {
9575 /* For 32-bit DWARF, the 1-byte address_size field is 10 bytes from
9576 the start of the section:
9577 unit_length: 4 bytes
9578 version: 2 bytes
9579 debug_abbrev_offset: 4 bytes
9580 -----------------------------
9581 Total: 10 bytes */
9582
9583 debug_line_pointer_size = byte_get (start + 10, 1);
9584 }
3590ea00
NC
9585 return 0;
9586}
9587
252b5132 9588 /* A structure containing the name of a debug section and a pointer
3590ea00
NC
9589 to a function that can decode it. The third field is a prescan
9590 function to be run over the section before displaying any of the
9591 sections. */
252b5132
RH
9592struct
9593{
b34976b6
AM
9594 const char *const name;
9595 int (*display) PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
9596 int (*prescan) PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
252b5132
RH
9597}
9598debug_displays[] =
9599{
b34976b6
AM
9600 { ".debug_abbrev", display_debug_abbrev, NULL },
9601 { ".debug_aranges", display_debug_aranges, NULL },
9602 { ".debug_frame", display_debug_frames, NULL },
9603 { ".debug_info", display_debug_info, prescan_debug_info },
9604 { ".debug_line", display_debug_lines, NULL },
9605 { ".debug_pubnames", display_debug_pubnames, NULL },
9606 { ".eh_frame", display_debug_frames, NULL },
9607 { ".debug_macinfo", display_debug_macinfo, NULL },
9608 { ".debug_str", display_debug_str, NULL },
9609 { ".debug_loc", display_debug_loc, NULL },
9610 { ".debug_pubtypes", display_debug_not_supported, NULL },
9611 { ".debug_ranges", display_debug_not_supported, NULL },
9612 { ".debug_static_func", display_debug_not_supported, NULL },
9613 { ".debug_static_vars", display_debug_not_supported, NULL },
9614 { ".debug_types", display_debug_not_supported, NULL },
9615 { ".debug_weaknames", display_debug_not_supported, NULL }
252b5132
RH
9616};
9617
9618static int
9619display_debug_section (section, file)
b34976b6
AM
9620 Elf_Internal_Shdr *section;
9621 FILE *file;
252b5132 9622{
b34976b6
AM
9623 char *name = SECTION_NAME (section);
9624 bfd_size_type length;
9625 unsigned char *start;
9626 int i;
252b5132
RH
9627
9628 length = section->sh_size;
9629 if (length == 0)
9630 {
9631 printf (_("\nSection '%s' has no debugging data.\n"), name);
9632 return 0;
9633 }
9634
0823fbca 9635 start = (unsigned char *) get_data (NULL, file, section->sh_offset, length,
a6e9f9df
AM
9636 _("debug section data"));
9637 if (!start)
9638 return 0;
252b5132
RH
9639
9640 /* See if we know how to display the contents of this section. */
09fd7e38 9641 if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
7036c0e1 9642 name = ".debug_info";
584da044 9643
252b5132
RH
9644 for (i = NUM_ELEM (debug_displays); i--;)
9645 if (strcmp (debug_displays[i].name, name) == 0)
9646 {
9647 debug_displays[i].display (section, start, file);
9648 break;
9649 }
9650
9651 if (i == -1)
2c71103e 9652 printf (_("Unrecognized debug section: %s\n"), name);
252b5132
RH
9653
9654 free (start);
9655
9656 /* If we loaded in the abbrev section at some point,
9657 we must release it here. */
261a45ad 9658 free_abbrevs ();
252b5132
RH
9659
9660 return 1;
9661}
9662
9663static int
9664process_section_contents (file)
b34976b6 9665 FILE *file;
252b5132 9666{
b34976b6
AM
9667 Elf_Internal_Shdr *section;
9668 unsigned int i;
252b5132
RH
9669
9670 if (! do_dump)
9671 return 1;
9672
3590ea00
NC
9673 /* Pre-scan the debug sections to find some debug information not
9674 present in some of them. For the .debug_line, we must find out the
9675 size of address (specified in .debug_info and .debug_aranges). */
9676 for (i = 0, section = section_headers;
9677 i < elf_header.e_shnum && i < num_dump_sects;
b34976b6 9678 i++, section++)
3590ea00 9679 {
b34976b6
AM
9680 char *name = SECTION_NAME (section);
9681 int j;
3590ea00
NC
9682
9683 if (section->sh_size == 0)
53c7db4b 9684 continue;
3590ea00
NC
9685
9686 /* See if there is some pre-scan operation for this section. */
9687 for (j = NUM_ELEM (debug_displays); j--;)
53c7db4b 9688 if (strcmp (debug_displays[j].name, name) == 0)
3590ea00
NC
9689 {
9690 if (debug_displays[j].prescan != NULL)
9691 {
b34976b6
AM
9692 bfd_size_type length;
9693 unsigned char *start;
3590ea00
NC
9694
9695 length = section->sh_size;
a6e9f9df 9696 start = ((unsigned char *)
0823fbca 9697 get_data (NULL, file, section->sh_offset, length,
a6e9f9df
AM
9698 _("debug section data")));
9699 if (!start)
9700 return 0;
3590ea00
NC
9701
9702 debug_displays[j].prescan (section, start, file);
9703 free (start);
9704 }
103f02d3 9705
53c7db4b
KH
9706 break;
9707 }
3590ea00
NC
9708 }
9709
252b5132 9710 for (i = 0, section = section_headers;
3590ea00 9711 i < elf_header.e_shnum && i < num_dump_sects;
b34976b6 9712 i++, section++)
252b5132
RH
9713 {
9714#ifdef SUPPORT_DISASSEMBLY
9715 if (dump_sects[i] & DISASS_DUMP)
9716 disassemble_section (section, file);
9717#endif
9718 if (dump_sects[i] & HEX_DUMP)
9719 dump_section (section, file);
9720
9721 if (dump_sects[i] & DEBUG_DUMP)
9722 display_debug_section (section, file);
9723 }
9724
9725 if (i < num_dump_sects)
9726 warn (_("Some sections were not dumped because they do not exist!\n"));
9727
9728 return 1;
9729}
9730
9731static void
9732process_mips_fpe_exception (mask)
9733 int mask;
9734{
9735 if (mask)
9736 {
9737 int first = 1;
9738 if (mask & OEX_FPU_INEX)
9739 fputs ("INEX", stdout), first = 0;
9740 if (mask & OEX_FPU_UFLO)
9741 printf ("%sUFLO", first ? "" : "|"), first = 0;
9742 if (mask & OEX_FPU_OFLO)
9743 printf ("%sOFLO", first ? "" : "|"), first = 0;
9744 if (mask & OEX_FPU_DIV0)
9745 printf ("%sDIV0", first ? "" : "|"), first = 0;
9746 if (mask & OEX_FPU_INVAL)
9747 printf ("%sINVAL", first ? "" : "|");
9748 }
9749 else
9750 fputs ("0", stdout);
9751}
9752
9753static int
9754process_mips_specific (file)
b34976b6 9755 FILE *file;
252b5132 9756{
b34976b6 9757 Elf_Internal_Dyn *entry;
252b5132
RH
9758 size_t liblist_offset = 0;
9759 size_t liblistno = 0;
9760 size_t conflictsno = 0;
9761 size_t options_offset = 0;
9762 size_t conflicts_offset = 0;
9763
9764 /* We have a lot of special sections. Thanks SGI! */
9765 if (dynamic_segment == NULL)
9766 /* No information available. */
9767 return 0;
9768
9769 for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
9770 switch (entry->d_tag)
9771 {
9772 case DT_MIPS_LIBLIST:
d93f0186
NC
9773 liblist_offset
9774 = offset_from_vma (file, entry->d_un.d_val,
9775 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
9776 break;
9777 case DT_MIPS_LIBLISTNO:
9778 liblistno = entry->d_un.d_val;
9779 break;
9780 case DT_MIPS_OPTIONS:
d93f0186 9781 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
9782 break;
9783 case DT_MIPS_CONFLICT:
d93f0186
NC
9784 conflicts_offset
9785 = offset_from_vma (file, entry->d_un.d_val,
9786 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
9787 break;
9788 case DT_MIPS_CONFLICTNO:
9789 conflictsno = entry->d_un.d_val;
9790 break;
9791 default:
9792 break;
9793 }
9794
9795 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
9796 {
b34976b6 9797 Elf32_External_Lib *elib;
252b5132
RH
9798 size_t cnt;
9799
a6e9f9df
AM
9800 elib = ((Elf32_External_Lib *)
9801 get_data (NULL, file, liblist_offset,
9802 liblistno * sizeof (Elf32_External_Lib),
9803 _("liblist")));
9804 if (elib)
252b5132 9805 {
a6e9f9df
AM
9806 printf ("\nSection '.liblist' contains %lu entries:\n",
9807 (unsigned long) liblistno);
9808 fputs (" Library Time Stamp Checksum Version Flags\n",
9809 stdout);
9810
9811 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 9812 {
a6e9f9df
AM
9813 Elf32_Lib liblist;
9814 time_t time;
9815 char timebuf[20];
b34976b6 9816 struct tm *tmp;
a6e9f9df
AM
9817
9818 liblist.l_name = BYTE_GET (elib[cnt].l_name);
9819 time = BYTE_GET (elib[cnt].l_time_stamp);
9820 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
9821 liblist.l_version = BYTE_GET (elib[cnt].l_version);
9822 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
9823
9824 tmp = gmtime (&time);
9825 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
9826 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9827 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
9828
31104126
NC
9829 printf ("%3lu: ", (unsigned long) cnt);
9830 print_symbol (20, dynamic_strings + liblist.l_name);
9831 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
9832 liblist.l_version);
a6e9f9df
AM
9833
9834 if (liblist.l_flags == 0)
9835 puts (" NONE");
9836 else
9837 {
9838 static const struct
252b5132 9839 {
b34976b6 9840 const char *name;
a6e9f9df 9841 int bit;
252b5132 9842 }
a6e9f9df
AM
9843 l_flags_vals[] =
9844 {
9845 { " EXACT_MATCH", LL_EXACT_MATCH },
9846 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
9847 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
9848 { " EXPORTS", LL_EXPORTS },
9849 { " DELAY_LOAD", LL_DELAY_LOAD },
9850 { " DELTA", LL_DELTA }
9851 };
9852 int flags = liblist.l_flags;
9853 size_t fcnt;
9854
9855 for (fcnt = 0;
9856 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
9857 ++fcnt)
9858 if ((flags & l_flags_vals[fcnt].bit) != 0)
9859 {
9860 fputs (l_flags_vals[fcnt].name, stdout);
9861 flags ^= l_flags_vals[fcnt].bit;
9862 }
9863 if (flags != 0)
9864 printf (" %#x", (unsigned int) flags);
252b5132 9865
a6e9f9df
AM
9866 puts ("");
9867 }
252b5132 9868 }
252b5132 9869
a6e9f9df
AM
9870 free (elib);
9871 }
252b5132
RH
9872 }
9873
9874 if (options_offset != 0)
9875 {
b34976b6
AM
9876 Elf_External_Options *eopt;
9877 Elf_Internal_Shdr *sect = section_headers;
9878 Elf_Internal_Options *iopt;
9879 Elf_Internal_Options *option;
252b5132
RH
9880 size_t offset;
9881 int cnt;
9882
9883 /* Find the section header so that we get the size. */
9884 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 9885 ++sect;
252b5132 9886
a6e9f9df
AM
9887 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset,
9888 sect->sh_size, _("options"));
9889 if (eopt)
252b5132 9890 {
a6e9f9df 9891 iopt = ((Elf_Internal_Options *)
b34976b6 9892 malloc ((sect->sh_size / sizeof (eopt)) * sizeof (*iopt)));
a6e9f9df
AM
9893 if (iopt == NULL)
9894 {
9895 error (_("Out of memory"));
9896 return 0;
9897 }
76da6bbe 9898
a6e9f9df
AM
9899 offset = cnt = 0;
9900 option = iopt;
252b5132 9901
a6e9f9df
AM
9902 while (offset < sect->sh_size)
9903 {
b34976b6 9904 Elf_External_Options *eoption;
252b5132 9905
a6e9f9df 9906 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 9907
a6e9f9df
AM
9908 option->kind = BYTE_GET (eoption->kind);
9909 option->size = BYTE_GET (eoption->size);
9910 option->section = BYTE_GET (eoption->section);
9911 option->info = BYTE_GET (eoption->info);
76da6bbe 9912
a6e9f9df 9913 offset += option->size;
252b5132 9914
a6e9f9df
AM
9915 ++option;
9916 ++cnt;
9917 }
252b5132 9918
a6e9f9df
AM
9919 printf (_("\nSection '%s' contains %d entries:\n"),
9920 SECTION_NAME (sect), cnt);
76da6bbe 9921
a6e9f9df 9922 option = iopt;
252b5132 9923
a6e9f9df 9924 while (cnt-- > 0)
252b5132 9925 {
a6e9f9df
AM
9926 size_t len;
9927
9928 switch (option->kind)
252b5132 9929 {
a6e9f9df
AM
9930 case ODK_NULL:
9931 /* This shouldn't happen. */
9932 printf (" NULL %d %lx", option->section, option->info);
9933 break;
9934 case ODK_REGINFO:
9935 printf (" REGINFO ");
9936 if (elf_header.e_machine == EM_MIPS)
9937 {
9938 /* 32bit form. */
b34976b6
AM
9939 Elf32_External_RegInfo *ereg;
9940 Elf32_RegInfo reginfo;
a6e9f9df
AM
9941
9942 ereg = (Elf32_External_RegInfo *) (option + 1);
9943 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
9944 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
9945 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
9946 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
9947 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
9948 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
9949
9950 printf ("GPR %08lx GP 0x%lx\n",
9951 reginfo.ri_gprmask,
9952 (unsigned long) reginfo.ri_gp_value);
9953 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
9954 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
9955 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
9956 }
9957 else
9958 {
9959 /* 64 bit form. */
b34976b6 9960 Elf64_External_RegInfo *ereg;
a6e9f9df
AM
9961 Elf64_Internal_RegInfo reginfo;
9962
9963 ereg = (Elf64_External_RegInfo *) (option + 1);
9964 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
9965 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
9966 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
9967 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
9968 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
9969 reginfo.ri_gp_value = BYTE_GET8 (ereg->ri_gp_value);
9970
9971 printf ("GPR %08lx GP 0x",
9972 reginfo.ri_gprmask);
9973 printf_vma (reginfo.ri_gp_value);
9974 printf ("\n");
9975
9976 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
9977 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
9978 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
9979 }
9980 ++option;
9981 continue;
9982 case ODK_EXCEPTIONS:
9983 fputs (" EXCEPTIONS fpe_min(", stdout);
9984 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
9985 fputs (") fpe_max(", stdout);
9986 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
9987 fputs (")", stdout);
9988
9989 if (option->info & OEX_PAGE0)
9990 fputs (" PAGE0", stdout);
9991 if (option->info & OEX_SMM)
9992 fputs (" SMM", stdout);
9993 if (option->info & OEX_FPDBUG)
9994 fputs (" FPDBUG", stdout);
9995 if (option->info & OEX_DISMISS)
9996 fputs (" DISMISS", stdout);
9997 break;
9998 case ODK_PAD:
9999 fputs (" PAD ", stdout);
10000 if (option->info & OPAD_PREFIX)
10001 fputs (" PREFIX", stdout);
10002 if (option->info & OPAD_POSTFIX)
10003 fputs (" POSTFIX", stdout);
10004 if (option->info & OPAD_SYMBOL)
10005 fputs (" SYMBOL", stdout);
10006 break;
10007 case ODK_HWPATCH:
10008 fputs (" HWPATCH ", stdout);
10009 if (option->info & OHW_R4KEOP)
10010 fputs (" R4KEOP", stdout);
10011 if (option->info & OHW_R8KPFETCH)
10012 fputs (" R8KPFETCH", stdout);
10013 if (option->info & OHW_R5KEOP)
10014 fputs (" R5KEOP", stdout);
10015 if (option->info & OHW_R5KCVTL)
10016 fputs (" R5KCVTL", stdout);
10017 break;
10018 case ODK_FILL:
10019 fputs (" FILL ", stdout);
10020 /* XXX Print content of info word? */
10021 break;
10022 case ODK_TAGS:
10023 fputs (" TAGS ", stdout);
10024 /* XXX Print content of info word? */
10025 break;
10026 case ODK_HWAND:
10027 fputs (" HWAND ", stdout);
10028 if (option->info & OHWA0_R4KEOP_CHECKED)
10029 fputs (" R4KEOP_CHECKED", stdout);
10030 if (option->info & OHWA0_R4KEOP_CLEAN)
10031 fputs (" R4KEOP_CLEAN", stdout);
10032 break;
10033 case ODK_HWOR:
10034 fputs (" HWOR ", stdout);
10035 if (option->info & OHWA0_R4KEOP_CHECKED)
10036 fputs (" R4KEOP_CHECKED", stdout);
10037 if (option->info & OHWA0_R4KEOP_CLEAN)
10038 fputs (" R4KEOP_CLEAN", stdout);
10039 break;
10040 case ODK_GP_GROUP:
10041 printf (" GP_GROUP %#06lx self-contained %#06lx",
10042 option->info & OGP_GROUP,
10043 (option->info & OGP_SELF) >> 16);
10044 break;
10045 case ODK_IDENT:
10046 printf (" IDENT %#06lx self-contained %#06lx",
10047 option->info & OGP_GROUP,
10048 (option->info & OGP_SELF) >> 16);
10049 break;
10050 default:
10051 /* This shouldn't happen. */
10052 printf (" %3d ??? %d %lx",
10053 option->kind, option->section, option->info);
10054 break;
252b5132 10055 }
a6e9f9df 10056
b34976b6 10057 len = sizeof (*eopt);
a6e9f9df
AM
10058 while (len < option->size)
10059 if (((char *) option)[len] >= ' '
10060 && ((char *) option)[len] < 0x7f)
10061 printf ("%c", ((char *) option)[len++]);
10062 else
10063 printf ("\\%03o", ((char *) option)[len++]);
10064
10065 fputs ("\n", stdout);
252b5132 10066 ++option;
252b5132
RH
10067 }
10068
a6e9f9df 10069 free (eopt);
252b5132 10070 }
252b5132
RH
10071 }
10072
10073 if (conflicts_offset != 0 && conflictsno != 0)
10074 {
b34976b6 10075 Elf32_Conflict *iconf;
252b5132
RH
10076 size_t cnt;
10077
10078 if (dynamic_symbols == NULL)
10079 {
3a1a2036 10080 error (_("conflict list found without a dynamic symbol table"));
252b5132
RH
10081 return 0;
10082 }
10083
b34976b6 10084 iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (*iconf));
252b5132
RH
10085 if (iconf == NULL)
10086 {
10087 error (_("Out of memory"));
10088 return 0;
10089 }
10090
9ea033b2 10091 if (is_32bit_elf)
252b5132 10092 {
b34976b6 10093 Elf32_External_Conflict *econf32;
a6e9f9df
AM
10094
10095 econf32 = ((Elf32_External_Conflict *)
10096 get_data (NULL, file, conflicts_offset,
b34976b6 10097 conflictsno * sizeof (*econf32),
a6e9f9df
AM
10098 _("conflict")));
10099 if (!econf32)
10100 return 0;
252b5132
RH
10101
10102 for (cnt = 0; cnt < conflictsno; ++cnt)
10103 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
10104
10105 free (econf32);
252b5132
RH
10106 }
10107 else
10108 {
b34976b6 10109 Elf64_External_Conflict *econf64;
a6e9f9df
AM
10110
10111 econf64 = ((Elf64_External_Conflict *)
10112 get_data (NULL, file, conflicts_offset,
b34976b6 10113 conflictsno * sizeof (*econf64),
a6e9f9df
AM
10114 _("conflict")));
10115 if (!econf64)
10116 return 0;
252b5132
RH
10117
10118 for (cnt = 0; cnt < conflictsno; ++cnt)
10119 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
10120
10121 free (econf64);
252b5132
RH
10122 }
10123
410f7a12
L
10124 printf (_("\nSection '.conflict' contains %ld entries:\n"),
10125 (long) conflictsno);
252b5132
RH
10126 puts (_(" Num: Index Value Name"));
10127
10128 for (cnt = 0; cnt < conflictsno; ++cnt)
10129 {
b34976b6 10130 Elf_Internal_Sym *psym = & dynamic_symbols[iconf[cnt]];
252b5132 10131
b34976b6 10132 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 10133 print_vma (psym->st_value, FULL_HEX);
31104126
NC
10134 putchar (' ');
10135 print_symbol (25, dynamic_strings + psym->st_name);
10136 putchar ('\n');
252b5132
RH
10137 }
10138
252b5132
RH
10139 free (iconf);
10140 }
10141
10142 return 1;
10143}
10144
047b2264
JJ
10145static int
10146process_gnu_liblist (file)
b34976b6 10147 FILE *file;
047b2264 10148{
b34976b6
AM
10149 Elf_Internal_Shdr *section, *string_sec;
10150 Elf32_External_Lib *elib;
10151 char *strtab;
047b2264
JJ
10152 size_t cnt;
10153 unsigned i;
10154
10155 if (! do_arch)
10156 return 0;
10157
10158 for (i = 0, section = section_headers;
10159 i < elf_header.e_shnum;
b34976b6 10160 i++, section++)
047b2264
JJ
10161 {
10162 switch (section->sh_type)
10163 {
10164 case SHT_GNU_LIBLIST:
10165 elib = ((Elf32_External_Lib *)
10166 get_data (NULL, file, section->sh_offset, section->sh_size,
10167 _("liblist")));
10168
10169 if (elib == NULL)
10170 break;
10171 string_sec = SECTION_HEADER (section->sh_link);
10172
10173 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
10174 string_sec->sh_size,
10175 _("liblist string table"));
10176
10177 if (strtab == NULL
10178 || section->sh_entsize != sizeof (Elf32_External_Lib))
10179 {
10180 free (elib);
10181 break;
10182 }
10183
10184 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
10185 SECTION_NAME (section),
10186 (long) (section->sh_size / sizeof (Elf32_External_Lib)));
10187
10188 puts (" Library Time Stamp Checksum Version Flags");
10189
10190 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
10191 ++cnt)
10192 {
10193 Elf32_Lib liblist;
10194 time_t time;
10195 char timebuf[20];
b34976b6 10196 struct tm *tmp;
047b2264
JJ
10197
10198 liblist.l_name = BYTE_GET (elib[cnt].l_name);
10199 time = BYTE_GET (elib[cnt].l_time_stamp);
10200 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
10201 liblist.l_version = BYTE_GET (elib[cnt].l_version);
10202 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
10203
10204 tmp = gmtime (&time);
10205 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
10206 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10207 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
10208
10209 printf ("%3lu: ", (unsigned long) cnt);
10210 if (do_wide)
10211 printf ("%-20s", strtab + liblist.l_name);
10212 else
10213 printf ("%-20.20s", strtab + liblist.l_name);
10214 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
10215 liblist.l_version, liblist.l_flags);
10216 }
10217
10218 free (elib);
10219 }
10220 }
10221
10222 return 1;
10223}
10224
9437c45b 10225static const char *
779fe533
NC
10226get_note_type (e_type)
10227 unsigned e_type;
10228{
10229 static char buff[64];
103f02d3 10230
779fe533
NC
10231 switch (e_type)
10232 {
10233 case NT_PRSTATUS: return _("NT_PRSTATUS (prstatus structure)");
10234 case NT_FPREGSET: return _("NT_FPREGSET (floating point registers)");
b34976b6
AM
10235 case NT_PRPSINFO: return _("NT_PRPSINFO (prpsinfo structure)");
10236 case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
10237 case NT_PRXFPREG: return _("NT_PRXFPREG (user_xfpregs structure)");
779fe533
NC
10238 case NT_PSTATUS: return _("NT_PSTATUS (pstatus structure)");
10239 case NT_FPREGS: return _("NT_FPREGS (floating point registers)");
10240 case NT_PSINFO: return _("NT_PSINFO (psinfo structure)");
10241 case NT_LWPSTATUS: return _("NT_LWPSTATUS (lwpstatus_t structure)");
10242 case NT_LWPSINFO: return _("NT_LWPSINFO (lwpsinfo_t structure)");
3a1a2036 10243 case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus structure)");
779fe533
NC
10244 default:
10245 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
10246 return buff;
10247 }
10248}
10249
9437c45b
JT
10250static const char *
10251get_netbsd_elfcore_note_type (e_type)
10252 unsigned e_type;
10253{
10254 static char buff[64];
10255
b4db1224 10256 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
10257 {
10258 /* NetBSD core "procinfo" structure. */
10259 return _("NetBSD procinfo structure");
10260 }
10261
10262 /* As of Jan 2002 there are no other machine-independent notes
10263 defined for NetBSD core files. If the note type is less
10264 than the start of the machine-dependent note types, we don't
10265 understand it. */
10266
b4db1224 10267 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b
JT
10268 {
10269 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
10270 return buff;
10271 }
10272
10273 switch (elf_header.e_machine)
10274 {
10275 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
10276 and PT_GETFPREGS == mach+2. */
10277
10278 case EM_OLD_ALPHA:
10279 case EM_ALPHA:
10280 case EM_SPARC:
10281 case EM_SPARC32PLUS:
10282 case EM_SPARCV9:
10283 switch (e_type)
10284 {
b4db1224
JT
10285 case NT_NETBSDCORE_FIRSTMACH+0:
10286 return _("PT_GETREGS (reg structure)");
10287 case NT_NETBSDCORE_FIRSTMACH+2:
10288 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
10289 default:
10290 break;
10291 }
10292 break;
10293
10294 /* On all other arch's, PT_GETREGS == mach+1 and
10295 PT_GETFPREGS == mach+3. */
10296 default:
10297 switch (e_type)
10298 {
b4db1224
JT
10299 case NT_NETBSDCORE_FIRSTMACH+1:
10300 return _("PT_GETREGS (reg structure)");
10301 case NT_NETBSDCORE_FIRSTMACH+3:
10302 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
10303 default:
10304 break;
10305 }
10306 }
10307
b4db1224 10308 sprintf (buff, _("PT_FIRSTMACH+%d"), e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
10309 return buff;
10310}
10311
6d118b09
NC
10312/* Note that by the ELF standard, the name field is already null byte
10313 terminated, and namesz includes the terminating null byte.
10314 I.E. the value of namesz for the name "FSF" is 4.
10315
e3c8793a 10316 If the value of namesz is zero, there is no name present. */
779fe533
NC
10317static int
10318process_note (pnote)
b34976b6 10319 Elf_Internal_Note *pnote;
779fe533 10320{
9437c45b
JT
10321 const char *nt;
10322
10323 if (pnote->namesz == 0)
10324 {
10325 /* If there is no note name, then use the default set of
10326 note type strings. */
10327 nt = get_note_type (pnote->type);
10328 }
10329 else if (strncmp (pnote->namedata, "NetBSD-CORE", 11) == 0)
10330 {
10331 /* NetBSD-specific core file notes. */
10332 nt = get_netbsd_elfcore_note_type (pnote->type);
10333 }
10334 else
10335 {
10336 /* Don't recognize this note name; just use the default set of
10337 note type strings. */
10338 nt = get_note_type (pnote->type);
10339 }
10340
103f02d3 10341 printf (" %s\t\t0x%08lx\t%s\n",
6d118b09 10342 pnote->namesz ? pnote->namedata : "(NONE)",
9437c45b 10343 pnote->descsz, nt);
779fe533
NC
10344 return 1;
10345}
10346
6d118b09 10347
779fe533
NC
10348static int
10349process_corefile_note_segment (file, offset, length)
b34976b6 10350 FILE *file;
f7a99963
NC
10351 bfd_vma offset;
10352 bfd_vma length;
779fe533 10353{
b34976b6
AM
10354 Elf_External_Note *pnotes;
10355 Elf_External_Note *external;
10356 int res = 1;
103f02d3 10357
779fe533
NC
10358 if (length <= 0)
10359 return 0;
103f02d3 10360
a6e9f9df
AM
10361 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, length,
10362 _("notes"));
10363 if (!pnotes)
10364 return 0;
779fe533 10365
103f02d3 10366 external = pnotes;
103f02d3 10367
305c7206 10368 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 10369 (unsigned long) offset, (unsigned long) length);
779fe533 10370 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 10371
6d118b09 10372 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 10373 {
b34976b6
AM
10374 Elf_External_Note *next;
10375 Elf_Internal_Note inote;
10376 char *temp = NULL;
6d118b09
NC
10377
10378 inote.type = BYTE_GET (external->type);
10379 inote.namesz = BYTE_GET (external->namesz);
10380 inote.namedata = external->name;
10381 inote.descsz = BYTE_GET (external->descsz);
10382 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
10383 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 10384
3e55a963
NC
10385 next = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
10386
10387 if (((char *) next) > (((char *) pnotes) + length))
10388 {
10389 warn (_("corrupt note found at offset %x into core notes\n"),
10390 ((char *) external) - ((char *) pnotes));
10391 warn (_(" type: %x, namesize: %08lx, descsize: %08lx\n"),
10392 inote.type, inote.namesz, inote.descsz);
10393 break;
10394 }
10395
10396 external = next;
6d118b09
NC
10397
10398 /* Verify that name is null terminated. It appears that at least
10399 one version of Linux (RedHat 6.0) generates corefiles that don't
10400 comply with the ELF spec by failing to include the null byte in
10401 namesz. */
10402 if (inote.namedata[inote.namesz] != '\0')
10403 {
10404 temp = malloc (inote.namesz + 1);
76da6bbe 10405
6d118b09
NC
10406 if (temp == NULL)
10407 {
10408 error (_("Out of memory\n"));
10409 res = 0;
10410 break;
10411 }
76da6bbe 10412
6d118b09
NC
10413 strncpy (temp, inote.namedata, inote.namesz);
10414 temp[inote.namesz] = 0;
76da6bbe 10415
6d118b09
NC
10416 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
10417 inote.namedata = temp;
10418 }
10419
10420 res &= process_note (& inote);
103f02d3 10421
6d118b09
NC
10422 if (temp != NULL)
10423 {
10424 free (temp);
10425 temp = NULL;
10426 }
779fe533
NC
10427 }
10428
10429 free (pnotes);
103f02d3 10430
779fe533
NC
10431 return res;
10432}
10433
10434static int
10435process_corefile_note_segments (file)
b34976b6 10436 FILE *file;
779fe533 10437{
b34976b6
AM
10438 Elf_Internal_Phdr *segment;
10439 unsigned int i;
10440 int res = 1;
103f02d3 10441
d93f0186 10442 if (! get_program_headers (file))
779fe533 10443 return 0;
103f02d3 10444
779fe533
NC
10445 for (i = 0, segment = program_headers;
10446 i < elf_header.e_phnum;
b34976b6 10447 i++, segment++)
779fe533
NC
10448 {
10449 if (segment->p_type == PT_NOTE)
103f02d3 10450 res &= process_corefile_note_segment (file,
30800947
NC
10451 (bfd_vma) segment->p_offset,
10452 (bfd_vma) segment->p_filesz);
779fe533 10453 }
103f02d3 10454
779fe533
NC
10455 return res;
10456}
10457
10458static int
10459process_corefile_contents (file)
b34976b6 10460 FILE *file;
779fe533
NC
10461{
10462 /* If we have not been asked to display the notes then do nothing. */
10463 if (! do_notes)
10464 return 1;
103f02d3 10465
779fe533
NC
10466 /* If file is not a core file then exit. */
10467 if (elf_header.e_type != ET_CORE)
10468 return 1;
103f02d3 10469
779fe533
NC
10470 /* No program headers means no NOTE segment. */
10471 if (elf_header.e_phnum == 0)
10472 {
10473 printf (_("No note segments present in the core file.\n"));
10474 return 1;
10475 }
10476
10477 return process_corefile_note_segments (file);
10478}
10479
252b5132
RH
10480static int
10481process_arch_specific (file)
b34976b6 10482 FILE *file;
252b5132 10483{
a952a375
NC
10484 if (! do_arch)
10485 return 1;
10486
252b5132
RH
10487 switch (elf_header.e_machine)
10488 {
10489 case EM_MIPS:
4fe85591 10490 case EM_MIPS_RS3_LE:
252b5132
RH
10491 return process_mips_specific (file);
10492 break;
10493 default:
10494 break;
10495 }
10496 return 1;
10497}
10498
10499static int
10500get_file_header (file)
b34976b6 10501 FILE *file;
252b5132 10502{
9ea033b2
NC
10503 /* Read in the identity array. */
10504 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
10505 return 0;
10506
9ea033b2 10507 /* Determine how to read the rest of the header. */
b34976b6 10508 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
10509 {
10510 default: /* fall through */
10511 case ELFDATANONE: /* fall through */
adab8cdc
AO
10512 case ELFDATA2LSB:
10513 byte_get = byte_get_little_endian;
10514 byte_put = byte_put_little_endian;
10515 break;
10516 case ELFDATA2MSB:
10517 byte_get = byte_get_big_endian;
10518 byte_put = byte_put_big_endian;
10519 break;
9ea033b2
NC
10520 }
10521
10522 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 10523 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
10524
10525 /* Read in the rest of the header. */
10526 if (is_32bit_elf)
10527 {
10528 Elf32_External_Ehdr ehdr32;
252b5132 10529
9ea033b2
NC
10530 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
10531 return 0;
103f02d3 10532
9ea033b2
NC
10533 elf_header.e_type = BYTE_GET (ehdr32.e_type);
10534 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
10535 elf_header.e_version = BYTE_GET (ehdr32.e_version);
10536 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
10537 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
10538 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
10539 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
10540 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
10541 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
10542 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
10543 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
10544 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
10545 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
10546 }
252b5132 10547 else
9ea033b2
NC
10548 {
10549 Elf64_External_Ehdr ehdr64;
a952a375
NC
10550
10551 /* If we have been compiled with sizeof (bfd_vma) == 4, then
10552 we will not be able to cope with the 64bit data found in
10553 64 ELF files. Detect this now and abort before we start
10554 overwritting things. */
10555 if (sizeof (bfd_vma) < 8)
10556 {
e3c8793a
NC
10557 error (_("This instance of readelf has been built without support for a\n\
1055864 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
10559 return 0;
10560 }
103f02d3 10561
9ea033b2
NC
10562 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
10563 return 0;
103f02d3 10564
9ea033b2
NC
10565 elf_header.e_type = BYTE_GET (ehdr64.e_type);
10566 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
10567 elf_header.e_version = BYTE_GET (ehdr64.e_version);
10568 elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry);
10569 elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff);
10570 elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff);
10571 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
10572 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
10573 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
10574 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
10575 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
10576 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
10577 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
10578 }
252b5132 10579
7ece0d85
JJ
10580 if (elf_header.e_shoff)
10581 {
10582 /* There may be some extensions in the first section header. Don't
10583 bomb if we can't read it. */
10584 if (is_32bit_elf)
10585 get_32bit_section_headers (file, 1);
10586 else
10587 get_64bit_section_headers (file, 1);
10588 }
560f3c1c 10589
252b5132
RH
10590 return 1;
10591}
10592
ff78d6d6 10593static int
252b5132 10594process_file (file_name)
b34976b6 10595 char *file_name;
252b5132 10596{
b34976b6
AM
10597 FILE *file;
10598 struct stat statbuf;
252b5132
RH
10599 unsigned int i;
10600
10601 if (stat (file_name, & statbuf) < 0)
10602 {
10603 error (_("Cannot stat input file %s.\n"), file_name);
ff78d6d6 10604 return 1;
252b5132
RH
10605 }
10606
10607 file = fopen (file_name, "rb");
10608 if (file == NULL)
10609 {
10610 error (_("Input file %s not found.\n"), file_name);
ff78d6d6 10611 return 1;
252b5132
RH
10612 }
10613
10614 if (! get_file_header (file))
10615 {
10616 error (_("%s: Failed to read file header\n"), file_name);
10617 fclose (file);
ff78d6d6 10618 return 1;
252b5132
RH
10619 }
10620
10621 /* Initialise per file variables. */
10622 for (i = NUM_ELEM (version_info); i--;)
10623 version_info[i] = 0;
10624
10625 for (i = NUM_ELEM (dynamic_info); i--;)
10626 dynamic_info[i] = 0;
10627
10628 /* Process the file. */
10629 if (show_name)
10630 printf (_("\nFile: %s\n"), file_name);
10631
10632 if (! process_file_header ())
10633 {
10634 fclose (file);
ff78d6d6 10635 return 1;
252b5132
RH
10636 }
10637
2f62977e
NC
10638 if (! process_section_headers (file))
10639 {
10640 /* Without loaded section headers we
10641 cannot process lots of things. */
10642 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 10643
2f62977e
NC
10644 if (! do_using_dynamic)
10645 do_syms = do_reloc = 0;
10646 }
252b5132 10647
2f62977e
NC
10648 if (process_program_headers (file))
10649 process_dynamic_segment (file);
252b5132
RH
10650
10651 process_relocs (file);
10652
4d6ed7c8
NC
10653 process_unwind (file);
10654
252b5132
RH
10655 process_symbol_table (file);
10656
10657 process_syminfo (file);
10658
10659 process_version_sections (file);
10660
10661 process_section_contents (file);
103f02d3 10662
779fe533 10663 process_corefile_contents (file);
103f02d3 10664
047b2264
JJ
10665 process_gnu_liblist (file);
10666
252b5132
RH
10667 process_arch_specific (file);
10668
10669 fclose (file);
10670
d93f0186
NC
10671 if (program_headers)
10672 {
10673 free (program_headers);
10674 program_headers = NULL;
10675 }
10676
252b5132
RH
10677 if (section_headers)
10678 {
10679 free (section_headers);
10680 section_headers = NULL;
10681 }
10682
10683 if (string_table)
10684 {
10685 free (string_table);
10686 string_table = NULL;
d40ac9bd 10687 string_table_length = 0;
252b5132
RH
10688 }
10689
10690 if (dynamic_strings)
10691 {
10692 free (dynamic_strings);
10693 dynamic_strings = NULL;
10694 }
10695
10696 if (dynamic_symbols)
10697 {
10698 free (dynamic_symbols);
10699 dynamic_symbols = NULL;
19936277 10700 num_dynamic_syms = 0;
252b5132
RH
10701 }
10702
10703 if (dynamic_syminfo)
10704 {
10705 free (dynamic_syminfo);
10706 dynamic_syminfo = NULL;
10707 }
ff78d6d6
L
10708
10709 return 0;
252b5132
RH
10710}
10711
10712#ifdef SUPPORT_DISASSEMBLY
10713/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 10714 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 10715 symbols. */
252b5132
RH
10716
10717void
b34976b6 10718print_address (unsigned int addr, FILE *outfile)
252b5132
RH
10719{
10720 fprintf (outfile,"0x%8.8x", addr);
10721}
10722
e3c8793a 10723/* Needed by the i386 disassembler. */
252b5132
RH
10724void
10725db_task_printsym (unsigned int addr)
10726{
10727 print_address (addr, stderr);
10728}
10729#endif
10730
e414a165
NC
10731int main PARAMS ((int, char **));
10732
252b5132
RH
10733int
10734main (argc, argv)
b34976b6
AM
10735 int argc;
10736 char **argv;
252b5132 10737{
ff78d6d6 10738 int err;
59f14fc0
AS
10739 char *cmdline_dump_sects = NULL;
10740 unsigned num_cmdline_dump_sects = 0;
ff78d6d6 10741
252b5132
RH
10742#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
10743 setlocale (LC_MESSAGES, "");
3882b010
L
10744#endif
10745#if defined (HAVE_SETLOCALE)
10746 setlocale (LC_CTYPE, "");
252b5132
RH
10747#endif
10748 bindtextdomain (PACKAGE, LOCALEDIR);
10749 textdomain (PACKAGE);
10750
10751 parse_args (argc, argv);
10752
10753 if (optind < (argc - 1))
10754 show_name = 1;
10755
59f14fc0
AS
10756 /* When processing more than one file remember the dump requests
10757 issued on command line to reset them after each file. */
10758 if (optind + 1 < argc && dump_sects != NULL)
10759 {
10760 cmdline_dump_sects = malloc (num_dump_sects);
10761 if (cmdline_dump_sects == NULL)
10762 error (_("Out of memory allocating dump request table."));
10763 else
10764 {
10765 memcpy (cmdline_dump_sects, dump_sects, num_dump_sects);
10766 num_cmdline_dump_sects = num_dump_sects;
10767 }
10768 }
10769
ff78d6d6 10770 err = 0;
252b5132 10771 while (optind < argc)
59f14fc0
AS
10772 {
10773 err |= process_file (argv[optind++]);
10774
10775 /* Reset dump requests. */
10776 if (optind < argc && dump_sects != NULL)
10777 {
10778 num_dump_sects = num_cmdline_dump_sects;
10779 if (num_cmdline_dump_sects > 0)
10780 memcpy (dump_sects, cmdline_dump_sects, num_cmdline_dump_sects);
10781 }
10782 }
252b5132
RH
10783
10784 if (dump_sects != NULL)
10785 free (dump_sects);
59f14fc0
AS
10786 if (cmdline_dump_sects != NULL)
10787 free (cmdline_dump_sects);
252b5132 10788
ff78d6d6 10789 return err;
252b5132 10790}
This page took 0.804703 seconds and 4 git commands to generate.