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