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