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