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