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