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