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