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