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