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