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