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