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