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