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