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