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