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