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