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