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