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