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