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