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