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