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