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