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