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