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