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