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