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