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