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