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