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