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