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