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