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