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