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