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