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