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