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