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