]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
* elf32-ppc.c (ppc_elf_modify_segment_map): Delete.
[thirdparty/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
252b5132 2406static const char *
d3ba0551 2407get_section_type_name (unsigned int sh_type)
252b5132 2408{
b34976b6 2409 static char buff[32];
252b5132
RH
2410
2411 switch (sh_type)
2412 {
2413 case SHT_NULL: return "NULL";
2414 case SHT_PROGBITS: return "PROGBITS";
2415 case SHT_SYMTAB: return "SYMTAB";
2416 case SHT_STRTAB: return "STRTAB";
2417 case SHT_RELA: return "RELA";
2418 case SHT_HASH: return "HASH";
2419 case SHT_DYNAMIC: return "DYNAMIC";
2420 case SHT_NOTE: return "NOTE";
2421 case SHT_NOBITS: return "NOBITS";
2422 case SHT_REL: return "REL";
2423 case SHT_SHLIB: return "SHLIB";
2424 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
2425 case SHT_INIT_ARRAY: return "INIT_ARRAY";
2426 case SHT_FINI_ARRAY: return "FINI_ARRAY";
2427 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
93ebe586
NC
2428 case SHT_GROUP: return "GROUP";
2429 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
2430 case SHT_GNU_verdef: return "VERDEF";
2431 case SHT_GNU_verneed: return "VERNEED";
2432 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
2433 case 0x6ffffff0: return "VERSYM";
2434 case 0x6ffffffc: return "VERDEF";
252b5132
RH
2435 case 0x7ffffffd: return "AUXILIARY";
2436 case 0x7fffffff: return "FILTER";
047b2264 2437 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
2438
2439 default:
2440 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
2441 {
b34976b6 2442 const char *result;
252b5132
RH
2443
2444 switch (elf_header.e_machine)
2445 {
2446 case EM_MIPS:
4fe85591 2447 case EM_MIPS_RS3_LE:
252b5132
RH
2448 result = get_mips_section_type_name (sh_type);
2449 break;
103f02d3
UD
2450 case EM_PARISC:
2451 result = get_parisc_section_type_name (sh_type);
2452 break;
4d6ed7c8
NC
2453 case EM_IA_64:
2454 result = get_ia64_section_type_name (sh_type);
2455 break;
252b5132
RH
2456 default:
2457 result = NULL;
2458 break;
2459 }
2460
2461 if (result != NULL)
2462 return result;
2463
c91d0dfb 2464 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
2465 }
2466 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
c91d0dfb 2467 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
252b5132 2468 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 2469 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132
RH
2470 else
2471 sprintf (buff, _("<unknown>: %x"), sh_type);
103f02d3 2472
252b5132
RH
2473 return buff;
2474 }
2475}
2476
2979dc34
JJ
2477#define OPTION_DEBUG_DUMP 512
2478
b34976b6 2479struct option options[] =
252b5132 2480{
b34976b6 2481 {"all", no_argument, 0, 'a'},
252b5132
RH
2482 {"file-header", no_argument, 0, 'h'},
2483 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
2484 {"headers", no_argument, 0, 'e'},
2485 {"histogram", no_argument, 0, 'I'},
2486 {"segments", no_argument, 0, 'l'},
2487 {"sections", no_argument, 0, 'S'},
252b5132 2488 {"section-headers", no_argument, 0, 'S'},
f5842774 2489 {"section-groups", no_argument, 0, 'g'},
b34976b6
AM
2490 {"symbols", no_argument, 0, 's'},
2491 {"syms", no_argument, 0, 's'},
2492 {"relocs", no_argument, 0, 'r'},
2493 {"notes", no_argument, 0, 'n'},
2494 {"dynamic", no_argument, 0, 'd'},
a952a375 2495 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
2496 {"version-info", no_argument, 0, 'V'},
2497 {"use-dynamic", no_argument, 0, 'D'},
b34976b6 2498 {"hex-dump", required_argument, 0, 'x'},
2979dc34 2499 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
4d6ed7c8 2500 {"unwind", no_argument, 0, 'u'},
252b5132
RH
2501#ifdef SUPPORT_DISASSEMBLY
2502 {"instruction-dump", required_argument, 0, 'i'},
2503#endif
2504
b34976b6
AM
2505 {"version", no_argument, 0, 'v'},
2506 {"wide", no_argument, 0, 'W'},
2507 {"help", no_argument, 0, 'H'},
2508 {0, no_argument, 0, 0}
252b5132
RH
2509};
2510
2511static void
d3ba0551 2512usage (void)
252b5132 2513{
8b53311e
NC
2514 fprintf (stdout, _("Usage: readelf <option(s)> elf-file(s)\n"));
2515 fprintf (stdout, _(" Display information about the contents of ELF format files\n"));
2516 fprintf (stdout, _(" Options are:\n\
2517 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
2518 -h --file-header Display the ELF file header\n\
2519 -l --program-headers Display the program headers\n\
2520 --segments An alias for --program-headers\n\
2521 -S --section-headers Display the sections' header\n\
2522 --sections An alias for --section-headers\n\
f5842774 2523 -g --section-groups Display the section groups\n\
8b53311e
NC
2524 -e --headers Equivalent to: -h -l -S\n\
2525 -s --syms Display the symbol table\n\
2526 --symbols An alias for --syms\n\
2527 -n --notes Display the core notes (if present)\n\
2528 -r --relocs Display the relocations (if present)\n\
2529 -u --unwind Display the unwind info (if present)\n\
b2d38a17 2530 -d --dynamic Display the dynamic section (if present)\n\
8b53311e
NC
2531 -V --version-info Display the version sections (if present)\n\
2532 -A --arch-specific Display architecture specific information (if any).\n\
2533 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
2534 -x --hex-dump=<number> Dump the contents of section <number>\n\
2979dc34
JJ
2535 -w[liaprmfFso] or\n\
2536 --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames,=str,=loc]\n\
8b53311e 2537 Display the contents of DWARF2 debug sections\n"));
252b5132 2538#ifdef SUPPORT_DISASSEMBLY
8b53311e
NC
2539 fprintf (stdout, _("\
2540 -i --instruction-dump=<number>\n\
2541 Disassemble the contents of section <number>\n"));
252b5132 2542#endif
8b53311e
NC
2543 fprintf (stdout, _("\
2544 -I --histogram Display histogram of bucket list lengths\n\
2545 -W --wide Allow output width to exceed 80 characters\n\
2546 -H --help Display this information\n\
2547 -v --version Display the version number of readelf\n"));
8ad3436c 2548 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
2549
2550 exit (0);
2551}
2552
2553static void
d3ba0551 2554request_dump (unsigned int section, int type)
252b5132
RH
2555{
2556 if (section >= num_dump_sects)
2557 {
b34976b6 2558 char *new_dump_sects;
252b5132 2559
d3ba0551 2560 new_dump_sects = calloc (section + 1, 1);
252b5132
RH
2561
2562 if (new_dump_sects == NULL)
2563 error (_("Out of memory allocating dump request table."));
2564 else
2565 {
2566 /* Copy current flag settings. */
2567 memcpy (new_dump_sects, dump_sects, num_dump_sects);
2568
2569 free (dump_sects);
2570
2571 dump_sects = new_dump_sects;
2572 num_dump_sects = section + 1;
2573 }
2574 }
2575
2576 if (dump_sects)
b34976b6 2577 dump_sects[section] |= type;
252b5132
RH
2578
2579 return;
2580}
2581
2582static void
d3ba0551 2583parse_args (int argc, char **argv)
252b5132
RH
2584{
2585 int c;
2586
2587 if (argc < 2)
2588 usage ();
2589
2590 while ((c = getopt_long
f5842774 2591 (argc, argv, "ersuahnldSDAIgw::x:i:vVWH", options, NULL)) != EOF)
252b5132 2592 {
b34976b6
AM
2593 char *cp;
2594 int section;
252b5132
RH
2595
2596 switch (c)
2597 {
2598 case 0:
2599 /* Long options. */
2600 break;
2601 case 'H':
2602 usage ();
2603 break;
2604
2605 case 'a':
b34976b6
AM
2606 do_syms++;
2607 do_reloc++;
2608 do_unwind++;
2609 do_dynamic++;
2610 do_header++;
2611 do_sections++;
f5842774 2612 do_section_groups++;
b34976b6
AM
2613 do_segments++;
2614 do_version++;
2615 do_histogram++;
2616 do_arch++;
2617 do_notes++;
252b5132 2618 break;
f5842774
L
2619 case 'g':
2620 do_section_groups++;
2621 break;
252b5132 2622 case 'e':
b34976b6
AM
2623 do_header++;
2624 do_sections++;
2625 do_segments++;
252b5132 2626 break;
a952a375 2627 case 'A':
b34976b6 2628 do_arch++;
a952a375 2629 break;
252b5132 2630 case 'D':
b34976b6 2631 do_using_dynamic++;
252b5132
RH
2632 break;
2633 case 'r':
b34976b6 2634 do_reloc++;
252b5132 2635 break;
4d6ed7c8 2636 case 'u':
b34976b6 2637 do_unwind++;
4d6ed7c8 2638 break;
252b5132 2639 case 'h':
b34976b6 2640 do_header++;
252b5132
RH
2641 break;
2642 case 'l':
b34976b6 2643 do_segments++;
252b5132
RH
2644 break;
2645 case 's':
b34976b6 2646 do_syms++;
252b5132
RH
2647 break;
2648 case 'S':
b34976b6 2649 do_sections++;
252b5132
RH
2650 break;
2651 case 'd':
b34976b6 2652 do_dynamic++;
252b5132 2653 break;
a952a375 2654 case 'I':
b34976b6 2655 do_histogram++;
a952a375 2656 break;
779fe533 2657 case 'n':
b34976b6 2658 do_notes++;
779fe533 2659 break;
252b5132 2660 case 'x':
b34976b6 2661 do_dump++;
252b5132 2662 section = strtoul (optarg, & cp, 0);
b34976b6 2663 if (! *cp && section >= 0)
252b5132
RH
2664 {
2665 request_dump (section, HEX_DUMP);
2666 break;
2667 }
2668 goto oops;
2669 case 'w':
b34976b6 2670 do_dump++;
252b5132
RH
2671 if (optarg == 0)
2672 do_debugging = 1;
2673 else
2674 {
f662939a 2675 unsigned int index = 0;
53c7db4b 2676
252b5132 2677 do_debugging = 0;
252b5132 2678
f662939a
NC
2679 while (optarg[index])
2680 switch (optarg[index++])
2681 {
2682 case 'i':
2683 case 'I':
2684 do_debug_info = 1;
2685 break;
2686
2687 case 'a':
2688 case 'A':
2689 do_debug_abbrevs = 1;
2690 break;
2691
2692 case 'l':
2693 case 'L':
2694 do_debug_lines = 1;
2695 break;
2696
2697 case 'p':
2698 case 'P':
2699 do_debug_pubnames = 1;
2700 break;
2701
2702 case 'r':
2703 case 'R':
2704 do_debug_aranges = 1;
2705 break;
2706
2707 case 'F':
2708 do_debug_frames_interp = 1;
2709 case 'f':
2710 do_debug_frames = 1;
2711 break;
2712
2713 case 'm':
2714 case 'M':
2715 do_debug_macinfo = 1;
2716 break;
2717
261a45ad
NC
2718 case 's':
2719 case 'S':
2720 do_debug_str = 1;
2721 break;
2722
a2f14207
DB
2723 case 'o':
2724 case 'O':
2725 do_debug_loc = 1;
2726 break;
53c7db4b 2727
f662939a 2728 default:
2c71103e 2729 warn (_("Unrecognized debug option '%s'\n"), optarg);
f662939a
NC
2730 break;
2731 }
252b5132
RH
2732 }
2733 break;
2979dc34 2734 case OPTION_DEBUG_DUMP:
b34976b6 2735 do_dump++;
2979dc34
JJ
2736 if (optarg == 0)
2737 do_debugging = 1;
2738 else
2739 {
c5b060ad 2740 static const char *debug_dump_opt[]
2979dc34
JJ
2741 = { "line", "info", "abbrev", "pubnames", "ranges",
2742 "macro", "frames", "frames-interp", "str", "loc", NULL };
2743 unsigned int index;
2744 const char *p;
2745
2746 do_debugging = 0;
2747
2748 p = optarg;
2749 while (*p)
2750 {
2751 for (index = 0; debug_dump_opt[index]; index++)
2752 {
2753 size_t len = strlen (debug_dump_opt[index]);
2754
2755 if (strncmp (p, debug_dump_opt[index], len) == 0
2756 && (p[len] == ',' || p[len] == '\0'))
2757 {
2758 switch (p[0])
2759 {
2760 case 'i':
2761 do_debug_info = 1;
2762 break;
2763
2764 case 'a':
2765 do_debug_abbrevs = 1;
2766 break;
2767
2768 case 'l':
2769 if (p[1] == 'i')
2770 do_debug_lines = 1;
2771 else
2772 do_debug_loc = 1;
2773 break;
2774
2775 case 'p':
2776 do_debug_pubnames = 1;
2777 break;
2778
2779 case 'r':
2780 do_debug_aranges = 1;
2781 break;
2782
2783 case 'f':
2784 if (len > 6)
2785 do_debug_frames_interp = 1;
2786 do_debug_frames = 1;
2787 break;
2788
2789 case 'm':
2790 do_debug_macinfo = 1;
2791 break;
2792
2793 case 's':
2794 do_debug_str = 1;
2795 break;
2796 }
2797
2798 p += len;
2799 break;
2800 }
2801 }
2802
2803 if (debug_dump_opt[index] == NULL)
2804 {
2805 warn (_("Unrecognized debug option '%s'\n"), p);
2806 p = strchr (p, ',');
2807 if (p == NULL)
2808 break;
2809 }
2810
2811 if (*p == ',')
2812 p++;
2813 }
2814 }
2815 break;
252b5132
RH
2816#ifdef SUPPORT_DISASSEMBLY
2817 case 'i':
b34976b6 2818 do_dump++;
252b5132 2819 section = strtoul (optarg, & cp, 0);
b34976b6 2820 if (! *cp && section >= 0)
252b5132
RH
2821 {
2822 request_dump (section, DISASS_DUMP);
2823 break;
2824 }
2825 goto oops;
2826#endif
2827 case 'v':
2828 print_version (program_name);
2829 break;
2830 case 'V':
b34976b6 2831 do_version++;
252b5132 2832 break;
d974e256 2833 case 'W':
b34976b6 2834 do_wide++;
d974e256 2835 break;
252b5132
RH
2836 default:
2837 oops:
2838 /* xgettext:c-format */
2839 error (_("Invalid option '-%c'\n"), c);
2840 /* Drop through. */
2841 case '?':
2842 usage ();
2843 }
2844 }
2845
4d6ed7c8 2846 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 2847 && !do_segments && !do_header && !do_dump && !do_version
f5842774
L
2848 && !do_histogram && !do_debugging && !do_arch && !do_notes
2849 && !do_section_groups)
252b5132
RH
2850 usage ();
2851 else if (argc < 3)
2852 {
2853 warn (_("Nothing to do.\n"));
2854 usage();
2855 }
2856}
2857
2858static const char *
d3ba0551 2859get_elf_class (unsigned int elf_class)
252b5132 2860{
b34976b6 2861 static char buff[32];
103f02d3 2862
252b5132
RH
2863 switch (elf_class)
2864 {
2865 case ELFCLASSNONE: return _("none");
e3c8793a
NC
2866 case ELFCLASS32: return "ELF32";
2867 case ELFCLASS64: return "ELF64";
ab5e7794 2868 default:
789be9f7 2869 sprintf (buff, _("<unknown: %x>"), elf_class);
ab5e7794 2870 return buff;
252b5132
RH
2871 }
2872}
2873
2874static const char *
d3ba0551 2875get_data_encoding (unsigned int encoding)
252b5132 2876{
b34976b6 2877 static char buff[32];
103f02d3 2878
252b5132
RH
2879 switch (encoding)
2880 {
2881 case ELFDATANONE: return _("none");
33c63f9d
CM
2882 case ELFDATA2LSB: return _("2's complement, little endian");
2883 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 2884 default:
789be9f7 2885 sprintf (buff, _("<unknown: %x>"), encoding);
ab5e7794 2886 return buff;
252b5132
RH
2887 }
2888}
2889
252b5132 2890/* Decode the data held in 'elf_header'. */
ee42cf8c 2891
252b5132 2892static int
d3ba0551 2893process_file_header (void)
252b5132 2894{
b34976b6
AM
2895 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
2896 || elf_header.e_ident[EI_MAG1] != ELFMAG1
2897 || elf_header.e_ident[EI_MAG2] != ELFMAG2
2898 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
2899 {
2900 error
2901 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
2902 return 0;
2903 }
2904
2905 if (do_header)
2906 {
2907 int i;
2908
2909 printf (_("ELF Header:\n"));
2910 printf (_(" Magic: "));
b34976b6
AM
2911 for (i = 0; i < EI_NIDENT; i++)
2912 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
2913 printf ("\n");
2914 printf (_(" Class: %s\n"),
b34976b6 2915 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 2916 printf (_(" Data: %s\n"),
b34976b6 2917 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 2918 printf (_(" Version: %d %s\n"),
b34976b6
AM
2919 elf_header.e_ident[EI_VERSION],
2920 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 2921 ? "(current)"
b34976b6 2922 : (elf_header.e_ident[EI_VERSION] != EV_NONE
789be9f7
ILT
2923 ? "<unknown: %lx>"
2924 : "")));
252b5132 2925 printf (_(" OS/ABI: %s\n"),
b34976b6 2926 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 2927 printf (_(" ABI Version: %d\n"),
b34976b6 2928 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
2929 printf (_(" Type: %s\n"),
2930 get_file_type (elf_header.e_type));
2931 printf (_(" Machine: %s\n"),
2932 get_machine_name (elf_header.e_machine));
2933 printf (_(" Version: 0x%lx\n"),
2934 (unsigned long) elf_header.e_version);
76da6bbe 2935
f7a99963
NC
2936 printf (_(" Entry point address: "));
2937 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
2938 printf (_("\n Start of program headers: "));
2939 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
2940 printf (_(" (bytes into file)\n Start of section headers: "));
2941 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
2942 printf (_(" (bytes into file)\n"));
76da6bbe 2943
252b5132
RH
2944 printf (_(" Flags: 0x%lx%s\n"),
2945 (unsigned long) elf_header.e_flags,
2946 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
2947 printf (_(" Size of this header: %ld (bytes)\n"),
2948 (long) elf_header.e_ehsize);
2949 printf (_(" Size of program headers: %ld (bytes)\n"),
2950 (long) elf_header.e_phentsize);
2951 printf (_(" Number of program headers: %ld\n"),
2952 (long) elf_header.e_phnum);
2953 printf (_(" Size of section headers: %ld (bytes)\n"),
2954 (long) elf_header.e_shentsize);
560f3c1c 2955 printf (_(" Number of section headers: %ld"),
252b5132 2956 (long) elf_header.e_shnum);
560f3c1c
AM
2957 if (section_headers != NULL && elf_header.e_shnum == 0)
2958 printf (" (%ld)", (long) section_headers[0].sh_size);
2959 putc ('\n', stdout);
2960 printf (_(" Section header string table index: %ld"),
252b5132 2961 (long) elf_header.e_shstrndx);
560f3c1c
AM
2962 if (section_headers != NULL && elf_header.e_shstrndx == SHN_XINDEX)
2963 printf (" (%ld)", (long) section_headers[0].sh_link);
2964 putc ('\n', stdout);
2965 }
2966
2967 if (section_headers != NULL)
2968 {
2969 if (elf_header.e_shnum == 0)
2970 elf_header.e_shnum = section_headers[0].sh_size;
2971 if (elf_header.e_shstrndx == SHN_XINDEX)
2972 elf_header.e_shstrndx = section_headers[0].sh_link;
2973 free (section_headers);
2974 section_headers = NULL;
252b5132 2975 }
103f02d3 2976
9ea033b2
NC
2977 return 1;
2978}
2979
252b5132 2980
9ea033b2 2981static int
d3ba0551 2982get_32bit_program_headers (FILE *file, Elf_Internal_Phdr *program_headers)
9ea033b2 2983{
b34976b6
AM
2984 Elf32_External_Phdr *phdrs;
2985 Elf32_External_Phdr *external;
2986 Elf_Internal_Phdr *internal;
2987 unsigned int i;
103f02d3 2988
d3ba0551
AM
2989 phdrs = get_data (NULL, file, elf_header.e_phoff,
2990 elf_header.e_phentsize * elf_header.e_phnum,
2991 _("program headers"));
a6e9f9df
AM
2992 if (!phdrs)
2993 return 0;
9ea033b2
NC
2994
2995 for (i = 0, internal = program_headers, external = phdrs;
2996 i < elf_header.e_phnum;
b34976b6 2997 i++, internal++, external++)
252b5132 2998 {
9ea033b2
NC
2999 internal->p_type = BYTE_GET (external->p_type);
3000 internal->p_offset = BYTE_GET (external->p_offset);
3001 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3002 internal->p_paddr = BYTE_GET (external->p_paddr);
3003 internal->p_filesz = BYTE_GET (external->p_filesz);
3004 internal->p_memsz = BYTE_GET (external->p_memsz);
3005 internal->p_flags = BYTE_GET (external->p_flags);
3006 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3007 }
3008
9ea033b2
NC
3009 free (phdrs);
3010
252b5132
RH
3011 return 1;
3012}
3013
9ea033b2 3014static int
d3ba0551 3015get_64bit_program_headers (FILE *file, Elf_Internal_Phdr *program_headers)
9ea033b2 3016{
b34976b6
AM
3017 Elf64_External_Phdr *phdrs;
3018 Elf64_External_Phdr *external;
3019 Elf_Internal_Phdr *internal;
3020 unsigned int i;
103f02d3 3021
d3ba0551
AM
3022 phdrs = get_data (NULL, file, elf_header.e_phoff,
3023 elf_header.e_phentsize * elf_header.e_phnum,
3024 _("program headers"));
a6e9f9df
AM
3025 if (!phdrs)
3026 return 0;
9ea033b2
NC
3027
3028 for (i = 0, internal = program_headers, external = phdrs;
3029 i < elf_header.e_phnum;
b34976b6 3030 i++, internal++, external++)
9ea033b2
NC
3031 {
3032 internal->p_type = BYTE_GET (external->p_type);
3033 internal->p_flags = BYTE_GET (external->p_flags);
3034 internal->p_offset = BYTE_GET8 (external->p_offset);
3035 internal->p_vaddr = BYTE_GET8 (external->p_vaddr);
3036 internal->p_paddr = BYTE_GET8 (external->p_paddr);
3037 internal->p_filesz = BYTE_GET8 (external->p_filesz);
3038 internal->p_memsz = BYTE_GET8 (external->p_memsz);
3039 internal->p_align = BYTE_GET8 (external->p_align);
3040 }
3041
3042 free (phdrs);
3043
3044 return 1;
3045}
252b5132 3046
d93f0186
NC
3047/* Returns 1 if the program headers were read into `program_headers'. */
3048
3049static int
d3ba0551 3050get_program_headers (FILE *file)
d93f0186
NC
3051{
3052 Elf_Internal_Phdr *phdrs;
3053
3054 /* Check cache of prior read. */
3055 if (program_headers != NULL)
3056 return 1;
3057
d3ba0551 3058 phdrs = malloc (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
d93f0186
NC
3059
3060 if (phdrs == NULL)
3061 {
3062 error (_("Out of memory\n"));
3063 return 0;
3064 }
3065
3066 if (is_32bit_elf
3067 ? get_32bit_program_headers (file, phdrs)
3068 : get_64bit_program_headers (file, phdrs))
3069 {
3070 program_headers = phdrs;
3071 return 1;
3072 }
3073
3074 free (phdrs);
3075 return 0;
3076}
3077
2f62977e
NC
3078/* Returns 1 if the program headers were loaded. */
3079
252b5132 3080static int
d3ba0551 3081process_program_headers (FILE *file)
252b5132 3082{
b34976b6
AM
3083 Elf_Internal_Phdr *segment;
3084 unsigned int i;
252b5132
RH
3085
3086 if (elf_header.e_phnum == 0)
3087 {
3088 if (do_segments)
3089 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3090 return 0;
252b5132
RH
3091 }
3092
3093 if (do_segments && !do_header)
3094 {
f7a99963
NC
3095 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3096 printf (_("Entry point "));
3097 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3098 printf (_("\nThere are %d program headers, starting at offset "),
3099 elf_header.e_phnum);
3100 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3101 printf ("\n");
252b5132
RH
3102 }
3103
d93f0186 3104 if (! get_program_headers (file))
252b5132 3105 return 0;
103f02d3 3106
252b5132
RH
3107 if (do_segments)
3108 {
3a1a2036
NC
3109 if (elf_header.e_phnum > 1)
3110 printf (_("\nProgram Headers:\n"));
3111 else
3112 printf (_("\nProgram Headers:\n"));
76da6bbe 3113
f7a99963
NC
3114 if (is_32bit_elf)
3115 printf
3116 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3117 else if (do_wide)
3118 printf
3119 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3120 else
3121 {
3122 printf
3123 (_(" Type Offset VirtAddr PhysAddr\n"));
3124 printf
3125 (_(" FileSiz MemSiz Flags Align\n"));
3126 }
252b5132
RH
3127 }
3128
252b5132 3129 dynamic_addr = 0;
1b228002 3130 dynamic_size = 0;
252b5132
RH
3131
3132 for (i = 0, segment = program_headers;
3133 i < elf_header.e_phnum;
b34976b6 3134 i++, segment++)
252b5132
RH
3135 {
3136 if (do_segments)
3137 {
103f02d3 3138 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3139
3140 if (is_32bit_elf)
3141 {
3142 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3143 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3144 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3145 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3146 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3147 printf ("%c%c%c ",
3148 (segment->p_flags & PF_R ? 'R' : ' '),
3149 (segment->p_flags & PF_W ? 'W' : ' '),
3150 (segment->p_flags & PF_X ? 'E' : ' '));
3151 printf ("%#lx", (unsigned long) segment->p_align);
3152 }
d974e256
JJ
3153 else if (do_wide)
3154 {
3155 if ((unsigned long) segment->p_offset == segment->p_offset)
3156 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3157 else
3158 {
3159 print_vma (segment->p_offset, FULL_HEX);
3160 putchar (' ');
3161 }
3162
3163 print_vma (segment->p_vaddr, FULL_HEX);
3164 putchar (' ');
3165 print_vma (segment->p_paddr, FULL_HEX);
3166 putchar (' ');
3167
3168 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3169 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3170 else
3171 {
3172 print_vma (segment->p_filesz, FULL_HEX);
3173 putchar (' ');
3174 }
3175
3176 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3177 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3178 else
3179 {
3180 print_vma (segment->p_offset, FULL_HEX);
3181 }
3182
3183 printf (" %c%c%c ",
3184 (segment->p_flags & PF_R ? 'R' : ' '),
3185 (segment->p_flags & PF_W ? 'W' : ' '),
3186 (segment->p_flags & PF_X ? 'E' : ' '));
3187
3188 if ((unsigned long) segment->p_align == segment->p_align)
3189 printf ("%#lx", (unsigned long) segment->p_align);
3190 else
3191 {
3192 print_vma (segment->p_align, PREFIX_HEX);
3193 }
3194 }
f7a99963
NC
3195 else
3196 {
3197 print_vma (segment->p_offset, FULL_HEX);
3198 putchar (' ');
3199 print_vma (segment->p_vaddr, FULL_HEX);
3200 putchar (' ');
3201 print_vma (segment->p_paddr, FULL_HEX);
3202 printf ("\n ");
3203 print_vma (segment->p_filesz, FULL_HEX);
3204 putchar (' ');
3205 print_vma (segment->p_memsz, FULL_HEX);
3206 printf (" %c%c%c ",
3207 (segment->p_flags & PF_R ? 'R' : ' '),
3208 (segment->p_flags & PF_W ? 'W' : ' '),
3209 (segment->p_flags & PF_X ? 'E' : ' '));
3210 print_vma (segment->p_align, HEX);
3211 }
252b5132
RH
3212 }
3213
3214 switch (segment->p_type)
3215 {
252b5132
RH
3216 case PT_DYNAMIC:
3217 if (dynamic_addr)
3218 error (_("more than one dynamic segment\n"));
3219
b2d38a17
NC
3220 /* Try to locate the .dynamic section. If there is
3221 a section header table, we can easily locate it. */
3222 if (section_headers != NULL)
3223 {
3224 Elf_Internal_Shdr *sec;
3225 unsigned int j;
3226
3227 for (j = 0, sec = section_headers;
3228 j < elf_header.e_shnum;
3229 j++, sec++)
3230 if (strcmp (SECTION_NAME (sec), ".dynamic") == 0)
3231 break;
3232
3233 if (j == elf_header.e_shnum || sec->sh_size == 0)
3234 {
3235 error (_("no .dynamic section in the dynamic segment"));
3236 break;
3237 }
3238
3239 dynamic_addr = sec->sh_offset;
3240 dynamic_size = sec->sh_size;
3241
3242 if (dynamic_addr < segment->p_offset
3243 || dynamic_addr > segment->p_offset + segment->p_filesz)
3244 warn (_("the .dynamic section is not contained within the dynamic segment"));
3245 else if (dynamic_addr > segment->p_offset)
3246 warn (_("the .dynamic section is not the first section in the dynamic segment."));
3247 }
3248 else
3249 {
3250 /* Otherwise, we can only assume that the .dynamic
3251 section is the first section in the DYNAMIC segment. */
3252 dynamic_addr = segment->p_offset;
3253 dynamic_size = segment->p_filesz;
3254 }
252b5132
RH
3255 break;
3256
3257 case PT_INTERP:
fb52b2f4
NC
3258 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3259 SEEK_SET))
252b5132
RH
3260 error (_("Unable to find program interpreter name\n"));
3261 else
3262 {
3263 program_interpreter[0] = 0;
3264 fscanf (file, "%63s", program_interpreter);
3265
3266 if (do_segments)
3267 printf (_("\n [Requesting program interpreter: %s]"),
3268 program_interpreter);
3269 }
3270 break;
3271 }
3272
3273 if (do_segments)
3274 putc ('\n', stdout);
3275 }
3276
252b5132
RH
3277 if (do_segments && section_headers != NULL)
3278 {
3279 printf (_("\n Section to Segment mapping:\n"));
3280 printf (_(" Segment Sections...\n"));
3281
3282 assert (string_table != NULL);
3283
3284 for (i = 0; i < elf_header.e_phnum; i++)
3285 {
9ad5cbcf 3286 unsigned int j;
b34976b6 3287 Elf_Internal_Shdr *section;
252b5132
RH
3288
3289 segment = program_headers + i;
3290 section = section_headers;
3291
3292 printf (" %2.2d ", i);
3293
b34976b6 3294 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132
RH
3295 {
3296 if (section->sh_size > 0
3297 /* Compare allocated sections by VMA, unallocated
3298 sections by file offset. */
3299 && (section->sh_flags & SHF_ALLOC
3300 ? (section->sh_addr >= segment->p_vaddr
3301 && section->sh_addr + section->sh_size
3302 <= segment->p_vaddr + segment->p_memsz)
b4c96d0d 3303 : ((bfd_vma) section->sh_offset >= segment->p_offset
252b5132
RH
3304 && (section->sh_offset + section->sh_size
3305 <= segment->p_offset + segment->p_filesz))))
3306 printf ("%s ", SECTION_NAME (section));
3307 }
3308
3309 putc ('\n',stdout);
3310 }
3311 }
3312
252b5132
RH
3313 return 1;
3314}
3315
3316
d93f0186
NC
3317/* Find the file offset corresponding to VMA by using the program headers. */
3318
3319static long
d3ba0551 3320offset_from_vma (FILE *file, bfd_vma vma, bfd_size_type size)
d93f0186
NC
3321{
3322 Elf_Internal_Phdr *seg;
3323
3324 if (! get_program_headers (file))
3325 {
3326 warn (_("Cannot interpret virtual addresses without program headers.\n"));
3327 return (long) vma;
3328 }
3329
3330 for (seg = program_headers;
3331 seg < program_headers + elf_header.e_phnum;
3332 ++seg)
3333 {
3334 if (seg->p_type != PT_LOAD)
3335 continue;
3336
3337 if (vma >= (seg->p_vaddr & -seg->p_align)
3338 && vma + size <= seg->p_vaddr + seg->p_filesz)
3339 return vma - seg->p_vaddr + seg->p_offset;
3340 }
3341
3342 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
3343 (long) vma);
3344 return (long) vma;
3345}
3346
3347
252b5132 3348static int
d3ba0551 3349get_32bit_section_headers (FILE *file, unsigned int num)
252b5132 3350{
b34976b6
AM
3351 Elf32_External_Shdr *shdrs;
3352 Elf_Internal_Shdr *internal;
3353 unsigned int i;
252b5132 3354
d3ba0551
AM
3355 shdrs = get_data (NULL, file, elf_header.e_shoff,
3356 elf_header.e_shentsize * num, _("section headers"));
a6e9f9df
AM
3357 if (!shdrs)
3358 return 0;
252b5132 3359
d3ba0551 3360 section_headers = malloc (num * sizeof (Elf_Internal_Shdr));
252b5132
RH
3361
3362 if (section_headers == NULL)
3363 {
3364 error (_("Out of memory\n"));
3365 return 0;
3366 }
3367
3368 for (i = 0, internal = section_headers;
560f3c1c 3369 i < num;
b34976b6 3370 i++, internal++)
252b5132
RH
3371 {
3372 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3373 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
3374 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3375 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3376 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3377 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3378 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3379 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3380 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3381 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
3382 }
3383
3384 free (shdrs);
3385
3386 return 1;
3387}
3388
9ea033b2 3389static int
d3ba0551 3390get_64bit_section_headers (FILE *file, unsigned int num)
9ea033b2 3391{
b34976b6
AM
3392 Elf64_External_Shdr *shdrs;
3393 Elf_Internal_Shdr *internal;
3394 unsigned int i;
9ea033b2 3395
d3ba0551
AM
3396 shdrs = get_data (NULL, file, elf_header.e_shoff,
3397 elf_header.e_shentsize * num, _("section headers"));
a6e9f9df
AM
3398 if (!shdrs)
3399 return 0;
9ea033b2 3400
d3ba0551 3401 section_headers = malloc (num * sizeof (Elf_Internal_Shdr));
9ea033b2
NC
3402
3403 if (section_headers == NULL)
3404 {
3405 error (_("Out of memory\n"));
3406 return 0;
3407 }
3408
3409 for (i = 0, internal = section_headers;
560f3c1c 3410 i < num;
b34976b6 3411 i++, internal++)
9ea033b2
NC
3412 {
3413 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3414 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
3415 internal->sh_flags = BYTE_GET8 (shdrs[i].sh_flags);
3416 internal->sh_addr = BYTE_GET8 (shdrs[i].sh_addr);
3417 internal->sh_size = BYTE_GET8 (shdrs[i].sh_size);
3418 internal->sh_entsize = BYTE_GET8 (shdrs[i].sh_entsize);
3419 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3420 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3421 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3422 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3423 }
3424
3425 free (shdrs);
3426
3427 return 1;
3428}
3429
252b5132 3430static Elf_Internal_Sym *
d3ba0551 3431get_32bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section)
252b5132 3432{
9ad5cbcf 3433 unsigned long number;
b34976b6 3434 Elf32_External_Sym *esyms;
9ad5cbcf 3435 Elf_External_Sym_Shndx *shndx;
b34976b6
AM
3436 Elf_Internal_Sym *isyms;
3437 Elf_Internal_Sym *psym;
3438 unsigned int j;
252b5132 3439
d3ba0551
AM
3440 esyms = get_data (NULL, file, section->sh_offset, section->sh_size,
3441 _("symbols"));
a6e9f9df
AM
3442 if (!esyms)
3443 return NULL;
252b5132 3444
9ad5cbcf
AM
3445 shndx = NULL;
3446 if (symtab_shndx_hdr != NULL
3447 && (symtab_shndx_hdr->sh_link
3448 == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
3449 {
d3ba0551
AM
3450 shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
3451 symtab_shndx_hdr->sh_size, _("symtab shndx"));
9ad5cbcf
AM
3452 if (!shndx)
3453 {
3454 free (esyms);
3455 return NULL;
3456 }
3457 }
3458
3459 number = section->sh_size / section->sh_entsize;
d3ba0551 3460 isyms = malloc (number * sizeof (Elf_Internal_Sym));
252b5132
RH
3461
3462 if (isyms == NULL)
3463 {
3464 error (_("Out of memory\n"));
9ad5cbcf
AM
3465 if (shndx)
3466 free (shndx);
252b5132 3467 free (esyms);
252b5132
RH
3468 return NULL;
3469 }
3470
3471 for (j = 0, psym = isyms;
3472 j < number;
b34976b6 3473 j++, psym++)
252b5132
RH
3474 {
3475 psym->st_name = BYTE_GET (esyms[j].st_name);
3476 psym->st_value = BYTE_GET (esyms[j].st_value);
3477 psym->st_size = BYTE_GET (esyms[j].st_size);
3478 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
9ad5cbcf
AM
3479 if (psym->st_shndx == SHN_XINDEX && shndx != NULL)
3480 psym->st_shndx
3481 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
252b5132
RH
3482 psym->st_info = BYTE_GET (esyms[j].st_info);
3483 psym->st_other = BYTE_GET (esyms[j].st_other);
3484 }
3485
9ad5cbcf
AM
3486 if (shndx)
3487 free (shndx);
252b5132
RH
3488 free (esyms);
3489
3490 return isyms;
3491}
3492
9ea033b2 3493static Elf_Internal_Sym *
d3ba0551 3494get_64bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section)
9ea033b2 3495{
9ad5cbcf 3496 unsigned long number;
b34976b6 3497 Elf64_External_Sym *esyms;
9ad5cbcf 3498 Elf_External_Sym_Shndx *shndx;
b34976b6
AM
3499 Elf_Internal_Sym *isyms;
3500 Elf_Internal_Sym *psym;
3501 unsigned int j;
9ea033b2 3502
d3ba0551
AM
3503 esyms = get_data (NULL, file, section->sh_offset, section->sh_size,
3504 _("symbols"));
a6e9f9df
AM
3505 if (!esyms)
3506 return NULL;
9ea033b2 3507
9ad5cbcf
AM
3508 shndx = NULL;
3509 if (symtab_shndx_hdr != NULL
3510 && (symtab_shndx_hdr->sh_link
3511 == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
3512 {
d3ba0551
AM
3513 shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
3514 symtab_shndx_hdr->sh_size, _("symtab shndx"));
9ad5cbcf
AM
3515 if (!shndx)
3516 {
3517 free (esyms);
3518 return NULL;
3519 }
3520 }
3521
3522 number = section->sh_size / section->sh_entsize;
d3ba0551 3523 isyms = malloc (number * sizeof (Elf_Internal_Sym));
9ea033b2
NC
3524
3525 if (isyms == NULL)
3526 {
3527 error (_("Out of memory\n"));
9ad5cbcf
AM
3528 if (shndx)
3529 free (shndx);
9ea033b2 3530 free (esyms);
9ea033b2
NC
3531 return NULL;
3532 }
3533
3534 for (j = 0, psym = isyms;
3535 j < number;
b34976b6 3536 j++, psym++)
9ea033b2
NC
3537 {
3538 psym->st_name = BYTE_GET (esyms[j].st_name);
3539 psym->st_info = BYTE_GET (esyms[j].st_info);
3540 psym->st_other = BYTE_GET (esyms[j].st_other);
3541 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
9ad5cbcf
AM
3542 if (psym->st_shndx == SHN_XINDEX && shndx != NULL)
3543 psym->st_shndx
3544 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
9ea033b2
NC
3545 psym->st_value = BYTE_GET8 (esyms[j].st_value);
3546 psym->st_size = BYTE_GET8 (esyms[j].st_size);
3547 }
3548
9ad5cbcf
AM
3549 if (shndx)
3550 free (shndx);
9ea033b2
NC
3551 free (esyms);
3552
3553 return isyms;
3554}
3555
d1133906 3556static const char *
d3ba0551 3557get_elf_section_flags (bfd_vma sh_flags)
d1133906 3558{
b34976b6 3559 static char buff[32];
d1133906 3560
b34976b6 3561 *buff = 0;
76da6bbe 3562
d1133906
NC
3563 while (sh_flags)
3564 {
3565 bfd_vma flag;
3566
3567 flag = sh_flags & - sh_flags;
3568 sh_flags &= ~ flag;
76da6bbe 3569
d1133906
NC
3570 switch (flag)
3571 {
b34976b6
AM
3572 case SHF_WRITE: strcat (buff, "W"); break;
3573 case SHF_ALLOC: strcat (buff, "A"); break;
3574 case SHF_EXECINSTR: strcat (buff, "X"); break;
3575 case SHF_MERGE: strcat (buff, "M"); break;
3576 case SHF_STRINGS: strcat (buff, "S"); break;
3577 case SHF_INFO_LINK: strcat (buff, "I"); break;
3578 case SHF_LINK_ORDER: strcat (buff, "L"); break;
d1133906 3579 case SHF_OS_NONCONFORMING: strcat (buff, "O"); break;
b34976b6 3580 case SHF_GROUP: strcat (buff, "G"); break;
13ae64f3 3581 case SHF_TLS: strcat (buff, "T"); break;
76da6bbe 3582
d1133906
NC
3583 default:
3584 if (flag & SHF_MASKOS)
3585 {
3586 strcat (buff, "o");
3587 sh_flags &= ~ SHF_MASKOS;
3588 }
3589 else if (flag & SHF_MASKPROC)
3590 {
3591 strcat (buff, "p");
3592 sh_flags &= ~ SHF_MASKPROC;
3593 }
3594 else
3595 strcat (buff, "x");
3596 break;
3597 }
3598 }
76da6bbe 3599
d1133906
NC
3600 return buff;
3601}
3602
252b5132 3603static int
d3ba0551 3604process_section_headers (FILE *file)
252b5132 3605{
b34976b6
AM
3606 Elf_Internal_Shdr *section;
3607 unsigned int i;
252b5132
RH
3608
3609 section_headers = NULL;
3610
3611 if (elf_header.e_shnum == 0)
3612 {
3613 if (do_sections)
3614 printf (_("\nThere are no sections in this file.\n"));
3615
3616 return 1;
3617 }
3618
3619 if (do_sections && !do_header)
9ea033b2 3620 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
3621 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
3622
9ea033b2
NC
3623 if (is_32bit_elf)
3624 {
560f3c1c 3625 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
3626 return 0;
3627 }
560f3c1c 3628 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
3629 return 0;
3630
3631 /* Read in the string table, so that we have names to display. */
9ad5cbcf 3632 section = SECTION_HEADER (elf_header.e_shstrndx);
252b5132
RH
3633
3634 if (section->sh_size != 0)
3635 {
d3ba0551
AM
3636 string_table = get_data (NULL, file, section->sh_offset,
3637 section->sh_size, _("string table"));
d40ac9bd 3638
96c223ce
NC
3639 if (string_table == NULL)
3640 return 0;
0de14b54 3641
d40ac9bd 3642 string_table_length = section->sh_size;
252b5132
RH
3643 }
3644
3645 /* Scan the sections for the dynamic symbol table
e3c8793a 3646 and dynamic string table and debug sections. */
252b5132
RH
3647 dynamic_symbols = NULL;
3648 dynamic_strings = NULL;
3649 dynamic_syminfo = NULL;
f1ef08cb 3650 symtab_shndx_hdr = NULL;
103f02d3 3651
252b5132
RH
3652 for (i = 0, section = section_headers;
3653 i < elf_header.e_shnum;
b34976b6 3654 i++, section++)
252b5132 3655 {
b34976b6 3656 char *name = SECTION_NAME (section);
252b5132
RH
3657
3658 if (section->sh_type == SHT_DYNSYM)
3659 {
3660 if (dynamic_symbols != NULL)
3661 {
3662 error (_("File contains multiple dynamic symbol tables\n"));
3663 continue;
3664 }
3665
19936277 3666 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 3667 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
3668 }
3669 else if (section->sh_type == SHT_STRTAB
3670 && strcmp (name, ".dynstr") == 0)
3671 {
3672 if (dynamic_strings != NULL)
3673 {
3674 error (_("File contains multiple dynamic string tables\n"));
3675 continue;
3676 }
3677
d3ba0551
AM
3678 dynamic_strings = get_data (NULL, file, section->sh_offset,
3679 section->sh_size, _("dynamic strings"));
252b5132 3680 }
9ad5cbcf
AM
3681 else if (section->sh_type == SHT_SYMTAB_SHNDX)
3682 {
3683 if (symtab_shndx_hdr != NULL)
3684 {
3685 error (_("File contains multiple symtab shndx tables\n"));
3686 continue;
3687 }
3688 symtab_shndx_hdr = section;
3689 }
252b5132 3690 else if ((do_debugging || do_debug_info || do_debug_abbrevs
31b6fca6 3691 || do_debug_lines || do_debug_pubnames || do_debug_aranges
a2f14207
DB
3692 || do_debug_frames || do_debug_macinfo || do_debug_str
3693 || do_debug_loc)
252b5132
RH
3694 && strncmp (name, ".debug_", 7) == 0)
3695 {
3696 name += 7;
3697
3698 if (do_debugging
3699 || (do_debug_info && (strcmp (name, "info") == 0))
3700 || (do_debug_abbrevs && (strcmp (name, "abbrev") == 0))
3701 || (do_debug_lines && (strcmp (name, "line") == 0))
3702 || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
3703 || (do_debug_aranges && (strcmp (name, "aranges") == 0))
c47d488e 3704 || (do_debug_frames && (strcmp (name, "frame") == 0))
e0c60db2 3705 || (do_debug_macinfo && (strcmp (name, "macinfo") == 0))
261a45ad 3706 || (do_debug_str && (strcmp (name, "str") == 0))
a2f14207 3707 || (do_debug_loc && (strcmp (name, "loc") == 0))
252b5132
RH
3708 )
3709 request_dump (i, DEBUG_DUMP);
3710 }
09fd7e38
JM
3711 /* linkonce section to be combined with .debug_info at link time. */
3712 else if ((do_debugging || do_debug_info)
3713 && strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
3714 request_dump (i, DEBUG_DUMP);
c47d488e
DD
3715 else if (do_debug_frames && strcmp (name, ".eh_frame") == 0)
3716 request_dump (i, DEBUG_DUMP);
252b5132
RH
3717 }
3718
3719 if (! do_sections)
3720 return 1;
3721
3a1a2036
NC
3722 if (elf_header.e_shnum > 1)
3723 printf (_("\nSection Headers:\n"));
3724 else
3725 printf (_("\nSection Header:\n"));
76da6bbe 3726
f7a99963
NC
3727 if (is_32bit_elf)
3728 printf
3729 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
d974e256
JJ
3730 else if (do_wide)
3731 printf
3732 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
f7a99963
NC
3733 else
3734 {
3735 printf (_(" [Nr] Name Type Address Offset\n"));
3736 printf (_(" Size EntSize Flags Link Info Align\n"));
3737 }
252b5132
RH
3738
3739 for (i = 0, section = section_headers;
3740 i < elf_header.e_shnum;
b34976b6 3741 i++, section++)
252b5132 3742 {
9ad5cbcf
AM
3743 printf (" [%2u] %-17.17s %-15.15s ",
3744 SECTION_HEADER_NUM (i),
252b5132
RH
3745 SECTION_NAME (section),
3746 get_section_type_name (section->sh_type));
3747
f7a99963
NC
3748 if (is_32bit_elf)
3749 {
3750 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 3751
f7a99963
NC
3752 printf ( " %6.6lx %6.6lx %2.2lx",
3753 (unsigned long) section->sh_offset,
3754 (unsigned long) section->sh_size,
3755 (unsigned long) section->sh_entsize);
d1133906
NC
3756
3757 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 3758
f2da459f 3759 printf ("%2ld %3lu %2ld\n",
f7a99963
NC
3760 (unsigned long) section->sh_link,
3761 (unsigned long) section->sh_info,
3762 (unsigned long) section->sh_addralign);
3763 }
d974e256
JJ
3764 else if (do_wide)
3765 {
3766 print_vma (section->sh_addr, LONG_HEX);
3767
3768 if ((long) section->sh_offset == section->sh_offset)
3769 printf (" %6.6lx", (unsigned long) section->sh_offset);
3770 else
3771 {
3772 putchar (' ');
3773 print_vma (section->sh_offset, LONG_HEX);
3774 }
3775
3776 if ((unsigned long) section->sh_size == section->sh_size)
3777 printf (" %6.6lx", (unsigned long) section->sh_size);
3778 else
3779 {
3780 putchar (' ');
3781 print_vma (section->sh_size, LONG_HEX);
3782 }
3783
3784 if ((unsigned long) section->sh_entsize == section->sh_entsize)
3785 printf (" %2.2lx", (unsigned long) section->sh_entsize);
3786 else
3787 {
3788 putchar (' ');
3789 print_vma (section->sh_entsize, LONG_HEX);
3790 }
3791
3792 printf (" %3s ", get_elf_section_flags (section->sh_flags));
3793
f2da459f 3794 printf ("%2ld %3lu ",
d974e256
JJ
3795 (unsigned long) section->sh_link,
3796 (unsigned long) section->sh_info);
3797
3798 if ((unsigned long) section->sh_addralign == section->sh_addralign)
3799 printf ("%2ld\n", (unsigned long) section->sh_addralign);
3800 else
3801 {
3802 print_vma (section->sh_addralign, DEC);
3803 putchar ('\n');
3804 }
3805 }
f7a99963
NC
3806 else
3807 {
3808 putchar (' ');
3809 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
3810 if ((long) section->sh_offset == section->sh_offset)
3811 printf (" %8.8lx", (unsigned long) section->sh_offset);
3812 else
3813 {
3814 printf (" ");
3815 print_vma (section->sh_offset, LONG_HEX);
3816 }
f7a99963
NC
3817 printf ("\n ");
3818 print_vma (section->sh_size, LONG_HEX);
3819 printf (" ");
3820 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 3821
d1133906 3822 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 3823
f2da459f 3824 printf (" %2ld %3lu %ld\n",
f7a99963
NC
3825 (unsigned long) section->sh_link,
3826 (unsigned long) section->sh_info,
3827 (unsigned long) section->sh_addralign);
3828 }
252b5132
RH
3829 }
3830
e3c8793a
NC
3831 printf (_("Key to Flags:\n\
3832 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
3833 I (info), L (link order), G (group), x (unknown)\n\
3834 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
d1133906 3835
252b5132
RH
3836 return 1;
3837}
3838
f5842774
L
3839static const char *
3840get_group_flags (unsigned int flags)
3841{
3842 static char buff[32];
3843 switch (flags)
3844 {
3845 case GRP_COMDAT:
3846 return "COMDAT";
3847
3848 default:
3849 sprintf (buff, _("[<unknown>: 0x%x]"), flags);
3850 break;
3851 }
3852 return buff;
3853}
3854
3855static int
3856process_section_groups (FILE *file)
3857{
3858 Elf_Internal_Shdr *section;
3859 unsigned int i;
e4b17d5c 3860 struct group *group;
f5842774
L
3861
3862 if (elf_header.e_shnum == 0)
3863 {
3864 if (do_section_groups)
3865 printf (_("\nThere are no section groups in this file.\n"));
3866
3867 return 1;
3868 }
3869
3870 if (section_headers == NULL)
3871 {
3872 error (_("Section headers are not available!\n"));
3873 abort ();
3874 }
3875
e4b17d5c
L
3876 section_headers_groups = calloc (elf_header.e_shnum,
3877 sizeof (struct group *));
3878
3879 if (section_headers_groups == NULL)
3880 {
3881 error (_("Out of memory\n"));
3882 return 0;
3883 }
3884
f5842774
L
3885 /* Scan the sections for the group section. */
3886 for (i = 0, section = section_headers;
3887 i < elf_header.e_shnum;
3888 i++, section++)
e4b17d5c
L
3889 if (section->sh_type == SHT_GROUP)
3890 group_count++;
3891
3892 section_groups = calloc (group_count, sizeof (struct group));
3893
3894 if (section_groups == NULL)
3895 {
3896 error (_("Out of memory\n"));
3897 return 0;
3898 }
3899
3900 for (i = 0, section = section_headers, group = section_groups;
3901 i < elf_header.e_shnum;
3902 i++, section++)
f5842774
L
3903 {
3904 if (section->sh_type == SHT_GROUP)
3905 {
3906 char *name = SECTION_NAME (section);
3907 char *group_name, *strtab, *start, *indices;
3908 unsigned int entry, j, size;
3909 Elf_Internal_Sym *sym;
3910 Elf_Internal_Shdr *symtab_sec, *strtab_sec, *sec;
3911 Elf_Internal_Sym *symtab;
3912
3913 /* Get the symbol table. */
3914 symtab_sec = SECTION_HEADER (section->sh_link);
3915 if (symtab_sec->sh_type != SHT_SYMTAB)
3916 {
3917 error (_("Bad sh_link in group section `%s'\n"), name);
3918 continue;
3919 }
3920 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
3921
3922 sym = symtab + section->sh_info;
3923
3924 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
3925 {
3926 bfd_vma sec_index = SECTION_HEADER_INDEX (sym->st_shndx);
3927 if (sec_index == 0)
3928 {
3929 error (_("Bad sh_info in group section `%s'\n"), name);
3930 continue;
3931 }
ba2685cc 3932
f5842774
L
3933 group_name = SECTION_NAME (section_headers + sec_index);
3934 strtab = NULL;
3935 }
3936 else
3937 {
3938 /* Get the string table. */
3939 strtab_sec = SECTION_HEADER (symtab_sec->sh_link);
3940 strtab = get_data (NULL, file, strtab_sec->sh_offset,
3941 strtab_sec->sh_size,
3942 _("string table"));
3943
3944 group_name = strtab + sym->st_name;
3945 }
3946
3947 start = get_data (NULL, file, section->sh_offset,
3948 section->sh_size, _("section data"));
3949
3950 indices = start;
3951 size = (section->sh_size / section->sh_entsize) - 1;
3952 entry = byte_get (indices, 4);
3953 indices += 4;
e4b17d5c
L
3954
3955 if (do_section_groups)
3956 {
3957 printf ("\n%s group section `%s' [%s] contains %u sections:\n",
ba2685cc
AM
3958 get_group_flags (entry), name, group_name, size);
3959
e4b17d5c
L
3960 printf (_(" [Index] Name\n"));
3961 }
3962
3963 group->group_index = i;
3964
f5842774
L
3965 for (j = 0; j < size; j++)
3966 {
e4b17d5c
L
3967 struct group_list *g;
3968
f5842774
L
3969 entry = byte_get (indices, 4);
3970 indices += 4;
3971
e4b17d5c
L
3972 if (section_headers_groups [SECTION_HEADER_INDEX (entry)]
3973 != NULL)
3974 {
3975 error (_("section [%5u] already in group section [%5u]\n"),
3976 entry, section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
3977 continue;
3978 }
3979
3980 section_headers_groups [SECTION_HEADER_INDEX (entry)]
3981 = group;
3982
3983 if (do_section_groups)
3984 {
3985 sec = SECTION_HEADER (entry);
3986 printf (" [%5u] %s\n",
3987 entry, SECTION_NAME (sec));
ba2685cc
AM
3988 }
3989
e4b17d5c
L
3990 g = xmalloc (sizeof (struct group_list));
3991 g->section_index = entry;
3992 g->next = group->root;
3993 group->root = g;
f5842774
L
3994 }
3995
3996 if (strtab)
3997 free (strtab);
3998 if (start)
3999 free (start);
e4b17d5c
L
4000
4001 group++;
f5842774
L
4002 }
4003 }
4004
4005 return 1;
4006}
4007
566b0d53
L
4008struct
4009{
4010 const char *name;
4011 int reloc;
4012 int size;
4013 int rela;
4014} dynamic_relocations [] =
4015{
4016 { "REL", DT_REL, DT_RELSZ, FALSE },
4017 { "RELA", DT_RELA, DT_RELASZ, TRUE },
4018 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
4019};
4020
252b5132
RH
4021/* Process the reloc section. */
4022static int
d3ba0551 4023process_relocs (FILE *file)
252b5132 4024{
b34976b6
AM
4025 unsigned long rel_size;
4026 unsigned long rel_offset;
252b5132
RH
4027
4028
4029 if (!do_reloc)
4030 return 1;
4031
4032 if (do_using_dynamic)
4033 {
566b0d53
L
4034 int is_rela;
4035 const char *name;
4036 int has_dynamic_reloc;
4037 unsigned int i;
0de14b54 4038
566b0d53 4039 has_dynamic_reloc = 0;
252b5132 4040
566b0d53 4041 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 4042 {
566b0d53
L
4043 is_rela = dynamic_relocations [i].rela;
4044 name = dynamic_relocations [i].name;
4045 rel_size = dynamic_info [dynamic_relocations [i].size];
4046 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 4047
566b0d53
L
4048 has_dynamic_reloc |= rel_size;
4049
4050 if (is_rela == UNKNOWN)
aa903cfb 4051 {
566b0d53
L
4052 if (dynamic_relocations [i].reloc == DT_JMPREL)
4053 switch (dynamic_info[DT_PLTREL])
4054 {
4055 case DT_REL:
4056 is_rela = FALSE;
4057 break;
4058 case DT_RELA:
4059 is_rela = TRUE;
4060 break;
4061 }
aa903cfb 4062 }
252b5132 4063
566b0d53
L
4064 if (rel_size)
4065 {
4066 printf
4067 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
4068 name, rel_offset, rel_size);
252b5132 4069
d93f0186
NC
4070 dump_relocations (file,
4071 offset_from_vma (file, rel_offset, rel_size),
4072 rel_size,
566b0d53
L
4073 dynamic_symbols, num_dynamic_syms,
4074 dynamic_strings, is_rela);
4075 }
252b5132 4076 }
566b0d53
L
4077
4078 if (! has_dynamic_reloc)
252b5132
RH
4079 printf (_("\nThere are no dynamic relocations in this file.\n"));
4080 }
4081 else
4082 {
b34976b6
AM
4083 Elf_Internal_Shdr *section;
4084 unsigned long i;
4085 int found = 0;
252b5132
RH
4086
4087 for (i = 0, section = section_headers;
4088 i < elf_header.e_shnum;
b34976b6 4089 i++, section++)
252b5132
RH
4090 {
4091 if ( section->sh_type != SHT_RELA
4092 && section->sh_type != SHT_REL)
4093 continue;
4094
4095 rel_offset = section->sh_offset;
4096 rel_size = section->sh_size;
4097
4098 if (rel_size)
4099 {
b34976b6
AM
4100 Elf_Internal_Shdr *strsec;
4101 Elf_Internal_Sym *symtab;
4102 char *strtab;
4103 int is_rela;
4104 unsigned long nsyms;
103f02d3 4105
252b5132
RH
4106 printf (_("\nRelocation section "));
4107
4108 if (string_table == NULL)
19936277 4109 printf ("%d", section->sh_name);
252b5132 4110 else
3a1a2036 4111 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
4112
4113 printf (_(" at offset 0x%lx contains %lu entries:\n"),
4114 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
4115
af3fc3bc
AM
4116 symtab = NULL;
4117 strtab = NULL;
4118 nsyms = 0;
4119 if (section->sh_link)
4120 {
b34976b6 4121 Elf_Internal_Shdr *symsec;
252b5132 4122
9ad5cbcf 4123 symsec = SECTION_HEADER (section->sh_link);
af3fc3bc 4124 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 4125 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 4126
af3fc3bc
AM
4127 if (symtab == NULL)
4128 continue;
252b5132 4129
9ad5cbcf 4130 strsec = SECTION_HEADER (symsec->sh_link);
103f02d3 4131
d3ba0551
AM
4132 strtab = get_data (NULL, file, strsec->sh_offset,
4133 strsec->sh_size, _("string table"));
af3fc3bc 4134 }
aa903cfb 4135 is_rela = section->sh_type == SHT_RELA;
252b5132 4136
af3fc3bc
AM
4137 dump_relocations (file, rel_offset, rel_size,
4138 symtab, nsyms, strtab, is_rela);
252b5132 4139
af3fc3bc
AM
4140 if (strtab)
4141 free (strtab);
4142 if (symtab)
4143 free (symtab);
252b5132
RH
4144
4145 found = 1;
4146 }
4147 }
4148
4149 if (! found)
4150 printf (_("\nThere are no relocations in this file.\n"));
4151 }
4152
4153 return 1;
4154}
4155
4d6ed7c8
NC
4156#include "unwind-ia64.h"
4157
4158/* An absolute address consists of a section and an offset. If the
4159 section is NULL, the offset itself is the address, otherwise, the
4160 address equals to LOAD_ADDRESS(section) + offset. */
4161
4162struct absaddr
4163 {
4164 unsigned short section;
4165 bfd_vma offset;
4166 };
4167
4168struct unw_aux_info
4169 {
4170 struct unw_table_entry
4171 {
b34976b6
AM
4172 struct absaddr start;
4173 struct absaddr end;
4174 struct absaddr info;
4d6ed7c8 4175 }
b34976b6
AM
4176 *table; /* Unwind table. */
4177 unsigned long table_len; /* Length of unwind table. */
4178 unsigned char *info; /* Unwind info. */
4179 unsigned long info_size; /* Size of unwind info. */
4180 bfd_vma info_addr; /* starting address of unwind info. */
4181 bfd_vma seg_base; /* Starting address of segment. */
4182 Elf_Internal_Sym *symtab; /* The symbol table. */
4183 unsigned long nsyms; /* Number of symbols. */
4184 char *strtab; /* The string table. */
4185 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
4186 };
4187
4d6ed7c8 4188static void
d3ba0551
AM
4189find_symbol_for_address (struct unw_aux_info *aux,
4190 struct absaddr addr,
4191 const char **symname,
4192 bfd_vma *offset)
4d6ed7c8 4193{
d3ba0551 4194 bfd_vma dist = 0x100000;
4d6ed7c8
NC
4195 Elf_Internal_Sym *sym, *best = NULL;
4196 unsigned long i;
4197
4198 for (i = 0, sym = aux->symtab; i < aux->nsyms; ++i, ++sym)
4199 {
4200 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
4201 && sym->st_name != 0
4202 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
4203 && addr.offset >= sym->st_value
4204 && addr.offset - sym->st_value < dist)
4205 {
4206 best = sym;
4207 dist = addr.offset - sym->st_value;
4208 if (!dist)
4209 break;
4210 }
4211 }
4212 if (best)
4213 {
4214 *symname = (best->st_name >= aux->strtab_size
4215 ? "<corrupt>" : aux->strtab + best->st_name);
4216 *offset = dist;
4217 return;
4218 }
4219 *symname = NULL;
4220 *offset = addr.offset;
4221}
4222
4223static void
d3ba0551 4224dump_ia64_unwind (struct unw_aux_info *aux)
4d6ed7c8
NC
4225{
4226 bfd_vma addr_size;
b34976b6 4227 struct unw_table_entry *tp;
4d6ed7c8 4228 int in_body;
7036c0e1 4229
4d6ed7c8
NC
4230 addr_size = is_32bit_elf ? 4 : 8;
4231
4232 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
4233 {
4234 bfd_vma stamp;
4235 bfd_vma offset;
b34976b6
AM
4236 const unsigned char *dp;
4237 const unsigned char *head;
4238 const char *procname;
4d6ed7c8
NC
4239
4240 find_symbol_for_address (aux, tp->start, &procname, &offset);
4241
4242 fputs ("\n<", stdout);
4243
4244 if (procname)
4245 {
4246 fputs (procname, stdout);
4247
4248 if (offset)
4249 printf ("+%lx", (unsigned long) offset);
4250 }
4251
4252 fputs (">: [", stdout);
4253 print_vma (tp->start.offset, PREFIX_HEX);
4254 fputc ('-', stdout);
4255 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 4256 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
4257 (unsigned long) (tp->info.offset - aux->seg_base));
4258
4259 head = aux->info + (tp->info.offset - aux->info_addr);
4260 stamp = BYTE_GET8 ((unsigned char *) head);
4261
86f55779 4262 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
4263 (unsigned) UNW_VER (stamp),
4264 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
4265 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
4266 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
4267 (unsigned long) (addr_size * UNW_LENGTH (stamp)));
4268
4269 if (UNW_VER (stamp) != 1)
4270 {
4271 printf ("\tUnknown version.\n");
4272 continue;
4273 }
4274
4275 in_body = 0;
4276 for (dp = head + 8; dp < head + 8 + addr_size * UNW_LENGTH (stamp);)
4277 dp = unw_decode (dp, in_body, & in_body);
4278 }
4279}
4280
4281static int
d3ba0551
AM
4282slurp_ia64_unwind_table (FILE *file,
4283 struct unw_aux_info *aux,
4284 Elf_Internal_Shdr *sec)
4d6ed7c8
NC
4285{
4286 unsigned long size, addr_size, nrelas, i;
d93f0186 4287 Elf_Internal_Phdr *seg;
4d6ed7c8 4288 struct unw_table_entry *tep;
c8286bd1 4289 Elf_Internal_Shdr *relsec;
4d6ed7c8
NC
4290 Elf_Internal_Rela *rela, *rp;
4291 unsigned char *table, *tp;
4292 Elf_Internal_Sym *sym;
4293 const char *relname;
4d6ed7c8
NC
4294
4295 addr_size = is_32bit_elf ? 4 : 8;
4296
4297 /* First, find the starting address of the segment that includes
4298 this section: */
4299
4300 if (elf_header.e_phnum)
4301 {
d93f0186 4302 if (! get_program_headers (file))
4d6ed7c8 4303 return 0;
4d6ed7c8 4304
d93f0186
NC
4305 for (seg = program_headers;
4306 seg < program_headers + elf_header.e_phnum;
4307 ++seg)
4d6ed7c8
NC
4308 {
4309 if (seg->p_type != PT_LOAD)
4310 continue;
4311
4312 if (sec->sh_addr >= seg->p_vaddr
4313 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
4314 {
4315 aux->seg_base = seg->p_vaddr;
4316 break;
4317 }
4318 }
4d6ed7c8
NC
4319 }
4320
4321 /* Second, build the unwind table from the contents of the unwind section: */
4322 size = sec->sh_size;
d3ba0551 4323 table = get_data (NULL, file, sec->sh_offset, size, _("unwind table"));
a6e9f9df
AM
4324 if (!table)
4325 return 0;
4d6ed7c8
NC
4326
4327 tep = aux->table = xmalloc (size / (3 * addr_size) * sizeof (aux->table[0]));
b34976b6 4328 for (tp = table; tp < table + size; tp += 3 * addr_size, ++tep)
4d6ed7c8
NC
4329 {
4330 tep->start.section = SHN_UNDEF;
4331 tep->end.section = SHN_UNDEF;
4332 tep->info.section = SHN_UNDEF;
4333 if (is_32bit_elf)
4334 {
4335 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
4336 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
4337 tep->info.offset = byte_get ((unsigned char *) tp + 8, 4);
4338 }
4339 else
4340 {
4341 tep->start.offset = BYTE_GET8 ((unsigned char *) tp + 0);
4342 tep->end.offset = BYTE_GET8 ((unsigned char *) tp + 8);
4343 tep->info.offset = BYTE_GET8 ((unsigned char *) tp + 16);
4344 }
4345 tep->start.offset += aux->seg_base;
4346 tep->end.offset += aux->seg_base;
4347 tep->info.offset += aux->seg_base;
4348 }
4349 free (table);
4350
4351 /* Third, apply any relocations to the unwind table: */
4352
4353 for (relsec = section_headers;
4354 relsec < section_headers + elf_header.e_shnum;
4355 ++relsec)
4356 {
4357 if (relsec->sh_type != SHT_RELA
9ad5cbcf 4358 || SECTION_HEADER (relsec->sh_info) != sec)
4d6ed7c8
NC
4359 continue;
4360
4361 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
4362 & rela, & nrelas))
4363 return 0;
4364
4365 for (rp = rela; rp < rela + nrelas; ++rp)
4366 {
4367 if (is_32bit_elf)
4368 {
4369 relname = elf_ia64_reloc_type (ELF32_R_TYPE (rp->r_info));
4370 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
4371
4372 if (ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
4373 {
e5fb9629 4374 warn (_("Skipping unexpected symbol type %u\n"),
4d6ed7c8
NC
4375 ELF32_ST_TYPE (sym->st_info));
4376 continue;
4377 }
4378 }
4379 else
4380 {
4381 relname = elf_ia64_reloc_type (ELF64_R_TYPE (rp->r_info));
4382 sym = aux->symtab + ELF64_R_SYM (rp->r_info);
4383
4384 if (ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
4385 {
e5fb9629 4386 warn (_("Skipping unexpected symbol type %u\n"),
4d6ed7c8
NC
4387 ELF64_ST_TYPE (sym->st_info));
4388 continue;
4389 }
4390 }
4391
4392 if (strncmp (relname, "R_IA64_SEGREL", 13) != 0)
4393 {
e5fb9629 4394 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
4395 continue;
4396 }
4397
4398 i = rp->r_offset / (3 * addr_size);
4399
4400 switch (rp->r_offset/addr_size % 3)
4401 {
4402 case 0:
4403 aux->table[i].start.section = sym->st_shndx;
4404 aux->table[i].start.offset += rp->r_addend;
4405 break;
4406 case 1:
4407 aux->table[i].end.section = sym->st_shndx;
4408 aux->table[i].end.offset += rp->r_addend;
4409 break;
4410 case 2:
4411 aux->table[i].info.section = sym->st_shndx;
4412 aux->table[i].info.offset += rp->r_addend;
4413 break;
4414 default:
4415 break;
4416 }
4417 }
4418
4419 free (rela);
4420 }
4421
4422 aux->table_len = size / (3 * addr_size);
4423 return 1;
4424}
4425
4426static int
d3ba0551 4427process_unwind (FILE *file)
4d6ed7c8 4428{
c8286bd1 4429 Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
579f31ac 4430 unsigned long i, addr_size, unwcount = 0, unwstart = 0;
4d6ed7c8
NC
4431 struct unw_aux_info aux;
4432
e58d53af
L
4433 if (!do_unwind)
4434 return 1;
4435
f1467e33
L
4436 if (elf_header.e_machine != EM_IA_64)
4437 {
4438 printf (_("\nThere are no unwind sections in this file.\n"));
4439 return 1;
4440 }
4441
4d6ed7c8
NC
4442 memset (& aux, 0, sizeof (aux));
4443
4444 addr_size = is_32bit_elf ? 4 : 8;
4445
4d6ed7c8
NC
4446 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
4447 {
4448 if (sec->sh_type == SHT_SYMTAB)
4449 {
4450 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 4451 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 4452
9ad5cbcf 4453 strsec = SECTION_HEADER (sec->sh_link);
4d6ed7c8 4454 aux.strtab_size = strsec->sh_size;
d3ba0551
AM
4455 aux.strtab = get_data (NULL, file, strsec->sh_offset,
4456 aux.strtab_size, _("string table"));
4d6ed7c8
NC
4457 }
4458 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
4459 unwcount++;
4460 }
4461
4462 if (!unwcount)
4463 printf (_("\nThere are no unwind sections in this file.\n"));
4464
4465 while (unwcount-- > 0)
4466 {
4467 char *suffix;
4468 size_t len, len2;
4469
4470 for (i = unwstart, sec = section_headers + unwstart;
4471 i < elf_header.e_shnum; ++i, ++sec)
4472 if (sec->sh_type == SHT_IA_64_UNWIND)
4473 {
4474 unwsec = sec;
4475 break;
4476 }
4477
4478 unwstart = i + 1;
4479 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
4480
e4b17d5c
L
4481 if ((unwsec->sh_flags & SHF_GROUP) != 0)
4482 {
4483 /* We need to find which section group it is in. */
4484 struct group_list *g = section_headers_groups [i]->root;
4485
4486 for (; g != NULL; g = g->next)
4487 {
4488 sec = SECTION_HEADER (g->section_index);
4489 if (strcmp (SECTION_NAME (sec),
4490 ELF_STRING_ia64_unwind_info) == 0)
4491 break;
4492 }
4493
4494 if (g == NULL)
4495 i = elf_header.e_shnum;
4496 }
4497 else if (strncmp (SECTION_NAME (unwsec),
4498 ELF_STRING_ia64_unwind_once, len) == 0)
579f31ac
JJ
4499 {
4500 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO */
4501 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
4502 suffix = SECTION_NAME (unwsec) + len;
4503 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
4504 ++i, ++sec)
4505 if (strncmp (SECTION_NAME (sec),
4506 ELF_STRING_ia64_unwind_info_once, len2) == 0
4507 && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
4508 break;
4509 }
4510 else
4511 {
4512 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
4513 .IA_64.unwind or BAR -> .IA_64.unwind_info */
4514 len = sizeof (ELF_STRING_ia64_unwind) - 1;
4515 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
4516 suffix = "";
4517 if (strncmp (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind,
4518 len) == 0)
4519 suffix = SECTION_NAME (unwsec) + len;
4520 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
4521 ++i, ++sec)
4522 if (strncmp (SECTION_NAME (sec),
4523 ELF_STRING_ia64_unwind_info, len2) == 0
4524 && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
4525 break;
4526 }
4527
4528 if (i == elf_header.e_shnum)
4529 {
4530 printf (_("\nCould not find unwind info section for "));
4531
4532 if (string_table == NULL)
4533 printf ("%d", unwsec->sh_name);
4534 else
3a1a2036 4535 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
4536 }
4537 else
4d6ed7c8
NC
4538 {
4539 aux.info_size = sec->sh_size;
4540 aux.info_addr = sec->sh_addr;
d3ba0551
AM
4541 aux.info = get_data (NULL, file, sec->sh_offset, aux.info_size,
4542 _("unwind info"));
4d6ed7c8 4543
579f31ac 4544 printf (_("\nUnwind section "));
4d6ed7c8 4545
579f31ac
JJ
4546 if (string_table == NULL)
4547 printf ("%d", unwsec->sh_name);
4548 else
3a1a2036 4549 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 4550
579f31ac 4551 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 4552 (unsigned long) unwsec->sh_offset,
579f31ac 4553 (unsigned long) (unwsec->sh_size / (3 * addr_size)));
4d6ed7c8 4554
579f31ac 4555 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 4556
579f31ac
JJ
4557 if (aux.table_len > 0)
4558 dump_ia64_unwind (& aux);
4559
4560 if (aux.table)
4561 free ((char *) aux.table);
4562 if (aux.info)
4563 free ((char *) aux.info);
4564 aux.table = NULL;
4565 aux.info = NULL;
4566 }
4d6ed7c8 4567 }
4d6ed7c8 4568
4d6ed7c8
NC
4569 if (aux.symtab)
4570 free (aux.symtab);
4571 if (aux.strtab)
4572 free ((char *) aux.strtab);
4573
4574 return 1;
4575}
4576
252b5132 4577static void
b2d38a17 4578dynamic_section_mips_val (Elf_Internal_Dyn *entry)
252b5132
RH
4579{
4580 switch (entry->d_tag)
4581 {
4582 case DT_MIPS_FLAGS:
4583 if (entry->d_un.d_val == 0)
4584 printf ("NONE\n");
4585 else
4586 {
4587 static const char * opts[] =
4588 {
4589 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
4590 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
4591 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
4592 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
4593 "RLD_ORDER_SAFE"
4594 };
4595 unsigned int cnt;
4596 int first = 1;
b34976b6 4597 for (cnt = 0; cnt < NUM_ELEM (opts); ++cnt)
252b5132
RH
4598 if (entry->d_un.d_val & (1 << cnt))
4599 {
4600 printf ("%s%s", first ? "" : " ", opts[cnt]);
4601 first = 0;
4602 }
4603 puts ("");
4604 }
4605 break;
103f02d3 4606
252b5132
RH
4607 case DT_MIPS_IVERSION:
4608 if (dynamic_strings != NULL)
4609 printf ("Interface Version: %s\n",
4610 dynamic_strings + entry->d_un.d_val);
4611 else
4612 printf ("%ld\n", (long) entry->d_un.d_ptr);
4613 break;
103f02d3 4614
252b5132
RH
4615 case DT_MIPS_TIME_STAMP:
4616 {
4617 char timebuf[20];
b34976b6 4618 struct tm *tmp;
50da7a9c 4619
252b5132 4620 time_t time = entry->d_un.d_val;
50da7a9c
NC
4621 tmp = gmtime (&time);
4622 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
4623 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
4624 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
4625 printf ("Time Stamp: %s\n", timebuf);
4626 }
4627 break;
103f02d3 4628
252b5132
RH
4629 case DT_MIPS_RLD_VERSION:
4630 case DT_MIPS_LOCAL_GOTNO:
4631 case DT_MIPS_CONFLICTNO:
4632 case DT_MIPS_LIBLISTNO:
4633 case DT_MIPS_SYMTABNO:
4634 case DT_MIPS_UNREFEXTNO:
4635 case DT_MIPS_HIPAGENO:
4636 case DT_MIPS_DELTA_CLASS_NO:
4637 case DT_MIPS_DELTA_INSTANCE_NO:
4638 case DT_MIPS_DELTA_RELOC_NO:
4639 case DT_MIPS_DELTA_SYM_NO:
4640 case DT_MIPS_DELTA_CLASSSYM_NO:
4641 case DT_MIPS_COMPACT_SIZE:
4642 printf ("%ld\n", (long) entry->d_un.d_ptr);
4643 break;
103f02d3
UD
4644
4645 default:
4646 printf ("%#lx\n", (long) entry->d_un.d_ptr);
4647 }
4648}
4649
4650
4651static void
b2d38a17 4652dynamic_section_parisc_val (Elf_Internal_Dyn *entry)
103f02d3
UD
4653{
4654 switch (entry->d_tag)
4655 {
4656 case DT_HP_DLD_FLAGS:
4657 {
4658 static struct
4659 {
4660 long int bit;
b34976b6 4661 const char *str;
5e220199
NC
4662 }
4663 flags[] =
4664 {
4665 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
4666 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
4667 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
4668 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
4669 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
4670 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
4671 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
4672 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
4673 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
4674 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
4675 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" }
4676 };
103f02d3 4677 int first = 1;
5e220199 4678 size_t cnt;
f7a99963 4679 bfd_vma val = entry->d_un.d_val;
103f02d3
UD
4680
4681 for (cnt = 0; cnt < sizeof (flags) / sizeof (flags[0]); ++cnt)
4682 if (val & flags[cnt].bit)
30800947
NC
4683 {
4684 if (! first)
4685 putchar (' ');
4686 fputs (flags[cnt].str, stdout);
4687 first = 0;
4688 val ^= flags[cnt].bit;
4689 }
76da6bbe 4690
103f02d3 4691 if (val != 0 || first)
f7a99963
NC
4692 {
4693 if (! first)
4694 putchar (' ');
4695 print_vma (val, HEX);
4696 }
103f02d3
UD
4697 }
4698 break;
76da6bbe 4699
252b5132 4700 default:
f7a99963
NC
4701 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
4702 break;
252b5132 4703 }
35b1837e 4704 putchar ('\n');
252b5132
RH
4705}
4706
ecc51f48 4707static void
b2d38a17 4708dynamic_section_ia64_val (Elf_Internal_Dyn *entry)
ecc51f48
NC
4709{
4710 switch (entry->d_tag)
4711 {
0de14b54 4712 case DT_IA_64_PLT_RESERVE:
bdf4d63a 4713 /* First 3 slots reserved. */
ecc51f48
NC
4714 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
4715 printf (" -- ");
4716 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
4717 break;
4718
4719 default:
4720 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
4721 break;
ecc51f48 4722 }
bdf4d63a 4723 putchar ('\n');
ecc51f48
NC
4724}
4725
252b5132 4726static int
b2d38a17 4727get_32bit_dynamic_section (FILE *file)
252b5132 4728{
fb514b26 4729 Elf32_External_Dyn *edyn, *ext;
b34976b6 4730 Elf_Internal_Dyn *entry;
103f02d3 4731
d3ba0551 4732 edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
b2d38a17 4733 _("dynamic section"));
a6e9f9df
AM
4734 if (!edyn)
4735 return 0;
103f02d3 4736
ba2685cc
AM
4737/* SGI's ELF has more than one section in the DYNAMIC segment, and we
4738 might not have the luxury of section headers. Look for the DT_NULL
4739 terminator to determine the number of entries. */
4740 for (ext = edyn, dynamic_nent = 0;
4741 (char *) ext < (char *) edyn + dynamic_size;
4742 ext++)
4743 {
4744 dynamic_nent++;
4745 if (BYTE_GET (ext->d_tag) == DT_NULL)
4746 break;
4747 }
252b5132 4748
ba2685cc 4749 dynamic_section = malloc (dynamic_nent * sizeof (*entry));
b2d38a17 4750 if (dynamic_section == NULL)
252b5132 4751 {
9ea033b2
NC
4752 error (_("Out of memory\n"));
4753 free (edyn);
4754 return 0;
4755 }
252b5132 4756
fb514b26 4757 for (ext = edyn, entry = dynamic_section;
ba2685cc 4758 entry < dynamic_section + dynamic_nent;
fb514b26 4759 ext++, entry++)
9ea033b2 4760 {
fb514b26
AM
4761 entry->d_tag = BYTE_GET (ext->d_tag);
4762 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
4763 }
4764
9ea033b2
NC
4765 free (edyn);
4766
4767 return 1;
4768}
4769
4770static int
b2d38a17 4771get_64bit_dynamic_section (FILE *file)
9ea033b2 4772{
fb514b26 4773 Elf64_External_Dyn *edyn, *ext;
b34976b6 4774 Elf_Internal_Dyn *entry;
103f02d3 4775
d3ba0551 4776 edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
b2d38a17 4777 _("dynamic section"));
a6e9f9df
AM
4778 if (!edyn)
4779 return 0;
103f02d3 4780
ba2685cc
AM
4781/* SGI's ELF has more than one section in the DYNAMIC segment, and we
4782 might not have the luxury of section headers. Look for the DT_NULL
4783 terminator to determine the number of entries. */
4784 for (ext = edyn, dynamic_nent = 0;
4785 (char *) ext < (char *) edyn + dynamic_size;
4786 ext++)
4787 {
4788 dynamic_nent++;
4789 if (BYTE_GET8 (ext->d_tag) == DT_NULL)
4790 break;
4791 }
252b5132 4792
ba2685cc 4793 dynamic_section = malloc (dynamic_nent * sizeof (*entry));
b2d38a17 4794 if (dynamic_section == NULL)
252b5132
RH
4795 {
4796 error (_("Out of memory\n"));
4797 free (edyn);
4798 return 0;
4799 }
4800
fb514b26 4801 for (ext = edyn, entry = dynamic_section;
ba2685cc 4802 entry < dynamic_section + dynamic_nent;
fb514b26 4803 ext++, entry++)
252b5132 4804 {
fb514b26
AM
4805 entry->d_tag = BYTE_GET8 (ext->d_tag);
4806 entry->d_un.d_val = BYTE_GET8 (ext->d_un.d_val);
252b5132
RH
4807 }
4808
4809 free (edyn);
4810
9ea033b2
NC
4811 return 1;
4812}
4813
d1133906 4814static const char *
d3ba0551 4815get_dynamic_flags (bfd_vma flags)
d1133906 4816{
b34976b6 4817 static char buff[128];
13ae64f3
JJ
4818 char *p = buff;
4819
4820 *p = '\0';
d1133906
NC
4821 while (flags)
4822 {
4823 bfd_vma flag;
4824
4825 flag = flags & - flags;
4826 flags &= ~ flag;
4827
13ae64f3
JJ
4828 if (p != buff)
4829 *p++ = ' ';
4830
d1133906
NC
4831 switch (flag)
4832 {
b34976b6
AM
4833 case DF_ORIGIN: strcpy (p, "ORIGIN"); break;
4834 case DF_SYMBOLIC: strcpy (p, "SYMBOLIC"); break;
4835 case DF_TEXTREL: strcpy (p, "TEXTREL"); break;
4836 case DF_BIND_NOW: strcpy (p, "BIND_NOW"); break;
4837 case DF_STATIC_TLS: strcpy (p, "STATIC_TLS"); break;
4838 default: strcpy (p, "unknown"); break;
d1133906 4839 }
13ae64f3
JJ
4840
4841 p = strchr (p, '\0');
d1133906 4842 }
305c7206 4843 return buff;
d1133906
NC
4844}
4845
b2d38a17
NC
4846/* Parse and display the contents of the dynamic section. */
4847
9ea033b2 4848static int
b2d38a17 4849process_dynamic_section (FILE *file)
9ea033b2 4850{
b34976b6 4851 Elf_Internal_Dyn *entry;
9ea033b2
NC
4852
4853 if (dynamic_size == 0)
4854 {
4855 if (do_dynamic)
b2d38a17 4856 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
4857
4858 return 1;
4859 }
4860
4861 if (is_32bit_elf)
4862 {
b2d38a17 4863 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
4864 return 0;
4865 }
b2d38a17 4866 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
4867 return 0;
4868
252b5132
RH
4869 /* Find the appropriate symbol table. */
4870 if (dynamic_symbols == NULL)
4871 {
86dba8ee
AM
4872 for (entry = dynamic_section;
4873 entry < dynamic_section + dynamic_nent;
4874 ++entry)
252b5132 4875 {
c8286bd1 4876 Elf_Internal_Shdr section;
252b5132
RH
4877
4878 if (entry->d_tag != DT_SYMTAB)
4879 continue;
4880
4881 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
4882
4883 /* Since we do not know how big the symbol table is,
4884 we default to reading in the entire file (!) and
4885 processing that. This is overkill, I know, but it
e3c8793a 4886 should work. */
d93f0186 4887 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 4888
fb52b2f4
NC
4889 if (archive_file_offset != 0)
4890 section.sh_size = archive_file_size - section.sh_offset;
4891 else
4892 {
4893 if (fseek (file, 0, SEEK_END))
4894 error (_("Unable to seek to end of file!"));
4895
4896 section.sh_size = ftell (file) - section.sh_offset;
4897 }
252b5132 4898
9ea033b2 4899 if (is_32bit_elf)
9ad5cbcf 4900 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 4901 else
9ad5cbcf 4902 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 4903
9ad5cbcf 4904 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 4905 if (num_dynamic_syms < 1)
252b5132
RH
4906 {
4907 error (_("Unable to determine the number of symbols to load\n"));
4908 continue;
4909 }
4910
9ad5cbcf 4911 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
4912 }
4913 }
4914
4915 /* Similarly find a string table. */
4916 if (dynamic_strings == NULL)
4917 {
86dba8ee
AM
4918 for (entry = dynamic_section;
4919 entry < dynamic_section + dynamic_nent;
4920 ++entry)
252b5132
RH
4921 {
4922 unsigned long offset;
b34976b6 4923 long str_tab_len;
252b5132
RH
4924
4925 if (entry->d_tag != DT_STRTAB)
4926 continue;
4927
4928 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
4929
4930 /* Since we do not know how big the string table is,
4931 we default to reading in the entire file (!) and
4932 processing that. This is overkill, I know, but it
e3c8793a 4933 should work. */
252b5132 4934
d93f0186 4935 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
4936
4937 if (archive_file_offset != 0)
4938 str_tab_len = archive_file_size - offset;
4939 else
4940 {
4941 if (fseek (file, 0, SEEK_END))
4942 error (_("Unable to seek to end of file\n"));
4943 str_tab_len = ftell (file) - offset;
4944 }
252b5132
RH
4945
4946 if (str_tab_len < 1)
4947 {
4948 error
4949 (_("Unable to determine the length of the dynamic string table\n"));
4950 continue;
4951 }
4952
d3ba0551
AM
4953 dynamic_strings = get_data (NULL, file, offset, str_tab_len,
4954 _("dynamic string table"));
252b5132
RH
4955 break;
4956 }
4957 }
4958
4959 /* And find the syminfo section if available. */
4960 if (dynamic_syminfo == NULL)
4961 {
3e8bba36 4962 unsigned long syminsz = 0;
252b5132 4963
86dba8ee
AM
4964 for (entry = dynamic_section;
4965 entry < dynamic_section + dynamic_nent;
4966 ++entry)
252b5132
RH
4967 {
4968 if (entry->d_tag == DT_SYMINENT)
4969 {
4970 /* Note: these braces are necessary to avoid a syntax
4971 error from the SunOS4 C compiler. */
4972 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
4973 }
4974 else if (entry->d_tag == DT_SYMINSZ)
4975 syminsz = entry->d_un.d_val;
4976 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
4977 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
4978 syminsz);
252b5132
RH
4979 }
4980
4981 if (dynamic_syminfo_offset != 0 && syminsz != 0)
4982 {
86dba8ee 4983 Elf_External_Syminfo *extsyminfo, *extsym;
b34976b6 4984 Elf_Internal_Syminfo *syminfo;
252b5132
RH
4985
4986 /* There is a syminfo section. Read the data. */
d3ba0551
AM
4987 extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, syminsz,
4988 _("symbol information"));
a6e9f9df
AM
4989 if (!extsyminfo)
4990 return 0;
252b5132 4991
d3ba0551 4992 dynamic_syminfo = malloc (syminsz);
252b5132
RH
4993 if (dynamic_syminfo == NULL)
4994 {
4995 error (_("Out of memory\n"));
4996 return 0;
4997 }
4998
4999 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
5000 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
5001 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
5002 ++syminfo, ++extsym)
252b5132 5003 {
86dba8ee
AM
5004 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
5005 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
5006 }
5007
5008 free (extsyminfo);
5009 }
5010 }
5011
5012 if (do_dynamic && dynamic_addr)
86dba8ee
AM
5013 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
5014 dynamic_addr, dynamic_nent);
252b5132
RH
5015 if (do_dynamic)
5016 printf (_(" Tag Type Name/Value\n"));
5017
86dba8ee
AM
5018 for (entry = dynamic_section;
5019 entry < dynamic_section + dynamic_nent;
5020 entry++)
252b5132
RH
5021 {
5022 if (do_dynamic)
f7a99963 5023 {
b34976b6 5024 const char *dtype;
e699b9ff 5025
f7a99963
NC
5026 putchar (' ');
5027 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
5028 dtype = get_dynamic_type (entry->d_tag);
5029 printf (" (%s)%*s", dtype,
5030 ((is_32bit_elf ? 27 : 19)
5031 - (int) strlen (dtype)),
f7a99963
NC
5032 " ");
5033 }
252b5132
RH
5034
5035 switch (entry->d_tag)
5036 {
d1133906
NC
5037 case DT_FLAGS:
5038 if (do_dynamic)
13ae64f3 5039 puts (get_dynamic_flags (entry->d_un.d_val));
d1133906 5040 break;
76da6bbe 5041
252b5132
RH
5042 case DT_AUXILIARY:
5043 case DT_FILTER:
019148e4
L
5044 case DT_CONFIG:
5045 case DT_DEPAUDIT:
5046 case DT_AUDIT:
252b5132
RH
5047 if (do_dynamic)
5048 {
019148e4 5049 switch (entry->d_tag)
b34976b6 5050 {
019148e4
L
5051 case DT_AUXILIARY:
5052 printf (_("Auxiliary library"));
5053 break;
5054
5055 case DT_FILTER:
5056 printf (_("Filter library"));
5057 break;
5058
b34976b6 5059 case DT_CONFIG:
019148e4
L
5060 printf (_("Configuration file"));
5061 break;
5062
5063 case DT_DEPAUDIT:
5064 printf (_("Dependency audit library"));
5065 break;
5066
5067 case DT_AUDIT:
5068 printf (_("Audit library"));
5069 break;
5070 }
252b5132
RH
5071
5072 if (dynamic_strings)
5073 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
5074 else
f7a99963
NC
5075 {
5076 printf (": ");
5077 print_vma (entry->d_un.d_val, PREFIX_HEX);
5078 putchar ('\n');
5079 }
252b5132
RH
5080 }
5081 break;
5082
dcefbbbd 5083 case DT_FEATURE:
252b5132
RH
5084 if (do_dynamic)
5085 {
5086 printf (_("Flags:"));
86f55779 5087
252b5132
RH
5088 if (entry->d_un.d_val == 0)
5089 printf (_(" None\n"));
5090 else
5091 {
5092 unsigned long int val = entry->d_un.d_val;
86f55779 5093
252b5132
RH
5094 if (val & DTF_1_PARINIT)
5095 {
5096 printf (" PARINIT");
5097 val ^= DTF_1_PARINIT;
5098 }
dcefbbbd
L
5099 if (val & DTF_1_CONFEXP)
5100 {
5101 printf (" CONFEXP");
5102 val ^= DTF_1_CONFEXP;
5103 }
252b5132
RH
5104 if (val != 0)
5105 printf (" %lx", val);
5106 puts ("");
5107 }
5108 }
5109 break;
5110
5111 case DT_POSFLAG_1:
5112 if (do_dynamic)
5113 {
5114 printf (_("Flags:"));
86f55779 5115
252b5132
RH
5116 if (entry->d_un.d_val == 0)
5117 printf (_(" None\n"));
5118 else
5119 {
5120 unsigned long int val = entry->d_un.d_val;
86f55779 5121
252b5132
RH
5122 if (val & DF_P1_LAZYLOAD)
5123 {
5124 printf (" LAZYLOAD");
5125 val ^= DF_P1_LAZYLOAD;
5126 }
5127 if (val & DF_P1_GROUPPERM)
5128 {
5129 printf (" GROUPPERM");
5130 val ^= DF_P1_GROUPPERM;
5131 }
5132 if (val != 0)
5133 printf (" %lx", val);
5134 puts ("");
5135 }
5136 }
5137 break;
5138
5139 case DT_FLAGS_1:
5140 if (do_dynamic)
5141 {
5142 printf (_("Flags:"));
5143 if (entry->d_un.d_val == 0)
5144 printf (_(" None\n"));
5145 else
5146 {
5147 unsigned long int val = entry->d_un.d_val;
86f55779 5148
252b5132
RH
5149 if (val & DF_1_NOW)
5150 {
5151 printf (" NOW");
5152 val ^= DF_1_NOW;
5153 }
5154 if (val & DF_1_GLOBAL)
5155 {
5156 printf (" GLOBAL");
5157 val ^= DF_1_GLOBAL;
5158 }
5159 if (val & DF_1_GROUP)
5160 {
5161 printf (" GROUP");
5162 val ^= DF_1_GROUP;
5163 }
5164 if (val & DF_1_NODELETE)
5165 {
5166 printf (" NODELETE");
5167 val ^= DF_1_NODELETE;
5168 }
5169 if (val & DF_1_LOADFLTR)
5170 {
5171 printf (" LOADFLTR");
5172 val ^= DF_1_LOADFLTR;
5173 }
5174 if (val & DF_1_INITFIRST)
5175 {
5176 printf (" INITFIRST");
5177 val ^= DF_1_INITFIRST;
5178 }
5179 if (val & DF_1_NOOPEN)
5180 {
5181 printf (" NOOPEN");
5182 val ^= DF_1_NOOPEN;
5183 }
5184 if (val & DF_1_ORIGIN)
5185 {
5186 printf (" ORIGIN");
5187 val ^= DF_1_ORIGIN;
5188 }
5189 if (val & DF_1_DIRECT)
5190 {
5191 printf (" DIRECT");
5192 val ^= DF_1_DIRECT;
5193 }
5194 if (val & DF_1_TRANS)
5195 {
5196 printf (" TRANS");
5197 val ^= DF_1_TRANS;
5198 }
5199 if (val & DF_1_INTERPOSE)
5200 {
5201 printf (" INTERPOSE");
5202 val ^= DF_1_INTERPOSE;
5203 }
f7db6139 5204 if (val & DF_1_NODEFLIB)
dcefbbbd 5205 {
f7db6139
L
5206 printf (" NODEFLIB");
5207 val ^= DF_1_NODEFLIB;
dcefbbbd
L
5208 }
5209 if (val & DF_1_NODUMP)
5210 {
5211 printf (" NODUMP");
5212 val ^= DF_1_NODUMP;
5213 }
5214 if (val & DF_1_CONLFAT)
5215 {
5216 printf (" CONLFAT");
5217 val ^= DF_1_CONLFAT;
5218 }
252b5132
RH
5219 if (val != 0)
5220 printf (" %lx", val);
5221 puts ("");
5222 }
5223 }
5224 break;
5225
5226 case DT_PLTREL:
566b0d53 5227 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
5228 if (do_dynamic)
5229 puts (get_dynamic_type (entry->d_un.d_val));
5230 break;
5231
5232 case DT_NULL :
5233 case DT_NEEDED :
5234 case DT_PLTGOT :
5235 case DT_HASH :
5236 case DT_STRTAB :
5237 case DT_SYMTAB :
5238 case DT_RELA :
5239 case DT_INIT :
5240 case DT_FINI :
5241 case DT_SONAME :
5242 case DT_RPATH :
5243 case DT_SYMBOLIC:
5244 case DT_REL :
5245 case DT_DEBUG :
5246 case DT_TEXTREL :
5247 case DT_JMPREL :
019148e4 5248 case DT_RUNPATH :
252b5132
RH
5249 dynamic_info[entry->d_tag] = entry->d_un.d_val;
5250
5251 if (do_dynamic)
5252 {
b34976b6 5253 char *name;
252b5132
RH
5254
5255 if (dynamic_strings == NULL)
5256 name = NULL;
5257 else
5258 name = dynamic_strings + entry->d_un.d_val;
5259
5260 if (name)
5261 {
5262 switch (entry->d_tag)
5263 {
5264 case DT_NEEDED:
5265 printf (_("Shared library: [%s]"), name);
5266
f7a99963
NC
5267 if (strcmp (name, program_interpreter) == 0)
5268 printf (_(" program interpreter"));
252b5132
RH
5269 break;
5270
5271 case DT_SONAME:
f7a99963 5272 printf (_("Library soname: [%s]"), name);
252b5132
RH
5273 break;
5274
5275 case DT_RPATH:
f7a99963 5276 printf (_("Library rpath: [%s]"), name);
252b5132
RH
5277 break;
5278
019148e4
L
5279 case DT_RUNPATH:
5280 printf (_("Library runpath: [%s]"), name);
5281 break;
5282
252b5132 5283 default:
f7a99963
NC
5284 print_vma (entry->d_un.d_val, PREFIX_HEX);
5285 break;
252b5132
RH
5286 }
5287 }
5288 else
f7a99963
NC
5289 print_vma (entry->d_un.d_val, PREFIX_HEX);
5290
5291 putchar ('\n');
252b5132
RH
5292 }
5293 break;
5294
5295 case DT_PLTRELSZ:
5296 case DT_RELASZ :
5297 case DT_STRSZ :
5298 case DT_RELSZ :
5299 case DT_RELAENT :
5300 case DT_SYMENT :
5301 case DT_RELENT :
566b0d53 5302 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
5303 case DT_PLTPADSZ:
5304 case DT_MOVEENT :
5305 case DT_MOVESZ :
5306 case DT_INIT_ARRAYSZ:
5307 case DT_FINI_ARRAYSZ:
047b2264
JJ
5308 case DT_GNU_CONFLICTSZ:
5309 case DT_GNU_LIBLISTSZ:
252b5132 5310 if (do_dynamic)
f7a99963
NC
5311 {
5312 print_vma (entry->d_un.d_val, UNSIGNED);
5313 printf (" (bytes)\n");
5314 }
252b5132
RH
5315 break;
5316
5317 case DT_VERDEFNUM:
5318 case DT_VERNEEDNUM:
5319 case DT_RELACOUNT:
5320 case DT_RELCOUNT:
5321 if (do_dynamic)
f7a99963
NC
5322 {
5323 print_vma (entry->d_un.d_val, UNSIGNED);
5324 putchar ('\n');
5325 }
252b5132
RH
5326 break;
5327
5328 case DT_SYMINSZ:
5329 case DT_SYMINENT:
5330 case DT_SYMINFO:
5331 case DT_USED:
5332 case DT_INIT_ARRAY:
5333 case DT_FINI_ARRAY:
5334 if (do_dynamic)
5335 {
5336 if (dynamic_strings != NULL && entry->d_tag == DT_USED)
5337 {
b34976b6 5338 char *name;
252b5132
RH
5339
5340 name = dynamic_strings + entry->d_un.d_val;
5341
b34976b6 5342 if (*name)
252b5132
RH
5343 {
5344 printf (_("Not needed object: [%s]\n"), name);
5345 break;
5346 }
5347 }
103f02d3 5348
f7a99963
NC
5349 print_vma (entry->d_un.d_val, PREFIX_HEX);
5350 putchar ('\n');
252b5132
RH
5351 }
5352 break;
5353
5354 case DT_BIND_NOW:
5355 /* The value of this entry is ignored. */
35b1837e
AM
5356 if (do_dynamic)
5357 putchar ('\n');
252b5132 5358 break;
103f02d3 5359
047b2264
JJ
5360 case DT_GNU_PRELINKED:
5361 if (do_dynamic)
5362 {
b34976b6 5363 struct tm *tmp;
047b2264
JJ
5364 time_t time = entry->d_un.d_val;
5365
5366 tmp = gmtime (&time);
5367 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
5368 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
5369 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
5370
5371 }
5372 break;
5373
252b5132
RH
5374 default:
5375 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 5376 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
5377 entry->d_un.d_val;
5378
5379 if (do_dynamic)
5380 {
5381 switch (elf_header.e_machine)
5382 {
5383 case EM_MIPS:
4fe85591 5384 case EM_MIPS_RS3_LE:
b2d38a17 5385 dynamic_section_mips_val (entry);
252b5132 5386 break;
103f02d3 5387 case EM_PARISC:
b2d38a17 5388 dynamic_section_parisc_val (entry);
103f02d3 5389 break;
ecc51f48 5390 case EM_IA_64:
b2d38a17 5391 dynamic_section_ia64_val (entry);
ecc51f48 5392 break;
252b5132 5393 default:
f7a99963
NC
5394 print_vma (entry->d_un.d_val, PREFIX_HEX);
5395 putchar ('\n');
252b5132
RH
5396 }
5397 }
5398 break;
5399 }
5400 }
5401
5402 return 1;
5403}
5404
5405static char *
d3ba0551 5406get_ver_flags (unsigned int flags)
252b5132 5407{
b34976b6 5408 static char buff[32];
252b5132
RH
5409
5410 buff[0] = 0;
5411
5412 if (flags == 0)
5413 return _("none");
5414
5415 if (flags & VER_FLG_BASE)
5416 strcat (buff, "BASE ");
5417
5418 if (flags & VER_FLG_WEAK)
5419 {
5420 if (flags & VER_FLG_BASE)
5421 strcat (buff, "| ");
5422
5423 strcat (buff, "WEAK ");
5424 }
5425
5426 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
5427 strcat (buff, "| <unknown>");
5428
5429 return buff;
5430}
5431
5432/* Display the contents of the version sections. */
5433static int
d3ba0551 5434process_version_sections (FILE *file)
252b5132 5435{
b34976b6
AM
5436 Elf_Internal_Shdr *section;
5437 unsigned i;
5438 int found = 0;
252b5132
RH
5439
5440 if (! do_version)
5441 return 1;
5442
5443 for (i = 0, section = section_headers;
5444 i < elf_header.e_shnum;
b34976b6 5445 i++, section++)
252b5132
RH
5446 {
5447 switch (section->sh_type)
5448 {
5449 case SHT_GNU_verdef:
5450 {
b34976b6
AM
5451 Elf_External_Verdef *edefs;
5452 unsigned int idx;
5453 unsigned int cnt;
252b5132
RH
5454
5455 found = 1;
5456
5457 printf
5458 (_("\nVersion definition section '%s' contains %ld entries:\n"),
5459 SECTION_NAME (section), section->sh_info);
5460
5461 printf (_(" Addr: 0x"));
5462 printf_vma (section->sh_addr);
5463 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 5464 (unsigned long) section->sh_offset, section->sh_link,
9ad5cbcf 5465 SECTION_NAME (SECTION_HEADER (section->sh_link)));
252b5132 5466
d3ba0551
AM
5467 edefs = get_data (NULL, file, section->sh_offset, section->sh_size,
5468 _("version definition section"));
a6e9f9df
AM
5469 if (!edefs)
5470 break;
252b5132 5471
b34976b6 5472 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 5473 {
b34976b6
AM
5474 char *vstart;
5475 Elf_External_Verdef *edef;
5476 Elf_Internal_Verdef ent;
5477 Elf_External_Verdaux *eaux;
5478 Elf_Internal_Verdaux aux;
5479 int j;
5480 int isum;
103f02d3 5481
252b5132
RH
5482 vstart = ((char *) edefs) + idx;
5483
5484 edef = (Elf_External_Verdef *) vstart;
5485
5486 ent.vd_version = BYTE_GET (edef->vd_version);
5487 ent.vd_flags = BYTE_GET (edef->vd_flags);
5488 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
5489 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
5490 ent.vd_hash = BYTE_GET (edef->vd_hash);
5491 ent.vd_aux = BYTE_GET (edef->vd_aux);
5492 ent.vd_next = BYTE_GET (edef->vd_next);
5493
5494 printf (_(" %#06x: Rev: %d Flags: %s"),
5495 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
5496
5497 printf (_(" Index: %d Cnt: %d "),
5498 ent.vd_ndx, ent.vd_cnt);
5499
5500 vstart += ent.vd_aux;
5501
5502 eaux = (Elf_External_Verdaux *) vstart;
5503
5504 aux.vda_name = BYTE_GET (eaux->vda_name);
5505 aux.vda_next = BYTE_GET (eaux->vda_next);
5506
5507 if (dynamic_strings)
5508 printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
5509 else
5510 printf (_("Name index: %ld\n"), aux.vda_name);
5511
5512 isum = idx + ent.vd_aux;
5513
b34976b6 5514 for (j = 1; j < ent.vd_cnt; j++)
252b5132
RH
5515 {
5516 isum += aux.vda_next;
5517 vstart += aux.vda_next;
5518
5519 eaux = (Elf_External_Verdaux *) vstart;
5520
5521 aux.vda_name = BYTE_GET (eaux->vda_name);
5522 aux.vda_next = BYTE_GET (eaux->vda_next);
5523
5524 if (dynamic_strings)
5525 printf (_(" %#06x: Parent %d: %s\n"),
5526 isum, j, dynamic_strings + aux.vda_name);
5527 else
5528 printf (_(" %#06x: Parent %d, name index: %ld\n"),
5529 isum, j, aux.vda_name);
5530 }
5531
5532 idx += ent.vd_next;
5533 }
5534
5535 free (edefs);
5536 }
5537 break;
103f02d3 5538
252b5132
RH
5539 case SHT_GNU_verneed:
5540 {
b34976b6
AM
5541 Elf_External_Verneed *eneed;
5542 unsigned int idx;
5543 unsigned int cnt;
252b5132
RH
5544
5545 found = 1;
5546
5547 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
5548 SECTION_NAME (section), section->sh_info);
5549
5550 printf (_(" Addr: 0x"));
5551 printf_vma (section->sh_addr);
5552 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
1b228002 5553 (unsigned long) section->sh_offset, section->sh_link,
9ad5cbcf 5554 SECTION_NAME (SECTION_HEADER (section->sh_link)));
252b5132 5555
d3ba0551
AM
5556 eneed = get_data (NULL, file, section->sh_offset, section->sh_size,
5557 _("version need section"));
a6e9f9df
AM
5558 if (!eneed)
5559 break;
252b5132
RH
5560
5561 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
5562 {
b34976b6
AM
5563 Elf_External_Verneed *entry;
5564 Elf_Internal_Verneed ent;
5565 int j;
5566 int isum;
5567 char *vstart;
252b5132
RH
5568
5569 vstart = ((char *) eneed) + idx;
5570
5571 entry = (Elf_External_Verneed *) vstart;
5572
5573 ent.vn_version = BYTE_GET (entry->vn_version);
5574 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
5575 ent.vn_file = BYTE_GET (entry->vn_file);
5576 ent.vn_aux = BYTE_GET (entry->vn_aux);
5577 ent.vn_next = BYTE_GET (entry->vn_next);
5578
5579 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
5580
5581 if (dynamic_strings)
5582 printf (_(" File: %s"), dynamic_strings + ent.vn_file);
5583 else
5584 printf (_(" File: %lx"), ent.vn_file);
5585
5586 printf (_(" Cnt: %d\n"), ent.vn_cnt);
5587
5588 vstart += ent.vn_aux;
5589
5590 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
5591 {
b34976b6
AM
5592 Elf_External_Vernaux *eaux;
5593 Elf_Internal_Vernaux aux;
252b5132
RH
5594
5595 eaux = (Elf_External_Vernaux *) vstart;
5596
5597 aux.vna_hash = BYTE_GET (eaux->vna_hash);
5598 aux.vna_flags = BYTE_GET (eaux->vna_flags);
5599 aux.vna_other = BYTE_GET (eaux->vna_other);
5600 aux.vna_name = BYTE_GET (eaux->vna_name);
5601 aux.vna_next = BYTE_GET (eaux->vna_next);
5602
5603 if (dynamic_strings)
ecc2063b 5604 printf (_(" %#06x: Name: %s"),
252b5132
RH
5605 isum, dynamic_strings + aux.vna_name);
5606 else
ecc2063b 5607 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
5608 isum, aux.vna_name);
5609
5610 printf (_(" Flags: %s Version: %d\n"),
5611 get_ver_flags (aux.vna_flags), aux.vna_other);
5612
5613 isum += aux.vna_next;
5614 vstart += aux.vna_next;
5615 }
5616
5617 idx += ent.vn_next;
5618 }
103f02d3 5619
252b5132
RH
5620 free (eneed);
5621 }
5622 break;
5623
5624 case SHT_GNU_versym:
5625 {
b34976b6
AM
5626 Elf_Internal_Shdr *link_section;
5627 int total;
5628 int cnt;
5629 unsigned char *edata;
5630 unsigned short *data;
5631 char *strtab;
5632 Elf_Internal_Sym *symbols;
5633 Elf_Internal_Shdr *string_sec;
d3ba0551 5634 long off;
252b5132 5635
9ad5cbcf 5636 link_section = SECTION_HEADER (section->sh_link);
252b5132
RH
5637 total = section->sh_size / section->sh_entsize;
5638
5639 found = 1;
5640
9ad5cbcf 5641 symbols = GET_ELF_SYMBOLS (file, link_section);
252b5132 5642
9ad5cbcf 5643 string_sec = SECTION_HEADER (link_section->sh_link);
252b5132 5644
d3ba0551
AM
5645 strtab = get_data (NULL, file, string_sec->sh_offset,
5646 string_sec->sh_size, _("version string table"));
a6e9f9df
AM
5647 if (!strtab)
5648 break;
252b5132
RH
5649
5650 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
5651 SECTION_NAME (section), total);
5652
5653 printf (_(" Addr: "));
5654 printf_vma (section->sh_addr);
5655 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 5656 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
5657 SECTION_NAME (link_section));
5658
d3ba0551
AM
5659 off = offset_from_vma (file,
5660 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
5661 total * sizeof (short));
5662 edata = get_data (NULL, file, off, total * sizeof (short),
5663 _("version symbol data"));
a6e9f9df
AM
5664 if (!edata)
5665 {
5666 free (strtab);
5667 break;
5668 }
252b5132 5669
d3ba0551 5670 data = malloc (total * sizeof (short));
252b5132
RH
5671
5672 for (cnt = total; cnt --;)
b34976b6
AM
5673 data[cnt] = byte_get (edata + cnt * sizeof (short),
5674 sizeof (short));
252b5132
RH
5675
5676 free (edata);
5677
5678 for (cnt = 0; cnt < total; cnt += 4)
5679 {
5680 int j, nn;
00d93f34 5681 int check_def, check_need;
b34976b6 5682 char *name;
252b5132
RH
5683
5684 printf (" %03x:", cnt);
5685
5686 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 5687 switch (data[cnt + j])
252b5132
RH
5688 {
5689 case 0:
5690 fputs (_(" 0 (*local*) "), stdout);
5691 break;
5692
5693 case 1:
5694 fputs (_(" 1 (*global*) "), stdout);
5695 break;
5696
5697 default:
b34976b6
AM
5698 nn = printf ("%4x%c", data[cnt + j] & 0x7fff,
5699 data[cnt + j] & 0x8000 ? 'h' : ' ');
252b5132 5700
00d93f34
JJ
5701 check_def = 1;
5702 check_need = 1;
b34976b6 5703 if (SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
00d93f34 5704 != SHT_NOBITS)
252b5132 5705 {
b34976b6 5706 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
5707 check_def = 0;
5708 else
5709 check_need = 0;
252b5132 5710 }
00d93f34
JJ
5711
5712 if (check_need
b34976b6 5713 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 5714 {
b34976b6
AM
5715 Elf_Internal_Verneed ivn;
5716 unsigned long offset;
252b5132 5717
d93f0186
NC
5718 offset = offset_from_vma
5719 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
5720 sizeof (Elf_External_Verneed));
252b5132 5721
b34976b6 5722 do
252b5132 5723 {
b34976b6
AM
5724 Elf_Internal_Vernaux ivna;
5725 Elf_External_Verneed evn;
5726 Elf_External_Vernaux evna;
5727 unsigned long a_off;
252b5132 5728
a6e9f9df
AM
5729 get_data (&evn, file, offset, sizeof (evn),
5730 _("version need"));
252b5132
RH
5731
5732 ivn.vn_aux = BYTE_GET (evn.vn_aux);
5733 ivn.vn_next = BYTE_GET (evn.vn_next);
5734
5735 a_off = offset + ivn.vn_aux;
5736
5737 do
5738 {
a6e9f9df
AM
5739 get_data (&evna, file, a_off, sizeof (evna),
5740 _("version need aux (2)"));
252b5132
RH
5741
5742 ivna.vna_next = BYTE_GET (evna.vna_next);
5743 ivna.vna_other = BYTE_GET (evna.vna_other);
5744
5745 a_off += ivna.vna_next;
5746 }
b34976b6 5747 while (ivna.vna_other != data[cnt + j]
252b5132
RH
5748 && ivna.vna_next != 0);
5749
b34976b6 5750 if (ivna.vna_other == data[cnt + j])
252b5132
RH
5751 {
5752 ivna.vna_name = BYTE_GET (evna.vna_name);
5753
16062207 5754 name = strtab + ivna.vna_name;
252b5132 5755 nn += printf ("(%s%-*s",
16062207
ILT
5756 name,
5757 12 - (int) strlen (name),
252b5132 5758 ")");
00d93f34 5759 check_def = 0;
252b5132
RH
5760 break;
5761 }
5762
5763 offset += ivn.vn_next;
5764 }
5765 while (ivn.vn_next);
5766 }
00d93f34 5767
b34976b6
AM
5768 if (check_def && data[cnt + j] != 0x8001
5769 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 5770 {
b34976b6
AM
5771 Elf_Internal_Verdef ivd;
5772 Elf_External_Verdef evd;
5773 unsigned long offset;
252b5132 5774
d93f0186
NC
5775 offset = offset_from_vma
5776 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
5777 sizeof evd);
252b5132
RH
5778
5779 do
5780 {
a6e9f9df
AM
5781 get_data (&evd, file, offset, sizeof (evd),
5782 _("version def"));
252b5132
RH
5783
5784 ivd.vd_next = BYTE_GET (evd.vd_next);
5785 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
5786
5787 offset += ivd.vd_next;
5788 }
b34976b6 5789 while (ivd.vd_ndx != (data[cnt + j] & 0x7fff)
252b5132
RH
5790 && ivd.vd_next != 0);
5791
b34976b6 5792 if (ivd.vd_ndx == (data[cnt + j] & 0x7fff))
252b5132 5793 {
b34976b6
AM
5794 Elf_External_Verdaux evda;
5795 Elf_Internal_Verdaux ivda;
252b5132
RH
5796
5797 ivd.vd_aux = BYTE_GET (evd.vd_aux);
5798
a6e9f9df
AM
5799 get_data (&evda, file,
5800 offset - ivd.vd_next + ivd.vd_aux,
5801 sizeof (evda), _("version def aux"));
252b5132
RH
5802
5803 ivda.vda_name = BYTE_GET (evda.vda_name);
5804
16062207 5805 name = strtab + ivda.vda_name;
252b5132 5806 nn += printf ("(%s%-*s",
16062207
ILT
5807 name,
5808 12 - (int) strlen (name),
252b5132
RH
5809 ")");
5810 }
5811 }
5812
5813 if (nn < 18)
5814 printf ("%*c", 18 - nn, ' ');
5815 }
5816
5817 putchar ('\n');
5818 }
5819
5820 free (data);
5821 free (strtab);
5822 free (symbols);
5823 }
5824 break;
103f02d3 5825
252b5132
RH
5826 default:
5827 break;
5828 }
5829 }
5830
5831 if (! found)
5832 printf (_("\nNo version information found in this file.\n"));
5833
5834 return 1;
5835}
5836
d1133906 5837static const char *
d3ba0551 5838get_symbol_binding (unsigned int binding)
252b5132 5839{
b34976b6 5840 static char buff[32];
252b5132
RH
5841
5842 switch (binding)
5843 {
b34976b6
AM
5844 case STB_LOCAL: return "LOCAL";
5845 case STB_GLOBAL: return "GLOBAL";
5846 case STB_WEAK: return "WEAK";
252b5132
RH
5847 default:
5848 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
5849 sprintf (buff, _("<processor specific>: %d"), binding);
5850 else if (binding >= STB_LOOS && binding <= STB_HIOS)
5851 sprintf (buff, _("<OS specific>: %d"), binding);
5852 else
5853 sprintf (buff, _("<unknown>: %d"), binding);
5854 return buff;
5855 }
5856}
5857
d1133906 5858static const char *
d3ba0551 5859get_symbol_type (unsigned int type)
252b5132 5860{
b34976b6 5861 static char buff[32];
252b5132
RH
5862
5863 switch (type)
5864 {
b34976b6
AM
5865 case STT_NOTYPE: return "NOTYPE";
5866 case STT_OBJECT: return "OBJECT";
5867 case STT_FUNC: return "FUNC";
5868 case STT_SECTION: return "SECTION";
5869 case STT_FILE: return "FILE";
5870 case STT_COMMON: return "COMMON";
5871 case STT_TLS: return "TLS";
252b5132
RH
5872 default:
5873 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
5874 {
5875 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
5876 return "THUMB_FUNC";
5877
351b4b40 5878 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
5879 return "REGISTER";
5880
5881 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
5882 return "PARISC_MILLI";
5883
df75f1af
NC
5884 sprintf (buff, _("<processor specific>: %d"), type);
5885 }
252b5132 5886 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
5887 {
5888 if (elf_header.e_machine == EM_PARISC)
5889 {
5890 if (type == STT_HP_OPAQUE)
5891 return "HP_OPAQUE";
5892 if (type == STT_HP_STUB)
5893 return "HP_STUB";
5894 }
5895
5896 sprintf (buff, _("<OS specific>: %d"), type);
5897 }
252b5132
RH
5898 else
5899 sprintf (buff, _("<unknown>: %d"), type);
5900 return buff;
5901 }
5902}
5903
d1133906 5904static const char *
d3ba0551 5905get_symbol_visibility (unsigned int visibility)
d1133906
NC
5906{
5907 switch (visibility)
5908 {
b34976b6
AM
5909 case STV_DEFAULT: return "DEFAULT";
5910 case STV_INTERNAL: return "INTERNAL";
5911 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
5912 case STV_PROTECTED: return "PROTECTED";
5913 default: abort ();
5914 }
5915}
5916
5917static const char *
d3ba0551 5918get_symbol_index_type (unsigned int type)
252b5132 5919{
b34976b6 5920 static char buff[32];
5cf1065c 5921
252b5132
RH
5922 switch (type)
5923 {
b34976b6
AM
5924 case SHN_UNDEF: return "UND";
5925 case SHN_ABS: return "ABS";
5926 case SHN_COMMON: return "COM";
252b5132 5927 default:
9ce701e2
L
5928 if (type == SHN_IA_64_ANSI_COMMON
5929 && elf_header.e_machine == EM_IA_64
5930 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
5931 return "ANSI_COM";
5932 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
5cf1065c 5933 sprintf (buff, "PRC[0x%04x]", type);
252b5132 5934 else if (type >= SHN_LOOS && type <= SHN_HIOS)
5cf1065c 5935 sprintf (buff, "OS [0x%04x]", type);
9ad5cbcf 5936 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
5cf1065c 5937 sprintf (buff, "RSV[0x%04x]", type);
252b5132 5938 else
232e7cb8 5939 sprintf (buff, "%3d", type);
5cf1065c 5940 break;
252b5132 5941 }
5cf1065c
NC
5942
5943 return buff;
252b5132
RH
5944}
5945
252b5132 5946static int *
d3ba0551 5947get_dynamic_data (FILE *file, unsigned int number)
252b5132 5948{
b34976b6
AM
5949 unsigned char *e_data;
5950 int *i_data;
252b5132 5951
d3ba0551 5952 e_data = malloc (number * 4);
252b5132
RH
5953
5954 if (e_data == NULL)
5955 {
5956 error (_("Out of memory\n"));
5957 return NULL;
5958 }
5959
5960 if (fread (e_data, 4, number, file) != number)
5961 {
5962 error (_("Unable to read in dynamic data\n"));
5963 return NULL;
5964 }
5965
d3ba0551 5966 i_data = malloc (number * sizeof (*i_data));
252b5132
RH
5967
5968 if (i_data == NULL)
5969 {
5970 error (_("Out of memory\n"));
5971 free (e_data);
5972 return NULL;
5973 }
5974
5975 while (number--)
b34976b6 5976 i_data[number] = byte_get (e_data + number * 4, 4);
252b5132
RH
5977
5978 free (e_data);
5979
5980 return i_data;
5981}
5982
e3c8793a 5983/* Dump the symbol table. */
252b5132 5984static int
d3ba0551 5985process_symbol_table (FILE *file)
252b5132 5986{
b34976b6
AM
5987 Elf_Internal_Shdr *section;
5988 unsigned char nb[4];
5989 unsigned char nc[4];
5990 int nbuckets = 0;
5991 int nchains = 0;
5992 int *buckets = NULL;
5993 int *chains = NULL;
252b5132
RH
5994
5995 if (! do_syms && !do_histogram)
5996 return 1;
5997
5998 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
5999 || do_histogram))
6000 {
fb52b2f4
NC
6001 if (fseek (file,
6002 (archive_file_offset
6003 + offset_from_vma (file, dynamic_info[DT_HASH],
6004 sizeof nb + sizeof nc)),
d93f0186 6005 SEEK_SET))
252b5132
RH
6006 {
6007 error (_("Unable to seek to start of dynamic information"));
6008 return 0;
6009 }
6010
6011 if (fread (nb, sizeof (nb), 1, file) != 1)
6012 {
6013 error (_("Failed to read in number of buckets\n"));
6014 return 0;
6015 }
6016
6017 if (fread (nc, sizeof (nc), 1, file) != 1)
6018 {
6019 error (_("Failed to read in number of chains\n"));
6020 return 0;
6021 }
6022
6023 nbuckets = byte_get (nb, 4);
6024 nchains = byte_get (nc, 4);
6025
6026 buckets = get_dynamic_data (file, nbuckets);
6027 chains = get_dynamic_data (file, nchains);
6028
6029 if (buckets == NULL || chains == NULL)
6030 return 0;
6031 }
6032
6033 if (do_syms
6034 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
6035 {
b34976b6
AM
6036 int hn;
6037 int si;
252b5132
RH
6038
6039 printf (_("\nSymbol table for image:\n"));
f7a99963 6040 if (is_32bit_elf)
ca47b30c 6041 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 6042 else
ca47b30c 6043 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
252b5132
RH
6044
6045 for (hn = 0; hn < nbuckets; hn++)
6046 {
b34976b6 6047 if (! buckets[hn])
252b5132
RH
6048 continue;
6049
b34976b6 6050 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
252b5132 6051 {
b34976b6 6052 Elf_Internal_Sym *psym;
252b5132
RH
6053
6054 psym = dynamic_symbols + si;
6055
f7a99963
NC
6056 printf (" %3d %3d: ", si, hn);
6057 print_vma (psym->st_value, LONG_HEX);
6058 putchar (' ' );
d1133906 6059 print_vma (psym->st_size, DEC_5);
76da6bbe 6060
d1133906
NC
6061 printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
6062 printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
6063 printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126
NC
6064 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
6065 print_symbol (25, dynamic_strings + psym->st_name);
6066 putchar ('\n');
252b5132
RH
6067 }
6068 }
6069 }
6070 else if (do_syms && !do_using_dynamic)
6071 {
b34976b6 6072 unsigned int i;
252b5132
RH
6073
6074 for (i = 0, section = section_headers;
6075 i < elf_header.e_shnum;
6076 i++, section++)
6077 {
b34976b6
AM
6078 unsigned int si;
6079 char *strtab;
6080 Elf_Internal_Sym *symtab;
6081 Elf_Internal_Sym *psym;
252b5132
RH
6082
6083
6084 if ( section->sh_type != SHT_SYMTAB
6085 && section->sh_type != SHT_DYNSYM)
6086 continue;
6087
6088 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
6089 SECTION_NAME (section),
6090 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 6091 if (is_32bit_elf)
ca47b30c 6092 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 6093 else
ca47b30c 6094 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 6095
9ad5cbcf 6096 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
6097 if (symtab == NULL)
6098 continue;
6099
6100 if (section->sh_link == elf_header.e_shstrndx)
6101 strtab = string_table;
6102 else
6103 {
b34976b6 6104 Elf_Internal_Shdr *string_sec;
252b5132 6105
9ad5cbcf 6106 string_sec = SECTION_HEADER (section->sh_link);
252b5132 6107
d3ba0551
AM
6108 strtab = get_data (NULL, file, string_sec->sh_offset,
6109 string_sec->sh_size, _("string table"));
252b5132
RH
6110 }
6111
6112 for (si = 0, psym = symtab;
6113 si < section->sh_size / section->sh_entsize;
b34976b6 6114 si++, psym++)
252b5132 6115 {
5e220199 6116 printf ("%6d: ", si);
f7a99963
NC
6117 print_vma (psym->st_value, LONG_HEX);
6118 putchar (' ');
6119 print_vma (psym->st_size, DEC_5);
d1133906
NC
6120 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
6121 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
6122 printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126
NC
6123 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
6124 print_symbol (25, strtab + psym->st_name);
252b5132
RH
6125
6126 if (section->sh_type == SHT_DYNSYM &&
b34976b6 6127 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 6128 {
b34976b6
AM
6129 unsigned char data[2];
6130 unsigned short vers_data;
6131 unsigned long offset;
6132 int is_nobits;
6133 int check_def;
252b5132 6134
d93f0186
NC
6135 offset = offset_from_vma
6136 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
6137 sizeof data + si * sizeof (vers_data));
252b5132 6138
a6e9f9df
AM
6139 get_data (&data, file, offset + si * sizeof (vers_data),
6140 sizeof (data), _("version data"));
252b5132
RH
6141
6142 vers_data = byte_get (data, 2);
6143
9ad5cbcf
AM
6144 is_nobits = (SECTION_HEADER (psym->st_shndx)->sh_type
6145 == SHT_NOBITS);
252b5132
RH
6146
6147 check_def = (psym->st_shndx != SHN_UNDEF);
6148
6149 if ((vers_data & 0x8000) || vers_data > 1)
6150 {
b34976b6 6151 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 6152 && (is_nobits || ! check_def))
252b5132 6153 {
b34976b6
AM
6154 Elf_External_Verneed evn;
6155 Elf_Internal_Verneed ivn;
6156 Elf_Internal_Vernaux ivna;
252b5132
RH
6157
6158 /* We must test both. */
d93f0186
NC
6159 offset = offset_from_vma
6160 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
6161 sizeof evn);
252b5132 6162
252b5132
RH
6163 do
6164 {
b34976b6 6165 unsigned long vna_off;
252b5132 6166
a6e9f9df
AM
6167 get_data (&evn, file, offset, sizeof (evn),
6168 _("version need"));
dd27201e
L
6169
6170 ivn.vn_aux = BYTE_GET (evn.vn_aux);
6171 ivn.vn_next = BYTE_GET (evn.vn_next);
6172
252b5132
RH
6173 vna_off = offset + ivn.vn_aux;
6174
6175 do
6176 {
b34976b6 6177 Elf_External_Vernaux evna;
252b5132 6178
a6e9f9df
AM
6179 get_data (&evna, file, vna_off,
6180 sizeof (evna),
6181 _("version need aux (3)"));
252b5132
RH
6182
6183 ivna.vna_other = BYTE_GET (evna.vna_other);
6184 ivna.vna_next = BYTE_GET (evna.vna_next);
6185 ivna.vna_name = BYTE_GET (evna.vna_name);
6186
6187 vna_off += ivna.vna_next;
6188 }
6189 while (ivna.vna_other != vers_data
6190 && ivna.vna_next != 0);
6191
6192 if (ivna.vna_other == vers_data)
6193 break;
6194
6195 offset += ivn.vn_next;
6196 }
6197 while (ivn.vn_next != 0);
6198
6199 if (ivna.vna_other == vers_data)
6200 {
6201 printf ("@%s (%d)",
6202 strtab + ivna.vna_name, ivna.vna_other);
6203 check_def = 0;
6204 }
6205 else if (! is_nobits)
6206 error (_("bad dynamic symbol"));
6207 else
6208 check_def = 1;
6209 }
6210
6211 if (check_def)
6212 {
00d93f34 6213 if (vers_data != 0x8001
b34976b6 6214 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 6215 {
b34976b6
AM
6216 Elf_Internal_Verdef ivd;
6217 Elf_Internal_Verdaux ivda;
6218 Elf_External_Verdaux evda;
6219 unsigned long offset;
252b5132 6220
d93f0186
NC
6221 offset = offset_from_vma
6222 (file,
6223 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
6224 sizeof (Elf_External_Verdef));
252b5132
RH
6225
6226 do
6227 {
b34976b6 6228 Elf_External_Verdef evd;
252b5132 6229
a6e9f9df
AM
6230 get_data (&evd, file, offset, sizeof (evd),
6231 _("version def"));
252b5132 6232
b34976b6
AM
6233 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
6234 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
6235 ivd.vd_next = BYTE_GET (evd.vd_next);
6236
6237 offset += ivd.vd_next;
6238 }
6239 while (ivd.vd_ndx != (vers_data & 0x7fff)
6240 && ivd.vd_next != 0);
6241
6242 offset -= ivd.vd_next;
6243 offset += ivd.vd_aux;
6244
a6e9f9df
AM
6245 get_data (&evda, file, offset, sizeof (evda),
6246 _("version def aux"));
252b5132
RH
6247
6248 ivda.vda_name = BYTE_GET (evda.vda_name);
6249
6250 if (psym->st_name != ivda.vda_name)
6251 printf ((vers_data & 0x8000)
6252 ? "@%s" : "@@%s",
6253 strtab + ivda.vda_name);
6254 }
6255 }
6256 }
6257 }
6258
6259 putchar ('\n');
6260 }
6261
6262 free (symtab);
6263 if (strtab != string_table)
6264 free (strtab);
6265 }
6266 }
6267 else if (do_syms)
6268 printf
6269 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
6270
6271 if (do_histogram && buckets != NULL)
6272 {
b34976b6
AM
6273 int *lengths;
6274 int *counts;
6275 int hn;
6276 int si;
6277 int maxlength = 0;
6278 int nzero_counts = 0;
6279 int nsyms = 0;
252b5132
RH
6280
6281 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
6282 nbuckets);
6283 printf (_(" Length Number %% of total Coverage\n"));
6284
d3ba0551 6285 lengths = calloc (nbuckets, sizeof (int));
252b5132
RH
6286 if (lengths == NULL)
6287 {
6288 error (_("Out of memory"));
6289 return 0;
6290 }
6291 for (hn = 0; hn < nbuckets; ++hn)
6292 {
b34976b6 6293 if (! buckets[hn])
252b5132
RH
6294 continue;
6295
f7a99963 6296 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 6297 {
b34976b6 6298 ++nsyms;
252b5132 6299 if (maxlength < ++lengths[hn])
b34976b6 6300 ++maxlength;
252b5132
RH
6301 }
6302 }
6303
d3ba0551 6304 counts = calloc (maxlength + 1, sizeof (int));
252b5132
RH
6305 if (counts == NULL)
6306 {
6307 error (_("Out of memory"));
6308 return 0;
6309 }
6310
6311 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 6312 ++counts[lengths[hn]];
252b5132 6313
103f02d3 6314 if (nbuckets > 0)
252b5132 6315 {
103f02d3
UD
6316 printf (" 0 %-10d (%5.1f%%)\n",
6317 counts[0], (counts[0] * 100.0) / nbuckets);
6318 for (si = 1; si <= maxlength; ++si)
6319 {
6320 nzero_counts += counts[si] * si;
6321 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
6322 si, counts[si], (counts[si] * 100.0) / nbuckets,
6323 (nzero_counts * 100.0) / nsyms);
6324 }
252b5132
RH
6325 }
6326
6327 free (counts);
6328 free (lengths);
6329 }
6330
6331 if (buckets != NULL)
6332 {
6333 free (buckets);
6334 free (chains);
6335 }
6336
6337 return 1;
6338}
6339
6340static int
d3ba0551 6341process_syminfo (FILE *file ATTRIBUTE_UNUSED)
252b5132 6342{
b4c96d0d 6343 unsigned int i;
252b5132
RH
6344
6345 if (dynamic_syminfo == NULL
6346 || !do_dynamic)
6347 /* No syminfo, this is ok. */
6348 return 1;
6349
6350 /* There better should be a dynamic symbol section. */
6351 if (dynamic_symbols == NULL || dynamic_strings == NULL)
6352 return 0;
6353
6354 if (dynamic_addr)
6355 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
6356 dynamic_syminfo_offset, dynamic_syminfo_nent);
6357
6358 printf (_(" Num: Name BoundTo Flags\n"));
6359 for (i = 0; i < dynamic_syminfo_nent; ++i)
6360 {
6361 unsigned short int flags = dynamic_syminfo[i].si_flags;
6362
31104126
NC
6363 printf ("%4d: ", i);
6364 print_symbol (30, dynamic_strings + dynamic_symbols[i].st_name);
6365 putchar (' ');
252b5132
RH
6366
6367 switch (dynamic_syminfo[i].si_boundto)
6368 {
6369 case SYMINFO_BT_SELF:
6370 fputs ("SELF ", stdout);
6371 break;
6372 case SYMINFO_BT_PARENT:
6373 fputs ("PARENT ", stdout);
6374 break;
6375 default:
6376 if (dynamic_syminfo[i].si_boundto > 0
86dba8ee 6377 && dynamic_syminfo[i].si_boundto < dynamic_nent)
31104126 6378 {
b34976b6
AM
6379 print_symbol (10,
6380 dynamic_strings
b2d38a17 6381 + (dynamic_section
b34976b6 6382 [dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
6383 putchar (' ' );
6384 }
252b5132
RH
6385 else
6386 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
6387 break;
6388 }
6389
6390 if (flags & SYMINFO_FLG_DIRECT)
6391 printf (" DIRECT");
6392 if (flags & SYMINFO_FLG_PASSTHRU)
6393 printf (" PASSTHRU");
6394 if (flags & SYMINFO_FLG_COPY)
6395 printf (" COPY");
6396 if (flags & SYMINFO_FLG_LAZYLOAD)
6397 printf (" LAZYLOAD");
6398
6399 puts ("");
6400 }
6401
6402 return 1;
6403}
6404
6405#ifdef SUPPORT_DISASSEMBLY
6406static void
d3ba0551 6407disassemble_section (Elf_Internal_Shdr *section, FILE *file)
252b5132
RH
6408{
6409 printf (_("\nAssembly dump of section %s\n"),
6410 SECTION_NAME (section));
6411
6412 /* XXX -- to be done --- XXX */
6413
6414 return 1;
6415}
6416#endif
6417
6418static int
d3ba0551 6419dump_section (Elf_Internal_Shdr *section, FILE *file)
252b5132 6420{
b34976b6
AM
6421 bfd_size_type bytes;
6422 bfd_vma addr;
6423 unsigned char *data;
6424 unsigned char *start;
252b5132
RH
6425
6426 bytes = section->sh_size;
6427
e69f2d21 6428 if (bytes == 0 || section->sh_type == SHT_NOBITS)
252b5132
RH
6429 {
6430 printf (_("\nSection '%s' has no data to dump.\n"),
6431 SECTION_NAME (section));
6432 return 0;
6433 }
6434 else
6435 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
6436
6437 addr = section->sh_addr;
6438
d3ba0551 6439 start = get_data (NULL, file, section->sh_offset, bytes, _("section data"));
a6e9f9df
AM
6440 if (!start)
6441 return 0;
252b5132
RH
6442
6443 data = start;
6444
6445 while (bytes)
6446 {
6447 int j;
6448 int k;
6449 int lbytes;
6450
6451 lbytes = (bytes > 16 ? 16 : bytes);
6452
148d3c43 6453 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132 6454
b34976b6 6455 switch (elf_header.e_ident[EI_DATA])
252b5132 6456 {
9ea033b2 6457 default:
252b5132
RH
6458 case ELFDATA2LSB:
6459 for (j = 15; j >= 0; j --)
6460 {
6461 if (j < lbytes)
b34976b6 6462 printf ("%2.2x", data[j]);
252b5132
RH
6463 else
6464 printf (" ");
6465
6466 if (!(j & 0x3))
6467 printf (" ");
6468 }
6469 break;
6470
6471 case ELFDATA2MSB:
6472 for (j = 0; j < 16; j++)
6473 {
6474 if (j < lbytes)
b34976b6 6475 printf ("%2.2x", data[j]);
252b5132
RH
6476 else
6477 printf (" ");
6478
6479 if ((j & 3) == 3)
6480 printf (" ");
6481 }
6482 break;
6483 }
6484
6485 for (j = 0; j < lbytes; j++)
6486 {
b34976b6 6487 k = data[j];
9376f0c7 6488 if (k >= ' ' && k < 0x7f)
252b5132
RH
6489 printf ("%c", k);
6490 else
6491 printf (".");
6492 }
6493
6494 putchar ('\n');
6495
6496 data += lbytes;
6497 addr += lbytes;
6498 bytes -= lbytes;
6499 }
6500
6501 free (start);
6502
6503 return 1;
6504}
6505
6506
6507static unsigned long int
d3ba0551 6508read_leb128 (unsigned char *data, int *length_return, int sign)
252b5132
RH
6509{
6510 unsigned long int result = 0;
b34976b6
AM
6511 unsigned int num_read = 0;
6512 int shift = 0;
6513 unsigned char byte;
252b5132
RH
6514
6515 do
6516 {
b34976b6
AM
6517 byte = *data++;
6518 num_read++;
252b5132
RH
6519
6520 result |= (byte & 0x7f) << shift;
6521
6522 shift += 7;
6523
6524 }
6525 while (byte & 0x80);
6526
6527 if (length_return != NULL)
b34976b6 6528 *length_return = num_read;
252b5132
RH
6529
6530 if (sign && (shift < 32) && (byte & 0x40))
6531 result |= -1 << shift;
6532
6533 return result;
6534}
6535
6536typedef struct State_Machine_Registers
6537{
b34976b6
AM
6538 unsigned long address;
6539 unsigned int file;
6540 unsigned int line;
6541 unsigned int column;
6542 int is_stmt;
6543 int basic_block;
6544 int end_sequence;
252b5132
RH
6545/* This variable hold the number of the last entry seen
6546 in the File Table. */
b34976b6 6547 unsigned int last_file_entry;
252b5132
RH
6548} SMR;
6549
6550static SMR state_machine_regs;
6551
6552static void
d3ba0551 6553reset_state_machine (int is_stmt)
252b5132
RH
6554{
6555 state_machine_regs.address = 0;
6556 state_machine_regs.file = 1;
6557 state_machine_regs.line = 1;
6558 state_machine_regs.column = 0;
6559 state_machine_regs.is_stmt = is_stmt;
6560 state_machine_regs.basic_block = 0;
6561 state_machine_regs.end_sequence = 0;
6562 state_machine_regs.last_file_entry = 0;
6563}
6564
6565/* Handled an extend line op. Returns true if this is the end
6566 of sequence. */
6567static int
d3ba0551 6568process_extended_line_op (unsigned char *data, int is_stmt, int pointer_size)
252b5132 6569{
b34976b6
AM
6570 unsigned char op_code;
6571 int bytes_read;
6572 unsigned int len;
6573 unsigned char *name;
6574 unsigned long adr;
103f02d3 6575
252b5132
RH
6576 len = read_leb128 (data, & bytes_read, 0);
6577 data += bytes_read;
6578
6579 if (len == 0)
6580 {
e5fb9629 6581 warn (_("badly formed extended line op encountered!\n"));
252b5132
RH
6582 return bytes_read;
6583 }
6584
6585 len += bytes_read;
b34976b6 6586 op_code = *data++;
252b5132
RH
6587
6588 printf (_(" Extended opcode %d: "), op_code);
103f02d3 6589
252b5132
RH
6590 switch (op_code)
6591 {
6592 case DW_LNE_end_sequence:
6593 printf (_("End of Sequence\n\n"));
6594 reset_state_machine (is_stmt);
6595 break;
6596
6597 case DW_LNE_set_address:
3590ea00 6598 adr = byte_get (data, pointer_size);
252b5132
RH
6599 printf (_("set Address to 0x%lx\n"), adr);
6600 state_machine_regs.address = adr;
6601 break;
6602
6603 case DW_LNE_define_file:
6604 printf (_(" define new File Table entry\n"));
6605 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
103f02d3 6606
b34976b6 6607 printf (_(" %d\t"), ++state_machine_regs.last_file_entry);
252b5132 6608 name = data;
3c9f43b1 6609 data += strlen ((char *) data) + 1;
252b5132
RH
6610 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6611 data += bytes_read;
6612 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6613 data += bytes_read;
6614 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6615 printf (_("%s\n\n"), name);
6616 break;
6617
6618 default:
6619 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
6620 break;
6621 }
6622
6623 return len;
6624}
6625
d9296b18
NC
6626/* Finds section NAME inside FILE and returns a
6627 pointer to it, or NULL upon failure. */
6628
6629static Elf_Internal_Shdr *
6630find_section (const char * name)
6631{
6632 Elf_Internal_Shdr *sec;
6633 unsigned int i;
0de14b54 6634
d9296b18
NC
6635 for (i = elf_header.e_shnum, sec = section_headers + i - 1;
6636 i; --i, --sec)
6637 if (strcmp (SECTION_NAME (sec), name) == 0)
6638 break;
6639
6640 if (i && sec && sec->sh_size != 0)
6641 return sec;
6642
6643 return NULL;
6644}
6645
3590ea00
NC
6646/* Size of pointers in the .debug_line section. This information is not
6647 really present in that section. It's obtained before dumping the debug
6648 sections by doing some pre-scan of the .debug_info section. */
0e0c4098
NC
6649static unsigned int * debug_line_pointer_sizes = NULL;
6650static unsigned int num_debug_line_pointer_sizes = 0;
252b5132 6651
d9296b18
NC
6652/* Locate and scan the .debug_info section in the file and record the pointer
6653 sizes for the compilation units in it. Usually an executable will have
6654 just one pointer size, but this is not guaranteed, and so we try not to
6655 make any assumptions. Returns zero upon failure, or the number of
6656 compilation units upon success. */
6657
6658static unsigned int
6659get_debug_line_pointer_sizes (FILE * file)
6660{
6661 Elf_Internal_Shdr * section;
6662 unsigned char * start;
6663 unsigned char * end;
6664 unsigned char * begin;
6665 unsigned long length;
6666 unsigned int num_units;
6667 unsigned int unit;
6668
6669 section = find_section (".debug_info");
6670 if (section == NULL)
6671 return 0;
6672
6673 length = section->sh_size;
6674 start = get_data (NULL, file, section->sh_offset, section->sh_size,
6675 _("extracting pointer sizes from .debug_info section"));
6676 if (start == NULL)
6677 return 0;
6678
6679 end = start + section->sh_size;
6680 /* First scan the section to get the number of comp units. */
6681 for (begin = start, num_units = 0; begin < end; num_units++)
6682 {
6683 /* Read the first 4 bytes. For a 32-bit DWARF section, this will
6684 be the length. For a 64-bit DWARF section, it'll be the escape
6685 code 0xffffffff followed by an 8 byte length. */
6686 length = byte_get (begin, 4);
6687
6688 if (length == 0xffffffff)
6689 {
6690 length = byte_get (begin + 4, 8);
6691 begin += length + 12;
6692 }
6693 else
6694 begin += length + 4;
6695 }
6696
6697 if (num_units == 0)
6698 {
6699 error (_("No comp units in .debug_info section ?"));
6700 free (start);
6701 return 0;
6702 }
6703
6704 /* Then allocate an array to hold the pointer sizes. */
6705 debug_line_pointer_sizes = malloc (num_units * sizeof * debug_line_pointer_sizes);
6706 if (debug_line_pointer_sizes == NULL)
6707 {
6708 error (_("Not enough memory for a pointer size array of %u entries"),
6709 num_units);
6710 free (start);
6711 return 0;
6712 }
6713
6714 /* Populate the array. */
6715 for (begin = start, unit = 0; begin < end; unit++)
6716 {
6717 length = byte_get (begin, 4);
6718 if (length == 0xffffffff)
6719 {
6720 /* For 64-bit DWARF, the 1-byte address_size field is 22 bytes
6721 from the start of the section. This is computed as follows:
6722
6723 unit_length: 12 bytes
6724 version: 2 bytes
6725 debug_abbrev_offset: 8 bytes
6726 -----------------------------
6727 Total: 22 bytes */
6728
6729 debug_line_pointer_sizes [unit] = byte_get (begin + 22, 1);
6730 length = byte_get (begin + 4, 8);
6731 begin += length + 12;
6732 }
6733 else
6734 {
6735 /* For 32-bit DWARF, the 1-byte address_size field is 10 bytes from
6736 the start of the section:
0de14b54 6737
d9296b18
NC
6738 unit_length: 4 bytes
6739 version: 2 bytes
6740 debug_abbrev_offset: 4 bytes
6741 -----------------------------
6742 Total: 10 bytes */
6743
6744 debug_line_pointer_sizes [unit] = byte_get (begin + 10, 1);
6745 begin += length + 4;
6746 }
6747 }
6748
6749 free (start);
6750 num_debug_line_pointer_sizes = num_units;
6751 return num_units;
6752}
6753
252b5132 6754static int
d3ba0551 6755display_debug_lines (Elf_Internal_Shdr *section,
d9296b18 6756 unsigned char *start, FILE *file)
252b5132 6757{
ee42cf8c 6758 unsigned char *hdrptr;
b34976b6
AM
6759 DWARF2_Internal_LineInfo info;
6760 unsigned char *standard_opcodes;
6761 unsigned char *data = start;
6762 unsigned char *end = start + section->sh_size;
6763 unsigned char *end_of_sequence;
6764 int i;
ee42cf8c
NC
6765 int offset_size;
6766 int initial_length_size;
0e0c4098 6767 unsigned int comp_unit = 0;
252b5132
RH
6768
6769 printf (_("\nDump of debug contents of section %s:\n\n"),
6770 SECTION_NAME (section));
6771
d9296b18
NC
6772 if (num_debug_line_pointer_sizes == 0)
6773 get_debug_line_pointer_sizes (file);
6774
252b5132
RH
6775 while (data < end)
6776 {
0e0c4098
NC
6777 unsigned int pointer_size;
6778
ee42cf8c 6779 hdrptr = data;
252b5132
RH
6780
6781 /* Check the length of the block. */
ee42cf8c
NC
6782 info.li_length = byte_get (hdrptr, 4);
6783 hdrptr += 4;
428409d5
NC
6784
6785 if (info.li_length == 0xffffffff)
6786 {
ee42cf8c
NC
6787 /* This section is 64-bit DWARF 3. */
6788 info.li_length = byte_get (hdrptr, 8);
6789 hdrptr += 8;
6790 offset_size = 8;
6791 initial_length_size = 12;
6792 }
6793 else
6794 {
6795 offset_size = 4;
6796 initial_length_size = 4;
428409d5
NC
6797 }
6798
ee42cf8c 6799 if (info.li_length + initial_length_size > section->sh_size)
252b5132
RH
6800 {
6801 warn
6802 (_("The line info appears to be corrupt - the section is too small\n"));
6803 return 0;
6804 }
103f02d3 6805
252b5132 6806 /* Check its version number. */
ee42cf8c
NC
6807 info.li_version = byte_get (hdrptr, 2);
6808 hdrptr += 2;
6809 if (info.li_version != 2 && info.li_version != 3)
252b5132 6810 {
ee42cf8c 6811 warn (_("Only DWARF version 2 and 3 line info is currently supported.\n"));
252b5132
RH
6812 return 0;
6813 }
103f02d3 6814
ee42cf8c
NC
6815 info.li_prologue_length = byte_get (hdrptr, offset_size);
6816 hdrptr += offset_size;
6817 info.li_min_insn_length = byte_get (hdrptr, 1);
6818 hdrptr++;
6819 info.li_default_is_stmt = byte_get (hdrptr, 1);
6820 hdrptr++;
6821 info.li_line_base = byte_get (hdrptr, 1);
6822 hdrptr++;
6823 info.li_line_range = byte_get (hdrptr, 1);
6824 hdrptr++;
6825 info.li_opcode_base = byte_get (hdrptr, 1);
6826 hdrptr++;
103f02d3 6827
252b5132
RH
6828 /* Sign extend the line base field. */
6829 info.li_line_base <<= 24;
6830 info.li_line_base >>= 24;
103f02d3 6831
0e0c4098
NC
6832 /* Get the pointer size from the comp unit associated
6833 with this block of line number information. */
6834 if (comp_unit >= num_debug_line_pointer_sizes)
6835 {
6836 error (_("Not enough comp units for .debug_lines section\n"));
6837 return 0;
6838 }
6839 else
6840 {
6841 pointer_size = debug_line_pointer_sizes [comp_unit];
6842 comp_unit ++;
6843 }
6844
252b5132
RH
6845 printf (_(" Length: %ld\n"), info.li_length);
6846 printf (_(" DWARF Version: %d\n"), info.li_version);
ff94ebf2 6847 printf (_(" Prologue Length: %d\n"), info.li_prologue_length);
252b5132
RH
6848 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
6849 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
6850 printf (_(" Line Base: %d\n"), info.li_line_base);
6851 printf (_(" Line Range: %d\n"), info.li_line_range);
6852 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
0e0c4098 6853 printf (_(" (Pointer size: %u)\n"), pointer_size);
252b5132 6854
ee42cf8c 6855 end_of_sequence = data + info.li_length + initial_length_size;
252b5132
RH
6856
6857 reset_state_machine (info.li_default_is_stmt);
103f02d3 6858
252b5132 6859 /* Display the contents of the Opcodes table. */
ee42cf8c 6860 standard_opcodes = hdrptr;
103f02d3 6861
252b5132 6862 printf (_("\n Opcodes:\n"));
103f02d3 6863
252b5132 6864 for (i = 1; i < info.li_opcode_base; i++)
7a4b7442 6865 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
103f02d3 6866
252b5132
RH
6867 /* Display the contents of the Directory table. */
6868 data = standard_opcodes + info.li_opcode_base - 1;
103f02d3 6869
b34976b6 6870 if (*data == 0)
252b5132
RH
6871 printf (_("\n The Directory Table is empty.\n"));
6872 else
6873 {
6874 printf (_("\n The Directory Table:\n"));
103f02d3 6875
b34976b6 6876 while (*data != 0)
252b5132
RH
6877 {
6878 printf (_(" %s\n"), data);
103f02d3 6879
3c9f43b1 6880 data += strlen ((char *) data) + 1;
252b5132
RH
6881 }
6882 }
103f02d3 6883
252b5132 6884 /* Skip the NUL at the end of the table. */
b34976b6 6885 data++;
103f02d3 6886
252b5132 6887 /* Display the contents of the File Name table. */
b34976b6 6888 if (*data == 0)
252b5132
RH
6889 printf (_("\n The File Name Table is empty.\n"));
6890 else
6891 {
6892 printf (_("\n The File Name Table:\n"));
6893 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
103f02d3 6894
b34976b6 6895 while (*data != 0)
252b5132 6896 {
b34976b6 6897 unsigned char *name;
252b5132 6898 int bytes_read;
103f02d3 6899
b34976b6 6900 printf (_(" %d\t"), ++state_machine_regs.last_file_entry);
252b5132 6901 name = data;
103f02d3 6902
3c9f43b1 6903 data += strlen ((char *) data) + 1;
103f02d3 6904
252b5132
RH
6905 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6906 data += bytes_read;
6907 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6908 data += bytes_read;
6909 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6910 data += bytes_read;
6911 printf (_("%s\n"), name);
6912 }
6913 }
103f02d3 6914
252b5132 6915 /* Skip the NUL at the end of the table. */
b34976b6 6916 data++;
103f02d3 6917
252b5132
RH
6918 /* Now display the statements. */
6919 printf (_("\n Line Number Statements:\n"));
103f02d3
UD
6920
6921
252b5132
RH
6922 while (data < end_of_sequence)
6923 {
6924 unsigned char op_code;
b34976b6
AM
6925 int adv;
6926 int bytes_read;
103f02d3 6927
b34976b6 6928 op_code = *data++;
103f02d3 6929
1a509dcc
GK
6930 if (op_code >= info.li_opcode_base)
6931 {
6932 op_code -= info.li_opcode_base;
6933 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
6934 state_machine_regs.address += adv;
6935 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
6936 op_code, adv, state_machine_regs.address);
6937 adv = (op_code % info.li_line_range) + info.li_line_base;
6938 state_machine_regs.line += adv;
6939 printf (_(" and Line by %d to %d\n"),
6940 adv, state_machine_regs.line);
53c7db4b
KH
6941 }
6942 else switch (op_code)
252b5132
RH
6943 {
6944 case DW_LNS_extended_op:
3590ea00 6945 data += process_extended_line_op (data, info.li_default_is_stmt,
0e0c4098 6946 pointer_size);
252b5132 6947 break;
103f02d3 6948
252b5132
RH
6949 case DW_LNS_copy:
6950 printf (_(" Copy\n"));
6951 break;
103f02d3 6952
252b5132
RH
6953 case DW_LNS_advance_pc:
6954 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
6955 data += bytes_read;
6956 state_machine_regs.address += adv;
6957 printf (_(" Advance PC by %d to %lx\n"), adv,
6958 state_machine_regs.address);
6959 break;
103f02d3 6960
252b5132
RH
6961 case DW_LNS_advance_line:
6962 adv = read_leb128 (data, & bytes_read, 1);
6963 data += bytes_read;
6964 state_machine_regs.line += adv;
6965 printf (_(" Advance Line by %d to %d\n"), adv,
6966 state_machine_regs.line);
6967 break;
103f02d3 6968
252b5132
RH
6969 case DW_LNS_set_file:
6970 adv = read_leb128 (data, & bytes_read, 0);
6971 data += bytes_read;
6972 printf (_(" Set File Name to entry %d in the File Name Table\n"),
6973 adv);
6974 state_machine_regs.file = adv;
6975 break;
103f02d3 6976
252b5132
RH
6977 case DW_LNS_set_column:
6978 adv = read_leb128 (data, & bytes_read, 0);
6979 data += bytes_read;
6980 printf (_(" Set column to %d\n"), adv);
6981 state_machine_regs.column = adv;
6982 break;
103f02d3 6983
252b5132
RH
6984 case DW_LNS_negate_stmt:
6985 adv = state_machine_regs.is_stmt;
6986 adv = ! adv;
6987 printf (_(" Set is_stmt to %d\n"), adv);
6988 state_machine_regs.is_stmt = adv;
6989 break;
103f02d3 6990
252b5132
RH
6991 case DW_LNS_set_basic_block:
6992 printf (_(" Set basic block\n"));
6993 state_machine_regs.basic_block = 1;
6994 break;
103f02d3 6995
252b5132 6996 case DW_LNS_const_add_pc:
2366453a
NC
6997 adv = (((255 - info.li_opcode_base) / info.li_line_range)
6998 * info.li_min_insn_length);
252b5132
RH
6999 state_machine_regs.address += adv;
7000 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
7001 state_machine_regs.address);
7002 break;
103f02d3 7003
252b5132
RH
7004 case DW_LNS_fixed_advance_pc:
7005 adv = byte_get (data, 2);
7006 data += 2;
7007 state_machine_regs.address += adv;
7008 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
7009 adv, state_machine_regs.address);
7010 break;
103f02d3 7011
1a509dcc
GK
7012 case DW_LNS_set_prologue_end:
7013 printf (_(" Set prologue_end to true\n"));
7014 break;
53c7db4b 7015
1a509dcc
GK
7016 case DW_LNS_set_epilogue_begin:
7017 printf (_(" Set epilogue_begin to true\n"));
7018 break;
53c7db4b 7019
1a509dcc
GK
7020 case DW_LNS_set_isa:
7021 adv = read_leb128 (data, & bytes_read, 0);
7022 data += bytes_read;
7023 printf (_(" Set ISA to %d\n"), adv);
7024 break;
53c7db4b 7025
252b5132 7026 default:
1a509dcc
GK
7027 printf (_(" Unknown opcode %d with operands: "), op_code);
7028 {
7029 int i;
7030 for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
7031 {
7032 printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
7033 i == 1 ? "" : ", ");
7034 data += bytes_read;
7035 }
7036 putchar ('\n');
7037 }
252b5132
RH
7038 break;
7039 }
7040 }
1a509dcc 7041 putchar ('\n');
252b5132 7042 }
103f02d3 7043
252b5132
RH
7044 return 1;
7045}
7046
7047static int
d3ba0551
AM
7048display_debug_pubnames (Elf_Internal_Shdr *section,
7049 unsigned char *start,
7050 FILE *file ATTRIBUTE_UNUSED)
252b5132 7051{
b34976b6
AM
7052 DWARF2_Internal_PubNames pubnames;
7053 unsigned char *end;
252b5132
RH
7054
7055 end = start + section->sh_size;
7056
7057 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
7058
7059 while (start < end)
7060 {
b34976b6
AM
7061 unsigned char *data;
7062 unsigned long offset;
ee42cf8c 7063 int offset_size, initial_length_size;
252b5132 7064
ee42cf8c 7065 data = start;
252b5132 7066
ee42cf8c
NC
7067 pubnames.pn_length = byte_get (data, 4);
7068 data += 4;
428409d5
NC
7069 if (pubnames.pn_length == 0xffffffff)
7070 {
ee42cf8c
NC
7071 pubnames.pn_length = byte_get (data, 8);
7072 data += 8;
7073 offset_size = 8;
7074 initial_length_size = 12;
7075 }
7076 else
7077 {
7078 offset_size = 4;
7079 initial_length_size = 4;
428409d5
NC
7080 }
7081
ee42cf8c
NC
7082 pubnames.pn_version = byte_get (data, 2);
7083 data += 2;
7084 pubnames.pn_offset = byte_get (data, offset_size);
7085 data += offset_size;
7086 pubnames.pn_size = byte_get (data, offset_size);
7087 data += offset_size;
7088
7089 start += pubnames.pn_length + initial_length_size;
7090
7091 if (pubnames.pn_version != 2 && pubnames.pn_version != 3)
252b5132 7092 {
3f215a10
NC
7093 static int warned = 0;
7094
7095 if (! warned)
7096 {
ee42cf8c 7097 warn (_("Only DWARF 2 and 3 pubnames are currently supported\n"));
3f215a10
NC
7098 warned = 1;
7099 }
76da6bbe 7100
252b5132
RH
7101 continue;
7102 }
7103
7104 printf (_(" Length: %ld\n"),
7105 pubnames.pn_length);
7106 printf (_(" Version: %d\n"),
7107 pubnames.pn_version);
7108 printf (_(" Offset into .debug_info section: %ld\n"),
7109 pubnames.pn_offset);
7110 printf (_(" Size of area in .debug_info section: %ld\n"),
7111 pubnames.pn_size);
7112
7113 printf (_("\n Offset\tName\n"));
7114
7115 do
7116 {
ee42cf8c 7117 offset = byte_get (data, offset_size);
252b5132
RH
7118
7119 if (offset != 0)
7120 {
ee42cf8c 7121 data += offset_size;
935a41f5 7122 printf (" %-6ld\t\t%s\n", offset, data);
3c9f43b1 7123 data += strlen ((char *) data) + 1;
252b5132
RH
7124 }
7125 }
7126 while (offset != 0);
7127 }
7128
7129 printf ("\n");
7130 return 1;
7131}
7132
7133static char *
d3ba0551 7134get_TAG_name (unsigned long tag)
252b5132
RH
7135{
7136 switch (tag)
7137 {
b34976b6
AM
7138 case DW_TAG_padding: return "DW_TAG_padding";
7139 case DW_TAG_array_type: return "DW_TAG_array_type";
7140 case DW_TAG_class_type: return "DW_TAG_class_type";
7141 case DW_TAG_entry_point: return "DW_TAG_entry_point";
7142 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
7143 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
7144 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
7145 case DW_TAG_label: return "DW_TAG_label";
7146 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
7147 case DW_TAG_member: return "DW_TAG_member";
7148 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
7149 case DW_TAG_reference_type: return "DW_TAG_reference_type";
7150 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
7151 case DW_TAG_string_type: return "DW_TAG_string_type";
7152 case DW_TAG_structure_type: return "DW_TAG_structure_type";
7153 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
7154 case DW_TAG_typedef: return "DW_TAG_typedef";
7155 case DW_TAG_union_type: return "DW_TAG_union_type";
252b5132 7156 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
b34976b6
AM
7157 case DW_TAG_variant: return "DW_TAG_variant";
7158 case DW_TAG_common_block: return "DW_TAG_common_block";
7159 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
7160 case DW_TAG_inheritance: return "DW_TAG_inheritance";
7161 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
7162 case DW_TAG_module: return "DW_TAG_module";
7163 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
7164 case DW_TAG_set_type: return "DW_TAG_set_type";
7165 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
7166 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
7167 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
7168 case DW_TAG_base_type: return "DW_TAG_base_type";
7169 case DW_TAG_catch_block: return "DW_TAG_catch_block";
7170 case DW_TAG_const_type: return "DW_TAG_const_type";
7171 case DW_TAG_constant: return "DW_TAG_constant";
7172 case DW_TAG_enumerator: return "DW_TAG_enumerator";
7173 case DW_TAG_file_type: return "DW_TAG_file_type";
7174 case DW_TAG_friend: return "DW_TAG_friend";
7175 case DW_TAG_namelist: return "DW_TAG_namelist";
7176 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
7177 case DW_TAG_packed_type: return "DW_TAG_packed_type";
7178 case DW_TAG_subprogram: return "DW_TAG_subprogram";
7179 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
7180 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
7181 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
7182 case DW_TAG_try_block: return "DW_TAG_try_block";
7183 case DW_TAG_variant_part: return "DW_TAG_variant_part";
7184 case DW_TAG_variable: return "DW_TAG_variable";
7185 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
7186 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
7187 case DW_TAG_format_label: return "DW_TAG_format_label";
7188 case DW_TAG_function_template: return "DW_TAG_function_template";
7189 case DW_TAG_class_template: return "DW_TAG_class_template";
b811889f 7190 /* DWARF 2.1 values. */
b34976b6
AM
7191 case DW_TAG_dwarf_procedure: return "DW_TAG_dwarf_procedure";
7192 case DW_TAG_restrict_type: return "DW_TAG_restrict_type";
7193 case DW_TAG_interface_type: return "DW_TAG_interface_type";
7194 case DW_TAG_namespace: return "DW_TAG_namespace";
7195 case DW_TAG_imported_module: return "DW_TAG_imported_module";
7196 case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type";
7197 case DW_TAG_partial_unit: return "DW_TAG_partial_unit";
7198 case DW_TAG_imported_unit: return "DW_TAG_imported_unit";
84ad6ede 7199 /* UPC values. */
ba2685cc
AM
7200 case DW_TAG_upc_shared_type: return "DW_TAG_upc_shared_type";
7201 case DW_TAG_upc_strict_type: return "DW_TAG_upc_strict_type";
7202 case DW_TAG_upc_relaxed_type: return "DW_TAG_upc_relaxed_type";
252b5132
RH
7203 default:
7204 {
b34976b6 7205 static char buffer[100];
252b5132
RH
7206
7207 sprintf (buffer, _("Unknown TAG value: %lx"), tag);
7208 return buffer;
7209 }
7210 }
7211}
7212
7213static char *
d3ba0551 7214get_AT_name (unsigned long attribute)
252b5132
RH
7215{
7216 switch (attribute)
7217 {
b34976b6
AM
7218 case DW_AT_sibling: return "DW_AT_sibling";
7219 case DW_AT_location: return "DW_AT_location";
7220 case DW_AT_name: return "DW_AT_name";
7221 case DW_AT_ordering: return "DW_AT_ordering";
7222 case DW_AT_subscr_data: return "DW_AT_subscr_data";
7223 case DW_AT_byte_size: return "DW_AT_byte_size";
7224 case DW_AT_bit_offset: return "DW_AT_bit_offset";
7225 case DW_AT_bit_size: return "DW_AT_bit_size";
7226 case DW_AT_element_list: return "DW_AT_element_list";
7227 case DW_AT_stmt_list: return "DW_AT_stmt_list";
7228 case DW_AT_low_pc: return "DW_AT_low_pc";
7229 case DW_AT_high_pc: return "DW_AT_high_pc";
7230 case DW_AT_language: return "DW_AT_language";
7231 case DW_AT_member: return "DW_AT_member";
7232 case DW_AT_discr: return "DW_AT_discr";
7233 case DW_AT_discr_value: return "DW_AT_discr_value";
7234 case DW_AT_visibility: return "DW_AT_visibility";
7235 case DW_AT_import: return "DW_AT_import";
7236 case DW_AT_string_length: return "DW_AT_string_length";
7237 case DW_AT_common_reference: return "DW_AT_common_reference";
7238 case DW_AT_comp_dir: return "DW_AT_comp_dir";
7239 case DW_AT_const_value: return "DW_AT_const_value";
7240 case DW_AT_containing_type: return "DW_AT_containing_type";
7241 case DW_AT_default_value: return "DW_AT_default_value";
7242 case DW_AT_inline: return "DW_AT_inline";
7243 case DW_AT_is_optional: return "DW_AT_is_optional";
7244 case DW_AT_lower_bound: return "DW_AT_lower_bound";
7245 case DW_AT_producer: return "DW_AT_producer";
7246 case DW_AT_prototyped: return "DW_AT_prototyped";
7247 case DW_AT_return_addr: return "DW_AT_return_addr";
7248 case DW_AT_start_scope: return "DW_AT_start_scope";
7249 case DW_AT_stride_size: return "DW_AT_stride_size";
7250 case DW_AT_upper_bound: return "DW_AT_upper_bound";
7251 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
7252 case DW_AT_accessibility: return "DW_AT_accessibility";
7253 case DW_AT_address_class: return "DW_AT_address_class";
7254 case DW_AT_artificial: return "DW_AT_artificial";
7255 case DW_AT_base_types: return "DW_AT_base_types";
7256 case DW_AT_calling_convention: return "DW_AT_calling_convention";
7257 case DW_AT_count: return "DW_AT_count";
7258 case DW_AT_data_member_location: return "DW_AT_data_member_location";
7259 case DW_AT_decl_column: return "DW_AT_decl_column";
7260 case DW_AT_decl_file: return "DW_AT_decl_file";
7261 case DW_AT_decl_line: return "DW_AT_decl_line";
7262 case DW_AT_declaration: return "DW_AT_declaration";
7263 case DW_AT_discr_list: return "DW_AT_discr_list";
7264 case DW_AT_encoding: return "DW_AT_encoding";
7265 case DW_AT_external: return "DW_AT_external";
7266 case DW_AT_frame_base: return "DW_AT_frame_base";
7267 case DW_AT_friend: return "DW_AT_friend";
7268 case DW_AT_identifier_case: return "DW_AT_identifier_case";
7269 case DW_AT_macro_info: return "DW_AT_macro_info";
7270 case DW_AT_namelist_items: return "DW_AT_namelist_items";
7271 case DW_AT_priority: return "DW_AT_priority";
7272 case DW_AT_segment: return "DW_AT_segment";
7273 case DW_AT_specification: return "DW_AT_specification";
7274 case DW_AT_static_link: return "DW_AT_static_link";
7275 case DW_AT_type: return "DW_AT_type";
7276 case DW_AT_use_location: return "DW_AT_use_location";
7277 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
7278 case DW_AT_virtuality: return "DW_AT_virtuality";
7279 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
12ab83a9 7280 /* DWARF 2.1 values. */
b34976b6
AM
7281 case DW_AT_allocated: return "DW_AT_allocated";
7282 case DW_AT_associated: return "DW_AT_associated";
7283 case DW_AT_data_location: return "DW_AT_data_location";
7284 case DW_AT_stride: return "DW_AT_stride";
7285 case DW_AT_entry_pc: return "DW_AT_entry_pc";
7286 case DW_AT_use_UTF8: return "DW_AT_use_UTF8";
7287 case DW_AT_extension: return "DW_AT_extension";
7288 case DW_AT_ranges: return "DW_AT_ranges";
7289 case DW_AT_trampoline: return "DW_AT_trampoline";
7290 case DW_AT_call_column: return "DW_AT_call_column";
7291 case DW_AT_call_file: return "DW_AT_call_file";
7292 case DW_AT_call_line: return "DW_AT_call_line";
12ab83a9 7293 /* SGI/MIPS extensions. */
b34976b6
AM
7294 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
7295 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
7296 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
7297 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
252b5132 7298 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
b34976b6
AM
7299 case DW_AT_MIPS_software_pipeline_depth:
7300 return "DW_AT_MIPS_software_pipeline_depth";
7301 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
7302 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
7303 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
7304 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
7305 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
12ab83a9 7306 /* GNU extensions. */
b34976b6
AM
7307 case DW_AT_sf_names: return "DW_AT_sf_names";
7308 case DW_AT_src_info: return "DW_AT_src_info";
7309 case DW_AT_mac_info: return "DW_AT_mac_info";
7310 case DW_AT_src_coords: return "DW_AT_src_coords";
7311 case DW_AT_body_begin: return "DW_AT_body_begin";
7312 case DW_AT_body_end: return "DW_AT_body_end";
7313 case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
84ad6ede
NC
7314 /* UPC extension. */
7315 case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled";
252b5132
RH
7316 default:
7317 {
b34976b6 7318 static char buffer[100];
252b5132
RH
7319
7320 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
7321 return buffer;
7322 }
7323 }
7324}
7325
7326static char *
d3ba0551 7327get_FORM_name (unsigned long form)
252b5132
RH
7328{
7329 switch (form)
7330 {
b34976b6
AM
7331 case DW_FORM_addr: return "DW_FORM_addr";
7332 case DW_FORM_block2: return "DW_FORM_block2";
7333 case DW_FORM_block4: return "DW_FORM_block4";
7334 case DW_FORM_data2: return "DW_FORM_data2";
7335 case DW_FORM_data4: return "DW_FORM_data4";
7336 case DW_FORM_data8: return "DW_FORM_data8";
7337 case DW_FORM_string: return "DW_FORM_string";
7338 case DW_FORM_block: return "DW_FORM_block";
7339 case DW_FORM_block1: return "DW_FORM_block1";
7340 case DW_FORM_data1: return "DW_FORM_data1";
7341 case DW_FORM_flag: return "DW_FORM_flag";
7342 case DW_FORM_sdata: return "DW_FORM_sdata";
7343 case DW_FORM_strp: return "DW_FORM_strp";
7344 case DW_FORM_udata: return "DW_FORM_udata";
7345 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
7346 case DW_FORM_ref1: return "DW_FORM_ref1";
7347 case DW_FORM_ref2: return "DW_FORM_ref2";
7348 case DW_FORM_ref4: return "DW_FORM_ref4";
7349 case DW_FORM_ref8: return "DW_FORM_ref8";
7350 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
7351 case DW_FORM_indirect: return "DW_FORM_indirect";
252b5132
RH
7352 default:
7353 {
b34976b6 7354 static char buffer[100];
252b5132
RH
7355
7356 sprintf (buffer, _("Unknown FORM value: %lx"), form);
7357 return buffer;
7358 }
7359 }
7360}
7361
50c2245b 7362/* FIXME: There are better and more efficient ways to handle
252b5132
RH
7363 these structures. For now though, I just want something that
7364 is simple to implement. */
7365typedef struct abbrev_attr
7366{
b34976b6
AM
7367 unsigned long attribute;
7368 unsigned long form;
7369 struct abbrev_attr *next;
252b5132
RH
7370}
7371abbrev_attr;
7372
7373typedef struct abbrev_entry
7374{
b34976b6
AM
7375 unsigned long entry;
7376 unsigned long tag;
7377 int children;
7378 struct abbrev_attr *first_attr;
7379 struct abbrev_attr *last_attr;
7380 struct abbrev_entry *next;
252b5132
RH
7381}
7382abbrev_entry;
7383
b34976b6
AM
7384static abbrev_entry *first_abbrev = NULL;
7385static abbrev_entry *last_abbrev = NULL;
252b5132
RH
7386
7387static void
d3ba0551 7388free_abbrevs (void)
252b5132 7389{
b34976b6 7390 abbrev_entry *abbrev;
252b5132
RH
7391
7392 for (abbrev = first_abbrev; abbrev;)
7393 {
b34976b6
AM
7394 abbrev_entry *next = abbrev->next;
7395 abbrev_attr *attr;
252b5132
RH
7396
7397 for (attr = abbrev->first_attr; attr;)
7398 {
b34976b6 7399 abbrev_attr *next = attr->next;
252b5132
RH
7400
7401 free (attr);
7402 attr = next;
7403 }
7404
7405 free (abbrev);
7406 abbrev = next;
7407 }
7408
7409 last_abbrev = first_abbrev = NULL;
7410}
7411
7412static void
d3ba0551 7413add_abbrev (unsigned long number, unsigned long tag, int children)
252b5132 7414{
b34976b6 7415 abbrev_entry *entry;
252b5132 7416
d3ba0551 7417 entry = malloc (sizeof (*entry));
252b5132
RH
7418
7419 if (entry == NULL)
7420 /* ugg */
7421 return;
7422
7423 entry->entry = number;
7424 entry->tag = tag;
7425 entry->children = children;
7426 entry->first_attr = NULL;
7427 entry->last_attr = NULL;
7428 entry->next = NULL;
7429
7430 if (first_abbrev == NULL)
7431 first_abbrev = entry;
7432 else
7433 last_abbrev->next = entry;
7434
7435 last_abbrev = entry;
7436}
7437
7438static void
d3ba0551 7439add_abbrev_attr (unsigned long attribute, unsigned long form)
252b5132 7440{
b34976b6 7441 abbrev_attr *attr;
252b5132 7442
d3ba0551 7443 attr = malloc (sizeof (*attr));
252b5132
RH
7444
7445 if (attr == NULL)
7446 /* ugg */
7447 return;
7448
7449 attr->attribute = attribute;
7450 attr->form = form;
7451 attr->next = NULL;
7452
7453 if (last_abbrev->first_attr == NULL)
7454 last_abbrev->first_attr = attr;
7455 else
7456 last_abbrev->last_attr->next = attr;
7457
7458 last_abbrev->last_attr = attr;
7459}
7460
7461/* Processes the (partial) contents of a .debug_abbrev section.
7462 Returns NULL if the end of the section was encountered.
7463 Returns the address after the last byte read if the end of
7464 an abbreviation set was found. */
7465
7466static unsigned char *
d3ba0551 7467process_abbrev_section (unsigned char *start, unsigned char *end)
252b5132
RH
7468{
7469 if (first_abbrev != NULL)
7470 return NULL;
7471
7472 while (start < end)
7473 {
b34976b6 7474 int bytes_read;
252b5132
RH
7475 unsigned long entry;
7476 unsigned long tag;
7477 unsigned long attribute;
b34976b6 7478 int children;
252b5132
RH
7479
7480 entry = read_leb128 (start, & bytes_read, 0);
7481 start += bytes_read;
7482
a3f779db
NC
7483 /* A single zero is supposed to end the section according
7484 to the standard. If there's more, then signal that to
7485 the caller. */
252b5132 7486 if (entry == 0)
a3f779db 7487 return start == end ? NULL : start;
252b5132
RH
7488
7489 tag = read_leb128 (start, & bytes_read, 0);
7490 start += bytes_read;
7491
b34976b6 7492 children = *start++;
252b5132
RH
7493
7494 add_abbrev (entry, tag, children);
7495
7496 do
7497 {
7498 unsigned long form;
7499
7500 attribute = read_leb128 (start, & bytes_read, 0);
7501 start += bytes_read;
7502
7503 form = read_leb128 (start, & bytes_read, 0);
7504 start += bytes_read;
7505
7506 if (attribute != 0)
7507 add_abbrev_attr (attribute, form);
7508 }
7509 while (attribute != 0);
7510 }
7511
7512 return NULL;
7513}
7514
7515
e0c60db2 7516static int
d3ba0551
AM
7517display_debug_macinfo (Elf_Internal_Shdr *section,
7518 unsigned char *start,
7519 FILE *file ATTRIBUTE_UNUSED)
e0c60db2 7520{
b34976b6
AM
7521 unsigned char *end = start + section->sh_size;
7522 unsigned char *curr = start;
e0c60db2
NC
7523 unsigned int bytes_read;
7524 enum dwarf_macinfo_record_type op;
7525
7526 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
7527
7528 while (curr < end)
7529 {
7530 unsigned int lineno;
b34976b6 7531 const char *string;
e0c60db2 7532
b34976b6
AM
7533 op = *curr;
7534 curr++;
e0c60db2
NC
7535
7536 switch (op)
7537 {
7538 case DW_MACINFO_start_file:
7539 {
7540 unsigned int filenum;
7541
7542 lineno = read_leb128 (curr, & bytes_read, 0);
7543 curr += bytes_read;
7544 filenum = read_leb128 (curr, & bytes_read, 0);
7545 curr += bytes_read;
7546
7547 printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"), lineno, filenum);
7548 }
7549 break;
7550
7551 case DW_MACINFO_end_file:
7552 printf (_(" DW_MACINFO_end_file\n"));
7553 break;
7554
7555 case DW_MACINFO_define:
7556 lineno = read_leb128 (curr, & bytes_read, 0);
7557 curr += bytes_read;
7558 string = curr;
7559 curr += strlen (string) + 1;
7560 printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"), lineno, string);
7561 break;
7562
7563 case DW_MACINFO_undef:
7564 lineno = read_leb128 (curr, & bytes_read, 0);
7565 curr += bytes_read;
7566 string = curr;
7567 curr += strlen (string) + 1;
7568 printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"), lineno, string);
7569 break;
7570
7571 case DW_MACINFO_vendor_ext:
7572 {
7573 unsigned int constant;
7574
7575 constant = read_leb128 (curr, & bytes_read, 0);
7576 curr += bytes_read;
7577 string = curr;
7578 curr += strlen (string) + 1;
7579 printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"), constant, string);
7580 }
7581 break;
7582 }
7583 }
7584
7585 return 1;
7586}
0823fbca 7587
e0c60db2 7588
252b5132 7589static int
d3ba0551
AM
7590display_debug_abbrev (Elf_Internal_Shdr *section,
7591 unsigned char *start,
7592 FILE *file ATTRIBUTE_UNUSED)
252b5132 7593{
b34976b6
AM
7594 abbrev_entry *entry;
7595 unsigned char *end = start + section->sh_size;
252b5132
RH
7596
7597 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
7598
7599 do
7600 {
7601 start = process_abbrev_section (start, end);
7602
ef5cdfc7
JJ
7603 if (first_abbrev == NULL)
7604 continue;
7605
252b5132
RH
7606 printf (_(" Number TAG\n"));
7607
7608 for (entry = first_abbrev; entry; entry = entry->next)
7609 {
b34976b6 7610 abbrev_attr *attr;
252b5132
RH
7611
7612 printf (_(" %ld %s [%s]\n"),
7613 entry->entry,
7614 get_TAG_name (entry->tag),
7615 entry->children ? _("has children") : _("no children"));
7616
7617 for (attr = entry->first_attr; attr; attr = attr->next)
7618 {
7619 printf (_(" %-18s %s\n"),
7620 get_AT_name (attr->attribute),
7621 get_FORM_name (attr->form));
7622 }
7623 }
ef5cdfc7
JJ
7624
7625 free_abbrevs ();
252b5132
RH
7626 }
7627 while (start);
7628
7629 printf ("\n");
7630
7631 return 1;
7632}
7633
7634
7635static unsigned char *
d3ba0551 7636display_block (unsigned char *data, unsigned long length)
252b5132
RH
7637{
7638 printf (_(" %lu byte block: "), length);
7639
7640 while (length --)
b34976b6 7641 printf ("%lx ", (unsigned long) byte_get (data++, 1));
252b5132
RH
7642
7643 return data;
7644}
7645
7646static void
d3ba0551
AM
7647decode_location_expression (unsigned char * data,
7648 unsigned int pointer_size,
7649 unsigned long length)
252b5132 7650{
b34976b6
AM
7651 unsigned op;
7652 int bytes_read;
7653 unsigned long uvalue;
7654 unsigned char *end = data + length;
252b5132 7655
eb6bd4d3 7656 while (data < end)
252b5132 7657 {
b34976b6 7658 op = *data++;
252b5132 7659
eb6bd4d3
JM
7660 switch (op)
7661 {
7662 case DW_OP_addr:
7663 printf ("DW_OP_addr: %lx",
7664 (unsigned long) byte_get (data, pointer_size));
7665 data += pointer_size;
7666 break;
7667 case DW_OP_deref:
7668 printf ("DW_OP_deref");
7669 break;
7670 case DW_OP_const1u:
7671 printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
7672 break;
7673 case DW_OP_const1s:
74013231 7674 printf ("DW_OP_const1s: %ld", (long) byte_get_signed (data++, 1));
eb6bd4d3
JM
7675 break;
7676 case DW_OP_const2u:
7677 printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
7678 data += 2;
7679 break;
7680 case DW_OP_const2s:
74013231 7681 printf ("DW_OP_const2s: %ld", (long) byte_get_signed (data, 2));
eb6bd4d3
JM
7682 data += 2;
7683 break;
7684 case DW_OP_const4u:
7685 printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
7686 data += 4;
7687 break;
7688 case DW_OP_const4s:
74013231 7689 printf ("DW_OP_const4s: %ld", (long) byte_get_signed (data, 4));
eb6bd4d3
JM
7690 data += 4;
7691 break;
7692 case DW_OP_const8u:
7693 printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
7694 (unsigned long) byte_get (data + 4, 4));
7695 data += 8;
7696 break;
7697 case DW_OP_const8s:
7698 printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
7699 (long) byte_get (data + 4, 4));
7700 data += 8;
7701 break;
7702 case DW_OP_constu:
7703 printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
7704 data += bytes_read;
7705 break;
7706 case DW_OP_consts:
7707 printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
7708 data += bytes_read;
7709 break;
7710 case DW_OP_dup:
7711 printf ("DW_OP_dup");
7712 break;
7713 case DW_OP_drop:
7714 printf ("DW_OP_drop");
7715 break;
7716 case DW_OP_over:
7717 printf ("DW_OP_over");
7718 break;
7719 case DW_OP_pick:
7720 printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
7721 break;
7722 case DW_OP_swap:
7723 printf ("DW_OP_swap");
7724 break;
7725 case DW_OP_rot:
7726 printf ("DW_OP_rot");
7727 break;
7728 case DW_OP_xderef:
7729 printf ("DW_OP_xderef");
7730 break;
7731 case DW_OP_abs:
7732 printf ("DW_OP_abs");
7733 break;
7734 case DW_OP_and:
7735 printf ("DW_OP_and");
7736 break;
7737 case DW_OP_div:
7738 printf ("DW_OP_div");
7739 break;
7740 case DW_OP_minus:
7741 printf ("DW_OP_minus");
7742 break;
7743 case DW_OP_mod:
7744 printf ("DW_OP_mod");
7745 break;
7746 case DW_OP_mul:
7747 printf ("DW_OP_mul");
7748 break;
7749 case DW_OP_neg:
7750 printf ("DW_OP_neg");
7751 break;
7752 case DW_OP_not:
7753 printf ("DW_OP_not");
7754 break;
7755 case DW_OP_or:
7756 printf ("DW_OP_or");
7757 break;
7758 case DW_OP_plus:
7759 printf ("DW_OP_plus");
7760 break;
7761 case DW_OP_plus_uconst:
7762 printf ("DW_OP_plus_uconst: %lu",
7763 read_leb128 (data, &bytes_read, 0));
7764 data += bytes_read;
7765 break;
7766 case DW_OP_shl:
7767 printf ("DW_OP_shl");
7768 break;
7769 case DW_OP_shr:
7770 printf ("DW_OP_shr");
7771 break;
7772 case DW_OP_shra:
7773 printf ("DW_OP_shra");
7774 break;
7775 case DW_OP_xor:
7776 printf ("DW_OP_xor");
7777 break;
7778 case DW_OP_bra:
74013231 7779 printf ("DW_OP_bra: %ld", (long) byte_get_signed (data, 2));
eb6bd4d3
JM
7780 data += 2;
7781 break;
7782 case DW_OP_eq:
7783 printf ("DW_OP_eq");
7784 break;
7785 case DW_OP_ge:
7786 printf ("DW_OP_ge");
7787 break;
7788 case DW_OP_gt:
7789 printf ("DW_OP_gt");
7790 break;
7791 case DW_OP_le:
7792 printf ("DW_OP_le");
7793 break;
7794 case DW_OP_lt:
7795 printf ("DW_OP_lt");
7796 break;
7797 case DW_OP_ne:
7798 printf ("DW_OP_ne");
7799 break;
7800 case DW_OP_skip:
74013231 7801 printf ("DW_OP_skip: %ld", (long) byte_get_signed (data, 2));
eb6bd4d3
JM
7802 data += 2;
7803 break;
7804
7805 case DW_OP_lit0:
7806 case DW_OP_lit1:
7807 case DW_OP_lit2:
7808 case DW_OP_lit3:
7809 case DW_OP_lit4:
7810 case DW_OP_lit5:
7811 case DW_OP_lit6:
7812 case DW_OP_lit7:
7813 case DW_OP_lit8:
7814 case DW_OP_lit9:
7815 case DW_OP_lit10:
7816 case DW_OP_lit11:
7817 case DW_OP_lit12:
7818 case DW_OP_lit13:
7819 case DW_OP_lit14:
7820 case DW_OP_lit15:
7821 case DW_OP_lit16:
7822 case DW_OP_lit17:
7823 case DW_OP_lit18:
7824 case DW_OP_lit19:
7825 case DW_OP_lit20:
7826 case DW_OP_lit21:
7827 case DW_OP_lit22:
7828 case DW_OP_lit23:
7829 case DW_OP_lit24:
7830 case DW_OP_lit25:
7831 case DW_OP_lit26:
7832 case DW_OP_lit27:
7833 case DW_OP_lit28:
7834 case DW_OP_lit29:
7835 case DW_OP_lit30:
7836 case DW_OP_lit31:
7837 printf ("DW_OP_lit%d", op - DW_OP_lit0);
7838 break;
7839
7840 case DW_OP_reg0:
7841 case DW_OP_reg1:
7842 case DW_OP_reg2:
7843 case DW_OP_reg3:
7844 case DW_OP_reg4:
7845 case DW_OP_reg5:
7846 case DW_OP_reg6:
7847 case DW_OP_reg7:
7848 case DW_OP_reg8:
7849 case DW_OP_reg9:
7850 case DW_OP_reg10:
7851 case DW_OP_reg11:
7852 case DW_OP_reg12:
7853 case DW_OP_reg13:
7854 case DW_OP_reg14:
7855 case DW_OP_reg15:
7856 case DW_OP_reg16:
7857 case DW_OP_reg17:
7858 case DW_OP_reg18:
7859 case DW_OP_reg19:
7860 case DW_OP_reg20:
7861 case DW_OP_reg21:
7862 case DW_OP_reg22:
7863 case DW_OP_reg23:
7864 case DW_OP_reg24:
7865 case DW_OP_reg25:
7866 case DW_OP_reg26:
7867 case DW_OP_reg27:
7868 case DW_OP_reg28:
7869 case DW_OP_reg29:
7870 case DW_OP_reg30:
7871 case DW_OP_reg31:
7872 printf ("DW_OP_reg%d", op - DW_OP_reg0);
7873 break;
7874
7875 case DW_OP_breg0:
7876 case DW_OP_breg1:
7877 case DW_OP_breg2:
7878 case DW_OP_breg3:
7879 case DW_OP_breg4:
7880 case DW_OP_breg5:
7881 case DW_OP_breg6:
7882 case DW_OP_breg7:
7883 case DW_OP_breg8:
7884 case DW_OP_breg9:
7885 case DW_OP_breg10:
7886 case DW_OP_breg11:
7887 case DW_OP_breg12:
7888 case DW_OP_breg13:
7889 case DW_OP_breg14:
7890 case DW_OP_breg15:
7891 case DW_OP_breg16:
7892 case DW_OP_breg17:
7893 case DW_OP_breg18:
7894 case DW_OP_breg19:
7895 case DW_OP_breg20:
7896 case DW_OP_breg21:
7897 case DW_OP_breg22:
7898 case DW_OP_breg23:
7899 case DW_OP_breg24:
7900 case DW_OP_breg25:
7901 case DW_OP_breg26:
7902 case DW_OP_breg27:
7903 case DW_OP_breg28:
7904 case DW_OP_breg29:
7905 case DW_OP_breg30:
7906 case DW_OP_breg31:
7907 printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
7908 read_leb128 (data, &bytes_read, 1));
7909 data += bytes_read;
7910 break;
7911
7912 case DW_OP_regx:
7913 printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
7914 data += bytes_read;
7915 break;
7916 case DW_OP_fbreg:
7917 printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
7918 data += bytes_read;
7919 break;
7920 case DW_OP_bregx:
7921 uvalue = read_leb128 (data, &bytes_read, 0);
7922 data += bytes_read;
7923 printf ("DW_OP_bregx: %lu %ld", uvalue,
7924 read_leb128 (data, &bytes_read, 1));
7925 data += bytes_read;
7926 break;
7927 case DW_OP_piece:
7928 printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
7929 data += bytes_read;
7930 break;
7931 case DW_OP_deref_size:
7932 printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
7933 break;
7934 case DW_OP_xderef_size:
7935 printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
7936 break;
7937 case DW_OP_nop:
7938 printf ("DW_OP_nop");
7939 break;
7940
065c959b 7941 /* DWARF 3 extensions. */
12ab83a9
NC
7942 case DW_OP_push_object_address:
7943 printf ("DW_OP_push_object_address");
7944 break;
7945 case DW_OP_call2:
7946 printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2));
7947 data += 2;
7948 break;
7949 case DW_OP_call4:
7950 printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4));
7951 data += 4;
7952 break;
065c959b
NC
7953 case DW_OP_call_ref:
7954 printf ("DW_OP_call_ref");
7955 break;
7956
7957 /* GNU extensions. */
7958 case DW_OP_GNU_push_tls_address:
7959 printf ("DW_OP_GNU_push_tls_address");
12ab83a9
NC
7960 break;
7961
eb6bd4d3
JM
7962 default:
7963 if (op >= DW_OP_lo_user
7964 && op <= DW_OP_hi_user)
7965 printf (_("(User defined location op)"));
7966 else
7967 printf (_("(Unknown location op)"));
7968 /* No way to tell where the next op is, so just bail. */
7969 return;
7970 }
12ab83a9
NC
7971
7972 /* Separate the ops. */
3f7de0e7
NC
7973 if (data < end)
7974 printf ("; ");
252b5132
RH
7975 }
7976}
7977
b34976b6
AM
7978static const char *debug_loc_contents;
7979static bfd_vma debug_loc_size;
a2f14207
DB
7980
7981static void
d3ba0551 7982load_debug_loc (FILE *file)
a2f14207 7983{
b34976b6 7984 Elf_Internal_Shdr *sec;
a2f14207
DB
7985
7986 /* If it is already loaded, do nothing. */
7987 if (debug_loc_contents != NULL)
7988 return;
7989
7990 /* Locate the .debug_loc section. */
d9296b18
NC
7991 sec = find_section (".debug_loc");
7992 if (sec == NULL)
a2f14207
DB
7993 return;
7994
7995 debug_loc_size = sec->sh_size;
7996
d3ba0551
AM
7997 debug_loc_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
7998 _("debug_loc section data"));
a2f14207
DB
7999}
8000
8001static void
d3ba0551 8002free_debug_loc (void)
a2f14207
DB
8003{
8004 if (debug_loc_contents == NULL)
8005 return;
8006
8007 free ((char *) debug_loc_contents);
8008 debug_loc_contents = NULL;
8009 debug_loc_size = 0;
8010}
8011
a2f14207 8012
a2f14207 8013static int
d3ba0551 8014display_debug_loc (Elf_Internal_Shdr *section,
d9296b18 8015 unsigned char *start, FILE *file)
a2f14207
DB
8016{
8017 unsigned char *section_end;
8018 unsigned long bytes;
8019 unsigned char *section_begin = start;
8020 bfd_vma addr;
0e0c4098 8021 unsigned int comp_unit = 0;
53c7db4b 8022
a2f14207
DB
8023 addr = section->sh_addr;
8024 bytes = section->sh_size;
8025 section_end = start + bytes;
065c959b 8026
a2f14207
DB
8027 if (bytes == 0)
8028 {
8029 printf (_("\nThe .debug_loc section is empty.\n"));
8030 return 0;
8031 }
065c959b 8032
d9296b18
NC
8033 if (num_debug_line_pointer_sizes == 0)
8034 get_debug_line_pointer_sizes (file);
8035
a2f14207
DB
8036 printf (_("Contents of the .debug_loc section:\n\n"));
8037 printf (_("\n Offset Begin End Expression\n"));
065c959b 8038
a2f14207
DB
8039 while (start < section_end)
8040 {
8041 unsigned long begin;
8042 unsigned long end;
8043 unsigned short length;
8044 unsigned long offset;
0e0c4098 8045 unsigned int pointer_size;
a2f14207
DB
8046
8047 offset = start - section_begin;
8048
0e0c4098
NC
8049 /* Get the pointer size from the comp unit associated
8050 with this block of location information. */
8051 if (comp_unit >= num_debug_line_pointer_sizes)
8052 {
8053 error (_("Not enough comp units for .debug_loc section\n"));
8054 return 0;
8055 }
8056 else
8057 {
8058 pointer_size = debug_line_pointer_sizes [comp_unit];
8059 comp_unit ++;
8060 }
8061
a2f14207
DB
8062 while (1)
8063 {
0e0c4098
NC
8064 begin = byte_get (start, pointer_size);
8065 start += pointer_size;
8066 end = byte_get (start, pointer_size);
8067 start += pointer_size;
53c7db4b 8068
a2f14207
DB
8069 if (begin == 0 && end == 0)
8070 break;
53c7db4b 8071
8dde85fc
NC
8072 /* For now, skip any base address specifiers. */
8073 if (begin == 0xffffffff)
8074 continue;
8075
a2f14207
DB
8076 begin += addr;
8077 end += addr;
53c7db4b 8078
a2f14207
DB
8079 length = byte_get (start, 2);
8080 start += 2;
53c7db4b 8081
a2f14207 8082 printf (" %8.8lx %8.8lx %8.8lx (", offset, begin, end);
0e0c4098 8083 decode_location_expression (start, pointer_size, length);
a2f14207 8084 printf (")\n");
53c7db4b 8085
a2f14207
DB
8086 start += length;
8087 }
8088 printf ("\n");
8089 }
8090 return 1;
8091}
252b5132 8092
b34976b6
AM
8093static const char *debug_str_contents;
8094static bfd_vma debug_str_size;
261a45ad
NC
8095
8096static void
d3ba0551 8097load_debug_str (FILE *file)
261a45ad 8098{
b34976b6 8099 Elf_Internal_Shdr *sec;
261a45ad
NC
8100
8101 /* If it is already loaded, do nothing. */
8102 if (debug_str_contents != NULL)
8103 return;
8104
8105 /* Locate the .debug_str section. */
d9296b18
NC
8106 sec = find_section (".debug_str");
8107 if (sec == NULL)
261a45ad
NC
8108 return;
8109
8110 debug_str_size = sec->sh_size;
8111
d3ba0551
AM
8112 debug_str_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
8113 _("debug_str section data"));
261a45ad
NC
8114}
8115
8116static void
d3ba0551 8117free_debug_str (void)
261a45ad
NC
8118{
8119 if (debug_str_contents == NULL)
8120 return;
8121
8122 free ((char *) debug_str_contents);
8123 debug_str_contents = NULL;
8124 debug_str_size = 0;
8125}
8126
8127static const char *
d3ba0551 8128fetch_indirect_string (unsigned long offset)
261a45ad
NC
8129{
8130 if (debug_str_contents == NULL)
8131 return _("<no .debug_str section>");
8132
8133 if (offset > debug_str_size)
8134 return _("<offset is too big>");
8135
8136 return debug_str_contents + offset;
8137}
8138
261a45ad 8139static int
d3ba0551
AM
8140display_debug_str (Elf_Internal_Shdr *section,
8141 unsigned char *start,
8142 FILE *file ATTRIBUTE_UNUSED)
261a45ad 8143{
b34976b6
AM
8144 unsigned long bytes;
8145 bfd_vma addr;
261a45ad
NC
8146
8147 addr = section->sh_addr;
8148 bytes = section->sh_size;
8149
8150 if (bytes == 0)
8151 {
8152 printf (_("\nThe .debug_str section is empty.\n"));
8153 return 0;
8154 }
8155
8156 printf (_("Contents of the .debug_str section:\n\n"));
8157
8158 while (bytes)
8159 {
8160 int j;
8161 int k;
8162 int lbytes;
8163
8164 lbytes = (bytes > 16 ? 16 : bytes);
8165
8166 printf (" 0x%8.8lx ", (unsigned long) addr);
8167
8168 for (j = 0; j < 16; j++)
8169 {
8170 if (j < lbytes)
b34976b6 8171 printf ("%2.2x", start[j]);
261a45ad
NC
8172 else
8173 printf (" ");
8174
8175 if ((j & 3) == 3)
8176 printf (" ");
8177 }
8178
8179 for (j = 0; j < lbytes; j++)
8180 {
b34976b6 8181 k = start[j];
261a45ad
NC
8182 if (k >= ' ' && k < 0x80)
8183 printf ("%c", k);
8184 else
8185 printf (".");
8186 }
8187
8188 putchar ('\n');
8189
8190 start += lbytes;
8191 addr += lbytes;
8192 bytes -= lbytes;
8193 }
8194
8195 return 1;
8196}
8197
252b5132 8198static unsigned char *
d3ba0551
AM
8199read_and_display_attr_value (unsigned long attribute,
8200 unsigned long form,
8201 unsigned char *data,
8202 unsigned long cu_offset,
8203 unsigned long pointer_size,
8204 unsigned long offset_size,
8205 int dwarf_version)
252b5132 8206{
b34976b6
AM
8207 unsigned long uvalue = 0;
8208 unsigned char *block_start = NULL;
8209 int bytes_read;
252b5132 8210
252b5132
RH
8211 switch (form)
8212 {
60bcf0fa
NC
8213 default:
8214 break;
76da6bbe 8215
252b5132 8216 case DW_FORM_ref_addr:
ee42cf8c
NC
8217 if (dwarf_version == 2)
8218 {
8219 uvalue = byte_get (data, pointer_size);
8220 data += pointer_size;
8221 }
8222 else if (dwarf_version == 3)
8223 {
8224 uvalue = byte_get (data, offset_size);
8225 data += offset_size;
8226 }
8227 else
ba2685cc 8228 {
ee42cf8c
NC
8229 error (_("Internal error: DWARF version is not 2 or 3.\n"));
8230 }
8231 break;
8232
252b5132
RH
8233 case DW_FORM_addr:
8234 uvalue = byte_get (data, pointer_size);
252b5132
RH
8235 data += pointer_size;
8236 break;
8237
ef5cdfc7 8238 case DW_FORM_strp:
ee42cf8c
NC
8239 uvalue = byte_get (data, offset_size);
8240 data += offset_size;
ef5cdfc7
JJ
8241 break;
8242
252b5132
RH
8243 case DW_FORM_ref1:
8244 case DW_FORM_flag:
8245 case DW_FORM_data1:
b34976b6 8246 uvalue = byte_get (data++, 1);
252b5132
RH
8247 break;
8248
8249 case DW_FORM_ref2:
8250 case DW_FORM_data2:
8251 uvalue = byte_get (data, 2);
8252 data += 2;
252b5132
RH
8253 break;
8254
8255 case DW_FORM_ref4:
8256 case DW_FORM_data4:
8257 uvalue = byte_get (data, 4);
8258 data += 4;
1fa37306
JM
8259 break;
8260
8261 case DW_FORM_sdata:
8262 uvalue = read_leb128 (data, & bytes_read, 1);
8263 data += bytes_read;
8264 break;
8265
8266 case DW_FORM_ref_udata:
8267 case DW_FORM_udata:
8268 uvalue = read_leb128 (data, & bytes_read, 0);
8269 data += bytes_read;
8270 break;
81766fca
RH
8271
8272 case DW_FORM_indirect:
8273 form = read_leb128 (data, & bytes_read, 0);
8274 data += bytes_read;
8275 printf (" %s", get_FORM_name (form));
8276 return read_and_display_attr_value (attribute, form, data, cu_offset,
ee42cf8c
NC
8277 pointer_size, offset_size,
8278 dwarf_version);
1fa37306
JM
8279 }
8280
8281 switch (form)
8282 {
8283 case DW_FORM_ref_addr:
8284 printf (" <#%lx>", uvalue);
8285 break;
76da6bbe 8286
1fa37306
JM
8287 case DW_FORM_ref1:
8288 case DW_FORM_ref2:
8289 case DW_FORM_ref4:
8290 case DW_FORM_ref_udata:
8291 printf (" <%lx>", uvalue + cu_offset);
8292 break;
8293
8294 case DW_FORM_addr:
8295 printf (" %#lx", uvalue);
935a41f5 8296 break;
1fa37306
JM
8297
8298 case DW_FORM_flag:
8299 case DW_FORM_data1:
8300 case DW_FORM_data2:
8301 case DW_FORM_data4:
8302 case DW_FORM_sdata:
8303 case DW_FORM_udata:
8304 printf (" %ld", uvalue);
252b5132
RH
8305 break;
8306
8307 case DW_FORM_ref8:
8308 case DW_FORM_data8:
8309 uvalue = byte_get (data, 4);
8310 printf (" %lx", uvalue);
148d3c43 8311 printf (" %lx", (unsigned long) byte_get (data + 4, 4));
252b5132
RH
8312 data += 8;
8313 break;
8314
8315 case DW_FORM_string:
8316 printf (" %s", data);
3c9f43b1 8317 data += strlen ((char *) data) + 1;
252b5132
RH
8318 break;
8319
252b5132
RH
8320 case DW_FORM_block:
8321 uvalue = read_leb128 (data, & bytes_read, 0);
8322 block_start = data + bytes_read;
8323 data = display_block (block_start, uvalue);
252b5132
RH
8324 break;
8325
8326 case DW_FORM_block1:
8327 uvalue = byte_get (data, 1);
8328 block_start = data + 1;
8329 data = display_block (block_start, uvalue);
252b5132
RH
8330 break;
8331
8332 case DW_FORM_block2:
8333 uvalue = byte_get (data, 2);
8334 block_start = data + 2;
8335 data = display_block (block_start, uvalue);
252b5132
RH
8336 break;
8337
8338 case DW_FORM_block4:
8339 uvalue = byte_get (data, 4);
8340 block_start = data + 4;
8341 data = display_block (block_start, uvalue);
252b5132
RH
8342 break;
8343
8344 case DW_FORM_strp:
f1ef08cb
AM
8345 printf (_(" (indirect string, offset: 0x%lx): %s"),
8346 uvalue, fetch_indirect_string (uvalue));
ef5cdfc7
JJ
8347 break;
8348
252b5132 8349 case DW_FORM_indirect:
e3c8793a 8350 /* Handled above. */
252b5132
RH
8351 break;
8352
8353 default:
2c71103e 8354 warn (_("Unrecognized form: %d\n"), form);
252b5132
RH
8355 break;
8356 }
8357
50c2245b 8358 /* For some attributes we can display further information. */
252b5132
RH
8359
8360 printf ("\t");
8361
8362 switch (attribute)
8363 {
8364 case DW_AT_inline:
8365 switch (uvalue)
8366 {
b34976b6
AM
8367 case DW_INL_not_inlined:
8368 printf (_("(not inlined)"));
8369 break;
8370 case DW_INL_inlined:
8371 printf (_("(inlined)"));
8372 break;
8373 case DW_INL_declared_not_inlined:
8374 printf (_("(declared as inline but ignored)"));
8375 break;
8376 case DW_INL_declared_inlined:
8377 printf (_("(declared as inline and inlined)"));
8378 break;
8379 default:
8380 printf (_(" (Unknown inline attribute value: %lx)"), uvalue);
8381 break;
252b5132
RH
8382 }
8383 break;
8384
252b5132
RH
8385 case DW_AT_language:
8386 switch (uvalue)
8387 {
b34976b6
AM
8388 case DW_LANG_C: printf ("(non-ANSI C)"); break;
8389 case DW_LANG_C89: printf ("(ANSI C)"); break;
8390 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
8391 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
8392 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
8393 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
8394 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
8395 case DW_LANG_Ada83: printf ("(Ada)"); break;
8396 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
8397 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
8398 /* DWARF 2.1 values. */
8399 case DW_LANG_C99: printf ("(ANSI C99)"); break;
8400 case DW_LANG_Ada95: printf ("(ADA 95)"); break;
8401 case DW_LANG_Fortran95: printf ("(Fortran 95)"); break;
b811889f 8402 /* MIPS extension. */
b34976b6 8403 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
84ad6ede
NC
8404 /* UPC extension. */
8405 case DW_LANG_Upc: printf ("(Unified Parallel C)"); break;
b34976b6
AM
8406 default:
8407 printf ("(Unknown: %lx)", uvalue);
8408 break;
252b5132
RH
8409 }
8410 break;
8411
8412 case DW_AT_encoding:
8413 switch (uvalue)
8414 {
b34976b6
AM
8415 case DW_ATE_void: printf ("(void)"); break;
8416 case DW_ATE_address: printf ("(machine address)"); break;
8417 case DW_ATE_boolean: printf ("(boolean)"); break;
8418 case DW_ATE_complex_float: printf ("(complex float)"); break;
8419 case DW_ATE_float: printf ("(float)"); break;
8420 case DW_ATE_signed: printf ("(signed)"); break;
8421 case DW_ATE_signed_char: printf ("(signed char)"); break;
8422 case DW_ATE_unsigned: printf ("(unsigned)"); break;
8423 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
b811889f 8424 /* DWARF 2.1 value. */
b34976b6 8425 case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
252b5132
RH
8426 default:
8427 if (uvalue >= DW_ATE_lo_user
8428 && uvalue <= DW_ATE_hi_user)
8429 printf ("(user defined type)");
8430 else
8431 printf ("(unknown type)");
8432 break;
8433 }
8434 break;
8435
8436 case DW_AT_accessibility:
8437 switch (uvalue)
8438 {
8439 case DW_ACCESS_public: printf ("(public)"); break;
8440 case DW_ACCESS_protected: printf ("(protected)"); break;
8441 case DW_ACCESS_private: printf ("(private)"); break;
b34976b6
AM
8442 default:
8443 printf ("(unknown accessibility)");
8444 break;
252b5132
RH
8445 }
8446 break;
8447
8448 case DW_AT_visibility:
8449 switch (uvalue)
8450 {
b34976b6
AM
8451 case DW_VIS_local: printf ("(local)"); break;
8452 case DW_VIS_exported: printf ("(exported)"); break;
8453 case DW_VIS_qualified: printf ("(qualified)"); break;
8454 default: printf ("(unknown visibility)"); break;
252b5132
RH
8455 }
8456 break;
8457
8458 case DW_AT_virtuality:
8459 switch (uvalue)
8460 {
8461 case DW_VIRTUALITY_none: printf ("(none)"); break;
8462 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
8463 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
b34976b6 8464 default: printf ("(unknown virtuality)"); break;
252b5132
RH
8465 }
8466 break;
8467
8468 case DW_AT_identifier_case:
8469 switch (uvalue)
8470 {
8471 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
8472 case DW_ID_up_case: printf ("(up_case)"); break;
8473 case DW_ID_down_case: printf ("(down_case)"); break;
8474 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
b34976b6 8475 default: printf ("(unknown case)"); break;
252b5132
RH
8476 }
8477 break;
8478
8479 case DW_AT_calling_convention:
8480 switch (uvalue)
8481 {
8482 case DW_CC_normal: printf ("(normal)"); break;
8483 case DW_CC_program: printf ("(program)"); break;
8484 case DW_CC_nocall: printf ("(nocall)"); break;
8485 default:
8486 if (uvalue >= DW_CC_lo_user
8487 && uvalue <= DW_CC_hi_user)
8488 printf ("(user defined)");
8489 else
8490 printf ("(unknown convention)");
8491 }
8492 break;
8493
12ab83a9
NC
8494 case DW_AT_ordering:
8495 switch (uvalue)
8496 {
8497 case -1: printf ("(undefined)"); break;
8498 case 0: printf ("(row major)"); break;
8499 case 1: printf ("(column major)"); break;
8500 }
8501 break;
8502
eb6bd4d3 8503 case DW_AT_frame_base:
252b5132
RH
8504 case DW_AT_location:
8505 case DW_AT_data_member_location:
8506 case DW_AT_vtable_elem_location:
12ab83a9
NC
8507 case DW_AT_allocated:
8508 case DW_AT_associated:
8509 case DW_AT_data_location:
8510 case DW_AT_stride:
8511 case DW_AT_upper_bound:
8512 case DW_AT_lower_bound:
eb6bd4d3
JM
8513 if (block_start)
8514 {
8515 printf ("(");
8516 decode_location_expression (block_start, pointer_size, uvalue);
8517 printf (")");
8518 }
ee42cf8c 8519 else if (form == DW_FORM_data4 || form == DW_FORM_data8)
a2f14207
DB
8520 {
8521 printf ("(");
8522 printf ("location list");
8523 printf (")");
8524 }
252b5132
RH
8525 break;
8526
8527 default:
8528 break;
8529 }
8530
81766fca
RH
8531 return data;
8532}
8533
8534static unsigned char *
d3ba0551
AM
8535read_and_display_attr (unsigned long attribute,
8536 unsigned long form,
8537 unsigned char *data,
8538 unsigned long cu_offset,
8539 unsigned long pointer_size,
8540 unsigned long offset_size,
8541 int dwarf_version)
81766fca
RH
8542{
8543 printf (" %-18s:", get_AT_name (attribute));
8544 data = read_and_display_attr_value (attribute, form, data, cu_offset,
ee42cf8c 8545 pointer_size, offset_size, dwarf_version);
252b5132
RH
8546 printf ("\n");
8547 return data;
8548}
8549
d84de024
AM
8550/* Apply addends of RELA relocations. */
8551
8552static int
8553debug_apply_rela_addends (FILE *file,
8554 Elf_Internal_Shdr *section,
8555 int reloc_size,
8556 unsigned char *sec_data,
8557 unsigned char *start,
8558 unsigned char *end)
8559{
8560 Elf_Internal_Shdr *relsec;
8561
8562 if (end - start < reloc_size)
8563 return 1;
8564
8565 for (relsec = section_headers;
8566 relsec < section_headers + elf_header.e_shnum;
8567 ++relsec)
8568 {
8569 unsigned long nrelas;
8570 Elf_Internal_Rela *rela, *rp;
8571 Elf_Internal_Shdr *symsec;
8572 Elf_Internal_Sym *symtab;
8573 Elf_Internal_Sym *sym;
8574
8575 if (relsec->sh_type != SHT_RELA
8576 || SECTION_HEADER (relsec->sh_info) != section
8577 || relsec->sh_size == 0)
8578 continue;
8579
8580 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
8581 &rela, &nrelas))
8582 return 0;
8583
8584 symsec = SECTION_HEADER (relsec->sh_link);
8585 symtab = GET_ELF_SYMBOLS (file, symsec);
8586
8587 for (rp = rela; rp < rela + nrelas; ++rp)
8588 {
8589 unsigned char *loc;
8590
8591 if (rp->r_offset >= (bfd_vma) (start - sec_data)
8592 && rp->r_offset < (bfd_vma) (end - sec_data) - reloc_size)
8593 loc = sec_data + rp->r_offset;
8594 else
8595 continue;
8596
8597 if (is_32bit_elf)
8598 {
8599 sym = symtab + ELF32_R_SYM (rp->r_info);
8600
8601 if (ELF32_R_SYM (rp->r_info) != 0
8602 && ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
8603 {
8604 warn (_("Skipping unexpected symbol type %u\n"),
8605 ELF32_ST_TYPE (sym->st_info));
8606 continue;
8607 }
8608 }
8609 else
8610 {
8611 sym = symtab + ELF64_R_SYM (rp->r_info);
8612
8613 if (ELF64_R_SYM (rp->r_info) != 0
8614 && ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
8615 {
8616 warn (_("Skipping unexpected symbol type %u\n"),
8617 ELF64_ST_TYPE (sym->st_info));
8618 continue;
8619 }
8620 }
8621
8622 byte_put (loc, rp->r_addend, reloc_size);
8623 }
8624
8625 free (symtab);
8626 free (rela);
8627 break;
8628 }
8629 return 1;
8630}
8631
252b5132 8632static int
d3ba0551
AM
8633display_debug_info (Elf_Internal_Shdr *section,
8634 unsigned char *start,
8635 FILE *file)
252b5132 8636{
b34976b6
AM
8637 unsigned char *end = start + section->sh_size;
8638 unsigned char *section_begin = start;
252b5132
RH
8639
8640 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
8641
261a45ad 8642 load_debug_str (file);
a2f14207 8643 load_debug_loc (file);
ef5cdfc7 8644
252b5132
RH
8645 while (start < end)
8646 {
b34976b6 8647 DWARF2_Internal_CompUnit compunit;
ee42cf8c
NC
8648 unsigned char *hdrptr;
8649 unsigned char *cu_abbrev_offset_ptr;
b34976b6 8650 unsigned char *tags;
b34976b6
AM
8651 int level;
8652 unsigned long cu_offset;
ee42cf8c
NC
8653 int offset_size;
8654 int initial_length_size;
252b5132 8655
ee42cf8c 8656 hdrptr = start;
252b5132 8657
ee42cf8c
NC
8658 compunit.cu_length = byte_get (hdrptr, 4);
8659 hdrptr += 4;
252b5132 8660
428409d5
NC
8661 if (compunit.cu_length == 0xffffffff)
8662 {
ee42cf8c
NC
8663 compunit.cu_length = byte_get (hdrptr, 8);
8664 hdrptr += 8;
8665 offset_size = 8;
8666 initial_length_size = 12;
8667 }
8668 else
8669 {
8670 offset_size = 4;
8671 initial_length_size = 4;
428409d5
NC
8672 }
8673
ee42cf8c
NC
8674 compunit.cu_version = byte_get (hdrptr, 2);
8675 hdrptr += 2;
8676
d84de024
AM
8677 cu_offset = start - section_begin;
8678 start += compunit.cu_length + initial_length_size;
c0e047e0 8679
d84de024
AM
8680 if (elf_header.e_type == ET_REL
8681 && !debug_apply_rela_addends (file, section, offset_size,
8682 section_begin, hdrptr, start))
8683 return 0;
c0e047e0 8684
adab8cdc
AO
8685 cu_abbrev_offset_ptr = hdrptr;
8686 compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size);
8687 hdrptr += offset_size;
8688
8689 compunit.cu_pointer_size = byte_get (hdrptr, 1);
8690 hdrptr += 1;
8691
ee42cf8c 8692 tags = hdrptr;
252b5132 8693
09fd7e38
JM
8694 printf (_(" Compilation Unit @ %lx:\n"), cu_offset);
8695 printf (_(" Length: %ld\n"), compunit.cu_length);
8696 printf (_(" Version: %d\n"), compunit.cu_version);
8697 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
8698 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
8699
ee42cf8c 8700 if (compunit.cu_version != 2 && compunit.cu_version != 3)
252b5132 8701 {
ee42cf8c 8702 warn (_("Only version 2 and 3 DWARF debug information is currently supported.\n"));
252b5132
RH
8703 continue;
8704 }
8705
261a45ad 8706 free_abbrevs ();
252b5132
RH
8707
8708 /* Read in the abbrevs used by this compilation unit. */
252b5132 8709 {
b34976b6
AM
8710 Elf_Internal_Shdr *sec;
8711 unsigned char *begin;
252b5132
RH
8712
8713 /* Locate the .debug_abbrev section and process it. */
d9296b18
NC
8714 sec = find_section (".debug_abbrev");
8715 if (sec == NULL)
252b5132
RH
8716 {
8717 warn (_("Unable to locate .debug_abbrev section!\n"));
8718 return 0;
8719 }
8720
d3ba0551
AM
8721 begin = get_data (NULL, file, sec->sh_offset, sec->sh_size,
8722 _("debug_abbrev section data"));
a6e9f9df
AM
8723 if (!begin)
8724 return 0;
252b5132
RH
8725
8726 process_abbrev_section (begin + compunit.cu_abbrev_offset,
8727 begin + sec->sh_size);
8728
8729 free (begin);
8730 }
8731
8732 level = 0;
8733 while (tags < start)
8734 {
b34976b6
AM
8735 int bytes_read;
8736 unsigned long abbrev_number;
8737 abbrev_entry *entry;
8738 abbrev_attr *attr;
252b5132
RH
8739
8740 abbrev_number = read_leb128 (tags, & bytes_read, 0);
8741 tags += bytes_read;
8742
8743 /* A null DIE marks the end of a list of children. */
8744 if (abbrev_number == 0)
8745 {
8746 --level;
8747 continue;
8748 }
8749
8750 /* Scan through the abbreviation list until we reach the
8751 correct entry. */
8752 for (entry = first_abbrev;
8753 entry && entry->entry != abbrev_number;
8754 entry = entry->next)
8755 continue;
8756
8757 if (entry == NULL)
8758 {
b4c96d0d 8759 warn (_("Unable to locate entry %lu in the abbreviation table\n"),
252b5132
RH
8760 abbrev_number);
8761 return 0;
8762 }
8763
410f7a12
L
8764 printf (_(" <%d><%lx>: Abbrev Number: %lu (%s)\n"),
8765 level,
8766 (unsigned long) (tags - section_begin - bytes_read),
252b5132
RH
8767 abbrev_number,
8768 get_TAG_name (entry->tag));
8769
8770 for (attr = entry->first_attr; attr; attr = attr->next)
8771 tags = read_and_display_attr (attr->attribute,
8772 attr->form,
1fa37306 8773 tags, cu_offset,
ee42cf8c
NC
8774 compunit.cu_pointer_size,
8775 offset_size,
8776 compunit.cu_version);
252b5132
RH
8777
8778 if (entry->children)
8779 ++level;
8780 }
8781 }
8782
261a45ad 8783 free_debug_str ();
a2f14207 8784 free_debug_loc ();
ef5cdfc7 8785
252b5132
RH
8786 printf ("\n");
8787
8788 return 1;
8789}
8790
8791static int
d3ba0551
AM
8792display_debug_aranges (Elf_Internal_Shdr *section,
8793 unsigned char *start,
8794 FILE *file ATTRIBUTE_UNUSED)
252b5132 8795{
b34976b6 8796 unsigned char *end = start + section->sh_size;
252b5132
RH
8797
8798 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
8799
8800 while (start < end)
8801 {
ee42cf8c 8802 unsigned char *hdrptr;
b34976b6
AM
8803 DWARF2_Internal_ARange arange;
8804 unsigned char *ranges;
8805 unsigned long length;
8806 unsigned long address;
8807 int excess;
ee42cf8c
NC
8808 int offset_size;
8809 int initial_length_size;
252b5132 8810
ee42cf8c 8811 hdrptr = start;
252b5132 8812
ee42cf8c
NC
8813 arange.ar_length = byte_get (hdrptr, 4);
8814 hdrptr += 4;
252b5132 8815
e414a165
NC
8816 if (arange.ar_length == 0xffffffff)
8817 {
ee42cf8c
NC
8818 arange.ar_length = byte_get (hdrptr, 8);
8819 hdrptr += 8;
8820 offset_size = 8;
8821 initial_length_size = 12;
8822 }
8823 else
ba2685cc 8824 {
ee42cf8c
NC
8825 offset_size = 4;
8826 initial_length_size = 4;
e414a165
NC
8827 }
8828
ee42cf8c
NC
8829 arange.ar_version = byte_get (hdrptr, 2);
8830 hdrptr += 2;
8831
8832 arange.ar_info_offset = byte_get (hdrptr, offset_size);
8833 hdrptr += offset_size;
8834
8835 arange.ar_pointer_size = byte_get (hdrptr, 1);
8836 hdrptr += 1;
8837
8838 arange.ar_segment_size = byte_get (hdrptr, 1);
8839 hdrptr += 1;
8840
8841 if (arange.ar_version != 2 && arange.ar_version != 3)
3f215a10 8842 {
ee42cf8c 8843 warn (_("Only DWARF 2 and 3 aranges are currently supported.\n"));
3f215a10
NC
8844 break;
8845 }
8846
252b5132
RH
8847 printf (_(" Length: %ld\n"), arange.ar_length);
8848 printf (_(" Version: %d\n"), arange.ar_version);
8849 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
8850 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
8851 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
8852
8853 printf (_("\n Address Length\n"));
8854
ee42cf8c 8855 ranges = hdrptr;
252b5132 8856
7a4b7442 8857 /* Must pad to an alignment boundary that is twice the pointer size. */
ee42cf8c 8858 excess = (hdrptr - start) % (2 * arange.ar_pointer_size);
7a4b7442
NC
8859 if (excess)
8860 ranges += (2 * arange.ar_pointer_size) - excess;
8861
252b5132
RH
8862 for (;;)
8863 {
8864 address = byte_get (ranges, arange.ar_pointer_size);
8865
252b5132
RH
8866 ranges += arange.ar_pointer_size;
8867
8868 length = byte_get (ranges, arange.ar_pointer_size);
8869
8870 ranges += arange.ar_pointer_size;
8871
7a4b7442
NC
8872 /* A pair of zeros marks the end of the list. */
8873 if (address == 0 && length == 0)
8874 break;
103f02d3 8875
252b5132
RH
8876 printf (" %8.8lx %lu\n", address, length);
8877 }
8878
ee42cf8c 8879 start += arange.ar_length + initial_length_size;
252b5132
RH
8880 }
8881
8882 printf ("\n");
8883
8884 return 1;
8885}
8886
c47d488e
DD
8887typedef struct Frame_Chunk
8888{
b34976b6
AM
8889 struct Frame_Chunk *next;
8890 unsigned char *chunk_start;
8891 int ncols;
a98cc2b2 8892 /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */
b34976b6
AM
8893 short int *col_type;
8894 int *col_offset;
8895 char *augmentation;
8896 unsigned int code_factor;
8897 int data_factor;
8898 unsigned long pc_begin;
8899 unsigned long pc_range;
8900 int cfa_reg;
8901 int cfa_offset;
8902 int ra;
8903 unsigned char fde_encoding;
63044634 8904 unsigned char cfa_exp;
c47d488e
DD
8905}
8906Frame_Chunk;
8907
a98cc2b2
AH
8908/* A marker for a col_type that means this column was never referenced
8909 in the frame info. */
8910#define DW_CFA_unreferenced (-1)
8911
c47d488e 8912static void
d3ba0551 8913frame_need_space (Frame_Chunk *fc, int reg)
c47d488e
DD
8914{
8915 int prev = fc->ncols;
8916
8917 if (reg < fc->ncols)
8918 return;
584da044 8919
c47d488e 8920 fc->ncols = reg + 1;
d3ba0551
AM
8921 fc->col_type = xrealloc (fc->col_type, fc->ncols * sizeof (short int));
8922 fc->col_offset = xrealloc (fc->col_offset, fc->ncols * sizeof (int));
c47d488e
DD
8923
8924 while (prev < fc->ncols)
8925 {
a98cc2b2 8926 fc->col_type[prev] = DW_CFA_unreferenced;
c47d488e
DD
8927 fc->col_offset[prev] = 0;
8928 prev++;
8929 }
8930}
8931
8932static void
d3ba0551 8933frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
c47d488e
DD
8934{
8935 int r;
8936 char tmp[100];
8937
b34976b6
AM
8938 if (*max_regs < fc->ncols)
8939 *max_regs = fc->ncols;
584da044 8940
b34976b6 8941 if (*need_col_headers)
c47d488e 8942 {
b34976b6 8943 *need_col_headers = 0;
584da044 8944
c47d488e 8945 printf (" LOC CFA ");
584da044 8946
b34976b6 8947 for (r = 0; r < *max_regs; r++)
a98cc2b2
AH
8948 if (fc->col_type[r] != DW_CFA_unreferenced)
8949 {
8950 if (r == fc->ra)
8951 printf ("ra ");
8952 else
8953 printf ("r%-4d", r);
8954 }
584da044 8955
c47d488e
DD
8956 printf ("\n");
8957 }
584da044 8958
31b6fca6 8959 printf ("%08lx ", fc->pc_begin);
63044634
RH
8960 if (fc->cfa_exp)
8961 strcpy (tmp, "exp");
8962 else
8963 sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
c47d488e 8964 printf ("%-8s ", tmp);
584da044
NC
8965
8966 for (r = 0; r < fc->ncols; r++)
c47d488e 8967 {
a98cc2b2 8968 if (fc->col_type[r] != DW_CFA_unreferenced)
c47d488e 8969 {
a98cc2b2
AH
8970 switch (fc->col_type[r])
8971 {
8972 case DW_CFA_undefined:
8973 strcpy (tmp, "u");
8974 break;
8975 case DW_CFA_same_value:
8976 strcpy (tmp, "s");
8977 break;
8978 case DW_CFA_offset:
8979 sprintf (tmp, "c%+d", fc->col_offset[r]);
8980 break;
8981 case DW_CFA_register:
8982 sprintf (tmp, "r%d", fc->col_offset[r]);
8983 break;
63044634
RH
8984 case DW_CFA_expression:
8985 strcpy (tmp, "exp");
8986 break;
a98cc2b2
AH
8987 default:
8988 strcpy (tmp, "n/a");
8989 break;
8990 }
8991 printf ("%-5s", tmp);
c47d488e 8992 }
c47d488e
DD
8993 }
8994 printf ("\n");
8995}
8996
31b6fca6 8997static int
d3ba0551 8998size_of_encoded_value (int encoding)
31b6fca6
RH
8999{
9000 switch (encoding & 0x7)
9001 {
9002 default: /* ??? */
9003 case 0: return is_32bit_elf ? 4 : 8;
9004 case 2: return 2;
9005 case 3: return 4;
9006 case 4: return 8;
9007 }
9008}
9009
38fafa6d 9010static bfd_vma
d3ba0551 9011get_encoded_value (unsigned char *data, int encoding)
38fafa6d
RH
9012{
9013 int size = size_of_encoded_value (encoding);
9014 if (encoding & DW_EH_PE_signed)
9015 return byte_get_signed (data, size);
9016 else
9017 return byte_get (data, size);
9018}
9019
c47d488e 9020#define GET(N) byte_get (start, N); start += N
584da044
NC
9021#define LEB() read_leb128 (start, & length_return, 0); start += length_return
9022#define SLEB() read_leb128 (start, & length_return, 1); start += length_return
c47d488e
DD
9023
9024static int
d3ba0551
AM
9025display_debug_frames (Elf_Internal_Shdr *section,
9026 unsigned char *start,
9027 FILE *file ATTRIBUTE_UNUSED)
c47d488e 9028{
b34976b6
AM
9029 unsigned char *end = start + section->sh_size;
9030 unsigned char *section_start = start;
9031 Frame_Chunk *chunks = 0;
9032 Frame_Chunk *remembered_state = 0;
9033 Frame_Chunk *rs;
9034 int is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
9035 int length_return;
9036 int max_regs = 0;
9037 int addr_size = is_32bit_elf ? 4 : 8;
c47d488e
DD
9038
9039 printf (_("The section %s contains:\n"), SECTION_NAME (section));
9040
9041 while (start < end)
9042 {
b34976b6
AM
9043 unsigned char *saved_start;
9044 unsigned char *block_end;
9045 unsigned long length;
9046 unsigned long cie_id;
9047 Frame_Chunk *fc;
9048 Frame_Chunk *cie;
9049 int need_col_headers = 1;
9050 unsigned char *augmentation_data = NULL;
9051 unsigned long augmentation_data_len = 0;
9052 int encoded_ptr_size = addr_size;
ee42cf8c
NC
9053 int offset_size;
9054 int initial_length_size;
c47d488e
DD
9055
9056 saved_start = start;
9057 length = byte_get (start, 4); start += 4;
9058
9059 if (length == 0)
f1ef08cb
AM
9060 {
9061 printf ("\n%08lx ZERO terminator\n\n",
9062 (unsigned long)(saved_start - section_start));
9063 return 1;
9064 }
c47d488e 9065
428409d5
NC
9066 if (length == 0xffffffff)
9067 {
ee42cf8c
NC
9068 length = byte_get (start, 8);
9069 start += 8;
9070 offset_size = 8;
9071 initial_length_size = 12;
9072 }
9073 else
9074 {
9075 offset_size = 4;
9076 initial_length_size = 4;
428409d5
NC
9077 }
9078
ee42cf8c
NC
9079 block_end = saved_start + length + initial_length_size;
9080 cie_id = byte_get (start, offset_size); start += offset_size;
c47d488e 9081
d84de024
AM
9082 if (elf_header.e_type == ET_REL
9083 && !debug_apply_rela_addends (file, section, offset_size,
9084 section_start, start, block_end))
9085 return 0;
9086
c47d488e
DD
9087 if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
9088 {
31b6fca6
RH
9089 int version;
9090
d3ba0551 9091 fc = xmalloc (sizeof (Frame_Chunk));
c47d488e
DD
9092 memset (fc, 0, sizeof (Frame_Chunk));
9093
9094 fc->next = chunks;
9095 chunks = fc;
9096 fc->chunk_start = saved_start;
9097 fc->ncols = 0;
d3ba0551
AM
9098 fc->col_type = xmalloc (sizeof (short int));
9099 fc->col_offset = xmalloc (sizeof (int));
c47d488e
DD
9100 frame_need_space (fc, max_regs-1);
9101
31b6fca6 9102 version = *start++;
584da044 9103
31b6fca6
RH
9104 fc->augmentation = start;
9105 start = strchr (start, '\0') + 1;
584da044 9106
c47d488e
DD
9107 if (fc->augmentation[0] == 'z')
9108 {
c47d488e
DD
9109 fc->code_factor = LEB ();
9110 fc->data_factor = SLEB ();
0da76f83
NC
9111 if (version == 1)
9112 {
9113 fc->ra = GET (1);
9114 }
9115 else
9116 {
9117 fc->ra = LEB ();
9118 }
31b6fca6
RH
9119 augmentation_data_len = LEB ();
9120 augmentation_data = start;
9121 start += augmentation_data_len;
c47d488e
DD
9122 }
9123 else if (strcmp (fc->augmentation, "eh") == 0)
9124 {
31b6fca6 9125 start += addr_size;
c47d488e
DD
9126 fc->code_factor = LEB ();
9127 fc->data_factor = SLEB ();
0da76f83
NC
9128 if (version == 1)
9129 {
9130 fc->ra = GET (1);
9131 }
9132 else
9133 {
9134 fc->ra = LEB ();
9135 }
c47d488e
DD
9136 }
9137 else
9138 {
9139 fc->code_factor = LEB ();
9140 fc->data_factor = SLEB ();
0da76f83
NC
9141 if (version == 1)
9142 {
9143 fc->ra = GET (1);
9144 }
9145 else
9146 {
9147 fc->ra = LEB ();
9148 }
c47d488e
DD
9149 }
9150 cie = fc;
31b6fca6
RH
9151
9152 if (do_debug_frames_interp)
9153 printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
7036c0e1 9154 (unsigned long)(saved_start - section_start), length, cie_id,
31b6fca6
RH
9155 fc->augmentation, fc->code_factor, fc->data_factor,
9156 fc->ra);
9157 else
9158 {
9159 printf ("\n%08lx %08lx %08lx CIE\n",
7036c0e1 9160 (unsigned long)(saved_start - section_start), length, cie_id);
31b6fca6
RH
9161 printf (" Version: %d\n", version);
9162 printf (" Augmentation: \"%s\"\n", fc->augmentation);
9163 printf (" Code alignment factor: %u\n", fc->code_factor);
9164 printf (" Data alignment factor: %d\n", fc->data_factor);
9165 printf (" Return address column: %d\n", fc->ra);
9166
9167 if (augmentation_data_len)
9168 {
9169 unsigned long i;
9170 printf (" Augmentation data: ");
9171 for (i = 0; i < augmentation_data_len; ++i)
9172 printf (" %02x", augmentation_data[i]);
9173 putchar ('\n');
9174 }
9175 putchar ('\n');
9176 }
9177
9178 if (augmentation_data_len)
9179 {
9180 unsigned char *p, *q;
9181 p = fc->augmentation + 1;
9182 q = augmentation_data;
9183
9184 while (1)
9185 {
9186 if (*p == 'L')
7036c0e1 9187 q++;
31b6fca6
RH
9188 else if (*p == 'P')
9189 q += 1 + size_of_encoded_value (*q);
9190 else if (*p == 'R')
9191 fc->fde_encoding = *q++;
9192 else
9193 break;
9194 p++;
9195 }
9196
9197 if (fc->fde_encoding)
9198 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
9199 }
c47d488e
DD
9200
9201 frame_need_space (fc, fc->ra);
9202 }
9203 else
9204 {
b34976b6 9205 unsigned char *look_for;
c47d488e 9206 static Frame_Chunk fde_fc;
584da044
NC
9207
9208 fc = & fde_fc;
c47d488e
DD
9209 memset (fc, 0, sizeof (Frame_Chunk));
9210
31b6fca6 9211 look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
c47d488e 9212
428409d5 9213 for (cie = chunks; cie ; cie = cie->next)
31b6fca6
RH
9214 if (cie->chunk_start == look_for)
9215 break;
c47d488e 9216
c47d488e
DD
9217 if (!cie)
9218 {
31b6fca6
RH
9219 warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
9220 cie_id, saved_start);
c47d488e
DD
9221 start = block_end;
9222 fc->ncols = 0;
d3ba0551
AM
9223 fc->col_type = xmalloc (sizeof (short int));
9224 fc->col_offset = xmalloc (sizeof (int));
584da044 9225 frame_need_space (fc, max_regs - 1);
c47d488e
DD
9226 cie = fc;
9227 fc->augmentation = "";
31b6fca6 9228 fc->fde_encoding = 0;
c47d488e
DD
9229 }
9230 else
9231 {
9232 fc->ncols = cie->ncols;
d3ba0551
AM
9233 fc->col_type = xmalloc (fc->ncols * sizeof (short int));
9234 fc->col_offset = xmalloc (fc->ncols * sizeof (int));
a98cc2b2 9235 memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
c47d488e
DD
9236 memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
9237 fc->augmentation = cie->augmentation;
9238 fc->code_factor = cie->code_factor;
9239 fc->data_factor = cie->data_factor;
9240 fc->cfa_reg = cie->cfa_reg;
9241 fc->cfa_offset = cie->cfa_offset;
9242 fc->ra = cie->ra;
9243 frame_need_space (fc, max_regs-1);
31b6fca6 9244 fc->fde_encoding = cie->fde_encoding;
c47d488e
DD
9245 }
9246
31b6fca6
RH
9247 if (fc->fde_encoding)
9248 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
9249
38fafa6d 9250 fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
d84de024
AM
9251 if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
9252 /* Don't adjust for ET_REL since there's invariably a pcrel
9253 reloc here, which we haven't applied. */
9254 && elf_header.e_type != ET_REL)
f1ef08cb 9255 fc->pc_begin += section->sh_addr + (start - section_start);
31b6fca6
RH
9256 start += encoded_ptr_size;
9257 fc->pc_range = byte_get (start, encoded_ptr_size);
9258 start += encoded_ptr_size;
9259
c47d488e
DD
9260 if (cie->augmentation[0] == 'z')
9261 {
31b6fca6
RH
9262 augmentation_data_len = LEB ();
9263 augmentation_data = start;
9264 start += augmentation_data_len;
c47d488e
DD
9265 }
9266
410f7a12 9267 printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
7036c0e1 9268 (unsigned long)(saved_start - section_start), length, cie_id,
410f7a12
L
9269 (unsigned long)(cie->chunk_start - section_start),
9270 fc->pc_begin, fc->pc_begin + fc->pc_range);
31b6fca6
RH
9271 if (! do_debug_frames_interp && augmentation_data_len)
9272 {
9273 unsigned long i;
9274 printf (" Augmentation data: ");
9275 for (i = 0; i < augmentation_data_len; ++i)
ba2685cc 9276 printf (" %02x", augmentation_data[i]);
31b6fca6
RH
9277 putchar ('\n');
9278 putchar ('\n');
9279 }
c47d488e
DD
9280 }
9281
9282 /* At this point, fc is the current chunk, cie (if any) is set, and we're
9283 about to interpret instructions for the chunk. */
38fafa6d
RH
9284 /* ??? At present we need to do this always, since this sizes the
9285 fc->col_type and fc->col_offset arrays, which we write into always.
9286 We should probably split the interpreted and non-interpreted bits
9287 into two different routines, since there's so much that doesn't
9288 really overlap between them. */
9289 if (1 || do_debug_frames_interp)
53c7db4b
KH
9290 {
9291 /* Start by making a pass over the chunk, allocating storage
9292 and taking note of what registers are used. */
b34976b6 9293 unsigned char *tmp = start;
a98cc2b2 9294
53c7db4b
KH
9295 while (start < block_end)
9296 {
9297 unsigned op, opa;
63044634 9298 unsigned long reg, tmp;
7036c0e1 9299
b34976b6 9300 op = *start++;
53c7db4b
KH
9301 opa = op & 0x3f;
9302 if (op & 0xc0)
9303 op &= 0xc0;
7036c0e1 9304
53c7db4b 9305 /* Warning: if you add any more cases to this switch, be
ba2685cc 9306 sure to add them to the corresponding switch below. */
53c7db4b
KH
9307 switch (op)
9308 {
9309 case DW_CFA_advance_loc:
9310 break;
9311 case DW_CFA_offset:
9312 LEB ();
9313 frame_need_space (fc, opa);
9314 fc->col_type[opa] = DW_CFA_undefined;
9315 break;
9316 case DW_CFA_restore:
9317 frame_need_space (fc, opa);
9318 fc->col_type[opa] = DW_CFA_undefined;
9319 break;
9320 case DW_CFA_set_loc:
9321 start += encoded_ptr_size;
9322 break;
9323 case DW_CFA_advance_loc1:
9324 start += 1;
9325 break;
9326 case DW_CFA_advance_loc2:
9327 start += 2;
9328 break;
9329 case DW_CFA_advance_loc4:
9330 start += 4;
9331 break;
9332 case DW_CFA_offset_extended:
9333 reg = LEB (); LEB ();
9334 frame_need_space (fc, reg);
9335 fc->col_type[reg] = DW_CFA_undefined;
9336 break;
9337 case DW_CFA_restore_extended:
9338 reg = LEB ();
9339 frame_need_space (fc, reg);
9340 fc->col_type[reg] = DW_CFA_undefined;
9341 break;
9342 case DW_CFA_undefined:
9343 reg = LEB ();
9344 frame_need_space (fc, reg);
9345 fc->col_type[reg] = DW_CFA_undefined;
9346 break;
9347 case DW_CFA_same_value:
9348 reg = LEB ();
9349 frame_need_space (fc, reg);
9350 fc->col_type[reg] = DW_CFA_undefined;
9351 break;
9352 case DW_CFA_register:
9353 reg = LEB (); LEB ();
9354 frame_need_space (fc, reg);
9355 fc->col_type[reg] = DW_CFA_undefined;
9356 break;
9357 case DW_CFA_def_cfa:
9358 LEB (); LEB ();
9359 break;
9360 case DW_CFA_def_cfa_register:
9361 LEB ();
9362 break;
9363 case DW_CFA_def_cfa_offset:
9364 LEB ();
9365 break;
63044634
RH
9366 case DW_CFA_def_cfa_expression:
9367 tmp = LEB ();
9368 start += tmp;
9369 break;
9370 case DW_CFA_expression:
9371 reg = LEB ();
9372 tmp = LEB ();
9373 start += tmp;
9374 frame_need_space (fc, reg);
9375 fc->col_type[reg] = DW_CFA_undefined;
9376 break;
91a106e6
L
9377 case DW_CFA_offset_extended_sf:
9378 reg = LEB (); SLEB ();
9379 frame_need_space (fc, reg);
9380 fc->col_type[reg] = DW_CFA_undefined;
9381 break;
9382 case DW_CFA_def_cfa_sf:
9383 LEB (); SLEB ();
9384 break;
9385 case DW_CFA_def_cfa_offset_sf:
9386 SLEB ();
9387 break;
63044634
RH
9388 case DW_CFA_MIPS_advance_loc8:
9389 start += 8;
9390 break;
53c7db4b
KH
9391 case DW_CFA_GNU_args_size:
9392 LEB ();
9393 break;
53c7db4b
KH
9394 case DW_CFA_GNU_negative_offset_extended:
9395 reg = LEB (); LEB ();
9396 frame_need_space (fc, reg);
9397 fc->col_type[reg] = DW_CFA_undefined;
7036c0e1 9398
53c7db4b
KH
9399 default:
9400 break;
9401 }
9402 }
9403 start = tmp;
9404 }
a98cc2b2
AH
9405
9406 /* Now we know what registers are used, make a second pass over
ba2685cc 9407 the chunk, this time actually printing out the info. */
a98cc2b2 9408
c47d488e
DD
9409 while (start < block_end)
9410 {
9411 unsigned op, opa;
9412 unsigned long ul, reg, roffs;
9413 long l, ofs;
9414 bfd_vma vma;
9415
b34976b6 9416 op = *start++;
c47d488e
DD
9417 opa = op & 0x3f;
9418 if (op & 0xc0)
9419 op &= 0xc0;
9420
53c7db4b
KH
9421 /* Warning: if you add any more cases to this switch, be
9422 sure to add them to the corresponding switch above. */
c47d488e
DD
9423 switch (op)
9424 {
9425 case DW_CFA_advance_loc:
31b6fca6 9426 if (do_debug_frames_interp)
53c7db4b 9427 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9428 else
53c7db4b
KH
9429 printf (" DW_CFA_advance_loc: %d to %08lx\n",
9430 opa * fc->code_factor,
31b6fca6 9431 fc->pc_begin + opa * fc->code_factor);
c47d488e
DD
9432 fc->pc_begin += opa * fc->code_factor;
9433 break;
9434
9435 case DW_CFA_offset:
c47d488e 9436 roffs = LEB ();
31b6fca6 9437 if (! do_debug_frames_interp)
53c7db4b 9438 printf (" DW_CFA_offset: r%d at cfa%+ld\n",
31b6fca6 9439 opa, roffs * fc->data_factor);
c47d488e
DD
9440 fc->col_type[opa] = DW_CFA_offset;
9441 fc->col_offset[opa] = roffs * fc->data_factor;
9442 break;
9443
9444 case DW_CFA_restore:
31b6fca6 9445 if (! do_debug_frames_interp)
53c7db4b 9446 printf (" DW_CFA_restore: r%d\n", opa);
c47d488e
DD
9447 fc->col_type[opa] = cie->col_type[opa];
9448 fc->col_offset[opa] = cie->col_offset[opa];
9449 break;
9450
9451 case DW_CFA_set_loc:
38fafa6d 9452 vma = get_encoded_value (start, fc->fde_encoding);
d84de024
AM
9453 if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
9454 && elf_header.e_type != ET_REL)
f1ef08cb 9455 vma += section->sh_addr + (start - section_start);
31b6fca6
RH
9456 start += encoded_ptr_size;
9457 if (do_debug_frames_interp)
53c7db4b 9458 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9459 else
53c7db4b 9460 printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
c47d488e
DD
9461 fc->pc_begin = vma;
9462 break;
9463
9464 case DW_CFA_advance_loc1:
c47d488e 9465 ofs = byte_get (start, 1); start += 1;
31b6fca6 9466 if (do_debug_frames_interp)
53c7db4b 9467 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9468 else
53c7db4b
KH
9469 printf (" DW_CFA_advance_loc1: %ld to %08lx\n",
9470 ofs * fc->code_factor,
31b6fca6 9471 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
9472 fc->pc_begin += ofs * fc->code_factor;
9473 break;
9474
9475 case DW_CFA_advance_loc2:
c47d488e 9476 ofs = byte_get (start, 2); start += 2;
31b6fca6 9477 if (do_debug_frames_interp)
53c7db4b 9478 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9479 else
53c7db4b
KH
9480 printf (" DW_CFA_advance_loc2: %ld to %08lx\n",
9481 ofs * fc->code_factor,
31b6fca6 9482 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
9483 fc->pc_begin += ofs * fc->code_factor;
9484 break;
9485
9486 case DW_CFA_advance_loc4:
c47d488e 9487 ofs = byte_get (start, 4); start += 4;
31b6fca6 9488 if (do_debug_frames_interp)
53c7db4b 9489 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9490 else
53c7db4b
KH
9491 printf (" DW_CFA_advance_loc4: %ld to %08lx\n",
9492 ofs * fc->code_factor,
31b6fca6 9493 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
9494 fc->pc_begin += ofs * fc->code_factor;
9495 break;
9496
9497 case DW_CFA_offset_extended:
9498 reg = LEB ();
9499 roffs = LEB ();
31b6fca6 9500 if (! do_debug_frames_interp)
7036c0e1 9501 printf (" DW_CFA_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 9502 reg, roffs * fc->data_factor);
c47d488e
DD
9503 fc->col_type[reg] = DW_CFA_offset;
9504 fc->col_offset[reg] = roffs * fc->data_factor;
9505 break;
9506
9507 case DW_CFA_restore_extended:
9508 reg = LEB ();
31b6fca6 9509 if (! do_debug_frames_interp)
53c7db4b 9510 printf (" DW_CFA_restore_extended: r%ld\n", reg);
c47d488e
DD
9511 fc->col_type[reg] = cie->col_type[reg];
9512 fc->col_offset[reg] = cie->col_offset[reg];
9513 break;
9514
9515 case DW_CFA_undefined:
9516 reg = LEB ();
31b6fca6 9517 if (! do_debug_frames_interp)
53c7db4b 9518 printf (" DW_CFA_undefined: r%ld\n", reg);
c47d488e
DD
9519 fc->col_type[reg] = DW_CFA_undefined;
9520 fc->col_offset[reg] = 0;
9521 break;
9522
9523 case DW_CFA_same_value:
9524 reg = LEB ();
31b6fca6 9525 if (! do_debug_frames_interp)
53c7db4b 9526 printf (" DW_CFA_same_value: r%ld\n", reg);
c47d488e
DD
9527 fc->col_type[reg] = DW_CFA_same_value;
9528 fc->col_offset[reg] = 0;
9529 break;
9530
9531 case DW_CFA_register:
9532 reg = LEB ();
9533 roffs = LEB ();
31b6fca6 9534 if (! do_debug_frames_interp)
636fc387 9535 printf (" DW_CFA_register: r%ld in r%ld\n", reg, roffs);
c47d488e
DD
9536 fc->col_type[reg] = DW_CFA_register;
9537 fc->col_offset[reg] = roffs;
9538 break;
9539
9540 case DW_CFA_remember_state:
31b6fca6 9541 if (! do_debug_frames_interp)
53c7db4b 9542 printf (" DW_CFA_remember_state\n");
d3ba0551 9543 rs = xmalloc (sizeof (Frame_Chunk));
c47d488e 9544 rs->ncols = fc->ncols;
d3ba0551
AM
9545 rs->col_type = xmalloc (rs->ncols * sizeof (short int));
9546 rs->col_offset = xmalloc (rs->ncols * sizeof (int));
c47d488e
DD
9547 memcpy (rs->col_type, fc->col_type, rs->ncols);
9548 memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
9549 rs->next = remembered_state;
9550 remembered_state = rs;
9551 break;
9552
9553 case DW_CFA_restore_state:
31b6fca6 9554 if (! do_debug_frames_interp)
53c7db4b 9555 printf (" DW_CFA_restore_state\n");
c47d488e 9556 rs = remembered_state;
8c9a9879
RH
9557 if (rs)
9558 {
9559 remembered_state = rs->next;
9560 frame_need_space (fc, rs->ncols-1);
9561 memcpy (fc->col_type, rs->col_type, rs->ncols);
9562 memcpy (fc->col_offset, rs->col_offset,
9563 rs->ncols * sizeof (int));
9564 free (rs->col_type);
9565 free (rs->col_offset);
9566 free (rs);
9567 }
9568 else if (do_debug_frames_interp)
9569 printf ("Mismatched DW_CFA_restore_state\n");
c47d488e
DD
9570 break;
9571
9572 case DW_CFA_def_cfa:
9573 fc->cfa_reg = LEB ();
9574 fc->cfa_offset = LEB ();
63044634 9575 fc->cfa_exp = 0;
31b6fca6 9576 if (! do_debug_frames_interp)
53c7db4b 9577 printf (" DW_CFA_def_cfa: r%d ofs %d\n",
31b6fca6 9578 fc->cfa_reg, fc->cfa_offset);
c47d488e
DD
9579 break;
9580
9581 case DW_CFA_def_cfa_register:
9582 fc->cfa_reg = LEB ();
63044634 9583 fc->cfa_exp = 0;
31b6fca6 9584 if (! do_debug_frames_interp)
53c7db4b 9585 printf (" DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
c47d488e
DD
9586 break;
9587
9588 case DW_CFA_def_cfa_offset:
9589 fc->cfa_offset = LEB ();
31b6fca6 9590 if (! do_debug_frames_interp)
53c7db4b 9591 printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
c47d488e
DD
9592 break;
9593
9594 case DW_CFA_nop:
31b6fca6 9595 if (! do_debug_frames_interp)
53c7db4b 9596 printf (" DW_CFA_nop\n");
c47d488e
DD
9597 break;
9598
63044634
RH
9599 case DW_CFA_def_cfa_expression:
9600 ul = LEB ();
9601 if (! do_debug_frames_interp)
9602 {
9603 printf (" DW_CFA_def_cfa_expression (");
9604 decode_location_expression (start, addr_size, ul);
9605 printf (")\n");
9606 }
9607 fc->cfa_exp = 1;
9608 start += ul;
9609 break;
9610
9611 case DW_CFA_expression:
9612 reg = LEB ();
9613 ul = LEB ();
9614 if (! do_debug_frames_interp)
9615 {
9616 printf (" DW_CFA_expression: r%ld (", reg);
9617 decode_location_expression (start, addr_size, ul);
9618 printf (")\n");
9619 }
9620 fc->col_type[reg] = DW_CFA_expression;
9621 start += ul;
9622 break;
9623
91a106e6
L
9624 case DW_CFA_offset_extended_sf:
9625 reg = LEB ();
9626 l = SLEB ();
9627 frame_need_space (fc, reg);
9628 if (! do_debug_frames_interp)
9629 printf (" DW_CFA_offset_extended_sf: r%ld at cfa%+ld\n",
9630 reg, l * fc->data_factor);
9631 fc->col_type[reg] = DW_CFA_offset;
9632 fc->col_offset[reg] = l * fc->data_factor;
9633 break;
9634
9635 case DW_CFA_def_cfa_sf:
9636 fc->cfa_reg = LEB ();
9637 fc->cfa_offset = SLEB ();
63044634 9638 fc->cfa_exp = 0;
91a106e6
L
9639 if (! do_debug_frames_interp)
9640 printf (" DW_CFA_def_cfa_sf: r%d ofs %d\n",
9641 fc->cfa_reg, fc->cfa_offset);
9642 break;
9643
9644 case DW_CFA_def_cfa_offset_sf:
9645 fc->cfa_offset = SLEB ();
9646 if (! do_debug_frames_interp)
9647 printf (" DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset);
9648 break;
9649
63044634
RH
9650 case DW_CFA_MIPS_advance_loc8:
9651 ofs = byte_get (start, 8); start += 8;
9652 if (do_debug_frames_interp)
9653 frame_display_row (fc, &need_col_headers, &max_regs);
9654 else
9655 printf (" DW_CFA_MIPS_advance_loc8: %ld to %08lx\n",
9656 ofs * fc->code_factor,
9657 fc->pc_begin + ofs * fc->code_factor);
9658 fc->pc_begin += ofs * fc->code_factor;
9659 break;
9660
c47d488e 9661 case DW_CFA_GNU_window_save:
31b6fca6 9662 if (! do_debug_frames_interp)
53c7db4b 9663 printf (" DW_CFA_GNU_window_save\n");
c47d488e
DD
9664 break;
9665
c47d488e
DD
9666 case DW_CFA_GNU_args_size:
9667 ul = LEB ();
31b6fca6 9668 if (! do_debug_frames_interp)
53c7db4b 9669 printf (" DW_CFA_GNU_args_size: %ld\n", ul);
c47d488e
DD
9670 break;
9671
c47d488e
DD
9672 case DW_CFA_GNU_negative_offset_extended:
9673 reg = LEB ();
9674 l = - LEB ();
9675 frame_need_space (fc, reg);
31b6fca6 9676 if (! do_debug_frames_interp)
53c7db4b 9677 printf (" DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 9678 reg, l * fc->data_factor);
c47d488e
DD
9679 fc->col_type[reg] = DW_CFA_offset;
9680 fc->col_offset[reg] = l * fc->data_factor;
9681 break;
9682
9683 default:
9684 fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
9685 start = block_end;
9686 }
9687 }
9688
31b6fca6 9689 if (do_debug_frames_interp)
53c7db4b 9690 frame_display_row (fc, &need_col_headers, &max_regs);
c47d488e
DD
9691
9692 start = block_end;
9693 }
9694
9695 printf ("\n");
9696
9697 return 1;
9698}
9699
9700#undef GET
9701#undef LEB
9702#undef SLEB
252b5132
RH
9703
9704static int
d3ba0551
AM
9705display_debug_not_supported (Elf_Internal_Shdr *section,
9706 unsigned char *start ATTRIBUTE_UNUSED,
9707 FILE *file ATTRIBUTE_UNUSED)
252b5132
RH
9708{
9709 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
9710 SECTION_NAME (section));
9711
9712 return 1;
9713}
9714
d9296b18
NC
9715/* A structure containing the name of a debug section
9716 and a pointer to a function that can decode it. */
252b5132
RH
9717struct
9718{
b34976b6 9719 const char *const name;
d3ba0551 9720 int (*display) (Elf_Internal_Shdr *, unsigned char *, FILE *);
252b5132
RH
9721}
9722debug_displays[] =
9723{
d9296b18
NC
9724 { ".debug_abbrev", display_debug_abbrev },
9725 { ".debug_aranges", display_debug_aranges },
9726 { ".debug_frame", display_debug_frames },
9727 { ".debug_info", display_debug_info },
9728 { ".debug_line", display_debug_lines },
9729 { ".debug_pubnames", display_debug_pubnames },
9730 { ".eh_frame", display_debug_frames },
9731 { ".debug_macinfo", display_debug_macinfo },
9732 { ".debug_str", display_debug_str },
9733 { ".debug_loc", display_debug_loc },
935a41f5 9734 { ".debug_pubtypes", display_debug_pubnames },
d9296b18
NC
9735 { ".debug_ranges", display_debug_not_supported },
9736 { ".debug_static_func", display_debug_not_supported },
9737 { ".debug_static_vars", display_debug_not_supported },
9738 { ".debug_types", display_debug_not_supported },
9739 { ".debug_weaknames", display_debug_not_supported }
252b5132
RH
9740};
9741
9742static int
d3ba0551 9743display_debug_section (Elf_Internal_Shdr *section, FILE *file)
252b5132 9744{
b34976b6
AM
9745 char *name = SECTION_NAME (section);
9746 bfd_size_type length;
9747 unsigned char *start;
9748 int i;
252b5132
RH
9749
9750 length = section->sh_size;
9751 if (length == 0)
9752 {
9753 printf (_("\nSection '%s' has no debugging data.\n"), name);
9754 return 0;
9755 }
9756
d3ba0551
AM
9757 start = get_data (NULL, file, section->sh_offset, length,
9758 _("debug section data"));
a6e9f9df
AM
9759 if (!start)
9760 return 0;
252b5132
RH
9761
9762 /* See if we know how to display the contents of this section. */
09fd7e38 9763 if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
7036c0e1 9764 name = ".debug_info";
584da044 9765
252b5132
RH
9766 for (i = NUM_ELEM (debug_displays); i--;)
9767 if (strcmp (debug_displays[i].name, name) == 0)
9768 {
9769 debug_displays[i].display (section, start, file);
9770 break;
9771 }
9772
9773 if (i == -1)
2c71103e 9774 printf (_("Unrecognized debug section: %s\n"), name);
252b5132
RH
9775
9776 free (start);
9777
9778 /* If we loaded in the abbrev section at some point,
9779 we must release it here. */
261a45ad 9780 free_abbrevs ();
252b5132
RH
9781
9782 return 1;
9783}
9784
9785static int
d3ba0551 9786process_section_contents (FILE *file)
252b5132 9787{
b34976b6
AM
9788 Elf_Internal_Shdr *section;
9789 unsigned int i;
252b5132
RH
9790
9791 if (! do_dump)
9792 return 1;
9793
9794 for (i = 0, section = section_headers;
3590ea00 9795 i < elf_header.e_shnum && i < num_dump_sects;
b34976b6 9796 i++, section++)
252b5132
RH
9797 {
9798#ifdef SUPPORT_DISASSEMBLY
9799 if (dump_sects[i] & DISASS_DUMP)
9800 disassemble_section (section, file);
9801#endif
9802 if (dump_sects[i] & HEX_DUMP)
9803 dump_section (section, file);
9804
9805 if (dump_sects[i] & DEBUG_DUMP)
9806 display_debug_section (section, file);
9807 }
9808
9809 if (i < num_dump_sects)
9810 warn (_("Some sections were not dumped because they do not exist!\n"));
9811
9812 return 1;
9813}
9814
9815static void
d3ba0551 9816process_mips_fpe_exception (int mask)
252b5132
RH
9817{
9818 if (mask)
9819 {
9820 int first = 1;
9821 if (mask & OEX_FPU_INEX)
9822 fputs ("INEX", stdout), first = 0;
9823 if (mask & OEX_FPU_UFLO)
9824 printf ("%sUFLO", first ? "" : "|"), first = 0;
9825 if (mask & OEX_FPU_OFLO)
9826 printf ("%sOFLO", first ? "" : "|"), first = 0;
9827 if (mask & OEX_FPU_DIV0)
9828 printf ("%sDIV0", first ? "" : "|"), first = 0;
9829 if (mask & OEX_FPU_INVAL)
9830 printf ("%sINVAL", first ? "" : "|");
9831 }
9832 else
9833 fputs ("0", stdout);
9834}
9835
9836static int
d3ba0551 9837process_mips_specific (FILE *file)
252b5132 9838{
b34976b6 9839 Elf_Internal_Dyn *entry;
252b5132
RH
9840 size_t liblist_offset = 0;
9841 size_t liblistno = 0;
9842 size_t conflictsno = 0;
9843 size_t options_offset = 0;
9844 size_t conflicts_offset = 0;
9845
9846 /* We have a lot of special sections. Thanks SGI! */
b2d38a17 9847 if (dynamic_section == NULL)
252b5132
RH
9848 /* No information available. */
9849 return 0;
9850
b2d38a17 9851 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
9852 switch (entry->d_tag)
9853 {
9854 case DT_MIPS_LIBLIST:
d93f0186
NC
9855 liblist_offset
9856 = offset_from_vma (file, entry->d_un.d_val,
9857 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
9858 break;
9859 case DT_MIPS_LIBLISTNO:
9860 liblistno = entry->d_un.d_val;
9861 break;
9862 case DT_MIPS_OPTIONS:
d93f0186 9863 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
9864 break;
9865 case DT_MIPS_CONFLICT:
d93f0186
NC
9866 conflicts_offset
9867 = offset_from_vma (file, entry->d_un.d_val,
9868 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
9869 break;
9870 case DT_MIPS_CONFLICTNO:
9871 conflictsno = entry->d_un.d_val;
9872 break;
9873 default:
9874 break;
9875 }
9876
9877 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
9878 {
b34976b6 9879 Elf32_External_Lib *elib;
252b5132
RH
9880 size_t cnt;
9881
d3ba0551
AM
9882 elib = get_data (NULL, file, liblist_offset,
9883 liblistno * sizeof (Elf32_External_Lib),
9884 _("liblist"));
a6e9f9df 9885 if (elib)
252b5132 9886 {
a6e9f9df
AM
9887 printf ("\nSection '.liblist' contains %lu entries:\n",
9888 (unsigned long) liblistno);
9889 fputs (" Library Time Stamp Checksum Version Flags\n",
9890 stdout);
9891
9892 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 9893 {
a6e9f9df
AM
9894 Elf32_Lib liblist;
9895 time_t time;
9896 char timebuf[20];
b34976b6 9897 struct tm *tmp;
a6e9f9df
AM
9898
9899 liblist.l_name = BYTE_GET (elib[cnt].l_name);
9900 time = BYTE_GET (elib[cnt].l_time_stamp);
9901 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
9902 liblist.l_version = BYTE_GET (elib[cnt].l_version);
9903 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
9904
9905 tmp = gmtime (&time);
9906 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
9907 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9908 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
9909
31104126
NC
9910 printf ("%3lu: ", (unsigned long) cnt);
9911 print_symbol (20, dynamic_strings + liblist.l_name);
9912 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
9913 liblist.l_version);
a6e9f9df
AM
9914
9915 if (liblist.l_flags == 0)
9916 puts (" NONE");
9917 else
9918 {
9919 static const struct
252b5132 9920 {
b34976b6 9921 const char *name;
a6e9f9df 9922 int bit;
252b5132 9923 }
a6e9f9df
AM
9924 l_flags_vals[] =
9925 {
9926 { " EXACT_MATCH", LL_EXACT_MATCH },
9927 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
9928 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
9929 { " EXPORTS", LL_EXPORTS },
9930 { " DELAY_LOAD", LL_DELAY_LOAD },
9931 { " DELTA", LL_DELTA }
9932 };
9933 int flags = liblist.l_flags;
9934 size_t fcnt;
9935
9936 for (fcnt = 0;
9937 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
9938 ++fcnt)
9939 if ((flags & l_flags_vals[fcnt].bit) != 0)
9940 {
9941 fputs (l_flags_vals[fcnt].name, stdout);
9942 flags ^= l_flags_vals[fcnt].bit;
9943 }
9944 if (flags != 0)
9945 printf (" %#x", (unsigned int) flags);
252b5132 9946
a6e9f9df
AM
9947 puts ("");
9948 }
252b5132 9949 }
252b5132 9950
a6e9f9df
AM
9951 free (elib);
9952 }
252b5132
RH
9953 }
9954
9955 if (options_offset != 0)
9956 {
b34976b6
AM
9957 Elf_External_Options *eopt;
9958 Elf_Internal_Shdr *sect = section_headers;
9959 Elf_Internal_Options *iopt;
9960 Elf_Internal_Options *option;
252b5132
RH
9961 size_t offset;
9962 int cnt;
9963
9964 /* Find the section header so that we get the size. */
9965 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 9966 ++sect;
252b5132 9967
d3ba0551
AM
9968 eopt = get_data (NULL, file, options_offset, sect->sh_size,
9969 _("options"));
a6e9f9df 9970 if (eopt)
252b5132 9971 {
d3ba0551 9972 iopt = malloc ((sect->sh_size / sizeof (eopt)) * sizeof (*iopt));
a6e9f9df
AM
9973 if (iopt == NULL)
9974 {
9975 error (_("Out of memory"));
9976 return 0;
9977 }
76da6bbe 9978
a6e9f9df
AM
9979 offset = cnt = 0;
9980 option = iopt;
252b5132 9981
a6e9f9df
AM
9982 while (offset < sect->sh_size)
9983 {
b34976b6 9984 Elf_External_Options *eoption;
252b5132 9985
a6e9f9df 9986 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 9987
a6e9f9df
AM
9988 option->kind = BYTE_GET (eoption->kind);
9989 option->size = BYTE_GET (eoption->size);
9990 option->section = BYTE_GET (eoption->section);
9991 option->info = BYTE_GET (eoption->info);
76da6bbe 9992
a6e9f9df 9993 offset += option->size;
252b5132 9994
a6e9f9df
AM
9995 ++option;
9996 ++cnt;
9997 }
252b5132 9998
a6e9f9df
AM
9999 printf (_("\nSection '%s' contains %d entries:\n"),
10000 SECTION_NAME (sect), cnt);
76da6bbe 10001
a6e9f9df 10002 option = iopt;
252b5132 10003
a6e9f9df 10004 while (cnt-- > 0)
252b5132 10005 {
a6e9f9df
AM
10006 size_t len;
10007
10008 switch (option->kind)
252b5132 10009 {
a6e9f9df
AM
10010 case ODK_NULL:
10011 /* This shouldn't happen. */
10012 printf (" NULL %d %lx", option->section, option->info);
10013 break;
10014 case ODK_REGINFO:
10015 printf (" REGINFO ");
10016 if (elf_header.e_machine == EM_MIPS)
10017 {
10018 /* 32bit form. */
b34976b6
AM
10019 Elf32_External_RegInfo *ereg;
10020 Elf32_RegInfo reginfo;
a6e9f9df
AM
10021
10022 ereg = (Elf32_External_RegInfo *) (option + 1);
10023 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
10024 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
10025 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
10026 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
10027 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
10028 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
10029
10030 printf ("GPR %08lx GP 0x%lx\n",
10031 reginfo.ri_gprmask,
10032 (unsigned long) reginfo.ri_gp_value);
10033 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
10034 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
10035 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
10036 }
10037 else
10038 {
10039 /* 64 bit form. */
b34976b6 10040 Elf64_External_RegInfo *ereg;
a6e9f9df
AM
10041 Elf64_Internal_RegInfo reginfo;
10042
10043 ereg = (Elf64_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_GET8 (ereg->ri_gp_value);
10050
10051 printf ("GPR %08lx GP 0x",
10052 reginfo.ri_gprmask);
10053 printf_vma (reginfo.ri_gp_value);
10054 printf ("\n");
10055
10056 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
10057 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
10058 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
10059 }
10060 ++option;
10061 continue;
10062 case ODK_EXCEPTIONS:
10063 fputs (" EXCEPTIONS fpe_min(", stdout);
10064 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
10065 fputs (") fpe_max(", stdout);
10066 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
10067 fputs (")", stdout);
10068
10069 if (option->info & OEX_PAGE0)
10070 fputs (" PAGE0", stdout);
10071 if (option->info & OEX_SMM)
10072 fputs (" SMM", stdout);
10073 if (option->info & OEX_FPDBUG)
10074 fputs (" FPDBUG", stdout);
10075 if (option->info & OEX_DISMISS)
10076 fputs (" DISMISS", stdout);
10077 break;
10078 case ODK_PAD:
10079 fputs (" PAD ", stdout);
10080 if (option->info & OPAD_PREFIX)
10081 fputs (" PREFIX", stdout);
10082 if (option->info & OPAD_POSTFIX)
10083 fputs (" POSTFIX", stdout);
10084 if (option->info & OPAD_SYMBOL)
10085 fputs (" SYMBOL", stdout);
10086 break;
10087 case ODK_HWPATCH:
10088 fputs (" HWPATCH ", stdout);
10089 if (option->info & OHW_R4KEOP)
10090 fputs (" R4KEOP", stdout);
10091 if (option->info & OHW_R8KPFETCH)
10092 fputs (" R8KPFETCH", stdout);
10093 if (option->info & OHW_R5KEOP)
10094 fputs (" R5KEOP", stdout);
10095 if (option->info & OHW_R5KCVTL)
10096 fputs (" R5KCVTL", stdout);
10097 break;
10098 case ODK_FILL:
10099 fputs (" FILL ", stdout);
10100 /* XXX Print content of info word? */
10101 break;
10102 case ODK_TAGS:
10103 fputs (" TAGS ", stdout);
10104 /* XXX Print content of info word? */
10105 break;
10106 case ODK_HWAND:
10107 fputs (" HWAND ", stdout);
10108 if (option->info & OHWA0_R4KEOP_CHECKED)
10109 fputs (" R4KEOP_CHECKED", stdout);
10110 if (option->info & OHWA0_R4KEOP_CLEAN)
10111 fputs (" R4KEOP_CLEAN", stdout);
10112 break;
10113 case ODK_HWOR:
10114 fputs (" HWOR ", stdout);
10115 if (option->info & OHWA0_R4KEOP_CHECKED)
10116 fputs (" R4KEOP_CHECKED", stdout);
10117 if (option->info & OHWA0_R4KEOP_CLEAN)
10118 fputs (" R4KEOP_CLEAN", stdout);
10119 break;
10120 case ODK_GP_GROUP:
10121 printf (" GP_GROUP %#06lx self-contained %#06lx",
10122 option->info & OGP_GROUP,
10123 (option->info & OGP_SELF) >> 16);
10124 break;
10125 case ODK_IDENT:
10126 printf (" IDENT %#06lx self-contained %#06lx",
10127 option->info & OGP_GROUP,
10128 (option->info & OGP_SELF) >> 16);
10129 break;
10130 default:
10131 /* This shouldn't happen. */
10132 printf (" %3d ??? %d %lx",
10133 option->kind, option->section, option->info);
10134 break;
252b5132 10135 }
a6e9f9df 10136
b34976b6 10137 len = sizeof (*eopt);
a6e9f9df
AM
10138 while (len < option->size)
10139 if (((char *) option)[len] >= ' '
10140 && ((char *) option)[len] < 0x7f)
10141 printf ("%c", ((char *) option)[len++]);
10142 else
10143 printf ("\\%03o", ((char *) option)[len++]);
10144
10145 fputs ("\n", stdout);
252b5132 10146 ++option;
252b5132
RH
10147 }
10148
a6e9f9df 10149 free (eopt);
252b5132 10150 }
252b5132
RH
10151 }
10152
10153 if (conflicts_offset != 0 && conflictsno != 0)
10154 {
b34976b6 10155 Elf32_Conflict *iconf;
252b5132
RH
10156 size_t cnt;
10157
10158 if (dynamic_symbols == NULL)
10159 {
3a1a2036 10160 error (_("conflict list found without a dynamic symbol table"));
252b5132
RH
10161 return 0;
10162 }
10163
d3ba0551 10164 iconf = malloc (conflictsno * sizeof (*iconf));
252b5132
RH
10165 if (iconf == NULL)
10166 {
10167 error (_("Out of memory"));
10168 return 0;
10169 }
10170
9ea033b2 10171 if (is_32bit_elf)
252b5132 10172 {
b34976b6 10173 Elf32_External_Conflict *econf32;
a6e9f9df 10174
d3ba0551
AM
10175 econf32 = get_data (NULL, file, conflicts_offset,
10176 conflictsno * sizeof (*econf32), _("conflict"));
a6e9f9df
AM
10177 if (!econf32)
10178 return 0;
252b5132
RH
10179
10180 for (cnt = 0; cnt < conflictsno; ++cnt)
10181 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
10182
10183 free (econf32);
252b5132
RH
10184 }
10185 else
10186 {
b34976b6 10187 Elf64_External_Conflict *econf64;
a6e9f9df 10188
d3ba0551
AM
10189 econf64 = get_data (NULL, file, conflicts_offset,
10190 conflictsno * sizeof (*econf64), _("conflict"));
a6e9f9df
AM
10191 if (!econf64)
10192 return 0;
252b5132
RH
10193
10194 for (cnt = 0; cnt < conflictsno; ++cnt)
10195 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
10196
10197 free (econf64);
252b5132
RH
10198 }
10199
c7e7ca54
NC
10200 printf (_("\nSection '.conflict' contains %lu entries:\n"),
10201 (unsigned long) conflictsno);
252b5132
RH
10202 puts (_(" Num: Index Value Name"));
10203
10204 for (cnt = 0; cnt < conflictsno; ++cnt)
10205 {
b34976b6 10206 Elf_Internal_Sym *psym = & dynamic_symbols[iconf[cnt]];
252b5132 10207
b34976b6 10208 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 10209 print_vma (psym->st_value, FULL_HEX);
31104126
NC
10210 putchar (' ');
10211 print_symbol (25, dynamic_strings + psym->st_name);
10212 putchar ('\n');
252b5132
RH
10213 }
10214
252b5132
RH
10215 free (iconf);
10216 }
10217
10218 return 1;
10219}
10220
047b2264 10221static int
d3ba0551 10222process_gnu_liblist (FILE *file)
047b2264 10223{
b34976b6
AM
10224 Elf_Internal_Shdr *section, *string_sec;
10225 Elf32_External_Lib *elib;
10226 char *strtab;
047b2264
JJ
10227 size_t cnt;
10228 unsigned i;
10229
10230 if (! do_arch)
10231 return 0;
10232
10233 for (i = 0, section = section_headers;
10234 i < elf_header.e_shnum;
b34976b6 10235 i++, section++)
047b2264
JJ
10236 {
10237 switch (section->sh_type)
10238 {
10239 case SHT_GNU_LIBLIST:
d3ba0551
AM
10240 elib = get_data (NULL, file, section->sh_offset, section->sh_size,
10241 _("liblist"));
047b2264
JJ
10242
10243 if (elib == NULL)
10244 break;
10245 string_sec = SECTION_HEADER (section->sh_link);
10246
d3ba0551
AM
10247 strtab = get_data (NULL, file, string_sec->sh_offset,
10248 string_sec->sh_size, _("liblist string table"));
047b2264
JJ
10249
10250 if (strtab == NULL
10251 || section->sh_entsize != sizeof (Elf32_External_Lib))
10252 {
10253 free (elib);
10254 break;
10255 }
10256
10257 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
10258 SECTION_NAME (section),
10259 (long) (section->sh_size / sizeof (Elf32_External_Lib)));
10260
10261 puts (" Library Time Stamp Checksum Version Flags");
10262
10263 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
10264 ++cnt)
10265 {
10266 Elf32_Lib liblist;
10267 time_t time;
10268 char timebuf[20];
b34976b6 10269 struct tm *tmp;
047b2264
JJ
10270
10271 liblist.l_name = BYTE_GET (elib[cnt].l_name);
10272 time = BYTE_GET (elib[cnt].l_time_stamp);
10273 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
10274 liblist.l_version = BYTE_GET (elib[cnt].l_version);
10275 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
10276
10277 tmp = gmtime (&time);
10278 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
10279 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10280 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
10281
10282 printf ("%3lu: ", (unsigned long) cnt);
10283 if (do_wide)
10284 printf ("%-20s", strtab + liblist.l_name);
10285 else
10286 printf ("%-20.20s", strtab + liblist.l_name);
10287 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
10288 liblist.l_version, liblist.l_flags);
10289 }
10290
10291 free (elib);
10292 }
10293 }
10294
10295 return 1;
10296}
10297
9437c45b 10298static const char *
d3ba0551 10299get_note_type (unsigned e_type)
779fe533
NC
10300{
10301 static char buff[64];
103f02d3 10302
779fe533
NC
10303 switch (e_type)
10304 {
0de14b54 10305 case NT_AUXV: return _("NT_AUXV (auxiliary vector)");
779fe533
NC
10306 case NT_PRSTATUS: return _("NT_PRSTATUS (prstatus structure)");
10307 case NT_FPREGSET: return _("NT_FPREGSET (floating point registers)");
b34976b6
AM
10308 case NT_PRPSINFO: return _("NT_PRPSINFO (prpsinfo structure)");
10309 case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
10310 case NT_PRXFPREG: return _("NT_PRXFPREG (user_xfpregs structure)");
779fe533
NC
10311 case NT_PSTATUS: return _("NT_PSTATUS (pstatus structure)");
10312 case NT_FPREGS: return _("NT_FPREGS (floating point registers)");
10313 case NT_PSINFO: return _("NT_PSINFO (psinfo structure)");
10314 case NT_LWPSTATUS: return _("NT_LWPSTATUS (lwpstatus_t structure)");
10315 case NT_LWPSINFO: return _("NT_LWPSINFO (lwpsinfo_t structure)");
3a1a2036 10316 case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus structure)");
779fe533
NC
10317 default:
10318 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
10319 return buff;
10320 }
10321}
10322
9437c45b 10323static const char *
d3ba0551 10324get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
10325{
10326 static char buff[64];
10327
b4db1224 10328 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
10329 {
10330 /* NetBSD core "procinfo" structure. */
10331 return _("NetBSD procinfo structure");
10332 }
10333
10334 /* As of Jan 2002 there are no other machine-independent notes
10335 defined for NetBSD core files. If the note type is less
10336 than the start of the machine-dependent note types, we don't
10337 understand it. */
10338
b4db1224 10339 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b
JT
10340 {
10341 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
10342 return buff;
10343 }
10344
10345 switch (elf_header.e_machine)
10346 {
10347 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
10348 and PT_GETFPREGS == mach+2. */
10349
10350 case EM_OLD_ALPHA:
10351 case EM_ALPHA:
10352 case EM_SPARC:
10353 case EM_SPARC32PLUS:
10354 case EM_SPARCV9:
10355 switch (e_type)
10356 {
b4db1224
JT
10357 case NT_NETBSDCORE_FIRSTMACH+0:
10358 return _("PT_GETREGS (reg structure)");
10359 case NT_NETBSDCORE_FIRSTMACH+2:
10360 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
10361 default:
10362 break;
10363 }
10364 break;
10365
10366 /* On all other arch's, PT_GETREGS == mach+1 and
10367 PT_GETFPREGS == mach+3. */
10368 default:
10369 switch (e_type)
10370 {
b4db1224
JT
10371 case NT_NETBSDCORE_FIRSTMACH+1:
10372 return _("PT_GETREGS (reg structure)");
10373 case NT_NETBSDCORE_FIRSTMACH+3:
10374 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
10375 default:
10376 break;
10377 }
10378 }
10379
b4db1224 10380 sprintf (buff, _("PT_FIRSTMACH+%d"), e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
10381 return buff;
10382}
10383
6d118b09
NC
10384/* Note that by the ELF standard, the name field is already null byte
10385 terminated, and namesz includes the terminating null byte.
10386 I.E. the value of namesz for the name "FSF" is 4.
10387
e3c8793a 10388 If the value of namesz is zero, there is no name present. */
779fe533 10389static int
d3ba0551 10390process_note (Elf_Internal_Note *pnote)
779fe533 10391{
9437c45b
JT
10392 const char *nt;
10393
10394 if (pnote->namesz == 0)
10395 {
10396 /* If there is no note name, then use the default set of
10397 note type strings. */
10398 nt = get_note_type (pnote->type);
10399 }
10400 else if (strncmp (pnote->namedata, "NetBSD-CORE", 11) == 0)
10401 {
10402 /* NetBSD-specific core file notes. */
10403 nt = get_netbsd_elfcore_note_type (pnote->type);
10404 }
10405 else
10406 {
10407 /* Don't recognize this note name; just use the default set of
10408 note type strings. */
10409 nt = get_note_type (pnote->type);
10410 }
10411
103f02d3 10412 printf (" %s\t\t0x%08lx\t%s\n",
6d118b09 10413 pnote->namesz ? pnote->namedata : "(NONE)",
9437c45b 10414 pnote->descsz, nt);
779fe533
NC
10415 return 1;
10416}
10417
6d118b09 10418
779fe533 10419static int
d3ba0551 10420process_corefile_note_segment (FILE *file, bfd_vma offset, bfd_vma length)
779fe533 10421{
b34976b6
AM
10422 Elf_External_Note *pnotes;
10423 Elf_External_Note *external;
10424 int res = 1;
103f02d3 10425
779fe533
NC
10426 if (length <= 0)
10427 return 0;
103f02d3 10428
d3ba0551 10429 pnotes = get_data (NULL, file, offset, length, _("notes"));
a6e9f9df
AM
10430 if (!pnotes)
10431 return 0;
779fe533 10432
103f02d3 10433 external = pnotes;
103f02d3 10434
305c7206 10435 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 10436 (unsigned long) offset, (unsigned long) length);
779fe533 10437 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 10438
6d118b09 10439 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 10440 {
b34976b6
AM
10441 Elf_External_Note *next;
10442 Elf_Internal_Note inote;
10443 char *temp = NULL;
6d118b09
NC
10444
10445 inote.type = BYTE_GET (external->type);
10446 inote.namesz = BYTE_GET (external->namesz);
10447 inote.namedata = external->name;
10448 inote.descsz = BYTE_GET (external->descsz);
10449 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
10450 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 10451
3e55a963
NC
10452 next = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
10453
10454 if (((char *) next) > (((char *) pnotes) + length))
10455 {
10456 warn (_("corrupt note found at offset %x into core notes\n"),
10457 ((char *) external) - ((char *) pnotes));
10458 warn (_(" type: %x, namesize: %08lx, descsize: %08lx\n"),
10459 inote.type, inote.namesz, inote.descsz);
10460 break;
10461 }
10462
10463 external = next;
6d118b09
NC
10464
10465 /* Verify that name is null terminated. It appears that at least
10466 one version of Linux (RedHat 6.0) generates corefiles that don't
10467 comply with the ELF spec by failing to include the null byte in
10468 namesz. */
10469 if (inote.namedata[inote.namesz] != '\0')
10470 {
10471 temp = malloc (inote.namesz + 1);
76da6bbe 10472
6d118b09
NC
10473 if (temp == NULL)
10474 {
10475 error (_("Out of memory\n"));
10476 res = 0;
10477 break;
10478 }
76da6bbe 10479
6d118b09
NC
10480 strncpy (temp, inote.namedata, inote.namesz);
10481 temp[inote.namesz] = 0;
76da6bbe 10482
6d118b09
NC
10483 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
10484 inote.namedata = temp;
10485 }
10486
10487 res &= process_note (& inote);
103f02d3 10488
6d118b09
NC
10489 if (temp != NULL)
10490 {
10491 free (temp);
10492 temp = NULL;
10493 }
779fe533
NC
10494 }
10495
10496 free (pnotes);
103f02d3 10497
779fe533
NC
10498 return res;
10499}
10500
10501static int
d3ba0551 10502process_corefile_note_segments (FILE *file)
779fe533 10503{
b34976b6
AM
10504 Elf_Internal_Phdr *segment;
10505 unsigned int i;
10506 int res = 1;
103f02d3 10507
d93f0186 10508 if (! get_program_headers (file))
779fe533 10509 return 0;
103f02d3 10510
779fe533
NC
10511 for (i = 0, segment = program_headers;
10512 i < elf_header.e_phnum;
b34976b6 10513 i++, segment++)
779fe533
NC
10514 {
10515 if (segment->p_type == PT_NOTE)
103f02d3 10516 res &= process_corefile_note_segment (file,
30800947
NC
10517 (bfd_vma) segment->p_offset,
10518 (bfd_vma) segment->p_filesz);
779fe533 10519 }
103f02d3 10520
779fe533
NC
10521 return res;
10522}
10523
10524static int
d3ba0551 10525process_corefile_contents (FILE *file)
779fe533
NC
10526{
10527 /* If we have not been asked to display the notes then do nothing. */
10528 if (! do_notes)
10529 return 1;
103f02d3 10530
779fe533
NC
10531 /* If file is not a core file then exit. */
10532 if (elf_header.e_type != ET_CORE)
10533 return 1;
103f02d3 10534
779fe533
NC
10535 /* No program headers means no NOTE segment. */
10536 if (elf_header.e_phnum == 0)
10537 {
10538 printf (_("No note segments present in the core file.\n"));
10539 return 1;
10540 }
10541
10542 return process_corefile_note_segments (file);
10543}
10544
252b5132 10545static int
d3ba0551 10546process_arch_specific (FILE *file)
252b5132 10547{
a952a375
NC
10548 if (! do_arch)
10549 return 1;
10550
252b5132
RH
10551 switch (elf_header.e_machine)
10552 {
10553 case EM_MIPS:
4fe85591 10554 case EM_MIPS_RS3_LE:
252b5132
RH
10555 return process_mips_specific (file);
10556 break;
10557 default:
10558 break;
10559 }
10560 return 1;
10561}
10562
10563static int
d3ba0551 10564get_file_header (FILE *file)
252b5132 10565{
9ea033b2
NC
10566 /* Read in the identity array. */
10567 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
10568 return 0;
10569
9ea033b2 10570 /* Determine how to read the rest of the header. */
b34976b6 10571 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
10572 {
10573 default: /* fall through */
10574 case ELFDATANONE: /* fall through */
adab8cdc
AO
10575 case ELFDATA2LSB:
10576 byte_get = byte_get_little_endian;
10577 byte_put = byte_put_little_endian;
10578 break;
10579 case ELFDATA2MSB:
10580 byte_get = byte_get_big_endian;
10581 byte_put = byte_put_big_endian;
10582 break;
9ea033b2
NC
10583 }
10584
10585 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 10586 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
10587
10588 /* Read in the rest of the header. */
10589 if (is_32bit_elf)
10590 {
10591 Elf32_External_Ehdr ehdr32;
252b5132 10592
9ea033b2
NC
10593 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
10594 return 0;
103f02d3 10595
9ea033b2
NC
10596 elf_header.e_type = BYTE_GET (ehdr32.e_type);
10597 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
10598 elf_header.e_version = BYTE_GET (ehdr32.e_version);
10599 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
10600 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
10601 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
10602 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
10603 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
10604 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
10605 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
10606 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
10607 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
10608 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
10609 }
252b5132 10610 else
9ea033b2
NC
10611 {
10612 Elf64_External_Ehdr ehdr64;
a952a375
NC
10613
10614 /* If we have been compiled with sizeof (bfd_vma) == 4, then
10615 we will not be able to cope with the 64bit data found in
10616 64 ELF files. Detect this now and abort before we start
50c2245b 10617 overwriting things. */
a952a375
NC
10618 if (sizeof (bfd_vma) < 8)
10619 {
e3c8793a
NC
10620 error (_("This instance of readelf has been built without support for a\n\
1062164 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
10622 return 0;
10623 }
103f02d3 10624
9ea033b2
NC
10625 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
10626 return 0;
103f02d3 10627
9ea033b2
NC
10628 elf_header.e_type = BYTE_GET (ehdr64.e_type);
10629 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
10630 elf_header.e_version = BYTE_GET (ehdr64.e_version);
10631 elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry);
10632 elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff);
10633 elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff);
10634 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
10635 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
10636 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
10637 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
10638 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
10639 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
10640 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
10641 }
252b5132 10642
7ece0d85
JJ
10643 if (elf_header.e_shoff)
10644 {
10645 /* There may be some extensions in the first section header. Don't
10646 bomb if we can't read it. */
10647 if (is_32bit_elf)
10648 get_32bit_section_headers (file, 1);
10649 else
10650 get_64bit_section_headers (file, 1);
10651 }
560f3c1c 10652
252b5132
RH
10653 return 1;
10654}
10655
fb52b2f4
NC
10656/* Process one ELF object file according to the command line options.
10657 This file may actually be stored in an archive. The file is
10658 positioned at the start of the ELF object. */
10659
ff78d6d6 10660static int
fb52b2f4 10661process_object (char *file_name, FILE *file)
252b5132 10662{
252b5132
RH
10663 unsigned int i;
10664
252b5132
RH
10665 if (! get_file_header (file))
10666 {
10667 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 10668 return 1;
252b5132
RH
10669 }
10670
10671 /* Initialise per file variables. */
10672 for (i = NUM_ELEM (version_info); i--;)
10673 version_info[i] = 0;
10674
10675 for (i = NUM_ELEM (dynamic_info); i--;)
10676 dynamic_info[i] = 0;
10677
10678 /* Process the file. */
10679 if (show_name)
10680 printf (_("\nFile: %s\n"), file_name);
10681
10682 if (! process_file_header ())
fb52b2f4 10683 return 1;
252b5132 10684
e4b17d5c
L
10685 if (! process_section_headers (file)
10686 || ! process_section_groups (file))
2f62977e 10687 {
e4b17d5c 10688 /* Without loaded section headers and section groups we
2f62977e
NC
10689 cannot process lots of things. */
10690 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 10691
2f62977e
NC
10692 if (! do_using_dynamic)
10693 do_syms = do_reloc = 0;
10694 }
252b5132 10695
2f62977e 10696 if (process_program_headers (file))
b2d38a17 10697 process_dynamic_section (file);
252b5132
RH
10698
10699 process_relocs (file);
10700
4d6ed7c8
NC
10701 process_unwind (file);
10702
252b5132
RH
10703 process_symbol_table (file);
10704
10705 process_syminfo (file);
10706
10707 process_version_sections (file);
10708
10709 process_section_contents (file);
f5842774 10710
779fe533 10711 process_corefile_contents (file);
103f02d3 10712
047b2264
JJ
10713 process_gnu_liblist (file);
10714
252b5132
RH
10715 process_arch_specific (file);
10716
d93f0186
NC
10717 if (program_headers)
10718 {
10719 free (program_headers);
10720 program_headers = NULL;
10721 }
10722
252b5132
RH
10723 if (section_headers)
10724 {
10725 free (section_headers);
10726 section_headers = NULL;
10727 }
10728
10729 if (string_table)
10730 {
10731 free (string_table);
10732 string_table = NULL;
d40ac9bd 10733 string_table_length = 0;
252b5132
RH
10734 }
10735
10736 if (dynamic_strings)
10737 {
10738 free (dynamic_strings);
10739 dynamic_strings = NULL;
10740 }
10741
10742 if (dynamic_symbols)
10743 {
10744 free (dynamic_symbols);
10745 dynamic_symbols = NULL;
19936277 10746 num_dynamic_syms = 0;
252b5132
RH
10747 }
10748
10749 if (dynamic_syminfo)
10750 {
10751 free (dynamic_syminfo);
10752 dynamic_syminfo = NULL;
10753 }
ff78d6d6 10754
e4b17d5c
L
10755 if (section_headers_groups)
10756 {
10757 free (section_headers_groups);
10758 section_headers_groups = NULL;
10759 }
10760
10761 if (section_groups)
10762 {
10763 struct group_list *g, *next;
10764
10765 for (i = 0; i < group_count; i++)
10766 {
10767 for (g = section_groups [i].root; g != NULL; g = next)
10768 {
10769 next = g->next;
10770 free (g);
10771 }
10772 }
10773
10774 free (section_groups);
10775 section_groups = NULL;
10776 }
10777
ff78d6d6 10778 return 0;
252b5132
RH
10779}
10780
fb52b2f4
NC
10781/* Process an ELF archive. The file is positioned just after the
10782 ARMAG string. */
10783
10784static int
10785process_archive (char *file_name, FILE *file)
10786{
10787 struct ar_hdr arhdr;
10788 size_t got;
10789 unsigned long size;
10790 char *longnames = NULL;
10791 unsigned long longnames_size = 0;
10792 size_t file_name_size;
d989285c 10793 int ret;
fb52b2f4
NC
10794
10795 show_name = 1;
10796
10797 got = fread (&arhdr, 1, sizeof arhdr, file);
10798 if (got != sizeof arhdr)
10799 {
10800 if (got == 0)
10801 return 0;
10802
10803 error (_("%s: failed to read archive header\n"), file_name);
10804 return 1;
10805 }
10806
10807 if (memcmp (arhdr.ar_name, "/ ", 16) == 0)
10808 {
10809 /* This is the archive symbol table. Skip it.
10810 FIXME: We should have an option to dump it. */
10811 size = strtoul (arhdr.ar_size, NULL, 10);
10812 if (fseek (file, size + (size & 1), SEEK_CUR) != 0)
10813 {
10814 error (_("%s: failed to skip archive symbol table\n"), file_name);
10815 return 1;
10816 }
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
10829 if (memcmp (arhdr.ar_name, "// ", 16) == 0)
10830 {
10831 /* This is the archive string table holding long member
10832 names. */
10833
10834 longnames_size = strtoul (arhdr.ar_size, NULL, 10);
10835
10836 longnames = malloc (longnames_size);
10837 if (longnames == NULL)
10838 {
10839 error (_("Out of memory\n"));
10840 return 1;
10841 }
10842
10843 if (fread (longnames, longnames_size, 1, file) != 1)
10844 {
d989285c 10845 free (longnames);
fb52b2f4
NC
10846 error(_("%s: failed to read string table\n"), file_name);
10847 return 1;
10848 }
10849
10850 if ((longnames_size & 1) != 0)
10851 getc (file);
10852
10853 got = fread (&arhdr, 1, sizeof arhdr, file);
10854 if (got != sizeof arhdr)
10855 {
d989285c
ILT
10856 free (longnames);
10857
fb52b2f4
NC
10858 if (got == 0)
10859 return 0;
10860
10861 error (_("%s: failed to read archive header\n"), file_name);
10862 return 1;
10863 }
10864 }
10865
10866 file_name_size = strlen (file_name);
d989285c 10867 ret = 0;
fb52b2f4
NC
10868
10869 while (1)
10870 {
10871 char *name;
10872 char *nameend;
10873 char *namealc;
10874
10875 if (arhdr.ar_name[0] == '/')
10876 {
10877 unsigned long off;
10878
10879 off = strtoul (arhdr.ar_name + 1, NULL, 10);
10880 if (off >= longnames_size)
10881 {
10882 error (_("%s: invalid archive string table offset %lu\n"), off);
d989285c
ILT
10883 ret = 1;
10884 break;
fb52b2f4
NC
10885 }
10886
10887 name = longnames + off;
10888 nameend = memchr (name, '/', longnames_size - off);
10889 }
10890 else
10891 {
10892 name = arhdr.ar_name;
10893 nameend = memchr (name, '/', 16);
10894 }
10895
10896 if (nameend == NULL)
10897 {
10898 error (_("%s: bad archive file name\n"));
d989285c
ILT
10899 ret = 1;
10900 break;
fb52b2f4
NC
10901 }
10902
10903 namealc = malloc (file_name_size + (nameend - name) + 3);
10904 if (namealc == NULL)
10905 {
10906 error (_("Out of memory\n"));
d989285c
ILT
10907 ret = 1;
10908 break;
fb52b2f4
NC
10909 }
10910
10911 memcpy (namealc, file_name, file_name_size);
10912 namealc[file_name_size] = '(';
10913 memcpy (namealc + file_name_size + 1, name, nameend - name);
10914 namealc[file_name_size + 1 + (nameend - name)] = ')';
10915 namealc[file_name_size + 2 + (nameend - name)] = '\0';
10916
10917 archive_file_offset = ftell (file);
10918 archive_file_size = strtoul (arhdr.ar_size, NULL, 10);
10919
d989285c 10920 ret |= process_object (namealc, file);
fb52b2f4
NC
10921
10922 free (namealc);
10923
10924 if (fseek (file,
10925 (archive_file_offset
10926 + archive_file_size
10927 + (archive_file_size & 1)),
10928 SEEK_SET) != 0)
10929 {
10930 error (_("%s: failed to seek to next archive header\n"), file_name);
d989285c
ILT
10931 ret = 1;
10932 break;
fb52b2f4
NC
10933 }
10934
10935 got = fread (&arhdr, 1, sizeof arhdr, file);
10936 if (got != sizeof arhdr)
10937 {
10938 if (got == 0)
d989285c 10939 break;
fb52b2f4
NC
10940
10941 error (_("%s: failed to read archive header\n"), file_name);
d989285c
ILT
10942 ret = 1;
10943 break;
fb52b2f4
NC
10944 }
10945 }
10946
10947 if (longnames != 0)
10948 free (longnames);
10949
d989285c 10950 return ret;
fb52b2f4
NC
10951}
10952
10953static int
10954process_file (char *file_name)
10955{
10956 FILE *file;
10957 struct stat statbuf;
10958 char armag[SARMAG];
10959 int ret;
10960
10961 if (stat (file_name, &statbuf) < 0)
10962 {
f24ddbdd
NC
10963 if (errno == ENOENT)
10964 error (_("'%s': No such file\n"), file_name);
10965 else
10966 error (_("Could not locate '%s'. System error message: %s\n"),
10967 file_name, strerror (errno));
10968 return 1;
10969 }
10970
10971 if (! S_ISREG (statbuf.st_mode))
10972 {
10973 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
10974 return 1;
10975 }
10976
10977 file = fopen (file_name, "rb");
10978 if (file == NULL)
10979 {
f24ddbdd 10980 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
10981 return 1;
10982 }
10983
10984 if (fread (armag, SARMAG, 1, file) != 1)
10985 {
10986 error (_("%s: Failed to read file header\n"), file_name);
10987 fclose (file);
10988 return 1;
10989 }
10990
10991 if (memcmp (armag, ARMAG, SARMAG) == 0)
10992 ret = process_archive (file_name, file);
10993 else
10994 {
10995 rewind (file);
10996 archive_file_size = archive_file_offset = 0;
10997 ret = process_object (file_name, file);
10998 }
10999
11000 fclose (file);
11001
11002 return ret;
11003}
11004
252b5132
RH
11005#ifdef SUPPORT_DISASSEMBLY
11006/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 11007 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 11008 symbols. */
252b5132
RH
11009
11010void
b34976b6 11011print_address (unsigned int addr, FILE *outfile)
252b5132
RH
11012{
11013 fprintf (outfile,"0x%8.8x", addr);
11014}
11015
e3c8793a 11016/* Needed by the i386 disassembler. */
252b5132
RH
11017void
11018db_task_printsym (unsigned int addr)
11019{
11020 print_address (addr, stderr);
11021}
11022#endif
11023
11024int
d3ba0551 11025main (int argc, char **argv)
252b5132 11026{
ff78d6d6 11027 int err;
59f14fc0
AS
11028 char *cmdline_dump_sects = NULL;
11029 unsigned num_cmdline_dump_sects = 0;
ff78d6d6 11030
252b5132
RH
11031#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
11032 setlocale (LC_MESSAGES, "");
3882b010
L
11033#endif
11034#if defined (HAVE_SETLOCALE)
11035 setlocale (LC_CTYPE, "");
252b5132
RH
11036#endif
11037 bindtextdomain (PACKAGE, LOCALEDIR);
11038 textdomain (PACKAGE);
11039
11040 parse_args (argc, argv);
11041
11042 if (optind < (argc - 1))
11043 show_name = 1;
11044
59f14fc0
AS
11045 /* When processing more than one file remember the dump requests
11046 issued on command line to reset them after each file. */
11047 if (optind + 1 < argc && dump_sects != NULL)
11048 {
11049 cmdline_dump_sects = malloc (num_dump_sects);
11050 if (cmdline_dump_sects == NULL)
11051 error (_("Out of memory allocating dump request table."));
11052 else
11053 {
11054 memcpy (cmdline_dump_sects, dump_sects, num_dump_sects);
11055 num_cmdline_dump_sects = num_dump_sects;
11056 }
11057 }
11058
ff78d6d6 11059 err = 0;
252b5132 11060 while (optind < argc)
59f14fc0
AS
11061 {
11062 err |= process_file (argv[optind++]);
11063
11064 /* Reset dump requests. */
11065 if (optind < argc && dump_sects != NULL)
11066 {
11067 num_dump_sects = num_cmdline_dump_sects;
11068 if (num_cmdline_dump_sects > 0)
11069 memcpy (dump_sects, cmdline_dump_sects, num_cmdline_dump_sects);
11070 }
11071 }
252b5132
RH
11072
11073 if (dump_sects != NULL)
11074 free (dump_sects);
59f14fc0
AS
11075 if (cmdline_dump_sects != NULL)
11076 free (cmdline_dump_sects);
252b5132 11077
ff78d6d6 11078 return err;
252b5132 11079}