]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
bfd/
[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
3f215a10
NC
7379 if (arange.ar_version != 2)
7380 {
7381 warn (_("Only DWARF 2 aranges are currently supported.\n"));
7382 break;
7383 }
7384
252b5132
RH
7385 printf (_(" Length: %ld\n"), arange.ar_length);
7386 printf (_(" Version: %d\n"), arange.ar_version);
7387 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
7388 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
7389 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
7390
7391 printf (_("\n Address Length\n"));
7392
7393 ranges = start + sizeof (* external);
7394
7a4b7442 7395 /* Must pad to an alignment boundary that is twice the pointer size. */
584da044 7396 excess = sizeof (* external) % (2 * arange.ar_pointer_size);
7a4b7442
NC
7397 if (excess)
7398 ranges += (2 * arange.ar_pointer_size) - excess;
7399
252b5132
RH
7400 for (;;)
7401 {
7402 address = byte_get (ranges, arange.ar_pointer_size);
7403
252b5132
RH
7404 ranges += arange.ar_pointer_size;
7405
7406 length = byte_get (ranges, arange.ar_pointer_size);
7407
7408 ranges += arange.ar_pointer_size;
7409
7a4b7442
NC
7410 /* A pair of zeros marks the end of the list. */
7411 if (address == 0 && length == 0)
7412 break;
103f02d3 7413
252b5132
RH
7414 printf (" %8.8lx %lu\n", address, length);
7415 }
7416
7417 start += arange.ar_length + sizeof (external->ar_length);
7418 }
7419
7420 printf ("\n");
7421
7422 return 1;
7423}
7424
c47d488e
DD
7425typedef struct Frame_Chunk
7426{
584da044
NC
7427 struct Frame_Chunk * next;
7428 unsigned char * chunk_start;
7429 int ncols;
a98cc2b2 7430 /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */
584da044
NC
7431 short int * col_type;
7432 int * col_offset;
7433 char * augmentation;
7434 unsigned int code_factor;
31b6fca6 7435 int data_factor;
584da044
NC
7436 unsigned long pc_begin;
7437 unsigned long pc_range;
7438 int cfa_reg;
7439 int cfa_offset;
7440 int ra;
31b6fca6 7441 unsigned char fde_encoding;
c47d488e
DD
7442}
7443Frame_Chunk;
7444
a98cc2b2
AH
7445/* A marker for a col_type that means this column was never referenced
7446 in the frame info. */
7447#define DW_CFA_unreferenced (-1)
7448
2863d58a
AM
7449static void frame_need_space PARAMS ((Frame_Chunk *, int));
7450static void frame_display_row PARAMS ((Frame_Chunk *, int *, int *));
7451static int size_of_encoded_value PARAMS ((int));
7452
c47d488e
DD
7453static void
7454frame_need_space (fc, reg)
584da044 7455 Frame_Chunk * fc;
c47d488e
DD
7456 int reg;
7457{
7458 int prev = fc->ncols;
7459
7460 if (reg < fc->ncols)
7461 return;
584da044 7462
c47d488e 7463 fc->ncols = reg + 1;
a98cc2b2
AH
7464 fc->col_type = (short int *) xrealloc (fc->col_type,
7465 fc->ncols * sizeof (short int));
c47d488e
DD
7466 fc->col_offset = (int *) xrealloc (fc->col_offset,
7467 fc->ncols * sizeof (int));
7468
7469 while (prev < fc->ncols)
7470 {
a98cc2b2 7471 fc->col_type[prev] = DW_CFA_unreferenced;
c47d488e
DD
7472 fc->col_offset[prev] = 0;
7473 prev++;
7474 }
7475}
7476
7477static void
7478frame_display_row (fc, need_col_headers, max_regs)
584da044
NC
7479 Frame_Chunk * fc;
7480 int * need_col_headers;
7481 int * max_regs;
c47d488e
DD
7482{
7483 int r;
7484 char tmp[100];
7485
584da044
NC
7486 if (* max_regs < fc->ncols)
7487 * max_regs = fc->ncols;
7488
7489 if (* need_col_headers)
c47d488e 7490 {
584da044
NC
7491 * need_col_headers = 0;
7492
c47d488e 7493 printf (" LOC CFA ");
584da044
NC
7494
7495 for (r = 0; r < * max_regs; r++)
a98cc2b2
AH
7496 if (fc->col_type[r] != DW_CFA_unreferenced)
7497 {
7498 if (r == fc->ra)
7499 printf ("ra ");
7500 else
7501 printf ("r%-4d", r);
7502 }
584da044 7503
c47d488e
DD
7504 printf ("\n");
7505 }
584da044 7506
31b6fca6 7507 printf ("%08lx ", fc->pc_begin);
c47d488e
DD
7508 sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
7509 printf ("%-8s ", tmp);
584da044
NC
7510
7511 for (r = 0; r < fc->ncols; r++)
c47d488e 7512 {
a98cc2b2 7513 if (fc->col_type[r] != DW_CFA_unreferenced)
c47d488e 7514 {
a98cc2b2
AH
7515 switch (fc->col_type[r])
7516 {
7517 case DW_CFA_undefined:
7518 strcpy (tmp, "u");
7519 break;
7520 case DW_CFA_same_value:
7521 strcpy (tmp, "s");
7522 break;
7523 case DW_CFA_offset:
7524 sprintf (tmp, "c%+d", fc->col_offset[r]);
7525 break;
7526 case DW_CFA_register:
7527 sprintf (tmp, "r%d", fc->col_offset[r]);
7528 break;
7529 default:
7530 strcpy (tmp, "n/a");
7531 break;
7532 }
7533 printf ("%-5s", tmp);
c47d488e 7534 }
c47d488e
DD
7535 }
7536 printf ("\n");
7537}
7538
31b6fca6
RH
7539static int
7540size_of_encoded_value (encoding)
7541 int encoding;
7542{
7543 switch (encoding & 0x7)
7544 {
7545 default: /* ??? */
7546 case 0: return is_32bit_elf ? 4 : 8;
7547 case 2: return 2;
7548 case 3: return 4;
7549 case 4: return 8;
7550 }
7551}
7552
c47d488e 7553#define GET(N) byte_get (start, N); start += N
584da044
NC
7554#define LEB() read_leb128 (start, & length_return, 0); start += length_return
7555#define SLEB() read_leb128 (start, & length_return, 1); start += length_return
c47d488e
DD
7556
7557static int
7558display_debug_frames (section, start, file)
7559 Elf32_Internal_Shdr * section;
7560 unsigned char * start;
7561 FILE * file ATTRIBUTE_UNUSED;
7562{
7563 unsigned char * end = start + section->sh_size;
584da044
NC
7564 unsigned char * section_start = start;
7565 Frame_Chunk * chunks = 0;
7566 Frame_Chunk * remembered_state = 0;
7567 Frame_Chunk * rs;
7568 int is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
7569 int length_return;
7570 int max_regs = 0;
31b6fca6 7571 int addr_size = is_32bit_elf ? 4 : 8;
c47d488e
DD
7572
7573 printf (_("The section %s contains:\n"), SECTION_NAME (section));
7574
7575 while (start < end)
7576 {
584da044
NC
7577 unsigned char * saved_start;
7578 unsigned char * block_end;
7579 unsigned long length;
7580 unsigned long cie_id;
7581 Frame_Chunk * fc;
7582 Frame_Chunk * cie;
7583 int need_col_headers = 1;
31b6fca6
RH
7584 unsigned char * augmentation_data = NULL;
7585 unsigned long augmentation_data_len = 0;
7586 int encoded_ptr_size = addr_size;
c47d488e
DD
7587
7588 saved_start = start;
7589 length = byte_get (start, 4); start += 4;
7590
7591 if (length == 0)
7592 return 1;
7593
7594 block_end = saved_start + length + 4;
7595 cie_id = byte_get (start, 4); start += 4;
7596
c47d488e
DD
7597 if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
7598 {
31b6fca6
RH
7599 int version;
7600
c47d488e
DD
7601 fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
7602 memset (fc, 0, sizeof (Frame_Chunk));
7603
7604 fc->next = chunks;
7605 chunks = fc;
7606 fc->chunk_start = saved_start;
7607 fc->ncols = 0;
a98cc2b2 7608 fc->col_type = (short int *) xmalloc (sizeof (short int));
c47d488e
DD
7609 fc->col_offset = (int *) xmalloc (sizeof (int));
7610 frame_need_space (fc, max_regs-1);
7611
31b6fca6 7612 version = *start++;
584da044 7613
31b6fca6
RH
7614 fc->augmentation = start;
7615 start = strchr (start, '\0') + 1;
584da044 7616
c47d488e
DD
7617 if (fc->augmentation[0] == 'z')
7618 {
c47d488e
DD
7619 fc->code_factor = LEB ();
7620 fc->data_factor = SLEB ();
7621 fc->ra = byte_get (start, 1); start += 1;
31b6fca6
RH
7622 augmentation_data_len = LEB ();
7623 augmentation_data = start;
7624 start += augmentation_data_len;
c47d488e
DD
7625 }
7626 else if (strcmp (fc->augmentation, "eh") == 0)
7627 {
31b6fca6 7628 start += addr_size;
c47d488e
DD
7629 fc->code_factor = LEB ();
7630 fc->data_factor = SLEB ();
7631 fc->ra = byte_get (start, 1); start += 1;
7632 }
7633 else
7634 {
7635 fc->code_factor = LEB ();
7636 fc->data_factor = SLEB ();
7637 fc->ra = byte_get (start, 1); start += 1;
7638 }
7639 cie = fc;
31b6fca6
RH
7640
7641 if (do_debug_frames_interp)
7642 printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
7036c0e1 7643 (unsigned long)(saved_start - section_start), length, cie_id,
31b6fca6
RH
7644 fc->augmentation, fc->code_factor, fc->data_factor,
7645 fc->ra);
7646 else
7647 {
7648 printf ("\n%08lx %08lx %08lx CIE\n",
7036c0e1 7649 (unsigned long)(saved_start - section_start), length, cie_id);
31b6fca6
RH
7650 printf (" Version: %d\n", version);
7651 printf (" Augmentation: \"%s\"\n", fc->augmentation);
7652 printf (" Code alignment factor: %u\n", fc->code_factor);
7653 printf (" Data alignment factor: %d\n", fc->data_factor);
7654 printf (" Return address column: %d\n", fc->ra);
7655
7656 if (augmentation_data_len)
7657 {
7658 unsigned long i;
7659 printf (" Augmentation data: ");
7660 for (i = 0; i < augmentation_data_len; ++i)
7661 printf (" %02x", augmentation_data[i]);
7662 putchar ('\n');
7663 }
7664 putchar ('\n');
7665 }
7666
7667 if (augmentation_data_len)
7668 {
7669 unsigned char *p, *q;
7670 p = fc->augmentation + 1;
7671 q = augmentation_data;
7672
7673 while (1)
7674 {
7675 if (*p == 'L')
7036c0e1 7676 q++;
31b6fca6
RH
7677 else if (*p == 'P')
7678 q += 1 + size_of_encoded_value (*q);
7679 else if (*p == 'R')
7680 fc->fde_encoding = *q++;
7681 else
7682 break;
7683 p++;
7684 }
7685
7686 if (fc->fde_encoding)
7687 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
7688 }
c47d488e
DD
7689
7690 frame_need_space (fc, fc->ra);
7691 }
7692 else
7693 {
584da044 7694 unsigned char * look_for;
c47d488e 7695 static Frame_Chunk fde_fc;
584da044
NC
7696
7697 fc = & fde_fc;
c47d488e
DD
7698 memset (fc, 0, sizeof (Frame_Chunk));
7699
31b6fca6 7700 look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
c47d488e 7701
31b6fca6
RH
7702 for (cie=chunks; cie ; cie = cie->next)
7703 if (cie->chunk_start == look_for)
7704 break;
c47d488e 7705
c47d488e
DD
7706 if (!cie)
7707 {
31b6fca6
RH
7708 warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
7709 cie_id, saved_start);
c47d488e
DD
7710 start = block_end;
7711 fc->ncols = 0;
a98cc2b2 7712 fc->col_type = (short int *) xmalloc (sizeof (short int));
c47d488e 7713 fc->col_offset = (int *) xmalloc (sizeof (int));
584da044 7714 frame_need_space (fc, max_regs - 1);
c47d488e
DD
7715 cie = fc;
7716 fc->augmentation = "";
31b6fca6 7717 fc->fde_encoding = 0;
c47d488e
DD
7718 }
7719 else
7720 {
7721 fc->ncols = cie->ncols;
a98cc2b2 7722 fc->col_type = (short int *) xmalloc (fc->ncols * sizeof (short int));
c47d488e 7723 fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
a98cc2b2 7724 memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
c47d488e
DD
7725 memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
7726 fc->augmentation = cie->augmentation;
7727 fc->code_factor = cie->code_factor;
7728 fc->data_factor = cie->data_factor;
7729 fc->cfa_reg = cie->cfa_reg;
7730 fc->cfa_offset = cie->cfa_offset;
7731 fc->ra = cie->ra;
7732 frame_need_space (fc, max_regs-1);
31b6fca6 7733 fc->fde_encoding = cie->fde_encoding;
c47d488e
DD
7734 }
7735
31b6fca6
RH
7736 if (fc->fde_encoding)
7737 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
7738
7739 fc->pc_begin = byte_get (start, encoded_ptr_size);
7740 start += encoded_ptr_size;
7741 fc->pc_range = byte_get (start, encoded_ptr_size);
7742 start += encoded_ptr_size;
7743
c47d488e
DD
7744 if (cie->augmentation[0] == 'z')
7745 {
31b6fca6
RH
7746 augmentation_data_len = LEB ();
7747 augmentation_data = start;
7748 start += augmentation_data_len;
c47d488e
DD
7749 }
7750
410f7a12 7751 printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
7036c0e1 7752 (unsigned long)(saved_start - section_start), length, cie_id,
410f7a12
L
7753 (unsigned long)(cie->chunk_start - section_start),
7754 fc->pc_begin, fc->pc_begin + fc->pc_range);
31b6fca6
RH
7755 if (! do_debug_frames_interp && augmentation_data_len)
7756 {
7757 unsigned long i;
7758 printf (" Augmentation data: ");
7759 for (i = 0; i < augmentation_data_len; ++i)
7760 printf (" %02x", augmentation_data[i]);
7761 putchar ('\n');
7762 putchar ('\n');
7763 }
c47d488e
DD
7764 }
7765
7766 /* At this point, fc is the current chunk, cie (if any) is set, and we're
7767 about to interpret instructions for the chunk. */
7768
31b6fca6 7769 if (do_debug_frames_interp)
a98cc2b2
AH
7770 {
7771 /* Start by making a pass over the chunk, allocating storage
7772 and taking note of what registers are used. */
584da044 7773 unsigned char * tmp = start;
a98cc2b2 7774
a98cc2b2
AH
7775 while (start < block_end)
7776 {
7777 unsigned op, opa;
7778 unsigned long reg;
7036c0e1 7779
584da044 7780 op = * start ++;
a98cc2b2
AH
7781 opa = op & 0x3f;
7782 if (op & 0xc0)
7783 op &= 0xc0;
7036c0e1 7784
a98cc2b2
AH
7785 /* Warning: if you add any more cases to this switch, be
7786 sure to add them to the corresponding switch below. */
7787 switch (op)
7788 {
7789 case DW_CFA_advance_loc:
7790 break;
7791 case DW_CFA_offset:
7792 LEB ();
7793 frame_need_space (fc, opa);
7794 fc->col_type[opa] = DW_CFA_undefined;
7795 break;
7796 case DW_CFA_restore:
7797 frame_need_space (fc, opa);
7798 fc->col_type[opa] = DW_CFA_undefined;
7799 break;
7800 case DW_CFA_set_loc:
31b6fca6 7801 start += encoded_ptr_size;
a98cc2b2
AH
7802 break;
7803 case DW_CFA_advance_loc1:
7804 start += 1;
7805 break;
7806 case DW_CFA_advance_loc2:
7807 start += 2;
7808 break;
7809 case DW_CFA_advance_loc4:
7810 start += 4;
7811 break;
7812 case DW_CFA_offset_extended:
7813 reg = LEB (); LEB ();
7814 frame_need_space (fc, reg);
7815 fc->col_type[reg] = DW_CFA_undefined;
7816 break;
7817 case DW_CFA_restore_extended:
7818 reg = LEB ();
7819 frame_need_space (fc, reg);
7820 fc->col_type[reg] = DW_CFA_undefined;
7821 break;
7822 case DW_CFA_undefined:
7823 reg = LEB ();
7824 frame_need_space (fc, reg);
7825 fc->col_type[reg] = DW_CFA_undefined;
7826 break;
7827 case DW_CFA_same_value:
7828 reg = LEB ();
7829 frame_need_space (fc, reg);
7830 fc->col_type[reg] = DW_CFA_undefined;
7831 break;
7832 case DW_CFA_register:
7833 reg = LEB (); LEB ();
7834 frame_need_space (fc, reg);
7835 fc->col_type[reg] = DW_CFA_undefined;
7836 break;
7837 case DW_CFA_def_cfa:
7838 LEB (); LEB ();
7839 break;
7840 case DW_CFA_def_cfa_register:
7841 LEB ();
7842 break;
7843 case DW_CFA_def_cfa_offset:
7844 LEB ();
7845 break;
7846#ifndef DW_CFA_GNU_args_size
7847#define DW_CFA_GNU_args_size 0x2e
7848#endif
7849 case DW_CFA_GNU_args_size:
7850 LEB ();
7036c0e1 7851 break;
a98cc2b2
AH
7852#ifndef DW_CFA_GNU_negative_offset_extended
7853#define DW_CFA_GNU_negative_offset_extended 0x2f
7854#endif
7855 case DW_CFA_GNU_negative_offset_extended:
7036c0e1 7856 reg = LEB (); LEB ();
a98cc2b2
AH
7857 frame_need_space (fc, reg);
7858 fc->col_type[reg] = DW_CFA_undefined;
7036c0e1 7859
a98cc2b2
AH
7860 default:
7861 break;
7862 }
7863 }
7864 start = tmp;
7865 }
7866
7867 /* Now we know what registers are used, make a second pass over
7868 the chunk, this time actually printing out the info. */
7869
c47d488e
DD
7870 while (start < block_end)
7871 {
7872 unsigned op, opa;
7873 unsigned long ul, reg, roffs;
7874 long l, ofs;
7875 bfd_vma vma;
7876
7877 op = * start ++;
7878 opa = op & 0x3f;
7879 if (op & 0xc0)
7880 op &= 0xc0;
7881
a98cc2b2
AH
7882 /* Warning: if you add any more cases to this switch, be
7883 sure to add them to the corresponding switch above. */
c47d488e
DD
7884 switch (op)
7885 {
7886 case DW_CFA_advance_loc:
31b6fca6
RH
7887 if (do_debug_frames_interp)
7888 frame_display_row (fc, &need_col_headers, &max_regs);
7889 else
7890 printf (" DW_CFA_advance_loc: %d to %08lx\n",
7891 opa * fc->code_factor,
7892 fc->pc_begin + opa * fc->code_factor);
c47d488e
DD
7893 fc->pc_begin += opa * fc->code_factor;
7894 break;
7895
7896 case DW_CFA_offset:
c47d488e 7897 roffs = LEB ();
31b6fca6 7898 if (! do_debug_frames_interp)
7036c0e1 7899 printf (" DW_CFA_offset: r%d at cfa%+ld\n",
31b6fca6 7900 opa, roffs * fc->data_factor);
c47d488e
DD
7901 fc->col_type[opa] = DW_CFA_offset;
7902 fc->col_offset[opa] = roffs * fc->data_factor;
7903 break;
7904
7905 case DW_CFA_restore:
31b6fca6
RH
7906 if (! do_debug_frames_interp)
7907 printf (" DW_CFA_restore: r%d\n", opa);
c47d488e
DD
7908 fc->col_type[opa] = cie->col_type[opa];
7909 fc->col_offset[opa] = cie->col_offset[opa];
7910 break;
7911
7912 case DW_CFA_set_loc:
31b6fca6
RH
7913 vma = byte_get (start, encoded_ptr_size);
7914 start += encoded_ptr_size;
7915 if (do_debug_frames_interp)
7916 frame_display_row (fc, &need_col_headers, &max_regs);
7917 else
7036c0e1 7918 printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
c47d488e
DD
7919 fc->pc_begin = vma;
7920 break;
7921
7922 case DW_CFA_advance_loc1:
c47d488e 7923 ofs = byte_get (start, 1); start += 1;
31b6fca6
RH
7924 if (do_debug_frames_interp)
7925 frame_display_row (fc, &need_col_headers, &max_regs);
7926 else
7036c0e1 7927 printf (" DW_CFA_advance_loc1: %ld to %08lx\n",
31b6fca6
RH
7928 ofs * fc->code_factor,
7929 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
7930 fc->pc_begin += ofs * fc->code_factor;
7931 break;
7932
7933 case DW_CFA_advance_loc2:
c47d488e 7934 ofs = byte_get (start, 2); start += 2;
31b6fca6
RH
7935 if (do_debug_frames_interp)
7936 frame_display_row (fc, &need_col_headers, &max_regs);
7937 else
7036c0e1 7938 printf (" DW_CFA_advance_loc2: %ld to %08lx\n",
31b6fca6
RH
7939 ofs * fc->code_factor,
7940 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
7941 fc->pc_begin += ofs * fc->code_factor;
7942 break;
7943
7944 case DW_CFA_advance_loc4:
c47d488e 7945 ofs = byte_get (start, 4); start += 4;
31b6fca6
RH
7946 if (do_debug_frames_interp)
7947 frame_display_row (fc, &need_col_headers, &max_regs);
7948 else
7036c0e1 7949 printf (" DW_CFA_advance_loc4: %ld to %08lx\n",
31b6fca6
RH
7950 ofs * fc->code_factor,
7951 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
7952 fc->pc_begin += ofs * fc->code_factor;
7953 break;
7954
7955 case DW_CFA_offset_extended:
7956 reg = LEB ();
7957 roffs = LEB ();
31b6fca6 7958 if (! do_debug_frames_interp)
7036c0e1 7959 printf (" DW_CFA_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 7960 reg, roffs * fc->data_factor);
c47d488e
DD
7961 fc->col_type[reg] = DW_CFA_offset;
7962 fc->col_offset[reg] = roffs * fc->data_factor;
7963 break;
7964
7965 case DW_CFA_restore_extended:
7966 reg = LEB ();
31b6fca6 7967 if (! do_debug_frames_interp)
7036c0e1 7968 printf (" DW_CFA_restore_extended: r%ld\n", reg);
c47d488e
DD
7969 fc->col_type[reg] = cie->col_type[reg];
7970 fc->col_offset[reg] = cie->col_offset[reg];
7971 break;
7972
7973 case DW_CFA_undefined:
7974 reg = LEB ();
31b6fca6 7975 if (! do_debug_frames_interp)
7036c0e1 7976 printf (" DW_CFA_undefined: r%ld\n", reg);
c47d488e
DD
7977 fc->col_type[reg] = DW_CFA_undefined;
7978 fc->col_offset[reg] = 0;
7979 break;
7980
7981 case DW_CFA_same_value:
7982 reg = LEB ();
31b6fca6 7983 if (! do_debug_frames_interp)
7036c0e1 7984 printf (" DW_CFA_same_value: r%ld\n", reg);
c47d488e
DD
7985 fc->col_type[reg] = DW_CFA_same_value;
7986 fc->col_offset[reg] = 0;
7987 break;
7988
7989 case DW_CFA_register:
7990 reg = LEB ();
7991 roffs = LEB ();
31b6fca6 7992 if (! do_debug_frames_interp)
7036c0e1 7993 printf (" DW_CFA_register: r%ld\n", reg);
c47d488e
DD
7994 fc->col_type[reg] = DW_CFA_register;
7995 fc->col_offset[reg] = roffs;
7996 break;
7997
7998 case DW_CFA_remember_state:
31b6fca6
RH
7999 if (! do_debug_frames_interp)
8000 printf (" DW_CFA_remember_state\n");
c47d488e
DD
8001 rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
8002 rs->ncols = fc->ncols;
a98cc2b2 8003 rs->col_type = (short int *) xmalloc (rs->ncols * sizeof (short int));
c47d488e
DD
8004 rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
8005 memcpy (rs->col_type, fc->col_type, rs->ncols);
8006 memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
8007 rs->next = remembered_state;
8008 remembered_state = rs;
8009 break;
8010
8011 case DW_CFA_restore_state:
31b6fca6
RH
8012 if (! do_debug_frames_interp)
8013 printf (" DW_CFA_restore_state\n");
c47d488e
DD
8014 rs = remembered_state;
8015 remembered_state = rs->next;
8016 frame_need_space (fc, rs->ncols-1);
8017 memcpy (fc->col_type, rs->col_type, rs->ncols);
8018 memcpy (fc->col_offset, rs->col_offset, rs->ncols * sizeof (int));
8019 free (rs->col_type);
8020 free (rs->col_offset);
8021 free (rs);
8022 break;
8023
8024 case DW_CFA_def_cfa:
8025 fc->cfa_reg = LEB ();
8026 fc->cfa_offset = LEB ();
31b6fca6
RH
8027 if (! do_debug_frames_interp)
8028 printf (" DW_CFA_def_cfa: r%d ofs %d\n",
8029 fc->cfa_reg, fc->cfa_offset);
c47d488e
DD
8030 break;
8031
8032 case DW_CFA_def_cfa_register:
8033 fc->cfa_reg = LEB ();
31b6fca6
RH
8034 if (! do_debug_frames_interp)
8035 printf (" DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
c47d488e
DD
8036 break;
8037
8038 case DW_CFA_def_cfa_offset:
8039 fc->cfa_offset = LEB ();
31b6fca6
RH
8040 if (! do_debug_frames_interp)
8041 printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
c47d488e
DD
8042 break;
8043
8044 case DW_CFA_nop:
31b6fca6
RH
8045 if (! do_debug_frames_interp)
8046 printf (" DW_CFA_nop\n");
c47d488e
DD
8047 break;
8048
8049#ifndef DW_CFA_GNU_window_save
8050#define DW_CFA_GNU_window_save 0x2d
8051#endif
8052 case DW_CFA_GNU_window_save:
31b6fca6
RH
8053 if (! do_debug_frames_interp)
8054 printf (" DW_CFA_GNU_window_save\n");
c47d488e
DD
8055 break;
8056
c47d488e
DD
8057 case DW_CFA_GNU_args_size:
8058 ul = LEB ();
31b6fca6 8059 if (! do_debug_frames_interp)
7036c0e1 8060 printf (" DW_CFA_GNU_args_size: %ld\n", ul);
c47d488e
DD
8061 break;
8062
c47d488e
DD
8063 case DW_CFA_GNU_negative_offset_extended:
8064 reg = LEB ();
8065 l = - LEB ();
8066 frame_need_space (fc, reg);
31b6fca6 8067 if (! do_debug_frames_interp)
7036c0e1 8068 printf (" DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 8069 reg, l * fc->data_factor);
c47d488e
DD
8070 fc->col_type[reg] = DW_CFA_offset;
8071 fc->col_offset[reg] = l * fc->data_factor;
8072 break;
8073
8074 default:
8075 fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
8076 start = block_end;
8077 }
8078 }
8079
31b6fca6
RH
8080 if (do_debug_frames_interp)
8081 frame_display_row (fc, &need_col_headers, &max_regs);
c47d488e
DD
8082
8083 start = block_end;
8084 }
8085
8086 printf ("\n");
8087
8088 return 1;
8089}
8090
8091#undef GET
8092#undef LEB
8093#undef SLEB
252b5132
RH
8094
8095static int
8096display_debug_not_supported (section, start, file)
8097 Elf32_Internal_Shdr * section;
b4c96d0d
ILT
8098 unsigned char * start ATTRIBUTE_UNUSED;
8099 FILE * file ATTRIBUTE_UNUSED;
252b5132
RH
8100{
8101 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
8102 SECTION_NAME (section));
8103
8104 return 1;
8105}
8106
3590ea00
NC
8107/* Pre-scan the .debug_info section to record the size of address.
8108 When dumping the .debug_line, we use that size information, assuming
8109 that all compilation units have the same address size. */
8110static int
8111prescan_debug_info (section, start, file)
8112 Elf32_Internal_Shdr * section ATTRIBUTE_UNUSED;
8113 unsigned char * start;
8114 FILE * file ATTRIBUTE_UNUSED;
8115{
8116 DWARF2_External_CompUnit * external;
8117
8118 external = (DWARF2_External_CompUnit *) start;
8119
8120 debug_line_pointer_size = BYTE_GET (external->cu_pointer_size);
8121 return 0;
8122}
8123
252b5132 8124 /* A structure containing the name of a debug section and a pointer
3590ea00
NC
8125 to a function that can decode it. The third field is a prescan
8126 function to be run over the section before displaying any of the
8127 sections. */
252b5132
RH
8128struct
8129{
8130 char * name;
3590ea00
NC
8131 int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
8132 int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
252b5132
RH
8133}
8134debug_displays[] =
8135{
3590ea00
NC
8136 { ".debug_info", display_debug_info, prescan_debug_info },
8137 { ".debug_abbrev", display_debug_abbrev, NULL },
8138 { ".debug_line", display_debug_lines, NULL },
8139 { ".debug_aranges", display_debug_aranges, NULL },
8140 { ".debug_pubnames", display_debug_pubnames, NULL },
c47d488e
DD
8141 { ".debug_frame", display_debug_frames, NULL },
8142 { ".eh_frame", display_debug_frames, NULL },
e0c60db2 8143 { ".debug_macinfo", display_debug_macinfo, NULL },
3590ea00
NC
8144 { ".debug_str", display_debug_not_supported, NULL },
8145 { ".debug_static_func", display_debug_not_supported, NULL },
8146 { ".debug_static_vars", display_debug_not_supported, NULL },
8147 { ".debug_types", display_debug_not_supported, NULL },
8148 { ".debug_weaknames", display_debug_not_supported, NULL }
252b5132
RH
8149};
8150
8151static int
8152display_debug_section (section, file)
8153 Elf32_Internal_Shdr * section;
8154 FILE * file;
8155{
8156 char * name = SECTION_NAME (section);
8157 bfd_size_type length;
8158 unsigned char * start;
8159 int i;
8160
8161 length = section->sh_size;
8162 if (length == 0)
8163 {
8164 printf (_("\nSection '%s' has no debugging data.\n"), name);
8165 return 0;
8166 }
8167
0823fbca 8168 start = (unsigned char *) get_data (NULL, file, section->sh_offset, length,
a6e9f9df
AM
8169 _("debug section data"));
8170 if (!start)
8171 return 0;
252b5132
RH
8172
8173 /* See if we know how to display the contents of this section. */
09fd7e38 8174 if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
7036c0e1 8175 name = ".debug_info";
584da044 8176
252b5132
RH
8177 for (i = NUM_ELEM (debug_displays); i--;)
8178 if (strcmp (debug_displays[i].name, name) == 0)
8179 {
8180 debug_displays[i].display (section, start, file);
8181 break;
8182 }
8183
8184 if (i == -1)
8185 printf (_("Unrecognised debug section: %s\n"), name);
8186
8187 free (start);
8188
8189 /* If we loaded in the abbrev section at some point,
8190 we must release it here. */
8191 if (first_abbrev != NULL)
8192 free_abbrevs ();
8193
8194 return 1;
8195}
8196
8197static int
8198process_section_contents (file)
8199 FILE * file;
8200{
3590ea00 8201 Elf32_Internal_Shdr * section;
7036c0e1 8202 unsigned int i;
252b5132
RH
8203
8204 if (! do_dump)
8205 return 1;
8206
3590ea00
NC
8207 /* Pre-scan the debug sections to find some debug information not
8208 present in some of them. For the .debug_line, we must find out the
8209 size of address (specified in .debug_info and .debug_aranges). */
8210 for (i = 0, section = section_headers;
8211 i < elf_header.e_shnum && i < num_dump_sects;
8212 i ++, section ++)
8213 {
8214 char * name = SECTION_NAME (section);
8215 int j;
8216
8217 if (section->sh_size == 0)
8218 continue;
8219
8220 /* See if there is some pre-scan operation for this section. */
8221 for (j = NUM_ELEM (debug_displays); j--;)
8222 if (strcmp (debug_displays[j].name, name) == 0)
8223 {
8224 if (debug_displays[j].prescan != NULL)
8225 {
8226 bfd_size_type length;
8227 unsigned char * start;
8228
8229 length = section->sh_size;
a6e9f9df 8230 start = ((unsigned char *)
0823fbca 8231 get_data (NULL, file, section->sh_offset, length,
a6e9f9df
AM
8232 _("debug section data")));
8233 if (!start)
8234 return 0;
3590ea00
NC
8235
8236 debug_displays[j].prescan (section, start, file);
8237 free (start);
8238 }
103f02d3 8239
3590ea00
NC
8240 break;
8241 }
8242 }
8243
252b5132 8244 for (i = 0, section = section_headers;
3590ea00 8245 i < elf_header.e_shnum && i < num_dump_sects;
252b5132
RH
8246 i ++, section ++)
8247 {
8248#ifdef SUPPORT_DISASSEMBLY
8249 if (dump_sects[i] & DISASS_DUMP)
8250 disassemble_section (section, file);
8251#endif
8252 if (dump_sects[i] & HEX_DUMP)
8253 dump_section (section, file);
8254
8255 if (dump_sects[i] & DEBUG_DUMP)
8256 display_debug_section (section, file);
8257 }
8258
8259 if (i < num_dump_sects)
8260 warn (_("Some sections were not dumped because they do not exist!\n"));
8261
8262 return 1;
8263}
8264
8265static void
8266process_mips_fpe_exception (mask)
8267 int mask;
8268{
8269 if (mask)
8270 {
8271 int first = 1;
8272 if (mask & OEX_FPU_INEX)
8273 fputs ("INEX", stdout), first = 0;
8274 if (mask & OEX_FPU_UFLO)
8275 printf ("%sUFLO", first ? "" : "|"), first = 0;
8276 if (mask & OEX_FPU_OFLO)
8277 printf ("%sOFLO", first ? "" : "|"), first = 0;
8278 if (mask & OEX_FPU_DIV0)
8279 printf ("%sDIV0", first ? "" : "|"), first = 0;
8280 if (mask & OEX_FPU_INVAL)
8281 printf ("%sINVAL", first ? "" : "|");
8282 }
8283 else
8284 fputs ("0", stdout);
8285}
8286
8287static int
8288process_mips_specific (file)
9ea033b2 8289 FILE * file;
252b5132 8290{
9ea033b2 8291 Elf_Internal_Dyn * entry;
252b5132
RH
8292 size_t liblist_offset = 0;
8293 size_t liblistno = 0;
8294 size_t conflictsno = 0;
8295 size_t options_offset = 0;
8296 size_t conflicts_offset = 0;
8297
8298 /* We have a lot of special sections. Thanks SGI! */
8299 if (dynamic_segment == NULL)
8300 /* No information available. */
8301 return 0;
8302
8303 for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
8304 switch (entry->d_tag)
8305 {
8306 case DT_MIPS_LIBLIST:
8307 liblist_offset = entry->d_un.d_val - loadaddr;
8308 break;
8309 case DT_MIPS_LIBLISTNO:
8310 liblistno = entry->d_un.d_val;
8311 break;
8312 case DT_MIPS_OPTIONS:
8313 options_offset = entry->d_un.d_val - loadaddr;
8314 break;
8315 case DT_MIPS_CONFLICT:
8316 conflicts_offset = entry->d_un.d_val - loadaddr;
8317 break;
8318 case DT_MIPS_CONFLICTNO:
8319 conflictsno = entry->d_un.d_val;
8320 break;
8321 default:
8322 break;
8323 }
8324
8325 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
8326 {
9ea033b2 8327 Elf32_External_Lib * elib;
252b5132
RH
8328 size_t cnt;
8329
a6e9f9df
AM
8330 elib = ((Elf32_External_Lib *)
8331 get_data (NULL, file, liblist_offset,
8332 liblistno * sizeof (Elf32_External_Lib),
8333 _("liblist")));
8334 if (elib)
252b5132 8335 {
a6e9f9df
AM
8336 printf ("\nSection '.liblist' contains %lu entries:\n",
8337 (unsigned long) liblistno);
8338 fputs (" Library Time Stamp Checksum Version Flags\n",
8339 stdout);
8340
8341 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 8342 {
a6e9f9df
AM
8343 Elf32_Lib liblist;
8344 time_t time;
8345 char timebuf[20];
8346 struct tm * tmp;
8347
8348 liblist.l_name = BYTE_GET (elib[cnt].l_name);
8349 time = BYTE_GET (elib[cnt].l_time_stamp);
8350 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
8351 liblist.l_version = BYTE_GET (elib[cnt].l_version);
8352 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
8353
8354 tmp = gmtime (&time);
8355 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
8356 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8357 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8358
8359 printf ("%3lu: %-20s %s %#10lx %-7ld", (unsigned long) cnt,
8360 dynamic_strings + liblist.l_name, timebuf,
8361 liblist.l_checksum, liblist.l_version);
8362
8363 if (liblist.l_flags == 0)
8364 puts (" NONE");
8365 else
8366 {
8367 static const struct
252b5132 8368 {
a6e9f9df
AM
8369 const char * name;
8370 int bit;
252b5132 8371 }
a6e9f9df
AM
8372 l_flags_vals[] =
8373 {
8374 { " EXACT_MATCH", LL_EXACT_MATCH },
8375 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
8376 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
8377 { " EXPORTS", LL_EXPORTS },
8378 { " DELAY_LOAD", LL_DELAY_LOAD },
8379 { " DELTA", LL_DELTA }
8380 };
8381 int flags = liblist.l_flags;
8382 size_t fcnt;
8383
8384 for (fcnt = 0;
8385 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
8386 ++fcnt)
8387 if ((flags & l_flags_vals[fcnt].bit) != 0)
8388 {
8389 fputs (l_flags_vals[fcnt].name, stdout);
8390 flags ^= l_flags_vals[fcnt].bit;
8391 }
8392 if (flags != 0)
8393 printf (" %#x", (unsigned int) flags);
252b5132 8394
a6e9f9df
AM
8395 puts ("");
8396 }
252b5132 8397 }
252b5132 8398
a6e9f9df
AM
8399 free (elib);
8400 }
252b5132
RH
8401 }
8402
8403 if (options_offset != 0)
8404 {
9ea033b2 8405 Elf_External_Options * eopt;
d1133906 8406 Elf_Internal_Shdr * sect = section_headers;
9ea033b2
NC
8407 Elf_Internal_Options * iopt;
8408 Elf_Internal_Options * option;
252b5132
RH
8409 size_t offset;
8410 int cnt;
8411
8412 /* Find the section header so that we get the size. */
8413 while (sect->sh_type != SHT_MIPS_OPTIONS)
d1133906 8414 ++ sect;
252b5132 8415
a6e9f9df
AM
8416 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset,
8417 sect->sh_size, _("options"));
8418 if (eopt)
252b5132 8419 {
a6e9f9df
AM
8420 iopt = ((Elf_Internal_Options *)
8421 malloc ((sect->sh_size / sizeof (eopt)) * sizeof (* iopt)));
8422 if (iopt == NULL)
8423 {
8424 error (_("Out of memory"));
8425 return 0;
8426 }
76da6bbe 8427
a6e9f9df
AM
8428 offset = cnt = 0;
8429 option = iopt;
252b5132 8430
a6e9f9df
AM
8431 while (offset < sect->sh_size)
8432 {
8433 Elf_External_Options * eoption;
252b5132 8434
a6e9f9df 8435 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 8436
a6e9f9df
AM
8437 option->kind = BYTE_GET (eoption->kind);
8438 option->size = BYTE_GET (eoption->size);
8439 option->section = BYTE_GET (eoption->section);
8440 option->info = BYTE_GET (eoption->info);
76da6bbe 8441
a6e9f9df 8442 offset += option->size;
252b5132 8443
a6e9f9df
AM
8444 ++option;
8445 ++cnt;
8446 }
252b5132 8447
a6e9f9df
AM
8448 printf (_("\nSection '%s' contains %d entries:\n"),
8449 SECTION_NAME (sect), cnt);
76da6bbe 8450
a6e9f9df 8451 option = iopt;
252b5132 8452
a6e9f9df 8453 while (cnt-- > 0)
252b5132 8454 {
a6e9f9df
AM
8455 size_t len;
8456
8457 switch (option->kind)
252b5132 8458 {
a6e9f9df
AM
8459 case ODK_NULL:
8460 /* This shouldn't happen. */
8461 printf (" NULL %d %lx", option->section, option->info);
8462 break;
8463 case ODK_REGINFO:
8464 printf (" REGINFO ");
8465 if (elf_header.e_machine == EM_MIPS)
8466 {
8467 /* 32bit form. */
8468 Elf32_External_RegInfo * ereg;
8469 Elf32_RegInfo reginfo;
8470
8471 ereg = (Elf32_External_RegInfo *) (option + 1);
8472 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8473 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8474 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8475 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8476 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8477 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
8478
8479 printf ("GPR %08lx GP 0x%lx\n",
8480 reginfo.ri_gprmask,
8481 (unsigned long) reginfo.ri_gp_value);
8482 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
8483 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8484 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8485 }
8486 else
8487 {
8488 /* 64 bit form. */
8489 Elf64_External_RegInfo * ereg;
8490 Elf64_Internal_RegInfo reginfo;
8491
8492 ereg = (Elf64_External_RegInfo *) (option + 1);
8493 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8494 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8495 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8496 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8497 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8498 reginfo.ri_gp_value = BYTE_GET8 (ereg->ri_gp_value);
8499
8500 printf ("GPR %08lx GP 0x",
8501 reginfo.ri_gprmask);
8502 printf_vma (reginfo.ri_gp_value);
8503 printf ("\n");
8504
8505 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
8506 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8507 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8508 }
8509 ++option;
8510 continue;
8511 case ODK_EXCEPTIONS:
8512 fputs (" EXCEPTIONS fpe_min(", stdout);
8513 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
8514 fputs (") fpe_max(", stdout);
8515 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
8516 fputs (")", stdout);
8517
8518 if (option->info & OEX_PAGE0)
8519 fputs (" PAGE0", stdout);
8520 if (option->info & OEX_SMM)
8521 fputs (" SMM", stdout);
8522 if (option->info & OEX_FPDBUG)
8523 fputs (" FPDBUG", stdout);
8524 if (option->info & OEX_DISMISS)
8525 fputs (" DISMISS", stdout);
8526 break;
8527 case ODK_PAD:
8528 fputs (" PAD ", stdout);
8529 if (option->info & OPAD_PREFIX)
8530 fputs (" PREFIX", stdout);
8531 if (option->info & OPAD_POSTFIX)
8532 fputs (" POSTFIX", stdout);
8533 if (option->info & OPAD_SYMBOL)
8534 fputs (" SYMBOL", stdout);
8535 break;
8536 case ODK_HWPATCH:
8537 fputs (" HWPATCH ", stdout);
8538 if (option->info & OHW_R4KEOP)
8539 fputs (" R4KEOP", stdout);
8540 if (option->info & OHW_R8KPFETCH)
8541 fputs (" R8KPFETCH", stdout);
8542 if (option->info & OHW_R5KEOP)
8543 fputs (" R5KEOP", stdout);
8544 if (option->info & OHW_R5KCVTL)
8545 fputs (" R5KCVTL", stdout);
8546 break;
8547 case ODK_FILL:
8548 fputs (" FILL ", stdout);
8549 /* XXX Print content of info word? */
8550 break;
8551 case ODK_TAGS:
8552 fputs (" TAGS ", stdout);
8553 /* XXX Print content of info word? */
8554 break;
8555 case ODK_HWAND:
8556 fputs (" HWAND ", stdout);
8557 if (option->info & OHWA0_R4KEOP_CHECKED)
8558 fputs (" R4KEOP_CHECKED", stdout);
8559 if (option->info & OHWA0_R4KEOP_CLEAN)
8560 fputs (" R4KEOP_CLEAN", stdout);
8561 break;
8562 case ODK_HWOR:
8563 fputs (" HWOR ", stdout);
8564 if (option->info & OHWA0_R4KEOP_CHECKED)
8565 fputs (" R4KEOP_CHECKED", stdout);
8566 if (option->info & OHWA0_R4KEOP_CLEAN)
8567 fputs (" R4KEOP_CLEAN", stdout);
8568 break;
8569 case ODK_GP_GROUP:
8570 printf (" GP_GROUP %#06lx self-contained %#06lx",
8571 option->info & OGP_GROUP,
8572 (option->info & OGP_SELF) >> 16);
8573 break;
8574 case ODK_IDENT:
8575 printf (" IDENT %#06lx self-contained %#06lx",
8576 option->info & OGP_GROUP,
8577 (option->info & OGP_SELF) >> 16);
8578 break;
8579 default:
8580 /* This shouldn't happen. */
8581 printf (" %3d ??? %d %lx",
8582 option->kind, option->section, option->info);
8583 break;
252b5132 8584 }
a6e9f9df
AM
8585
8586 len = sizeof (* eopt);
8587 while (len < option->size)
8588 if (((char *) option)[len] >= ' '
8589 && ((char *) option)[len] < 0x7f)
8590 printf ("%c", ((char *) option)[len++]);
8591 else
8592 printf ("\\%03o", ((char *) option)[len++]);
8593
8594 fputs ("\n", stdout);
252b5132 8595 ++option;
252b5132
RH
8596 }
8597
a6e9f9df 8598 free (eopt);
252b5132 8599 }
252b5132
RH
8600 }
8601
8602 if (conflicts_offset != 0 && conflictsno != 0)
8603 {
9ea033b2 8604 Elf32_Conflict * iconf;
252b5132
RH
8605 size_t cnt;
8606
8607 if (dynamic_symbols == NULL)
8608 {
8609 error (_("conflict list with without table"));
8610 return 0;
8611 }
8612
584da044 8613 iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (* iconf));
252b5132
RH
8614 if (iconf == NULL)
8615 {
8616 error (_("Out of memory"));
8617 return 0;
8618 }
8619
9ea033b2 8620 if (is_32bit_elf)
252b5132 8621 {
a6e9f9df
AM
8622 Elf32_External_Conflict * econf32;
8623
8624 econf32 = ((Elf32_External_Conflict *)
8625 get_data (NULL, file, conflicts_offset,
8626 conflictsno * sizeof (* econf32),
8627 _("conflict")));
8628 if (!econf32)
8629 return 0;
252b5132
RH
8630
8631 for (cnt = 0; cnt < conflictsno; ++cnt)
8632 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
8633
8634 free (econf32);
252b5132
RH
8635 }
8636 else
8637 {
a6e9f9df
AM
8638 Elf64_External_Conflict * econf64;
8639
8640 econf64 = ((Elf64_External_Conflict *)
8641 get_data (NULL, file, conflicts_offset,
8642 conflictsno * sizeof (* econf64),
8643 _("conflict")));
8644 if (!econf64)
8645 return 0;
252b5132
RH
8646
8647 for (cnt = 0; cnt < conflictsno; ++cnt)
8648 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
8649
8650 free (econf64);
252b5132
RH
8651 }
8652
410f7a12
L
8653 printf (_("\nSection '.conflict' contains %ld entries:\n"),
8654 (long) conflictsno);
252b5132
RH
8655 puts (_(" Num: Index Value Name"));
8656
8657 for (cnt = 0; cnt < conflictsno; ++cnt)
8658 {
19936277 8659 Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
252b5132 8660
16062207 8661 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963
NC
8662 print_vma (psym->st_value, FULL_HEX);
8663 printf (" %s\n", dynamic_strings + psym->st_name);
252b5132
RH
8664 }
8665
252b5132
RH
8666 free (iconf);
8667 }
8668
8669 return 1;
8670}
8671
779fe533
NC
8672static char *
8673get_note_type (e_type)
8674 unsigned e_type;
8675{
8676 static char buff[64];
103f02d3 8677
779fe533
NC
8678 switch (e_type)
8679 {
8680 case NT_PRSTATUS: return _("NT_PRSTATUS (prstatus structure)");
8681 case NT_FPREGSET: return _("NT_FPREGSET (floating point registers)");
8682 case NT_PRPSINFO: return _("NT_PRPSINFO (prpsinfo structure)");
8683 case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
d1133906 8684 case NT_PRXFPREG: return _("NT_PRXFPREG (user_xfpregs structure)");
779fe533
NC
8685 case NT_PSTATUS: return _("NT_PSTATUS (pstatus structure)");
8686 case NT_FPREGS: return _("NT_FPREGS (floating point registers)");
8687 case NT_PSINFO: return _("NT_PSINFO (psinfo structure)");
8688 case NT_LWPSTATUS: return _("NT_LWPSTATUS (lwpstatus_t structure)");
8689 case NT_LWPSINFO: return _("NT_LWPSINFO (lwpsinfo_t structure)");
7bea2f73 8690 case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus strcuture)");
779fe533
NC
8691 default:
8692 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
8693 return buff;
8694 }
8695}
8696
6d118b09
NC
8697/* Note that by the ELF standard, the name field is already null byte
8698 terminated, and namesz includes the terminating null byte.
8699 I.E. the value of namesz for the name "FSF" is 4.
8700
8701 If the value of namesz is zero, there is no name present. */
779fe533
NC
8702static int
8703process_note (pnote)
6d118b09 8704 Elf32_Internal_Note * pnote;
779fe533 8705{
103f02d3 8706 printf (" %s\t\t0x%08lx\t%s\n",
6d118b09 8707 pnote->namesz ? pnote->namedata : "(NONE)",
7036c0e1 8708 pnote->descsz, get_note_type (pnote->type));
779fe533
NC
8709 return 1;
8710}
8711
6d118b09 8712
779fe533
NC
8713static int
8714process_corefile_note_segment (file, offset, length)
8715 FILE * file;
f7a99963
NC
8716 bfd_vma offset;
8717 bfd_vma length;
779fe533
NC
8718{
8719 Elf_External_Note * pnotes;
8720 Elf_External_Note * external;
779fe533 8721 int res = 1;
103f02d3 8722
779fe533
NC
8723 if (length <= 0)
8724 return 0;
103f02d3 8725
a6e9f9df
AM
8726 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, length,
8727 _("notes"));
8728 if (!pnotes)
8729 return 0;
779fe533 8730
103f02d3 8731 external = pnotes;
103f02d3 8732
305c7206 8733 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 8734 (unsigned long) offset, (unsigned long) length);
779fe533 8735 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 8736
6d118b09 8737 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 8738 {
6d118b09
NC
8739 Elf32_Internal_Note inote;
8740 char * temp = NULL;
8741
8742 inote.type = BYTE_GET (external->type);
8743 inote.namesz = BYTE_GET (external->namesz);
8744 inote.namedata = external->name;
8745 inote.descsz = BYTE_GET (external->descsz);
8746 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
8747 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 8748
6d118b09
NC
8749 external = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
8750
8751 /* Verify that name is null terminated. It appears that at least
8752 one version of Linux (RedHat 6.0) generates corefiles that don't
8753 comply with the ELF spec by failing to include the null byte in
8754 namesz. */
8755 if (inote.namedata[inote.namesz] != '\0')
8756 {
8757 temp = malloc (inote.namesz + 1);
76da6bbe 8758
6d118b09
NC
8759 if (temp == NULL)
8760 {
8761 error (_("Out of memory\n"));
8762 res = 0;
8763 break;
8764 }
76da6bbe 8765
6d118b09
NC
8766 strncpy (temp, inote.namedata, inote.namesz);
8767 temp[inote.namesz] = 0;
76da6bbe 8768
6d118b09
NC
8769 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
8770 inote.namedata = temp;
8771 }
8772
8773 res &= process_note (& inote);
103f02d3 8774
6d118b09
NC
8775 if (temp != NULL)
8776 {
8777 free (temp);
8778 temp = NULL;
8779 }
779fe533
NC
8780 }
8781
8782 free (pnotes);
103f02d3 8783
779fe533
NC
8784 return res;
8785}
8786
8787static int
8788process_corefile_note_segments (file)
8789 FILE * file;
8790{
8791 Elf_Internal_Phdr * program_headers;
8792 Elf_Internal_Phdr * segment;
8793 unsigned int i;
8794 int res = 1;
103f02d3 8795
779fe533
NC
8796 program_headers = (Elf_Internal_Phdr *) malloc
8797 (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
8798
8799 if (program_headers == NULL)
8800 {
8801 error (_("Out of memory\n"));
8802 return 0;
8803 }
8804
8805 if (is_32bit_elf)
8806 i = get_32bit_program_headers (file, program_headers);
8807 else
8808 i = get_64bit_program_headers (file, program_headers);
8809
8810 if (i == 0)
8811 {
8812 free (program_headers);
8813 return 0;
8814 }
103f02d3 8815
779fe533
NC
8816 for (i = 0, segment = program_headers;
8817 i < elf_header.e_phnum;
8818 i ++, segment ++)
8819 {
8820 if (segment->p_type == PT_NOTE)
103f02d3 8821 res &= process_corefile_note_segment (file,
30800947
NC
8822 (bfd_vma) segment->p_offset,
8823 (bfd_vma) segment->p_filesz);
779fe533 8824 }
103f02d3 8825
779fe533
NC
8826 free (program_headers);
8827
8828 return res;
8829}
8830
8831static int
8832process_corefile_contents (file)
8833 FILE * file;
8834{
8835 /* If we have not been asked to display the notes then do nothing. */
8836 if (! do_notes)
8837 return 1;
103f02d3 8838
779fe533
NC
8839 /* If file is not a core file then exit. */
8840 if (elf_header.e_type != ET_CORE)
8841 return 1;
103f02d3 8842
779fe533
NC
8843 /* No program headers means no NOTE segment. */
8844 if (elf_header.e_phnum == 0)
8845 {
8846 printf (_("No note segments present in the core file.\n"));
8847 return 1;
8848 }
8849
8850 return process_corefile_note_segments (file);
8851}
8852
252b5132
RH
8853static int
8854process_arch_specific (file)
9ea033b2 8855 FILE * file;
252b5132 8856{
a952a375
NC
8857 if (! do_arch)
8858 return 1;
8859
252b5132
RH
8860 switch (elf_header.e_machine)
8861 {
8862 case EM_MIPS:
4fe85591 8863 case EM_MIPS_RS3_LE:
252b5132
RH
8864 return process_mips_specific (file);
8865 break;
8866 default:
8867 break;
8868 }
8869 return 1;
8870}
8871
8872static int
8873get_file_header (file)
8874 FILE * file;
8875{
9ea033b2
NC
8876 /* Read in the identity array. */
8877 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
8878 return 0;
8879
9ea033b2
NC
8880 /* Determine how to read the rest of the header. */
8881 switch (elf_header.e_ident [EI_DATA])
8882 {
8883 default: /* fall through */
8884 case ELFDATANONE: /* fall through */
8885 case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
8886 case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
8887 }
8888
8889 /* For now we only support 32 bit and 64 bit ELF files. */
8890 is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
8891
8892 /* Read in the rest of the header. */
8893 if (is_32bit_elf)
8894 {
8895 Elf32_External_Ehdr ehdr32;
252b5132 8896
9ea033b2
NC
8897 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
8898 return 0;
103f02d3 8899
9ea033b2
NC
8900 elf_header.e_type = BYTE_GET (ehdr32.e_type);
8901 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
8902 elf_header.e_version = BYTE_GET (ehdr32.e_version);
8903 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
8904 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
8905 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
8906 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
8907 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
8908 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
8909 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
8910 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
8911 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
8912 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
8913 }
252b5132 8914 else
9ea033b2
NC
8915 {
8916 Elf64_External_Ehdr ehdr64;
a952a375
NC
8917
8918 /* If we have been compiled with sizeof (bfd_vma) == 4, then
8919 we will not be able to cope with the 64bit data found in
8920 64 ELF files. Detect this now and abort before we start
8921 overwritting things. */
8922 if (sizeof (bfd_vma) < 8)
8923 {
8924 error (_("This instance of readelf has been built without support for a\n"));
8925 error (_("64 bit data type and so it cannot read 64 bit ELF files.\n"));
8926 return 0;
8927 }
103f02d3 8928
9ea033b2
NC
8929 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
8930 return 0;
103f02d3 8931
9ea033b2
NC
8932 elf_header.e_type = BYTE_GET (ehdr64.e_type);
8933 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
8934 elf_header.e_version = BYTE_GET (ehdr64.e_version);
8935 elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry);
8936 elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff);
8937 elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff);
8938 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
8939 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
8940 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
8941 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
8942 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
8943 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
8944 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
8945 }
252b5132
RH
8946
8947 return 1;
8948}
8949
ff78d6d6 8950static int
252b5132
RH
8951process_file (file_name)
8952 char * file_name;
8953{
8954 FILE * file;
8955 struct stat statbuf;
8956 unsigned int i;
8957
8958 if (stat (file_name, & statbuf) < 0)
8959 {
8960 error (_("Cannot stat input file %s.\n"), file_name);
ff78d6d6 8961 return 1;
252b5132
RH
8962 }
8963
8964 file = fopen (file_name, "rb");
8965 if (file == NULL)
8966 {
8967 error (_("Input file %s not found.\n"), file_name);
ff78d6d6 8968 return 1;
252b5132
RH
8969 }
8970
8971 if (! get_file_header (file))
8972 {
8973 error (_("%s: Failed to read file header\n"), file_name);
8974 fclose (file);
ff78d6d6 8975 return 1;
252b5132
RH
8976 }
8977
8978 /* Initialise per file variables. */
8979 for (i = NUM_ELEM (version_info); i--;)
8980 version_info[i] = 0;
8981
8982 for (i = NUM_ELEM (dynamic_info); i--;)
8983 dynamic_info[i] = 0;
8984
8985 /* Process the file. */
8986 if (show_name)
8987 printf (_("\nFile: %s\n"), file_name);
8988
8989 if (! process_file_header ())
8990 {
8991 fclose (file);
ff78d6d6 8992 return 1;
252b5132
RH
8993 }
8994
8995 process_section_headers (file);
8996
8997 process_program_headers (file);
8998
8999 process_dynamic_segment (file);
9000
9001 process_relocs (file);
9002
4d6ed7c8
NC
9003 process_unwind (file);
9004
252b5132
RH
9005 process_symbol_table (file);
9006
9007 process_syminfo (file);
9008
9009 process_version_sections (file);
9010
9011 process_section_contents (file);
103f02d3 9012
779fe533 9013 process_corefile_contents (file);
103f02d3 9014
252b5132
RH
9015 process_arch_specific (file);
9016
9017 fclose (file);
9018
9019 if (section_headers)
9020 {
9021 free (section_headers);
9022 section_headers = NULL;
9023 }
9024
9025 if (string_table)
9026 {
9027 free (string_table);
9028 string_table = NULL;
d40ac9bd 9029 string_table_length = 0;
252b5132
RH
9030 }
9031
9032 if (dynamic_strings)
9033 {
9034 free (dynamic_strings);
9035 dynamic_strings = NULL;
9036 }
9037
9038 if (dynamic_symbols)
9039 {
9040 free (dynamic_symbols);
9041 dynamic_symbols = NULL;
19936277 9042 num_dynamic_syms = 0;
252b5132
RH
9043 }
9044
9045 if (dynamic_syminfo)
9046 {
9047 free (dynamic_syminfo);
9048 dynamic_syminfo = NULL;
9049 }
ff78d6d6
L
9050
9051 return 0;
252b5132
RH
9052}
9053
9054#ifdef SUPPORT_DISASSEMBLY
9055/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2
NC
9056 fix this so that we insert symbolic addresses here, esp for GOT/PLT
9057 symbols */
252b5132
RH
9058
9059void
9060print_address (unsigned int addr, FILE * outfile)
9061{
9062 fprintf (outfile,"0x%8.8x", addr);
9063}
9064
9065/* Needed by the i386 disassembler. */
9066void
9067db_task_printsym (unsigned int addr)
9068{
9069 print_address (addr, stderr);
9070}
9071#endif
9072
9073int
9074main (argc, argv)
9075 int argc;
9076 char ** argv;
9077{
ff78d6d6
L
9078 int err;
9079
252b5132
RH
9080#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
9081 setlocale (LC_MESSAGES, "");
3882b010
L
9082#endif
9083#if defined (HAVE_SETLOCALE)
9084 setlocale (LC_CTYPE, "");
252b5132
RH
9085#endif
9086 bindtextdomain (PACKAGE, LOCALEDIR);
9087 textdomain (PACKAGE);
9088
9089 parse_args (argc, argv);
9090
9091 if (optind < (argc - 1))
9092 show_name = 1;
9093
ff78d6d6 9094 err = 0;
252b5132 9095 while (optind < argc)
ff78d6d6 9096 err |= process_file (argv [optind ++]);
252b5132
RH
9097
9098 if (dump_sects != NULL)
9099 free (dump_sects);
9100
ff78d6d6 9101 return err;
252b5132 9102}