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