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