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