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