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