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