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