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