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