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