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