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