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