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