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