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