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