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