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