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