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