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