]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
2004-10-21 Tomer Levi <Tomer.Levi@nsc.com>
[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
5ab0c1a1
L
4037 if (symtab)
4038 free (symtab);
f5842774
L
4039 if (strtab)
4040 free (strtab);
4041 if (start)
4042 free (start);
e4b17d5c
L
4043
4044 group++;
f5842774
L
4045 }
4046 }
4047
4048 return 1;
4049}
4050
566b0d53
L
4051struct
4052{
4053 const char *name;
4054 int reloc;
4055 int size;
4056 int rela;
4057} dynamic_relocations [] =
4058{
4059 { "REL", DT_REL, DT_RELSZ, FALSE },
4060 { "RELA", DT_RELA, DT_RELASZ, TRUE },
4061 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
4062};
4063
252b5132
RH
4064/* Process the reloc section. */
4065static int
d3ba0551 4066process_relocs (FILE *file)
252b5132 4067{
b34976b6
AM
4068 unsigned long rel_size;
4069 unsigned long rel_offset;
252b5132
RH
4070
4071
4072 if (!do_reloc)
4073 return 1;
4074
4075 if (do_using_dynamic)
4076 {
566b0d53
L
4077 int is_rela;
4078 const char *name;
4079 int has_dynamic_reloc;
4080 unsigned int i;
0de14b54 4081
566b0d53 4082 has_dynamic_reloc = 0;
252b5132 4083
566b0d53 4084 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 4085 {
566b0d53
L
4086 is_rela = dynamic_relocations [i].rela;
4087 name = dynamic_relocations [i].name;
4088 rel_size = dynamic_info [dynamic_relocations [i].size];
4089 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 4090
566b0d53
L
4091 has_dynamic_reloc |= rel_size;
4092
4093 if (is_rela == UNKNOWN)
aa903cfb 4094 {
566b0d53
L
4095 if (dynamic_relocations [i].reloc == DT_JMPREL)
4096 switch (dynamic_info[DT_PLTREL])
4097 {
4098 case DT_REL:
4099 is_rela = FALSE;
4100 break;
4101 case DT_RELA:
4102 is_rela = TRUE;
4103 break;
4104 }
aa903cfb 4105 }
252b5132 4106
566b0d53
L
4107 if (rel_size)
4108 {
4109 printf
4110 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
4111 name, rel_offset, rel_size);
252b5132 4112
d93f0186
NC
4113 dump_relocations (file,
4114 offset_from_vma (file, rel_offset, rel_size),
4115 rel_size,
566b0d53
L
4116 dynamic_symbols, num_dynamic_syms,
4117 dynamic_strings, is_rela);
4118 }
252b5132 4119 }
566b0d53
L
4120
4121 if (! has_dynamic_reloc)
252b5132
RH
4122 printf (_("\nThere are no dynamic relocations in this file.\n"));
4123 }
4124 else
4125 {
b34976b6
AM
4126 Elf_Internal_Shdr *section;
4127 unsigned long i;
4128 int found = 0;
252b5132
RH
4129
4130 for (i = 0, section = section_headers;
4131 i < elf_header.e_shnum;
b34976b6 4132 i++, section++)
252b5132
RH
4133 {
4134 if ( section->sh_type != SHT_RELA
4135 && section->sh_type != SHT_REL)
4136 continue;
4137
4138 rel_offset = section->sh_offset;
4139 rel_size = section->sh_size;
4140
4141 if (rel_size)
4142 {
b34976b6
AM
4143 Elf_Internal_Shdr *strsec;
4144 Elf_Internal_Sym *symtab;
4145 char *strtab;
4146 int is_rela;
4147 unsigned long nsyms;
103f02d3 4148
252b5132
RH
4149 printf (_("\nRelocation section "));
4150
4151 if (string_table == NULL)
19936277 4152 printf ("%d", section->sh_name);
252b5132 4153 else
3a1a2036 4154 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
4155
4156 printf (_(" at offset 0x%lx contains %lu entries:\n"),
4157 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
4158
af3fc3bc
AM
4159 symtab = NULL;
4160 strtab = NULL;
4161 nsyms = 0;
4162 if (section->sh_link)
4163 {
b34976b6 4164 Elf_Internal_Shdr *symsec;
252b5132 4165
9ad5cbcf 4166 symsec = SECTION_HEADER (section->sh_link);
af3fc3bc 4167 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 4168 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 4169
af3fc3bc
AM
4170 if (symtab == NULL)
4171 continue;
252b5132 4172
9ad5cbcf 4173 strsec = SECTION_HEADER (symsec->sh_link);
103f02d3 4174
d3ba0551
AM
4175 strtab = get_data (NULL, file, strsec->sh_offset,
4176 strsec->sh_size, _("string table"));
af3fc3bc 4177 }
aa903cfb 4178 is_rela = section->sh_type == SHT_RELA;
252b5132 4179
af3fc3bc
AM
4180 dump_relocations (file, rel_offset, rel_size,
4181 symtab, nsyms, strtab, is_rela);
252b5132 4182
af3fc3bc
AM
4183 if (strtab)
4184 free (strtab);
4185 if (symtab)
4186 free (symtab);
252b5132
RH
4187
4188 found = 1;
4189 }
4190 }
4191
4192 if (! found)
4193 printf (_("\nThere are no relocations in this file.\n"));
4194 }
4195
4196 return 1;
4197}
4198
4d6ed7c8
NC
4199#include "unwind-ia64.h"
4200
4201/* An absolute address consists of a section and an offset. If the
4202 section is NULL, the offset itself is the address, otherwise, the
4203 address equals to LOAD_ADDRESS(section) + offset. */
4204
4205struct absaddr
4206 {
4207 unsigned short section;
4208 bfd_vma offset;
4209 };
4210
4211struct unw_aux_info
4212 {
4213 struct unw_table_entry
4214 {
b34976b6
AM
4215 struct absaddr start;
4216 struct absaddr end;
4217 struct absaddr info;
4d6ed7c8 4218 }
b34976b6
AM
4219 *table; /* Unwind table. */
4220 unsigned long table_len; /* Length of unwind table. */
4221 unsigned char *info; /* Unwind info. */
4222 unsigned long info_size; /* Size of unwind info. */
4223 bfd_vma info_addr; /* starting address of unwind info. */
4224 bfd_vma seg_base; /* Starting address of segment. */
4225 Elf_Internal_Sym *symtab; /* The symbol table. */
4226 unsigned long nsyms; /* Number of symbols. */
4227 char *strtab; /* The string table. */
4228 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
4229 };
4230
4d6ed7c8 4231static void
d3ba0551
AM
4232find_symbol_for_address (struct unw_aux_info *aux,
4233 struct absaddr addr,
4234 const char **symname,
4235 bfd_vma *offset)
4d6ed7c8 4236{
d3ba0551 4237 bfd_vma dist = 0x100000;
4d6ed7c8
NC
4238 Elf_Internal_Sym *sym, *best = NULL;
4239 unsigned long i;
4240
4241 for (i = 0, sym = aux->symtab; i < aux->nsyms; ++i, ++sym)
4242 {
4243 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
4244 && sym->st_name != 0
4245 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
4246 && addr.offset >= sym->st_value
4247 && addr.offset - sym->st_value < dist)
4248 {
4249 best = sym;
4250 dist = addr.offset - sym->st_value;
4251 if (!dist)
4252 break;
4253 }
4254 }
4255 if (best)
4256 {
4257 *symname = (best->st_name >= aux->strtab_size
4258 ? "<corrupt>" : aux->strtab + best->st_name);
4259 *offset = dist;
4260 return;
4261 }
4262 *symname = NULL;
4263 *offset = addr.offset;
4264}
4265
4266static void
d3ba0551 4267dump_ia64_unwind (struct unw_aux_info *aux)
4d6ed7c8
NC
4268{
4269 bfd_vma addr_size;
b34976b6 4270 struct unw_table_entry *tp;
4d6ed7c8 4271 int in_body;
7036c0e1 4272
4d6ed7c8
NC
4273 addr_size = is_32bit_elf ? 4 : 8;
4274
4275 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
4276 {
4277 bfd_vma stamp;
4278 bfd_vma offset;
b34976b6
AM
4279 const unsigned char *dp;
4280 const unsigned char *head;
4281 const char *procname;
4d6ed7c8
NC
4282
4283 find_symbol_for_address (aux, tp->start, &procname, &offset);
4284
4285 fputs ("\n<", stdout);
4286
4287 if (procname)
4288 {
4289 fputs (procname, stdout);
4290
4291 if (offset)
4292 printf ("+%lx", (unsigned long) offset);
4293 }
4294
4295 fputs (">: [", stdout);
4296 print_vma (tp->start.offset, PREFIX_HEX);
4297 fputc ('-', stdout);
4298 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 4299 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
4300 (unsigned long) (tp->info.offset - aux->seg_base));
4301
4302 head = aux->info + (tp->info.offset - aux->info_addr);
4303 stamp = BYTE_GET8 ((unsigned char *) head);
4304
86f55779 4305 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
4306 (unsigned) UNW_VER (stamp),
4307 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
4308 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
4309 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
4310 (unsigned long) (addr_size * UNW_LENGTH (stamp)));
4311
4312 if (UNW_VER (stamp) != 1)
4313 {
4314 printf ("\tUnknown version.\n");
4315 continue;
4316 }
4317
4318 in_body = 0;
4319 for (dp = head + 8; dp < head + 8 + addr_size * UNW_LENGTH (stamp);)
4320 dp = unw_decode (dp, in_body, & in_body);
4321 }
4322}
4323
4324static int
d3ba0551
AM
4325slurp_ia64_unwind_table (FILE *file,
4326 struct unw_aux_info *aux,
4327 Elf_Internal_Shdr *sec)
4d6ed7c8
NC
4328{
4329 unsigned long size, addr_size, nrelas, i;
d93f0186 4330 Elf_Internal_Phdr *seg;
4d6ed7c8 4331 struct unw_table_entry *tep;
c8286bd1 4332 Elf_Internal_Shdr *relsec;
4d6ed7c8
NC
4333 Elf_Internal_Rela *rela, *rp;
4334 unsigned char *table, *tp;
4335 Elf_Internal_Sym *sym;
4336 const char *relname;
4d6ed7c8
NC
4337
4338 addr_size = is_32bit_elf ? 4 : 8;
4339
4340 /* First, find the starting address of the segment that includes
4341 this section: */
4342
4343 if (elf_header.e_phnum)
4344 {
d93f0186 4345 if (! get_program_headers (file))
4d6ed7c8 4346 return 0;
4d6ed7c8 4347
d93f0186
NC
4348 for (seg = program_headers;
4349 seg < program_headers + elf_header.e_phnum;
4350 ++seg)
4d6ed7c8
NC
4351 {
4352 if (seg->p_type != PT_LOAD)
4353 continue;
4354
4355 if (sec->sh_addr >= seg->p_vaddr
4356 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
4357 {
4358 aux->seg_base = seg->p_vaddr;
4359 break;
4360 }
4361 }
4d6ed7c8
NC
4362 }
4363
4364 /* Second, build the unwind table from the contents of the unwind section: */
4365 size = sec->sh_size;
d3ba0551 4366 table = get_data (NULL, file, sec->sh_offset, size, _("unwind table"));
a6e9f9df
AM
4367 if (!table)
4368 return 0;
4d6ed7c8
NC
4369
4370 tep = aux->table = xmalloc (size / (3 * addr_size) * sizeof (aux->table[0]));
b34976b6 4371 for (tp = table; tp < table + size; tp += 3 * addr_size, ++tep)
4d6ed7c8
NC
4372 {
4373 tep->start.section = SHN_UNDEF;
4374 tep->end.section = SHN_UNDEF;
4375 tep->info.section = SHN_UNDEF;
4376 if (is_32bit_elf)
4377 {
4378 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
4379 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
4380 tep->info.offset = byte_get ((unsigned char *) tp + 8, 4);
4381 }
4382 else
4383 {
4384 tep->start.offset = BYTE_GET8 ((unsigned char *) tp + 0);
4385 tep->end.offset = BYTE_GET8 ((unsigned char *) tp + 8);
4386 tep->info.offset = BYTE_GET8 ((unsigned char *) tp + 16);
4387 }
4388 tep->start.offset += aux->seg_base;
4389 tep->end.offset += aux->seg_base;
4390 tep->info.offset += aux->seg_base;
4391 }
4392 free (table);
4393
4394 /* Third, apply any relocations to the unwind table: */
4395
4396 for (relsec = section_headers;
4397 relsec < section_headers + elf_header.e_shnum;
4398 ++relsec)
4399 {
4400 if (relsec->sh_type != SHT_RELA
9ad5cbcf 4401 || SECTION_HEADER (relsec->sh_info) != sec)
4d6ed7c8
NC
4402 continue;
4403
4404 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
4405 & rela, & nrelas))
4406 return 0;
4407
4408 for (rp = rela; rp < rela + nrelas; ++rp)
4409 {
4410 if (is_32bit_elf)
4411 {
4412 relname = elf_ia64_reloc_type (ELF32_R_TYPE (rp->r_info));
4413 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
4414
4415 if (ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
4416 {
e5fb9629 4417 warn (_("Skipping unexpected symbol type %u\n"),
4d6ed7c8
NC
4418 ELF32_ST_TYPE (sym->st_info));
4419 continue;
4420 }
4421 }
4422 else
4423 {
4424 relname = elf_ia64_reloc_type (ELF64_R_TYPE (rp->r_info));
4425 sym = aux->symtab + ELF64_R_SYM (rp->r_info);
4426
4427 if (ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
4428 {
e5fb9629 4429 warn (_("Skipping unexpected symbol type %u\n"),
4d6ed7c8
NC
4430 ELF64_ST_TYPE (sym->st_info));
4431 continue;
4432 }
4433 }
4434
4435 if (strncmp (relname, "R_IA64_SEGREL", 13) != 0)
4436 {
e5fb9629 4437 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
4438 continue;
4439 }
4440
4441 i = rp->r_offset / (3 * addr_size);
4442
4443 switch (rp->r_offset/addr_size % 3)
4444 {
4445 case 0:
4446 aux->table[i].start.section = sym->st_shndx;
4447 aux->table[i].start.offset += rp->r_addend;
4448 break;
4449 case 1:
4450 aux->table[i].end.section = sym->st_shndx;
4451 aux->table[i].end.offset += rp->r_addend;
4452 break;
4453 case 2:
4454 aux->table[i].info.section = sym->st_shndx;
4455 aux->table[i].info.offset += rp->r_addend;
4456 break;
4457 default:
4458 break;
4459 }
4460 }
4461
4462 free (rela);
4463 }
4464
4465 aux->table_len = size / (3 * addr_size);
4466 return 1;
4467}
4468
4469static int
d3ba0551 4470process_unwind (FILE *file)
4d6ed7c8 4471{
c8286bd1 4472 Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
579f31ac 4473 unsigned long i, addr_size, unwcount = 0, unwstart = 0;
4d6ed7c8
NC
4474 struct unw_aux_info aux;
4475
e58d53af
L
4476 if (!do_unwind)
4477 return 1;
4478
f1467e33
L
4479 if (elf_header.e_machine != EM_IA_64)
4480 {
4481 printf (_("\nThere are no unwind sections in this file.\n"));
4482 return 1;
4483 }
4484
4d6ed7c8
NC
4485 memset (& aux, 0, sizeof (aux));
4486
4487 addr_size = is_32bit_elf ? 4 : 8;
4488
4d6ed7c8
NC
4489 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
4490 {
4491 if (sec->sh_type == SHT_SYMTAB)
4492 {
4493 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 4494 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 4495
9ad5cbcf 4496 strsec = SECTION_HEADER (sec->sh_link);
4d6ed7c8 4497 aux.strtab_size = strsec->sh_size;
d3ba0551
AM
4498 aux.strtab = get_data (NULL, file, strsec->sh_offset,
4499 aux.strtab_size, _("string table"));
4d6ed7c8
NC
4500 }
4501 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
4502 unwcount++;
4503 }
4504
4505 if (!unwcount)
4506 printf (_("\nThere are no unwind sections in this file.\n"));
4507
4508 while (unwcount-- > 0)
4509 {
4510 char *suffix;
4511 size_t len, len2;
4512
4513 for (i = unwstart, sec = section_headers + unwstart;
4514 i < elf_header.e_shnum; ++i, ++sec)
4515 if (sec->sh_type == SHT_IA_64_UNWIND)
4516 {
4517 unwsec = sec;
4518 break;
4519 }
4520
4521 unwstart = i + 1;
4522 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
4523
e4b17d5c
L
4524 if ((unwsec->sh_flags & SHF_GROUP) != 0)
4525 {
4526 /* We need to find which section group it is in. */
4527 struct group_list *g = section_headers_groups [i]->root;
4528
4529 for (; g != NULL; g = g->next)
4530 {
4531 sec = SECTION_HEADER (g->section_index);
4532 if (strcmp (SECTION_NAME (sec),
4533 ELF_STRING_ia64_unwind_info) == 0)
4534 break;
4535 }
4536
4537 if (g == NULL)
4538 i = elf_header.e_shnum;
4539 }
4540 else if (strncmp (SECTION_NAME (unwsec),
4541 ELF_STRING_ia64_unwind_once, len) == 0)
579f31ac
JJ
4542 {
4543 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO */
4544 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
4545 suffix = SECTION_NAME (unwsec) + len;
4546 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
4547 ++i, ++sec)
4548 if (strncmp (SECTION_NAME (sec),
4549 ELF_STRING_ia64_unwind_info_once, len2) == 0
4550 && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
4551 break;
4552 }
4553 else
4554 {
4555 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
4556 .IA_64.unwind or BAR -> .IA_64.unwind_info */
4557 len = sizeof (ELF_STRING_ia64_unwind) - 1;
4558 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
4559 suffix = "";
4560 if (strncmp (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind,
4561 len) == 0)
4562 suffix = SECTION_NAME (unwsec) + len;
4563 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
4564 ++i, ++sec)
4565 if (strncmp (SECTION_NAME (sec),
4566 ELF_STRING_ia64_unwind_info, len2) == 0
4567 && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
4568 break;
4569 }
4570
4571 if (i == elf_header.e_shnum)
4572 {
4573 printf (_("\nCould not find unwind info section for "));
4574
4575 if (string_table == NULL)
4576 printf ("%d", unwsec->sh_name);
4577 else
3a1a2036 4578 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
4579 }
4580 else
4d6ed7c8
NC
4581 {
4582 aux.info_size = sec->sh_size;
4583 aux.info_addr = sec->sh_addr;
d3ba0551
AM
4584 aux.info = get_data (NULL, file, sec->sh_offset, aux.info_size,
4585 _("unwind info"));
4d6ed7c8 4586
579f31ac 4587 printf (_("\nUnwind section "));
4d6ed7c8 4588
579f31ac
JJ
4589 if (string_table == NULL)
4590 printf ("%d", unwsec->sh_name);
4591 else
3a1a2036 4592 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 4593
579f31ac 4594 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 4595 (unsigned long) unwsec->sh_offset,
579f31ac 4596 (unsigned long) (unwsec->sh_size / (3 * addr_size)));
4d6ed7c8 4597
579f31ac 4598 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 4599
579f31ac
JJ
4600 if (aux.table_len > 0)
4601 dump_ia64_unwind (& aux);
4602
4603 if (aux.table)
4604 free ((char *) aux.table);
4605 if (aux.info)
4606 free ((char *) aux.info);
4607 aux.table = NULL;
4608 aux.info = NULL;
4609 }
4d6ed7c8 4610 }
4d6ed7c8 4611
4d6ed7c8
NC
4612 if (aux.symtab)
4613 free (aux.symtab);
4614 if (aux.strtab)
4615 free ((char *) aux.strtab);
4616
4617 return 1;
4618}
4619
252b5132 4620static void
b2d38a17 4621dynamic_section_mips_val (Elf_Internal_Dyn *entry)
252b5132
RH
4622{
4623 switch (entry->d_tag)
4624 {
4625 case DT_MIPS_FLAGS:
4626 if (entry->d_un.d_val == 0)
4627 printf ("NONE\n");
4628 else
4629 {
4630 static const char * opts[] =
4631 {
4632 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
4633 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
4634 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
4635 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
4636 "RLD_ORDER_SAFE"
4637 };
4638 unsigned int cnt;
4639 int first = 1;
b34976b6 4640 for (cnt = 0; cnt < NUM_ELEM (opts); ++cnt)
252b5132
RH
4641 if (entry->d_un.d_val & (1 << cnt))
4642 {
4643 printf ("%s%s", first ? "" : " ", opts[cnt]);
4644 first = 0;
4645 }
4646 puts ("");
4647 }
4648 break;
103f02d3 4649
252b5132
RH
4650 case DT_MIPS_IVERSION:
4651 if (dynamic_strings != NULL)
4652 printf ("Interface Version: %s\n",
4653 dynamic_strings + entry->d_un.d_val);
4654 else
4655 printf ("%ld\n", (long) entry->d_un.d_ptr);
4656 break;
103f02d3 4657
252b5132
RH
4658 case DT_MIPS_TIME_STAMP:
4659 {
4660 char timebuf[20];
b34976b6 4661 struct tm *tmp;
50da7a9c 4662
252b5132 4663 time_t time = entry->d_un.d_val;
50da7a9c
NC
4664 tmp = gmtime (&time);
4665 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
4666 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
4667 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
4668 printf ("Time Stamp: %s\n", timebuf);
4669 }
4670 break;
103f02d3 4671
252b5132
RH
4672 case DT_MIPS_RLD_VERSION:
4673 case DT_MIPS_LOCAL_GOTNO:
4674 case DT_MIPS_CONFLICTNO:
4675 case DT_MIPS_LIBLISTNO:
4676 case DT_MIPS_SYMTABNO:
4677 case DT_MIPS_UNREFEXTNO:
4678 case DT_MIPS_HIPAGENO:
4679 case DT_MIPS_DELTA_CLASS_NO:
4680 case DT_MIPS_DELTA_INSTANCE_NO:
4681 case DT_MIPS_DELTA_RELOC_NO:
4682 case DT_MIPS_DELTA_SYM_NO:
4683 case DT_MIPS_DELTA_CLASSSYM_NO:
4684 case DT_MIPS_COMPACT_SIZE:
4685 printf ("%ld\n", (long) entry->d_un.d_ptr);
4686 break;
103f02d3
UD
4687
4688 default:
4689 printf ("%#lx\n", (long) entry->d_un.d_ptr);
4690 }
4691}
4692
4693
4694static void
b2d38a17 4695dynamic_section_parisc_val (Elf_Internal_Dyn *entry)
103f02d3
UD
4696{
4697 switch (entry->d_tag)
4698 {
4699 case DT_HP_DLD_FLAGS:
4700 {
4701 static struct
4702 {
4703 long int bit;
b34976b6 4704 const char *str;
5e220199
NC
4705 }
4706 flags[] =
4707 {
4708 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
4709 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
4710 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
4711 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
4712 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
4713 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
4714 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
4715 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
4716 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
4717 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
4718 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" }
4719 };
103f02d3 4720 int first = 1;
5e220199 4721 size_t cnt;
f7a99963 4722 bfd_vma val = entry->d_un.d_val;
103f02d3
UD
4723
4724 for (cnt = 0; cnt < sizeof (flags) / sizeof (flags[0]); ++cnt)
4725 if (val & flags[cnt].bit)
30800947
NC
4726 {
4727 if (! first)
4728 putchar (' ');
4729 fputs (flags[cnt].str, stdout);
4730 first = 0;
4731 val ^= flags[cnt].bit;
4732 }
76da6bbe 4733
103f02d3 4734 if (val != 0 || first)
f7a99963
NC
4735 {
4736 if (! first)
4737 putchar (' ');
4738 print_vma (val, HEX);
4739 }
103f02d3
UD
4740 }
4741 break;
76da6bbe 4742
252b5132 4743 default:
f7a99963
NC
4744 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
4745 break;
252b5132 4746 }
35b1837e 4747 putchar ('\n');
252b5132
RH
4748}
4749
ecc51f48 4750static void
b2d38a17 4751dynamic_section_ia64_val (Elf_Internal_Dyn *entry)
ecc51f48
NC
4752{
4753 switch (entry->d_tag)
4754 {
0de14b54 4755 case DT_IA_64_PLT_RESERVE:
bdf4d63a 4756 /* First 3 slots reserved. */
ecc51f48
NC
4757 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
4758 printf (" -- ");
4759 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
4760 break;
4761
4762 default:
4763 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
4764 break;
ecc51f48 4765 }
bdf4d63a 4766 putchar ('\n');
ecc51f48
NC
4767}
4768
252b5132 4769static int
b2d38a17 4770get_32bit_dynamic_section (FILE *file)
252b5132 4771{
fb514b26 4772 Elf32_External_Dyn *edyn, *ext;
b34976b6 4773 Elf_Internal_Dyn *entry;
103f02d3 4774
d3ba0551 4775 edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
b2d38a17 4776 _("dynamic section"));
a6e9f9df
AM
4777 if (!edyn)
4778 return 0;
103f02d3 4779
ba2685cc
AM
4780/* SGI's ELF has more than one section in the DYNAMIC segment, and we
4781 might not have the luxury of section headers. Look for the DT_NULL
4782 terminator to determine the number of entries. */
4783 for (ext = edyn, dynamic_nent = 0;
4784 (char *) ext < (char *) edyn + dynamic_size;
4785 ext++)
4786 {
4787 dynamic_nent++;
4788 if (BYTE_GET (ext->d_tag) == DT_NULL)
4789 break;
4790 }
252b5132 4791
ba2685cc 4792 dynamic_section = malloc (dynamic_nent * sizeof (*entry));
b2d38a17 4793 if (dynamic_section == NULL)
252b5132 4794 {
9ea033b2
NC
4795 error (_("Out of memory\n"));
4796 free (edyn);
4797 return 0;
4798 }
252b5132 4799
fb514b26 4800 for (ext = edyn, entry = dynamic_section;
ba2685cc 4801 entry < dynamic_section + dynamic_nent;
fb514b26 4802 ext++, entry++)
9ea033b2 4803 {
fb514b26
AM
4804 entry->d_tag = BYTE_GET (ext->d_tag);
4805 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
4806 }
4807
9ea033b2
NC
4808 free (edyn);
4809
4810 return 1;
4811}
4812
4813static int
b2d38a17 4814get_64bit_dynamic_section (FILE *file)
9ea033b2 4815{
fb514b26 4816 Elf64_External_Dyn *edyn, *ext;
b34976b6 4817 Elf_Internal_Dyn *entry;
103f02d3 4818
d3ba0551 4819 edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
b2d38a17 4820 _("dynamic section"));
a6e9f9df
AM
4821 if (!edyn)
4822 return 0;
103f02d3 4823
ba2685cc
AM
4824/* SGI's ELF has more than one section in the DYNAMIC segment, and we
4825 might not have the luxury of section headers. Look for the DT_NULL
4826 terminator to determine the number of entries. */
4827 for (ext = edyn, dynamic_nent = 0;
4828 (char *) ext < (char *) edyn + dynamic_size;
4829 ext++)
4830 {
4831 dynamic_nent++;
4832 if (BYTE_GET8 (ext->d_tag) == DT_NULL)
4833 break;
4834 }
252b5132 4835
ba2685cc 4836 dynamic_section = malloc (dynamic_nent * sizeof (*entry));
b2d38a17 4837 if (dynamic_section == NULL)
252b5132
RH
4838 {
4839 error (_("Out of memory\n"));
4840 free (edyn);
4841 return 0;
4842 }
4843
fb514b26 4844 for (ext = edyn, entry = dynamic_section;
ba2685cc 4845 entry < dynamic_section + dynamic_nent;
fb514b26 4846 ext++, entry++)
252b5132 4847 {
fb514b26
AM
4848 entry->d_tag = BYTE_GET8 (ext->d_tag);
4849 entry->d_un.d_val = BYTE_GET8 (ext->d_un.d_val);
252b5132
RH
4850 }
4851
4852 free (edyn);
4853
9ea033b2
NC
4854 return 1;
4855}
4856
d1133906 4857static const char *
d3ba0551 4858get_dynamic_flags (bfd_vma flags)
d1133906 4859{
b34976b6 4860 static char buff[128];
13ae64f3
JJ
4861 char *p = buff;
4862
4863 *p = '\0';
d1133906
NC
4864 while (flags)
4865 {
4866 bfd_vma flag;
4867
4868 flag = flags & - flags;
4869 flags &= ~ flag;
4870
13ae64f3
JJ
4871 if (p != buff)
4872 *p++ = ' ';
4873
d1133906
NC
4874 switch (flag)
4875 {
b34976b6
AM
4876 case DF_ORIGIN: strcpy (p, "ORIGIN"); break;
4877 case DF_SYMBOLIC: strcpy (p, "SYMBOLIC"); break;
4878 case DF_TEXTREL: strcpy (p, "TEXTREL"); break;
4879 case DF_BIND_NOW: strcpy (p, "BIND_NOW"); break;
4880 case DF_STATIC_TLS: strcpy (p, "STATIC_TLS"); break;
4881 default: strcpy (p, "unknown"); break;
d1133906 4882 }
13ae64f3
JJ
4883
4884 p = strchr (p, '\0');
d1133906 4885 }
305c7206 4886 return buff;
d1133906
NC
4887}
4888
b2d38a17
NC
4889/* Parse and display the contents of the dynamic section. */
4890
9ea033b2 4891static int
b2d38a17 4892process_dynamic_section (FILE *file)
9ea033b2 4893{
b34976b6 4894 Elf_Internal_Dyn *entry;
9ea033b2
NC
4895
4896 if (dynamic_size == 0)
4897 {
4898 if (do_dynamic)
b2d38a17 4899 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
4900
4901 return 1;
4902 }
4903
4904 if (is_32bit_elf)
4905 {
b2d38a17 4906 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
4907 return 0;
4908 }
b2d38a17 4909 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
4910 return 0;
4911
252b5132
RH
4912 /* Find the appropriate symbol table. */
4913 if (dynamic_symbols == NULL)
4914 {
86dba8ee
AM
4915 for (entry = dynamic_section;
4916 entry < dynamic_section + dynamic_nent;
4917 ++entry)
252b5132 4918 {
c8286bd1 4919 Elf_Internal_Shdr section;
252b5132
RH
4920
4921 if (entry->d_tag != DT_SYMTAB)
4922 continue;
4923
4924 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
4925
4926 /* Since we do not know how big the symbol table is,
4927 we default to reading in the entire file (!) and
4928 processing that. This is overkill, I know, but it
e3c8793a 4929 should work. */
d93f0186 4930 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 4931
fb52b2f4
NC
4932 if (archive_file_offset != 0)
4933 section.sh_size = archive_file_size - section.sh_offset;
4934 else
4935 {
4936 if (fseek (file, 0, SEEK_END))
4937 error (_("Unable to seek to end of file!"));
4938
4939 section.sh_size = ftell (file) - section.sh_offset;
4940 }
252b5132 4941
9ea033b2 4942 if (is_32bit_elf)
9ad5cbcf 4943 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 4944 else
9ad5cbcf 4945 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 4946
9ad5cbcf 4947 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 4948 if (num_dynamic_syms < 1)
252b5132
RH
4949 {
4950 error (_("Unable to determine the number of symbols to load\n"));
4951 continue;
4952 }
4953
9ad5cbcf 4954 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
4955 }
4956 }
4957
4958 /* Similarly find a string table. */
4959 if (dynamic_strings == NULL)
4960 {
86dba8ee
AM
4961 for (entry = dynamic_section;
4962 entry < dynamic_section + dynamic_nent;
4963 ++entry)
252b5132
RH
4964 {
4965 unsigned long offset;
b34976b6 4966 long str_tab_len;
252b5132
RH
4967
4968 if (entry->d_tag != DT_STRTAB)
4969 continue;
4970
4971 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
4972
4973 /* Since we do not know how big the string table is,
4974 we default to reading in the entire file (!) and
4975 processing that. This is overkill, I know, but it
e3c8793a 4976 should work. */
252b5132 4977
d93f0186 4978 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
4979
4980 if (archive_file_offset != 0)
4981 str_tab_len = archive_file_size - offset;
4982 else
4983 {
4984 if (fseek (file, 0, SEEK_END))
4985 error (_("Unable to seek to end of file\n"));
4986 str_tab_len = ftell (file) - offset;
4987 }
252b5132
RH
4988
4989 if (str_tab_len < 1)
4990 {
4991 error
4992 (_("Unable to determine the length of the dynamic string table\n"));
4993 continue;
4994 }
4995
d3ba0551
AM
4996 dynamic_strings = get_data (NULL, file, offset, str_tab_len,
4997 _("dynamic string table"));
252b5132
RH
4998 break;
4999 }
5000 }
5001
5002 /* And find the syminfo section if available. */
5003 if (dynamic_syminfo == NULL)
5004 {
3e8bba36 5005 unsigned long syminsz = 0;
252b5132 5006
86dba8ee
AM
5007 for (entry = dynamic_section;
5008 entry < dynamic_section + dynamic_nent;
5009 ++entry)
252b5132
RH
5010 {
5011 if (entry->d_tag == DT_SYMINENT)
5012 {
5013 /* Note: these braces are necessary to avoid a syntax
5014 error from the SunOS4 C compiler. */
5015 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
5016 }
5017 else if (entry->d_tag == DT_SYMINSZ)
5018 syminsz = entry->d_un.d_val;
5019 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
5020 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
5021 syminsz);
252b5132
RH
5022 }
5023
5024 if (dynamic_syminfo_offset != 0 && syminsz != 0)
5025 {
86dba8ee 5026 Elf_External_Syminfo *extsyminfo, *extsym;
b34976b6 5027 Elf_Internal_Syminfo *syminfo;
252b5132
RH
5028
5029 /* There is a syminfo section. Read the data. */
d3ba0551
AM
5030 extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, syminsz,
5031 _("symbol information"));
a6e9f9df
AM
5032 if (!extsyminfo)
5033 return 0;
252b5132 5034
d3ba0551 5035 dynamic_syminfo = malloc (syminsz);
252b5132
RH
5036 if (dynamic_syminfo == NULL)
5037 {
5038 error (_("Out of memory\n"));
5039 return 0;
5040 }
5041
5042 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
5043 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
5044 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
5045 ++syminfo, ++extsym)
252b5132 5046 {
86dba8ee
AM
5047 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
5048 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
5049 }
5050
5051 free (extsyminfo);
5052 }
5053 }
5054
5055 if (do_dynamic && dynamic_addr)
86dba8ee
AM
5056 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
5057 dynamic_addr, dynamic_nent);
252b5132
RH
5058 if (do_dynamic)
5059 printf (_(" Tag Type Name/Value\n"));
5060
86dba8ee
AM
5061 for (entry = dynamic_section;
5062 entry < dynamic_section + dynamic_nent;
5063 entry++)
252b5132
RH
5064 {
5065 if (do_dynamic)
f7a99963 5066 {
b34976b6 5067 const char *dtype;
e699b9ff 5068
f7a99963
NC
5069 putchar (' ');
5070 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
5071 dtype = get_dynamic_type (entry->d_tag);
5072 printf (" (%s)%*s", dtype,
5073 ((is_32bit_elf ? 27 : 19)
5074 - (int) strlen (dtype)),
f7a99963
NC
5075 " ");
5076 }
252b5132
RH
5077
5078 switch (entry->d_tag)
5079 {
d1133906
NC
5080 case DT_FLAGS:
5081 if (do_dynamic)
13ae64f3 5082 puts (get_dynamic_flags (entry->d_un.d_val));
d1133906 5083 break;
76da6bbe 5084
252b5132
RH
5085 case DT_AUXILIARY:
5086 case DT_FILTER:
019148e4
L
5087 case DT_CONFIG:
5088 case DT_DEPAUDIT:
5089 case DT_AUDIT:
252b5132
RH
5090 if (do_dynamic)
5091 {
019148e4 5092 switch (entry->d_tag)
b34976b6 5093 {
019148e4
L
5094 case DT_AUXILIARY:
5095 printf (_("Auxiliary library"));
5096 break;
5097
5098 case DT_FILTER:
5099 printf (_("Filter library"));
5100 break;
5101
b34976b6 5102 case DT_CONFIG:
019148e4
L
5103 printf (_("Configuration file"));
5104 break;
5105
5106 case DT_DEPAUDIT:
5107 printf (_("Dependency audit library"));
5108 break;
5109
5110 case DT_AUDIT:
5111 printf (_("Audit library"));
5112 break;
5113 }
252b5132
RH
5114
5115 if (dynamic_strings)
5116 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
5117 else
f7a99963
NC
5118 {
5119 printf (": ");
5120 print_vma (entry->d_un.d_val, PREFIX_HEX);
5121 putchar ('\n');
5122 }
252b5132
RH
5123 }
5124 break;
5125
dcefbbbd 5126 case DT_FEATURE:
252b5132
RH
5127 if (do_dynamic)
5128 {
5129 printf (_("Flags:"));
86f55779 5130
252b5132
RH
5131 if (entry->d_un.d_val == 0)
5132 printf (_(" None\n"));
5133 else
5134 {
5135 unsigned long int val = entry->d_un.d_val;
86f55779 5136
252b5132
RH
5137 if (val & DTF_1_PARINIT)
5138 {
5139 printf (" PARINIT");
5140 val ^= DTF_1_PARINIT;
5141 }
dcefbbbd
L
5142 if (val & DTF_1_CONFEXP)
5143 {
5144 printf (" CONFEXP");
5145 val ^= DTF_1_CONFEXP;
5146 }
252b5132
RH
5147 if (val != 0)
5148 printf (" %lx", val);
5149 puts ("");
5150 }
5151 }
5152 break;
5153
5154 case DT_POSFLAG_1:
5155 if (do_dynamic)
5156 {
5157 printf (_("Flags:"));
86f55779 5158
252b5132
RH
5159 if (entry->d_un.d_val == 0)
5160 printf (_(" None\n"));
5161 else
5162 {
5163 unsigned long int val = entry->d_un.d_val;
86f55779 5164
252b5132
RH
5165 if (val & DF_P1_LAZYLOAD)
5166 {
5167 printf (" LAZYLOAD");
5168 val ^= DF_P1_LAZYLOAD;
5169 }
5170 if (val & DF_P1_GROUPPERM)
5171 {
5172 printf (" GROUPPERM");
5173 val ^= DF_P1_GROUPPERM;
5174 }
5175 if (val != 0)
5176 printf (" %lx", val);
5177 puts ("");
5178 }
5179 }
5180 break;
5181
5182 case DT_FLAGS_1:
5183 if (do_dynamic)
5184 {
5185 printf (_("Flags:"));
5186 if (entry->d_un.d_val == 0)
5187 printf (_(" None\n"));
5188 else
5189 {
5190 unsigned long int val = entry->d_un.d_val;
86f55779 5191
252b5132
RH
5192 if (val & DF_1_NOW)
5193 {
5194 printf (" NOW");
5195 val ^= DF_1_NOW;
5196 }
5197 if (val & DF_1_GLOBAL)
5198 {
5199 printf (" GLOBAL");
5200 val ^= DF_1_GLOBAL;
5201 }
5202 if (val & DF_1_GROUP)
5203 {
5204 printf (" GROUP");
5205 val ^= DF_1_GROUP;
5206 }
5207 if (val & DF_1_NODELETE)
5208 {
5209 printf (" NODELETE");
5210 val ^= DF_1_NODELETE;
5211 }
5212 if (val & DF_1_LOADFLTR)
5213 {
5214 printf (" LOADFLTR");
5215 val ^= DF_1_LOADFLTR;
5216 }
5217 if (val & DF_1_INITFIRST)
5218 {
5219 printf (" INITFIRST");
5220 val ^= DF_1_INITFIRST;
5221 }
5222 if (val & DF_1_NOOPEN)
5223 {
5224 printf (" NOOPEN");
5225 val ^= DF_1_NOOPEN;
5226 }
5227 if (val & DF_1_ORIGIN)
5228 {
5229 printf (" ORIGIN");
5230 val ^= DF_1_ORIGIN;
5231 }
5232 if (val & DF_1_DIRECT)
5233 {
5234 printf (" DIRECT");
5235 val ^= DF_1_DIRECT;
5236 }
5237 if (val & DF_1_TRANS)
5238 {
5239 printf (" TRANS");
5240 val ^= DF_1_TRANS;
5241 }
5242 if (val & DF_1_INTERPOSE)
5243 {
5244 printf (" INTERPOSE");
5245 val ^= DF_1_INTERPOSE;
5246 }
f7db6139 5247 if (val & DF_1_NODEFLIB)
dcefbbbd 5248 {
f7db6139
L
5249 printf (" NODEFLIB");
5250 val ^= DF_1_NODEFLIB;
dcefbbbd
L
5251 }
5252 if (val & DF_1_NODUMP)
5253 {
5254 printf (" NODUMP");
5255 val ^= DF_1_NODUMP;
5256 }
5257 if (val & DF_1_CONLFAT)
5258 {
5259 printf (" CONLFAT");
5260 val ^= DF_1_CONLFAT;
5261 }
252b5132
RH
5262 if (val != 0)
5263 printf (" %lx", val);
5264 puts ("");
5265 }
5266 }
5267 break;
5268
5269 case DT_PLTREL:
566b0d53 5270 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
5271 if (do_dynamic)
5272 puts (get_dynamic_type (entry->d_un.d_val));
5273 break;
5274
5275 case DT_NULL :
5276 case DT_NEEDED :
5277 case DT_PLTGOT :
5278 case DT_HASH :
5279 case DT_STRTAB :
5280 case DT_SYMTAB :
5281 case DT_RELA :
5282 case DT_INIT :
5283 case DT_FINI :
5284 case DT_SONAME :
5285 case DT_RPATH :
5286 case DT_SYMBOLIC:
5287 case DT_REL :
5288 case DT_DEBUG :
5289 case DT_TEXTREL :
5290 case DT_JMPREL :
019148e4 5291 case DT_RUNPATH :
252b5132
RH
5292 dynamic_info[entry->d_tag] = entry->d_un.d_val;
5293
5294 if (do_dynamic)
5295 {
b34976b6 5296 char *name;
252b5132
RH
5297
5298 if (dynamic_strings == NULL)
5299 name = NULL;
5300 else
5301 name = dynamic_strings + entry->d_un.d_val;
5302
5303 if (name)
5304 {
5305 switch (entry->d_tag)
5306 {
5307 case DT_NEEDED:
5308 printf (_("Shared library: [%s]"), name);
5309
f7a99963
NC
5310 if (strcmp (name, program_interpreter) == 0)
5311 printf (_(" program interpreter"));
252b5132
RH
5312 break;
5313
5314 case DT_SONAME:
f7a99963 5315 printf (_("Library soname: [%s]"), name);
252b5132
RH
5316 break;
5317
5318 case DT_RPATH:
f7a99963 5319 printf (_("Library rpath: [%s]"), name);
252b5132
RH
5320 break;
5321
019148e4
L
5322 case DT_RUNPATH:
5323 printf (_("Library runpath: [%s]"), name);
5324 break;
5325
252b5132 5326 default:
f7a99963
NC
5327 print_vma (entry->d_un.d_val, PREFIX_HEX);
5328 break;
252b5132
RH
5329 }
5330 }
5331 else
f7a99963
NC
5332 print_vma (entry->d_un.d_val, PREFIX_HEX);
5333
5334 putchar ('\n');
252b5132
RH
5335 }
5336 break;
5337
5338 case DT_PLTRELSZ:
5339 case DT_RELASZ :
5340 case DT_STRSZ :
5341 case DT_RELSZ :
5342 case DT_RELAENT :
5343 case DT_SYMENT :
5344 case DT_RELENT :
566b0d53 5345 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
5346 case DT_PLTPADSZ:
5347 case DT_MOVEENT :
5348 case DT_MOVESZ :
5349 case DT_INIT_ARRAYSZ:
5350 case DT_FINI_ARRAYSZ:
047b2264
JJ
5351 case DT_GNU_CONFLICTSZ:
5352 case DT_GNU_LIBLISTSZ:
252b5132 5353 if (do_dynamic)
f7a99963
NC
5354 {
5355 print_vma (entry->d_un.d_val, UNSIGNED);
5356 printf (" (bytes)\n");
5357 }
252b5132
RH
5358 break;
5359
5360 case DT_VERDEFNUM:
5361 case DT_VERNEEDNUM:
5362 case DT_RELACOUNT:
5363 case DT_RELCOUNT:
5364 if (do_dynamic)
f7a99963
NC
5365 {
5366 print_vma (entry->d_un.d_val, UNSIGNED);
5367 putchar ('\n');
5368 }
252b5132
RH
5369 break;
5370
5371 case DT_SYMINSZ:
5372 case DT_SYMINENT:
5373 case DT_SYMINFO:
5374 case DT_USED:
5375 case DT_INIT_ARRAY:
5376 case DT_FINI_ARRAY:
5377 if (do_dynamic)
5378 {
5379 if (dynamic_strings != NULL && entry->d_tag == DT_USED)
5380 {
b34976b6 5381 char *name;
252b5132
RH
5382
5383 name = dynamic_strings + entry->d_un.d_val;
5384
b34976b6 5385 if (*name)
252b5132
RH
5386 {
5387 printf (_("Not needed object: [%s]\n"), name);
5388 break;
5389 }
5390 }
103f02d3 5391
f7a99963
NC
5392 print_vma (entry->d_un.d_val, PREFIX_HEX);
5393 putchar ('\n');
252b5132
RH
5394 }
5395 break;
5396
5397 case DT_BIND_NOW:
5398 /* The value of this entry is ignored. */
35b1837e
AM
5399 if (do_dynamic)
5400 putchar ('\n');
252b5132 5401 break;
103f02d3 5402
047b2264
JJ
5403 case DT_GNU_PRELINKED:
5404 if (do_dynamic)
5405 {
b34976b6 5406 struct tm *tmp;
047b2264
JJ
5407 time_t time = entry->d_un.d_val;
5408
5409 tmp = gmtime (&time);
5410 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
5411 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
5412 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
5413
5414 }
5415 break;
5416
252b5132
RH
5417 default:
5418 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 5419 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
5420 entry->d_un.d_val;
5421
5422 if (do_dynamic)
5423 {
5424 switch (elf_header.e_machine)
5425 {
5426 case EM_MIPS:
4fe85591 5427 case EM_MIPS_RS3_LE:
b2d38a17 5428 dynamic_section_mips_val (entry);
252b5132 5429 break;
103f02d3 5430 case EM_PARISC:
b2d38a17 5431 dynamic_section_parisc_val (entry);
103f02d3 5432 break;
ecc51f48 5433 case EM_IA_64:
b2d38a17 5434 dynamic_section_ia64_val (entry);
ecc51f48 5435 break;
252b5132 5436 default:
f7a99963
NC
5437 print_vma (entry->d_un.d_val, PREFIX_HEX);
5438 putchar ('\n');
252b5132
RH
5439 }
5440 }
5441 break;
5442 }
5443 }
5444
5445 return 1;
5446}
5447
5448static char *
d3ba0551 5449get_ver_flags (unsigned int flags)
252b5132 5450{
b34976b6 5451 static char buff[32];
252b5132
RH
5452
5453 buff[0] = 0;
5454
5455 if (flags == 0)
5456 return _("none");
5457
5458 if (flags & VER_FLG_BASE)
5459 strcat (buff, "BASE ");
5460
5461 if (flags & VER_FLG_WEAK)
5462 {
5463 if (flags & VER_FLG_BASE)
5464 strcat (buff, "| ");
5465
5466 strcat (buff, "WEAK ");
5467 }
5468
5469 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
5470 strcat (buff, "| <unknown>");
5471
5472 return buff;
5473}
5474
5475/* Display the contents of the version sections. */
5476static int
d3ba0551 5477process_version_sections (FILE *file)
252b5132 5478{
b34976b6
AM
5479 Elf_Internal_Shdr *section;
5480 unsigned i;
5481 int found = 0;
252b5132
RH
5482
5483 if (! do_version)
5484 return 1;
5485
5486 for (i = 0, section = section_headers;
5487 i < elf_header.e_shnum;
b34976b6 5488 i++, section++)
252b5132
RH
5489 {
5490 switch (section->sh_type)
5491 {
5492 case SHT_GNU_verdef:
5493 {
b34976b6
AM
5494 Elf_External_Verdef *edefs;
5495 unsigned int idx;
5496 unsigned int cnt;
252b5132
RH
5497
5498 found = 1;
5499
5500 printf
5501 (_("\nVersion definition section '%s' contains %ld entries:\n"),
5502 SECTION_NAME (section), section->sh_info);
5503
5504 printf (_(" Addr: 0x"));
5505 printf_vma (section->sh_addr);
5506 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 5507 (unsigned long) section->sh_offset, section->sh_link,
9ad5cbcf 5508 SECTION_NAME (SECTION_HEADER (section->sh_link)));
252b5132 5509
d3ba0551
AM
5510 edefs = get_data (NULL, file, section->sh_offset, section->sh_size,
5511 _("version definition section"));
a6e9f9df
AM
5512 if (!edefs)
5513 break;
252b5132 5514
b34976b6 5515 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 5516 {
b34976b6
AM
5517 char *vstart;
5518 Elf_External_Verdef *edef;
5519 Elf_Internal_Verdef ent;
5520 Elf_External_Verdaux *eaux;
5521 Elf_Internal_Verdaux aux;
5522 int j;
5523 int isum;
103f02d3 5524
252b5132
RH
5525 vstart = ((char *) edefs) + idx;
5526
5527 edef = (Elf_External_Verdef *) vstart;
5528
5529 ent.vd_version = BYTE_GET (edef->vd_version);
5530 ent.vd_flags = BYTE_GET (edef->vd_flags);
5531 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
5532 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
5533 ent.vd_hash = BYTE_GET (edef->vd_hash);
5534 ent.vd_aux = BYTE_GET (edef->vd_aux);
5535 ent.vd_next = BYTE_GET (edef->vd_next);
5536
5537 printf (_(" %#06x: Rev: %d Flags: %s"),
5538 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
5539
5540 printf (_(" Index: %d Cnt: %d "),
5541 ent.vd_ndx, ent.vd_cnt);
5542
5543 vstart += ent.vd_aux;
5544
5545 eaux = (Elf_External_Verdaux *) vstart;
5546
5547 aux.vda_name = BYTE_GET (eaux->vda_name);
5548 aux.vda_next = BYTE_GET (eaux->vda_next);
5549
5550 if (dynamic_strings)
5551 printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
5552 else
5553 printf (_("Name index: %ld\n"), aux.vda_name);
5554
5555 isum = idx + ent.vd_aux;
5556
b34976b6 5557 for (j = 1; j < ent.vd_cnt; j++)
252b5132
RH
5558 {
5559 isum += aux.vda_next;
5560 vstart += aux.vda_next;
5561
5562 eaux = (Elf_External_Verdaux *) vstart;
5563
5564 aux.vda_name = BYTE_GET (eaux->vda_name);
5565 aux.vda_next = BYTE_GET (eaux->vda_next);
5566
5567 if (dynamic_strings)
5568 printf (_(" %#06x: Parent %d: %s\n"),
5569 isum, j, dynamic_strings + aux.vda_name);
5570 else
5571 printf (_(" %#06x: Parent %d, name index: %ld\n"),
5572 isum, j, aux.vda_name);
5573 }
5574
5575 idx += ent.vd_next;
5576 }
5577
5578 free (edefs);
5579 }
5580 break;
103f02d3 5581
252b5132
RH
5582 case SHT_GNU_verneed:
5583 {
b34976b6
AM
5584 Elf_External_Verneed *eneed;
5585 unsigned int idx;
5586 unsigned int cnt;
252b5132
RH
5587
5588 found = 1;
5589
5590 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
5591 SECTION_NAME (section), section->sh_info);
5592
5593 printf (_(" Addr: 0x"));
5594 printf_vma (section->sh_addr);
5595 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
1b228002 5596 (unsigned long) section->sh_offset, section->sh_link,
9ad5cbcf 5597 SECTION_NAME (SECTION_HEADER (section->sh_link)));
252b5132 5598
d3ba0551
AM
5599 eneed = get_data (NULL, file, section->sh_offset, section->sh_size,
5600 _("version need section"));
a6e9f9df
AM
5601 if (!eneed)
5602 break;
252b5132
RH
5603
5604 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
5605 {
b34976b6
AM
5606 Elf_External_Verneed *entry;
5607 Elf_Internal_Verneed ent;
5608 int j;
5609 int isum;
5610 char *vstart;
252b5132
RH
5611
5612 vstart = ((char *) eneed) + idx;
5613
5614 entry = (Elf_External_Verneed *) vstart;
5615
5616 ent.vn_version = BYTE_GET (entry->vn_version);
5617 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
5618 ent.vn_file = BYTE_GET (entry->vn_file);
5619 ent.vn_aux = BYTE_GET (entry->vn_aux);
5620 ent.vn_next = BYTE_GET (entry->vn_next);
5621
5622 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
5623
5624 if (dynamic_strings)
5625 printf (_(" File: %s"), dynamic_strings + ent.vn_file);
5626 else
5627 printf (_(" File: %lx"), ent.vn_file);
5628
5629 printf (_(" Cnt: %d\n"), ent.vn_cnt);
5630
5631 vstart += ent.vn_aux;
5632
5633 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
5634 {
b34976b6
AM
5635 Elf_External_Vernaux *eaux;
5636 Elf_Internal_Vernaux aux;
252b5132
RH
5637
5638 eaux = (Elf_External_Vernaux *) vstart;
5639
5640 aux.vna_hash = BYTE_GET (eaux->vna_hash);
5641 aux.vna_flags = BYTE_GET (eaux->vna_flags);
5642 aux.vna_other = BYTE_GET (eaux->vna_other);
5643 aux.vna_name = BYTE_GET (eaux->vna_name);
5644 aux.vna_next = BYTE_GET (eaux->vna_next);
5645
5646 if (dynamic_strings)
ecc2063b 5647 printf (_(" %#06x: Name: %s"),
252b5132
RH
5648 isum, dynamic_strings + aux.vna_name);
5649 else
ecc2063b 5650 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
5651 isum, aux.vna_name);
5652
5653 printf (_(" Flags: %s Version: %d\n"),
5654 get_ver_flags (aux.vna_flags), aux.vna_other);
5655
5656 isum += aux.vna_next;
5657 vstart += aux.vna_next;
5658 }
5659
5660 idx += ent.vn_next;
5661 }
103f02d3 5662
252b5132
RH
5663 free (eneed);
5664 }
5665 break;
5666
5667 case SHT_GNU_versym:
5668 {
b34976b6
AM
5669 Elf_Internal_Shdr *link_section;
5670 int total;
5671 int cnt;
5672 unsigned char *edata;
5673 unsigned short *data;
5674 char *strtab;
5675 Elf_Internal_Sym *symbols;
5676 Elf_Internal_Shdr *string_sec;
d3ba0551 5677 long off;
252b5132 5678
9ad5cbcf 5679 link_section = SECTION_HEADER (section->sh_link);
252b5132
RH
5680 total = section->sh_size / section->sh_entsize;
5681
5682 found = 1;
5683
9ad5cbcf 5684 symbols = GET_ELF_SYMBOLS (file, link_section);
252b5132 5685
9ad5cbcf 5686 string_sec = SECTION_HEADER (link_section->sh_link);
252b5132 5687
d3ba0551
AM
5688 strtab = get_data (NULL, file, string_sec->sh_offset,
5689 string_sec->sh_size, _("version string table"));
a6e9f9df
AM
5690 if (!strtab)
5691 break;
252b5132
RH
5692
5693 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
5694 SECTION_NAME (section), total);
5695
5696 printf (_(" Addr: "));
5697 printf_vma (section->sh_addr);
5698 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 5699 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
5700 SECTION_NAME (link_section));
5701
d3ba0551
AM
5702 off = offset_from_vma (file,
5703 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
5704 total * sizeof (short));
5705 edata = get_data (NULL, file, off, total * sizeof (short),
5706 _("version symbol data"));
a6e9f9df
AM
5707 if (!edata)
5708 {
5709 free (strtab);
5710 break;
5711 }
252b5132 5712
d3ba0551 5713 data = malloc (total * sizeof (short));
252b5132
RH
5714
5715 for (cnt = total; cnt --;)
b34976b6
AM
5716 data[cnt] = byte_get (edata + cnt * sizeof (short),
5717 sizeof (short));
252b5132
RH
5718
5719 free (edata);
5720
5721 for (cnt = 0; cnt < total; cnt += 4)
5722 {
5723 int j, nn;
00d93f34 5724 int check_def, check_need;
b34976b6 5725 char *name;
252b5132
RH
5726
5727 printf (" %03x:", cnt);
5728
5729 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 5730 switch (data[cnt + j])
252b5132
RH
5731 {
5732 case 0:
5733 fputs (_(" 0 (*local*) "), stdout);
5734 break;
5735
5736 case 1:
5737 fputs (_(" 1 (*global*) "), stdout);
5738 break;
5739
5740 default:
b34976b6
AM
5741 nn = printf ("%4x%c", data[cnt + j] & 0x7fff,
5742 data[cnt + j] & 0x8000 ? 'h' : ' ');
252b5132 5743
00d93f34
JJ
5744 check_def = 1;
5745 check_need = 1;
b34976b6 5746 if (SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
00d93f34 5747 != SHT_NOBITS)
252b5132 5748 {
b34976b6 5749 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
5750 check_def = 0;
5751 else
5752 check_need = 0;
252b5132 5753 }
00d93f34
JJ
5754
5755 if (check_need
b34976b6 5756 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 5757 {
b34976b6
AM
5758 Elf_Internal_Verneed ivn;
5759 unsigned long offset;
252b5132 5760
d93f0186
NC
5761 offset = offset_from_vma
5762 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
5763 sizeof (Elf_External_Verneed));
252b5132 5764
b34976b6 5765 do
252b5132 5766 {
b34976b6
AM
5767 Elf_Internal_Vernaux ivna;
5768 Elf_External_Verneed evn;
5769 Elf_External_Vernaux evna;
5770 unsigned long a_off;
252b5132 5771
a6e9f9df
AM
5772 get_data (&evn, file, offset, sizeof (evn),
5773 _("version need"));
252b5132
RH
5774
5775 ivn.vn_aux = BYTE_GET (evn.vn_aux);
5776 ivn.vn_next = BYTE_GET (evn.vn_next);
5777
5778 a_off = offset + ivn.vn_aux;
5779
5780 do
5781 {
a6e9f9df
AM
5782 get_data (&evna, file, a_off, sizeof (evna),
5783 _("version need aux (2)"));
252b5132
RH
5784
5785 ivna.vna_next = BYTE_GET (evna.vna_next);
5786 ivna.vna_other = BYTE_GET (evna.vna_other);
5787
5788 a_off += ivna.vna_next;
5789 }
b34976b6 5790 while (ivna.vna_other != data[cnt + j]
252b5132
RH
5791 && ivna.vna_next != 0);
5792
b34976b6 5793 if (ivna.vna_other == data[cnt + j])
252b5132
RH
5794 {
5795 ivna.vna_name = BYTE_GET (evna.vna_name);
5796
16062207 5797 name = strtab + ivna.vna_name;
252b5132 5798 nn += printf ("(%s%-*s",
16062207
ILT
5799 name,
5800 12 - (int) strlen (name),
252b5132 5801 ")");
00d93f34 5802 check_def = 0;
252b5132
RH
5803 break;
5804 }
5805
5806 offset += ivn.vn_next;
5807 }
5808 while (ivn.vn_next);
5809 }
00d93f34 5810
b34976b6
AM
5811 if (check_def && data[cnt + j] != 0x8001
5812 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 5813 {
b34976b6
AM
5814 Elf_Internal_Verdef ivd;
5815 Elf_External_Verdef evd;
5816 unsigned long offset;
252b5132 5817
d93f0186
NC
5818 offset = offset_from_vma
5819 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
5820 sizeof evd);
252b5132
RH
5821
5822 do
5823 {
a6e9f9df
AM
5824 get_data (&evd, file, offset, sizeof (evd),
5825 _("version def"));
252b5132
RH
5826
5827 ivd.vd_next = BYTE_GET (evd.vd_next);
5828 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
5829
5830 offset += ivd.vd_next;
5831 }
b34976b6 5832 while (ivd.vd_ndx != (data[cnt + j] & 0x7fff)
252b5132
RH
5833 && ivd.vd_next != 0);
5834
b34976b6 5835 if (ivd.vd_ndx == (data[cnt + j] & 0x7fff))
252b5132 5836 {
b34976b6
AM
5837 Elf_External_Verdaux evda;
5838 Elf_Internal_Verdaux ivda;
252b5132
RH
5839
5840 ivd.vd_aux = BYTE_GET (evd.vd_aux);
5841
a6e9f9df
AM
5842 get_data (&evda, file,
5843 offset - ivd.vd_next + ivd.vd_aux,
5844 sizeof (evda), _("version def aux"));
252b5132
RH
5845
5846 ivda.vda_name = BYTE_GET (evda.vda_name);
5847
16062207 5848 name = strtab + ivda.vda_name;
252b5132 5849 nn += printf ("(%s%-*s",
16062207
ILT
5850 name,
5851 12 - (int) strlen (name),
252b5132
RH
5852 ")");
5853 }
5854 }
5855
5856 if (nn < 18)
5857 printf ("%*c", 18 - nn, ' ');
5858 }
5859
5860 putchar ('\n');
5861 }
5862
5863 free (data);
5864 free (strtab);
5865 free (symbols);
5866 }
5867 break;
103f02d3 5868
252b5132
RH
5869 default:
5870 break;
5871 }
5872 }
5873
5874 if (! found)
5875 printf (_("\nNo version information found in this file.\n"));
5876
5877 return 1;
5878}
5879
d1133906 5880static const char *
d3ba0551 5881get_symbol_binding (unsigned int binding)
252b5132 5882{
b34976b6 5883 static char buff[32];
252b5132
RH
5884
5885 switch (binding)
5886 {
b34976b6
AM
5887 case STB_LOCAL: return "LOCAL";
5888 case STB_GLOBAL: return "GLOBAL";
5889 case STB_WEAK: return "WEAK";
252b5132
RH
5890 default:
5891 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
5892 sprintf (buff, _("<processor specific>: %d"), binding);
5893 else if (binding >= STB_LOOS && binding <= STB_HIOS)
5894 sprintf (buff, _("<OS specific>: %d"), binding);
5895 else
5896 sprintf (buff, _("<unknown>: %d"), binding);
5897 return buff;
5898 }
5899}
5900
d1133906 5901static const char *
d3ba0551 5902get_symbol_type (unsigned int type)
252b5132 5903{
b34976b6 5904 static char buff[32];
252b5132
RH
5905
5906 switch (type)
5907 {
b34976b6
AM
5908 case STT_NOTYPE: return "NOTYPE";
5909 case STT_OBJECT: return "OBJECT";
5910 case STT_FUNC: return "FUNC";
5911 case STT_SECTION: return "SECTION";
5912 case STT_FILE: return "FILE";
5913 case STT_COMMON: return "COMMON";
5914 case STT_TLS: return "TLS";
252b5132
RH
5915 default:
5916 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
5917 {
5918 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
5919 return "THUMB_FUNC";
5920
351b4b40 5921 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
5922 return "REGISTER";
5923
5924 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
5925 return "PARISC_MILLI";
5926
df75f1af
NC
5927 sprintf (buff, _("<processor specific>: %d"), type);
5928 }
252b5132 5929 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
5930 {
5931 if (elf_header.e_machine == EM_PARISC)
5932 {
5933 if (type == STT_HP_OPAQUE)
5934 return "HP_OPAQUE";
5935 if (type == STT_HP_STUB)
5936 return "HP_STUB";
5937 }
5938
5939 sprintf (buff, _("<OS specific>: %d"), type);
5940 }
252b5132
RH
5941 else
5942 sprintf (buff, _("<unknown>: %d"), type);
5943 return buff;
5944 }
5945}
5946
d1133906 5947static const char *
d3ba0551 5948get_symbol_visibility (unsigned int visibility)
d1133906
NC
5949{
5950 switch (visibility)
5951 {
b34976b6
AM
5952 case STV_DEFAULT: return "DEFAULT";
5953 case STV_INTERNAL: return "INTERNAL";
5954 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
5955 case STV_PROTECTED: return "PROTECTED";
5956 default: abort ();
5957 }
5958}
5959
5960static const char *
d3ba0551 5961get_symbol_index_type (unsigned int type)
252b5132 5962{
b34976b6 5963 static char buff[32];
5cf1065c 5964
252b5132
RH
5965 switch (type)
5966 {
b34976b6
AM
5967 case SHN_UNDEF: return "UND";
5968 case SHN_ABS: return "ABS";
5969 case SHN_COMMON: return "COM";
252b5132 5970 default:
9ce701e2
L
5971 if (type == SHN_IA_64_ANSI_COMMON
5972 && elf_header.e_machine == EM_IA_64
5973 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
5974 return "ANSI_COM";
5975 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
5cf1065c 5976 sprintf (buff, "PRC[0x%04x]", type);
252b5132 5977 else if (type >= SHN_LOOS && type <= SHN_HIOS)
5cf1065c 5978 sprintf (buff, "OS [0x%04x]", type);
9ad5cbcf 5979 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
5cf1065c 5980 sprintf (buff, "RSV[0x%04x]", type);
252b5132 5981 else
232e7cb8 5982 sprintf (buff, "%3d", type);
5cf1065c 5983 break;
252b5132 5984 }
5cf1065c
NC
5985
5986 return buff;
252b5132
RH
5987}
5988
252b5132 5989static int *
d3ba0551 5990get_dynamic_data (FILE *file, unsigned int number)
252b5132 5991{
b34976b6
AM
5992 unsigned char *e_data;
5993 int *i_data;
252b5132 5994
d3ba0551 5995 e_data = malloc (number * 4);
252b5132
RH
5996
5997 if (e_data == NULL)
5998 {
5999 error (_("Out of memory\n"));
6000 return NULL;
6001 }
6002
6003 if (fread (e_data, 4, number, file) != number)
6004 {
6005 error (_("Unable to read in dynamic data\n"));
6006 return NULL;
6007 }
6008
d3ba0551 6009 i_data = malloc (number * sizeof (*i_data));
252b5132
RH
6010
6011 if (i_data == NULL)
6012 {
6013 error (_("Out of memory\n"));
6014 free (e_data);
6015 return NULL;
6016 }
6017
6018 while (number--)
b34976b6 6019 i_data[number] = byte_get (e_data + number * 4, 4);
252b5132
RH
6020
6021 free (e_data);
6022
6023 return i_data;
6024}
6025
e3c8793a 6026/* Dump the symbol table. */
252b5132 6027static int
d3ba0551 6028process_symbol_table (FILE *file)
252b5132 6029{
b34976b6
AM
6030 Elf_Internal_Shdr *section;
6031 unsigned char nb[4];
6032 unsigned char nc[4];
6033 int nbuckets = 0;
6034 int nchains = 0;
6035 int *buckets = NULL;
6036 int *chains = NULL;
252b5132
RH
6037
6038 if (! do_syms && !do_histogram)
6039 return 1;
6040
6041 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
6042 || do_histogram))
6043 {
fb52b2f4
NC
6044 if (fseek (file,
6045 (archive_file_offset
6046 + offset_from_vma (file, dynamic_info[DT_HASH],
6047 sizeof nb + sizeof nc)),
d93f0186 6048 SEEK_SET))
252b5132
RH
6049 {
6050 error (_("Unable to seek to start of dynamic information"));
6051 return 0;
6052 }
6053
6054 if (fread (nb, sizeof (nb), 1, file) != 1)
6055 {
6056 error (_("Failed to read in number of buckets\n"));
6057 return 0;
6058 }
6059
6060 if (fread (nc, sizeof (nc), 1, file) != 1)
6061 {
6062 error (_("Failed to read in number of chains\n"));
6063 return 0;
6064 }
6065
6066 nbuckets = byte_get (nb, 4);
6067 nchains = byte_get (nc, 4);
6068
6069 buckets = get_dynamic_data (file, nbuckets);
6070 chains = get_dynamic_data (file, nchains);
6071
6072 if (buckets == NULL || chains == NULL)
6073 return 0;
6074 }
6075
6076 if (do_syms
6077 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
6078 {
b34976b6
AM
6079 int hn;
6080 int si;
252b5132
RH
6081
6082 printf (_("\nSymbol table for image:\n"));
f7a99963 6083 if (is_32bit_elf)
ca47b30c 6084 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 6085 else
ca47b30c 6086 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
252b5132
RH
6087
6088 for (hn = 0; hn < nbuckets; hn++)
6089 {
b34976b6 6090 if (! buckets[hn])
252b5132
RH
6091 continue;
6092
b34976b6 6093 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
252b5132 6094 {
b34976b6 6095 Elf_Internal_Sym *psym;
252b5132
RH
6096
6097 psym = dynamic_symbols + si;
6098
f7a99963
NC
6099 printf (" %3d %3d: ", si, hn);
6100 print_vma (psym->st_value, LONG_HEX);
6101 putchar (' ' );
d1133906 6102 print_vma (psym->st_size, DEC_5);
76da6bbe 6103
d1133906
NC
6104 printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
6105 printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
6106 printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126
NC
6107 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
6108 print_symbol (25, dynamic_strings + psym->st_name);
6109 putchar ('\n');
252b5132
RH
6110 }
6111 }
6112 }
6113 else if (do_syms && !do_using_dynamic)
6114 {
b34976b6 6115 unsigned int i;
252b5132
RH
6116
6117 for (i = 0, section = section_headers;
6118 i < elf_header.e_shnum;
6119 i++, section++)
6120 {
b34976b6
AM
6121 unsigned int si;
6122 char *strtab;
6123 Elf_Internal_Sym *symtab;
6124 Elf_Internal_Sym *psym;
252b5132
RH
6125
6126
6127 if ( section->sh_type != SHT_SYMTAB
6128 && section->sh_type != SHT_DYNSYM)
6129 continue;
6130
6131 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
6132 SECTION_NAME (section),
6133 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 6134 if (is_32bit_elf)
ca47b30c 6135 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 6136 else
ca47b30c 6137 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 6138
9ad5cbcf 6139 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
6140 if (symtab == NULL)
6141 continue;
6142
6143 if (section->sh_link == elf_header.e_shstrndx)
6144 strtab = string_table;
6145 else
6146 {
b34976b6 6147 Elf_Internal_Shdr *string_sec;
252b5132 6148
9ad5cbcf 6149 string_sec = SECTION_HEADER (section->sh_link);
252b5132 6150
d3ba0551
AM
6151 strtab = get_data (NULL, file, string_sec->sh_offset,
6152 string_sec->sh_size, _("string table"));
252b5132
RH
6153 }
6154
6155 for (si = 0, psym = symtab;
6156 si < section->sh_size / section->sh_entsize;
b34976b6 6157 si++, psym++)
252b5132 6158 {
5e220199 6159 printf ("%6d: ", si);
f7a99963
NC
6160 print_vma (psym->st_value, LONG_HEX);
6161 putchar (' ');
6162 print_vma (psym->st_size, DEC_5);
d1133906
NC
6163 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
6164 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
6165 printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126
NC
6166 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
6167 print_symbol (25, strtab + psym->st_name);
252b5132
RH
6168
6169 if (section->sh_type == SHT_DYNSYM &&
b34976b6 6170 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 6171 {
b34976b6
AM
6172 unsigned char data[2];
6173 unsigned short vers_data;
6174 unsigned long offset;
6175 int is_nobits;
6176 int check_def;
252b5132 6177
d93f0186
NC
6178 offset = offset_from_vma
6179 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
6180 sizeof data + si * sizeof (vers_data));
252b5132 6181
a6e9f9df
AM
6182 get_data (&data, file, offset + si * sizeof (vers_data),
6183 sizeof (data), _("version data"));
252b5132
RH
6184
6185 vers_data = byte_get (data, 2);
6186
9ad5cbcf
AM
6187 is_nobits = (SECTION_HEADER (psym->st_shndx)->sh_type
6188 == SHT_NOBITS);
252b5132
RH
6189
6190 check_def = (psym->st_shndx != SHN_UNDEF);
6191
6192 if ((vers_data & 0x8000) || vers_data > 1)
6193 {
b34976b6 6194 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 6195 && (is_nobits || ! check_def))
252b5132 6196 {
b34976b6
AM
6197 Elf_External_Verneed evn;
6198 Elf_Internal_Verneed ivn;
6199 Elf_Internal_Vernaux ivna;
252b5132
RH
6200
6201 /* We must test both. */
d93f0186
NC
6202 offset = offset_from_vma
6203 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
6204 sizeof evn);
252b5132 6205
252b5132
RH
6206 do
6207 {
b34976b6 6208 unsigned long vna_off;
252b5132 6209
a6e9f9df
AM
6210 get_data (&evn, file, offset, sizeof (evn),
6211 _("version need"));
dd27201e
L
6212
6213 ivn.vn_aux = BYTE_GET (evn.vn_aux);
6214 ivn.vn_next = BYTE_GET (evn.vn_next);
6215
252b5132
RH
6216 vna_off = offset + ivn.vn_aux;
6217
6218 do
6219 {
b34976b6 6220 Elf_External_Vernaux evna;
252b5132 6221
a6e9f9df
AM
6222 get_data (&evna, file, vna_off,
6223 sizeof (evna),
6224 _("version need aux (3)"));
252b5132
RH
6225
6226 ivna.vna_other = BYTE_GET (evna.vna_other);
6227 ivna.vna_next = BYTE_GET (evna.vna_next);
6228 ivna.vna_name = BYTE_GET (evna.vna_name);
6229
6230 vna_off += ivna.vna_next;
6231 }
6232 while (ivna.vna_other != vers_data
6233 && ivna.vna_next != 0);
6234
6235 if (ivna.vna_other == vers_data)
6236 break;
6237
6238 offset += ivn.vn_next;
6239 }
6240 while (ivn.vn_next != 0);
6241
6242 if (ivna.vna_other == vers_data)
6243 {
6244 printf ("@%s (%d)",
6245 strtab + ivna.vna_name, ivna.vna_other);
6246 check_def = 0;
6247 }
6248 else if (! is_nobits)
6249 error (_("bad dynamic symbol"));
6250 else
6251 check_def = 1;
6252 }
6253
6254 if (check_def)
6255 {
00d93f34 6256 if (vers_data != 0x8001
b34976b6 6257 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 6258 {
b34976b6
AM
6259 Elf_Internal_Verdef ivd;
6260 Elf_Internal_Verdaux ivda;
6261 Elf_External_Verdaux evda;
6262 unsigned long offset;
252b5132 6263
d93f0186
NC
6264 offset = offset_from_vma
6265 (file,
6266 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
6267 sizeof (Elf_External_Verdef));
252b5132
RH
6268
6269 do
6270 {
b34976b6 6271 Elf_External_Verdef evd;
252b5132 6272
a6e9f9df
AM
6273 get_data (&evd, file, offset, sizeof (evd),
6274 _("version def"));
252b5132 6275
b34976b6
AM
6276 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
6277 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
6278 ivd.vd_next = BYTE_GET (evd.vd_next);
6279
6280 offset += ivd.vd_next;
6281 }
6282 while (ivd.vd_ndx != (vers_data & 0x7fff)
6283 && ivd.vd_next != 0);
6284
6285 offset -= ivd.vd_next;
6286 offset += ivd.vd_aux;
6287
a6e9f9df
AM
6288 get_data (&evda, file, offset, sizeof (evda),
6289 _("version def aux"));
252b5132
RH
6290
6291 ivda.vda_name = BYTE_GET (evda.vda_name);
6292
6293 if (psym->st_name != ivda.vda_name)
6294 printf ((vers_data & 0x8000)
6295 ? "@%s" : "@@%s",
6296 strtab + ivda.vda_name);
6297 }
6298 }
6299 }
6300 }
6301
6302 putchar ('\n');
6303 }
6304
6305 free (symtab);
6306 if (strtab != string_table)
6307 free (strtab);
6308 }
6309 }
6310 else if (do_syms)
6311 printf
6312 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
6313
6314 if (do_histogram && buckets != NULL)
6315 {
b34976b6
AM
6316 int *lengths;
6317 int *counts;
6318 int hn;
6319 int si;
6320 int maxlength = 0;
6321 int nzero_counts = 0;
6322 int nsyms = 0;
252b5132
RH
6323
6324 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
6325 nbuckets);
6326 printf (_(" Length Number %% of total Coverage\n"));
6327
d3ba0551 6328 lengths = calloc (nbuckets, sizeof (int));
252b5132
RH
6329 if (lengths == NULL)
6330 {
6331 error (_("Out of memory"));
6332 return 0;
6333 }
6334 for (hn = 0; hn < nbuckets; ++hn)
6335 {
b34976b6 6336 if (! buckets[hn])
252b5132
RH
6337 continue;
6338
f7a99963 6339 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 6340 {
b34976b6 6341 ++nsyms;
252b5132 6342 if (maxlength < ++lengths[hn])
b34976b6 6343 ++maxlength;
252b5132
RH
6344 }
6345 }
6346
d3ba0551 6347 counts = calloc (maxlength + 1, sizeof (int));
252b5132
RH
6348 if (counts == NULL)
6349 {
6350 error (_("Out of memory"));
6351 return 0;
6352 }
6353
6354 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 6355 ++counts[lengths[hn]];
252b5132 6356
103f02d3 6357 if (nbuckets > 0)
252b5132 6358 {
103f02d3
UD
6359 printf (" 0 %-10d (%5.1f%%)\n",
6360 counts[0], (counts[0] * 100.0) / nbuckets);
6361 for (si = 1; si <= maxlength; ++si)
6362 {
6363 nzero_counts += counts[si] * si;
6364 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
6365 si, counts[si], (counts[si] * 100.0) / nbuckets,
6366 (nzero_counts * 100.0) / nsyms);
6367 }
252b5132
RH
6368 }
6369
6370 free (counts);
6371 free (lengths);
6372 }
6373
6374 if (buckets != NULL)
6375 {
6376 free (buckets);
6377 free (chains);
6378 }
6379
6380 return 1;
6381}
6382
6383static int
d3ba0551 6384process_syminfo (FILE *file ATTRIBUTE_UNUSED)
252b5132 6385{
b4c96d0d 6386 unsigned int i;
252b5132
RH
6387
6388 if (dynamic_syminfo == NULL
6389 || !do_dynamic)
6390 /* No syminfo, this is ok. */
6391 return 1;
6392
6393 /* There better should be a dynamic symbol section. */
6394 if (dynamic_symbols == NULL || dynamic_strings == NULL)
6395 return 0;
6396
6397 if (dynamic_addr)
6398 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
6399 dynamic_syminfo_offset, dynamic_syminfo_nent);
6400
6401 printf (_(" Num: Name BoundTo Flags\n"));
6402 for (i = 0; i < dynamic_syminfo_nent; ++i)
6403 {
6404 unsigned short int flags = dynamic_syminfo[i].si_flags;
6405
31104126
NC
6406 printf ("%4d: ", i);
6407 print_symbol (30, dynamic_strings + dynamic_symbols[i].st_name);
6408 putchar (' ');
252b5132
RH
6409
6410 switch (dynamic_syminfo[i].si_boundto)
6411 {
6412 case SYMINFO_BT_SELF:
6413 fputs ("SELF ", stdout);
6414 break;
6415 case SYMINFO_BT_PARENT:
6416 fputs ("PARENT ", stdout);
6417 break;
6418 default:
6419 if (dynamic_syminfo[i].si_boundto > 0
86dba8ee 6420 && dynamic_syminfo[i].si_boundto < dynamic_nent)
31104126 6421 {
b34976b6
AM
6422 print_symbol (10,
6423 dynamic_strings
b2d38a17 6424 + (dynamic_section
b34976b6 6425 [dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
6426 putchar (' ' );
6427 }
252b5132
RH
6428 else
6429 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
6430 break;
6431 }
6432
6433 if (flags & SYMINFO_FLG_DIRECT)
6434 printf (" DIRECT");
6435 if (flags & SYMINFO_FLG_PASSTHRU)
6436 printf (" PASSTHRU");
6437 if (flags & SYMINFO_FLG_COPY)
6438 printf (" COPY");
6439 if (flags & SYMINFO_FLG_LAZYLOAD)
6440 printf (" LAZYLOAD");
6441
6442 puts ("");
6443 }
6444
6445 return 1;
6446}
6447
6448#ifdef SUPPORT_DISASSEMBLY
6449static void
d3ba0551 6450disassemble_section (Elf_Internal_Shdr *section, FILE *file)
252b5132
RH
6451{
6452 printf (_("\nAssembly dump of section %s\n"),
6453 SECTION_NAME (section));
6454
6455 /* XXX -- to be done --- XXX */
6456
6457 return 1;
6458}
6459#endif
6460
6461static int
d3ba0551 6462dump_section (Elf_Internal_Shdr *section, FILE *file)
252b5132 6463{
b34976b6
AM
6464 bfd_size_type bytes;
6465 bfd_vma addr;
6466 unsigned char *data;
6467 unsigned char *start;
252b5132
RH
6468
6469 bytes = section->sh_size;
6470
e69f2d21 6471 if (bytes == 0 || section->sh_type == SHT_NOBITS)
252b5132
RH
6472 {
6473 printf (_("\nSection '%s' has no data to dump.\n"),
6474 SECTION_NAME (section));
6475 return 0;
6476 }
6477 else
6478 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
6479
6480 addr = section->sh_addr;
6481
d3ba0551 6482 start = get_data (NULL, file, section->sh_offset, bytes, _("section data"));
a6e9f9df
AM
6483 if (!start)
6484 return 0;
252b5132
RH
6485
6486 data = start;
6487
6488 while (bytes)
6489 {
6490 int j;
6491 int k;
6492 int lbytes;
6493
6494 lbytes = (bytes > 16 ? 16 : bytes);
6495
148d3c43 6496 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132 6497
b34976b6 6498 switch (elf_header.e_ident[EI_DATA])
252b5132 6499 {
9ea033b2 6500 default:
252b5132
RH
6501 case ELFDATA2LSB:
6502 for (j = 15; j >= 0; j --)
6503 {
6504 if (j < lbytes)
b34976b6 6505 printf ("%2.2x", data[j]);
252b5132
RH
6506 else
6507 printf (" ");
6508
6509 if (!(j & 0x3))
6510 printf (" ");
6511 }
6512 break;
6513
6514 case ELFDATA2MSB:
6515 for (j = 0; j < 16; j++)
6516 {
6517 if (j < lbytes)
b34976b6 6518 printf ("%2.2x", data[j]);
252b5132
RH
6519 else
6520 printf (" ");
6521
6522 if ((j & 3) == 3)
6523 printf (" ");
6524 }
6525 break;
6526 }
6527
6528 for (j = 0; j < lbytes; j++)
6529 {
b34976b6 6530 k = data[j];
9376f0c7 6531 if (k >= ' ' && k < 0x7f)
252b5132
RH
6532 printf ("%c", k);
6533 else
6534 printf (".");
6535 }
6536
6537 putchar ('\n');
6538
6539 data += lbytes;
6540 addr += lbytes;
6541 bytes -= lbytes;
6542 }
6543
6544 free (start);
6545
6546 return 1;
6547}
6548
6549
6550static unsigned long int
d3ba0551 6551read_leb128 (unsigned char *data, int *length_return, int sign)
252b5132
RH
6552{
6553 unsigned long int result = 0;
b34976b6
AM
6554 unsigned int num_read = 0;
6555 int shift = 0;
6556 unsigned char byte;
252b5132
RH
6557
6558 do
6559 {
b34976b6
AM
6560 byte = *data++;
6561 num_read++;
252b5132
RH
6562
6563 result |= (byte & 0x7f) << shift;
6564
6565 shift += 7;
6566
6567 }
6568 while (byte & 0x80);
6569
6570 if (length_return != NULL)
b34976b6 6571 *length_return = num_read;
252b5132
RH
6572
6573 if (sign && (shift < 32) && (byte & 0x40))
6574 result |= -1 << shift;
6575
6576 return result;
6577}
6578
6579typedef struct State_Machine_Registers
6580{
b34976b6
AM
6581 unsigned long address;
6582 unsigned int file;
6583 unsigned int line;
6584 unsigned int column;
6585 int is_stmt;
6586 int basic_block;
6587 int end_sequence;
252b5132
RH
6588/* This variable hold the number of the last entry seen
6589 in the File Table. */
b34976b6 6590 unsigned int last_file_entry;
252b5132
RH
6591} SMR;
6592
6593static SMR state_machine_regs;
6594
6595static void
d3ba0551 6596reset_state_machine (int is_stmt)
252b5132
RH
6597{
6598 state_machine_regs.address = 0;
6599 state_machine_regs.file = 1;
6600 state_machine_regs.line = 1;
6601 state_machine_regs.column = 0;
6602 state_machine_regs.is_stmt = is_stmt;
6603 state_machine_regs.basic_block = 0;
6604 state_machine_regs.end_sequence = 0;
6605 state_machine_regs.last_file_entry = 0;
6606}
6607
6608/* Handled an extend line op. Returns true if this is the end
6609 of sequence. */
6610static int
d3ba0551 6611process_extended_line_op (unsigned char *data, int is_stmt, int pointer_size)
252b5132 6612{
b34976b6
AM
6613 unsigned char op_code;
6614 int bytes_read;
6615 unsigned int len;
6616 unsigned char *name;
6617 unsigned long adr;
103f02d3 6618
252b5132
RH
6619 len = read_leb128 (data, & bytes_read, 0);
6620 data += bytes_read;
6621
6622 if (len == 0)
6623 {
e5fb9629 6624 warn (_("badly formed extended line op encountered!\n"));
252b5132
RH
6625 return bytes_read;
6626 }
6627
6628 len += bytes_read;
b34976b6 6629 op_code = *data++;
252b5132
RH
6630
6631 printf (_(" Extended opcode %d: "), op_code);
103f02d3 6632
252b5132
RH
6633 switch (op_code)
6634 {
6635 case DW_LNE_end_sequence:
6636 printf (_("End of Sequence\n\n"));
6637 reset_state_machine (is_stmt);
6638 break;
6639
6640 case DW_LNE_set_address:
3590ea00 6641 adr = byte_get (data, pointer_size);
252b5132
RH
6642 printf (_("set Address to 0x%lx\n"), adr);
6643 state_machine_regs.address = adr;
6644 break;
6645
6646 case DW_LNE_define_file:
6647 printf (_(" define new File Table entry\n"));
6648 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
103f02d3 6649
b34976b6 6650 printf (_(" %d\t"), ++state_machine_regs.last_file_entry);
252b5132 6651 name = data;
3c9f43b1 6652 data += strlen ((char *) data) + 1;
252b5132
RH
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 data += bytes_read;
6657 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6658 printf (_("%s\n\n"), name);
6659 break;
6660
6661 default:
6662 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
6663 break;
6664 }
6665
6666 return len;
6667}
6668
d9296b18
NC
6669/* Finds section NAME inside FILE and returns a
6670 pointer to it, or NULL upon failure. */
6671
6672static Elf_Internal_Shdr *
6673find_section (const char * name)
6674{
6675 Elf_Internal_Shdr *sec;
6676 unsigned int i;
0de14b54 6677
d9296b18
NC
6678 for (i = elf_header.e_shnum, sec = section_headers + i - 1;
6679 i; --i, --sec)
6680 if (strcmp (SECTION_NAME (sec), name) == 0)
6681 break;
6682
6683 if (i && sec && sec->sh_size != 0)
6684 return sec;
6685
6686 return NULL;
6687}
6688
3590ea00
NC
6689/* Size of pointers in the .debug_line section. This information is not
6690 really present in that section. It's obtained before dumping the debug
6691 sections by doing some pre-scan of the .debug_info section. */
0e0c4098
NC
6692static unsigned int * debug_line_pointer_sizes = NULL;
6693static unsigned int num_debug_line_pointer_sizes = 0;
252b5132 6694
d9296b18
NC
6695/* Locate and scan the .debug_info section in the file and record the pointer
6696 sizes for the compilation units in it. Usually an executable will have
6697 just one pointer size, but this is not guaranteed, and so we try not to
6698 make any assumptions. Returns zero upon failure, or the number of
6699 compilation units upon success. */
6700
6701static unsigned int
6702get_debug_line_pointer_sizes (FILE * file)
6703{
6704 Elf_Internal_Shdr * section;
6705 unsigned char * start;
6706 unsigned char * end;
6707 unsigned char * begin;
6708 unsigned long length;
6709 unsigned int num_units;
6710 unsigned int unit;
6711
6712 section = find_section (".debug_info");
6713 if (section == NULL)
6714 return 0;
6715
6716 length = section->sh_size;
6717 start = get_data (NULL, file, section->sh_offset, section->sh_size,
6718 _("extracting pointer sizes from .debug_info section"));
6719 if (start == NULL)
6720 return 0;
6721
6722 end = start + section->sh_size;
6723 /* First scan the section to get the number of comp units. */
6724 for (begin = start, num_units = 0; begin < end; num_units++)
6725 {
6726 /* Read the first 4 bytes. For a 32-bit DWARF section, this will
6727 be the length. For a 64-bit DWARF section, it'll be the escape
6728 code 0xffffffff followed by an 8 byte length. */
6729 length = byte_get (begin, 4);
6730
6731 if (length == 0xffffffff)
6732 {
6733 length = byte_get (begin + 4, 8);
6734 begin += length + 12;
6735 }
6736 else
6737 begin += length + 4;
6738 }
6739
6740 if (num_units == 0)
6741 {
6742 error (_("No comp units in .debug_info section ?"));
6743 free (start);
6744 return 0;
6745 }
6746
6747 /* Then allocate an array to hold the pointer sizes. */
6748 debug_line_pointer_sizes = malloc (num_units * sizeof * debug_line_pointer_sizes);
6749 if (debug_line_pointer_sizes == NULL)
6750 {
6751 error (_("Not enough memory for a pointer size array of %u entries"),
6752 num_units);
6753 free (start);
6754 return 0;
6755 }
6756
6757 /* Populate the array. */
6758 for (begin = start, unit = 0; begin < end; unit++)
6759 {
6760 length = byte_get (begin, 4);
6761 if (length == 0xffffffff)
6762 {
6763 /* For 64-bit DWARF, the 1-byte address_size field is 22 bytes
6764 from the start of the section. This is computed as follows:
6765
6766 unit_length: 12 bytes
6767 version: 2 bytes
6768 debug_abbrev_offset: 8 bytes
6769 -----------------------------
6770 Total: 22 bytes */
6771
6772 debug_line_pointer_sizes [unit] = byte_get (begin + 22, 1);
6773 length = byte_get (begin + 4, 8);
6774 begin += length + 12;
6775 }
6776 else
6777 {
6778 /* For 32-bit DWARF, the 1-byte address_size field is 10 bytes from
6779 the start of the section:
0de14b54 6780
d9296b18
NC
6781 unit_length: 4 bytes
6782 version: 2 bytes
6783 debug_abbrev_offset: 4 bytes
6784 -----------------------------
6785 Total: 10 bytes */
6786
6787 debug_line_pointer_sizes [unit] = byte_get (begin + 10, 1);
6788 begin += length + 4;
6789 }
6790 }
6791
6792 free (start);
6793 num_debug_line_pointer_sizes = num_units;
6794 return num_units;
6795}
6796
252b5132 6797static int
d3ba0551 6798display_debug_lines (Elf_Internal_Shdr *section,
d9296b18 6799 unsigned char *start, FILE *file)
252b5132 6800{
ee42cf8c 6801 unsigned char *hdrptr;
b34976b6
AM
6802 DWARF2_Internal_LineInfo info;
6803 unsigned char *standard_opcodes;
6804 unsigned char *data = start;
6805 unsigned char *end = start + section->sh_size;
6806 unsigned char *end_of_sequence;
6807 int i;
ee42cf8c
NC
6808 int offset_size;
6809 int initial_length_size;
0e0c4098 6810 unsigned int comp_unit = 0;
252b5132
RH
6811
6812 printf (_("\nDump of debug contents of section %s:\n\n"),
6813 SECTION_NAME (section));
6814
d9296b18
NC
6815 if (num_debug_line_pointer_sizes == 0)
6816 get_debug_line_pointer_sizes (file);
6817
252b5132
RH
6818 while (data < end)
6819 {
0e0c4098
NC
6820 unsigned int pointer_size;
6821
ee42cf8c 6822 hdrptr = data;
252b5132
RH
6823
6824 /* Check the length of the block. */
ee42cf8c
NC
6825 info.li_length = byte_get (hdrptr, 4);
6826 hdrptr += 4;
428409d5
NC
6827
6828 if (info.li_length == 0xffffffff)
6829 {
ee42cf8c
NC
6830 /* This section is 64-bit DWARF 3. */
6831 info.li_length = byte_get (hdrptr, 8);
6832 hdrptr += 8;
6833 offset_size = 8;
6834 initial_length_size = 12;
6835 }
6836 else
6837 {
6838 offset_size = 4;
6839 initial_length_size = 4;
428409d5
NC
6840 }
6841
ee42cf8c 6842 if (info.li_length + initial_length_size > section->sh_size)
252b5132
RH
6843 {
6844 warn
6845 (_("The line info appears to be corrupt - the section is too small\n"));
6846 return 0;
6847 }
103f02d3 6848
252b5132 6849 /* Check its version number. */
ee42cf8c
NC
6850 info.li_version = byte_get (hdrptr, 2);
6851 hdrptr += 2;
6852 if (info.li_version != 2 && info.li_version != 3)
252b5132 6853 {
ee42cf8c 6854 warn (_("Only DWARF version 2 and 3 line info is currently supported.\n"));
252b5132
RH
6855 return 0;
6856 }
103f02d3 6857
ee42cf8c
NC
6858 info.li_prologue_length = byte_get (hdrptr, offset_size);
6859 hdrptr += offset_size;
6860 info.li_min_insn_length = byte_get (hdrptr, 1);
6861 hdrptr++;
6862 info.li_default_is_stmt = byte_get (hdrptr, 1);
6863 hdrptr++;
6864 info.li_line_base = byte_get (hdrptr, 1);
6865 hdrptr++;
6866 info.li_line_range = byte_get (hdrptr, 1);
6867 hdrptr++;
6868 info.li_opcode_base = byte_get (hdrptr, 1);
6869 hdrptr++;
103f02d3 6870
252b5132
RH
6871 /* Sign extend the line base field. */
6872 info.li_line_base <<= 24;
6873 info.li_line_base >>= 24;
103f02d3 6874
0e0c4098
NC
6875 /* Get the pointer size from the comp unit associated
6876 with this block of line number information. */
6877 if (comp_unit >= num_debug_line_pointer_sizes)
6878 {
6879 error (_("Not enough comp units for .debug_lines section\n"));
6880 return 0;
6881 }
6882 else
6883 {
6884 pointer_size = debug_line_pointer_sizes [comp_unit];
6885 comp_unit ++;
6886 }
6887
252b5132
RH
6888 printf (_(" Length: %ld\n"), info.li_length);
6889 printf (_(" DWARF Version: %d\n"), info.li_version);
ff94ebf2 6890 printf (_(" Prologue Length: %d\n"), info.li_prologue_length);
252b5132
RH
6891 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
6892 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
6893 printf (_(" Line Base: %d\n"), info.li_line_base);
6894 printf (_(" Line Range: %d\n"), info.li_line_range);
6895 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
0e0c4098 6896 printf (_(" (Pointer size: %u)\n"), pointer_size);
252b5132 6897
ee42cf8c 6898 end_of_sequence = data + info.li_length + initial_length_size;
252b5132
RH
6899
6900 reset_state_machine (info.li_default_is_stmt);
103f02d3 6901
252b5132 6902 /* Display the contents of the Opcodes table. */
ee42cf8c 6903 standard_opcodes = hdrptr;
103f02d3 6904
252b5132 6905 printf (_("\n Opcodes:\n"));
103f02d3 6906
252b5132 6907 for (i = 1; i < info.li_opcode_base; i++)
7a4b7442 6908 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
103f02d3 6909
252b5132
RH
6910 /* Display the contents of the Directory table. */
6911 data = standard_opcodes + info.li_opcode_base - 1;
103f02d3 6912
b34976b6 6913 if (*data == 0)
252b5132
RH
6914 printf (_("\n The Directory Table is empty.\n"));
6915 else
6916 {
6917 printf (_("\n The Directory Table:\n"));
103f02d3 6918
b34976b6 6919 while (*data != 0)
252b5132
RH
6920 {
6921 printf (_(" %s\n"), data);
103f02d3 6922
3c9f43b1 6923 data += strlen ((char *) data) + 1;
252b5132
RH
6924 }
6925 }
103f02d3 6926
252b5132 6927 /* Skip the NUL at the end of the table. */
b34976b6 6928 data++;
103f02d3 6929
252b5132 6930 /* Display the contents of the File Name table. */
b34976b6 6931 if (*data == 0)
252b5132
RH
6932 printf (_("\n The File Name Table is empty.\n"));
6933 else
6934 {
6935 printf (_("\n The File Name Table:\n"));
6936 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
103f02d3 6937
b34976b6 6938 while (*data != 0)
252b5132 6939 {
b34976b6 6940 unsigned char *name;
252b5132 6941 int bytes_read;
103f02d3 6942
b34976b6 6943 printf (_(" %d\t"), ++state_machine_regs.last_file_entry);
252b5132 6944 name = data;
103f02d3 6945
3c9f43b1 6946 data += strlen ((char *) data) + 1;
103f02d3 6947
252b5132
RH
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 (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6953 data += bytes_read;
6954 printf (_("%s\n"), name);
6955 }
6956 }
103f02d3 6957
252b5132 6958 /* Skip the NUL at the end of the table. */
b34976b6 6959 data++;
103f02d3 6960
252b5132
RH
6961 /* Now display the statements. */
6962 printf (_("\n Line Number Statements:\n"));
103f02d3
UD
6963
6964
252b5132
RH
6965 while (data < end_of_sequence)
6966 {
6967 unsigned char op_code;
b34976b6
AM
6968 int adv;
6969 int bytes_read;
103f02d3 6970
b34976b6 6971 op_code = *data++;
103f02d3 6972
1a509dcc
GK
6973 if (op_code >= info.li_opcode_base)
6974 {
6975 op_code -= info.li_opcode_base;
6976 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
6977 state_machine_regs.address += adv;
6978 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
6979 op_code, adv, state_machine_regs.address);
6980 adv = (op_code % info.li_line_range) + info.li_line_base;
6981 state_machine_regs.line += adv;
6982 printf (_(" and Line by %d to %d\n"),
6983 adv, state_machine_regs.line);
53c7db4b
KH
6984 }
6985 else switch (op_code)
252b5132
RH
6986 {
6987 case DW_LNS_extended_op:
3590ea00 6988 data += process_extended_line_op (data, info.li_default_is_stmt,
0e0c4098 6989 pointer_size);
252b5132 6990 break;
103f02d3 6991
252b5132
RH
6992 case DW_LNS_copy:
6993 printf (_(" Copy\n"));
6994 break;
103f02d3 6995
252b5132
RH
6996 case DW_LNS_advance_pc:
6997 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
6998 data += bytes_read;
6999 state_machine_regs.address += adv;
7000 printf (_(" Advance PC by %d to %lx\n"), adv,
7001 state_machine_regs.address);
7002 break;
103f02d3 7003
252b5132
RH
7004 case DW_LNS_advance_line:
7005 adv = read_leb128 (data, & bytes_read, 1);
7006 data += bytes_read;
7007 state_machine_regs.line += adv;
7008 printf (_(" Advance Line by %d to %d\n"), adv,
7009 state_machine_regs.line);
7010 break;
103f02d3 7011
252b5132
RH
7012 case DW_LNS_set_file:
7013 adv = read_leb128 (data, & bytes_read, 0);
7014 data += bytes_read;
7015 printf (_(" Set File Name to entry %d in the File Name Table\n"),
7016 adv);
7017 state_machine_regs.file = adv;
7018 break;
103f02d3 7019
252b5132
RH
7020 case DW_LNS_set_column:
7021 adv = read_leb128 (data, & bytes_read, 0);
7022 data += bytes_read;
7023 printf (_(" Set column to %d\n"), adv);
7024 state_machine_regs.column = adv;
7025 break;
103f02d3 7026
252b5132
RH
7027 case DW_LNS_negate_stmt:
7028 adv = state_machine_regs.is_stmt;
7029 adv = ! adv;
7030 printf (_(" Set is_stmt to %d\n"), adv);
7031 state_machine_regs.is_stmt = adv;
7032 break;
103f02d3 7033
252b5132
RH
7034 case DW_LNS_set_basic_block:
7035 printf (_(" Set basic block\n"));
7036 state_machine_regs.basic_block = 1;
7037 break;
103f02d3 7038
252b5132 7039 case DW_LNS_const_add_pc:
2366453a
NC
7040 adv = (((255 - info.li_opcode_base) / info.li_line_range)
7041 * info.li_min_insn_length);
252b5132
RH
7042 state_machine_regs.address += adv;
7043 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
7044 state_machine_regs.address);
7045 break;
103f02d3 7046
252b5132
RH
7047 case DW_LNS_fixed_advance_pc:
7048 adv = byte_get (data, 2);
7049 data += 2;
7050 state_machine_regs.address += adv;
7051 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
7052 adv, state_machine_regs.address);
7053 break;
103f02d3 7054
1a509dcc
GK
7055 case DW_LNS_set_prologue_end:
7056 printf (_(" Set prologue_end to true\n"));
7057 break;
53c7db4b 7058
1a509dcc
GK
7059 case DW_LNS_set_epilogue_begin:
7060 printf (_(" Set epilogue_begin to true\n"));
7061 break;
53c7db4b 7062
1a509dcc
GK
7063 case DW_LNS_set_isa:
7064 adv = read_leb128 (data, & bytes_read, 0);
7065 data += bytes_read;
7066 printf (_(" Set ISA to %d\n"), adv);
7067 break;
53c7db4b 7068
252b5132 7069 default:
1a509dcc
GK
7070 printf (_(" Unknown opcode %d with operands: "), op_code);
7071 {
7072 int i;
7073 for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
7074 {
7075 printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
7076 i == 1 ? "" : ", ");
7077 data += bytes_read;
7078 }
7079 putchar ('\n');
7080 }
252b5132
RH
7081 break;
7082 }
7083 }
1a509dcc 7084 putchar ('\n');
252b5132 7085 }
103f02d3 7086
252b5132
RH
7087 return 1;
7088}
7089
7090static int
d3ba0551
AM
7091display_debug_pubnames (Elf_Internal_Shdr *section,
7092 unsigned char *start,
7093 FILE *file ATTRIBUTE_UNUSED)
252b5132 7094{
b34976b6
AM
7095 DWARF2_Internal_PubNames pubnames;
7096 unsigned char *end;
252b5132
RH
7097
7098 end = start + section->sh_size;
7099
7100 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
7101
7102 while (start < end)
7103 {
b34976b6
AM
7104 unsigned char *data;
7105 unsigned long offset;
ee42cf8c 7106 int offset_size, initial_length_size;
252b5132 7107
ee42cf8c 7108 data = start;
252b5132 7109
ee42cf8c
NC
7110 pubnames.pn_length = byte_get (data, 4);
7111 data += 4;
428409d5
NC
7112 if (pubnames.pn_length == 0xffffffff)
7113 {
ee42cf8c
NC
7114 pubnames.pn_length = byte_get (data, 8);
7115 data += 8;
7116 offset_size = 8;
7117 initial_length_size = 12;
7118 }
7119 else
7120 {
7121 offset_size = 4;
7122 initial_length_size = 4;
428409d5
NC
7123 }
7124
ee42cf8c
NC
7125 pubnames.pn_version = byte_get (data, 2);
7126 data += 2;
7127 pubnames.pn_offset = byte_get (data, offset_size);
7128 data += offset_size;
7129 pubnames.pn_size = byte_get (data, offset_size);
7130 data += offset_size;
7131
7132 start += pubnames.pn_length + initial_length_size;
7133
7134 if (pubnames.pn_version != 2 && pubnames.pn_version != 3)
252b5132 7135 {
3f215a10
NC
7136 static int warned = 0;
7137
7138 if (! warned)
7139 {
ee42cf8c 7140 warn (_("Only DWARF 2 and 3 pubnames are currently supported\n"));
3f215a10
NC
7141 warned = 1;
7142 }
76da6bbe 7143
252b5132
RH
7144 continue;
7145 }
7146
7147 printf (_(" Length: %ld\n"),
7148 pubnames.pn_length);
7149 printf (_(" Version: %d\n"),
7150 pubnames.pn_version);
7151 printf (_(" Offset into .debug_info section: %ld\n"),
7152 pubnames.pn_offset);
7153 printf (_(" Size of area in .debug_info section: %ld\n"),
7154 pubnames.pn_size);
7155
7156 printf (_("\n Offset\tName\n"));
7157
7158 do
7159 {
ee42cf8c 7160 offset = byte_get (data, offset_size);
252b5132
RH
7161
7162 if (offset != 0)
7163 {
ee42cf8c 7164 data += offset_size;
935a41f5 7165 printf (" %-6ld\t\t%s\n", offset, data);
3c9f43b1 7166 data += strlen ((char *) data) + 1;
252b5132
RH
7167 }
7168 }
7169 while (offset != 0);
7170 }
7171
7172 printf ("\n");
7173 return 1;
7174}
7175
7176static char *
d3ba0551 7177get_TAG_name (unsigned long tag)
252b5132
RH
7178{
7179 switch (tag)
7180 {
b34976b6
AM
7181 case DW_TAG_padding: return "DW_TAG_padding";
7182 case DW_TAG_array_type: return "DW_TAG_array_type";
7183 case DW_TAG_class_type: return "DW_TAG_class_type";
7184 case DW_TAG_entry_point: return "DW_TAG_entry_point";
7185 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
7186 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
7187 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
7188 case DW_TAG_label: return "DW_TAG_label";
7189 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
7190 case DW_TAG_member: return "DW_TAG_member";
7191 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
7192 case DW_TAG_reference_type: return "DW_TAG_reference_type";
7193 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
7194 case DW_TAG_string_type: return "DW_TAG_string_type";
7195 case DW_TAG_structure_type: return "DW_TAG_structure_type";
7196 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
7197 case DW_TAG_typedef: return "DW_TAG_typedef";
7198 case DW_TAG_union_type: return "DW_TAG_union_type";
252b5132 7199 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
b34976b6
AM
7200 case DW_TAG_variant: return "DW_TAG_variant";
7201 case DW_TAG_common_block: return "DW_TAG_common_block";
7202 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
7203 case DW_TAG_inheritance: return "DW_TAG_inheritance";
7204 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
7205 case DW_TAG_module: return "DW_TAG_module";
7206 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
7207 case DW_TAG_set_type: return "DW_TAG_set_type";
7208 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
7209 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
7210 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
7211 case DW_TAG_base_type: return "DW_TAG_base_type";
7212 case DW_TAG_catch_block: return "DW_TAG_catch_block";
7213 case DW_TAG_const_type: return "DW_TAG_const_type";
7214 case DW_TAG_constant: return "DW_TAG_constant";
7215 case DW_TAG_enumerator: return "DW_TAG_enumerator";
7216 case DW_TAG_file_type: return "DW_TAG_file_type";
7217 case DW_TAG_friend: return "DW_TAG_friend";
7218 case DW_TAG_namelist: return "DW_TAG_namelist";
7219 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
7220 case DW_TAG_packed_type: return "DW_TAG_packed_type";
7221 case DW_TAG_subprogram: return "DW_TAG_subprogram";
7222 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
7223 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
7224 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
7225 case DW_TAG_try_block: return "DW_TAG_try_block";
7226 case DW_TAG_variant_part: return "DW_TAG_variant_part";
7227 case DW_TAG_variable: return "DW_TAG_variable";
7228 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
7229 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
7230 case DW_TAG_format_label: return "DW_TAG_format_label";
7231 case DW_TAG_function_template: return "DW_TAG_function_template";
7232 case DW_TAG_class_template: return "DW_TAG_class_template";
b811889f 7233 /* DWARF 2.1 values. */
b34976b6
AM
7234 case DW_TAG_dwarf_procedure: return "DW_TAG_dwarf_procedure";
7235 case DW_TAG_restrict_type: return "DW_TAG_restrict_type";
7236 case DW_TAG_interface_type: return "DW_TAG_interface_type";
7237 case DW_TAG_namespace: return "DW_TAG_namespace";
7238 case DW_TAG_imported_module: return "DW_TAG_imported_module";
7239 case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type";
7240 case DW_TAG_partial_unit: return "DW_TAG_partial_unit";
7241 case DW_TAG_imported_unit: return "DW_TAG_imported_unit";
84ad6ede 7242 /* UPC values. */
ba2685cc
AM
7243 case DW_TAG_upc_shared_type: return "DW_TAG_upc_shared_type";
7244 case DW_TAG_upc_strict_type: return "DW_TAG_upc_strict_type";
7245 case DW_TAG_upc_relaxed_type: return "DW_TAG_upc_relaxed_type";
252b5132
RH
7246 default:
7247 {
b34976b6 7248 static char buffer[100];
252b5132
RH
7249
7250 sprintf (buffer, _("Unknown TAG value: %lx"), tag);
7251 return buffer;
7252 }
7253 }
7254}
7255
7256static char *
d3ba0551 7257get_AT_name (unsigned long attribute)
252b5132
RH
7258{
7259 switch (attribute)
7260 {
b34976b6
AM
7261 case DW_AT_sibling: return "DW_AT_sibling";
7262 case DW_AT_location: return "DW_AT_location";
7263 case DW_AT_name: return "DW_AT_name";
7264 case DW_AT_ordering: return "DW_AT_ordering";
7265 case DW_AT_subscr_data: return "DW_AT_subscr_data";
7266 case DW_AT_byte_size: return "DW_AT_byte_size";
7267 case DW_AT_bit_offset: return "DW_AT_bit_offset";
7268 case DW_AT_bit_size: return "DW_AT_bit_size";
7269 case DW_AT_element_list: return "DW_AT_element_list";
7270 case DW_AT_stmt_list: return "DW_AT_stmt_list";
7271 case DW_AT_low_pc: return "DW_AT_low_pc";
7272 case DW_AT_high_pc: return "DW_AT_high_pc";
7273 case DW_AT_language: return "DW_AT_language";
7274 case DW_AT_member: return "DW_AT_member";
7275 case DW_AT_discr: return "DW_AT_discr";
7276 case DW_AT_discr_value: return "DW_AT_discr_value";
7277 case DW_AT_visibility: return "DW_AT_visibility";
7278 case DW_AT_import: return "DW_AT_import";
7279 case DW_AT_string_length: return "DW_AT_string_length";
7280 case DW_AT_common_reference: return "DW_AT_common_reference";
7281 case DW_AT_comp_dir: return "DW_AT_comp_dir";
7282 case DW_AT_const_value: return "DW_AT_const_value";
7283 case DW_AT_containing_type: return "DW_AT_containing_type";
7284 case DW_AT_default_value: return "DW_AT_default_value";
7285 case DW_AT_inline: return "DW_AT_inline";
7286 case DW_AT_is_optional: return "DW_AT_is_optional";
7287 case DW_AT_lower_bound: return "DW_AT_lower_bound";
7288 case DW_AT_producer: return "DW_AT_producer";
7289 case DW_AT_prototyped: return "DW_AT_prototyped";
7290 case DW_AT_return_addr: return "DW_AT_return_addr";
7291 case DW_AT_start_scope: return "DW_AT_start_scope";
7292 case DW_AT_stride_size: return "DW_AT_stride_size";
7293 case DW_AT_upper_bound: return "DW_AT_upper_bound";
7294 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
7295 case DW_AT_accessibility: return "DW_AT_accessibility";
7296 case DW_AT_address_class: return "DW_AT_address_class";
7297 case DW_AT_artificial: return "DW_AT_artificial";
7298 case DW_AT_base_types: return "DW_AT_base_types";
7299 case DW_AT_calling_convention: return "DW_AT_calling_convention";
7300 case DW_AT_count: return "DW_AT_count";
7301 case DW_AT_data_member_location: return "DW_AT_data_member_location";
7302 case DW_AT_decl_column: return "DW_AT_decl_column";
7303 case DW_AT_decl_file: return "DW_AT_decl_file";
7304 case DW_AT_decl_line: return "DW_AT_decl_line";
7305 case DW_AT_declaration: return "DW_AT_declaration";
7306 case DW_AT_discr_list: return "DW_AT_discr_list";
7307 case DW_AT_encoding: return "DW_AT_encoding";
7308 case DW_AT_external: return "DW_AT_external";
7309 case DW_AT_frame_base: return "DW_AT_frame_base";
7310 case DW_AT_friend: return "DW_AT_friend";
7311 case DW_AT_identifier_case: return "DW_AT_identifier_case";
7312 case DW_AT_macro_info: return "DW_AT_macro_info";
7313 case DW_AT_namelist_items: return "DW_AT_namelist_items";
7314 case DW_AT_priority: return "DW_AT_priority";
7315 case DW_AT_segment: return "DW_AT_segment";
7316 case DW_AT_specification: return "DW_AT_specification";
7317 case DW_AT_static_link: return "DW_AT_static_link";
7318 case DW_AT_type: return "DW_AT_type";
7319 case DW_AT_use_location: return "DW_AT_use_location";
7320 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
7321 case DW_AT_virtuality: return "DW_AT_virtuality";
7322 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
12ab83a9 7323 /* DWARF 2.1 values. */
b34976b6
AM
7324 case DW_AT_allocated: return "DW_AT_allocated";
7325 case DW_AT_associated: return "DW_AT_associated";
7326 case DW_AT_data_location: return "DW_AT_data_location";
7327 case DW_AT_stride: return "DW_AT_stride";
7328 case DW_AT_entry_pc: return "DW_AT_entry_pc";
7329 case DW_AT_use_UTF8: return "DW_AT_use_UTF8";
7330 case DW_AT_extension: return "DW_AT_extension";
7331 case DW_AT_ranges: return "DW_AT_ranges";
7332 case DW_AT_trampoline: return "DW_AT_trampoline";
7333 case DW_AT_call_column: return "DW_AT_call_column";
7334 case DW_AT_call_file: return "DW_AT_call_file";
7335 case DW_AT_call_line: return "DW_AT_call_line";
12ab83a9 7336 /* SGI/MIPS extensions. */
b34976b6
AM
7337 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
7338 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
7339 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
7340 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
252b5132 7341 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
b34976b6
AM
7342 case DW_AT_MIPS_software_pipeline_depth:
7343 return "DW_AT_MIPS_software_pipeline_depth";
7344 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
7345 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
7346 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
7347 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
7348 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
12ab83a9 7349 /* GNU extensions. */
b34976b6
AM
7350 case DW_AT_sf_names: return "DW_AT_sf_names";
7351 case DW_AT_src_info: return "DW_AT_src_info";
7352 case DW_AT_mac_info: return "DW_AT_mac_info";
7353 case DW_AT_src_coords: return "DW_AT_src_coords";
7354 case DW_AT_body_begin: return "DW_AT_body_begin";
7355 case DW_AT_body_end: return "DW_AT_body_end";
7356 case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
84ad6ede
NC
7357 /* UPC extension. */
7358 case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled";
252b5132
RH
7359 default:
7360 {
b34976b6 7361 static char buffer[100];
252b5132
RH
7362
7363 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
7364 return buffer;
7365 }
7366 }
7367}
7368
7369static char *
d3ba0551 7370get_FORM_name (unsigned long form)
252b5132
RH
7371{
7372 switch (form)
7373 {
b34976b6
AM
7374 case DW_FORM_addr: return "DW_FORM_addr";
7375 case DW_FORM_block2: return "DW_FORM_block2";
7376 case DW_FORM_block4: return "DW_FORM_block4";
7377 case DW_FORM_data2: return "DW_FORM_data2";
7378 case DW_FORM_data4: return "DW_FORM_data4";
7379 case DW_FORM_data8: return "DW_FORM_data8";
7380 case DW_FORM_string: return "DW_FORM_string";
7381 case DW_FORM_block: return "DW_FORM_block";
7382 case DW_FORM_block1: return "DW_FORM_block1";
7383 case DW_FORM_data1: return "DW_FORM_data1";
7384 case DW_FORM_flag: return "DW_FORM_flag";
7385 case DW_FORM_sdata: return "DW_FORM_sdata";
7386 case DW_FORM_strp: return "DW_FORM_strp";
7387 case DW_FORM_udata: return "DW_FORM_udata";
7388 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
7389 case DW_FORM_ref1: return "DW_FORM_ref1";
7390 case DW_FORM_ref2: return "DW_FORM_ref2";
7391 case DW_FORM_ref4: return "DW_FORM_ref4";
7392 case DW_FORM_ref8: return "DW_FORM_ref8";
7393 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
7394 case DW_FORM_indirect: return "DW_FORM_indirect";
252b5132
RH
7395 default:
7396 {
b34976b6 7397 static char buffer[100];
252b5132
RH
7398
7399 sprintf (buffer, _("Unknown FORM value: %lx"), form);
7400 return buffer;
7401 }
7402 }
7403}
7404
50c2245b 7405/* FIXME: There are better and more efficient ways to handle
252b5132
RH
7406 these structures. For now though, I just want something that
7407 is simple to implement. */
7408typedef struct abbrev_attr
7409{
b34976b6
AM
7410 unsigned long attribute;
7411 unsigned long form;
7412 struct abbrev_attr *next;
252b5132
RH
7413}
7414abbrev_attr;
7415
7416typedef struct abbrev_entry
7417{
b34976b6
AM
7418 unsigned long entry;
7419 unsigned long tag;
7420 int children;
7421 struct abbrev_attr *first_attr;
7422 struct abbrev_attr *last_attr;
7423 struct abbrev_entry *next;
252b5132
RH
7424}
7425abbrev_entry;
7426
b34976b6
AM
7427static abbrev_entry *first_abbrev = NULL;
7428static abbrev_entry *last_abbrev = NULL;
252b5132
RH
7429
7430static void
d3ba0551 7431free_abbrevs (void)
252b5132 7432{
b34976b6 7433 abbrev_entry *abbrev;
252b5132
RH
7434
7435 for (abbrev = first_abbrev; abbrev;)
7436 {
b34976b6
AM
7437 abbrev_entry *next = abbrev->next;
7438 abbrev_attr *attr;
252b5132
RH
7439
7440 for (attr = abbrev->first_attr; attr;)
7441 {
b34976b6 7442 abbrev_attr *next = attr->next;
252b5132
RH
7443
7444 free (attr);
7445 attr = next;
7446 }
7447
7448 free (abbrev);
7449 abbrev = next;
7450 }
7451
7452 last_abbrev = first_abbrev = NULL;
7453}
7454
7455static void
d3ba0551 7456add_abbrev (unsigned long number, unsigned long tag, int children)
252b5132 7457{
b34976b6 7458 abbrev_entry *entry;
252b5132 7459
d3ba0551 7460 entry = malloc (sizeof (*entry));
252b5132
RH
7461
7462 if (entry == NULL)
7463 /* ugg */
7464 return;
7465
7466 entry->entry = number;
7467 entry->tag = tag;
7468 entry->children = children;
7469 entry->first_attr = NULL;
7470 entry->last_attr = NULL;
7471 entry->next = NULL;
7472
7473 if (first_abbrev == NULL)
7474 first_abbrev = entry;
7475 else
7476 last_abbrev->next = entry;
7477
7478 last_abbrev = entry;
7479}
7480
7481static void
d3ba0551 7482add_abbrev_attr (unsigned long attribute, unsigned long form)
252b5132 7483{
b34976b6 7484 abbrev_attr *attr;
252b5132 7485
d3ba0551 7486 attr = malloc (sizeof (*attr));
252b5132
RH
7487
7488 if (attr == NULL)
7489 /* ugg */
7490 return;
7491
7492 attr->attribute = attribute;
7493 attr->form = form;
7494 attr->next = NULL;
7495
7496 if (last_abbrev->first_attr == NULL)
7497 last_abbrev->first_attr = attr;
7498 else
7499 last_abbrev->last_attr->next = attr;
7500
7501 last_abbrev->last_attr = attr;
7502}
7503
7504/* Processes the (partial) contents of a .debug_abbrev section.
7505 Returns NULL if the end of the section was encountered.
7506 Returns the address after the last byte read if the end of
7507 an abbreviation set was found. */
7508
7509static unsigned char *
d3ba0551 7510process_abbrev_section (unsigned char *start, unsigned char *end)
252b5132
RH
7511{
7512 if (first_abbrev != NULL)
7513 return NULL;
7514
7515 while (start < end)
7516 {
b34976b6 7517 int bytes_read;
252b5132
RH
7518 unsigned long entry;
7519 unsigned long tag;
7520 unsigned long attribute;
b34976b6 7521 int children;
252b5132
RH
7522
7523 entry = read_leb128 (start, & bytes_read, 0);
7524 start += bytes_read;
7525
a3f779db
NC
7526 /* A single zero is supposed to end the section according
7527 to the standard. If there's more, then signal that to
7528 the caller. */
252b5132 7529 if (entry == 0)
a3f779db 7530 return start == end ? NULL : start;
252b5132
RH
7531
7532 tag = read_leb128 (start, & bytes_read, 0);
7533 start += bytes_read;
7534
b34976b6 7535 children = *start++;
252b5132
RH
7536
7537 add_abbrev (entry, tag, children);
7538
7539 do
7540 {
7541 unsigned long form;
7542
7543 attribute = read_leb128 (start, & bytes_read, 0);
7544 start += bytes_read;
7545
7546 form = read_leb128 (start, & bytes_read, 0);
7547 start += bytes_read;
7548
7549 if (attribute != 0)
7550 add_abbrev_attr (attribute, form);
7551 }
7552 while (attribute != 0);
7553 }
7554
7555 return NULL;
7556}
7557
7558
e0c60db2 7559static int
d3ba0551
AM
7560display_debug_macinfo (Elf_Internal_Shdr *section,
7561 unsigned char *start,
7562 FILE *file ATTRIBUTE_UNUSED)
e0c60db2 7563{
b34976b6
AM
7564 unsigned char *end = start + section->sh_size;
7565 unsigned char *curr = start;
e0c60db2
NC
7566 unsigned int bytes_read;
7567 enum dwarf_macinfo_record_type op;
7568
7569 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
7570
7571 while (curr < end)
7572 {
7573 unsigned int lineno;
b34976b6 7574 const char *string;
e0c60db2 7575
b34976b6
AM
7576 op = *curr;
7577 curr++;
e0c60db2
NC
7578
7579 switch (op)
7580 {
7581 case DW_MACINFO_start_file:
7582 {
7583 unsigned int filenum;
7584
7585 lineno = read_leb128 (curr, & bytes_read, 0);
7586 curr += bytes_read;
7587 filenum = read_leb128 (curr, & bytes_read, 0);
7588 curr += bytes_read;
7589
7590 printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"), lineno, filenum);
7591 }
7592 break;
7593
7594 case DW_MACINFO_end_file:
7595 printf (_(" DW_MACINFO_end_file\n"));
7596 break;
7597
7598 case DW_MACINFO_define:
7599 lineno = read_leb128 (curr, & bytes_read, 0);
7600 curr += bytes_read;
7601 string = curr;
7602 curr += strlen (string) + 1;
7603 printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"), lineno, string);
7604 break;
7605
7606 case DW_MACINFO_undef:
7607 lineno = read_leb128 (curr, & bytes_read, 0);
7608 curr += bytes_read;
7609 string = curr;
7610 curr += strlen (string) + 1;
7611 printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"), lineno, string);
7612 break;
7613
7614 case DW_MACINFO_vendor_ext:
7615 {
7616 unsigned int constant;
7617
7618 constant = read_leb128 (curr, & bytes_read, 0);
7619 curr += bytes_read;
7620 string = curr;
7621 curr += strlen (string) + 1;
7622 printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"), constant, string);
7623 }
7624 break;
7625 }
7626 }
7627
7628 return 1;
7629}
0823fbca 7630
e0c60db2 7631
252b5132 7632static int
d3ba0551
AM
7633display_debug_abbrev (Elf_Internal_Shdr *section,
7634 unsigned char *start,
7635 FILE *file ATTRIBUTE_UNUSED)
252b5132 7636{
b34976b6
AM
7637 abbrev_entry *entry;
7638 unsigned char *end = start + section->sh_size;
252b5132
RH
7639
7640 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
7641
7642 do
7643 {
7644 start = process_abbrev_section (start, end);
7645
ef5cdfc7
JJ
7646 if (first_abbrev == NULL)
7647 continue;
7648
252b5132
RH
7649 printf (_(" Number TAG\n"));
7650
7651 for (entry = first_abbrev; entry; entry = entry->next)
7652 {
b34976b6 7653 abbrev_attr *attr;
252b5132
RH
7654
7655 printf (_(" %ld %s [%s]\n"),
7656 entry->entry,
7657 get_TAG_name (entry->tag),
7658 entry->children ? _("has children") : _("no children"));
7659
7660 for (attr = entry->first_attr; attr; attr = attr->next)
7661 {
7662 printf (_(" %-18s %s\n"),
7663 get_AT_name (attr->attribute),
7664 get_FORM_name (attr->form));
7665 }
7666 }
ef5cdfc7
JJ
7667
7668 free_abbrevs ();
252b5132
RH
7669 }
7670 while (start);
7671
7672 printf ("\n");
7673
7674 return 1;
7675}
7676
7677
7678static unsigned char *
d3ba0551 7679display_block (unsigned char *data, unsigned long length)
252b5132
RH
7680{
7681 printf (_(" %lu byte block: "), length);
7682
7683 while (length --)
b34976b6 7684 printf ("%lx ", (unsigned long) byte_get (data++, 1));
252b5132
RH
7685
7686 return data;
7687}
7688
7689static void
d3ba0551
AM
7690decode_location_expression (unsigned char * data,
7691 unsigned int pointer_size,
7692 unsigned long length)
252b5132 7693{
b34976b6
AM
7694 unsigned op;
7695 int bytes_read;
7696 unsigned long uvalue;
7697 unsigned char *end = data + length;
252b5132 7698
eb6bd4d3 7699 while (data < end)
252b5132 7700 {
b34976b6 7701 op = *data++;
252b5132 7702
eb6bd4d3
JM
7703 switch (op)
7704 {
7705 case DW_OP_addr:
7706 printf ("DW_OP_addr: %lx",
7707 (unsigned long) byte_get (data, pointer_size));
7708 data += pointer_size;
7709 break;
7710 case DW_OP_deref:
7711 printf ("DW_OP_deref");
7712 break;
7713 case DW_OP_const1u:
7714 printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
7715 break;
7716 case DW_OP_const1s:
74013231 7717 printf ("DW_OP_const1s: %ld", (long) byte_get_signed (data++, 1));
eb6bd4d3
JM
7718 break;
7719 case DW_OP_const2u:
7720 printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
7721 data += 2;
7722 break;
7723 case DW_OP_const2s:
74013231 7724 printf ("DW_OP_const2s: %ld", (long) byte_get_signed (data, 2));
eb6bd4d3
JM
7725 data += 2;
7726 break;
7727 case DW_OP_const4u:
7728 printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
7729 data += 4;
7730 break;
7731 case DW_OP_const4s:
74013231 7732 printf ("DW_OP_const4s: %ld", (long) byte_get_signed (data, 4));
eb6bd4d3
JM
7733 data += 4;
7734 break;
7735 case DW_OP_const8u:
7736 printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
7737 (unsigned long) byte_get (data + 4, 4));
7738 data += 8;
7739 break;
7740 case DW_OP_const8s:
7741 printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
7742 (long) byte_get (data + 4, 4));
7743 data += 8;
7744 break;
7745 case DW_OP_constu:
7746 printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
7747 data += bytes_read;
7748 break;
7749 case DW_OP_consts:
7750 printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
7751 data += bytes_read;
7752 break;
7753 case DW_OP_dup:
7754 printf ("DW_OP_dup");
7755 break;
7756 case DW_OP_drop:
7757 printf ("DW_OP_drop");
7758 break;
7759 case DW_OP_over:
7760 printf ("DW_OP_over");
7761 break;
7762 case DW_OP_pick:
7763 printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
7764 break;
7765 case DW_OP_swap:
7766 printf ("DW_OP_swap");
7767 break;
7768 case DW_OP_rot:
7769 printf ("DW_OP_rot");
7770 break;
7771 case DW_OP_xderef:
7772 printf ("DW_OP_xderef");
7773 break;
7774 case DW_OP_abs:
7775 printf ("DW_OP_abs");
7776 break;
7777 case DW_OP_and:
7778 printf ("DW_OP_and");
7779 break;
7780 case DW_OP_div:
7781 printf ("DW_OP_div");
7782 break;
7783 case DW_OP_minus:
7784 printf ("DW_OP_minus");
7785 break;
7786 case DW_OP_mod:
7787 printf ("DW_OP_mod");
7788 break;
7789 case DW_OP_mul:
7790 printf ("DW_OP_mul");
7791 break;
7792 case DW_OP_neg:
7793 printf ("DW_OP_neg");
7794 break;
7795 case DW_OP_not:
7796 printf ("DW_OP_not");
7797 break;
7798 case DW_OP_or:
7799 printf ("DW_OP_or");
7800 break;
7801 case DW_OP_plus:
7802 printf ("DW_OP_plus");
7803 break;
7804 case DW_OP_plus_uconst:
7805 printf ("DW_OP_plus_uconst: %lu",
7806 read_leb128 (data, &bytes_read, 0));
7807 data += bytes_read;
7808 break;
7809 case DW_OP_shl:
7810 printf ("DW_OP_shl");
7811 break;
7812 case DW_OP_shr:
7813 printf ("DW_OP_shr");
7814 break;
7815 case DW_OP_shra:
7816 printf ("DW_OP_shra");
7817 break;
7818 case DW_OP_xor:
7819 printf ("DW_OP_xor");
7820 break;
7821 case DW_OP_bra:
74013231 7822 printf ("DW_OP_bra: %ld", (long) byte_get_signed (data, 2));
eb6bd4d3
JM
7823 data += 2;
7824 break;
7825 case DW_OP_eq:
7826 printf ("DW_OP_eq");
7827 break;
7828 case DW_OP_ge:
7829 printf ("DW_OP_ge");
7830 break;
7831 case DW_OP_gt:
7832 printf ("DW_OP_gt");
7833 break;
7834 case DW_OP_le:
7835 printf ("DW_OP_le");
7836 break;
7837 case DW_OP_lt:
7838 printf ("DW_OP_lt");
7839 break;
7840 case DW_OP_ne:
7841 printf ("DW_OP_ne");
7842 break;
7843 case DW_OP_skip:
74013231 7844 printf ("DW_OP_skip: %ld", (long) byte_get_signed (data, 2));
eb6bd4d3
JM
7845 data += 2;
7846 break;
7847
7848 case DW_OP_lit0:
7849 case DW_OP_lit1:
7850 case DW_OP_lit2:
7851 case DW_OP_lit3:
7852 case DW_OP_lit4:
7853 case DW_OP_lit5:
7854 case DW_OP_lit6:
7855 case DW_OP_lit7:
7856 case DW_OP_lit8:
7857 case DW_OP_lit9:
7858 case DW_OP_lit10:
7859 case DW_OP_lit11:
7860 case DW_OP_lit12:
7861 case DW_OP_lit13:
7862 case DW_OP_lit14:
7863 case DW_OP_lit15:
7864 case DW_OP_lit16:
7865 case DW_OP_lit17:
7866 case DW_OP_lit18:
7867 case DW_OP_lit19:
7868 case DW_OP_lit20:
7869 case DW_OP_lit21:
7870 case DW_OP_lit22:
7871 case DW_OP_lit23:
7872 case DW_OP_lit24:
7873 case DW_OP_lit25:
7874 case DW_OP_lit26:
7875 case DW_OP_lit27:
7876 case DW_OP_lit28:
7877 case DW_OP_lit29:
7878 case DW_OP_lit30:
7879 case DW_OP_lit31:
7880 printf ("DW_OP_lit%d", op - DW_OP_lit0);
7881 break;
7882
7883 case DW_OP_reg0:
7884 case DW_OP_reg1:
7885 case DW_OP_reg2:
7886 case DW_OP_reg3:
7887 case DW_OP_reg4:
7888 case DW_OP_reg5:
7889 case DW_OP_reg6:
7890 case DW_OP_reg7:
7891 case DW_OP_reg8:
7892 case DW_OP_reg9:
7893 case DW_OP_reg10:
7894 case DW_OP_reg11:
7895 case DW_OP_reg12:
7896 case DW_OP_reg13:
7897 case DW_OP_reg14:
7898 case DW_OP_reg15:
7899 case DW_OP_reg16:
7900 case DW_OP_reg17:
7901 case DW_OP_reg18:
7902 case DW_OP_reg19:
7903 case DW_OP_reg20:
7904 case DW_OP_reg21:
7905 case DW_OP_reg22:
7906 case DW_OP_reg23:
7907 case DW_OP_reg24:
7908 case DW_OP_reg25:
7909 case DW_OP_reg26:
7910 case DW_OP_reg27:
7911 case DW_OP_reg28:
7912 case DW_OP_reg29:
7913 case DW_OP_reg30:
7914 case DW_OP_reg31:
7915 printf ("DW_OP_reg%d", op - DW_OP_reg0);
7916 break;
7917
7918 case DW_OP_breg0:
7919 case DW_OP_breg1:
7920 case DW_OP_breg2:
7921 case DW_OP_breg3:
7922 case DW_OP_breg4:
7923 case DW_OP_breg5:
7924 case DW_OP_breg6:
7925 case DW_OP_breg7:
7926 case DW_OP_breg8:
7927 case DW_OP_breg9:
7928 case DW_OP_breg10:
7929 case DW_OP_breg11:
7930 case DW_OP_breg12:
7931 case DW_OP_breg13:
7932 case DW_OP_breg14:
7933 case DW_OP_breg15:
7934 case DW_OP_breg16:
7935 case DW_OP_breg17:
7936 case DW_OP_breg18:
7937 case DW_OP_breg19:
7938 case DW_OP_breg20:
7939 case DW_OP_breg21:
7940 case DW_OP_breg22:
7941 case DW_OP_breg23:
7942 case DW_OP_breg24:
7943 case DW_OP_breg25:
7944 case DW_OP_breg26:
7945 case DW_OP_breg27:
7946 case DW_OP_breg28:
7947 case DW_OP_breg29:
7948 case DW_OP_breg30:
7949 case DW_OP_breg31:
7950 printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
7951 read_leb128 (data, &bytes_read, 1));
7952 data += bytes_read;
7953 break;
7954
7955 case DW_OP_regx:
7956 printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
7957 data += bytes_read;
7958 break;
7959 case DW_OP_fbreg:
7960 printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
7961 data += bytes_read;
7962 break;
7963 case DW_OP_bregx:
7964 uvalue = read_leb128 (data, &bytes_read, 0);
7965 data += bytes_read;
7966 printf ("DW_OP_bregx: %lu %ld", uvalue,
7967 read_leb128 (data, &bytes_read, 1));
7968 data += bytes_read;
7969 break;
7970 case DW_OP_piece:
7971 printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
7972 data += bytes_read;
7973 break;
7974 case DW_OP_deref_size:
7975 printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
7976 break;
7977 case DW_OP_xderef_size:
7978 printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
7979 break;
7980 case DW_OP_nop:
7981 printf ("DW_OP_nop");
7982 break;
7983
065c959b 7984 /* DWARF 3 extensions. */
12ab83a9
NC
7985 case DW_OP_push_object_address:
7986 printf ("DW_OP_push_object_address");
7987 break;
7988 case DW_OP_call2:
7989 printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2));
7990 data += 2;
7991 break;
7992 case DW_OP_call4:
7993 printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4));
7994 data += 4;
7995 break;
065c959b
NC
7996 case DW_OP_call_ref:
7997 printf ("DW_OP_call_ref");
7998 break;
7999
8000 /* GNU extensions. */
8001 case DW_OP_GNU_push_tls_address:
8002 printf ("DW_OP_GNU_push_tls_address");
12ab83a9
NC
8003 break;
8004
eb6bd4d3
JM
8005 default:
8006 if (op >= DW_OP_lo_user
8007 && op <= DW_OP_hi_user)
8008 printf (_("(User defined location op)"));
8009 else
8010 printf (_("(Unknown location op)"));
8011 /* No way to tell where the next op is, so just bail. */
8012 return;
8013 }
12ab83a9
NC
8014
8015 /* Separate the ops. */
3f7de0e7
NC
8016 if (data < end)
8017 printf ("; ");
252b5132
RH
8018 }
8019}
8020
b34976b6
AM
8021static const char *debug_loc_contents;
8022static bfd_vma debug_loc_size;
a2f14207
DB
8023
8024static void
d3ba0551 8025load_debug_loc (FILE *file)
a2f14207 8026{
b34976b6 8027 Elf_Internal_Shdr *sec;
a2f14207
DB
8028
8029 /* If it is already loaded, do nothing. */
8030 if (debug_loc_contents != NULL)
8031 return;
8032
8033 /* Locate the .debug_loc section. */
d9296b18
NC
8034 sec = find_section (".debug_loc");
8035 if (sec == NULL)
a2f14207
DB
8036 return;
8037
8038 debug_loc_size = sec->sh_size;
8039
d3ba0551
AM
8040 debug_loc_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
8041 _("debug_loc section data"));
a2f14207
DB
8042}
8043
8044static void
d3ba0551 8045free_debug_loc (void)
a2f14207
DB
8046{
8047 if (debug_loc_contents == NULL)
8048 return;
8049
8050 free ((char *) debug_loc_contents);
8051 debug_loc_contents = NULL;
8052 debug_loc_size = 0;
8053}
8054
a2f14207 8055
a2f14207 8056static int
d3ba0551 8057display_debug_loc (Elf_Internal_Shdr *section,
d9296b18 8058 unsigned char *start, FILE *file)
a2f14207
DB
8059{
8060 unsigned char *section_end;
8061 unsigned long bytes;
8062 unsigned char *section_begin = start;
8063 bfd_vma addr;
0e0c4098 8064 unsigned int comp_unit = 0;
53c7db4b 8065
a2f14207
DB
8066 addr = section->sh_addr;
8067 bytes = section->sh_size;
8068 section_end = start + bytes;
065c959b 8069
a2f14207
DB
8070 if (bytes == 0)
8071 {
8072 printf (_("\nThe .debug_loc section is empty.\n"));
8073 return 0;
8074 }
065c959b 8075
d9296b18
NC
8076 if (num_debug_line_pointer_sizes == 0)
8077 get_debug_line_pointer_sizes (file);
8078
a2f14207
DB
8079 printf (_("Contents of the .debug_loc section:\n\n"));
8080 printf (_("\n Offset Begin End Expression\n"));
065c959b 8081
a2f14207
DB
8082 while (start < section_end)
8083 {
8084 unsigned long begin;
8085 unsigned long end;
8086 unsigned short length;
8087 unsigned long offset;
0e0c4098 8088 unsigned int pointer_size;
a2f14207
DB
8089
8090 offset = start - section_begin;
8091
0e0c4098
NC
8092 /* Get the pointer size from the comp unit associated
8093 with this block of location information. */
8094 if (comp_unit >= num_debug_line_pointer_sizes)
8095 {
8096 error (_("Not enough comp units for .debug_loc section\n"));
8097 return 0;
8098 }
8099 else
8100 {
8101 pointer_size = debug_line_pointer_sizes [comp_unit];
8102 comp_unit ++;
8103 }
8104
a2f14207
DB
8105 while (1)
8106 {
0e0c4098
NC
8107 begin = byte_get (start, pointer_size);
8108 start += pointer_size;
8109 end = byte_get (start, pointer_size);
8110 start += pointer_size;
53c7db4b 8111
a2f14207
DB
8112 if (begin == 0 && end == 0)
8113 break;
53c7db4b 8114
8dde85fc
NC
8115 /* For now, skip any base address specifiers. */
8116 if (begin == 0xffffffff)
8117 continue;
8118
a2f14207
DB
8119 begin += addr;
8120 end += addr;
53c7db4b 8121
a2f14207
DB
8122 length = byte_get (start, 2);
8123 start += 2;
53c7db4b 8124
a2f14207 8125 printf (" %8.8lx %8.8lx %8.8lx (", offset, begin, end);
0e0c4098 8126 decode_location_expression (start, pointer_size, length);
a2f14207 8127 printf (")\n");
53c7db4b 8128
a2f14207
DB
8129 start += length;
8130 }
8131 printf ("\n");
8132 }
8133 return 1;
8134}
252b5132 8135
b34976b6
AM
8136static const char *debug_str_contents;
8137static bfd_vma debug_str_size;
261a45ad
NC
8138
8139static void
d3ba0551 8140load_debug_str (FILE *file)
261a45ad 8141{
b34976b6 8142 Elf_Internal_Shdr *sec;
261a45ad
NC
8143
8144 /* If it is already loaded, do nothing. */
8145 if (debug_str_contents != NULL)
8146 return;
8147
8148 /* Locate the .debug_str section. */
d9296b18
NC
8149 sec = find_section (".debug_str");
8150 if (sec == NULL)
261a45ad
NC
8151 return;
8152
8153 debug_str_size = sec->sh_size;
8154
d3ba0551
AM
8155 debug_str_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
8156 _("debug_str section data"));
261a45ad
NC
8157}
8158
8159static void
d3ba0551 8160free_debug_str (void)
261a45ad
NC
8161{
8162 if (debug_str_contents == NULL)
8163 return;
8164
8165 free ((char *) debug_str_contents);
8166 debug_str_contents = NULL;
8167 debug_str_size = 0;
8168}
8169
8170static const char *
d3ba0551 8171fetch_indirect_string (unsigned long offset)
261a45ad
NC
8172{
8173 if (debug_str_contents == NULL)
8174 return _("<no .debug_str section>");
8175
8176 if (offset > debug_str_size)
8177 return _("<offset is too big>");
8178
8179 return debug_str_contents + offset;
8180}
8181
261a45ad 8182static int
d3ba0551
AM
8183display_debug_str (Elf_Internal_Shdr *section,
8184 unsigned char *start,
8185 FILE *file ATTRIBUTE_UNUSED)
261a45ad 8186{
b34976b6
AM
8187 unsigned long bytes;
8188 bfd_vma addr;
261a45ad
NC
8189
8190 addr = section->sh_addr;
8191 bytes = section->sh_size;
8192
8193 if (bytes == 0)
8194 {
8195 printf (_("\nThe .debug_str section is empty.\n"));
8196 return 0;
8197 }
8198
8199 printf (_("Contents of the .debug_str section:\n\n"));
8200
8201 while (bytes)
8202 {
8203 int j;
8204 int k;
8205 int lbytes;
8206
8207 lbytes = (bytes > 16 ? 16 : bytes);
8208
8209 printf (" 0x%8.8lx ", (unsigned long) addr);
8210
8211 for (j = 0; j < 16; j++)
8212 {
8213 if (j < lbytes)
b34976b6 8214 printf ("%2.2x", start[j]);
261a45ad
NC
8215 else
8216 printf (" ");
8217
8218 if ((j & 3) == 3)
8219 printf (" ");
8220 }
8221
8222 for (j = 0; j < lbytes; j++)
8223 {
b34976b6 8224 k = start[j];
261a45ad
NC
8225 if (k >= ' ' && k < 0x80)
8226 printf ("%c", k);
8227 else
8228 printf (".");
8229 }
8230
8231 putchar ('\n');
8232
8233 start += lbytes;
8234 addr += lbytes;
8235 bytes -= lbytes;
8236 }
8237
8238 return 1;
8239}
8240
252b5132 8241static unsigned char *
d3ba0551
AM
8242read_and_display_attr_value (unsigned long attribute,
8243 unsigned long form,
8244 unsigned char *data,
8245 unsigned long cu_offset,
8246 unsigned long pointer_size,
8247 unsigned long offset_size,
8248 int dwarf_version)
252b5132 8249{
b34976b6
AM
8250 unsigned long uvalue = 0;
8251 unsigned char *block_start = NULL;
8252 int bytes_read;
252b5132 8253
252b5132
RH
8254 switch (form)
8255 {
60bcf0fa
NC
8256 default:
8257 break;
76da6bbe 8258
252b5132 8259 case DW_FORM_ref_addr:
ee42cf8c
NC
8260 if (dwarf_version == 2)
8261 {
8262 uvalue = byte_get (data, pointer_size);
8263 data += pointer_size;
8264 }
8265 else if (dwarf_version == 3)
8266 {
8267 uvalue = byte_get (data, offset_size);
8268 data += offset_size;
8269 }
8270 else
ba2685cc 8271 {
ee42cf8c
NC
8272 error (_("Internal error: DWARF version is not 2 or 3.\n"));
8273 }
8274 break;
8275
252b5132
RH
8276 case DW_FORM_addr:
8277 uvalue = byte_get (data, pointer_size);
252b5132
RH
8278 data += pointer_size;
8279 break;
8280
ef5cdfc7 8281 case DW_FORM_strp:
ee42cf8c
NC
8282 uvalue = byte_get (data, offset_size);
8283 data += offset_size;
ef5cdfc7
JJ
8284 break;
8285
252b5132
RH
8286 case DW_FORM_ref1:
8287 case DW_FORM_flag:
8288 case DW_FORM_data1:
b34976b6 8289 uvalue = byte_get (data++, 1);
252b5132
RH
8290 break;
8291
8292 case DW_FORM_ref2:
8293 case DW_FORM_data2:
8294 uvalue = byte_get (data, 2);
8295 data += 2;
252b5132
RH
8296 break;
8297
8298 case DW_FORM_ref4:
8299 case DW_FORM_data4:
8300 uvalue = byte_get (data, 4);
8301 data += 4;
1fa37306
JM
8302 break;
8303
8304 case DW_FORM_sdata:
8305 uvalue = read_leb128 (data, & bytes_read, 1);
8306 data += bytes_read;
8307 break;
8308
8309 case DW_FORM_ref_udata:
8310 case DW_FORM_udata:
8311 uvalue = read_leb128 (data, & bytes_read, 0);
8312 data += bytes_read;
8313 break;
81766fca
RH
8314
8315 case DW_FORM_indirect:
8316 form = read_leb128 (data, & bytes_read, 0);
8317 data += bytes_read;
8318 printf (" %s", get_FORM_name (form));
8319 return read_and_display_attr_value (attribute, form, data, cu_offset,
ee42cf8c
NC
8320 pointer_size, offset_size,
8321 dwarf_version);
1fa37306
JM
8322 }
8323
8324 switch (form)
8325 {
8326 case DW_FORM_ref_addr:
8327 printf (" <#%lx>", uvalue);
8328 break;
76da6bbe 8329
1fa37306
JM
8330 case DW_FORM_ref1:
8331 case DW_FORM_ref2:
8332 case DW_FORM_ref4:
8333 case DW_FORM_ref_udata:
8334 printf (" <%lx>", uvalue + cu_offset);
8335 break;
8336
8337 case DW_FORM_addr:
8338 printf (" %#lx", uvalue);
935a41f5 8339 break;
1fa37306
JM
8340
8341 case DW_FORM_flag:
8342 case DW_FORM_data1:
8343 case DW_FORM_data2:
8344 case DW_FORM_data4:
8345 case DW_FORM_sdata:
8346 case DW_FORM_udata:
8347 printf (" %ld", uvalue);
252b5132
RH
8348 break;
8349
8350 case DW_FORM_ref8:
8351 case DW_FORM_data8:
8352 uvalue = byte_get (data, 4);
8353 printf (" %lx", uvalue);
148d3c43 8354 printf (" %lx", (unsigned long) byte_get (data + 4, 4));
252b5132
RH
8355 data += 8;
8356 break;
8357
8358 case DW_FORM_string:
8359 printf (" %s", data);
3c9f43b1 8360 data += strlen ((char *) data) + 1;
252b5132
RH
8361 break;
8362
252b5132
RH
8363 case DW_FORM_block:
8364 uvalue = read_leb128 (data, & bytes_read, 0);
8365 block_start = data + bytes_read;
8366 data = display_block (block_start, uvalue);
252b5132
RH
8367 break;
8368
8369 case DW_FORM_block1:
8370 uvalue = byte_get (data, 1);
8371 block_start = data + 1;
8372 data = display_block (block_start, uvalue);
252b5132
RH
8373 break;
8374
8375 case DW_FORM_block2:
8376 uvalue = byte_get (data, 2);
8377 block_start = data + 2;
8378 data = display_block (block_start, uvalue);
252b5132
RH
8379 break;
8380
8381 case DW_FORM_block4:
8382 uvalue = byte_get (data, 4);
8383 block_start = data + 4;
8384 data = display_block (block_start, uvalue);
252b5132
RH
8385 break;
8386
8387 case DW_FORM_strp:
f1ef08cb
AM
8388 printf (_(" (indirect string, offset: 0x%lx): %s"),
8389 uvalue, fetch_indirect_string (uvalue));
ef5cdfc7
JJ
8390 break;
8391
252b5132 8392 case DW_FORM_indirect:
e3c8793a 8393 /* Handled above. */
252b5132
RH
8394 break;
8395
8396 default:
2c71103e 8397 warn (_("Unrecognized form: %d\n"), form);
252b5132
RH
8398 break;
8399 }
8400
50c2245b 8401 /* For some attributes we can display further information. */
252b5132
RH
8402
8403 printf ("\t");
8404
8405 switch (attribute)
8406 {
8407 case DW_AT_inline:
8408 switch (uvalue)
8409 {
b34976b6
AM
8410 case DW_INL_not_inlined:
8411 printf (_("(not inlined)"));
8412 break;
8413 case DW_INL_inlined:
8414 printf (_("(inlined)"));
8415 break;
8416 case DW_INL_declared_not_inlined:
8417 printf (_("(declared as inline but ignored)"));
8418 break;
8419 case DW_INL_declared_inlined:
8420 printf (_("(declared as inline and inlined)"));
8421 break;
8422 default:
8423 printf (_(" (Unknown inline attribute value: %lx)"), uvalue);
8424 break;
252b5132
RH
8425 }
8426 break;
8427
252b5132
RH
8428 case DW_AT_language:
8429 switch (uvalue)
8430 {
b34976b6
AM
8431 case DW_LANG_C: printf ("(non-ANSI C)"); break;
8432 case DW_LANG_C89: printf ("(ANSI C)"); break;
8433 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
8434 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
8435 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
8436 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
8437 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
8438 case DW_LANG_Ada83: printf ("(Ada)"); break;
8439 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
8440 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
8441 /* DWARF 2.1 values. */
8442 case DW_LANG_C99: printf ("(ANSI C99)"); break;
8443 case DW_LANG_Ada95: printf ("(ADA 95)"); break;
8444 case DW_LANG_Fortran95: printf ("(Fortran 95)"); break;
b811889f 8445 /* MIPS extension. */
b34976b6 8446 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
84ad6ede
NC
8447 /* UPC extension. */
8448 case DW_LANG_Upc: printf ("(Unified Parallel C)"); break;
b34976b6
AM
8449 default:
8450 printf ("(Unknown: %lx)", uvalue);
8451 break;
252b5132
RH
8452 }
8453 break;
8454
8455 case DW_AT_encoding:
8456 switch (uvalue)
8457 {
b34976b6
AM
8458 case DW_ATE_void: printf ("(void)"); break;
8459 case DW_ATE_address: printf ("(machine address)"); break;
8460 case DW_ATE_boolean: printf ("(boolean)"); break;
8461 case DW_ATE_complex_float: printf ("(complex float)"); break;
8462 case DW_ATE_float: printf ("(float)"); break;
8463 case DW_ATE_signed: printf ("(signed)"); break;
8464 case DW_ATE_signed_char: printf ("(signed char)"); break;
8465 case DW_ATE_unsigned: printf ("(unsigned)"); break;
8466 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
b811889f 8467 /* DWARF 2.1 value. */
b34976b6 8468 case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
252b5132
RH
8469 default:
8470 if (uvalue >= DW_ATE_lo_user
8471 && uvalue <= DW_ATE_hi_user)
8472 printf ("(user defined type)");
8473 else
8474 printf ("(unknown type)");
8475 break;
8476 }
8477 break;
8478
8479 case DW_AT_accessibility:
8480 switch (uvalue)
8481 {
8482 case DW_ACCESS_public: printf ("(public)"); break;
8483 case DW_ACCESS_protected: printf ("(protected)"); break;
8484 case DW_ACCESS_private: printf ("(private)"); break;
b34976b6
AM
8485 default:
8486 printf ("(unknown accessibility)");
8487 break;
252b5132
RH
8488 }
8489 break;
8490
8491 case DW_AT_visibility:
8492 switch (uvalue)
8493 {
b34976b6
AM
8494 case DW_VIS_local: printf ("(local)"); break;
8495 case DW_VIS_exported: printf ("(exported)"); break;
8496 case DW_VIS_qualified: printf ("(qualified)"); break;
8497 default: printf ("(unknown visibility)"); break;
252b5132
RH
8498 }
8499 break;
8500
8501 case DW_AT_virtuality:
8502 switch (uvalue)
8503 {
8504 case DW_VIRTUALITY_none: printf ("(none)"); break;
8505 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
8506 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
b34976b6 8507 default: printf ("(unknown virtuality)"); break;
252b5132
RH
8508 }
8509 break;
8510
8511 case DW_AT_identifier_case:
8512 switch (uvalue)
8513 {
8514 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
8515 case DW_ID_up_case: printf ("(up_case)"); break;
8516 case DW_ID_down_case: printf ("(down_case)"); break;
8517 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
b34976b6 8518 default: printf ("(unknown case)"); break;
252b5132
RH
8519 }
8520 break;
8521
8522 case DW_AT_calling_convention:
8523 switch (uvalue)
8524 {
8525 case DW_CC_normal: printf ("(normal)"); break;
8526 case DW_CC_program: printf ("(program)"); break;
8527 case DW_CC_nocall: printf ("(nocall)"); break;
8528 default:
8529 if (uvalue >= DW_CC_lo_user
8530 && uvalue <= DW_CC_hi_user)
8531 printf ("(user defined)");
8532 else
8533 printf ("(unknown convention)");
8534 }
8535 break;
8536
12ab83a9
NC
8537 case DW_AT_ordering:
8538 switch (uvalue)
8539 {
8540 case -1: printf ("(undefined)"); break;
8541 case 0: printf ("(row major)"); break;
8542 case 1: printf ("(column major)"); break;
8543 }
8544 break;
8545
eb6bd4d3 8546 case DW_AT_frame_base:
252b5132
RH
8547 case DW_AT_location:
8548 case DW_AT_data_member_location:
8549 case DW_AT_vtable_elem_location:
12ab83a9
NC
8550 case DW_AT_allocated:
8551 case DW_AT_associated:
8552 case DW_AT_data_location:
8553 case DW_AT_stride:
8554 case DW_AT_upper_bound:
8555 case DW_AT_lower_bound:
eb6bd4d3
JM
8556 if (block_start)
8557 {
8558 printf ("(");
8559 decode_location_expression (block_start, pointer_size, uvalue);
8560 printf (")");
8561 }
ee42cf8c 8562 else if (form == DW_FORM_data4 || form == DW_FORM_data8)
a2f14207
DB
8563 {
8564 printf ("(");
8565 printf ("location list");
8566 printf (")");
8567 }
252b5132
RH
8568 break;
8569
8570 default:
8571 break;
8572 }
8573
81766fca
RH
8574 return data;
8575}
8576
8577static unsigned char *
d3ba0551
AM
8578read_and_display_attr (unsigned long attribute,
8579 unsigned long form,
8580 unsigned char *data,
8581 unsigned long cu_offset,
8582 unsigned long pointer_size,
8583 unsigned long offset_size,
8584 int dwarf_version)
81766fca
RH
8585{
8586 printf (" %-18s:", get_AT_name (attribute));
8587 data = read_and_display_attr_value (attribute, form, data, cu_offset,
ee42cf8c 8588 pointer_size, offset_size, dwarf_version);
252b5132
RH
8589 printf ("\n");
8590 return data;
8591}
8592
d84de024
AM
8593/* Apply addends of RELA relocations. */
8594
8595static int
8596debug_apply_rela_addends (FILE *file,
8597 Elf_Internal_Shdr *section,
8598 int reloc_size,
8599 unsigned char *sec_data,
8600 unsigned char *start,
8601 unsigned char *end)
8602{
8603 Elf_Internal_Shdr *relsec;
8604
8605 if (end - start < reloc_size)
8606 return 1;
8607
8608 for (relsec = section_headers;
8609 relsec < section_headers + elf_header.e_shnum;
8610 ++relsec)
8611 {
8612 unsigned long nrelas;
8613 Elf_Internal_Rela *rela, *rp;
8614 Elf_Internal_Shdr *symsec;
8615 Elf_Internal_Sym *symtab;
8616 Elf_Internal_Sym *sym;
8617
8618 if (relsec->sh_type != SHT_RELA
8619 || SECTION_HEADER (relsec->sh_info) != section
8620 || relsec->sh_size == 0)
8621 continue;
8622
8623 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
8624 &rela, &nrelas))
8625 return 0;
8626
8627 symsec = SECTION_HEADER (relsec->sh_link);
8628 symtab = GET_ELF_SYMBOLS (file, symsec);
8629
8630 for (rp = rela; rp < rela + nrelas; ++rp)
8631 {
8632 unsigned char *loc;
8633
8634 if (rp->r_offset >= (bfd_vma) (start - sec_data)
8635 && rp->r_offset < (bfd_vma) (end - sec_data) - reloc_size)
8636 loc = sec_data + rp->r_offset;
8637 else
8638 continue;
8639
8640 if (is_32bit_elf)
8641 {
8642 sym = symtab + ELF32_R_SYM (rp->r_info);
8643
8644 if (ELF32_R_SYM (rp->r_info) != 0
8645 && ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
8646 {
8647 warn (_("Skipping unexpected symbol type %u\n"),
8648 ELF32_ST_TYPE (sym->st_info));
8649 continue;
8650 }
8651 }
8652 else
8653 {
8654 sym = symtab + ELF64_R_SYM (rp->r_info);
8655
8656 if (ELF64_R_SYM (rp->r_info) != 0
8657 && ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
8658 {
8659 warn (_("Skipping unexpected symbol type %u\n"),
8660 ELF64_ST_TYPE (sym->st_info));
8661 continue;
8662 }
8663 }
8664
8665 byte_put (loc, rp->r_addend, reloc_size);
8666 }
8667
8668 free (symtab);
8669 free (rela);
8670 break;
8671 }
8672 return 1;
8673}
8674
252b5132 8675static int
d3ba0551
AM
8676display_debug_info (Elf_Internal_Shdr *section,
8677 unsigned char *start,
8678 FILE *file)
252b5132 8679{
b34976b6
AM
8680 unsigned char *end = start + section->sh_size;
8681 unsigned char *section_begin = start;
252b5132
RH
8682
8683 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
8684
261a45ad 8685 load_debug_str (file);
a2f14207 8686 load_debug_loc (file);
ef5cdfc7 8687
252b5132
RH
8688 while (start < end)
8689 {
b34976b6 8690 DWARF2_Internal_CompUnit compunit;
ee42cf8c
NC
8691 unsigned char *hdrptr;
8692 unsigned char *cu_abbrev_offset_ptr;
b34976b6 8693 unsigned char *tags;
b34976b6
AM
8694 int level;
8695 unsigned long cu_offset;
ee42cf8c
NC
8696 int offset_size;
8697 int initial_length_size;
252b5132 8698
ee42cf8c 8699 hdrptr = start;
252b5132 8700
ee42cf8c
NC
8701 compunit.cu_length = byte_get (hdrptr, 4);
8702 hdrptr += 4;
252b5132 8703
428409d5
NC
8704 if (compunit.cu_length == 0xffffffff)
8705 {
ee42cf8c
NC
8706 compunit.cu_length = byte_get (hdrptr, 8);
8707 hdrptr += 8;
8708 offset_size = 8;
8709 initial_length_size = 12;
8710 }
8711 else
8712 {
8713 offset_size = 4;
8714 initial_length_size = 4;
428409d5
NC
8715 }
8716
ee42cf8c
NC
8717 compunit.cu_version = byte_get (hdrptr, 2);
8718 hdrptr += 2;
8719
d84de024
AM
8720 cu_offset = start - section_begin;
8721 start += compunit.cu_length + initial_length_size;
c0e047e0 8722
d84de024
AM
8723 if (elf_header.e_type == ET_REL
8724 && !debug_apply_rela_addends (file, section, offset_size,
8725 section_begin, hdrptr, start))
8726 return 0;
c0e047e0 8727
adab8cdc
AO
8728 cu_abbrev_offset_ptr = hdrptr;
8729 compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size);
8730 hdrptr += offset_size;
8731
8732 compunit.cu_pointer_size = byte_get (hdrptr, 1);
8733 hdrptr += 1;
8734
ee42cf8c 8735 tags = hdrptr;
252b5132 8736
09fd7e38
JM
8737 printf (_(" Compilation Unit @ %lx:\n"), cu_offset);
8738 printf (_(" Length: %ld\n"), compunit.cu_length);
8739 printf (_(" Version: %d\n"), compunit.cu_version);
8740 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
8741 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
8742
ee42cf8c 8743 if (compunit.cu_version != 2 && compunit.cu_version != 3)
252b5132 8744 {
ee42cf8c 8745 warn (_("Only version 2 and 3 DWARF debug information is currently supported.\n"));
252b5132
RH
8746 continue;
8747 }
8748
261a45ad 8749 free_abbrevs ();
252b5132
RH
8750
8751 /* Read in the abbrevs used by this compilation unit. */
252b5132 8752 {
b34976b6
AM
8753 Elf_Internal_Shdr *sec;
8754 unsigned char *begin;
252b5132
RH
8755
8756 /* Locate the .debug_abbrev section and process it. */
d9296b18
NC
8757 sec = find_section (".debug_abbrev");
8758 if (sec == NULL)
252b5132
RH
8759 {
8760 warn (_("Unable to locate .debug_abbrev section!\n"));
8761 return 0;
8762 }
8763
d3ba0551
AM
8764 begin = get_data (NULL, file, sec->sh_offset, sec->sh_size,
8765 _("debug_abbrev section data"));
a6e9f9df
AM
8766 if (!begin)
8767 return 0;
252b5132
RH
8768
8769 process_abbrev_section (begin + compunit.cu_abbrev_offset,
8770 begin + sec->sh_size);
8771
8772 free (begin);
8773 }
8774
8775 level = 0;
8776 while (tags < start)
8777 {
b34976b6
AM
8778 int bytes_read;
8779 unsigned long abbrev_number;
8780 abbrev_entry *entry;
8781 abbrev_attr *attr;
252b5132
RH
8782
8783 abbrev_number = read_leb128 (tags, & bytes_read, 0);
8784 tags += bytes_read;
8785
8786 /* A null DIE marks the end of a list of children. */
8787 if (abbrev_number == 0)
8788 {
8789 --level;
8790 continue;
8791 }
8792
8793 /* Scan through the abbreviation list until we reach the
8794 correct entry. */
8795 for (entry = first_abbrev;
8796 entry && entry->entry != abbrev_number;
8797 entry = entry->next)
8798 continue;
8799
8800 if (entry == NULL)
8801 {
b4c96d0d 8802 warn (_("Unable to locate entry %lu in the abbreviation table\n"),
252b5132
RH
8803 abbrev_number);
8804 return 0;
8805 }
8806
410f7a12
L
8807 printf (_(" <%d><%lx>: Abbrev Number: %lu (%s)\n"),
8808 level,
8809 (unsigned long) (tags - section_begin - bytes_read),
252b5132
RH
8810 abbrev_number,
8811 get_TAG_name (entry->tag));
8812
8813 for (attr = entry->first_attr; attr; attr = attr->next)
8814 tags = read_and_display_attr (attr->attribute,
8815 attr->form,
1fa37306 8816 tags, cu_offset,
ee42cf8c
NC
8817 compunit.cu_pointer_size,
8818 offset_size,
8819 compunit.cu_version);
252b5132
RH
8820
8821 if (entry->children)
8822 ++level;
8823 }
8824 }
8825
261a45ad 8826 free_debug_str ();
a2f14207 8827 free_debug_loc ();
ef5cdfc7 8828
252b5132
RH
8829 printf ("\n");
8830
8831 return 1;
8832}
8833
8834static int
d3ba0551
AM
8835display_debug_aranges (Elf_Internal_Shdr *section,
8836 unsigned char *start,
8837 FILE *file ATTRIBUTE_UNUSED)
252b5132 8838{
b34976b6 8839 unsigned char *end = start + section->sh_size;
252b5132
RH
8840
8841 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
8842
8843 while (start < end)
8844 {
ee42cf8c 8845 unsigned char *hdrptr;
b34976b6
AM
8846 DWARF2_Internal_ARange arange;
8847 unsigned char *ranges;
8848 unsigned long length;
8849 unsigned long address;
8850 int excess;
ee42cf8c
NC
8851 int offset_size;
8852 int initial_length_size;
252b5132 8853
ee42cf8c 8854 hdrptr = start;
252b5132 8855
ee42cf8c
NC
8856 arange.ar_length = byte_get (hdrptr, 4);
8857 hdrptr += 4;
252b5132 8858
e414a165
NC
8859 if (arange.ar_length == 0xffffffff)
8860 {
ee42cf8c
NC
8861 arange.ar_length = byte_get (hdrptr, 8);
8862 hdrptr += 8;
8863 offset_size = 8;
8864 initial_length_size = 12;
8865 }
8866 else
ba2685cc 8867 {
ee42cf8c
NC
8868 offset_size = 4;
8869 initial_length_size = 4;
e414a165
NC
8870 }
8871
ee42cf8c
NC
8872 arange.ar_version = byte_get (hdrptr, 2);
8873 hdrptr += 2;
8874
8875 arange.ar_info_offset = byte_get (hdrptr, offset_size);
8876 hdrptr += offset_size;
8877
8878 arange.ar_pointer_size = byte_get (hdrptr, 1);
8879 hdrptr += 1;
8880
8881 arange.ar_segment_size = byte_get (hdrptr, 1);
8882 hdrptr += 1;
8883
8884 if (arange.ar_version != 2 && arange.ar_version != 3)
3f215a10 8885 {
ee42cf8c 8886 warn (_("Only DWARF 2 and 3 aranges are currently supported.\n"));
3f215a10
NC
8887 break;
8888 }
8889
252b5132
RH
8890 printf (_(" Length: %ld\n"), arange.ar_length);
8891 printf (_(" Version: %d\n"), arange.ar_version);
8892 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
8893 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
8894 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
8895
8896 printf (_("\n Address Length\n"));
8897
ee42cf8c 8898 ranges = hdrptr;
252b5132 8899
7a4b7442 8900 /* Must pad to an alignment boundary that is twice the pointer size. */
ee42cf8c 8901 excess = (hdrptr - start) % (2 * arange.ar_pointer_size);
7a4b7442
NC
8902 if (excess)
8903 ranges += (2 * arange.ar_pointer_size) - excess;
8904
252b5132
RH
8905 for (;;)
8906 {
8907 address = byte_get (ranges, arange.ar_pointer_size);
8908
252b5132
RH
8909 ranges += arange.ar_pointer_size;
8910
8911 length = byte_get (ranges, arange.ar_pointer_size);
8912
8913 ranges += arange.ar_pointer_size;
8914
7a4b7442
NC
8915 /* A pair of zeros marks the end of the list. */
8916 if (address == 0 && length == 0)
8917 break;
103f02d3 8918
252b5132
RH
8919 printf (" %8.8lx %lu\n", address, length);
8920 }
8921
ee42cf8c 8922 start += arange.ar_length + initial_length_size;
252b5132
RH
8923 }
8924
8925 printf ("\n");
8926
8927 return 1;
8928}
8929
c47d488e
DD
8930typedef struct Frame_Chunk
8931{
b34976b6
AM
8932 struct Frame_Chunk *next;
8933 unsigned char *chunk_start;
8934 int ncols;
a98cc2b2 8935 /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */
b34976b6
AM
8936 short int *col_type;
8937 int *col_offset;
8938 char *augmentation;
8939 unsigned int code_factor;
8940 int data_factor;
8941 unsigned long pc_begin;
8942 unsigned long pc_range;
8943 int cfa_reg;
8944 int cfa_offset;
8945 int ra;
8946 unsigned char fde_encoding;
63044634 8947 unsigned char cfa_exp;
c47d488e
DD
8948}
8949Frame_Chunk;
8950
a98cc2b2
AH
8951/* A marker for a col_type that means this column was never referenced
8952 in the frame info. */
8953#define DW_CFA_unreferenced (-1)
8954
c47d488e 8955static void
d3ba0551 8956frame_need_space (Frame_Chunk *fc, int reg)
c47d488e
DD
8957{
8958 int prev = fc->ncols;
8959
8960 if (reg < fc->ncols)
8961 return;
584da044 8962
c47d488e 8963 fc->ncols = reg + 1;
d3ba0551
AM
8964 fc->col_type = xrealloc (fc->col_type, fc->ncols * sizeof (short int));
8965 fc->col_offset = xrealloc (fc->col_offset, fc->ncols * sizeof (int));
c47d488e
DD
8966
8967 while (prev < fc->ncols)
8968 {
a98cc2b2 8969 fc->col_type[prev] = DW_CFA_unreferenced;
c47d488e
DD
8970 fc->col_offset[prev] = 0;
8971 prev++;
8972 }
8973}
8974
8975static void
d3ba0551 8976frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
c47d488e
DD
8977{
8978 int r;
8979 char tmp[100];
8980
b34976b6
AM
8981 if (*max_regs < fc->ncols)
8982 *max_regs = fc->ncols;
584da044 8983
b34976b6 8984 if (*need_col_headers)
c47d488e 8985 {
b34976b6 8986 *need_col_headers = 0;
584da044 8987
c47d488e 8988 printf (" LOC CFA ");
584da044 8989
b34976b6 8990 for (r = 0; r < *max_regs; r++)
a98cc2b2
AH
8991 if (fc->col_type[r] != DW_CFA_unreferenced)
8992 {
8993 if (r == fc->ra)
8994 printf ("ra ");
8995 else
8996 printf ("r%-4d", r);
8997 }
584da044 8998
c47d488e
DD
8999 printf ("\n");
9000 }
584da044 9001
31b6fca6 9002 printf ("%08lx ", fc->pc_begin);
63044634
RH
9003 if (fc->cfa_exp)
9004 strcpy (tmp, "exp");
9005 else
9006 sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
c47d488e 9007 printf ("%-8s ", tmp);
584da044
NC
9008
9009 for (r = 0; r < fc->ncols; r++)
c47d488e 9010 {
a98cc2b2 9011 if (fc->col_type[r] != DW_CFA_unreferenced)
c47d488e 9012 {
a98cc2b2
AH
9013 switch (fc->col_type[r])
9014 {
9015 case DW_CFA_undefined:
9016 strcpy (tmp, "u");
9017 break;
9018 case DW_CFA_same_value:
9019 strcpy (tmp, "s");
9020 break;
9021 case DW_CFA_offset:
9022 sprintf (tmp, "c%+d", fc->col_offset[r]);
9023 break;
9024 case DW_CFA_register:
9025 sprintf (tmp, "r%d", fc->col_offset[r]);
9026 break;
63044634
RH
9027 case DW_CFA_expression:
9028 strcpy (tmp, "exp");
9029 break;
a98cc2b2
AH
9030 default:
9031 strcpy (tmp, "n/a");
9032 break;
9033 }
9034 printf ("%-5s", tmp);
c47d488e 9035 }
c47d488e
DD
9036 }
9037 printf ("\n");
9038}
9039
31b6fca6 9040static int
d3ba0551 9041size_of_encoded_value (int encoding)
31b6fca6
RH
9042{
9043 switch (encoding & 0x7)
9044 {
9045 default: /* ??? */
9046 case 0: return is_32bit_elf ? 4 : 8;
9047 case 2: return 2;
9048 case 3: return 4;
9049 case 4: return 8;
9050 }
9051}
9052
38fafa6d 9053static bfd_vma
d3ba0551 9054get_encoded_value (unsigned char *data, int encoding)
38fafa6d
RH
9055{
9056 int size = size_of_encoded_value (encoding);
9057 if (encoding & DW_EH_PE_signed)
9058 return byte_get_signed (data, size);
9059 else
9060 return byte_get (data, size);
9061}
9062
c47d488e 9063#define GET(N) byte_get (start, N); start += N
584da044
NC
9064#define LEB() read_leb128 (start, & length_return, 0); start += length_return
9065#define SLEB() read_leb128 (start, & length_return, 1); start += length_return
c47d488e
DD
9066
9067static int
d3ba0551
AM
9068display_debug_frames (Elf_Internal_Shdr *section,
9069 unsigned char *start,
9070 FILE *file ATTRIBUTE_UNUSED)
c47d488e 9071{
b34976b6
AM
9072 unsigned char *end = start + section->sh_size;
9073 unsigned char *section_start = start;
9074 Frame_Chunk *chunks = 0;
9075 Frame_Chunk *remembered_state = 0;
9076 Frame_Chunk *rs;
9077 int is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
9078 int length_return;
9079 int max_regs = 0;
9080 int addr_size = is_32bit_elf ? 4 : 8;
c47d488e
DD
9081
9082 printf (_("The section %s contains:\n"), SECTION_NAME (section));
9083
9084 while (start < end)
9085 {
b34976b6
AM
9086 unsigned char *saved_start;
9087 unsigned char *block_end;
9088 unsigned long length;
9089 unsigned long cie_id;
9090 Frame_Chunk *fc;
9091 Frame_Chunk *cie;
9092 int need_col_headers = 1;
9093 unsigned char *augmentation_data = NULL;
9094 unsigned long augmentation_data_len = 0;
9095 int encoded_ptr_size = addr_size;
ee42cf8c
NC
9096 int offset_size;
9097 int initial_length_size;
c47d488e
DD
9098
9099 saved_start = start;
9100 length = byte_get (start, 4); start += 4;
9101
9102 if (length == 0)
f1ef08cb
AM
9103 {
9104 printf ("\n%08lx ZERO terminator\n\n",
9105 (unsigned long)(saved_start - section_start));
9106 return 1;
9107 }
c47d488e 9108
428409d5
NC
9109 if (length == 0xffffffff)
9110 {
ee42cf8c
NC
9111 length = byte_get (start, 8);
9112 start += 8;
9113 offset_size = 8;
9114 initial_length_size = 12;
9115 }
9116 else
9117 {
9118 offset_size = 4;
9119 initial_length_size = 4;
428409d5
NC
9120 }
9121
ee42cf8c
NC
9122 block_end = saved_start + length + initial_length_size;
9123 cie_id = byte_get (start, offset_size); start += offset_size;
c47d488e 9124
d84de024
AM
9125 if (elf_header.e_type == ET_REL
9126 && !debug_apply_rela_addends (file, section, offset_size,
9127 section_start, start, block_end))
9128 return 0;
9129
c47d488e
DD
9130 if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
9131 {
31b6fca6
RH
9132 int version;
9133
d3ba0551 9134 fc = xmalloc (sizeof (Frame_Chunk));
c47d488e
DD
9135 memset (fc, 0, sizeof (Frame_Chunk));
9136
9137 fc->next = chunks;
9138 chunks = fc;
9139 fc->chunk_start = saved_start;
9140 fc->ncols = 0;
d3ba0551
AM
9141 fc->col_type = xmalloc (sizeof (short int));
9142 fc->col_offset = xmalloc (sizeof (int));
c47d488e
DD
9143 frame_need_space (fc, max_regs-1);
9144
31b6fca6 9145 version = *start++;
584da044 9146
31b6fca6
RH
9147 fc->augmentation = start;
9148 start = strchr (start, '\0') + 1;
584da044 9149
c47d488e
DD
9150 if (fc->augmentation[0] == 'z')
9151 {
c47d488e
DD
9152 fc->code_factor = LEB ();
9153 fc->data_factor = SLEB ();
0da76f83
NC
9154 if (version == 1)
9155 {
9156 fc->ra = GET (1);
9157 }
9158 else
9159 {
9160 fc->ra = LEB ();
9161 }
31b6fca6
RH
9162 augmentation_data_len = LEB ();
9163 augmentation_data = start;
9164 start += augmentation_data_len;
c47d488e
DD
9165 }
9166 else if (strcmp (fc->augmentation, "eh") == 0)
9167 {
31b6fca6 9168 start += addr_size;
c47d488e
DD
9169 fc->code_factor = LEB ();
9170 fc->data_factor = SLEB ();
0da76f83
NC
9171 if (version == 1)
9172 {
9173 fc->ra = GET (1);
9174 }
9175 else
9176 {
9177 fc->ra = LEB ();
9178 }
c47d488e
DD
9179 }
9180 else
9181 {
9182 fc->code_factor = LEB ();
9183 fc->data_factor = SLEB ();
0da76f83
NC
9184 if (version == 1)
9185 {
9186 fc->ra = GET (1);
9187 }
9188 else
9189 {
9190 fc->ra = LEB ();
9191 }
c47d488e
DD
9192 }
9193 cie = fc;
31b6fca6
RH
9194
9195 if (do_debug_frames_interp)
9196 printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
7036c0e1 9197 (unsigned long)(saved_start - section_start), length, cie_id,
31b6fca6
RH
9198 fc->augmentation, fc->code_factor, fc->data_factor,
9199 fc->ra);
9200 else
9201 {
9202 printf ("\n%08lx %08lx %08lx CIE\n",
7036c0e1 9203 (unsigned long)(saved_start - section_start), length, cie_id);
31b6fca6
RH
9204 printf (" Version: %d\n", version);
9205 printf (" Augmentation: \"%s\"\n", fc->augmentation);
9206 printf (" Code alignment factor: %u\n", fc->code_factor);
9207 printf (" Data alignment factor: %d\n", fc->data_factor);
9208 printf (" Return address column: %d\n", fc->ra);
9209
9210 if (augmentation_data_len)
9211 {
9212 unsigned long i;
9213 printf (" Augmentation data: ");
9214 for (i = 0; i < augmentation_data_len; ++i)
9215 printf (" %02x", augmentation_data[i]);
9216 putchar ('\n');
9217 }
9218 putchar ('\n');
9219 }
9220
9221 if (augmentation_data_len)
9222 {
9223 unsigned char *p, *q;
9224 p = fc->augmentation + 1;
9225 q = augmentation_data;
9226
9227 while (1)
9228 {
9229 if (*p == 'L')
7036c0e1 9230 q++;
31b6fca6
RH
9231 else if (*p == 'P')
9232 q += 1 + size_of_encoded_value (*q);
9233 else if (*p == 'R')
9234 fc->fde_encoding = *q++;
9235 else
9236 break;
9237 p++;
9238 }
9239
9240 if (fc->fde_encoding)
9241 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
9242 }
c47d488e
DD
9243
9244 frame_need_space (fc, fc->ra);
9245 }
9246 else
9247 {
b34976b6 9248 unsigned char *look_for;
c47d488e 9249 static Frame_Chunk fde_fc;
584da044
NC
9250
9251 fc = & fde_fc;
c47d488e
DD
9252 memset (fc, 0, sizeof (Frame_Chunk));
9253
31b6fca6 9254 look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
c47d488e 9255
428409d5 9256 for (cie = chunks; cie ; cie = cie->next)
31b6fca6
RH
9257 if (cie->chunk_start == look_for)
9258 break;
c47d488e 9259
c47d488e
DD
9260 if (!cie)
9261 {
31b6fca6
RH
9262 warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
9263 cie_id, saved_start);
c47d488e
DD
9264 start = block_end;
9265 fc->ncols = 0;
d3ba0551
AM
9266 fc->col_type = xmalloc (sizeof (short int));
9267 fc->col_offset = xmalloc (sizeof (int));
584da044 9268 frame_need_space (fc, max_regs - 1);
c47d488e
DD
9269 cie = fc;
9270 fc->augmentation = "";
31b6fca6 9271 fc->fde_encoding = 0;
c47d488e
DD
9272 }
9273 else
9274 {
9275 fc->ncols = cie->ncols;
d3ba0551
AM
9276 fc->col_type = xmalloc (fc->ncols * sizeof (short int));
9277 fc->col_offset = xmalloc (fc->ncols * sizeof (int));
a98cc2b2 9278 memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
c47d488e
DD
9279 memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
9280 fc->augmentation = cie->augmentation;
9281 fc->code_factor = cie->code_factor;
9282 fc->data_factor = cie->data_factor;
9283 fc->cfa_reg = cie->cfa_reg;
9284 fc->cfa_offset = cie->cfa_offset;
9285 fc->ra = cie->ra;
9286 frame_need_space (fc, max_regs-1);
31b6fca6 9287 fc->fde_encoding = cie->fde_encoding;
c47d488e
DD
9288 }
9289
31b6fca6
RH
9290 if (fc->fde_encoding)
9291 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
9292
38fafa6d 9293 fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
d84de024
AM
9294 if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
9295 /* Don't adjust for ET_REL since there's invariably a pcrel
9296 reloc here, which we haven't applied. */
9297 && elf_header.e_type != ET_REL)
f1ef08cb 9298 fc->pc_begin += section->sh_addr + (start - section_start);
31b6fca6
RH
9299 start += encoded_ptr_size;
9300 fc->pc_range = byte_get (start, encoded_ptr_size);
9301 start += encoded_ptr_size;
9302
c47d488e
DD
9303 if (cie->augmentation[0] == 'z')
9304 {
31b6fca6
RH
9305 augmentation_data_len = LEB ();
9306 augmentation_data = start;
9307 start += augmentation_data_len;
c47d488e
DD
9308 }
9309
410f7a12 9310 printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
7036c0e1 9311 (unsigned long)(saved_start - section_start), length, cie_id,
410f7a12
L
9312 (unsigned long)(cie->chunk_start - section_start),
9313 fc->pc_begin, fc->pc_begin + fc->pc_range);
31b6fca6
RH
9314 if (! do_debug_frames_interp && augmentation_data_len)
9315 {
9316 unsigned long i;
9317 printf (" Augmentation data: ");
9318 for (i = 0; i < augmentation_data_len; ++i)
ba2685cc 9319 printf (" %02x", augmentation_data[i]);
31b6fca6
RH
9320 putchar ('\n');
9321 putchar ('\n');
9322 }
c47d488e
DD
9323 }
9324
9325 /* At this point, fc is the current chunk, cie (if any) is set, and we're
9326 about to interpret instructions for the chunk. */
38fafa6d
RH
9327 /* ??? At present we need to do this always, since this sizes the
9328 fc->col_type and fc->col_offset arrays, which we write into always.
9329 We should probably split the interpreted and non-interpreted bits
9330 into two different routines, since there's so much that doesn't
9331 really overlap between them. */
9332 if (1 || do_debug_frames_interp)
53c7db4b
KH
9333 {
9334 /* Start by making a pass over the chunk, allocating storage
9335 and taking note of what registers are used. */
b34976b6 9336 unsigned char *tmp = start;
a98cc2b2 9337
53c7db4b
KH
9338 while (start < block_end)
9339 {
9340 unsigned op, opa;
63044634 9341 unsigned long reg, tmp;
7036c0e1 9342
b34976b6 9343 op = *start++;
53c7db4b
KH
9344 opa = op & 0x3f;
9345 if (op & 0xc0)
9346 op &= 0xc0;
7036c0e1 9347
53c7db4b 9348 /* Warning: if you add any more cases to this switch, be
ba2685cc 9349 sure to add them to the corresponding switch below. */
53c7db4b
KH
9350 switch (op)
9351 {
9352 case DW_CFA_advance_loc:
9353 break;
9354 case DW_CFA_offset:
9355 LEB ();
9356 frame_need_space (fc, opa);
9357 fc->col_type[opa] = DW_CFA_undefined;
9358 break;
9359 case DW_CFA_restore:
9360 frame_need_space (fc, opa);
9361 fc->col_type[opa] = DW_CFA_undefined;
9362 break;
9363 case DW_CFA_set_loc:
9364 start += encoded_ptr_size;
9365 break;
9366 case DW_CFA_advance_loc1:
9367 start += 1;
9368 break;
9369 case DW_CFA_advance_loc2:
9370 start += 2;
9371 break;
9372 case DW_CFA_advance_loc4:
9373 start += 4;
9374 break;
9375 case DW_CFA_offset_extended:
9376 reg = LEB (); LEB ();
9377 frame_need_space (fc, reg);
9378 fc->col_type[reg] = DW_CFA_undefined;
9379 break;
9380 case DW_CFA_restore_extended:
9381 reg = LEB ();
9382 frame_need_space (fc, reg);
9383 fc->col_type[reg] = DW_CFA_undefined;
9384 break;
9385 case DW_CFA_undefined:
9386 reg = LEB ();
9387 frame_need_space (fc, reg);
9388 fc->col_type[reg] = DW_CFA_undefined;
9389 break;
9390 case DW_CFA_same_value:
9391 reg = LEB ();
9392 frame_need_space (fc, reg);
9393 fc->col_type[reg] = DW_CFA_undefined;
9394 break;
9395 case DW_CFA_register:
9396 reg = LEB (); LEB ();
9397 frame_need_space (fc, reg);
9398 fc->col_type[reg] = DW_CFA_undefined;
9399 break;
9400 case DW_CFA_def_cfa:
9401 LEB (); LEB ();
9402 break;
9403 case DW_CFA_def_cfa_register:
9404 LEB ();
9405 break;
9406 case DW_CFA_def_cfa_offset:
9407 LEB ();
9408 break;
63044634
RH
9409 case DW_CFA_def_cfa_expression:
9410 tmp = LEB ();
9411 start += tmp;
9412 break;
9413 case DW_CFA_expression:
9414 reg = LEB ();
9415 tmp = LEB ();
9416 start += tmp;
9417 frame_need_space (fc, reg);
9418 fc->col_type[reg] = DW_CFA_undefined;
9419 break;
91a106e6
L
9420 case DW_CFA_offset_extended_sf:
9421 reg = LEB (); SLEB ();
9422 frame_need_space (fc, reg);
9423 fc->col_type[reg] = DW_CFA_undefined;
9424 break;
9425 case DW_CFA_def_cfa_sf:
9426 LEB (); SLEB ();
9427 break;
9428 case DW_CFA_def_cfa_offset_sf:
9429 SLEB ();
9430 break;
63044634
RH
9431 case DW_CFA_MIPS_advance_loc8:
9432 start += 8;
9433 break;
53c7db4b
KH
9434 case DW_CFA_GNU_args_size:
9435 LEB ();
9436 break;
53c7db4b
KH
9437 case DW_CFA_GNU_negative_offset_extended:
9438 reg = LEB (); LEB ();
9439 frame_need_space (fc, reg);
9440 fc->col_type[reg] = DW_CFA_undefined;
7036c0e1 9441
53c7db4b
KH
9442 default:
9443 break;
9444 }
9445 }
9446 start = tmp;
9447 }
a98cc2b2
AH
9448
9449 /* Now we know what registers are used, make a second pass over
ba2685cc 9450 the chunk, this time actually printing out the info. */
a98cc2b2 9451
c47d488e
DD
9452 while (start < block_end)
9453 {
9454 unsigned op, opa;
9455 unsigned long ul, reg, roffs;
9456 long l, ofs;
9457 bfd_vma vma;
9458
b34976b6 9459 op = *start++;
c47d488e
DD
9460 opa = op & 0x3f;
9461 if (op & 0xc0)
9462 op &= 0xc0;
9463
53c7db4b
KH
9464 /* Warning: if you add any more cases to this switch, be
9465 sure to add them to the corresponding switch above. */
c47d488e
DD
9466 switch (op)
9467 {
9468 case DW_CFA_advance_loc:
31b6fca6 9469 if (do_debug_frames_interp)
53c7db4b 9470 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9471 else
53c7db4b
KH
9472 printf (" DW_CFA_advance_loc: %d to %08lx\n",
9473 opa * fc->code_factor,
31b6fca6 9474 fc->pc_begin + opa * fc->code_factor);
c47d488e
DD
9475 fc->pc_begin += opa * fc->code_factor;
9476 break;
9477
9478 case DW_CFA_offset:
c47d488e 9479 roffs = LEB ();
31b6fca6 9480 if (! do_debug_frames_interp)
53c7db4b 9481 printf (" DW_CFA_offset: r%d at cfa%+ld\n",
31b6fca6 9482 opa, roffs * fc->data_factor);
c47d488e
DD
9483 fc->col_type[opa] = DW_CFA_offset;
9484 fc->col_offset[opa] = roffs * fc->data_factor;
9485 break;
9486
9487 case DW_CFA_restore:
31b6fca6 9488 if (! do_debug_frames_interp)
53c7db4b 9489 printf (" DW_CFA_restore: r%d\n", opa);
c47d488e
DD
9490 fc->col_type[opa] = cie->col_type[opa];
9491 fc->col_offset[opa] = cie->col_offset[opa];
9492 break;
9493
9494 case DW_CFA_set_loc:
38fafa6d 9495 vma = get_encoded_value (start, fc->fde_encoding);
d84de024
AM
9496 if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
9497 && elf_header.e_type != ET_REL)
f1ef08cb 9498 vma += section->sh_addr + (start - section_start);
31b6fca6
RH
9499 start += encoded_ptr_size;
9500 if (do_debug_frames_interp)
53c7db4b 9501 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9502 else
53c7db4b 9503 printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
c47d488e
DD
9504 fc->pc_begin = vma;
9505 break;
9506
9507 case DW_CFA_advance_loc1:
c47d488e 9508 ofs = byte_get (start, 1); start += 1;
31b6fca6 9509 if (do_debug_frames_interp)
53c7db4b 9510 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9511 else
53c7db4b
KH
9512 printf (" DW_CFA_advance_loc1: %ld to %08lx\n",
9513 ofs * fc->code_factor,
31b6fca6 9514 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
9515 fc->pc_begin += ofs * fc->code_factor;
9516 break;
9517
9518 case DW_CFA_advance_loc2:
c47d488e 9519 ofs = byte_get (start, 2); start += 2;
31b6fca6 9520 if (do_debug_frames_interp)
53c7db4b 9521 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9522 else
53c7db4b
KH
9523 printf (" DW_CFA_advance_loc2: %ld to %08lx\n",
9524 ofs * fc->code_factor,
31b6fca6 9525 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
9526 fc->pc_begin += ofs * fc->code_factor;
9527 break;
9528
9529 case DW_CFA_advance_loc4:
c47d488e 9530 ofs = byte_get (start, 4); start += 4;
31b6fca6 9531 if (do_debug_frames_interp)
53c7db4b 9532 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9533 else
53c7db4b
KH
9534 printf (" DW_CFA_advance_loc4: %ld to %08lx\n",
9535 ofs * fc->code_factor,
31b6fca6 9536 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
9537 fc->pc_begin += ofs * fc->code_factor;
9538 break;
9539
9540 case DW_CFA_offset_extended:
9541 reg = LEB ();
9542 roffs = LEB ();
31b6fca6 9543 if (! do_debug_frames_interp)
7036c0e1 9544 printf (" DW_CFA_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 9545 reg, roffs * fc->data_factor);
c47d488e
DD
9546 fc->col_type[reg] = DW_CFA_offset;
9547 fc->col_offset[reg] = roffs * fc->data_factor;
9548 break;
9549
9550 case DW_CFA_restore_extended:
9551 reg = LEB ();
31b6fca6 9552 if (! do_debug_frames_interp)
53c7db4b 9553 printf (" DW_CFA_restore_extended: r%ld\n", reg);
c47d488e
DD
9554 fc->col_type[reg] = cie->col_type[reg];
9555 fc->col_offset[reg] = cie->col_offset[reg];
9556 break;
9557
9558 case DW_CFA_undefined:
9559 reg = LEB ();
31b6fca6 9560 if (! do_debug_frames_interp)
53c7db4b 9561 printf (" DW_CFA_undefined: r%ld\n", reg);
c47d488e
DD
9562 fc->col_type[reg] = DW_CFA_undefined;
9563 fc->col_offset[reg] = 0;
9564 break;
9565
9566 case DW_CFA_same_value:
9567 reg = LEB ();
31b6fca6 9568 if (! do_debug_frames_interp)
53c7db4b 9569 printf (" DW_CFA_same_value: r%ld\n", reg);
c47d488e
DD
9570 fc->col_type[reg] = DW_CFA_same_value;
9571 fc->col_offset[reg] = 0;
9572 break;
9573
9574 case DW_CFA_register:
9575 reg = LEB ();
9576 roffs = LEB ();
31b6fca6 9577 if (! do_debug_frames_interp)
636fc387 9578 printf (" DW_CFA_register: r%ld in r%ld\n", reg, roffs);
c47d488e
DD
9579 fc->col_type[reg] = DW_CFA_register;
9580 fc->col_offset[reg] = roffs;
9581 break;
9582
9583 case DW_CFA_remember_state:
31b6fca6 9584 if (! do_debug_frames_interp)
53c7db4b 9585 printf (" DW_CFA_remember_state\n");
d3ba0551 9586 rs = xmalloc (sizeof (Frame_Chunk));
c47d488e 9587 rs->ncols = fc->ncols;
d3ba0551
AM
9588 rs->col_type = xmalloc (rs->ncols * sizeof (short int));
9589 rs->col_offset = xmalloc (rs->ncols * sizeof (int));
c47d488e
DD
9590 memcpy (rs->col_type, fc->col_type, rs->ncols);
9591 memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
9592 rs->next = remembered_state;
9593 remembered_state = rs;
9594 break;
9595
9596 case DW_CFA_restore_state:
31b6fca6 9597 if (! do_debug_frames_interp)
53c7db4b 9598 printf (" DW_CFA_restore_state\n");
c47d488e 9599 rs = remembered_state;
8c9a9879
RH
9600 if (rs)
9601 {
9602 remembered_state = rs->next;
9603 frame_need_space (fc, rs->ncols-1);
9604 memcpy (fc->col_type, rs->col_type, rs->ncols);
9605 memcpy (fc->col_offset, rs->col_offset,
9606 rs->ncols * sizeof (int));
9607 free (rs->col_type);
9608 free (rs->col_offset);
9609 free (rs);
9610 }
9611 else if (do_debug_frames_interp)
9612 printf ("Mismatched DW_CFA_restore_state\n");
c47d488e
DD
9613 break;
9614
9615 case DW_CFA_def_cfa:
9616 fc->cfa_reg = LEB ();
9617 fc->cfa_offset = LEB ();
63044634 9618 fc->cfa_exp = 0;
31b6fca6 9619 if (! do_debug_frames_interp)
53c7db4b 9620 printf (" DW_CFA_def_cfa: r%d ofs %d\n",
31b6fca6 9621 fc->cfa_reg, fc->cfa_offset);
c47d488e
DD
9622 break;
9623
9624 case DW_CFA_def_cfa_register:
9625 fc->cfa_reg = LEB ();
63044634 9626 fc->cfa_exp = 0;
31b6fca6 9627 if (! do_debug_frames_interp)
53c7db4b 9628 printf (" DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
c47d488e
DD
9629 break;
9630
9631 case DW_CFA_def_cfa_offset:
9632 fc->cfa_offset = LEB ();
31b6fca6 9633 if (! do_debug_frames_interp)
53c7db4b 9634 printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
c47d488e
DD
9635 break;
9636
9637 case DW_CFA_nop:
31b6fca6 9638 if (! do_debug_frames_interp)
53c7db4b 9639 printf (" DW_CFA_nop\n");
c47d488e
DD
9640 break;
9641
63044634
RH
9642 case DW_CFA_def_cfa_expression:
9643 ul = LEB ();
9644 if (! do_debug_frames_interp)
9645 {
9646 printf (" DW_CFA_def_cfa_expression (");
9647 decode_location_expression (start, addr_size, ul);
9648 printf (")\n");
9649 }
9650 fc->cfa_exp = 1;
9651 start += ul;
9652 break;
9653
9654 case DW_CFA_expression:
9655 reg = LEB ();
9656 ul = LEB ();
9657 if (! do_debug_frames_interp)
9658 {
9659 printf (" DW_CFA_expression: r%ld (", reg);
9660 decode_location_expression (start, addr_size, ul);
9661 printf (")\n");
9662 }
9663 fc->col_type[reg] = DW_CFA_expression;
9664 start += ul;
9665 break;
9666
91a106e6
L
9667 case DW_CFA_offset_extended_sf:
9668 reg = LEB ();
9669 l = SLEB ();
9670 frame_need_space (fc, reg);
9671 if (! do_debug_frames_interp)
9672 printf (" DW_CFA_offset_extended_sf: r%ld at cfa%+ld\n",
9673 reg, l * fc->data_factor);
9674 fc->col_type[reg] = DW_CFA_offset;
9675 fc->col_offset[reg] = l * fc->data_factor;
9676 break;
9677
9678 case DW_CFA_def_cfa_sf:
9679 fc->cfa_reg = LEB ();
9680 fc->cfa_offset = SLEB ();
63044634 9681 fc->cfa_exp = 0;
91a106e6
L
9682 if (! do_debug_frames_interp)
9683 printf (" DW_CFA_def_cfa_sf: r%d ofs %d\n",
9684 fc->cfa_reg, fc->cfa_offset);
9685 break;
9686
9687 case DW_CFA_def_cfa_offset_sf:
9688 fc->cfa_offset = SLEB ();
9689 if (! do_debug_frames_interp)
9690 printf (" DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset);
9691 break;
9692
63044634
RH
9693 case DW_CFA_MIPS_advance_loc8:
9694 ofs = byte_get (start, 8); start += 8;
9695 if (do_debug_frames_interp)
9696 frame_display_row (fc, &need_col_headers, &max_regs);
9697 else
9698 printf (" DW_CFA_MIPS_advance_loc8: %ld to %08lx\n",
9699 ofs * fc->code_factor,
9700 fc->pc_begin + ofs * fc->code_factor);
9701 fc->pc_begin += ofs * fc->code_factor;
9702 break;
9703
c47d488e 9704 case DW_CFA_GNU_window_save:
31b6fca6 9705 if (! do_debug_frames_interp)
53c7db4b 9706 printf (" DW_CFA_GNU_window_save\n");
c47d488e
DD
9707 break;
9708
c47d488e
DD
9709 case DW_CFA_GNU_args_size:
9710 ul = LEB ();
31b6fca6 9711 if (! do_debug_frames_interp)
53c7db4b 9712 printf (" DW_CFA_GNU_args_size: %ld\n", ul);
c47d488e
DD
9713 break;
9714
c47d488e
DD
9715 case DW_CFA_GNU_negative_offset_extended:
9716 reg = LEB ();
9717 l = - LEB ();
9718 frame_need_space (fc, reg);
31b6fca6 9719 if (! do_debug_frames_interp)
53c7db4b 9720 printf (" DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 9721 reg, l * fc->data_factor);
c47d488e
DD
9722 fc->col_type[reg] = DW_CFA_offset;
9723 fc->col_offset[reg] = l * fc->data_factor;
9724 break;
9725
9726 default:
9727 fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
9728 start = block_end;
9729 }
9730 }
9731
31b6fca6 9732 if (do_debug_frames_interp)
53c7db4b 9733 frame_display_row (fc, &need_col_headers, &max_regs);
c47d488e
DD
9734
9735 start = block_end;
9736 }
9737
9738 printf ("\n");
9739
9740 return 1;
9741}
9742
9743#undef GET
9744#undef LEB
9745#undef SLEB
252b5132
RH
9746
9747static int
d3ba0551
AM
9748display_debug_not_supported (Elf_Internal_Shdr *section,
9749 unsigned char *start ATTRIBUTE_UNUSED,
9750 FILE *file ATTRIBUTE_UNUSED)
252b5132
RH
9751{
9752 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
9753 SECTION_NAME (section));
9754
9755 return 1;
9756}
9757
d9296b18
NC
9758/* A structure containing the name of a debug section
9759 and a pointer to a function that can decode it. */
252b5132
RH
9760struct
9761{
b34976b6 9762 const char *const name;
d3ba0551 9763 int (*display) (Elf_Internal_Shdr *, unsigned char *, FILE *);
252b5132
RH
9764}
9765debug_displays[] =
9766{
d9296b18
NC
9767 { ".debug_abbrev", display_debug_abbrev },
9768 { ".debug_aranges", display_debug_aranges },
9769 { ".debug_frame", display_debug_frames },
9770 { ".debug_info", display_debug_info },
9771 { ".debug_line", display_debug_lines },
9772 { ".debug_pubnames", display_debug_pubnames },
9773 { ".eh_frame", display_debug_frames },
9774 { ".debug_macinfo", display_debug_macinfo },
9775 { ".debug_str", display_debug_str },
9776 { ".debug_loc", display_debug_loc },
935a41f5 9777 { ".debug_pubtypes", display_debug_pubnames },
d9296b18
NC
9778 { ".debug_ranges", display_debug_not_supported },
9779 { ".debug_static_func", display_debug_not_supported },
9780 { ".debug_static_vars", display_debug_not_supported },
9781 { ".debug_types", display_debug_not_supported },
9782 { ".debug_weaknames", display_debug_not_supported }
252b5132
RH
9783};
9784
9785static int
d3ba0551 9786display_debug_section (Elf_Internal_Shdr *section, FILE *file)
252b5132 9787{
b34976b6
AM
9788 char *name = SECTION_NAME (section);
9789 bfd_size_type length;
9790 unsigned char *start;
9791 int i;
252b5132
RH
9792
9793 length = section->sh_size;
9794 if (length == 0)
9795 {
9796 printf (_("\nSection '%s' has no debugging data.\n"), name);
9797 return 0;
9798 }
9799
d3ba0551
AM
9800 start = get_data (NULL, file, section->sh_offset, length,
9801 _("debug section data"));
a6e9f9df
AM
9802 if (!start)
9803 return 0;
252b5132
RH
9804
9805 /* See if we know how to display the contents of this section. */
09fd7e38 9806 if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
7036c0e1 9807 name = ".debug_info";
584da044 9808
252b5132
RH
9809 for (i = NUM_ELEM (debug_displays); i--;)
9810 if (strcmp (debug_displays[i].name, name) == 0)
9811 {
9812 debug_displays[i].display (section, start, file);
9813 break;
9814 }
9815
9816 if (i == -1)
2c71103e 9817 printf (_("Unrecognized debug section: %s\n"), name);
252b5132
RH
9818
9819 free (start);
9820
9821 /* If we loaded in the abbrev section at some point,
9822 we must release it here. */
261a45ad 9823 free_abbrevs ();
252b5132
RH
9824
9825 return 1;
9826}
9827
9828static int
d3ba0551 9829process_section_contents (FILE *file)
252b5132 9830{
b34976b6
AM
9831 Elf_Internal_Shdr *section;
9832 unsigned int i;
252b5132
RH
9833
9834 if (! do_dump)
9835 return 1;
9836
9837 for (i = 0, section = section_headers;
3590ea00 9838 i < elf_header.e_shnum && i < num_dump_sects;
b34976b6 9839 i++, section++)
252b5132
RH
9840 {
9841#ifdef SUPPORT_DISASSEMBLY
9842 if (dump_sects[i] & DISASS_DUMP)
9843 disassemble_section (section, file);
9844#endif
9845 if (dump_sects[i] & HEX_DUMP)
9846 dump_section (section, file);
9847
9848 if (dump_sects[i] & DEBUG_DUMP)
9849 display_debug_section (section, file);
9850 }
9851
9852 if (i < num_dump_sects)
9853 warn (_("Some sections were not dumped because they do not exist!\n"));
9854
9855 return 1;
9856}
9857
9858static void
d3ba0551 9859process_mips_fpe_exception (int mask)
252b5132
RH
9860{
9861 if (mask)
9862 {
9863 int first = 1;
9864 if (mask & OEX_FPU_INEX)
9865 fputs ("INEX", stdout), first = 0;
9866 if (mask & OEX_FPU_UFLO)
9867 printf ("%sUFLO", first ? "" : "|"), first = 0;
9868 if (mask & OEX_FPU_OFLO)
9869 printf ("%sOFLO", first ? "" : "|"), first = 0;
9870 if (mask & OEX_FPU_DIV0)
9871 printf ("%sDIV0", first ? "" : "|"), first = 0;
9872 if (mask & OEX_FPU_INVAL)
9873 printf ("%sINVAL", first ? "" : "|");
9874 }
9875 else
9876 fputs ("0", stdout);
9877}
9878
9879static int
d3ba0551 9880process_mips_specific (FILE *file)
252b5132 9881{
b34976b6 9882 Elf_Internal_Dyn *entry;
252b5132
RH
9883 size_t liblist_offset = 0;
9884 size_t liblistno = 0;
9885 size_t conflictsno = 0;
9886 size_t options_offset = 0;
9887 size_t conflicts_offset = 0;
9888
9889 /* We have a lot of special sections. Thanks SGI! */
b2d38a17 9890 if (dynamic_section == NULL)
252b5132
RH
9891 /* No information available. */
9892 return 0;
9893
b2d38a17 9894 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
9895 switch (entry->d_tag)
9896 {
9897 case DT_MIPS_LIBLIST:
d93f0186
NC
9898 liblist_offset
9899 = offset_from_vma (file, entry->d_un.d_val,
9900 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
9901 break;
9902 case DT_MIPS_LIBLISTNO:
9903 liblistno = entry->d_un.d_val;
9904 break;
9905 case DT_MIPS_OPTIONS:
d93f0186 9906 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
9907 break;
9908 case DT_MIPS_CONFLICT:
d93f0186
NC
9909 conflicts_offset
9910 = offset_from_vma (file, entry->d_un.d_val,
9911 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
9912 break;
9913 case DT_MIPS_CONFLICTNO:
9914 conflictsno = entry->d_un.d_val;
9915 break;
9916 default:
9917 break;
9918 }
9919
9920 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
9921 {
b34976b6 9922 Elf32_External_Lib *elib;
252b5132
RH
9923 size_t cnt;
9924
d3ba0551
AM
9925 elib = get_data (NULL, file, liblist_offset,
9926 liblistno * sizeof (Elf32_External_Lib),
9927 _("liblist"));
a6e9f9df 9928 if (elib)
252b5132 9929 {
a6e9f9df
AM
9930 printf ("\nSection '.liblist' contains %lu entries:\n",
9931 (unsigned long) liblistno);
9932 fputs (" Library Time Stamp Checksum Version Flags\n",
9933 stdout);
9934
9935 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 9936 {
a6e9f9df
AM
9937 Elf32_Lib liblist;
9938 time_t time;
9939 char timebuf[20];
b34976b6 9940 struct tm *tmp;
a6e9f9df
AM
9941
9942 liblist.l_name = BYTE_GET (elib[cnt].l_name);
9943 time = BYTE_GET (elib[cnt].l_time_stamp);
9944 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
9945 liblist.l_version = BYTE_GET (elib[cnt].l_version);
9946 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
9947
9948 tmp = gmtime (&time);
9949 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
9950 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9951 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
9952
31104126
NC
9953 printf ("%3lu: ", (unsigned long) cnt);
9954 print_symbol (20, dynamic_strings + liblist.l_name);
9955 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
9956 liblist.l_version);
a6e9f9df
AM
9957
9958 if (liblist.l_flags == 0)
9959 puts (" NONE");
9960 else
9961 {
9962 static const struct
252b5132 9963 {
b34976b6 9964 const char *name;
a6e9f9df 9965 int bit;
252b5132 9966 }
a6e9f9df
AM
9967 l_flags_vals[] =
9968 {
9969 { " EXACT_MATCH", LL_EXACT_MATCH },
9970 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
9971 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
9972 { " EXPORTS", LL_EXPORTS },
9973 { " DELAY_LOAD", LL_DELAY_LOAD },
9974 { " DELTA", LL_DELTA }
9975 };
9976 int flags = liblist.l_flags;
9977 size_t fcnt;
9978
9979 for (fcnt = 0;
9980 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
9981 ++fcnt)
9982 if ((flags & l_flags_vals[fcnt].bit) != 0)
9983 {
9984 fputs (l_flags_vals[fcnt].name, stdout);
9985 flags ^= l_flags_vals[fcnt].bit;
9986 }
9987 if (flags != 0)
9988 printf (" %#x", (unsigned int) flags);
252b5132 9989
a6e9f9df
AM
9990 puts ("");
9991 }
252b5132 9992 }
252b5132 9993
a6e9f9df
AM
9994 free (elib);
9995 }
252b5132
RH
9996 }
9997
9998 if (options_offset != 0)
9999 {
b34976b6
AM
10000 Elf_External_Options *eopt;
10001 Elf_Internal_Shdr *sect = section_headers;
10002 Elf_Internal_Options *iopt;
10003 Elf_Internal_Options *option;
252b5132
RH
10004 size_t offset;
10005 int cnt;
10006
10007 /* Find the section header so that we get the size. */
10008 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 10009 ++sect;
252b5132 10010
d3ba0551
AM
10011 eopt = get_data (NULL, file, options_offset, sect->sh_size,
10012 _("options"));
a6e9f9df 10013 if (eopt)
252b5132 10014 {
d3ba0551 10015 iopt = malloc ((sect->sh_size / sizeof (eopt)) * sizeof (*iopt));
a6e9f9df
AM
10016 if (iopt == NULL)
10017 {
10018 error (_("Out of memory"));
10019 return 0;
10020 }
76da6bbe 10021
a6e9f9df
AM
10022 offset = cnt = 0;
10023 option = iopt;
252b5132 10024
a6e9f9df
AM
10025 while (offset < sect->sh_size)
10026 {
b34976b6 10027 Elf_External_Options *eoption;
252b5132 10028
a6e9f9df 10029 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 10030
a6e9f9df
AM
10031 option->kind = BYTE_GET (eoption->kind);
10032 option->size = BYTE_GET (eoption->size);
10033 option->section = BYTE_GET (eoption->section);
10034 option->info = BYTE_GET (eoption->info);
76da6bbe 10035
a6e9f9df 10036 offset += option->size;
252b5132 10037
a6e9f9df
AM
10038 ++option;
10039 ++cnt;
10040 }
252b5132 10041
a6e9f9df
AM
10042 printf (_("\nSection '%s' contains %d entries:\n"),
10043 SECTION_NAME (sect), cnt);
76da6bbe 10044
a6e9f9df 10045 option = iopt;
252b5132 10046
a6e9f9df 10047 while (cnt-- > 0)
252b5132 10048 {
a6e9f9df
AM
10049 size_t len;
10050
10051 switch (option->kind)
252b5132 10052 {
a6e9f9df
AM
10053 case ODK_NULL:
10054 /* This shouldn't happen. */
10055 printf (" NULL %d %lx", option->section, option->info);
10056 break;
10057 case ODK_REGINFO:
10058 printf (" REGINFO ");
10059 if (elf_header.e_machine == EM_MIPS)
10060 {
10061 /* 32bit form. */
b34976b6
AM
10062 Elf32_External_RegInfo *ereg;
10063 Elf32_RegInfo reginfo;
a6e9f9df
AM
10064
10065 ereg = (Elf32_External_RegInfo *) (option + 1);
10066 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
10067 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
10068 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
10069 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
10070 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
10071 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
10072
10073 printf ("GPR %08lx GP 0x%lx\n",
10074 reginfo.ri_gprmask,
10075 (unsigned long) reginfo.ri_gp_value);
10076 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
10077 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
10078 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
10079 }
10080 else
10081 {
10082 /* 64 bit form. */
b34976b6 10083 Elf64_External_RegInfo *ereg;
a6e9f9df
AM
10084 Elf64_Internal_RegInfo reginfo;
10085
10086 ereg = (Elf64_External_RegInfo *) (option + 1);
10087 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
10088 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
10089 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
10090 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
10091 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
10092 reginfo.ri_gp_value = BYTE_GET8 (ereg->ri_gp_value);
10093
10094 printf ("GPR %08lx GP 0x",
10095 reginfo.ri_gprmask);
10096 printf_vma (reginfo.ri_gp_value);
10097 printf ("\n");
10098
10099 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
10100 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
10101 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
10102 }
10103 ++option;
10104 continue;
10105 case ODK_EXCEPTIONS:
10106 fputs (" EXCEPTIONS fpe_min(", stdout);
10107 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
10108 fputs (") fpe_max(", stdout);
10109 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
10110 fputs (")", stdout);
10111
10112 if (option->info & OEX_PAGE0)
10113 fputs (" PAGE0", stdout);
10114 if (option->info & OEX_SMM)
10115 fputs (" SMM", stdout);
10116 if (option->info & OEX_FPDBUG)
10117 fputs (" FPDBUG", stdout);
10118 if (option->info & OEX_DISMISS)
10119 fputs (" DISMISS", stdout);
10120 break;
10121 case ODK_PAD:
10122 fputs (" PAD ", stdout);
10123 if (option->info & OPAD_PREFIX)
10124 fputs (" PREFIX", stdout);
10125 if (option->info & OPAD_POSTFIX)
10126 fputs (" POSTFIX", stdout);
10127 if (option->info & OPAD_SYMBOL)
10128 fputs (" SYMBOL", stdout);
10129 break;
10130 case ODK_HWPATCH:
10131 fputs (" HWPATCH ", stdout);
10132 if (option->info & OHW_R4KEOP)
10133 fputs (" R4KEOP", stdout);
10134 if (option->info & OHW_R8KPFETCH)
10135 fputs (" R8KPFETCH", stdout);
10136 if (option->info & OHW_R5KEOP)
10137 fputs (" R5KEOP", stdout);
10138 if (option->info & OHW_R5KCVTL)
10139 fputs (" R5KCVTL", stdout);
10140 break;
10141 case ODK_FILL:
10142 fputs (" FILL ", stdout);
10143 /* XXX Print content of info word? */
10144 break;
10145 case ODK_TAGS:
10146 fputs (" TAGS ", stdout);
10147 /* XXX Print content of info word? */
10148 break;
10149 case ODK_HWAND:
10150 fputs (" HWAND ", stdout);
10151 if (option->info & OHWA0_R4KEOP_CHECKED)
10152 fputs (" R4KEOP_CHECKED", stdout);
10153 if (option->info & OHWA0_R4KEOP_CLEAN)
10154 fputs (" R4KEOP_CLEAN", stdout);
10155 break;
10156 case ODK_HWOR:
10157 fputs (" HWOR ", stdout);
10158 if (option->info & OHWA0_R4KEOP_CHECKED)
10159 fputs (" R4KEOP_CHECKED", stdout);
10160 if (option->info & OHWA0_R4KEOP_CLEAN)
10161 fputs (" R4KEOP_CLEAN", stdout);
10162 break;
10163 case ODK_GP_GROUP:
10164 printf (" GP_GROUP %#06lx self-contained %#06lx",
10165 option->info & OGP_GROUP,
10166 (option->info & OGP_SELF) >> 16);
10167 break;
10168 case ODK_IDENT:
10169 printf (" IDENT %#06lx self-contained %#06lx",
10170 option->info & OGP_GROUP,
10171 (option->info & OGP_SELF) >> 16);
10172 break;
10173 default:
10174 /* This shouldn't happen. */
10175 printf (" %3d ??? %d %lx",
10176 option->kind, option->section, option->info);
10177 break;
252b5132 10178 }
a6e9f9df 10179
b34976b6 10180 len = sizeof (*eopt);
a6e9f9df
AM
10181 while (len < option->size)
10182 if (((char *) option)[len] >= ' '
10183 && ((char *) option)[len] < 0x7f)
10184 printf ("%c", ((char *) option)[len++]);
10185 else
10186 printf ("\\%03o", ((char *) option)[len++]);
10187
10188 fputs ("\n", stdout);
252b5132 10189 ++option;
252b5132
RH
10190 }
10191
a6e9f9df 10192 free (eopt);
252b5132 10193 }
252b5132
RH
10194 }
10195
10196 if (conflicts_offset != 0 && conflictsno != 0)
10197 {
b34976b6 10198 Elf32_Conflict *iconf;
252b5132
RH
10199 size_t cnt;
10200
10201 if (dynamic_symbols == NULL)
10202 {
3a1a2036 10203 error (_("conflict list found without a dynamic symbol table"));
252b5132
RH
10204 return 0;
10205 }
10206
d3ba0551 10207 iconf = malloc (conflictsno * sizeof (*iconf));
252b5132
RH
10208 if (iconf == NULL)
10209 {
10210 error (_("Out of memory"));
10211 return 0;
10212 }
10213
9ea033b2 10214 if (is_32bit_elf)
252b5132 10215 {
b34976b6 10216 Elf32_External_Conflict *econf32;
a6e9f9df 10217
d3ba0551
AM
10218 econf32 = get_data (NULL, file, conflicts_offset,
10219 conflictsno * sizeof (*econf32), _("conflict"));
a6e9f9df
AM
10220 if (!econf32)
10221 return 0;
252b5132
RH
10222
10223 for (cnt = 0; cnt < conflictsno; ++cnt)
10224 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
10225
10226 free (econf32);
252b5132
RH
10227 }
10228 else
10229 {
b34976b6 10230 Elf64_External_Conflict *econf64;
a6e9f9df 10231
d3ba0551
AM
10232 econf64 = get_data (NULL, file, conflicts_offset,
10233 conflictsno * sizeof (*econf64), _("conflict"));
a6e9f9df
AM
10234 if (!econf64)
10235 return 0;
252b5132
RH
10236
10237 for (cnt = 0; cnt < conflictsno; ++cnt)
10238 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
10239
10240 free (econf64);
252b5132
RH
10241 }
10242
c7e7ca54
NC
10243 printf (_("\nSection '.conflict' contains %lu entries:\n"),
10244 (unsigned long) conflictsno);
252b5132
RH
10245 puts (_(" Num: Index Value Name"));
10246
10247 for (cnt = 0; cnt < conflictsno; ++cnt)
10248 {
b34976b6 10249 Elf_Internal_Sym *psym = & dynamic_symbols[iconf[cnt]];
252b5132 10250
b34976b6 10251 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 10252 print_vma (psym->st_value, FULL_HEX);
31104126
NC
10253 putchar (' ');
10254 print_symbol (25, dynamic_strings + psym->st_name);
10255 putchar ('\n');
252b5132
RH
10256 }
10257
252b5132
RH
10258 free (iconf);
10259 }
10260
10261 return 1;
10262}
10263
047b2264 10264static int
d3ba0551 10265process_gnu_liblist (FILE *file)
047b2264 10266{
b34976b6
AM
10267 Elf_Internal_Shdr *section, *string_sec;
10268 Elf32_External_Lib *elib;
10269 char *strtab;
047b2264
JJ
10270 size_t cnt;
10271 unsigned i;
10272
10273 if (! do_arch)
10274 return 0;
10275
10276 for (i = 0, section = section_headers;
10277 i < elf_header.e_shnum;
b34976b6 10278 i++, section++)
047b2264
JJ
10279 {
10280 switch (section->sh_type)
10281 {
10282 case SHT_GNU_LIBLIST:
d3ba0551
AM
10283 elib = get_data (NULL, file, section->sh_offset, section->sh_size,
10284 _("liblist"));
047b2264
JJ
10285
10286 if (elib == NULL)
10287 break;
10288 string_sec = SECTION_HEADER (section->sh_link);
10289
d3ba0551
AM
10290 strtab = get_data (NULL, file, string_sec->sh_offset,
10291 string_sec->sh_size, _("liblist string table"));
047b2264
JJ
10292
10293 if (strtab == NULL
10294 || section->sh_entsize != sizeof (Elf32_External_Lib))
10295 {
10296 free (elib);
10297 break;
10298 }
10299
10300 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
10301 SECTION_NAME (section),
10302 (long) (section->sh_size / sizeof (Elf32_External_Lib)));
10303
10304 puts (" Library Time Stamp Checksum Version Flags");
10305
10306 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
10307 ++cnt)
10308 {
10309 Elf32_Lib liblist;
10310 time_t time;
10311 char timebuf[20];
b34976b6 10312 struct tm *tmp;
047b2264
JJ
10313
10314 liblist.l_name = BYTE_GET (elib[cnt].l_name);
10315 time = BYTE_GET (elib[cnt].l_time_stamp);
10316 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
10317 liblist.l_version = BYTE_GET (elib[cnt].l_version);
10318 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
10319
10320 tmp = gmtime (&time);
10321 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
10322 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10323 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
10324
10325 printf ("%3lu: ", (unsigned long) cnt);
10326 if (do_wide)
10327 printf ("%-20s", strtab + liblist.l_name);
10328 else
10329 printf ("%-20.20s", strtab + liblist.l_name);
10330 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
10331 liblist.l_version, liblist.l_flags);
10332 }
10333
10334 free (elib);
10335 }
10336 }
10337
10338 return 1;
10339}
10340
9437c45b 10341static const char *
d3ba0551 10342get_note_type (unsigned e_type)
779fe533
NC
10343{
10344 static char buff[64];
103f02d3 10345
779fe533
NC
10346 switch (e_type)
10347 {
0de14b54 10348 case NT_AUXV: return _("NT_AUXV (auxiliary vector)");
779fe533
NC
10349 case NT_PRSTATUS: return _("NT_PRSTATUS (prstatus structure)");
10350 case NT_FPREGSET: return _("NT_FPREGSET (floating point registers)");
b34976b6
AM
10351 case NT_PRPSINFO: return _("NT_PRPSINFO (prpsinfo structure)");
10352 case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
10353 case NT_PRXFPREG: return _("NT_PRXFPREG (user_xfpregs structure)");
779fe533
NC
10354 case NT_PSTATUS: return _("NT_PSTATUS (pstatus structure)");
10355 case NT_FPREGS: return _("NT_FPREGS (floating point registers)");
10356 case NT_PSINFO: return _("NT_PSINFO (psinfo structure)");
10357 case NT_LWPSTATUS: return _("NT_LWPSTATUS (lwpstatus_t structure)");
10358 case NT_LWPSINFO: return _("NT_LWPSINFO (lwpsinfo_t structure)");
3a1a2036 10359 case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus structure)");
779fe533
NC
10360 default:
10361 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
10362 return buff;
10363 }
10364}
10365
9437c45b 10366static const char *
d3ba0551 10367get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
10368{
10369 static char buff[64];
10370
b4db1224 10371 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
10372 {
10373 /* NetBSD core "procinfo" structure. */
10374 return _("NetBSD procinfo structure");
10375 }
10376
10377 /* As of Jan 2002 there are no other machine-independent notes
10378 defined for NetBSD core files. If the note type is less
10379 than the start of the machine-dependent note types, we don't
10380 understand it. */
10381
b4db1224 10382 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b
JT
10383 {
10384 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
10385 return buff;
10386 }
10387
10388 switch (elf_header.e_machine)
10389 {
10390 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
10391 and PT_GETFPREGS == mach+2. */
10392
10393 case EM_OLD_ALPHA:
10394 case EM_ALPHA:
10395 case EM_SPARC:
10396 case EM_SPARC32PLUS:
10397 case EM_SPARCV9:
10398 switch (e_type)
10399 {
b4db1224
JT
10400 case NT_NETBSDCORE_FIRSTMACH+0:
10401 return _("PT_GETREGS (reg structure)");
10402 case NT_NETBSDCORE_FIRSTMACH+2:
10403 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
10404 default:
10405 break;
10406 }
10407 break;
10408
10409 /* On all other arch's, PT_GETREGS == mach+1 and
10410 PT_GETFPREGS == mach+3. */
10411 default:
10412 switch (e_type)
10413 {
b4db1224
JT
10414 case NT_NETBSDCORE_FIRSTMACH+1:
10415 return _("PT_GETREGS (reg structure)");
10416 case NT_NETBSDCORE_FIRSTMACH+3:
10417 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
10418 default:
10419 break;
10420 }
10421 }
10422
b4db1224 10423 sprintf (buff, _("PT_FIRSTMACH+%d"), e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
10424 return buff;
10425}
10426
6d118b09
NC
10427/* Note that by the ELF standard, the name field is already null byte
10428 terminated, and namesz includes the terminating null byte.
10429 I.E. the value of namesz for the name "FSF" is 4.
10430
e3c8793a 10431 If the value of namesz is zero, there is no name present. */
779fe533 10432static int
d3ba0551 10433process_note (Elf_Internal_Note *pnote)
779fe533 10434{
9437c45b
JT
10435 const char *nt;
10436
10437 if (pnote->namesz == 0)
10438 {
10439 /* If there is no note name, then use the default set of
10440 note type strings. */
10441 nt = get_note_type (pnote->type);
10442 }
10443 else if (strncmp (pnote->namedata, "NetBSD-CORE", 11) == 0)
10444 {
10445 /* NetBSD-specific core file notes. */
10446 nt = get_netbsd_elfcore_note_type (pnote->type);
10447 }
10448 else
10449 {
10450 /* Don't recognize this note name; just use the default set of
10451 note type strings. */
10452 nt = get_note_type (pnote->type);
10453 }
10454
103f02d3 10455 printf (" %s\t\t0x%08lx\t%s\n",
6d118b09 10456 pnote->namesz ? pnote->namedata : "(NONE)",
9437c45b 10457 pnote->descsz, nt);
779fe533
NC
10458 return 1;
10459}
10460
6d118b09 10461
779fe533 10462static int
d3ba0551 10463process_corefile_note_segment (FILE *file, bfd_vma offset, bfd_vma length)
779fe533 10464{
b34976b6
AM
10465 Elf_External_Note *pnotes;
10466 Elf_External_Note *external;
10467 int res = 1;
103f02d3 10468
779fe533
NC
10469 if (length <= 0)
10470 return 0;
103f02d3 10471
d3ba0551 10472 pnotes = get_data (NULL, file, offset, length, _("notes"));
a6e9f9df
AM
10473 if (!pnotes)
10474 return 0;
779fe533 10475
103f02d3 10476 external = pnotes;
103f02d3 10477
305c7206 10478 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 10479 (unsigned long) offset, (unsigned long) length);
779fe533 10480 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 10481
6d118b09 10482 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 10483 {
b34976b6
AM
10484 Elf_External_Note *next;
10485 Elf_Internal_Note inote;
10486 char *temp = NULL;
6d118b09
NC
10487
10488 inote.type = BYTE_GET (external->type);
10489 inote.namesz = BYTE_GET (external->namesz);
10490 inote.namedata = external->name;
10491 inote.descsz = BYTE_GET (external->descsz);
10492 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
10493 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 10494
3e55a963
NC
10495 next = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
10496
10497 if (((char *) next) > (((char *) pnotes) + length))
10498 {
10499 warn (_("corrupt note found at offset %x into core notes\n"),
10500 ((char *) external) - ((char *) pnotes));
10501 warn (_(" type: %x, namesize: %08lx, descsize: %08lx\n"),
10502 inote.type, inote.namesz, inote.descsz);
10503 break;
10504 }
10505
10506 external = next;
6d118b09
NC
10507
10508 /* Verify that name is null terminated. It appears that at least
10509 one version of Linux (RedHat 6.0) generates corefiles that don't
10510 comply with the ELF spec by failing to include the null byte in
10511 namesz. */
10512 if (inote.namedata[inote.namesz] != '\0')
10513 {
10514 temp = malloc (inote.namesz + 1);
76da6bbe 10515
6d118b09
NC
10516 if (temp == NULL)
10517 {
10518 error (_("Out of memory\n"));
10519 res = 0;
10520 break;
10521 }
76da6bbe 10522
6d118b09
NC
10523 strncpy (temp, inote.namedata, inote.namesz);
10524 temp[inote.namesz] = 0;
76da6bbe 10525
6d118b09
NC
10526 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
10527 inote.namedata = temp;
10528 }
10529
10530 res &= process_note (& inote);
103f02d3 10531
6d118b09
NC
10532 if (temp != NULL)
10533 {
10534 free (temp);
10535 temp = NULL;
10536 }
779fe533
NC
10537 }
10538
10539 free (pnotes);
103f02d3 10540
779fe533
NC
10541 return res;
10542}
10543
10544static int
d3ba0551 10545process_corefile_note_segments (FILE *file)
779fe533 10546{
b34976b6
AM
10547 Elf_Internal_Phdr *segment;
10548 unsigned int i;
10549 int res = 1;
103f02d3 10550
d93f0186 10551 if (! get_program_headers (file))
779fe533 10552 return 0;
103f02d3 10553
779fe533
NC
10554 for (i = 0, segment = program_headers;
10555 i < elf_header.e_phnum;
b34976b6 10556 i++, segment++)
779fe533
NC
10557 {
10558 if (segment->p_type == PT_NOTE)
103f02d3 10559 res &= process_corefile_note_segment (file,
30800947
NC
10560 (bfd_vma) segment->p_offset,
10561 (bfd_vma) segment->p_filesz);
779fe533 10562 }
103f02d3 10563
779fe533
NC
10564 return res;
10565}
10566
10567static int
d3ba0551 10568process_corefile_contents (FILE *file)
779fe533
NC
10569{
10570 /* If we have not been asked to display the notes then do nothing. */
10571 if (! do_notes)
10572 return 1;
103f02d3 10573
779fe533
NC
10574 /* If file is not a core file then exit. */
10575 if (elf_header.e_type != ET_CORE)
10576 return 1;
103f02d3 10577
779fe533
NC
10578 /* No program headers means no NOTE segment. */
10579 if (elf_header.e_phnum == 0)
10580 {
10581 printf (_("No note segments present in the core file.\n"));
10582 return 1;
10583 }
10584
10585 return process_corefile_note_segments (file);
10586}
10587
252b5132 10588static int
d3ba0551 10589process_arch_specific (FILE *file)
252b5132 10590{
a952a375
NC
10591 if (! do_arch)
10592 return 1;
10593
252b5132
RH
10594 switch (elf_header.e_machine)
10595 {
10596 case EM_MIPS:
4fe85591 10597 case EM_MIPS_RS3_LE:
252b5132
RH
10598 return process_mips_specific (file);
10599 break;
10600 default:
10601 break;
10602 }
10603 return 1;
10604}
10605
10606static int
d3ba0551 10607get_file_header (FILE *file)
252b5132 10608{
9ea033b2
NC
10609 /* Read in the identity array. */
10610 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
10611 return 0;
10612
9ea033b2 10613 /* Determine how to read the rest of the header. */
b34976b6 10614 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
10615 {
10616 default: /* fall through */
10617 case ELFDATANONE: /* fall through */
adab8cdc
AO
10618 case ELFDATA2LSB:
10619 byte_get = byte_get_little_endian;
10620 byte_put = byte_put_little_endian;
10621 break;
10622 case ELFDATA2MSB:
10623 byte_get = byte_get_big_endian;
10624 byte_put = byte_put_big_endian;
10625 break;
9ea033b2
NC
10626 }
10627
10628 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 10629 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
10630
10631 /* Read in the rest of the header. */
10632 if (is_32bit_elf)
10633 {
10634 Elf32_External_Ehdr ehdr32;
252b5132 10635
9ea033b2
NC
10636 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
10637 return 0;
103f02d3 10638
9ea033b2
NC
10639 elf_header.e_type = BYTE_GET (ehdr32.e_type);
10640 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
10641 elf_header.e_version = BYTE_GET (ehdr32.e_version);
10642 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
10643 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
10644 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
10645 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
10646 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
10647 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
10648 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
10649 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
10650 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
10651 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
10652 }
252b5132 10653 else
9ea033b2
NC
10654 {
10655 Elf64_External_Ehdr ehdr64;
a952a375
NC
10656
10657 /* If we have been compiled with sizeof (bfd_vma) == 4, then
10658 we will not be able to cope with the 64bit data found in
10659 64 ELF files. Detect this now and abort before we start
50c2245b 10660 overwriting things. */
a952a375
NC
10661 if (sizeof (bfd_vma) < 8)
10662 {
e3c8793a
NC
10663 error (_("This instance of readelf has been built without support for a\n\
1066464 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
10665 return 0;
10666 }
103f02d3 10667
9ea033b2
NC
10668 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
10669 return 0;
103f02d3 10670
9ea033b2
NC
10671 elf_header.e_type = BYTE_GET (ehdr64.e_type);
10672 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
10673 elf_header.e_version = BYTE_GET (ehdr64.e_version);
10674 elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry);
10675 elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff);
10676 elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff);
10677 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
10678 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
10679 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
10680 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
10681 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
10682 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
10683 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
10684 }
252b5132 10685
7ece0d85
JJ
10686 if (elf_header.e_shoff)
10687 {
10688 /* There may be some extensions in the first section header. Don't
10689 bomb if we can't read it. */
10690 if (is_32bit_elf)
10691 get_32bit_section_headers (file, 1);
10692 else
10693 get_64bit_section_headers (file, 1);
10694 }
560f3c1c 10695
252b5132
RH
10696 return 1;
10697}
10698
fb52b2f4
NC
10699/* Process one ELF object file according to the command line options.
10700 This file may actually be stored in an archive. The file is
10701 positioned at the start of the ELF object. */
10702
ff78d6d6 10703static int
fb52b2f4 10704process_object (char *file_name, FILE *file)
252b5132 10705{
252b5132
RH
10706 unsigned int i;
10707
252b5132
RH
10708 if (! get_file_header (file))
10709 {
10710 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 10711 return 1;
252b5132
RH
10712 }
10713
10714 /* Initialise per file variables. */
10715 for (i = NUM_ELEM (version_info); i--;)
10716 version_info[i] = 0;
10717
10718 for (i = NUM_ELEM (dynamic_info); i--;)
10719 dynamic_info[i] = 0;
10720
10721 /* Process the file. */
10722 if (show_name)
10723 printf (_("\nFile: %s\n"), file_name);
10724
10725 if (! process_file_header ())
fb52b2f4 10726 return 1;
252b5132 10727
e4b17d5c
L
10728 if (! process_section_headers (file)
10729 || ! process_section_groups (file))
2f62977e 10730 {
e4b17d5c 10731 /* Without loaded section headers and section groups we
2f62977e
NC
10732 cannot process lots of things. */
10733 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 10734
2f62977e
NC
10735 if (! do_using_dynamic)
10736 do_syms = do_reloc = 0;
10737 }
252b5132 10738
2f62977e 10739 if (process_program_headers (file))
b2d38a17 10740 process_dynamic_section (file);
252b5132
RH
10741
10742 process_relocs (file);
10743
4d6ed7c8
NC
10744 process_unwind (file);
10745
252b5132
RH
10746 process_symbol_table (file);
10747
10748 process_syminfo (file);
10749
10750 process_version_sections (file);
10751
10752 process_section_contents (file);
f5842774 10753
779fe533 10754 process_corefile_contents (file);
103f02d3 10755
047b2264
JJ
10756 process_gnu_liblist (file);
10757
252b5132
RH
10758 process_arch_specific (file);
10759
d93f0186
NC
10760 if (program_headers)
10761 {
10762 free (program_headers);
10763 program_headers = NULL;
10764 }
10765
252b5132
RH
10766 if (section_headers)
10767 {
10768 free (section_headers);
10769 section_headers = NULL;
10770 }
10771
10772 if (string_table)
10773 {
10774 free (string_table);
10775 string_table = NULL;
d40ac9bd 10776 string_table_length = 0;
252b5132
RH
10777 }
10778
10779 if (dynamic_strings)
10780 {
10781 free (dynamic_strings);
10782 dynamic_strings = NULL;
10783 }
10784
10785 if (dynamic_symbols)
10786 {
10787 free (dynamic_symbols);
10788 dynamic_symbols = NULL;
19936277 10789 num_dynamic_syms = 0;
252b5132
RH
10790 }
10791
10792 if (dynamic_syminfo)
10793 {
10794 free (dynamic_syminfo);
10795 dynamic_syminfo = NULL;
10796 }
ff78d6d6 10797
e4b17d5c
L
10798 if (section_headers_groups)
10799 {
10800 free (section_headers_groups);
10801 section_headers_groups = NULL;
10802 }
10803
10804 if (section_groups)
10805 {
10806 struct group_list *g, *next;
10807
10808 for (i = 0; i < group_count; i++)
10809 {
10810 for (g = section_groups [i].root; g != NULL; g = next)
10811 {
10812 next = g->next;
10813 free (g);
10814 }
10815 }
10816
10817 free (section_groups);
10818 section_groups = NULL;
10819 }
10820
ff78d6d6 10821 return 0;
252b5132
RH
10822}
10823
fb52b2f4
NC
10824/* Process an ELF archive. The file is positioned just after the
10825 ARMAG string. */
10826
10827static int
10828process_archive (char *file_name, FILE *file)
10829{
10830 struct ar_hdr arhdr;
10831 size_t got;
10832 unsigned long size;
10833 char *longnames = NULL;
10834 unsigned long longnames_size = 0;
10835 size_t file_name_size;
d989285c 10836 int ret;
fb52b2f4
NC
10837
10838 show_name = 1;
10839
10840 got = fread (&arhdr, 1, sizeof arhdr, file);
10841 if (got != sizeof arhdr)
10842 {
10843 if (got == 0)
10844 return 0;
10845
10846 error (_("%s: failed to read archive header\n"), file_name);
10847 return 1;
10848 }
10849
10850 if (memcmp (arhdr.ar_name, "/ ", 16) == 0)
10851 {
10852 /* This is the archive symbol table. Skip it.
10853 FIXME: We should have an option to dump it. */
10854 size = strtoul (arhdr.ar_size, NULL, 10);
10855 if (fseek (file, size + (size & 1), SEEK_CUR) != 0)
10856 {
10857 error (_("%s: failed to skip archive symbol table\n"), file_name);
10858 return 1;
10859 }
10860
10861 got = fread (&arhdr, 1, sizeof arhdr, file);
10862 if (got != sizeof arhdr)
10863 {
10864 if (got == 0)
10865 return 0;
10866
10867 error (_("%s: failed to read archive header\n"), file_name);
10868 return 1;
10869 }
10870 }
10871
10872 if (memcmp (arhdr.ar_name, "// ", 16) == 0)
10873 {
10874 /* This is the archive string table holding long member
10875 names. */
10876
10877 longnames_size = strtoul (arhdr.ar_size, NULL, 10);
10878
10879 longnames = malloc (longnames_size);
10880 if (longnames == NULL)
10881 {
10882 error (_("Out of memory\n"));
10883 return 1;
10884 }
10885
10886 if (fread (longnames, longnames_size, 1, file) != 1)
10887 {
d989285c 10888 free (longnames);
fb52b2f4
NC
10889 error(_("%s: failed to read string table\n"), file_name);
10890 return 1;
10891 }
10892
10893 if ((longnames_size & 1) != 0)
10894 getc (file);
10895
10896 got = fread (&arhdr, 1, sizeof arhdr, file);
10897 if (got != sizeof arhdr)
10898 {
d989285c
ILT
10899 free (longnames);
10900
fb52b2f4
NC
10901 if (got == 0)
10902 return 0;
10903
10904 error (_("%s: failed to read archive header\n"), file_name);
10905 return 1;
10906 }
10907 }
10908
10909 file_name_size = strlen (file_name);
d989285c 10910 ret = 0;
fb52b2f4
NC
10911
10912 while (1)
10913 {
10914 char *name;
10915 char *nameend;
10916 char *namealc;
10917
10918 if (arhdr.ar_name[0] == '/')
10919 {
10920 unsigned long off;
10921
10922 off = strtoul (arhdr.ar_name + 1, NULL, 10);
10923 if (off >= longnames_size)
10924 {
10925 error (_("%s: invalid archive string table offset %lu\n"), off);
d989285c
ILT
10926 ret = 1;
10927 break;
fb52b2f4
NC
10928 }
10929
10930 name = longnames + off;
10931 nameend = memchr (name, '/', longnames_size - off);
10932 }
10933 else
10934 {
10935 name = arhdr.ar_name;
10936 nameend = memchr (name, '/', 16);
10937 }
10938
10939 if (nameend == NULL)
10940 {
10941 error (_("%s: bad archive file name\n"));
d989285c
ILT
10942 ret = 1;
10943 break;
fb52b2f4
NC
10944 }
10945
10946 namealc = malloc (file_name_size + (nameend - name) + 3);
10947 if (namealc == NULL)
10948 {
10949 error (_("Out of memory\n"));
d989285c
ILT
10950 ret = 1;
10951 break;
fb52b2f4
NC
10952 }
10953
10954 memcpy (namealc, file_name, file_name_size);
10955 namealc[file_name_size] = '(';
10956 memcpy (namealc + file_name_size + 1, name, nameend - name);
10957 namealc[file_name_size + 1 + (nameend - name)] = ')';
10958 namealc[file_name_size + 2 + (nameend - name)] = '\0';
10959
10960 archive_file_offset = ftell (file);
10961 archive_file_size = strtoul (arhdr.ar_size, NULL, 10);
10962
d989285c 10963 ret |= process_object (namealc, file);
fb52b2f4
NC
10964
10965 free (namealc);
10966
10967 if (fseek (file,
10968 (archive_file_offset
10969 + archive_file_size
10970 + (archive_file_size & 1)),
10971 SEEK_SET) != 0)
10972 {
10973 error (_("%s: failed to seek to next archive header\n"), file_name);
d989285c
ILT
10974 ret = 1;
10975 break;
fb52b2f4
NC
10976 }
10977
10978 got = fread (&arhdr, 1, sizeof arhdr, file);
10979 if (got != sizeof arhdr)
10980 {
10981 if (got == 0)
d989285c 10982 break;
fb52b2f4
NC
10983
10984 error (_("%s: failed to read archive header\n"), file_name);
d989285c
ILT
10985 ret = 1;
10986 break;
fb52b2f4
NC
10987 }
10988 }
10989
10990 if (longnames != 0)
10991 free (longnames);
10992
d989285c 10993 return ret;
fb52b2f4
NC
10994}
10995
10996static int
10997process_file (char *file_name)
10998{
10999 FILE *file;
11000 struct stat statbuf;
11001 char armag[SARMAG];
11002 int ret;
11003
11004 if (stat (file_name, &statbuf) < 0)
11005 {
f24ddbdd
NC
11006 if (errno == ENOENT)
11007 error (_("'%s': No such file\n"), file_name);
11008 else
11009 error (_("Could not locate '%s'. System error message: %s\n"),
11010 file_name, strerror (errno));
11011 return 1;
11012 }
11013
11014 if (! S_ISREG (statbuf.st_mode))
11015 {
11016 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
11017 return 1;
11018 }
11019
11020 file = fopen (file_name, "rb");
11021 if (file == NULL)
11022 {
f24ddbdd 11023 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
11024 return 1;
11025 }
11026
11027 if (fread (armag, SARMAG, 1, file) != 1)
11028 {
11029 error (_("%s: Failed to read file header\n"), file_name);
11030 fclose (file);
11031 return 1;
11032 }
11033
11034 if (memcmp (armag, ARMAG, SARMAG) == 0)
11035 ret = process_archive (file_name, file);
11036 else
11037 {
11038 rewind (file);
11039 archive_file_size = archive_file_offset = 0;
11040 ret = process_object (file_name, file);
11041 }
11042
11043 fclose (file);
11044
11045 return ret;
11046}
11047
252b5132
RH
11048#ifdef SUPPORT_DISASSEMBLY
11049/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 11050 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 11051 symbols. */
252b5132
RH
11052
11053void
b34976b6 11054print_address (unsigned int addr, FILE *outfile)
252b5132
RH
11055{
11056 fprintf (outfile,"0x%8.8x", addr);
11057}
11058
e3c8793a 11059/* Needed by the i386 disassembler. */
252b5132
RH
11060void
11061db_task_printsym (unsigned int addr)
11062{
11063 print_address (addr, stderr);
11064}
11065#endif
11066
11067int
d3ba0551 11068main (int argc, char **argv)
252b5132 11069{
ff78d6d6 11070 int err;
59f14fc0
AS
11071 char *cmdline_dump_sects = NULL;
11072 unsigned num_cmdline_dump_sects = 0;
ff78d6d6 11073
252b5132
RH
11074#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
11075 setlocale (LC_MESSAGES, "");
3882b010
L
11076#endif
11077#if defined (HAVE_SETLOCALE)
11078 setlocale (LC_CTYPE, "");
252b5132
RH
11079#endif
11080 bindtextdomain (PACKAGE, LOCALEDIR);
11081 textdomain (PACKAGE);
11082
11083 parse_args (argc, argv);
11084
11085 if (optind < (argc - 1))
11086 show_name = 1;
11087
59f14fc0
AS
11088 /* When processing more than one file remember the dump requests
11089 issued on command line to reset them after each file. */
11090 if (optind + 1 < argc && dump_sects != NULL)
11091 {
11092 cmdline_dump_sects = malloc (num_dump_sects);
11093 if (cmdline_dump_sects == NULL)
11094 error (_("Out of memory allocating dump request table."));
11095 else
11096 {
11097 memcpy (cmdline_dump_sects, dump_sects, num_dump_sects);
11098 num_cmdline_dump_sects = num_dump_sects;
11099 }
11100 }
11101
ff78d6d6 11102 err = 0;
252b5132 11103 while (optind < argc)
59f14fc0
AS
11104 {
11105 err |= process_file (argv[optind++]);
11106
11107 /* Reset dump requests. */
11108 if (optind < argc && dump_sects != NULL)
11109 {
11110 num_dump_sects = num_cmdline_dump_sects;
11111 if (num_cmdline_dump_sects > 0)
11112 memcpy (dump_sects, cmdline_dump_sects, num_cmdline_dump_sects);
11113 }
11114 }
252b5132
RH
11115
11116 if (dump_sects != NULL)
11117 free (dump_sects);
59f14fc0
AS
11118 if (cmdline_dump_sects != NULL)
11119 free (cmdline_dump_sects);
252b5132 11120
ff78d6d6 11121 return err;
252b5132 11122}