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