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