2005-02-20 Andrew Cagney <cagney@gnu.org>
[deliverable/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;
d1f5c6e3 188size_t group_count;
e4b17d5c
L
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;
d1f5c6e3
L
3959 Elf_Internal_Shdr *symtab_sec, *strtab_sec;
3960 Elf_Internal_Sym *symtab;
3961 char *strtab;
3962
3963 /* Don't process section groups unless needed. */
3964 if (!do_unwind && !do_section_groups)
3965 return 1;
f5842774
L
3966
3967 if (elf_header.e_shnum == 0)
3968 {
3969 if (do_section_groups)
d1f5c6e3 3970 printf (_("\nThere are no sections in this file.\n"));
f5842774
L
3971
3972 return 1;
3973 }
3974
3975 if (section_headers == NULL)
3976 {
3977 error (_("Section headers are not available!\n"));
3978 abort ();
3979 }
3980
e4b17d5c
L
3981 section_headers_groups = calloc (elf_header.e_shnum,
3982 sizeof (struct group *));
3983
3984 if (section_headers_groups == NULL)
3985 {
3986 error (_("Out of memory\n"));
3987 return 0;
3988 }
3989
f5842774 3990 /* Scan the sections for the group section. */
d1f5c6e3 3991 group_count = 0;
f5842774
L
3992 for (i = 0, section = section_headers;
3993 i < elf_header.e_shnum;
3994 i++, section++)
e4b17d5c
L
3995 if (section->sh_type == SHT_GROUP)
3996 group_count++;
3997
d1f5c6e3
L
3998 if (group_count == 0)
3999 {
4000 if (do_section_groups)
4001 printf (_("\nThere are no section groups in this file.\n"));
4002
4003 return 1;
4004 }
4005
e4b17d5c
L
4006 section_groups = calloc (group_count, sizeof (struct group));
4007
4008 if (section_groups == NULL)
4009 {
4010 error (_("Out of memory\n"));
4011 return 0;
4012 }
4013
d1f5c6e3
L
4014 symtab_sec = NULL;
4015 strtab_sec = NULL;
4016 symtab = NULL;
4017 strtab = NULL;
e4b17d5c
L
4018 for (i = 0, section = section_headers, group = section_groups;
4019 i < elf_header.e_shnum;
4020 i++, section++)
f5842774
L
4021 {
4022 if (section->sh_type == SHT_GROUP)
4023 {
4024 char *name = SECTION_NAME (section);
d1f5c6e3 4025 char *group_name, *start, *indices;
f5842774 4026 unsigned int entry, j, size;
d1f5c6e3 4027 Elf_Internal_Shdr *sec;
f5842774 4028 Elf_Internal_Sym *sym;
f5842774
L
4029
4030 /* Get the symbol table. */
d1f5c6e3
L
4031 sec = SECTION_HEADER (section->sh_link);
4032 if (sec->sh_type != SHT_SYMTAB)
f5842774
L
4033 {
4034 error (_("Bad sh_link in group section `%s'\n"), name);
4035 continue;
4036 }
d1f5c6e3
L
4037
4038 if (symtab_sec != sec)
4039 {
4040 symtab_sec = sec;
4041 if (symtab)
4042 free (symtab);
4043 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
4044 }
f5842774
L
4045
4046 sym = symtab + section->sh_info;
4047
4048 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4049 {
4050 bfd_vma sec_index = SECTION_HEADER_INDEX (sym->st_shndx);
4051 if (sec_index == 0)
4052 {
4053 error (_("Bad sh_info in group section `%s'\n"), name);
4054 continue;
4055 }
ba2685cc 4056
f5842774
L
4057 group_name = SECTION_NAME (section_headers + sec_index);
4058 strtab = NULL;
4059 }
4060 else
4061 {
4062 /* Get the string table. */
d1f5c6e3
L
4063 sec = SECTION_HEADER (symtab_sec->sh_link);
4064 if (strtab_sec != sec)
4065 {
4066 strtab_sec = sec;
4067 if (strtab)
4068 free (strtab);
4069 strtab = get_data (NULL, file, strtab_sec->sh_offset,
4070 strtab_sec->sh_size,
4071 _("string table"));
4072 }
f5842774
L
4073 group_name = strtab + sym->st_name;
4074 }
4075
4076 start = get_data (NULL, file, section->sh_offset,
4077 section->sh_size, _("section data"));
4078
4079 indices = start;
4080 size = (section->sh_size / section->sh_entsize) - 1;
4081 entry = byte_get (indices, 4);
4082 indices += 4;
e4b17d5c
L
4083
4084 if (do_section_groups)
4085 {
4086 printf ("\n%s group section `%s' [%s] contains %u sections:\n",
ba2685cc
AM
4087 get_group_flags (entry), name, group_name, size);
4088
e4b17d5c
L
4089 printf (_(" [Index] Name\n"));
4090 }
4091
4092 group->group_index = i;
4093
f5842774
L
4094 for (j = 0; j < size; j++)
4095 {
e4b17d5c
L
4096 struct group_list *g;
4097
f5842774
L
4098 entry = byte_get (indices, 4);
4099 indices += 4;
4100
e4b17d5c
L
4101 if (section_headers_groups [SECTION_HEADER_INDEX (entry)]
4102 != NULL)
4103 {
d1f5c6e3
L
4104 if (entry)
4105 {
4106 error (_("section [%5u] already in group section [%5u]\n"),
4107 entry,
4108 section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
4109 continue;
4110 }
4111 else
4112 {
4113 /* Intel C/C++ compiler may put section 0 in a
4114 section group. We just warn it the first time
4115 and ignore it afterwards. */
4116 static int warned = 0;
4117 if (!warned)
4118 {
4119 error (_("section 0 in group section [%5u]\n"),
4120 section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
4121 warned++;
4122 }
4123 }
e4b17d5c
L
4124 }
4125
4126 section_headers_groups [SECTION_HEADER_INDEX (entry)]
4127 = group;
4128
4129 if (do_section_groups)
4130 {
4131 sec = SECTION_HEADER (entry);
4132 printf (" [%5u] %s\n",
4133 entry, SECTION_NAME (sec));
ba2685cc
AM
4134 }
4135
e4b17d5c
L
4136 g = xmalloc (sizeof (struct group_list));
4137 g->section_index = entry;
4138 g->next = group->root;
4139 group->root = g;
f5842774
L
4140 }
4141
f5842774
L
4142 if (start)
4143 free (start);
e4b17d5c
L
4144
4145 group++;
f5842774
L
4146 }
4147 }
4148
d1f5c6e3
L
4149 if (symtab)
4150 free (symtab);
4151 if (strtab)
4152 free (strtab);
f5842774
L
4153 return 1;
4154}
4155
566b0d53
L
4156struct
4157{
4158 const char *name;
4159 int reloc;
4160 int size;
4161 int rela;
4162} dynamic_relocations [] =
4163{
4164 { "REL", DT_REL, DT_RELSZ, FALSE },
4165 { "RELA", DT_RELA, DT_RELASZ, TRUE },
4166 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
4167};
4168
252b5132 4169/* Process the reloc section. */
18bd398b 4170
252b5132 4171static int
d3ba0551 4172process_relocs (FILE *file)
252b5132 4173{
b34976b6
AM
4174 unsigned long rel_size;
4175 unsigned long rel_offset;
252b5132
RH
4176
4177
4178 if (!do_reloc)
4179 return 1;
4180
4181 if (do_using_dynamic)
4182 {
566b0d53
L
4183 int is_rela;
4184 const char *name;
4185 int has_dynamic_reloc;
4186 unsigned int i;
0de14b54 4187
566b0d53 4188 has_dynamic_reloc = 0;
252b5132 4189
566b0d53 4190 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 4191 {
566b0d53
L
4192 is_rela = dynamic_relocations [i].rela;
4193 name = dynamic_relocations [i].name;
4194 rel_size = dynamic_info [dynamic_relocations [i].size];
4195 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 4196
566b0d53
L
4197 has_dynamic_reloc |= rel_size;
4198
4199 if (is_rela == UNKNOWN)
aa903cfb 4200 {
566b0d53
L
4201 if (dynamic_relocations [i].reloc == DT_JMPREL)
4202 switch (dynamic_info[DT_PLTREL])
4203 {
4204 case DT_REL:
4205 is_rela = FALSE;
4206 break;
4207 case DT_RELA:
4208 is_rela = TRUE;
4209 break;
4210 }
aa903cfb 4211 }
252b5132 4212
566b0d53
L
4213 if (rel_size)
4214 {
4215 printf
4216 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
4217 name, rel_offset, rel_size);
252b5132 4218
d93f0186
NC
4219 dump_relocations (file,
4220 offset_from_vma (file, rel_offset, rel_size),
4221 rel_size,
566b0d53 4222 dynamic_symbols, num_dynamic_syms,
d79b3d50 4223 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 4224 }
252b5132 4225 }
566b0d53
L
4226
4227 if (! has_dynamic_reloc)
252b5132
RH
4228 printf (_("\nThere are no dynamic relocations in this file.\n"));
4229 }
4230 else
4231 {
b34976b6
AM
4232 Elf_Internal_Shdr *section;
4233 unsigned long i;
4234 int found = 0;
252b5132
RH
4235
4236 for (i = 0, section = section_headers;
4237 i < elf_header.e_shnum;
b34976b6 4238 i++, section++)
252b5132
RH
4239 {
4240 if ( section->sh_type != SHT_RELA
4241 && section->sh_type != SHT_REL)
4242 continue;
4243
4244 rel_offset = section->sh_offset;
4245 rel_size = section->sh_size;
4246
4247 if (rel_size)
4248 {
b34976b6 4249 Elf_Internal_Shdr *strsec;
b34976b6 4250 int is_rela;
103f02d3 4251
252b5132
RH
4252 printf (_("\nRelocation section "));
4253
4254 if (string_table == NULL)
19936277 4255 printf ("%d", section->sh_name);
252b5132 4256 else
3a1a2036 4257 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
4258
4259 printf (_(" at offset 0x%lx contains %lu entries:\n"),
4260 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
4261
d79b3d50
NC
4262 is_rela = section->sh_type == SHT_RELA;
4263
af3fc3bc
AM
4264 if (section->sh_link)
4265 {
b34976b6 4266 Elf_Internal_Shdr *symsec;
d79b3d50
NC
4267 Elf_Internal_Sym *symtab;
4268 unsigned long nsyms;
4269 unsigned long strtablen;
4270 char *strtab = NULL;
57346661 4271
9ad5cbcf 4272 symsec = SECTION_HEADER (section->sh_link);
af3fc3bc 4273 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 4274 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 4275
af3fc3bc
AM
4276 if (symtab == NULL)
4277 continue;
252b5132 4278
9ad5cbcf 4279 strsec = SECTION_HEADER (symsec->sh_link);
103f02d3 4280
d3ba0551
AM
4281 strtab = get_data (NULL, file, strsec->sh_offset,
4282 strsec->sh_size, _("string table"));
d79b3d50 4283 strtablen = strtab == NULL ? 0 : strsec->sh_size;
252b5132 4284
d79b3d50
NC
4285 dump_relocations (file, rel_offset, rel_size,
4286 symtab, nsyms, strtab, strtablen, is_rela);
4287 if (strtab)
4288 free (strtab);
4289 free (symtab);
4290 }
4291 else
4292 dump_relocations (file, rel_offset, rel_size,
4293 NULL, 0, NULL, 0, is_rela);
252b5132
RH
4294
4295 found = 1;
4296 }
4297 }
4298
4299 if (! found)
4300 printf (_("\nThere are no relocations in this file.\n"));
4301 }
4302
4303 return 1;
4304}
4305
57346661
AM
4306/* Process the unwind section. */
4307
4d6ed7c8
NC
4308#include "unwind-ia64.h"
4309
4310/* An absolute address consists of a section and an offset. If the
4311 section is NULL, the offset itself is the address, otherwise, the
4312 address equals to LOAD_ADDRESS(section) + offset. */
4313
4314struct absaddr
4315 {
4316 unsigned short section;
4317 bfd_vma offset;
4318 };
4319
57346661 4320struct ia64_unw_aux_info
4d6ed7c8 4321 {
57346661 4322 struct ia64_unw_table_entry
4d6ed7c8 4323 {
b34976b6
AM
4324 struct absaddr start;
4325 struct absaddr end;
4326 struct absaddr info;
4d6ed7c8 4327 }
b34976b6
AM
4328 *table; /* Unwind table. */
4329 unsigned long table_len; /* Length of unwind table. */
4330 unsigned char *info; /* Unwind info. */
4331 unsigned long info_size; /* Size of unwind info. */
4332 bfd_vma info_addr; /* starting address of unwind info. */
4333 bfd_vma seg_base; /* Starting address of segment. */
4334 Elf_Internal_Sym *symtab; /* The symbol table. */
4335 unsigned long nsyms; /* Number of symbols. */
4336 char *strtab; /* The string table. */
4337 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
4338 };
4339
4d6ed7c8 4340static void
57346661
AM
4341find_symbol_for_address (Elf_Internal_Sym *symtab,
4342 unsigned long nsyms,
4343 const char *strtab,
4344 unsigned long strtab_size,
d3ba0551
AM
4345 struct absaddr addr,
4346 const char **symname,
4347 bfd_vma *offset)
4d6ed7c8 4348{
d3ba0551 4349 bfd_vma dist = 0x100000;
4d6ed7c8
NC
4350 Elf_Internal_Sym *sym, *best = NULL;
4351 unsigned long i;
4352
57346661 4353 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8
NC
4354 {
4355 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
4356 && sym->st_name != 0
4357 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
4358 && addr.offset >= sym->st_value
4359 && addr.offset - sym->st_value < dist)
4360 {
4361 best = sym;
4362 dist = addr.offset - sym->st_value;
4363 if (!dist)
4364 break;
4365 }
4366 }
4367 if (best)
4368 {
57346661
AM
4369 *symname = (best->st_name >= strtab_size
4370 ? "<corrupt>" : strtab + best->st_name);
4d6ed7c8
NC
4371 *offset = dist;
4372 return;
4373 }
4374 *symname = NULL;
4375 *offset = addr.offset;
4376}
4377
4378static void
57346661 4379dump_ia64_unwind (struct ia64_unw_aux_info *aux)
4d6ed7c8 4380{
57346661 4381 struct ia64_unw_table_entry *tp;
4d6ed7c8 4382 int in_body;
7036c0e1 4383
4d6ed7c8
NC
4384 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
4385 {
4386 bfd_vma stamp;
4387 bfd_vma offset;
b34976b6
AM
4388 const unsigned char *dp;
4389 const unsigned char *head;
4390 const char *procname;
4d6ed7c8 4391
57346661
AM
4392 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
4393 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
4394
4395 fputs ("\n<", stdout);
4396
4397 if (procname)
4398 {
4399 fputs (procname, stdout);
4400
4401 if (offset)
4402 printf ("+%lx", (unsigned long) offset);
4403 }
4404
4405 fputs (">: [", stdout);
4406 print_vma (tp->start.offset, PREFIX_HEX);
4407 fputc ('-', stdout);
4408 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 4409 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
4410 (unsigned long) (tp->info.offset - aux->seg_base));
4411
4412 head = aux->info + (tp->info.offset - aux->info_addr);
4413 stamp = BYTE_GET8 ((unsigned char *) head);
4414
86f55779 4415 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
4416 (unsigned) UNW_VER (stamp),
4417 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
4418 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
4419 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 4420 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
4421
4422 if (UNW_VER (stamp) != 1)
4423 {
4424 printf ("\tUnknown version.\n");
4425 continue;
4426 }
4427
4428 in_body = 0;
89fac5e3 4429 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
4430 dp = unw_decode (dp, in_body, & in_body);
4431 }
4432}
4433
4434static int
d3ba0551 4435slurp_ia64_unwind_table (FILE *file,
57346661 4436 struct ia64_unw_aux_info *aux,
d3ba0551 4437 Elf_Internal_Shdr *sec)
4d6ed7c8 4438{
89fac5e3 4439 unsigned long size, nrelas, i;
d93f0186 4440 Elf_Internal_Phdr *seg;
57346661 4441 struct ia64_unw_table_entry *tep;
c8286bd1 4442 Elf_Internal_Shdr *relsec;
4d6ed7c8
NC
4443 Elf_Internal_Rela *rela, *rp;
4444 unsigned char *table, *tp;
4445 Elf_Internal_Sym *sym;
4446 const char *relname;
4d6ed7c8 4447
4d6ed7c8
NC
4448 /* First, find the starting address of the segment that includes
4449 this section: */
4450
4451 if (elf_header.e_phnum)
4452 {
d93f0186 4453 if (! get_program_headers (file))
4d6ed7c8 4454 return 0;
4d6ed7c8 4455
d93f0186
NC
4456 for (seg = program_headers;
4457 seg < program_headers + elf_header.e_phnum;
4458 ++seg)
4d6ed7c8
NC
4459 {
4460 if (seg->p_type != PT_LOAD)
4461 continue;
4462
4463 if (sec->sh_addr >= seg->p_vaddr
4464 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
4465 {
4466 aux->seg_base = seg->p_vaddr;
4467 break;
4468 }
4469 }
4d6ed7c8
NC
4470 }
4471
4472 /* Second, build the unwind table from the contents of the unwind section: */
4473 size = sec->sh_size;
d3ba0551 4474 table = get_data (NULL, file, sec->sh_offset, size, _("unwind table"));
a6e9f9df
AM
4475 if (!table)
4476 return 0;
4d6ed7c8 4477
89fac5e3
RS
4478 aux->table = xmalloc (size / (3 * eh_addr_size) * sizeof (aux->table[0]));
4479 tep = aux->table;
4480 for (tp = table; tp < table + size; tp += 3 * eh_addr_size, ++tep)
4d6ed7c8
NC
4481 {
4482 tep->start.section = SHN_UNDEF;
4483 tep->end.section = SHN_UNDEF;
4484 tep->info.section = SHN_UNDEF;
4485 if (is_32bit_elf)
4486 {
4487 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
4488 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
4489 tep->info.offset = byte_get ((unsigned char *) tp + 8, 4);
4490 }
4491 else
4492 {
4493 tep->start.offset = BYTE_GET8 ((unsigned char *) tp + 0);
4494 tep->end.offset = BYTE_GET8 ((unsigned char *) tp + 8);
4495 tep->info.offset = BYTE_GET8 ((unsigned char *) tp + 16);
4496 }
4497 tep->start.offset += aux->seg_base;
4498 tep->end.offset += aux->seg_base;
4499 tep->info.offset += aux->seg_base;
4500 }
4501 free (table);
4502
4503 /* Third, apply any relocations to the unwind table: */
4504
4505 for (relsec = section_headers;
4506 relsec < section_headers + elf_header.e_shnum;
4507 ++relsec)
4508 {
4509 if (relsec->sh_type != SHT_RELA
9ad5cbcf 4510 || SECTION_HEADER (relsec->sh_info) != sec)
4d6ed7c8
NC
4511 continue;
4512
4513 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
4514 & rela, & nrelas))
4515 return 0;
4516
4517 for (rp = rela; rp < rela + nrelas; ++rp)
4518 {
4519 if (is_32bit_elf)
4520 {
4521 relname = elf_ia64_reloc_type (ELF32_R_TYPE (rp->r_info));
4522 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
4d6ed7c8
NC
4523 }
4524 else
4525 {
4526 relname = elf_ia64_reloc_type (ELF64_R_TYPE (rp->r_info));
4527 sym = aux->symtab + ELF64_R_SYM (rp->r_info);
4d6ed7c8
NC
4528 }
4529
18bd398b 4530 if (! strneq (relname, "R_IA64_SEGREL", 13))
4d6ed7c8 4531 {
e5fb9629 4532 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
4533 continue;
4534 }
4535
89fac5e3 4536 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 4537
89fac5e3 4538 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
4539 {
4540 case 0:
4541 aux->table[i].start.section = sym->st_shndx;
1ffa9a18 4542 aux->table[i].start.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
4543 break;
4544 case 1:
4545 aux->table[i].end.section = sym->st_shndx;
1ffa9a18 4546 aux->table[i].end.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
4547 break;
4548 case 2:
4549 aux->table[i].info.section = sym->st_shndx;
1ffa9a18 4550 aux->table[i].info.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
4551 break;
4552 default:
4553 break;
4554 }
4555 }
4556
4557 free (rela);
4558 }
4559
89fac5e3 4560 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
4561 return 1;
4562}
4563
4564static int
57346661 4565ia64_process_unwind (FILE *file)
4d6ed7c8 4566{
c8286bd1 4567 Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
89fac5e3 4568 unsigned long i, unwcount = 0, unwstart = 0;
57346661 4569 struct ia64_unw_aux_info aux;
f1467e33 4570
4d6ed7c8
NC
4571 memset (& aux, 0, sizeof (aux));
4572
4d6ed7c8
NC
4573 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
4574 {
4575 if (sec->sh_type == SHT_SYMTAB)
4576 {
4577 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 4578 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 4579
9ad5cbcf 4580 strsec = SECTION_HEADER (sec->sh_link);
4d6ed7c8 4581 aux.strtab_size = strsec->sh_size;
d3ba0551
AM
4582 aux.strtab = get_data (NULL, file, strsec->sh_offset,
4583 aux.strtab_size, _("string table"));
4d6ed7c8
NC
4584 }
4585 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
4586 unwcount++;
4587 }
4588
4589 if (!unwcount)
4590 printf (_("\nThere are no unwind sections in this file.\n"));
4591
4592 while (unwcount-- > 0)
4593 {
4594 char *suffix;
4595 size_t len, len2;
4596
4597 for (i = unwstart, sec = section_headers + unwstart;
4598 i < elf_header.e_shnum; ++i, ++sec)
4599 if (sec->sh_type == SHT_IA_64_UNWIND)
4600 {
4601 unwsec = sec;
4602 break;
4603 }
4604
4605 unwstart = i + 1;
4606 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
4607
e4b17d5c
L
4608 if ((unwsec->sh_flags & SHF_GROUP) != 0)
4609 {
4610 /* We need to find which section group it is in. */
4611 struct group_list *g = section_headers_groups [i]->root;
4612
4613 for (; g != NULL; g = g->next)
4614 {
4615 sec = SECTION_HEADER (g->section_index);
18bd398b
NC
4616
4617 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 4618 break;
e4b17d5c
L
4619 }
4620
4621 if (g == NULL)
4622 i = elf_header.e_shnum;
4623 }
18bd398b 4624 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 4625 {
18bd398b 4626 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
4627 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
4628 suffix = SECTION_NAME (unwsec) + len;
4629 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
4630 ++i, ++sec)
18bd398b
NC
4631 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
4632 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
4633 break;
4634 }
4635 else
4636 {
4637 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 4638 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
4639 len = sizeof (ELF_STRING_ia64_unwind) - 1;
4640 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
4641 suffix = "";
18bd398b 4642 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
4643 suffix = SECTION_NAME (unwsec) + len;
4644 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
4645 ++i, ++sec)
18bd398b
NC
4646 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
4647 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
4648 break;
4649 }
4650
4651 if (i == elf_header.e_shnum)
4652 {
4653 printf (_("\nCould not find unwind info section for "));
4654
4655 if (string_table == NULL)
4656 printf ("%d", unwsec->sh_name);
4657 else
3a1a2036 4658 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
4659 }
4660 else
4d6ed7c8
NC
4661 {
4662 aux.info_size = sec->sh_size;
4663 aux.info_addr = sec->sh_addr;
d3ba0551
AM
4664 aux.info = get_data (NULL, file, sec->sh_offset, aux.info_size,
4665 _("unwind info"));
4d6ed7c8 4666
579f31ac 4667 printf (_("\nUnwind section "));
4d6ed7c8 4668
579f31ac
JJ
4669 if (string_table == NULL)
4670 printf ("%d", unwsec->sh_name);
4671 else
3a1a2036 4672 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 4673
579f31ac 4674 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 4675 (unsigned long) unwsec->sh_offset,
89fac5e3 4676 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 4677
579f31ac 4678 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 4679
579f31ac
JJ
4680 if (aux.table_len > 0)
4681 dump_ia64_unwind (& aux);
4682
4683 if (aux.table)
4684 free ((char *) aux.table);
4685 if (aux.info)
4686 free ((char *) aux.info);
4687 aux.table = NULL;
4688 aux.info = NULL;
4689 }
4d6ed7c8 4690 }
4d6ed7c8 4691
4d6ed7c8
NC
4692 if (aux.symtab)
4693 free (aux.symtab);
4694 if (aux.strtab)
4695 free ((char *) aux.strtab);
4696
4697 return 1;
4698}
4699
57346661
AM
4700struct hppa_unw_aux_info
4701 {
4702 struct hppa_unw_table_entry
4703 {
4704 struct absaddr start;
4705 struct absaddr end;
4706 unsigned int Cannot_unwind:1; /* 0 */
4707 unsigned int Millicode:1; /* 1 */
4708 unsigned int Millicode_save_sr0:1; /* 2 */
4709 unsigned int Region_description:2; /* 3..4 */
4710 unsigned int reserved1:1; /* 5 */
4711 unsigned int Entry_SR:1; /* 6 */
4712 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
4713 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
4714 unsigned int Args_stored:1; /* 16 */
4715 unsigned int Variable_Frame:1; /* 17 */
4716 unsigned int Separate_Package_Body:1; /* 18 */
4717 unsigned int Frame_Extension_Millicode:1; /* 19 */
4718 unsigned int Stack_Overflow_Check:1; /* 20 */
4719 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
4720 unsigned int Ada_Region:1; /* 22 */
4721 unsigned int cxx_info:1; /* 23 */
4722 unsigned int cxx_try_catch:1; /* 24 */
4723 unsigned int sched_entry_seq:1; /* 25 */
4724 unsigned int reserved2:1; /* 26 */
4725 unsigned int Save_SP:1; /* 27 */
4726 unsigned int Save_RP:1; /* 28 */
4727 unsigned int Save_MRP_in_frame:1; /* 29 */
4728 unsigned int extn_ptr_defined:1; /* 30 */
4729 unsigned int Cleanup_defined:1; /* 31 */
4730
4731 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
4732 unsigned int HP_UX_interrupt_marker:1; /* 1 */
4733 unsigned int Large_frame:1; /* 2 */
4734 unsigned int Pseudo_SP_Set:1; /* 3 */
4735 unsigned int reserved4:1; /* 4 */
4736 unsigned int Total_frame_size:27; /* 5..31 */
4737 }
4738 *table; /* Unwind table. */
4739 unsigned long table_len; /* Length of unwind table. */
4740 bfd_vma seg_base; /* Starting address of segment. */
4741 Elf_Internal_Sym *symtab; /* The symbol table. */
4742 unsigned long nsyms; /* Number of symbols. */
4743 char *strtab; /* The string table. */
4744 unsigned long strtab_size; /* Size of string table. */
4745 };
4746
4747static void
4748dump_hppa_unwind (struct hppa_unw_aux_info *aux)
4749{
57346661
AM
4750 struct hppa_unw_table_entry *tp;
4751
57346661
AM
4752 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
4753 {
4754 bfd_vma offset;
4755 const char *procname;
4756
4757 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
4758 aux->strtab_size, tp->start, &procname,
4759 &offset);
4760
4761 fputs ("\n<", stdout);
4762
4763 if (procname)
4764 {
4765 fputs (procname, stdout);
4766
4767 if (offset)
4768 printf ("+%lx", (unsigned long) offset);
4769 }
4770
4771 fputs (">: [", stdout);
4772 print_vma (tp->start.offset, PREFIX_HEX);
4773 fputc ('-', stdout);
4774 print_vma (tp->end.offset, PREFIX_HEX);
4775 printf ("]\n\t");
4776
18bd398b
NC
4777#define PF(_m) if (tp->_m) printf (#_m " ");
4778#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
4779 PF(Cannot_unwind);
4780 PF(Millicode);
4781 PF(Millicode_save_sr0);
18bd398b 4782 /* PV(Region_description); */
57346661
AM
4783 PF(Entry_SR);
4784 PV(Entry_FR);
4785 PV(Entry_GR);
4786 PF(Args_stored);
4787 PF(Variable_Frame);
4788 PF(Separate_Package_Body);
4789 PF(Frame_Extension_Millicode);
4790 PF(Stack_Overflow_Check);
4791 PF(Two_Instruction_SP_Increment);
4792 PF(Ada_Region);
4793 PF(cxx_info);
4794 PF(cxx_try_catch);
4795 PF(sched_entry_seq);
4796 PF(Save_SP);
4797 PF(Save_RP);
4798 PF(Save_MRP_in_frame);
4799 PF(extn_ptr_defined);
4800 PF(Cleanup_defined);
4801 PF(MPE_XL_interrupt_marker);
4802 PF(HP_UX_interrupt_marker);
4803 PF(Large_frame);
4804 PF(Pseudo_SP_Set);
4805 PV(Total_frame_size);
4806#undef PF
4807#undef PV
4808 }
4809
18bd398b 4810 printf ("\n");
57346661
AM
4811}
4812
4813static int
4814slurp_hppa_unwind_table (FILE *file,
4815 struct hppa_unw_aux_info *aux,
4816 Elf_Internal_Shdr *sec)
4817{
89fac5e3 4818 unsigned long size, unw_ent_size, nrelas, i;
57346661
AM
4819 Elf_Internal_Phdr *seg;
4820 struct hppa_unw_table_entry *tep;
4821 Elf_Internal_Shdr *relsec;
4822 Elf_Internal_Rela *rela, *rp;
4823 unsigned char *table, *tp;
4824 Elf_Internal_Sym *sym;
4825 const char *relname;
4826
57346661
AM
4827 /* First, find the starting address of the segment that includes
4828 this section. */
4829
4830 if (elf_header.e_phnum)
4831 {
4832 if (! get_program_headers (file))
4833 return 0;
4834
4835 for (seg = program_headers;
4836 seg < program_headers + elf_header.e_phnum;
4837 ++seg)
4838 {
4839 if (seg->p_type != PT_LOAD)
4840 continue;
4841
4842 if (sec->sh_addr >= seg->p_vaddr
4843 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
4844 {
4845 aux->seg_base = seg->p_vaddr;
4846 break;
4847 }
4848 }
4849 }
4850
4851 /* Second, build the unwind table from the contents of the unwind
4852 section. */
4853 size = sec->sh_size;
4854 table = get_data (NULL, file, sec->sh_offset, size, _("unwind table"));
4855 if (!table)
4856 return 0;
4857
89fac5e3 4858 unw_ent_size = 2 * eh_addr_size + 8;
57346661
AM
4859
4860 tep = aux->table = xmalloc (size / unw_ent_size * sizeof (aux->table[0]));
4861
89fac5e3 4862 for (tp = table; tp < table + size; tp += (2 * eh_addr_size + 8), ++tep)
57346661
AM
4863 {
4864 unsigned int tmp1, tmp2;
4865
4866 tep->start.section = SHN_UNDEF;
4867 tep->end.section = SHN_UNDEF;
4868
4869 if (is_32bit_elf)
4870 {
4871 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
4872 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
4873 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
4874 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
4875 }
4876 else
4877 {
4878 tep->start.offset = BYTE_GET8 ((unsigned char *) tp + 0);
4879 tep->end.offset = BYTE_GET8 ((unsigned char *) tp + 8);
4880 tmp1 = byte_get ((unsigned char *) tp + 16, 4);
4881 tmp2 = byte_get ((unsigned char *) tp + 20, 4);
4882 }
4883
4884 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
4885 tep->Millicode = (tmp1 >> 30) & 0x1;
4886 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
4887 tep->Region_description = (tmp1 >> 27) & 0x3;
4888 tep->reserved1 = (tmp1 >> 26) & 0x1;
4889 tep->Entry_SR = (tmp1 >> 25) & 0x1;
4890 tep->Entry_FR = (tmp1 >> 21) & 0xf;
4891 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
4892 tep->Args_stored = (tmp1 >> 15) & 0x1;
4893 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
4894 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
4895 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
4896 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
4897 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
4898 tep->Ada_Region = (tmp1 >> 9) & 0x1;
4899 tep->cxx_info = (tmp1 >> 8) & 0x1;
4900 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
4901 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
4902 tep->reserved2 = (tmp1 >> 5) & 0x1;
4903 tep->Save_SP = (tmp1 >> 4) & 0x1;
4904 tep->Save_RP = (tmp1 >> 3) & 0x1;
4905 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
4906 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
4907 tep->Cleanup_defined = tmp1 & 0x1;
4908
4909 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
4910 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
4911 tep->Large_frame = (tmp2 >> 29) & 0x1;
4912 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
4913 tep->reserved4 = (tmp2 >> 27) & 0x1;
4914 tep->Total_frame_size = tmp2 & 0x7ffffff;
4915
4916 tep->start.offset += aux->seg_base;
4917 tep->end.offset += aux->seg_base;
4918 }
4919 free (table);
4920
4921 /* Third, apply any relocations to the unwind table. */
4922
4923 for (relsec = section_headers;
4924 relsec < section_headers + elf_header.e_shnum;
4925 ++relsec)
4926 {
4927 if (relsec->sh_type != SHT_RELA
4928 || SECTION_HEADER (relsec->sh_info) != sec)
4929 continue;
4930
4931 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
4932 & rela, & nrelas))
4933 return 0;
4934
4935 for (rp = rela; rp < rela + nrelas; ++rp)
4936 {
4937 if (is_32bit_elf)
4938 {
4939 relname = elf_hppa_reloc_type (ELF32_R_TYPE (rp->r_info));
4940 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
4941 }
4942 else
4943 {
4944 relname = elf_hppa_reloc_type (ELF64_R_TYPE (rp->r_info));
4945 sym = aux->symtab + ELF64_R_SYM (rp->r_info);
4946 }
4947
4948 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
4949 if (strncmp (relname, "R_PARISC_SEGREL", 15) != 0)
4950 {
4951 warn (_("Skipping unexpected relocation type %s\n"), relname);
4952 continue;
4953 }
4954
4955 i = rp->r_offset / unw_ent_size;
4956
89fac5e3 4957 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
4958 {
4959 case 0:
4960 aux->table[i].start.section = sym->st_shndx;
4961 aux->table[i].start.offset += sym->st_value + rp->r_addend;
4962 break;
4963 case 1:
4964 aux->table[i].end.section = sym->st_shndx;
4965 aux->table[i].end.offset += sym->st_value + rp->r_addend;
4966 break;
4967 default:
4968 break;
4969 }
4970 }
4971
4972 free (rela);
4973 }
4974
4975 aux->table_len = size / unw_ent_size;
4976
4977 return 1;
4978}
4979
4980static int
4981hppa_process_unwind (FILE *file)
4982{
57346661 4983 struct hppa_unw_aux_info aux;
18bd398b
NC
4984 Elf_Internal_Shdr *unwsec = NULL;
4985 Elf_Internal_Shdr *strsec;
4986 Elf_Internal_Shdr *sec;
18bd398b 4987 unsigned long i;
57346661
AM
4988
4989 memset (& aux, 0, sizeof (aux));
4990
4991 assert (string_table != NULL);
57346661
AM
4992
4993 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
4994 {
4995 if (sec->sh_type == SHT_SYMTAB)
4996 {
4997 aux.nsyms = sec->sh_size / sec->sh_entsize;
4998 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4999
5000 strsec = SECTION_HEADER (sec->sh_link);
5001 aux.strtab_size = strsec->sh_size;
5002 aux.strtab = get_data (NULL, file, strsec->sh_offset,
5003 aux.strtab_size, _("string table"));
5004 }
18bd398b 5005 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
5006 unwsec = sec;
5007 }
5008
5009 if (!unwsec)
5010 printf (_("\nThere are no unwind sections in this file.\n"));
5011
5012 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5013 {
18bd398b 5014 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 5015 {
57346661
AM
5016 printf (_("\nUnwind section "));
5017 printf (_("'%s'"), SECTION_NAME (sec));
5018
5019 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5020 (unsigned long) sec->sh_offset,
89fac5e3 5021 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
5022
5023 slurp_hppa_unwind_table (file, &aux, sec);
5024 if (aux.table_len > 0)
5025 dump_hppa_unwind (&aux);
5026
5027 if (aux.table)
5028 free ((char *) aux.table);
5029 aux.table = NULL;
5030 }
5031 }
5032
5033 if (aux.symtab)
5034 free (aux.symtab);
5035 if (aux.strtab)
5036 free ((char *) aux.strtab);
5037
5038 return 1;
5039}
5040
5041static int
5042process_unwind (FILE *file)
5043{
5044 struct unwind_handler {
5045 int machtype;
5046 int (*handler)(FILE *file);
5047 } handlers[] = {
5048 { EM_IA_64, ia64_process_unwind },
5049 { EM_PARISC, hppa_process_unwind },
5050 { 0, 0 }
5051 };
5052 int i;
5053
5054 if (!do_unwind)
5055 return 1;
5056
5057 for (i = 0; handlers[i].handler != NULL; i++)
5058 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 5059 return handlers[i].handler (file);
57346661
AM
5060
5061 printf (_("\nThere are no unwind sections in this file.\n"));
5062 return 1;
5063}
5064
252b5132 5065static void
b2d38a17 5066dynamic_section_mips_val (Elf_Internal_Dyn *entry)
252b5132
RH
5067{
5068 switch (entry->d_tag)
5069 {
5070 case DT_MIPS_FLAGS:
5071 if (entry->d_un.d_val == 0)
5072 printf ("NONE\n");
5073 else
5074 {
5075 static const char * opts[] =
5076 {
5077 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
5078 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
5079 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
5080 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
5081 "RLD_ORDER_SAFE"
5082 };
5083 unsigned int cnt;
5084 int first = 1;
b34976b6 5085 for (cnt = 0; cnt < NUM_ELEM (opts); ++cnt)
252b5132
RH
5086 if (entry->d_un.d_val & (1 << cnt))
5087 {
5088 printf ("%s%s", first ? "" : " ", opts[cnt]);
5089 first = 0;
5090 }
5091 puts ("");
5092 }
5093 break;
103f02d3 5094
252b5132 5095 case DT_MIPS_IVERSION:
d79b3d50
NC
5096 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
5097 printf ("Interface Version: %s\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 5098 else
d79b3d50 5099 printf ("<corrupt: %ld>\n", (long) entry->d_un.d_ptr);
252b5132 5100 break;
103f02d3 5101
252b5132
RH
5102 case DT_MIPS_TIME_STAMP:
5103 {
5104 char timebuf[20];
b34976b6 5105 struct tm *tmp;
50da7a9c 5106
252b5132 5107 time_t time = entry->d_un.d_val;
50da7a9c
NC
5108 tmp = gmtime (&time);
5109 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
5110 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
5111 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
5112 printf ("Time Stamp: %s\n", timebuf);
5113 }
5114 break;
103f02d3 5115
252b5132
RH
5116 case DT_MIPS_RLD_VERSION:
5117 case DT_MIPS_LOCAL_GOTNO:
5118 case DT_MIPS_CONFLICTNO:
5119 case DT_MIPS_LIBLISTNO:
5120 case DT_MIPS_SYMTABNO:
5121 case DT_MIPS_UNREFEXTNO:
5122 case DT_MIPS_HIPAGENO:
5123 case DT_MIPS_DELTA_CLASS_NO:
5124 case DT_MIPS_DELTA_INSTANCE_NO:
5125 case DT_MIPS_DELTA_RELOC_NO:
5126 case DT_MIPS_DELTA_SYM_NO:
5127 case DT_MIPS_DELTA_CLASSSYM_NO:
5128 case DT_MIPS_COMPACT_SIZE:
5129 printf ("%ld\n", (long) entry->d_un.d_ptr);
5130 break;
103f02d3
UD
5131
5132 default:
5133 printf ("%#lx\n", (long) entry->d_un.d_ptr);
5134 }
5135}
5136
5137
5138static void
b2d38a17 5139dynamic_section_parisc_val (Elf_Internal_Dyn *entry)
103f02d3
UD
5140{
5141 switch (entry->d_tag)
5142 {
5143 case DT_HP_DLD_FLAGS:
5144 {
5145 static struct
5146 {
5147 long int bit;
b34976b6 5148 const char *str;
5e220199
NC
5149 }
5150 flags[] =
5151 {
5152 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
5153 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
5154 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
5155 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
5156 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
5157 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
5158 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
5159 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
5160 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
5161 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
5162 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" }
5163 };
103f02d3 5164 int first = 1;
5e220199 5165 size_t cnt;
f7a99963 5166 bfd_vma val = entry->d_un.d_val;
103f02d3
UD
5167
5168 for (cnt = 0; cnt < sizeof (flags) / sizeof (flags[0]); ++cnt)
5169 if (val & flags[cnt].bit)
30800947
NC
5170 {
5171 if (! first)
5172 putchar (' ');
5173 fputs (flags[cnt].str, stdout);
5174 first = 0;
5175 val ^= flags[cnt].bit;
5176 }
76da6bbe 5177
103f02d3 5178 if (val != 0 || first)
f7a99963
NC
5179 {
5180 if (! first)
5181 putchar (' ');
5182 print_vma (val, HEX);
5183 }
103f02d3
UD
5184 }
5185 break;
76da6bbe 5186
252b5132 5187 default:
f7a99963
NC
5188 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5189 break;
252b5132 5190 }
35b1837e 5191 putchar ('\n');
252b5132
RH
5192}
5193
ecc51f48 5194static void
b2d38a17 5195dynamic_section_ia64_val (Elf_Internal_Dyn *entry)
ecc51f48
NC
5196{
5197 switch (entry->d_tag)
5198 {
0de14b54 5199 case DT_IA_64_PLT_RESERVE:
bdf4d63a 5200 /* First 3 slots reserved. */
ecc51f48
NC
5201 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5202 printf (" -- ");
5203 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
5204 break;
5205
5206 default:
5207 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5208 break;
ecc51f48 5209 }
bdf4d63a 5210 putchar ('\n');
ecc51f48
NC
5211}
5212
252b5132 5213static int
b2d38a17 5214get_32bit_dynamic_section (FILE *file)
252b5132 5215{
fb514b26 5216 Elf32_External_Dyn *edyn, *ext;
b34976b6 5217 Elf_Internal_Dyn *entry;
103f02d3 5218
d3ba0551 5219 edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
b2d38a17 5220 _("dynamic section"));
a6e9f9df
AM
5221 if (!edyn)
5222 return 0;
103f02d3 5223
ba2685cc
AM
5224/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5225 might not have the luxury of section headers. Look for the DT_NULL
5226 terminator to determine the number of entries. */
5227 for (ext = edyn, dynamic_nent = 0;
5228 (char *) ext < (char *) edyn + dynamic_size;
5229 ext++)
5230 {
5231 dynamic_nent++;
5232 if (BYTE_GET (ext->d_tag) == DT_NULL)
5233 break;
5234 }
252b5132 5235
ba2685cc 5236 dynamic_section = malloc (dynamic_nent * sizeof (*entry));
b2d38a17 5237 if (dynamic_section == NULL)
252b5132 5238 {
9ea033b2
NC
5239 error (_("Out of memory\n"));
5240 free (edyn);
5241 return 0;
5242 }
252b5132 5243
fb514b26 5244 for (ext = edyn, entry = dynamic_section;
ba2685cc 5245 entry < dynamic_section + dynamic_nent;
fb514b26 5246 ext++, entry++)
9ea033b2 5247 {
fb514b26
AM
5248 entry->d_tag = BYTE_GET (ext->d_tag);
5249 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
5250 }
5251
9ea033b2
NC
5252 free (edyn);
5253
5254 return 1;
5255}
5256
5257static int
b2d38a17 5258get_64bit_dynamic_section (FILE *file)
9ea033b2 5259{
fb514b26 5260 Elf64_External_Dyn *edyn, *ext;
b34976b6 5261 Elf_Internal_Dyn *entry;
103f02d3 5262
d3ba0551 5263 edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
b2d38a17 5264 _("dynamic section"));
a6e9f9df
AM
5265 if (!edyn)
5266 return 0;
103f02d3 5267
ba2685cc
AM
5268/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5269 might not have the luxury of section headers. Look for the DT_NULL
5270 terminator to determine the number of entries. */
5271 for (ext = edyn, dynamic_nent = 0;
5272 (char *) ext < (char *) edyn + dynamic_size;
5273 ext++)
5274 {
5275 dynamic_nent++;
5276 if (BYTE_GET8 (ext->d_tag) == DT_NULL)
5277 break;
5278 }
252b5132 5279
ba2685cc 5280 dynamic_section = malloc (dynamic_nent * sizeof (*entry));
b2d38a17 5281 if (dynamic_section == NULL)
252b5132
RH
5282 {
5283 error (_("Out of memory\n"));
5284 free (edyn);
5285 return 0;
5286 }
5287
fb514b26 5288 for (ext = edyn, entry = dynamic_section;
ba2685cc 5289 entry < dynamic_section + dynamic_nent;
fb514b26 5290 ext++, entry++)
252b5132 5291 {
fb514b26
AM
5292 entry->d_tag = BYTE_GET8 (ext->d_tag);
5293 entry->d_un.d_val = BYTE_GET8 (ext->d_un.d_val);
252b5132
RH
5294 }
5295
5296 free (edyn);
5297
9ea033b2
NC
5298 return 1;
5299}
5300
d1133906 5301static const char *
d3ba0551 5302get_dynamic_flags (bfd_vma flags)
d1133906 5303{
b34976b6 5304 static char buff[128];
13ae64f3
JJ
5305 char *p = buff;
5306
5307 *p = '\0';
d1133906
NC
5308 while (flags)
5309 {
5310 bfd_vma flag;
5311
5312 flag = flags & - flags;
5313 flags &= ~ flag;
5314
13ae64f3
JJ
5315 if (p != buff)
5316 *p++ = ' ';
5317
d1133906
NC
5318 switch (flag)
5319 {
b34976b6
AM
5320 case DF_ORIGIN: strcpy (p, "ORIGIN"); break;
5321 case DF_SYMBOLIC: strcpy (p, "SYMBOLIC"); break;
5322 case DF_TEXTREL: strcpy (p, "TEXTREL"); break;
5323 case DF_BIND_NOW: strcpy (p, "BIND_NOW"); break;
5324 case DF_STATIC_TLS: strcpy (p, "STATIC_TLS"); break;
5325 default: strcpy (p, "unknown"); break;
d1133906 5326 }
13ae64f3
JJ
5327
5328 p = strchr (p, '\0');
d1133906 5329 }
305c7206 5330 return buff;
d1133906
NC
5331}
5332
b2d38a17
NC
5333/* Parse and display the contents of the dynamic section. */
5334
9ea033b2 5335static int
b2d38a17 5336process_dynamic_section (FILE *file)
9ea033b2 5337{
b34976b6 5338 Elf_Internal_Dyn *entry;
9ea033b2
NC
5339
5340 if (dynamic_size == 0)
5341 {
5342 if (do_dynamic)
b2d38a17 5343 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
5344
5345 return 1;
5346 }
5347
5348 if (is_32bit_elf)
5349 {
b2d38a17 5350 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
5351 return 0;
5352 }
b2d38a17 5353 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
5354 return 0;
5355
252b5132
RH
5356 /* Find the appropriate symbol table. */
5357 if (dynamic_symbols == NULL)
5358 {
86dba8ee
AM
5359 for (entry = dynamic_section;
5360 entry < dynamic_section + dynamic_nent;
5361 ++entry)
252b5132 5362 {
c8286bd1 5363 Elf_Internal_Shdr section;
252b5132
RH
5364
5365 if (entry->d_tag != DT_SYMTAB)
5366 continue;
5367
5368 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
5369
5370 /* Since we do not know how big the symbol table is,
5371 we default to reading in the entire file (!) and
5372 processing that. This is overkill, I know, but it
e3c8793a 5373 should work. */
d93f0186 5374 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 5375
fb52b2f4
NC
5376 if (archive_file_offset != 0)
5377 section.sh_size = archive_file_size - section.sh_offset;
5378 else
5379 {
5380 if (fseek (file, 0, SEEK_END))
5381 error (_("Unable to seek to end of file!"));
5382
5383 section.sh_size = ftell (file) - section.sh_offset;
5384 }
252b5132 5385
9ea033b2 5386 if (is_32bit_elf)
9ad5cbcf 5387 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 5388 else
9ad5cbcf 5389 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 5390
9ad5cbcf 5391 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 5392 if (num_dynamic_syms < 1)
252b5132
RH
5393 {
5394 error (_("Unable to determine the number of symbols to load\n"));
5395 continue;
5396 }
5397
9ad5cbcf 5398 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
5399 }
5400 }
5401
5402 /* Similarly find a string table. */
5403 if (dynamic_strings == NULL)
5404 {
86dba8ee
AM
5405 for (entry = dynamic_section;
5406 entry < dynamic_section + dynamic_nent;
5407 ++entry)
252b5132
RH
5408 {
5409 unsigned long offset;
b34976b6 5410 long str_tab_len;
252b5132
RH
5411
5412 if (entry->d_tag != DT_STRTAB)
5413 continue;
5414
5415 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
5416
5417 /* Since we do not know how big the string table is,
5418 we default to reading in the entire file (!) and
5419 processing that. This is overkill, I know, but it
e3c8793a 5420 should work. */
252b5132 5421
d93f0186 5422 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
5423
5424 if (archive_file_offset != 0)
5425 str_tab_len = archive_file_size - offset;
5426 else
5427 {
5428 if (fseek (file, 0, SEEK_END))
5429 error (_("Unable to seek to end of file\n"));
5430 str_tab_len = ftell (file) - offset;
5431 }
252b5132
RH
5432
5433 if (str_tab_len < 1)
5434 {
5435 error
5436 (_("Unable to determine the length of the dynamic string table\n"));
5437 continue;
5438 }
5439
d3ba0551
AM
5440 dynamic_strings = get_data (NULL, file, offset, str_tab_len,
5441 _("dynamic string table"));
d79b3d50 5442 dynamic_strings_length = str_tab_len;
252b5132
RH
5443 break;
5444 }
5445 }
5446
5447 /* And find the syminfo section if available. */
5448 if (dynamic_syminfo == NULL)
5449 {
3e8bba36 5450 unsigned long syminsz = 0;
252b5132 5451
86dba8ee
AM
5452 for (entry = dynamic_section;
5453 entry < dynamic_section + dynamic_nent;
5454 ++entry)
252b5132
RH
5455 {
5456 if (entry->d_tag == DT_SYMINENT)
5457 {
5458 /* Note: these braces are necessary to avoid a syntax
5459 error from the SunOS4 C compiler. */
5460 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
5461 }
5462 else if (entry->d_tag == DT_SYMINSZ)
5463 syminsz = entry->d_un.d_val;
5464 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
5465 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
5466 syminsz);
252b5132
RH
5467 }
5468
5469 if (dynamic_syminfo_offset != 0 && syminsz != 0)
5470 {
86dba8ee 5471 Elf_External_Syminfo *extsyminfo, *extsym;
b34976b6 5472 Elf_Internal_Syminfo *syminfo;
252b5132
RH
5473
5474 /* There is a syminfo section. Read the data. */
d3ba0551
AM
5475 extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, syminsz,
5476 _("symbol information"));
a6e9f9df
AM
5477 if (!extsyminfo)
5478 return 0;
252b5132 5479
d3ba0551 5480 dynamic_syminfo = malloc (syminsz);
252b5132
RH
5481 if (dynamic_syminfo == NULL)
5482 {
5483 error (_("Out of memory\n"));
5484 return 0;
5485 }
5486
5487 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
5488 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
5489 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
5490 ++syminfo, ++extsym)
252b5132 5491 {
86dba8ee
AM
5492 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
5493 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
5494 }
5495
5496 free (extsyminfo);
5497 }
5498 }
5499
5500 if (do_dynamic && dynamic_addr)
86dba8ee
AM
5501 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
5502 dynamic_addr, dynamic_nent);
252b5132
RH
5503 if (do_dynamic)
5504 printf (_(" Tag Type Name/Value\n"));
5505
86dba8ee
AM
5506 for (entry = dynamic_section;
5507 entry < dynamic_section + dynamic_nent;
5508 entry++)
252b5132
RH
5509 {
5510 if (do_dynamic)
f7a99963 5511 {
b34976b6 5512 const char *dtype;
e699b9ff 5513
f7a99963
NC
5514 putchar (' ');
5515 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
5516 dtype = get_dynamic_type (entry->d_tag);
5517 printf (" (%s)%*s", dtype,
5518 ((is_32bit_elf ? 27 : 19)
5519 - (int) strlen (dtype)),
f7a99963
NC
5520 " ");
5521 }
252b5132
RH
5522
5523 switch (entry->d_tag)
5524 {
d1133906
NC
5525 case DT_FLAGS:
5526 if (do_dynamic)
13ae64f3 5527 puts (get_dynamic_flags (entry->d_un.d_val));
d1133906 5528 break;
76da6bbe 5529
252b5132
RH
5530 case DT_AUXILIARY:
5531 case DT_FILTER:
019148e4
L
5532 case DT_CONFIG:
5533 case DT_DEPAUDIT:
5534 case DT_AUDIT:
252b5132
RH
5535 if (do_dynamic)
5536 {
019148e4 5537 switch (entry->d_tag)
b34976b6 5538 {
019148e4
L
5539 case DT_AUXILIARY:
5540 printf (_("Auxiliary library"));
5541 break;
5542
5543 case DT_FILTER:
5544 printf (_("Filter library"));
5545 break;
5546
b34976b6 5547 case DT_CONFIG:
019148e4
L
5548 printf (_("Configuration file"));
5549 break;
5550
5551 case DT_DEPAUDIT:
5552 printf (_("Dependency audit library"));
5553 break;
5554
5555 case DT_AUDIT:
5556 printf (_("Audit library"));
5557 break;
5558 }
252b5132 5559
d79b3d50
NC
5560 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
5561 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 5562 else
f7a99963
NC
5563 {
5564 printf (": ");
5565 print_vma (entry->d_un.d_val, PREFIX_HEX);
5566 putchar ('\n');
5567 }
252b5132
RH
5568 }
5569 break;
5570
dcefbbbd 5571 case DT_FEATURE:
252b5132
RH
5572 if (do_dynamic)
5573 {
5574 printf (_("Flags:"));
86f55779 5575
252b5132
RH
5576 if (entry->d_un.d_val == 0)
5577 printf (_(" None\n"));
5578 else
5579 {
5580 unsigned long int val = entry->d_un.d_val;
86f55779 5581
252b5132
RH
5582 if (val & DTF_1_PARINIT)
5583 {
5584 printf (" PARINIT");
5585 val ^= DTF_1_PARINIT;
5586 }
dcefbbbd
L
5587 if (val & DTF_1_CONFEXP)
5588 {
5589 printf (" CONFEXP");
5590 val ^= DTF_1_CONFEXP;
5591 }
252b5132
RH
5592 if (val != 0)
5593 printf (" %lx", val);
5594 puts ("");
5595 }
5596 }
5597 break;
5598
5599 case DT_POSFLAG_1:
5600 if (do_dynamic)
5601 {
5602 printf (_("Flags:"));
86f55779 5603
252b5132
RH
5604 if (entry->d_un.d_val == 0)
5605 printf (_(" None\n"));
5606 else
5607 {
5608 unsigned long int val = entry->d_un.d_val;
86f55779 5609
252b5132
RH
5610 if (val & DF_P1_LAZYLOAD)
5611 {
5612 printf (" LAZYLOAD");
5613 val ^= DF_P1_LAZYLOAD;
5614 }
5615 if (val & DF_P1_GROUPPERM)
5616 {
5617 printf (" GROUPPERM");
5618 val ^= DF_P1_GROUPPERM;
5619 }
5620 if (val != 0)
5621 printf (" %lx", val);
5622 puts ("");
5623 }
5624 }
5625 break;
5626
5627 case DT_FLAGS_1:
5628 if (do_dynamic)
5629 {
5630 printf (_("Flags:"));
5631 if (entry->d_un.d_val == 0)
5632 printf (_(" None\n"));
5633 else
5634 {
5635 unsigned long int val = entry->d_un.d_val;
86f55779 5636
252b5132
RH
5637 if (val & DF_1_NOW)
5638 {
5639 printf (" NOW");
5640 val ^= DF_1_NOW;
5641 }
5642 if (val & DF_1_GLOBAL)
5643 {
5644 printf (" GLOBAL");
5645 val ^= DF_1_GLOBAL;
5646 }
5647 if (val & DF_1_GROUP)
5648 {
5649 printf (" GROUP");
5650 val ^= DF_1_GROUP;
5651 }
5652 if (val & DF_1_NODELETE)
5653 {
5654 printf (" NODELETE");
5655 val ^= DF_1_NODELETE;
5656 }
5657 if (val & DF_1_LOADFLTR)
5658 {
5659 printf (" LOADFLTR");
5660 val ^= DF_1_LOADFLTR;
5661 }
5662 if (val & DF_1_INITFIRST)
5663 {
5664 printf (" INITFIRST");
5665 val ^= DF_1_INITFIRST;
5666 }
5667 if (val & DF_1_NOOPEN)
5668 {
5669 printf (" NOOPEN");
5670 val ^= DF_1_NOOPEN;
5671 }
5672 if (val & DF_1_ORIGIN)
5673 {
5674 printf (" ORIGIN");
5675 val ^= DF_1_ORIGIN;
5676 }
5677 if (val & DF_1_DIRECT)
5678 {
5679 printf (" DIRECT");
5680 val ^= DF_1_DIRECT;
5681 }
5682 if (val & DF_1_TRANS)
5683 {
5684 printf (" TRANS");
5685 val ^= DF_1_TRANS;
5686 }
5687 if (val & DF_1_INTERPOSE)
5688 {
5689 printf (" INTERPOSE");
5690 val ^= DF_1_INTERPOSE;
5691 }
f7db6139 5692 if (val & DF_1_NODEFLIB)
dcefbbbd 5693 {
f7db6139
L
5694 printf (" NODEFLIB");
5695 val ^= DF_1_NODEFLIB;
dcefbbbd
L
5696 }
5697 if (val & DF_1_NODUMP)
5698 {
5699 printf (" NODUMP");
5700 val ^= DF_1_NODUMP;
5701 }
5702 if (val & DF_1_CONLFAT)
5703 {
5704 printf (" CONLFAT");
5705 val ^= DF_1_CONLFAT;
5706 }
252b5132
RH
5707 if (val != 0)
5708 printf (" %lx", val);
5709 puts ("");
5710 }
5711 }
5712 break;
5713
5714 case DT_PLTREL:
566b0d53 5715 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
5716 if (do_dynamic)
5717 puts (get_dynamic_type (entry->d_un.d_val));
5718 break;
5719
5720 case DT_NULL :
5721 case DT_NEEDED :
5722 case DT_PLTGOT :
5723 case DT_HASH :
5724 case DT_STRTAB :
5725 case DT_SYMTAB :
5726 case DT_RELA :
5727 case DT_INIT :
5728 case DT_FINI :
5729 case DT_SONAME :
5730 case DT_RPATH :
5731 case DT_SYMBOLIC:
5732 case DT_REL :
5733 case DT_DEBUG :
5734 case DT_TEXTREL :
5735 case DT_JMPREL :
019148e4 5736 case DT_RUNPATH :
252b5132
RH
5737 dynamic_info[entry->d_tag] = entry->d_un.d_val;
5738
5739 if (do_dynamic)
5740 {
b34976b6 5741 char *name;
252b5132 5742
d79b3d50
NC
5743 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
5744 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 5745 else
d79b3d50 5746 name = NULL;
252b5132
RH
5747
5748 if (name)
5749 {
5750 switch (entry->d_tag)
5751 {
5752 case DT_NEEDED:
5753 printf (_("Shared library: [%s]"), name);
5754
18bd398b 5755 if (streq (name, program_interpreter))
f7a99963 5756 printf (_(" program interpreter"));
252b5132
RH
5757 break;
5758
5759 case DT_SONAME:
f7a99963 5760 printf (_("Library soname: [%s]"), name);
252b5132
RH
5761 break;
5762
5763 case DT_RPATH:
f7a99963 5764 printf (_("Library rpath: [%s]"), name);
252b5132
RH
5765 break;
5766
019148e4
L
5767 case DT_RUNPATH:
5768 printf (_("Library runpath: [%s]"), name);
5769 break;
5770
252b5132 5771 default:
f7a99963
NC
5772 print_vma (entry->d_un.d_val, PREFIX_HEX);
5773 break;
252b5132
RH
5774 }
5775 }
5776 else
f7a99963
NC
5777 print_vma (entry->d_un.d_val, PREFIX_HEX);
5778
5779 putchar ('\n');
252b5132
RH
5780 }
5781 break;
5782
5783 case DT_PLTRELSZ:
5784 case DT_RELASZ :
5785 case DT_STRSZ :
5786 case DT_RELSZ :
5787 case DT_RELAENT :
5788 case DT_SYMENT :
5789 case DT_RELENT :
566b0d53 5790 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
5791 case DT_PLTPADSZ:
5792 case DT_MOVEENT :
5793 case DT_MOVESZ :
5794 case DT_INIT_ARRAYSZ:
5795 case DT_FINI_ARRAYSZ:
047b2264
JJ
5796 case DT_GNU_CONFLICTSZ:
5797 case DT_GNU_LIBLISTSZ:
252b5132 5798 if (do_dynamic)
f7a99963
NC
5799 {
5800 print_vma (entry->d_un.d_val, UNSIGNED);
5801 printf (" (bytes)\n");
5802 }
252b5132
RH
5803 break;
5804
5805 case DT_VERDEFNUM:
5806 case DT_VERNEEDNUM:
5807 case DT_RELACOUNT:
5808 case DT_RELCOUNT:
5809 if (do_dynamic)
f7a99963
NC
5810 {
5811 print_vma (entry->d_un.d_val, UNSIGNED);
5812 putchar ('\n');
5813 }
252b5132
RH
5814 break;
5815
5816 case DT_SYMINSZ:
5817 case DT_SYMINENT:
5818 case DT_SYMINFO:
5819 case DT_USED:
5820 case DT_INIT_ARRAY:
5821 case DT_FINI_ARRAY:
5822 if (do_dynamic)
5823 {
d79b3d50
NC
5824 if (entry->d_tag == DT_USED
5825 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 5826 {
d79b3d50 5827 char *name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 5828
b34976b6 5829 if (*name)
252b5132
RH
5830 {
5831 printf (_("Not needed object: [%s]\n"), name);
5832 break;
5833 }
5834 }
103f02d3 5835
f7a99963
NC
5836 print_vma (entry->d_un.d_val, PREFIX_HEX);
5837 putchar ('\n');
252b5132
RH
5838 }
5839 break;
5840
5841 case DT_BIND_NOW:
5842 /* The value of this entry is ignored. */
35b1837e
AM
5843 if (do_dynamic)
5844 putchar ('\n');
252b5132 5845 break;
103f02d3 5846
047b2264
JJ
5847 case DT_GNU_PRELINKED:
5848 if (do_dynamic)
5849 {
b34976b6 5850 struct tm *tmp;
047b2264
JJ
5851 time_t time = entry->d_un.d_val;
5852
5853 tmp = gmtime (&time);
5854 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
5855 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
5856 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
5857
5858 }
5859 break;
5860
252b5132
RH
5861 default:
5862 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 5863 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
5864 entry->d_un.d_val;
5865
5866 if (do_dynamic)
5867 {
5868 switch (elf_header.e_machine)
5869 {
5870 case EM_MIPS:
4fe85591 5871 case EM_MIPS_RS3_LE:
b2d38a17 5872 dynamic_section_mips_val (entry);
252b5132 5873 break;
103f02d3 5874 case EM_PARISC:
b2d38a17 5875 dynamic_section_parisc_val (entry);
103f02d3 5876 break;
ecc51f48 5877 case EM_IA_64:
b2d38a17 5878 dynamic_section_ia64_val (entry);
ecc51f48 5879 break;
252b5132 5880 default:
f7a99963
NC
5881 print_vma (entry->d_un.d_val, PREFIX_HEX);
5882 putchar ('\n');
252b5132
RH
5883 }
5884 }
5885 break;
5886 }
5887 }
5888
5889 return 1;
5890}
5891
5892static char *
d3ba0551 5893get_ver_flags (unsigned int flags)
252b5132 5894{
b34976b6 5895 static char buff[32];
252b5132
RH
5896
5897 buff[0] = 0;
5898
5899 if (flags == 0)
5900 return _("none");
5901
5902 if (flags & VER_FLG_BASE)
5903 strcat (buff, "BASE ");
5904
5905 if (flags & VER_FLG_WEAK)
5906 {
5907 if (flags & VER_FLG_BASE)
5908 strcat (buff, "| ");
5909
5910 strcat (buff, "WEAK ");
5911 }
5912
5913 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
5914 strcat (buff, "| <unknown>");
5915
5916 return buff;
5917}
5918
5919/* Display the contents of the version sections. */
5920static int
d3ba0551 5921process_version_sections (FILE *file)
252b5132 5922{
b34976b6
AM
5923 Elf_Internal_Shdr *section;
5924 unsigned i;
5925 int found = 0;
252b5132
RH
5926
5927 if (! do_version)
5928 return 1;
5929
5930 for (i = 0, section = section_headers;
5931 i < elf_header.e_shnum;
b34976b6 5932 i++, section++)
252b5132
RH
5933 {
5934 switch (section->sh_type)
5935 {
5936 case SHT_GNU_verdef:
5937 {
b34976b6
AM
5938 Elf_External_Verdef *edefs;
5939 unsigned int idx;
5940 unsigned int cnt;
252b5132
RH
5941
5942 found = 1;
5943
5944 printf
5945 (_("\nVersion definition section '%s' contains %ld entries:\n"),
5946 SECTION_NAME (section), section->sh_info);
5947
5948 printf (_(" Addr: 0x"));
5949 printf_vma (section->sh_addr);
5950 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 5951 (unsigned long) section->sh_offset, section->sh_link,
9ad5cbcf 5952 SECTION_NAME (SECTION_HEADER (section->sh_link)));
252b5132 5953
d3ba0551
AM
5954 edefs = get_data (NULL, file, section->sh_offset, section->sh_size,
5955 _("version definition section"));
a6e9f9df
AM
5956 if (!edefs)
5957 break;
252b5132 5958
b34976b6 5959 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 5960 {
b34976b6
AM
5961 char *vstart;
5962 Elf_External_Verdef *edef;
5963 Elf_Internal_Verdef ent;
5964 Elf_External_Verdaux *eaux;
5965 Elf_Internal_Verdaux aux;
5966 int j;
5967 int isum;
103f02d3 5968
252b5132
RH
5969 vstart = ((char *) edefs) + idx;
5970
5971 edef = (Elf_External_Verdef *) vstart;
5972
5973 ent.vd_version = BYTE_GET (edef->vd_version);
5974 ent.vd_flags = BYTE_GET (edef->vd_flags);
5975 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
5976 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
5977 ent.vd_hash = BYTE_GET (edef->vd_hash);
5978 ent.vd_aux = BYTE_GET (edef->vd_aux);
5979 ent.vd_next = BYTE_GET (edef->vd_next);
5980
5981 printf (_(" %#06x: Rev: %d Flags: %s"),
5982 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
5983
5984 printf (_(" Index: %d Cnt: %d "),
5985 ent.vd_ndx, ent.vd_cnt);
5986
5987 vstart += ent.vd_aux;
5988
5989 eaux = (Elf_External_Verdaux *) vstart;
5990
5991 aux.vda_name = BYTE_GET (eaux->vda_name);
5992 aux.vda_next = BYTE_GET (eaux->vda_next);
5993
d79b3d50
NC
5994 if (VALID_DYNAMIC_NAME (aux.vda_name))
5995 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
5996 else
5997 printf (_("Name index: %ld\n"), aux.vda_name);
5998
5999 isum = idx + ent.vd_aux;
6000
b34976b6 6001 for (j = 1; j < ent.vd_cnt; j++)
252b5132
RH
6002 {
6003 isum += aux.vda_next;
6004 vstart += aux.vda_next;
6005
6006 eaux = (Elf_External_Verdaux *) vstart;
6007
6008 aux.vda_name = BYTE_GET (eaux->vda_name);
6009 aux.vda_next = BYTE_GET (eaux->vda_next);
6010
d79b3d50 6011 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 6012 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 6013 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
6014 else
6015 printf (_(" %#06x: Parent %d, name index: %ld\n"),
6016 isum, j, aux.vda_name);
6017 }
6018
6019 idx += ent.vd_next;
6020 }
6021
6022 free (edefs);
6023 }
6024 break;
103f02d3 6025
252b5132
RH
6026 case SHT_GNU_verneed:
6027 {
b34976b6
AM
6028 Elf_External_Verneed *eneed;
6029 unsigned int idx;
6030 unsigned int cnt;
252b5132
RH
6031
6032 found = 1;
6033
6034 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
6035 SECTION_NAME (section), section->sh_info);
6036
6037 printf (_(" Addr: 0x"));
6038 printf_vma (section->sh_addr);
6039 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
1b228002 6040 (unsigned long) section->sh_offset, section->sh_link,
9ad5cbcf 6041 SECTION_NAME (SECTION_HEADER (section->sh_link)));
252b5132 6042
d3ba0551
AM
6043 eneed = get_data (NULL, file, section->sh_offset, section->sh_size,
6044 _("version need section"));
a6e9f9df
AM
6045 if (!eneed)
6046 break;
252b5132
RH
6047
6048 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
6049 {
b34976b6
AM
6050 Elf_External_Verneed *entry;
6051 Elf_Internal_Verneed ent;
6052 int j;
6053 int isum;
6054 char *vstart;
252b5132
RH
6055
6056 vstart = ((char *) eneed) + idx;
6057
6058 entry = (Elf_External_Verneed *) vstart;
6059
6060 ent.vn_version = BYTE_GET (entry->vn_version);
6061 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
6062 ent.vn_file = BYTE_GET (entry->vn_file);
6063 ent.vn_aux = BYTE_GET (entry->vn_aux);
6064 ent.vn_next = BYTE_GET (entry->vn_next);
6065
6066 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
6067
d79b3d50
NC
6068 if (VALID_DYNAMIC_NAME (ent.vn_file))
6069 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
6070 else
6071 printf (_(" File: %lx"), ent.vn_file);
6072
6073 printf (_(" Cnt: %d\n"), ent.vn_cnt);
6074
6075 vstart += ent.vn_aux;
6076
6077 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
6078 {
b34976b6
AM
6079 Elf_External_Vernaux *eaux;
6080 Elf_Internal_Vernaux aux;
252b5132
RH
6081
6082 eaux = (Elf_External_Vernaux *) vstart;
6083
6084 aux.vna_hash = BYTE_GET (eaux->vna_hash);
6085 aux.vna_flags = BYTE_GET (eaux->vna_flags);
6086 aux.vna_other = BYTE_GET (eaux->vna_other);
6087 aux.vna_name = BYTE_GET (eaux->vna_name);
6088 aux.vna_next = BYTE_GET (eaux->vna_next);
6089
d79b3d50 6090 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 6091 printf (_(" %#06x: Name: %s"),
d79b3d50 6092 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 6093 else
ecc2063b 6094 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
6095 isum, aux.vna_name);
6096
6097 printf (_(" Flags: %s Version: %d\n"),
6098 get_ver_flags (aux.vna_flags), aux.vna_other);
6099
6100 isum += aux.vna_next;
6101 vstart += aux.vna_next;
6102 }
6103
6104 idx += ent.vn_next;
6105 }
103f02d3 6106
252b5132
RH
6107 free (eneed);
6108 }
6109 break;
6110
6111 case SHT_GNU_versym:
6112 {
b34976b6
AM
6113 Elf_Internal_Shdr *link_section;
6114 int total;
6115 int cnt;
6116 unsigned char *edata;
6117 unsigned short *data;
6118 char *strtab;
6119 Elf_Internal_Sym *symbols;
6120 Elf_Internal_Shdr *string_sec;
d3ba0551 6121 long off;
252b5132 6122
9ad5cbcf 6123 link_section = SECTION_HEADER (section->sh_link);
252b5132
RH
6124 total = section->sh_size / section->sh_entsize;
6125
6126 found = 1;
6127
9ad5cbcf 6128 symbols = GET_ELF_SYMBOLS (file, link_section);
252b5132 6129
9ad5cbcf 6130 string_sec = SECTION_HEADER (link_section->sh_link);
252b5132 6131
d3ba0551
AM
6132 strtab = get_data (NULL, file, string_sec->sh_offset,
6133 string_sec->sh_size, _("version string table"));
a6e9f9df
AM
6134 if (!strtab)
6135 break;
252b5132
RH
6136
6137 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
6138 SECTION_NAME (section), total);
6139
6140 printf (_(" Addr: "));
6141 printf_vma (section->sh_addr);
6142 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 6143 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
6144 SECTION_NAME (link_section));
6145
d3ba0551
AM
6146 off = offset_from_vma (file,
6147 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
6148 total * sizeof (short));
6149 edata = get_data (NULL, file, off, total * sizeof (short),
6150 _("version symbol data"));
a6e9f9df
AM
6151 if (!edata)
6152 {
6153 free (strtab);
6154 break;
6155 }
252b5132 6156
d3ba0551 6157 data = malloc (total * sizeof (short));
252b5132
RH
6158
6159 for (cnt = total; cnt --;)
b34976b6
AM
6160 data[cnt] = byte_get (edata + cnt * sizeof (short),
6161 sizeof (short));
252b5132
RH
6162
6163 free (edata);
6164
6165 for (cnt = 0; cnt < total; cnt += 4)
6166 {
6167 int j, nn;
00d93f34 6168 int check_def, check_need;
b34976b6 6169 char *name;
252b5132
RH
6170
6171 printf (" %03x:", cnt);
6172
6173 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 6174 switch (data[cnt + j])
252b5132
RH
6175 {
6176 case 0:
6177 fputs (_(" 0 (*local*) "), stdout);
6178 break;
6179
6180 case 1:
6181 fputs (_(" 1 (*global*) "), stdout);
6182 break;
6183
6184 default:
b34976b6
AM
6185 nn = printf ("%4x%c", data[cnt + j] & 0x7fff,
6186 data[cnt + j] & 0x8000 ? 'h' : ' ');
252b5132 6187
00d93f34
JJ
6188 check_def = 1;
6189 check_need = 1;
b34976b6 6190 if (SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
00d93f34 6191 != SHT_NOBITS)
252b5132 6192 {
b34976b6 6193 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
6194 check_def = 0;
6195 else
6196 check_need = 0;
252b5132 6197 }
00d93f34
JJ
6198
6199 if (check_need
b34976b6 6200 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 6201 {
b34976b6
AM
6202 Elf_Internal_Verneed ivn;
6203 unsigned long offset;
252b5132 6204
d93f0186
NC
6205 offset = offset_from_vma
6206 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
6207 sizeof (Elf_External_Verneed));
252b5132 6208
b34976b6 6209 do
252b5132 6210 {
b34976b6
AM
6211 Elf_Internal_Vernaux ivna;
6212 Elf_External_Verneed evn;
6213 Elf_External_Vernaux evna;
6214 unsigned long a_off;
252b5132 6215
a6e9f9df
AM
6216 get_data (&evn, file, offset, sizeof (evn),
6217 _("version need"));
252b5132
RH
6218
6219 ivn.vn_aux = BYTE_GET (evn.vn_aux);
6220 ivn.vn_next = BYTE_GET (evn.vn_next);
6221
6222 a_off = offset + ivn.vn_aux;
6223
6224 do
6225 {
a6e9f9df
AM
6226 get_data (&evna, file, a_off, sizeof (evna),
6227 _("version need aux (2)"));
252b5132
RH
6228
6229 ivna.vna_next = BYTE_GET (evna.vna_next);
6230 ivna.vna_other = BYTE_GET (evna.vna_other);
6231
6232 a_off += ivna.vna_next;
6233 }
b34976b6 6234 while (ivna.vna_other != data[cnt + j]
252b5132
RH
6235 && ivna.vna_next != 0);
6236
b34976b6 6237 if (ivna.vna_other == data[cnt + j])
252b5132
RH
6238 {
6239 ivna.vna_name = BYTE_GET (evna.vna_name);
6240
16062207 6241 name = strtab + ivna.vna_name;
252b5132 6242 nn += printf ("(%s%-*s",
16062207
ILT
6243 name,
6244 12 - (int) strlen (name),
252b5132 6245 ")");
00d93f34 6246 check_def = 0;
252b5132
RH
6247 break;
6248 }
6249
6250 offset += ivn.vn_next;
6251 }
6252 while (ivn.vn_next);
6253 }
00d93f34 6254
b34976b6
AM
6255 if (check_def && data[cnt + j] != 0x8001
6256 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 6257 {
b34976b6
AM
6258 Elf_Internal_Verdef ivd;
6259 Elf_External_Verdef evd;
6260 unsigned long offset;
252b5132 6261
d93f0186
NC
6262 offset = offset_from_vma
6263 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
6264 sizeof evd);
252b5132
RH
6265
6266 do
6267 {
a6e9f9df
AM
6268 get_data (&evd, file, offset, sizeof (evd),
6269 _("version def"));
252b5132
RH
6270
6271 ivd.vd_next = BYTE_GET (evd.vd_next);
6272 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
6273
6274 offset += ivd.vd_next;
6275 }
b34976b6 6276 while (ivd.vd_ndx != (data[cnt + j] & 0x7fff)
252b5132
RH
6277 && ivd.vd_next != 0);
6278
b34976b6 6279 if (ivd.vd_ndx == (data[cnt + j] & 0x7fff))
252b5132 6280 {
b34976b6
AM
6281 Elf_External_Verdaux evda;
6282 Elf_Internal_Verdaux ivda;
252b5132
RH
6283
6284 ivd.vd_aux = BYTE_GET (evd.vd_aux);
6285
a6e9f9df
AM
6286 get_data (&evda, file,
6287 offset - ivd.vd_next + ivd.vd_aux,
6288 sizeof (evda), _("version def aux"));
252b5132
RH
6289
6290 ivda.vda_name = BYTE_GET (evda.vda_name);
6291
16062207 6292 name = strtab + ivda.vda_name;
252b5132 6293 nn += printf ("(%s%-*s",
16062207
ILT
6294 name,
6295 12 - (int) strlen (name),
252b5132
RH
6296 ")");
6297 }
6298 }
6299
6300 if (nn < 18)
6301 printf ("%*c", 18 - nn, ' ');
6302 }
6303
6304 putchar ('\n');
6305 }
6306
6307 free (data);
6308 free (strtab);
6309 free (symbols);
6310 }
6311 break;
103f02d3 6312
252b5132
RH
6313 default:
6314 break;
6315 }
6316 }
6317
6318 if (! found)
6319 printf (_("\nNo version information found in this file.\n"));
6320
6321 return 1;
6322}
6323
d1133906 6324static const char *
d3ba0551 6325get_symbol_binding (unsigned int binding)
252b5132 6326{
b34976b6 6327 static char buff[32];
252b5132
RH
6328
6329 switch (binding)
6330 {
b34976b6
AM
6331 case STB_LOCAL: return "LOCAL";
6332 case STB_GLOBAL: return "GLOBAL";
6333 case STB_WEAK: return "WEAK";
252b5132
RH
6334 default:
6335 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
6336 sprintf (buff, _("<processor specific>: %d"), binding);
6337 else if (binding >= STB_LOOS && binding <= STB_HIOS)
6338 sprintf (buff, _("<OS specific>: %d"), binding);
6339 else
6340 sprintf (buff, _("<unknown>: %d"), binding);
6341 return buff;
6342 }
6343}
6344
d1133906 6345static const char *
d3ba0551 6346get_symbol_type (unsigned int type)
252b5132 6347{
b34976b6 6348 static char buff[32];
252b5132
RH
6349
6350 switch (type)
6351 {
b34976b6
AM
6352 case STT_NOTYPE: return "NOTYPE";
6353 case STT_OBJECT: return "OBJECT";
6354 case STT_FUNC: return "FUNC";
6355 case STT_SECTION: return "SECTION";
6356 case STT_FILE: return "FILE";
6357 case STT_COMMON: return "COMMON";
6358 case STT_TLS: return "TLS";
252b5132
RH
6359 default:
6360 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
6361 {
6362 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
6363 return "THUMB_FUNC";
6364
351b4b40 6365 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
6366 return "REGISTER";
6367
6368 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
6369 return "PARISC_MILLI";
6370
df75f1af
NC
6371 sprintf (buff, _("<processor specific>: %d"), type);
6372 }
252b5132 6373 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
6374 {
6375 if (elf_header.e_machine == EM_PARISC)
6376 {
6377 if (type == STT_HP_OPAQUE)
6378 return "HP_OPAQUE";
6379 if (type == STT_HP_STUB)
6380 return "HP_STUB";
6381 }
6382
6383 sprintf (buff, _("<OS specific>: %d"), type);
6384 }
252b5132
RH
6385 else
6386 sprintf (buff, _("<unknown>: %d"), type);
6387 return buff;
6388 }
6389}
6390
d1133906 6391static const char *
d3ba0551 6392get_symbol_visibility (unsigned int visibility)
d1133906
NC
6393{
6394 switch (visibility)
6395 {
b34976b6
AM
6396 case STV_DEFAULT: return "DEFAULT";
6397 case STV_INTERNAL: return "INTERNAL";
6398 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
6399 case STV_PROTECTED: return "PROTECTED";
6400 default: abort ();
6401 }
6402}
6403
6404static const char *
d3ba0551 6405get_symbol_index_type (unsigned int type)
252b5132 6406{
b34976b6 6407 static char buff[32];
5cf1065c 6408
252b5132
RH
6409 switch (type)
6410 {
b34976b6
AM
6411 case SHN_UNDEF: return "UND";
6412 case SHN_ABS: return "ABS";
6413 case SHN_COMMON: return "COM";
252b5132 6414 default:
9ce701e2
L
6415 if (type == SHN_IA_64_ANSI_COMMON
6416 && elf_header.e_machine == EM_IA_64
6417 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
6418 return "ANSI_COM";
6419 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
5cf1065c 6420 sprintf (buff, "PRC[0x%04x]", type);
252b5132 6421 else if (type >= SHN_LOOS && type <= SHN_HIOS)
5cf1065c 6422 sprintf (buff, "OS [0x%04x]", type);
9ad5cbcf 6423 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
5cf1065c 6424 sprintf (buff, "RSV[0x%04x]", type);
252b5132 6425 else
232e7cb8 6426 sprintf (buff, "%3d", type);
5cf1065c 6427 break;
252b5132 6428 }
5cf1065c
NC
6429
6430 return buff;
252b5132
RH
6431}
6432
252b5132 6433static int *
d3ba0551 6434get_dynamic_data (FILE *file, unsigned int number)
252b5132 6435{
b34976b6
AM
6436 unsigned char *e_data;
6437 int *i_data;
252b5132 6438
d3ba0551 6439 e_data = malloc (number * 4);
252b5132
RH
6440
6441 if (e_data == NULL)
6442 {
6443 error (_("Out of memory\n"));
6444 return NULL;
6445 }
6446
6447 if (fread (e_data, 4, number, file) != number)
6448 {
6449 error (_("Unable to read in dynamic data\n"));
6450 return NULL;
6451 }
6452
d3ba0551 6453 i_data = malloc (number * sizeof (*i_data));
252b5132
RH
6454
6455 if (i_data == NULL)
6456 {
6457 error (_("Out of memory\n"));
6458 free (e_data);
6459 return NULL;
6460 }
6461
6462 while (number--)
b34976b6 6463 i_data[number] = byte_get (e_data + number * 4, 4);
252b5132
RH
6464
6465 free (e_data);
6466
6467 return i_data;
6468}
6469
e3c8793a 6470/* Dump the symbol table. */
252b5132 6471static int
d3ba0551 6472process_symbol_table (FILE *file)
252b5132 6473{
b34976b6
AM
6474 Elf_Internal_Shdr *section;
6475 unsigned char nb[4];
6476 unsigned char nc[4];
6477 int nbuckets = 0;
6478 int nchains = 0;
6479 int *buckets = NULL;
6480 int *chains = NULL;
252b5132
RH
6481
6482 if (! do_syms && !do_histogram)
6483 return 1;
6484
6485 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
6486 || do_histogram))
6487 {
fb52b2f4
NC
6488 if (fseek (file,
6489 (archive_file_offset
6490 + offset_from_vma (file, dynamic_info[DT_HASH],
6491 sizeof nb + sizeof nc)),
d93f0186 6492 SEEK_SET))
252b5132
RH
6493 {
6494 error (_("Unable to seek to start of dynamic information"));
6495 return 0;
6496 }
6497
6498 if (fread (nb, sizeof (nb), 1, file) != 1)
6499 {
6500 error (_("Failed to read in number of buckets\n"));
6501 return 0;
6502 }
6503
6504 if (fread (nc, sizeof (nc), 1, file) != 1)
6505 {
6506 error (_("Failed to read in number of chains\n"));
6507 return 0;
6508 }
6509
6510 nbuckets = byte_get (nb, 4);
6511 nchains = byte_get (nc, 4);
6512
6513 buckets = get_dynamic_data (file, nbuckets);
6514 chains = get_dynamic_data (file, nchains);
6515
6516 if (buckets == NULL || chains == NULL)
6517 return 0;
6518 }
6519
6520 if (do_syms
6521 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
6522 {
b34976b6
AM
6523 int hn;
6524 int si;
252b5132
RH
6525
6526 printf (_("\nSymbol table for image:\n"));
f7a99963 6527 if (is_32bit_elf)
ca47b30c 6528 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 6529 else
ca47b30c 6530 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
252b5132
RH
6531
6532 for (hn = 0; hn < nbuckets; hn++)
6533 {
b34976b6 6534 if (! buckets[hn])
252b5132
RH
6535 continue;
6536
b34976b6 6537 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
252b5132 6538 {
b34976b6 6539 Elf_Internal_Sym *psym;
252b5132
RH
6540
6541 psym = dynamic_symbols + si;
6542
f7a99963
NC
6543 printf (" %3d %3d: ", si, hn);
6544 print_vma (psym->st_value, LONG_HEX);
6545 putchar (' ' );
d1133906 6546 print_vma (psym->st_size, DEC_5);
76da6bbe 6547
d1133906
NC
6548 printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
6549 printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
6550 printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126 6551 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
d79b3d50
NC
6552 if (VALID_DYNAMIC_NAME (psym->st_name))
6553 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
6554 else
6555 printf (" <corrupt: %14ld>", psym->st_name);
31104126 6556 putchar ('\n');
252b5132
RH
6557 }
6558 }
6559 }
6560 else if (do_syms && !do_using_dynamic)
6561 {
b34976b6 6562 unsigned int i;
252b5132
RH
6563
6564 for (i = 0, section = section_headers;
6565 i < elf_header.e_shnum;
6566 i++, section++)
6567 {
b34976b6
AM
6568 unsigned int si;
6569 char *strtab;
6570 Elf_Internal_Sym *symtab;
6571 Elf_Internal_Sym *psym;
252b5132
RH
6572
6573
6574 if ( section->sh_type != SHT_SYMTAB
6575 && section->sh_type != SHT_DYNSYM)
6576 continue;
6577
6578 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
6579 SECTION_NAME (section),
6580 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 6581 if (is_32bit_elf)
ca47b30c 6582 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 6583 else
ca47b30c 6584 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 6585
9ad5cbcf 6586 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
6587 if (symtab == NULL)
6588 continue;
6589
6590 if (section->sh_link == elf_header.e_shstrndx)
6591 strtab = string_table;
6592 else
6593 {
b34976b6 6594 Elf_Internal_Shdr *string_sec;
252b5132 6595
9ad5cbcf 6596 string_sec = SECTION_HEADER (section->sh_link);
252b5132 6597
d3ba0551
AM
6598 strtab = get_data (NULL, file, string_sec->sh_offset,
6599 string_sec->sh_size, _("string table"));
252b5132
RH
6600 }
6601
6602 for (si = 0, psym = symtab;
6603 si < section->sh_size / section->sh_entsize;
b34976b6 6604 si++, psym++)
252b5132 6605 {
5e220199 6606 printf ("%6d: ", si);
f7a99963
NC
6607 print_vma (psym->st_value, LONG_HEX);
6608 putchar (' ');
6609 print_vma (psym->st_size, DEC_5);
d1133906
NC
6610 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
6611 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
6612 printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126
NC
6613 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
6614 print_symbol (25, strtab + psym->st_name);
252b5132
RH
6615
6616 if (section->sh_type == SHT_DYNSYM &&
b34976b6 6617 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 6618 {
b34976b6
AM
6619 unsigned char data[2];
6620 unsigned short vers_data;
6621 unsigned long offset;
6622 int is_nobits;
6623 int check_def;
252b5132 6624
d93f0186
NC
6625 offset = offset_from_vma
6626 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
6627 sizeof data + si * sizeof (vers_data));
252b5132 6628
a6e9f9df
AM
6629 get_data (&data, file, offset + si * sizeof (vers_data),
6630 sizeof (data), _("version data"));
252b5132
RH
6631
6632 vers_data = byte_get (data, 2);
6633
9ad5cbcf
AM
6634 is_nobits = (SECTION_HEADER (psym->st_shndx)->sh_type
6635 == SHT_NOBITS);
252b5132
RH
6636
6637 check_def = (psym->st_shndx != SHN_UNDEF);
6638
6639 if ((vers_data & 0x8000) || vers_data > 1)
6640 {
b34976b6 6641 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 6642 && (is_nobits || ! check_def))
252b5132 6643 {
b34976b6
AM
6644 Elf_External_Verneed evn;
6645 Elf_Internal_Verneed ivn;
6646 Elf_Internal_Vernaux ivna;
252b5132
RH
6647
6648 /* We must test both. */
d93f0186
NC
6649 offset = offset_from_vma
6650 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
6651 sizeof evn);
252b5132 6652
252b5132
RH
6653 do
6654 {
b34976b6 6655 unsigned long vna_off;
252b5132 6656
a6e9f9df
AM
6657 get_data (&evn, file, offset, sizeof (evn),
6658 _("version need"));
dd27201e
L
6659
6660 ivn.vn_aux = BYTE_GET (evn.vn_aux);
6661 ivn.vn_next = BYTE_GET (evn.vn_next);
6662
252b5132
RH
6663 vna_off = offset + ivn.vn_aux;
6664
6665 do
6666 {
b34976b6 6667 Elf_External_Vernaux evna;
252b5132 6668
a6e9f9df
AM
6669 get_data (&evna, file, vna_off,
6670 sizeof (evna),
6671 _("version need aux (3)"));
252b5132
RH
6672
6673 ivna.vna_other = BYTE_GET (evna.vna_other);
6674 ivna.vna_next = BYTE_GET (evna.vna_next);
6675 ivna.vna_name = BYTE_GET (evna.vna_name);
6676
6677 vna_off += ivna.vna_next;
6678 }
6679 while (ivna.vna_other != vers_data
6680 && ivna.vna_next != 0);
6681
6682 if (ivna.vna_other == vers_data)
6683 break;
6684
6685 offset += ivn.vn_next;
6686 }
6687 while (ivn.vn_next != 0);
6688
6689 if (ivna.vna_other == vers_data)
6690 {
6691 printf ("@%s (%d)",
6692 strtab + ivna.vna_name, ivna.vna_other);
6693 check_def = 0;
6694 }
6695 else if (! is_nobits)
6696 error (_("bad dynamic symbol"));
6697 else
6698 check_def = 1;
6699 }
6700
6701 if (check_def)
6702 {
00d93f34 6703 if (vers_data != 0x8001
b34976b6 6704 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 6705 {
b34976b6
AM
6706 Elf_Internal_Verdef ivd;
6707 Elf_Internal_Verdaux ivda;
6708 Elf_External_Verdaux evda;
6709 unsigned long offset;
252b5132 6710
d93f0186
NC
6711 offset = offset_from_vma
6712 (file,
6713 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
6714 sizeof (Elf_External_Verdef));
252b5132
RH
6715
6716 do
6717 {
b34976b6 6718 Elf_External_Verdef evd;
252b5132 6719
a6e9f9df
AM
6720 get_data (&evd, file, offset, sizeof (evd),
6721 _("version def"));
252b5132 6722
b34976b6
AM
6723 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
6724 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
6725 ivd.vd_next = BYTE_GET (evd.vd_next);
6726
6727 offset += ivd.vd_next;
6728 }
6729 while (ivd.vd_ndx != (vers_data & 0x7fff)
6730 && ivd.vd_next != 0);
6731
6732 offset -= ivd.vd_next;
6733 offset += ivd.vd_aux;
6734
a6e9f9df
AM
6735 get_data (&evda, file, offset, sizeof (evda),
6736 _("version def aux"));
252b5132
RH
6737
6738 ivda.vda_name = BYTE_GET (evda.vda_name);
6739
6740 if (psym->st_name != ivda.vda_name)
6741 printf ((vers_data & 0x8000)
6742 ? "@%s" : "@@%s",
6743 strtab + ivda.vda_name);
6744 }
6745 }
6746 }
6747 }
6748
6749 putchar ('\n');
6750 }
6751
6752 free (symtab);
6753 if (strtab != string_table)
6754 free (strtab);
6755 }
6756 }
6757 else if (do_syms)
6758 printf
6759 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
6760
6761 if (do_histogram && buckets != NULL)
6762 {
b34976b6
AM
6763 int *lengths;
6764 int *counts;
6765 int hn;
6766 int si;
6767 int maxlength = 0;
6768 int nzero_counts = 0;
6769 int nsyms = 0;
252b5132
RH
6770
6771 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
6772 nbuckets);
6773 printf (_(" Length Number %% of total Coverage\n"));
6774
d3ba0551 6775 lengths = calloc (nbuckets, sizeof (int));
252b5132
RH
6776 if (lengths == NULL)
6777 {
6778 error (_("Out of memory"));
6779 return 0;
6780 }
6781 for (hn = 0; hn < nbuckets; ++hn)
6782 {
b34976b6 6783 if (! buckets[hn])
252b5132
RH
6784 continue;
6785
f7a99963 6786 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 6787 {
b34976b6 6788 ++nsyms;
252b5132 6789 if (maxlength < ++lengths[hn])
b34976b6 6790 ++maxlength;
252b5132
RH
6791 }
6792 }
6793
d3ba0551 6794 counts = calloc (maxlength + 1, sizeof (int));
252b5132
RH
6795 if (counts == NULL)
6796 {
6797 error (_("Out of memory"));
6798 return 0;
6799 }
6800
6801 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 6802 ++counts[lengths[hn]];
252b5132 6803
103f02d3 6804 if (nbuckets > 0)
252b5132 6805 {
103f02d3
UD
6806 printf (" 0 %-10d (%5.1f%%)\n",
6807 counts[0], (counts[0] * 100.0) / nbuckets);
6808 for (si = 1; si <= maxlength; ++si)
6809 {
6810 nzero_counts += counts[si] * si;
6811 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
6812 si, counts[si], (counts[si] * 100.0) / nbuckets,
6813 (nzero_counts * 100.0) / nsyms);
6814 }
252b5132
RH
6815 }
6816
6817 free (counts);
6818 free (lengths);
6819 }
6820
6821 if (buckets != NULL)
6822 {
6823 free (buckets);
6824 free (chains);
6825 }
6826
6827 return 1;
6828}
6829
6830static int
d3ba0551 6831process_syminfo (FILE *file ATTRIBUTE_UNUSED)
252b5132 6832{
b4c96d0d 6833 unsigned int i;
252b5132
RH
6834
6835 if (dynamic_syminfo == NULL
6836 || !do_dynamic)
6837 /* No syminfo, this is ok. */
6838 return 1;
6839
6840 /* There better should be a dynamic symbol section. */
6841 if (dynamic_symbols == NULL || dynamic_strings == NULL)
6842 return 0;
6843
6844 if (dynamic_addr)
6845 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
6846 dynamic_syminfo_offset, dynamic_syminfo_nent);
6847
6848 printf (_(" Num: Name BoundTo Flags\n"));
6849 for (i = 0; i < dynamic_syminfo_nent; ++i)
6850 {
6851 unsigned short int flags = dynamic_syminfo[i].si_flags;
6852
31104126 6853 printf ("%4d: ", i);
d79b3d50
NC
6854 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
6855 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
6856 else
6857 printf ("<corrupt: %19ld>", dynamic_symbols[i].st_name);
31104126 6858 putchar (' ');
252b5132
RH
6859
6860 switch (dynamic_syminfo[i].si_boundto)
6861 {
6862 case SYMINFO_BT_SELF:
6863 fputs ("SELF ", stdout);
6864 break;
6865 case SYMINFO_BT_PARENT:
6866 fputs ("PARENT ", stdout);
6867 break;
6868 default:
6869 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
6870 && dynamic_syminfo[i].si_boundto < dynamic_nent
6871 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 6872 {
d79b3d50 6873 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
6874 putchar (' ' );
6875 }
252b5132
RH
6876 else
6877 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
6878 break;
6879 }
6880
6881 if (flags & SYMINFO_FLG_DIRECT)
6882 printf (" DIRECT");
6883 if (flags & SYMINFO_FLG_PASSTHRU)
6884 printf (" PASSTHRU");
6885 if (flags & SYMINFO_FLG_COPY)
6886 printf (" COPY");
6887 if (flags & SYMINFO_FLG_LAZYLOAD)
6888 printf (" LAZYLOAD");
6889
6890 puts ("");
6891 }
6892
6893 return 1;
6894}
6895
6896#ifdef SUPPORT_DISASSEMBLY
18bd398b 6897static int
d3ba0551 6898disassemble_section (Elf_Internal_Shdr *section, FILE *file)
252b5132
RH
6899{
6900 printf (_("\nAssembly dump of section %s\n"),
6901 SECTION_NAME (section));
6902
6903 /* XXX -- to be done --- XXX */
6904
6905 return 1;
6906}
6907#endif
6908
6909static int
d3ba0551 6910dump_section (Elf_Internal_Shdr *section, FILE *file)
252b5132 6911{
b34976b6
AM
6912 bfd_size_type bytes;
6913 bfd_vma addr;
6914 unsigned char *data;
6915 unsigned char *start;
252b5132
RH
6916
6917 bytes = section->sh_size;
6918
e69f2d21 6919 if (bytes == 0 || section->sh_type == SHT_NOBITS)
252b5132
RH
6920 {
6921 printf (_("\nSection '%s' has no data to dump.\n"),
6922 SECTION_NAME (section));
6923 return 0;
6924 }
6925 else
6926 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
6927
6928 addr = section->sh_addr;
6929
d3ba0551 6930 start = get_data (NULL, file, section->sh_offset, bytes, _("section data"));
a6e9f9df
AM
6931 if (!start)
6932 return 0;
252b5132
RH
6933
6934 data = start;
6935
6936 while (bytes)
6937 {
6938 int j;
6939 int k;
6940 int lbytes;
6941
6942 lbytes = (bytes > 16 ? 16 : bytes);
6943
148d3c43 6944 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132 6945
b34976b6 6946 switch (elf_header.e_ident[EI_DATA])
252b5132 6947 {
9ea033b2 6948 default:
252b5132
RH
6949 case ELFDATA2LSB:
6950 for (j = 15; j >= 0; j --)
6951 {
6952 if (j < lbytes)
b34976b6 6953 printf ("%2.2x", data[j]);
252b5132
RH
6954 else
6955 printf (" ");
6956
6957 if (!(j & 0x3))
6958 printf (" ");
6959 }
6960 break;
6961
6962 case ELFDATA2MSB:
6963 for (j = 0; j < 16; j++)
6964 {
6965 if (j < lbytes)
b34976b6 6966 printf ("%2.2x", data[j]);
252b5132
RH
6967 else
6968 printf (" ");
6969
6970 if ((j & 3) == 3)
6971 printf (" ");
6972 }
6973 break;
6974 }
6975
6976 for (j = 0; j < lbytes; j++)
6977 {
b34976b6 6978 k = data[j];
9376f0c7 6979 if (k >= ' ' && k < 0x7f)
252b5132
RH
6980 printf ("%c", k);
6981 else
6982 printf (".");
6983 }
6984
6985 putchar ('\n');
6986
6987 data += lbytes;
6988 addr += lbytes;
6989 bytes -= lbytes;
6990 }
6991
6992 free (start);
6993
6994 return 1;
6995}
6996
6997
6998static unsigned long int
d3ba0551 6999read_leb128 (unsigned char *data, int *length_return, int sign)
252b5132
RH
7000{
7001 unsigned long int result = 0;
b34976b6 7002 unsigned int num_read = 0;
0c548fce 7003 unsigned int shift = 0;
b34976b6 7004 unsigned char byte;
252b5132
RH
7005
7006 do
7007 {
b34976b6
AM
7008 byte = *data++;
7009 num_read++;
252b5132 7010
0c548fce 7011 result |= ((unsigned long int) (byte & 0x7f)) << shift;
252b5132
RH
7012
7013 shift += 7;
7014
7015 }
7016 while (byte & 0x80);
7017
7018 if (length_return != NULL)
b34976b6 7019 *length_return = num_read;
252b5132 7020
0c548fce
L
7021 if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
7022 result |= -1L << shift;
252b5132
RH
7023
7024 return result;
7025}
7026
7027typedef struct State_Machine_Registers
7028{
b34976b6
AM
7029 unsigned long address;
7030 unsigned int file;
7031 unsigned int line;
7032 unsigned int column;
7033 int is_stmt;
7034 int basic_block;
7035 int end_sequence;
252b5132
RH
7036/* This variable hold the number of the last entry seen
7037 in the File Table. */
b34976b6 7038 unsigned int last_file_entry;
252b5132
RH
7039} SMR;
7040
7041static SMR state_machine_regs;
7042
7043static void
d3ba0551 7044reset_state_machine (int is_stmt)
252b5132
RH
7045{
7046 state_machine_regs.address = 0;
7047 state_machine_regs.file = 1;
7048 state_machine_regs.line = 1;
7049 state_machine_regs.column = 0;
7050 state_machine_regs.is_stmt = is_stmt;
7051 state_machine_regs.basic_block = 0;
7052 state_machine_regs.end_sequence = 0;
7053 state_machine_regs.last_file_entry = 0;
7054}
7055
7056/* Handled an extend line op. Returns true if this is the end
7057 of sequence. */
18bd398b 7058
252b5132 7059static int
d3ba0551 7060process_extended_line_op (unsigned char *data, int is_stmt, int pointer_size)
252b5132 7061{
b34976b6
AM
7062 unsigned char op_code;
7063 int bytes_read;
7064 unsigned int len;
7065 unsigned char *name;
7066 unsigned long adr;
103f02d3 7067
252b5132
RH
7068 len = read_leb128 (data, & bytes_read, 0);
7069 data += bytes_read;
7070
7071 if (len == 0)
7072 {
e5fb9629 7073 warn (_("badly formed extended line op encountered!\n"));
252b5132
RH
7074 return bytes_read;
7075 }
7076
7077 len += bytes_read;
b34976b6 7078 op_code = *data++;
252b5132
RH
7079
7080 printf (_(" Extended opcode %d: "), op_code);
103f02d3 7081
252b5132
RH
7082 switch (op_code)
7083 {
7084 case DW_LNE_end_sequence:
7085 printf (_("End of Sequence\n\n"));
7086 reset_state_machine (is_stmt);
7087 break;
7088
7089 case DW_LNE_set_address:
3590ea00 7090 adr = byte_get (data, pointer_size);
252b5132
RH
7091 printf (_("set Address to 0x%lx\n"), adr);
7092 state_machine_regs.address = adr;
7093 break;
7094
7095 case DW_LNE_define_file:
7096 printf (_(" define new File Table entry\n"));
7097 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
103f02d3 7098
b34976b6 7099 printf (_(" %d\t"), ++state_machine_regs.last_file_entry);
252b5132 7100 name = data;
3c9f43b1 7101 data += strlen ((char *) data) + 1;
252b5132
RH
7102 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
7103 data += bytes_read;
7104 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
7105 data += bytes_read;
7106 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
7107 printf (_("%s\n\n"), name);
7108 break;
7109
7110 default:
7111 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
7112 break;
7113 }
7114
7115 return len;
7116}
7117
5b18a4bc
NC
7118static const char *debug_str_contents;
7119static bfd_vma debug_str_size;
7120
7121static void
7122load_debug_str (FILE *file)
18bd398b 7123{
5b18a4bc 7124 Elf_Internal_Shdr *sec;
18bd398b 7125
5b18a4bc
NC
7126 /* If it is already loaded, do nothing. */
7127 if (debug_str_contents != NULL)
7128 return;
18bd398b 7129
5b18a4bc
NC
7130 /* Locate the .debug_str section. */
7131 sec = find_section (".debug_str");
7132 if (sec == NULL)
7133 return;
7134
7135 debug_str_size = sec->sh_size;
7136
7137 debug_str_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
7138 _("debug_str section data"));
7139}
7140
7141static void
7142free_debug_str (void)
18bd398b 7143{
5b18a4bc
NC
7144 if (debug_str_contents == NULL)
7145 return;
76a56260 7146
5b18a4bc
NC
7147 free ((char *) debug_str_contents);
7148 debug_str_contents = NULL;
7149 debug_str_size = 0;
7150}
76a56260 7151
5b18a4bc
NC
7152static const char *
7153fetch_indirect_string (unsigned long offset)
7154{
7155 if (debug_str_contents == NULL)
7156 return _("<no .debug_str section>");
7157
7158 if (offset > debug_str_size)
7159 return _("<offset is too big>");
18bd398b 7160
5b18a4bc 7161 return debug_str_contents + offset;
18bd398b 7162}
252b5132 7163
5b18a4bc
NC
7164static const char *debug_loc_contents;
7165static bfd_vma debug_loc_size;
d9296b18 7166
5b18a4bc
NC
7167static void
7168load_debug_loc (FILE *file)
d9296b18 7169{
5b18a4bc 7170 Elf_Internal_Shdr *sec;
76a56260 7171
5b18a4bc
NC
7172 /* If it is already loaded, do nothing. */
7173 if (debug_loc_contents != NULL)
7174 return;
18bd398b 7175
5b18a4bc
NC
7176 /* Locate the .debug_loc section. */
7177 sec = find_section (".debug_loc");
7178 if (sec == NULL)
7179 return;
d9296b18 7180
5b18a4bc 7181 debug_loc_size = sec->sh_size;
d9296b18 7182
5b18a4bc
NC
7183 debug_loc_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
7184 _("debug_loc section data"));
7185}
d9296b18 7186
5b18a4bc
NC
7187static void
7188free_debug_loc (void)
7189{
7190 if (debug_loc_contents == NULL)
7191 return;
d9296b18 7192
5b18a4bc
NC
7193 free ((char *) debug_loc_contents);
7194 debug_loc_contents = NULL;
7195 debug_loc_size = 0;
7196}
d9296b18 7197
5b18a4bc
NC
7198static const char * debug_range_contents;
7199static unsigned long debug_range_size;
d9296b18 7200
5b18a4bc
NC
7201static void
7202load_debug_range (FILE *file)
7203{
7204 Elf_Internal_Shdr *sec;
d9296b18 7205
5b18a4bc
NC
7206 /* If it is already loaded, do nothing. */
7207 if (debug_range_contents != NULL)
7208 return;
d9296b18 7209
5b18a4bc
NC
7210 /* Locate the .debug_str section. */
7211 sec = find_section (".debug_ranges");
7212 if (sec == NULL)
7213 return;
0de14b54 7214
5b18a4bc 7215 debug_range_size = sec->sh_size;
d9296b18 7216
5b18a4bc
NC
7217 debug_range_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
7218 _("debug_range section data"));
7219}
d9296b18 7220
5b18a4bc
NC
7221static void
7222free_debug_range (void)
7223{
7224 if (debug_range_contents == NULL)
7225 return;
18bd398b 7226
5b18a4bc
NC
7227 free ((char *) debug_range_contents);
7228 debug_range_contents = NULL;
7229 debug_range_size = 0;
d9296b18
NC
7230}
7231
5b18a4bc
NC
7232/* Apply addends of RELA relocations. */
7233
252b5132 7234static int
5b18a4bc
NC
7235debug_apply_rela_addends (FILE *file,
7236 Elf_Internal_Shdr *section,
7237 int reloc_size,
7238 unsigned char *sec_data,
7239 unsigned char *start,
7240 unsigned char *end)
252b5132 7241{
5b18a4bc 7242 Elf_Internal_Shdr *relsec;
252b5132 7243
5b18a4bc
NC
7244 if (end - start < reloc_size)
7245 return 1;
d9296b18 7246
5b18a4bc
NC
7247 for (relsec = section_headers;
7248 relsec < section_headers + elf_header.e_shnum;
7249 ++relsec)
252b5132 7250 {
5b18a4bc
NC
7251 unsigned long nrelas;
7252 Elf_Internal_Rela *rela, *rp;
7253 Elf_Internal_Shdr *symsec;
7254 Elf_Internal_Sym *symtab;
7255 Elf_Internal_Sym *sym;
252b5132 7256
5b18a4bc
NC
7257 if (relsec->sh_type != SHT_RELA
7258 || SECTION_HEADER (relsec->sh_info) != section
7259 || relsec->sh_size == 0)
7260 continue;
428409d5 7261
5b18a4bc
NC
7262 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7263 &rela, &nrelas))
7264 return 0;
428409d5 7265
5b18a4bc
NC
7266 symsec = SECTION_HEADER (relsec->sh_link);
7267 symtab = GET_ELF_SYMBOLS (file, symsec);
103f02d3 7268
5b18a4bc 7269 for (rp = rela; rp < rela + nrelas; ++rp)
252b5132 7270 {
5b18a4bc 7271 unsigned char *loc;
103f02d3 7272
5b18a4bc
NC
7273 if (rp->r_offset >= (bfd_vma) (start - sec_data)
7274 && rp->r_offset < (bfd_vma) (end - sec_data) - reloc_size)
7275 loc = sec_data + rp->r_offset;
7276 else
7277 continue;
103f02d3 7278
5b18a4bc
NC
7279 if (is_32bit_elf)
7280 {
7281 sym = symtab + ELF32_R_SYM (rp->r_info);
103f02d3 7282
5b18a4bc
NC
7283 if (ELF32_R_SYM (rp->r_info) != 0
7284 && ELF32_ST_TYPE (sym->st_info) != STT_SECTION
7285 /* Relocations against object symbols can happen,
7286 eg when referencing a global array. For an
7287 example of this see the _clz.o binary in libgcc.a. */
7288 && ELF32_ST_TYPE (sym->st_info) != STT_OBJECT)
7289 {
7290 warn (_("%s: skipping unexpected symbol type %s in relocation in section .rela%s\n"),
7291 get_symbol_type (ELF32_ST_TYPE (sym->st_info)),
7292 SECTION_NAME (section));
7293 continue;
7294 }
7295 }
7296 else
7297 {
7298 sym = symtab + ELF64_R_SYM (rp->r_info);
0e0c4098 7299
5b18a4bc
NC
7300 if (ELF64_R_SYM (rp->r_info) != 0
7301 && ELF64_ST_TYPE (sym->st_info) != STT_SECTION
7302 && ELF64_ST_TYPE (sym->st_info) != STT_OBJECT)
7303 {
7304 warn (_("skipping unexpected symbol type %s in relocation in section .rela.%s\n"),
7305 get_symbol_type (ELF64_ST_TYPE (sym->st_info)),
7306 SECTION_NAME (section));
7307 continue;
7308 }
7309 }
252b5132 7310
5b18a4bc
NC
7311 byte_put (loc, rp->r_addend, reloc_size);
7312 }
252b5132 7313
5b18a4bc
NC
7314 free (symtab);
7315 free (rela);
7316 break;
7317 }
7318 return 1;
7319}
103f02d3 7320
5b18a4bc
NC
7321/* FIXME: There are better and more efficient ways to handle
7322 these structures. For now though, I just want something that
7323 is simple to implement. */
7324typedef struct abbrev_attr
7325{
7326 unsigned long attribute;
7327 unsigned long form;
7328 struct abbrev_attr *next;
7329}
7330abbrev_attr;
103f02d3 7331
5b18a4bc
NC
7332typedef struct abbrev_entry
7333{
7334 unsigned long entry;
7335 unsigned long tag;
7336 int children;
7337 struct abbrev_attr *first_attr;
7338 struct abbrev_attr *last_attr;
7339 struct abbrev_entry *next;
7340}
7341abbrev_entry;
103f02d3 7342
5b18a4bc
NC
7343static abbrev_entry *first_abbrev = NULL;
7344static abbrev_entry *last_abbrev = NULL;
103f02d3 7345
5b18a4bc
NC
7346static void
7347free_abbrevs (void)
7348{
7349 abbrev_entry *abbrev;
103f02d3 7350
5b18a4bc
NC
7351 for (abbrev = first_abbrev; abbrev;)
7352 {
7353 abbrev_entry *next = abbrev->next;
7354 abbrev_attr *attr;
103f02d3 7355
5b18a4bc
NC
7356 for (attr = abbrev->first_attr; attr;)
7357 {
7358 abbrev_attr *next = attr->next;
103f02d3 7359
5b18a4bc
NC
7360 free (attr);
7361 attr = next;
252b5132 7362 }
103f02d3 7363
5b18a4bc
NC
7364 free (abbrev);
7365 abbrev = next;
7366 }
103f02d3 7367
5b18a4bc
NC
7368 last_abbrev = first_abbrev = NULL;
7369}
103f02d3 7370
5b18a4bc
NC
7371static void
7372add_abbrev (unsigned long number, unsigned long tag, int children)
7373{
7374 abbrev_entry *entry;
103f02d3 7375
5b18a4bc 7376 entry = malloc (sizeof (*entry));
103f02d3 7377
5b18a4bc
NC
7378 if (entry == NULL)
7379 /* ugg */
7380 return;
103f02d3 7381
5b18a4bc
NC
7382 entry->entry = number;
7383 entry->tag = tag;
7384 entry->children = children;
7385 entry->first_attr = NULL;
7386 entry->last_attr = NULL;
7387 entry->next = NULL;
103f02d3 7388
5b18a4bc
NC
7389 if (first_abbrev == NULL)
7390 first_abbrev = entry;
7391 else
7392 last_abbrev->next = entry;
103f02d3 7393
5b18a4bc
NC
7394 last_abbrev = entry;
7395}
103f02d3 7396
5b18a4bc
NC
7397static void
7398add_abbrev_attr (unsigned long attribute, unsigned long form)
7399{
7400 abbrev_attr *attr;
103f02d3 7401
5b18a4bc 7402 attr = malloc (sizeof (*attr));
103f02d3 7403
5b18a4bc
NC
7404 if (attr == NULL)
7405 /* ugg */
7406 return;
103f02d3 7407
5b18a4bc
NC
7408 attr->attribute = attribute;
7409 attr->form = form;
7410 attr->next = NULL;
103f02d3 7411
5b18a4bc
NC
7412 if (last_abbrev->first_attr == NULL)
7413 last_abbrev->first_attr = attr;
7414 else
7415 last_abbrev->last_attr->next = attr;
103f02d3 7416
5b18a4bc
NC
7417 last_abbrev->last_attr = attr;
7418}
103f02d3 7419
5b18a4bc
NC
7420/* Processes the (partial) contents of a .debug_abbrev section.
7421 Returns NULL if the end of the section was encountered.
7422 Returns the address after the last byte read if the end of
7423 an abbreviation set was found. */
103f02d3 7424
5b18a4bc
NC
7425static unsigned char *
7426process_abbrev_section (unsigned char *start, unsigned char *end)
7427{
7428 if (first_abbrev != NULL)
7429 return NULL;
103f02d3 7430
5b18a4bc
NC
7431 while (start < end)
7432 {
7433 int bytes_read;
7434 unsigned long entry;
7435 unsigned long tag;
7436 unsigned long attribute;
7437 int children;
103f02d3 7438
5b18a4bc
NC
7439 entry = read_leb128 (start, & bytes_read, 0);
7440 start += bytes_read;
103f02d3 7441
5b18a4bc
NC
7442 /* A single zero is supposed to end the section according
7443 to the standard. If there's more, then signal that to
7444 the caller. */
7445 if (entry == 0)
7446 return start == end ? NULL : start;
252b5132 7447
5b18a4bc
NC
7448 tag = read_leb128 (start, & bytes_read, 0);
7449 start += bytes_read;
428409d5 7450
5b18a4bc 7451 children = *start++;
ee42cf8c 7452
5b18a4bc 7453 add_abbrev (entry, tag, children);
ee42cf8c 7454
5b18a4bc 7455 do
252b5132 7456 {
5b18a4bc 7457 unsigned long form;
252b5132 7458
5b18a4bc
NC
7459 attribute = read_leb128 (start, & bytes_read, 0);
7460 start += bytes_read;
252b5132 7461
5b18a4bc
NC
7462 form = read_leb128 (start, & bytes_read, 0);
7463 start += bytes_read;
252b5132 7464
5b18a4bc
NC
7465 if (attribute != 0)
7466 add_abbrev_attr (attribute, form);
252b5132 7467 }
5b18a4bc 7468 while (attribute != 0);
252b5132
RH
7469 }
7470
5b18a4bc 7471 return NULL;
252b5132
RH
7472}
7473
7474static char *
d3ba0551 7475get_TAG_name (unsigned long tag)
252b5132
RH
7476{
7477 switch (tag)
7478 {
b34976b6
AM
7479 case DW_TAG_padding: return "DW_TAG_padding";
7480 case DW_TAG_array_type: return "DW_TAG_array_type";
7481 case DW_TAG_class_type: return "DW_TAG_class_type";
7482 case DW_TAG_entry_point: return "DW_TAG_entry_point";
7483 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
7484 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
7485 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
7486 case DW_TAG_label: return "DW_TAG_label";
7487 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
7488 case DW_TAG_member: return "DW_TAG_member";
7489 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
7490 case DW_TAG_reference_type: return "DW_TAG_reference_type";
7491 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
7492 case DW_TAG_string_type: return "DW_TAG_string_type";
7493 case DW_TAG_structure_type: return "DW_TAG_structure_type";
7494 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
7495 case DW_TAG_typedef: return "DW_TAG_typedef";
7496 case DW_TAG_union_type: return "DW_TAG_union_type";
252b5132 7497 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
b34976b6
AM
7498 case DW_TAG_variant: return "DW_TAG_variant";
7499 case DW_TAG_common_block: return "DW_TAG_common_block";
7500 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
7501 case DW_TAG_inheritance: return "DW_TAG_inheritance";
7502 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
7503 case DW_TAG_module: return "DW_TAG_module";
7504 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
7505 case DW_TAG_set_type: return "DW_TAG_set_type";
7506 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
7507 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
7508 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
7509 case DW_TAG_base_type: return "DW_TAG_base_type";
7510 case DW_TAG_catch_block: return "DW_TAG_catch_block";
7511 case DW_TAG_const_type: return "DW_TAG_const_type";
7512 case DW_TAG_constant: return "DW_TAG_constant";
7513 case DW_TAG_enumerator: return "DW_TAG_enumerator";
7514 case DW_TAG_file_type: return "DW_TAG_file_type";
7515 case DW_TAG_friend: return "DW_TAG_friend";
7516 case DW_TAG_namelist: return "DW_TAG_namelist";
7517 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
7518 case DW_TAG_packed_type: return "DW_TAG_packed_type";
7519 case DW_TAG_subprogram: return "DW_TAG_subprogram";
7520 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
7521 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
7522 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
7523 case DW_TAG_try_block: return "DW_TAG_try_block";
7524 case DW_TAG_variant_part: return "DW_TAG_variant_part";
7525 case DW_TAG_variable: return "DW_TAG_variable";
7526 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
7527 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
7528 case DW_TAG_format_label: return "DW_TAG_format_label";
7529 case DW_TAG_function_template: return "DW_TAG_function_template";
7530 case DW_TAG_class_template: return "DW_TAG_class_template";
b811889f 7531 /* DWARF 2.1 values. */
b34976b6
AM
7532 case DW_TAG_dwarf_procedure: return "DW_TAG_dwarf_procedure";
7533 case DW_TAG_restrict_type: return "DW_TAG_restrict_type";
7534 case DW_TAG_interface_type: return "DW_TAG_interface_type";
7535 case DW_TAG_namespace: return "DW_TAG_namespace";
7536 case DW_TAG_imported_module: return "DW_TAG_imported_module";
7537 case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type";
7538 case DW_TAG_partial_unit: return "DW_TAG_partial_unit";
7539 case DW_TAG_imported_unit: return "DW_TAG_imported_unit";
84ad6ede 7540 /* UPC values. */
ba2685cc
AM
7541 case DW_TAG_upc_shared_type: return "DW_TAG_upc_shared_type";
7542 case DW_TAG_upc_strict_type: return "DW_TAG_upc_strict_type";
7543 case DW_TAG_upc_relaxed_type: return "DW_TAG_upc_relaxed_type";
252b5132
RH
7544 default:
7545 {
b34976b6 7546 static char buffer[100];
252b5132
RH
7547
7548 sprintf (buffer, _("Unknown TAG value: %lx"), tag);
7549 return buffer;
7550 }
7551 }
7552}
7553
252b5132 7554static char *
d3ba0551 7555get_FORM_name (unsigned long form)
252b5132
RH
7556{
7557 switch (form)
7558 {
b34976b6
AM
7559 case DW_FORM_addr: return "DW_FORM_addr";
7560 case DW_FORM_block2: return "DW_FORM_block2";
7561 case DW_FORM_block4: return "DW_FORM_block4";
7562 case DW_FORM_data2: return "DW_FORM_data2";
7563 case DW_FORM_data4: return "DW_FORM_data4";
7564 case DW_FORM_data8: return "DW_FORM_data8";
7565 case DW_FORM_string: return "DW_FORM_string";
7566 case DW_FORM_block: return "DW_FORM_block";
7567 case DW_FORM_block1: return "DW_FORM_block1";
7568 case DW_FORM_data1: return "DW_FORM_data1";
7569 case DW_FORM_flag: return "DW_FORM_flag";
7570 case DW_FORM_sdata: return "DW_FORM_sdata";
7571 case DW_FORM_strp: return "DW_FORM_strp";
7572 case DW_FORM_udata: return "DW_FORM_udata";
7573 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
7574 case DW_FORM_ref1: return "DW_FORM_ref1";
7575 case DW_FORM_ref2: return "DW_FORM_ref2";
7576 case DW_FORM_ref4: return "DW_FORM_ref4";
7577 case DW_FORM_ref8: return "DW_FORM_ref8";
7578 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
7579 case DW_FORM_indirect: return "DW_FORM_indirect";
252b5132
RH
7580 default:
7581 {
b34976b6 7582 static char buffer[100];
252b5132
RH
7583
7584 sprintf (buffer, _("Unknown FORM value: %lx"), form);
7585 return buffer;
7586 }
7587 }
7588}
7589
5b18a4bc
NC
7590static unsigned char *
7591display_block (unsigned char *data, unsigned long length)
252b5132 7592{
5b18a4bc 7593 printf (_(" %lu byte block: "), length);
252b5132 7594
5b18a4bc
NC
7595 while (length --)
7596 printf ("%lx ", (unsigned long) byte_get (data++, 1));
252b5132 7597
5b18a4bc 7598 return data;
252b5132
RH
7599}
7600
b38c7015 7601static int
5b18a4bc
NC
7602decode_location_expression (unsigned char * data,
7603 unsigned int pointer_size,
7604 unsigned long length,
7605 unsigned long cu_offset)
e0c60db2 7606{
5b18a4bc
NC
7607 unsigned op;
7608 int bytes_read;
7609 unsigned long uvalue;
7610 unsigned char *end = data + length;
b38c7015 7611 int need_frame_base = 0;
e0c60db2 7612
5b18a4bc 7613 while (data < end)
e0c60db2 7614 {
5b18a4bc 7615 op = *data++;
e0c60db2
NC
7616
7617 switch (op)
7618 {
5b18a4bc
NC
7619 case DW_OP_addr:
7620 printf ("DW_OP_addr: %lx",
7621 (unsigned long) byte_get (data, pointer_size));
7622 data += pointer_size;
e0c60db2 7623 break;
5b18a4bc
NC
7624 case DW_OP_deref:
7625 printf ("DW_OP_deref");
e0c60db2 7626 break;
5b18a4bc
NC
7627 case DW_OP_const1u:
7628 printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
e0c60db2 7629 break;
5b18a4bc
NC
7630 case DW_OP_const1s:
7631 printf ("DW_OP_const1s: %ld", (long) byte_get_signed (data++, 1));
e0c60db2 7632 break;
5b18a4bc
NC
7633 case DW_OP_const2u:
7634 printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
7635 data += 2;
eb6bd4d3
JM
7636 break;
7637 case DW_OP_const2s:
74013231 7638 printf ("DW_OP_const2s: %ld", (long) byte_get_signed (data, 2));
eb6bd4d3
JM
7639 data += 2;
7640 break;
7641 case DW_OP_const4u:
7642 printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
7643 data += 4;
7644 break;
7645 case DW_OP_const4s:
74013231 7646 printf ("DW_OP_const4s: %ld", (long) byte_get_signed (data, 4));
eb6bd4d3
JM
7647 data += 4;
7648 break;
7649 case DW_OP_const8u:
7650 printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
7651 (unsigned long) byte_get (data + 4, 4));
7652 data += 8;
7653 break;
7654 case DW_OP_const8s:
7655 printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
7656 (long) byte_get (data + 4, 4));
7657 data += 8;
7658 break;
7659 case DW_OP_constu:
7660 printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
7661 data += bytes_read;
7662 break;
7663 case DW_OP_consts:
7664 printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
7665 data += bytes_read;
7666 break;
7667 case DW_OP_dup:
7668 printf ("DW_OP_dup");
7669 break;
7670 case DW_OP_drop:
7671 printf ("DW_OP_drop");
7672 break;
7673 case DW_OP_over:
7674 printf ("DW_OP_over");
7675 break;
7676 case DW_OP_pick:
7677 printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
7678 break;
7679 case DW_OP_swap:
7680 printf ("DW_OP_swap");
7681 break;
7682 case DW_OP_rot:
7683 printf ("DW_OP_rot");
7684 break;
7685 case DW_OP_xderef:
7686 printf ("DW_OP_xderef");
7687 break;
7688 case DW_OP_abs:
7689 printf ("DW_OP_abs");
7690 break;
7691 case DW_OP_and:
7692 printf ("DW_OP_and");
7693 break;
7694 case DW_OP_div:
7695 printf ("DW_OP_div");
7696 break;
7697 case DW_OP_minus:
7698 printf ("DW_OP_minus");
7699 break;
7700 case DW_OP_mod:
7701 printf ("DW_OP_mod");
7702 break;
7703 case DW_OP_mul:
7704 printf ("DW_OP_mul");
7705 break;
7706 case DW_OP_neg:
7707 printf ("DW_OP_neg");
7708 break;
7709 case DW_OP_not:
7710 printf ("DW_OP_not");
7711 break;
7712 case DW_OP_or:
7713 printf ("DW_OP_or");
7714 break;
7715 case DW_OP_plus:
7716 printf ("DW_OP_plus");
7717 break;
7718 case DW_OP_plus_uconst:
7719 printf ("DW_OP_plus_uconst: %lu",
7720 read_leb128 (data, &bytes_read, 0));
7721 data += bytes_read;
7722 break;
7723 case DW_OP_shl:
7724 printf ("DW_OP_shl");
7725 break;
7726 case DW_OP_shr:
7727 printf ("DW_OP_shr");
7728 break;
7729 case DW_OP_shra:
7730 printf ("DW_OP_shra");
7731 break;
7732 case DW_OP_xor:
7733 printf ("DW_OP_xor");
7734 break;
7735 case DW_OP_bra:
74013231 7736 printf ("DW_OP_bra: %ld", (long) byte_get_signed (data, 2));
eb6bd4d3
JM
7737 data += 2;
7738 break;
7739 case DW_OP_eq:
7740 printf ("DW_OP_eq");
7741 break;
7742 case DW_OP_ge:
7743 printf ("DW_OP_ge");
7744 break;
7745 case DW_OP_gt:
7746 printf ("DW_OP_gt");
7747 break;
7748 case DW_OP_le:
7749 printf ("DW_OP_le");
7750 break;
7751 case DW_OP_lt:
7752 printf ("DW_OP_lt");
7753 break;
7754 case DW_OP_ne:
7755 printf ("DW_OP_ne");
7756 break;
7757 case DW_OP_skip:
74013231 7758 printf ("DW_OP_skip: %ld", (long) byte_get_signed (data, 2));
eb6bd4d3
JM
7759 data += 2;
7760 break;
7761
5b18a4bc
NC
7762 case DW_OP_lit0:
7763 case DW_OP_lit1:
7764 case DW_OP_lit2:
7765 case DW_OP_lit3:
7766 case DW_OP_lit4:
7767 case DW_OP_lit5:
7768 case DW_OP_lit6:
7769 case DW_OP_lit7:
7770 case DW_OP_lit8:
7771 case DW_OP_lit9:
7772 case DW_OP_lit10:
7773 case DW_OP_lit11:
7774 case DW_OP_lit12:
7775 case DW_OP_lit13:
7776 case DW_OP_lit14:
7777 case DW_OP_lit15:
7778 case DW_OP_lit16:
7779 case DW_OP_lit17:
7780 case DW_OP_lit18:
7781 case DW_OP_lit19:
7782 case DW_OP_lit20:
7783 case DW_OP_lit21:
7784 case DW_OP_lit22:
7785 case DW_OP_lit23:
7786 case DW_OP_lit24:
7787 case DW_OP_lit25:
7788 case DW_OP_lit26:
7789 case DW_OP_lit27:
7790 case DW_OP_lit28:
7791 case DW_OP_lit29:
7792 case DW_OP_lit30:
7793 case DW_OP_lit31:
7794 printf ("DW_OP_lit%d", op - DW_OP_lit0);
7795 break;
7796
7797 case DW_OP_reg0:
7798 case DW_OP_reg1:
7799 case DW_OP_reg2:
7800 case DW_OP_reg3:
7801 case DW_OP_reg4:
7802 case DW_OP_reg5:
7803 case DW_OP_reg6:
7804 case DW_OP_reg7:
7805 case DW_OP_reg8:
7806 case DW_OP_reg9:
7807 case DW_OP_reg10:
7808 case DW_OP_reg11:
7809 case DW_OP_reg12:
7810 case DW_OP_reg13:
7811 case DW_OP_reg14:
7812 case DW_OP_reg15:
7813 case DW_OP_reg16:
7814 case DW_OP_reg17:
7815 case DW_OP_reg18:
7816 case DW_OP_reg19:
7817 case DW_OP_reg20:
7818 case DW_OP_reg21:
7819 case DW_OP_reg22:
7820 case DW_OP_reg23:
7821 case DW_OP_reg24:
7822 case DW_OP_reg25:
7823 case DW_OP_reg26:
7824 case DW_OP_reg27:
7825 case DW_OP_reg28:
7826 case DW_OP_reg29:
7827 case DW_OP_reg30:
7828 case DW_OP_reg31:
7829 printf ("DW_OP_reg%d", op - DW_OP_reg0);
7830 break;
7831
7832 case DW_OP_breg0:
7833 case DW_OP_breg1:
7834 case DW_OP_breg2:
7835 case DW_OP_breg3:
7836 case DW_OP_breg4:
7837 case DW_OP_breg5:
7838 case DW_OP_breg6:
7839 case DW_OP_breg7:
7840 case DW_OP_breg8:
7841 case DW_OP_breg9:
7842 case DW_OP_breg10:
7843 case DW_OP_breg11:
7844 case DW_OP_breg12:
7845 case DW_OP_breg13:
7846 case DW_OP_breg14:
7847 case DW_OP_breg15:
7848 case DW_OP_breg16:
7849 case DW_OP_breg17:
7850 case DW_OP_breg18:
7851 case DW_OP_breg19:
7852 case DW_OP_breg20:
7853 case DW_OP_breg21:
7854 case DW_OP_breg22:
7855 case DW_OP_breg23:
7856 case DW_OP_breg24:
7857 case DW_OP_breg25:
7858 case DW_OP_breg26:
7859 case DW_OP_breg27:
7860 case DW_OP_breg28:
7861 case DW_OP_breg29:
7862 case DW_OP_breg30:
7863 case DW_OP_breg31:
7864 printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
7865 read_leb128 (data, &bytes_read, 1));
7866 data += bytes_read;
7867 break;
7868
7869 case DW_OP_regx:
7870 printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
7871 data += bytes_read;
7872 break;
7873 case DW_OP_fbreg:
b38c7015 7874 need_frame_base = 1;
5b18a4bc
NC
7875 printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
7876 data += bytes_read;
7877 break;
7878 case DW_OP_bregx:
7879 uvalue = read_leb128 (data, &bytes_read, 0);
7880 data += bytes_read;
7881 printf ("DW_OP_bregx: %lu %ld", uvalue,
7882 read_leb128 (data, &bytes_read, 1));
7883 data += bytes_read;
7884 break;
7885 case DW_OP_piece:
7886 printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
7887 data += bytes_read;
7888 break;
7889 case DW_OP_deref_size:
7890 printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
7891 break;
7892 case DW_OP_xderef_size:
7893 printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
7894 break;
7895 case DW_OP_nop:
7896 printf ("DW_OP_nop");
7897 break;
7898
7899 /* DWARF 3 extensions. */
7900 case DW_OP_push_object_address:
7901 printf ("DW_OP_push_object_address");
7902 break;
7903 case DW_OP_call2:
7904 /* XXX: Strictly speaking for 64-bit DWARF3 files
7905 this ought to be an 8-byte wide computation. */
7906 printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2) + cu_offset);
7907 data += 2;
7908 break;
7909 case DW_OP_call4:
7910 /* XXX: Strictly speaking for 64-bit DWARF3 files
7911 this ought to be an 8-byte wide computation. */
7912 printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4) + cu_offset);
7913 data += 4;
7914 break;
7915 case DW_OP_call_ref:
7916 printf ("DW_OP_call_ref");
7917 break;
7918
7919 /* GNU extensions. */
7920 case DW_OP_GNU_push_tls_address:
7921 printf ("DW_OP_GNU_push_tls_address");
7922 break;
7923
7924 default:
7925 if (op >= DW_OP_lo_user
7926 && op <= DW_OP_hi_user)
7927 printf (_("(User defined location op)"));
7928 else
7929 printf (_("(Unknown location op)"));
7930 /* No way to tell where the next op is, so just bail. */
b38c7015 7931 return need_frame_base;
5b18a4bc
NC
7932 }
7933
7934 /* Separate the ops. */
7935 if (data < end)
7936 printf ("; ");
7937 }
b38c7015
L
7938
7939 return need_frame_base;
5b18a4bc
NC
7940}
7941
5b18a4bc
NC
7942/* This structure records the information that
7943 we extract from the.debug_info section. */
7944typedef struct
7945{
7946 unsigned int pointer_size;
7947 unsigned long cu_offset;
b38c7015 7948 unsigned long base_address;
5b18a4bc
NC
7949 /* This is an array of offsets to the location list table. */
7950 unsigned long *loc_offsets;
b38c7015 7951 int *have_frame_base;
5b18a4bc
NC
7952 unsigned int num_loc_offsets;
7953 unsigned int max_loc_offsets;
0853c092
L
7954 unsigned long *range_lists;
7955 unsigned int num_range_lists;
7956 unsigned int max_range_lists;
5b18a4bc
NC
7957}
7958debug_info;
7959
7960static debug_info * debug_information = NULL;
7961static unsigned int num_debug_info_entries = 0;
7962static unsigned int last_pointer_size = 0;
7963static int warned_about_missing_comp_units = FALSE;
7964
7965static unsigned char *
7966read_and_display_attr_value (unsigned long attribute,
7967 unsigned long form,
7968 unsigned char *data,
7969 unsigned long cu_offset,
7970 unsigned long pointer_size,
7971 unsigned long offset_size,
7972 int dwarf_version,
7973 debug_info *debug_info_p,
7974 int do_loc)
7975{
5b18a4bc
NC
7976 unsigned long uvalue = 0;
7977 unsigned char *block_start = NULL;
7978 int bytes_read;
7979
7980 switch (form)
7981 {
7982 default:
7983 break;
7984
7985 case DW_FORM_ref_addr:
7986 if (dwarf_version == 2)
7987 {
7988 uvalue = byte_get (data, pointer_size);
7989 data += pointer_size;
7990 }
7991 else if (dwarf_version == 3)
7992 {
7993 uvalue = byte_get (data, offset_size);
7994 data += offset_size;
7995 }
7996 else
7997 {
7998 error (_("Internal error: DWARF version is not 2 or 3.\n"));
7999 }
8000 break;
8001
8002 case DW_FORM_addr:
8003 uvalue = byte_get (data, pointer_size);
8004 data += pointer_size;
8005 break;
8006
8007 case DW_FORM_strp:
8008 uvalue = byte_get (data, offset_size);
8009 data += offset_size;
8010 break;
8011
8012 case DW_FORM_ref1:
8013 case DW_FORM_flag:
8014 case DW_FORM_data1:
8015 uvalue = byte_get (data++, 1);
8016 break;
8017
8018 case DW_FORM_ref2:
8019 case DW_FORM_data2:
8020 uvalue = byte_get (data, 2);
8021 data += 2;
8022 break;
8023
8024 case DW_FORM_ref4:
8025 case DW_FORM_data4:
8026 uvalue = byte_get (data, 4);
8027 data += 4;
8028 break;
8029
8030 case DW_FORM_sdata:
8031 uvalue = read_leb128 (data, & bytes_read, 1);
8032 data += bytes_read;
8033 break;
8034
8035 case DW_FORM_ref_udata:
8036 case DW_FORM_udata:
8037 uvalue = read_leb128 (data, & bytes_read, 0);
8038 data += bytes_read;
8039 break;
8040
8041 case DW_FORM_indirect:
8042 form = read_leb128 (data, & bytes_read, 0);
8043 data += bytes_read;
8044 if (!do_loc)
8045 printf (" %s", get_FORM_name (form));
8046 return read_and_display_attr_value (attribute, form, data,
8047 cu_offset, pointer_size,
8048 offset_size, dwarf_version,
8049 debug_info_p, do_loc);
8050 }
8051
8052 switch (form)
8053 {
8054 case DW_FORM_ref_addr:
8055 if (!do_loc)
8056 printf (" <#%lx>", uvalue);
8057 break;
8058
8059 case DW_FORM_ref1:
8060 case DW_FORM_ref2:
8061 case DW_FORM_ref4:
8062 case DW_FORM_ref_udata:
8063 if (!do_loc)
8064 printf (" <%lx>", uvalue + cu_offset);
8065 break;
8066
8067 case DW_FORM_data4:
8068 case DW_FORM_addr:
8069 if (!do_loc)
8070 printf (" %#lx", uvalue);
8071 break;
8072
8073 case DW_FORM_flag:
8074 case DW_FORM_data1:
8075 case DW_FORM_data2:
8076 case DW_FORM_sdata:
8077 case DW_FORM_udata:
8078 if (!do_loc)
8079 printf (" %ld", uvalue);
8080 break;
8081
8082 case DW_FORM_ref8:
8083 case DW_FORM_data8:
8084 if (!do_loc)
8085 {
8086 uvalue = byte_get (data, 4);
8087 printf (" %lx", uvalue);
8088 printf (" %lx", (unsigned long) byte_get (data + 4, 4));
8089 }
0853c092 8090 if ((do_loc || do_debug_loc || do_debug_ranges)
5b18a4bc
NC
8091 && num_debug_info_entries == 0)
8092 {
8093 if (sizeof (uvalue) == 8)
8094 uvalue = byte_get (data, 8);
8095 else
8096 error (_("DW_FORM_data8 is unsupported when sizeof (unsigned long) != 8\n"));
8097 }
8098 data += 8;
8099 break;
8100
8101 case DW_FORM_string:
8102 if (!do_loc)
8103 printf (" %s", data);
8104 data += strlen ((char *) data) + 1;
8105 break;
8106
8107 case DW_FORM_block:
8108 uvalue = read_leb128 (data, & bytes_read, 0);
8109 block_start = data + bytes_read;
8110 if (do_loc)
8111 data = block_start + uvalue;
8112 else
8113 data = display_block (block_start, uvalue);
8114 break;
8115
8116 case DW_FORM_block1:
8117 uvalue = byte_get (data, 1);
8118 block_start = data + 1;
8119 if (do_loc)
8120 data = block_start + uvalue;
8121 else
8122 data = display_block (block_start, uvalue);
8123 break;
8124
8125 case DW_FORM_block2:
8126 uvalue = byte_get (data, 2);
8127 block_start = data + 2;
8128 if (do_loc)
8129 data = block_start + uvalue;
8130 else
8131 data = display_block (block_start, uvalue);
8132 break;
8133
8134 case DW_FORM_block4:
8135 uvalue = byte_get (data, 4);
8136 block_start = data + 4;
8137 if (do_loc)
8138 data = block_start + uvalue;
8139 else
8140 data = display_block (block_start, uvalue);
8141 break;
8142
8143 case DW_FORM_strp:
8144 if (!do_loc)
8145 printf (_(" (indirect string, offset: 0x%lx): %s"),
8146 uvalue, fetch_indirect_string (uvalue));
8147 break;
8148
8149 case DW_FORM_indirect:
8150 /* Handled above. */
8151 break;
8152
8153 default:
8154 warn (_("Unrecognized form: %d\n"), form);
8155 break;
8156 }
8157
8158 /* For some attributes we can display further information. */
0853c092 8159 if ((do_loc || do_debug_loc || do_debug_ranges)
5b18a4bc
NC
8160 && num_debug_info_entries == 0)
8161 {
8162 switch (attribute)
8163 {
8164 case DW_AT_frame_base:
b38c7015 8165 have_frame_base = 1;
5b18a4bc
NC
8166 case DW_AT_location:
8167 case DW_AT_data_member_location:
8168 case DW_AT_vtable_elem_location:
8169 case DW_AT_allocated:
8170 case DW_AT_associated:
8171 case DW_AT_data_location:
8172 case DW_AT_stride:
8173 case DW_AT_upper_bound:
8174 case DW_AT_lower_bound:
8175 if (form == DW_FORM_data4 || form == DW_FORM_data8)
8176 {
8177 /* Process location list. */
8178 unsigned int max = debug_info_p->max_loc_offsets;
8179 unsigned int num = debug_info_p->num_loc_offsets;
8180
8181 if (max == 0 || num >= max)
8182 {
8183 max += 1024;
8184 debug_info_p->loc_offsets
8185 = xrealloc (debug_info_p->loc_offsets,
8186 max * sizeof (*debug_info_p->loc_offsets));
b38c7015
L
8187 debug_info_p->have_frame_base
8188 = xrealloc (debug_info_p->have_frame_base,
8189 max * sizeof (*debug_info_p->have_frame_base));
5b18a4bc
NC
8190 debug_info_p->max_loc_offsets = max;
8191 }
8192 debug_info_p->loc_offsets [num] = uvalue;
b38c7015 8193 debug_info_p->have_frame_base [num] = have_frame_base;
5b18a4bc
NC
8194 debug_info_p->num_loc_offsets++;
8195 }
8196 break;
b38c7015
L
8197
8198 case DW_AT_low_pc:
8199 if (need_base_address)
8200 debug_info_p->base_address = uvalue;
8201 break;
5b18a4bc 8202
0853c092
L
8203 case DW_AT_ranges:
8204 if (form == DW_FORM_data4 || form == DW_FORM_data8)
8205 {
8206 /* Process range list. */
8207 unsigned int max = debug_info_p->max_range_lists;
8208 unsigned int num = debug_info_p->num_range_lists;
8209
8210 if (max == 0 || num >= max)
8211 {
8212 max += 1024;
8213 debug_info_p->range_lists
8214 = xrealloc (debug_info_p->range_lists,
8215 max * sizeof (*debug_info_p->range_lists));
8216 debug_info_p->max_range_lists = max;
8217 }
8218 debug_info_p->range_lists [num] = uvalue;
8219 debug_info_p->num_range_lists++;
8220 }
8221 break;
8222
5b18a4bc
NC
8223 default:
8224 break;
8225 }
8226 }
8227
8228 if (do_loc)
8229 return data;
8230
8231 printf ("\t");
8232
8233 switch (attribute)
8234 {
8235 case DW_AT_inline:
8236 switch (uvalue)
8237 {
8238 case DW_INL_not_inlined:
8239 printf (_("(not inlined)"));
8240 break;
8241 case DW_INL_inlined:
8242 printf (_("(inlined)"));
8243 break;
8244 case DW_INL_declared_not_inlined:
8245 printf (_("(declared as inline but ignored)"));
8246 break;
8247 case DW_INL_declared_inlined:
8248 printf (_("(declared as inline and inlined)"));
8249 break;
8250 default:
8251 printf (_(" (Unknown inline attribute value: %lx)"), uvalue);
8252 break;
8253 }
8254 break;
8255
8256 case DW_AT_language:
8257 switch (uvalue)
8258 {
8259 case DW_LANG_C: printf ("(non-ANSI C)"); break;
8260 case DW_LANG_C89: printf ("(ANSI C)"); break;
8261 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
8262 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
8263 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
8264 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
8265 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
8266 case DW_LANG_Ada83: printf ("(Ada)"); break;
8267 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
8268 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
8269 /* DWARF 2.1 values. */
8270 case DW_LANG_C99: printf ("(ANSI C99)"); break;
8271 case DW_LANG_Ada95: printf ("(ADA 95)"); break;
8272 case DW_LANG_Fortran95: printf ("(Fortran 95)"); break;
8273 /* MIPS extension. */
8274 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
8275 /* UPC extension. */
8276 case DW_LANG_Upc: printf ("(Unified Parallel C)"); break;
8277 default:
8278 printf ("(Unknown: %lx)", uvalue);
8279 break;
8280 }
8281 break;
8282
8283 case DW_AT_encoding:
8284 switch (uvalue)
8285 {
8286 case DW_ATE_void: printf ("(void)"); break;
8287 case DW_ATE_address: printf ("(machine address)"); break;
8288 case DW_ATE_boolean: printf ("(boolean)"); break;
8289 case DW_ATE_complex_float: printf ("(complex float)"); break;
8290 case DW_ATE_float: printf ("(float)"); break;
8291 case DW_ATE_signed: printf ("(signed)"); break;
8292 case DW_ATE_signed_char: printf ("(signed char)"); break;
8293 case DW_ATE_unsigned: printf ("(unsigned)"); break;
8294 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
8295 /* DWARF 2.1 value. */
8296 case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
8297 default:
8298 if (uvalue >= DW_ATE_lo_user
8299 && uvalue <= DW_ATE_hi_user)
8300 printf ("(user defined type)");
8301 else
8302 printf ("(unknown type)");
8303 break;
8304 }
8305 break;
8306
8307 case DW_AT_accessibility:
8308 switch (uvalue)
8309 {
8310 case DW_ACCESS_public: printf ("(public)"); break;
8311 case DW_ACCESS_protected: printf ("(protected)"); break;
8312 case DW_ACCESS_private: printf ("(private)"); break;
8313 default:
8314 printf ("(unknown accessibility)");
8315 break;
8316 }
8317 break;
8318
8319 case DW_AT_visibility:
8320 switch (uvalue)
8321 {
8322 case DW_VIS_local: printf ("(local)"); break;
8323 case DW_VIS_exported: printf ("(exported)"); break;
8324 case DW_VIS_qualified: printf ("(qualified)"); break;
8325 default: printf ("(unknown visibility)"); break;
8326 }
8327 break;
8328
8329 case DW_AT_virtuality:
8330 switch (uvalue)
8331 {
8332 case DW_VIRTUALITY_none: printf ("(none)"); break;
8333 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
8334 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
8335 default: printf ("(unknown virtuality)"); break;
8336 }
8337 break;
8338
8339 case DW_AT_identifier_case:
8340 switch (uvalue)
8341 {
8342 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
8343 case DW_ID_up_case: printf ("(up_case)"); break;
8344 case DW_ID_down_case: printf ("(down_case)"); break;
8345 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
8346 default: printf ("(unknown case)"); break;
8347 }
8348 break;
8349
8350 case DW_AT_calling_convention:
8351 switch (uvalue)
8352 {
8353 case DW_CC_normal: printf ("(normal)"); break;
8354 case DW_CC_program: printf ("(program)"); break;
8355 case DW_CC_nocall: printf ("(nocall)"); break;
8356 default:
8357 if (uvalue >= DW_CC_lo_user
8358 && uvalue <= DW_CC_hi_user)
8359 printf ("(user defined)");
8360 else
8361 printf ("(unknown convention)");
8362 }
8363 break;
8364
8365 case DW_AT_ordering:
8366 switch (uvalue)
8367 {
8368 case -1: printf ("(undefined)"); break;
8369 case 0: printf ("(row major)"); break;
8370 case 1: printf ("(column major)"); break;
8371 }
8372 break;
8373
8374 case DW_AT_frame_base:
b38c7015 8375 have_frame_base = 1;
5b18a4bc
NC
8376 case DW_AT_location:
8377 case DW_AT_data_member_location:
8378 case DW_AT_vtable_elem_location:
8379 case DW_AT_allocated:
8380 case DW_AT_associated:
8381 case DW_AT_data_location:
8382 case DW_AT_stride:
8383 case DW_AT_upper_bound:
8384 case DW_AT_lower_bound:
8385 if (block_start)
8386 {
b38c7015
L
8387 int need_frame_base;
8388
5b18a4bc 8389 printf ("(");
b38c7015
L
8390 need_frame_base = decode_location_expression (block_start,
8391 pointer_size,
8392 uvalue,
8393 cu_offset);
5b18a4bc 8394 printf (")");
b38c7015
L
8395 if (need_frame_base && !have_frame_base)
8396 printf (_(" [without DW_AT_frame_base]"));
5b18a4bc
NC
8397 }
8398 else if (form == DW_FORM_data4 || form == DW_FORM_data8)
8399 printf (_("(location list)"));
8400
8401 break;
8402
5b18a4bc
NC
8403 default:
8404 break;
8405 }
8406
8407 return data;
8408}
8409
8410static char *
8411get_AT_name (unsigned long attribute)
8412{
8413 switch (attribute)
8414 {
8415 case DW_AT_sibling: return "DW_AT_sibling";
8416 case DW_AT_location: return "DW_AT_location";
8417 case DW_AT_name: return "DW_AT_name";
8418 case DW_AT_ordering: return "DW_AT_ordering";
8419 case DW_AT_subscr_data: return "DW_AT_subscr_data";
8420 case DW_AT_byte_size: return "DW_AT_byte_size";
8421 case DW_AT_bit_offset: return "DW_AT_bit_offset";
8422 case DW_AT_bit_size: return "DW_AT_bit_size";
8423 case DW_AT_element_list: return "DW_AT_element_list";
8424 case DW_AT_stmt_list: return "DW_AT_stmt_list";
8425 case DW_AT_low_pc: return "DW_AT_low_pc";
8426 case DW_AT_high_pc: return "DW_AT_high_pc";
8427 case DW_AT_language: return "DW_AT_language";
8428 case DW_AT_member: return "DW_AT_member";
8429 case DW_AT_discr: return "DW_AT_discr";
8430 case DW_AT_discr_value: return "DW_AT_discr_value";
8431 case DW_AT_visibility: return "DW_AT_visibility";
8432 case DW_AT_import: return "DW_AT_import";
8433 case DW_AT_string_length: return "DW_AT_string_length";
8434 case DW_AT_common_reference: return "DW_AT_common_reference";
8435 case DW_AT_comp_dir: return "DW_AT_comp_dir";
8436 case DW_AT_const_value: return "DW_AT_const_value";
8437 case DW_AT_containing_type: return "DW_AT_containing_type";
8438 case DW_AT_default_value: return "DW_AT_default_value";
8439 case DW_AT_inline: return "DW_AT_inline";
8440 case DW_AT_is_optional: return "DW_AT_is_optional";
8441 case DW_AT_lower_bound: return "DW_AT_lower_bound";
8442 case DW_AT_producer: return "DW_AT_producer";
8443 case DW_AT_prototyped: return "DW_AT_prototyped";
8444 case DW_AT_return_addr: return "DW_AT_return_addr";
8445 case DW_AT_start_scope: return "DW_AT_start_scope";
8446 case DW_AT_stride_size: return "DW_AT_stride_size";
8447 case DW_AT_upper_bound: return "DW_AT_upper_bound";
8448 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
8449 case DW_AT_accessibility: return "DW_AT_accessibility";
8450 case DW_AT_address_class: return "DW_AT_address_class";
8451 case DW_AT_artificial: return "DW_AT_artificial";
8452 case DW_AT_base_types: return "DW_AT_base_types";
8453 case DW_AT_calling_convention: return "DW_AT_calling_convention";
8454 case DW_AT_count: return "DW_AT_count";
8455 case DW_AT_data_member_location: return "DW_AT_data_member_location";
8456 case DW_AT_decl_column: return "DW_AT_decl_column";
8457 case DW_AT_decl_file: return "DW_AT_decl_file";
8458 case DW_AT_decl_line: return "DW_AT_decl_line";
8459 case DW_AT_declaration: return "DW_AT_declaration";
8460 case DW_AT_discr_list: return "DW_AT_discr_list";
8461 case DW_AT_encoding: return "DW_AT_encoding";
8462 case DW_AT_external: return "DW_AT_external";
8463 case DW_AT_frame_base: return "DW_AT_frame_base";
8464 case DW_AT_friend: return "DW_AT_friend";
8465 case DW_AT_identifier_case: return "DW_AT_identifier_case";
8466 case DW_AT_macro_info: return "DW_AT_macro_info";
8467 case DW_AT_namelist_items: return "DW_AT_namelist_items";
8468 case DW_AT_priority: return "DW_AT_priority";
8469 case DW_AT_segment: return "DW_AT_segment";
8470 case DW_AT_specification: return "DW_AT_specification";
8471 case DW_AT_static_link: return "DW_AT_static_link";
8472 case DW_AT_type: return "DW_AT_type";
8473 case DW_AT_use_location: return "DW_AT_use_location";
8474 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
8475 case DW_AT_virtuality: return "DW_AT_virtuality";
8476 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
8477 /* DWARF 2.1 values. */
8478 case DW_AT_allocated: return "DW_AT_allocated";
8479 case DW_AT_associated: return "DW_AT_associated";
8480 case DW_AT_data_location: return "DW_AT_data_location";
8481 case DW_AT_stride: return "DW_AT_stride";
8482 case DW_AT_entry_pc: return "DW_AT_entry_pc";
8483 case DW_AT_use_UTF8: return "DW_AT_use_UTF8";
8484 case DW_AT_extension: return "DW_AT_extension";
8485 case DW_AT_ranges: return "DW_AT_ranges";
8486 case DW_AT_trampoline: return "DW_AT_trampoline";
8487 case DW_AT_call_column: return "DW_AT_call_column";
8488 case DW_AT_call_file: return "DW_AT_call_file";
8489 case DW_AT_call_line: return "DW_AT_call_line";
8490 /* SGI/MIPS extensions. */
8491 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
8492 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
8493 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
8494 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
8495 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
8496 case DW_AT_MIPS_software_pipeline_depth:
8497 return "DW_AT_MIPS_software_pipeline_depth";
8498 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
8499 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
8500 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
8501 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
8502 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
8503 /* GNU extensions. */
8504 case DW_AT_sf_names: return "DW_AT_sf_names";
8505 case DW_AT_src_info: return "DW_AT_src_info";
8506 case DW_AT_mac_info: return "DW_AT_mac_info";
8507 case DW_AT_src_coords: return "DW_AT_src_coords";
8508 case DW_AT_body_begin: return "DW_AT_body_begin";
8509 case DW_AT_body_end: return "DW_AT_body_end";
8510 case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
8511 /* UPC extension. */
8512 case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled";
8513 default:
8514 {
8515 static char buffer[100];
8516
8517 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
8518 return buffer;
8519 }
8520 }
8521}
eb6bd4d3 8522
5b18a4bc
NC
8523static unsigned char *
8524read_and_display_attr (unsigned long attribute,
8525 unsigned long form,
8526 unsigned char *data,
8527 unsigned long cu_offset,
8528 unsigned long pointer_size,
8529 unsigned long offset_size,
8530 int dwarf_version,
8531 debug_info *debug_info_p,
8532 int do_loc)
8533{
8534 if (!do_loc)
8535 printf (" %-18s:", get_AT_name (attribute));
8536 data = read_and_display_attr_value (attribute, form, data, cu_offset,
8537 pointer_size, offset_size,
8538 dwarf_version, debug_info_p,
8539 do_loc);
8540 if (!do_loc)
8541 printf ("\n");
8542 return data;
8543}
eb6bd4d3 8544
eb6bd4d3 8545
5b18a4bc
NC
8546/* Process the contents of a .debug_info section. If do_loc is non-zero
8547 then we are scanning for location lists and we do not want to display
8548 anything to the user. */
eb6bd4d3 8549
5b18a4bc
NC
8550static int
8551process_debug_info (Elf_Internal_Shdr *section, unsigned char *start,
8552 FILE *file, int do_loc)
8553{
8554 unsigned char *end = start + section->sh_size;
8555 unsigned char *section_begin;
8556 unsigned int unit;
8557 unsigned int num_units = 0;
065c959b 8558
0853c092 8559 if ((do_loc || do_debug_loc || do_debug_ranges)
5b18a4bc
NC
8560 && num_debug_info_entries == 0)
8561 {
8562 unsigned long length;
12ab83a9 8563
5b18a4bc
NC
8564 /* First scan the section to get the number of comp units. */
8565 for (section_begin = start, num_units = 0; section_begin < end;
8566 num_units ++)
8567 {
8568 /* Read the first 4 bytes. For a 32-bit DWARF section, this
8569 will be the length. For a 64-bit DWARF section, it'll be
8570 the escape code 0xffffffff followed by an 8 byte length. */
8571 length = byte_get (section_begin, 4);
8572
8573 if (length == 0xffffffff)
8574 {
8575 length = byte_get (section_begin + 4, 8);
8576 section_begin += length + 12;
8577 }
eb6bd4d3 8578 else
5b18a4bc 8579 section_begin += length + 4;
eb6bd4d3 8580 }
12ab83a9 8581
5b18a4bc
NC
8582 if (num_units == 0)
8583 {
8584 error (_("No comp units in .debug_info section ?"));
8585 return 0;
8586 }
8587
8588 /* Then allocate an array to hold the information. */
8589 debug_information = malloc (num_units *
8590 sizeof (* debug_information));
8591 if (debug_information == NULL)
8592 {
8593 error (_("Not enough memory for a debug info array of %u entries"),
8594 num_units);
8595 return 0;
8596 }
252b5132 8597 }
252b5132 8598
5b18a4bc
NC
8599 if (!do_loc)
8600 {
8601 printf (_("The section %s contains:\n\n"),
8602 SECTION_NAME (section));
a2f14207 8603
5b18a4bc
NC
8604 load_debug_str (file);
8605 load_debug_loc (file);
8606 load_debug_range (file);
8607 }
a2f14207 8608
5b18a4bc
NC
8609 for (section_begin = start, unit = 0; start < end; unit++)
8610 {
8611 DWARF2_Internal_CompUnit compunit;
8612 unsigned char *hdrptr;
8613 unsigned char *cu_abbrev_offset_ptr;
8614 unsigned char *tags;
8615 int level;
8616 unsigned long cu_offset;
8617 int offset_size;
8618 int initial_length_size;
a2f14207 8619
5b18a4bc 8620 hdrptr = start;
a2f14207 8621
5b18a4bc
NC
8622 compunit.cu_length = byte_get (hdrptr, 4);
8623 hdrptr += 4;
a2f14207 8624
5b18a4bc
NC
8625 if (compunit.cu_length == 0xffffffff)
8626 {
8627 compunit.cu_length = byte_get (hdrptr, 8);
8628 hdrptr += 8;
8629 offset_size = 8;
8630 initial_length_size = 12;
8631 }
8632 else
8633 {
8634 offset_size = 4;
8635 initial_length_size = 4;
8636 }
a2f14207 8637
5b18a4bc
NC
8638 compunit.cu_version = byte_get (hdrptr, 2);
8639 hdrptr += 2;
8640
8641 cu_offset = start - section_begin;
8642 start += compunit.cu_length + initial_length_size;
a2f14207 8643
5b18a4bc
NC
8644 if (elf_header.e_type == ET_REL
8645 && !debug_apply_rela_addends (file, section, offset_size,
8646 section_begin, hdrptr, start))
8647 return 0;
a2f14207 8648
5b18a4bc
NC
8649 cu_abbrev_offset_ptr = hdrptr;
8650 compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size);
8651 hdrptr += offset_size;
a2f14207 8652
5b18a4bc
NC
8653 compunit.cu_pointer_size = byte_get (hdrptr, 1);
8654 hdrptr += 1;
0853c092 8655 if ((do_loc || do_debug_loc || do_debug_ranges)
5b18a4bc
NC
8656 && num_debug_info_entries == 0)
8657 {
8658 debug_information [unit].cu_offset = cu_offset;
8659 debug_information [unit].pointer_size
8660 = compunit.cu_pointer_size;
b38c7015 8661 debug_information [unit].base_address = 0;
5b18a4bc 8662 debug_information [unit].loc_offsets = NULL;
b38c7015 8663 debug_information [unit].have_frame_base = NULL;
5b18a4bc
NC
8664 debug_information [unit].max_loc_offsets = 0;
8665 debug_information [unit].num_loc_offsets = 0;
0853c092
L
8666 debug_information [unit].range_lists = NULL;
8667 debug_information [unit].max_range_lists= 0;
8668 debug_information [unit].num_range_lists = 0;
5b18a4bc 8669 }
53c7db4b 8670
5b18a4bc 8671 tags = hdrptr;
065c959b 8672
5b18a4bc
NC
8673 if (!do_loc)
8674 {
8675 printf (_(" Compilation Unit @ %lx:\n"), cu_offset);
8676 printf (_(" Length: %ld\n"), compunit.cu_length);
8677 printf (_(" Version: %d\n"), compunit.cu_version);
8678 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
8679 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
8680 }
065c959b 8681
5b18a4bc
NC
8682 if (compunit.cu_version != 2 && compunit.cu_version != 3)
8683 {
8684 warn (_("Only version 2 and 3 DWARF debug information is currently supported.\n"));
8685 continue;
8686 }
d9296b18 8687
5b18a4bc 8688 free_abbrevs ();
065c959b 8689
5b18a4bc
NC
8690 /* Read in the abbrevs used by this compilation unit. */
8691 {
8692 Elf_Internal_Shdr *sec;
8693 unsigned char *begin;
a2f14207 8694
5b18a4bc
NC
8695 /* Locate the .debug_abbrev section and process it. */
8696 sec = find_section (".debug_abbrev");
8697 if (sec == NULL)
8698 {
8699 warn (_("Unable to locate .debug_abbrev section!\n"));
8700 return 0;
8701 }
a2f14207 8702
5b18a4bc
NC
8703 begin = get_data (NULL, file, sec->sh_offset, sec->sh_size,
8704 _("debug_abbrev section data"));
8705 if (!begin)
8706 return 0;
76a56260 8707
5b18a4bc
NC
8708 process_abbrev_section (begin + compunit.cu_abbrev_offset,
8709 begin + sec->sh_size);
8710
8711 free (begin);
8712 }
0e0c4098 8713
5b18a4bc
NC
8714 level = 0;
8715 while (tags < start)
a2f14207 8716 {
5b18a4bc
NC
8717 int bytes_read;
8718 unsigned long abbrev_number;
8719 abbrev_entry *entry;
8720 abbrev_attr *attr;
53c7db4b 8721
5b18a4bc
NC
8722 abbrev_number = read_leb128 (tags, & bytes_read, 0);
8723 tags += bytes_read;
53c7db4b 8724
5b18a4bc
NC
8725 /* A null DIE marks the end of a list of children. */
8726 if (abbrev_number == 0)
8727 {
8728 --level;
8729 continue;
8730 }
8dde85fc 8731
5b18a4bc
NC
8732 /* Scan through the abbreviation list until we reach the
8733 correct entry. */
8734 for (entry = first_abbrev;
8735 entry && entry->entry != abbrev_number;
8736 entry = entry->next)
8737 continue;
53c7db4b 8738
5b18a4bc
NC
8739 if (entry == NULL)
8740 {
8741 warn (_("Unable to locate entry %lu in the abbreviation table\n"),
8742 abbrev_number);
8743 return 0;
8744 }
53c7db4b 8745
5b18a4bc
NC
8746 if (!do_loc)
8747 printf (_(" <%d><%lx>: Abbrev Number: %lu (%s)\n"),
8748 level,
8749 (unsigned long) (tags - section_begin
8750 - bytes_read),
8751 abbrev_number,
8752 get_TAG_name (entry->tag));
8753
b38c7015
L
8754 switch (entry->tag)
8755 {
8756 default:
8757 need_base_address = 0;
8758 break;
8759 case DW_TAG_compile_unit:
8760 need_base_address = 1;
b38c7015
L
8761 break;
8762 case DW_TAG_entry_point:
8763 case DW_TAG_inlined_subroutine:
8764 case DW_TAG_subprogram:
8765 need_base_address = 0;
8766 /* Assuming that there is no DW_AT_frame_base. */
8767 have_frame_base = 0;
8768 break;
8769 }
8770
5b18a4bc
NC
8771 for (attr = entry->first_attr; attr; attr = attr->next)
8772 tags = read_and_display_attr (attr->attribute,
8773 attr->form,
8774 tags, cu_offset,
8775 compunit.cu_pointer_size,
8776 offset_size,
8777 compunit.cu_version,
8778 &debug_information [unit],
8779 do_loc);
8780
8781 if (entry->children)
8782 ++level;
8783 }
8784 }
8785
0853c092
L
8786 /* Set num_debug_info_entries here so that it can be used to check if
8787 we need to proecess .debug_loc and .debug_ranges sections. */
8788 if ((do_loc || do_debug_loc || do_debug_ranges)
5b18a4bc
NC
8789 && num_debug_info_entries == 0)
8790 num_debug_info_entries = num_units;
8791
8792 if (!do_loc)
8793 {
8794 free_debug_range ();
8795 free_debug_str ();
8796 free_debug_loc ();
53c7db4b 8797
a2f14207
DB
8798 printf ("\n");
8799 }
5b18a4bc 8800
a2f14207
DB
8801 return 1;
8802}
252b5132 8803
5b18a4bc
NC
8804/* Retrieve the pointer size associated with the given compilation unit.
8805 Optionally the offset of this unit into the .debug_info section is
8806 also retutned. If there is no .debug_info section then an error
8807 message is issued and 0 is returned. If the requested comp unit has
8808 not been defined in the .debug_info section then a warning message
8809 is issued and the last know pointer size is returned. This message
8810 is only issued once per section dumped per file dumped. */
261a45ad 8811
5b18a4bc
NC
8812static unsigned int
8813get_pointer_size_and_offset_of_comp_unit (unsigned int comp_unit,
8814 const char * section_name,
8815 unsigned long * offset_return)
261a45ad 8816{
5b18a4bc 8817 unsigned long offset = 0;
261a45ad 8818
5b18a4bc
NC
8819 if (num_debug_info_entries == 0)
8820 error (_("%s section needs a populated .debug_info section\n"),
8821 section_name);
261a45ad 8822
5b18a4bc
NC
8823 else if (comp_unit >= num_debug_info_entries)
8824 {
8825 if (!warned_about_missing_comp_units)
8826 {
8827 warn (_("%s section has more comp units than .debug_info section\n"),
8828 section_name);
8829 warn (_("assuming that the pointer size is %d, from the last comp unit in .debug_info\n\n"),
8830 last_pointer_size);
8831 warned_about_missing_comp_units = TRUE;
8832 }
8833 }
8834 else
8835 {
8836 last_pointer_size = debug_information [comp_unit].pointer_size;
8837 offset = debug_information [comp_unit].cu_offset;
8838 }
261a45ad 8839
5b18a4bc
NC
8840 if (offset_return != NULL)
8841 * offset_return = offset;
261a45ad 8842
5b18a4bc 8843 return last_pointer_size;
261a45ad
NC
8844}
8845
5b18a4bc
NC
8846/* Locate and scan the .debug_info section in the file and record the pointer
8847 sizes and offsets for the compilation units in it. Usually an executable
8848 will have just one pointer size, but this is not guaranteed, and so we try
8849 not to make any assumptions. Returns zero upon failure, or the number of
8850 compilation units upon success. */
8851
8852static unsigned int
8853get_debug_info (FILE * file)
261a45ad 8854{
5b18a4bc
NC
8855 Elf_Internal_Shdr * section;
8856 unsigned char * start;
8857 int ret;
261a45ad 8858
5b18a4bc
NC
8859 /* Reset the last pointer size so that we can issue correct error
8860 messages if we are displaying the contents of more than one section. */
8861 last_pointer_size = 0;
8862 warned_about_missing_comp_units = FALSE;
261a45ad 8863
5b18a4bc
NC
8864 /* If we already have the information there is nothing else to do. */
8865 if (num_debug_info_entries > 0)
8866 return num_debug_info_entries;
261a45ad 8867
5b18a4bc
NC
8868 section = find_section (".debug_info");
8869 if (section == NULL)
8870 return 0;
261a45ad 8871
5b18a4bc
NC
8872 start = get_data (NULL, file, section->sh_offset, section->sh_size,
8873 _("extracting information from .debug_info section"));
8874 if (start == NULL)
8875 return 0;
8876
8877 ret = process_debug_info (section, start, file, 1);
8878 free (start);
8879
8880 return ret ? num_debug_info_entries : 0;
261a45ad
NC
8881}
8882
261a45ad 8883static int
5b18a4bc
NC
8884display_debug_lines (Elf_Internal_Shdr *section,
8885 unsigned char *start, FILE *file)
261a45ad 8886{
5b18a4bc
NC
8887 unsigned char *data = start;
8888 unsigned char *end = start + section->sh_size;
8889 unsigned int comp_unit = 0;
261a45ad 8890
5b18a4bc
NC
8891 printf (_("\nDump of debug contents of section %s:\n\n"),
8892 SECTION_NAME (section));
261a45ad 8893
5b18a4bc
NC
8894 get_debug_info (file);
8895
8896 while (data < end)
261a45ad 8897 {
5b18a4bc
NC
8898 DWARF2_Internal_LineInfo info;
8899 unsigned char *standard_opcodes;
8900 unsigned char *end_of_sequence;
8901 unsigned char *hdrptr;
8902 unsigned int pointer_size;
8903 int initial_length_size;
8904 int offset_size;
8905 int i;
8906
8907 hdrptr = data;
8908
8909 /* Check the length of the block. */
8910 info.li_length = byte_get (hdrptr, 4);
8911 hdrptr += 4;
8912
8913 if (info.li_length == 0xffffffff)
8914 {
8915 /* This section is 64-bit DWARF 3. */
8916 info.li_length = byte_get (hdrptr, 8);
8917 hdrptr += 8;
8918 offset_size = 8;
8919 initial_length_size = 12;
8920 }
8921 else
8922 {
8923 offset_size = 4;
8924 initial_length_size = 4;
8925 }
8926
8927 if (info.li_length + initial_length_size > section->sh_size)
8928 {
8929 warn
8930 (_("The line info appears to be corrupt - the section is too small\n"));
8931 return 0;
8932 }
8933
8934 /* Check its version number. */
8935 info.li_version = byte_get (hdrptr, 2);
8936 hdrptr += 2;
8937 if (info.li_version != 2 && info.li_version != 3)
8938 {
8939 warn (_("Only DWARF version 2 and 3 line info is currently supported.\n"));
8940 return 0;
8941 }
8942
8943 info.li_prologue_length = byte_get (hdrptr, offset_size);
8944 hdrptr += offset_size;
8945 info.li_min_insn_length = byte_get (hdrptr, 1);
8946 hdrptr++;
8947 info.li_default_is_stmt = byte_get (hdrptr, 1);
8948 hdrptr++;
8949 info.li_line_base = byte_get (hdrptr, 1);
8950 hdrptr++;
8951 info.li_line_range = byte_get (hdrptr, 1);
8952 hdrptr++;
8953 info.li_opcode_base = byte_get (hdrptr, 1);
8954 hdrptr++;
261a45ad 8955
5b18a4bc
NC
8956 /* Sign extend the line base field. */
8957 info.li_line_base <<= 24;
8958 info.li_line_base >>= 24;
261a45ad 8959
5b18a4bc
NC
8960 /* Get the pointer size from the comp unit associated
8961 with this block of line number information. */
8962 pointer_size = get_pointer_size_and_offset_of_comp_unit
8963 (comp_unit, ".debug_lines", NULL);
8964 comp_unit ++;
261a45ad 8965
5b18a4bc
NC
8966 printf (_(" Length: %ld\n"), info.li_length);
8967 printf (_(" DWARF Version: %d\n"), info.li_version);
8968 printf (_(" Prologue Length: %d\n"), info.li_prologue_length);
8969 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
8970 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
8971 printf (_(" Line Base: %d\n"), info.li_line_base);
8972 printf (_(" Line Range: %d\n"), info.li_line_range);
8973 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
8974 printf (_(" (Pointer size: %u)\n"), pointer_size);
261a45ad 8975
5b18a4bc 8976 end_of_sequence = data + info.li_length + initial_length_size;
261a45ad 8977
5b18a4bc 8978 reset_state_machine (info.li_default_is_stmt);
261a45ad 8979
5b18a4bc
NC
8980 /* Display the contents of the Opcodes table. */
8981 standard_opcodes = hdrptr;
261a45ad 8982
5b18a4bc 8983 printf (_("\n Opcodes:\n"));
261a45ad 8984
5b18a4bc
NC
8985 for (i = 1; i < info.li_opcode_base; i++)
8986 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
261a45ad 8987
5b18a4bc
NC
8988 /* Display the contents of the Directory table. */
8989 data = standard_opcodes + info.li_opcode_base - 1;
261a45ad 8990
5b18a4bc
NC
8991 if (*data == 0)
8992 printf (_("\n The Directory Table is empty.\n"));
8993 else
8994 {
8995 printf (_("\n The Directory Table:\n"));
261a45ad 8996
5b18a4bc
NC
8997 while (*data != 0)
8998 {
8999 printf (_(" %s\n"), data);
18bd398b 9000
5b18a4bc
NC
9001 data += strlen ((char *) data) + 1;
9002 }
9003 }
18bd398b 9004
5b18a4bc
NC
9005 /* Skip the NUL at the end of the table. */
9006 data++;
18bd398b 9007
5b18a4bc
NC
9008 /* Display the contents of the File Name table. */
9009 if (*data == 0)
9010 printf (_("\n The File Name Table is empty.\n"));
9011 else
9012 {
9013 printf (_("\n The File Name Table:\n"));
9014 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
18bd398b 9015
5b18a4bc
NC
9016 while (*data != 0)
9017 {
9018 unsigned char *name;
9019 int bytes_read;
18bd398b 9020
5b18a4bc
NC
9021 printf (_(" %d\t"), ++state_machine_regs.last_file_entry);
9022 name = data;
18bd398b 9023
5b18a4bc 9024 data += strlen ((char *) data) + 1;
18bd398b 9025
5b18a4bc
NC
9026 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
9027 data += bytes_read;
9028 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
9029 data += bytes_read;
9030 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
9031 data += bytes_read;
9032 printf (_("%s\n"), name);
9033 }
9034 }
18bd398b 9035
5b18a4bc
NC
9036 /* Skip the NUL at the end of the table. */
9037 data++;
18bd398b 9038
5b18a4bc
NC
9039 /* Now display the statements. */
9040 printf (_("\n Line Number Statements:\n"));
18bd398b 9041
5b18a4bc
NC
9042 while (data < end_of_sequence)
9043 {
9044 unsigned char op_code;
9045 int adv;
9046 int bytes_read;
18bd398b 9047
5b18a4bc 9048 op_code = *data++;
18bd398b 9049
5b18a4bc
NC
9050 if (op_code >= info.li_opcode_base)
9051 {
9052 op_code -= info.li_opcode_base;
9053 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
9054 state_machine_regs.address += adv;
9055 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
9056 op_code, adv, state_machine_regs.address);
9057 adv = (op_code % info.li_line_range) + info.li_line_base;
9058 state_machine_regs.line += adv;
9059 printf (_(" and Line by %d to %d\n"),
9060 adv, state_machine_regs.line);
9061 }
9062 else switch (op_code)
9063 {
9064 case DW_LNS_extended_op:
9065 data += process_extended_line_op (data, info.li_default_is_stmt,
9066 pointer_size);
9067 break;
18bd398b 9068
5b18a4bc
NC
9069 case DW_LNS_copy:
9070 printf (_(" Copy\n"));
9071 break;
18bd398b 9072
5b18a4bc
NC
9073 case DW_LNS_advance_pc:
9074 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
9075 data += bytes_read;
9076 state_machine_regs.address += adv;
9077 printf (_(" Advance PC by %d to %lx\n"), adv,
9078 state_machine_regs.address);
9079 break;
18bd398b 9080
5b18a4bc
NC
9081 case DW_LNS_advance_line:
9082 adv = read_leb128 (data, & bytes_read, 1);
9083 data += bytes_read;
9084 state_machine_regs.line += adv;
9085 printf (_(" Advance Line by %d to %d\n"), adv,
9086 state_machine_regs.line);
9087 break;
18bd398b 9088
5b18a4bc
NC
9089 case DW_LNS_set_file:
9090 adv = read_leb128 (data, & bytes_read, 0);
9091 data += bytes_read;
9092 printf (_(" Set File Name to entry %d in the File Name Table\n"),
9093 adv);
9094 state_machine_regs.file = adv;
9095 break;
18bd398b 9096
5b18a4bc
NC
9097 case DW_LNS_set_column:
9098 adv = read_leb128 (data, & bytes_read, 0);
9099 data += bytes_read;
9100 printf (_(" Set column to %d\n"), adv);
9101 state_machine_regs.column = adv;
9102 break;
18bd398b 9103
5b18a4bc
NC
9104 case DW_LNS_negate_stmt:
9105 adv = state_machine_regs.is_stmt;
9106 adv = ! adv;
9107 printf (_(" Set is_stmt to %d\n"), adv);
9108 state_machine_regs.is_stmt = adv;
9109 break;
18bd398b 9110
5b18a4bc
NC
9111 case DW_LNS_set_basic_block:
9112 printf (_(" Set basic block\n"));
9113 state_machine_regs.basic_block = 1;
9114 break;
18bd398b 9115
5b18a4bc
NC
9116 case DW_LNS_const_add_pc:
9117 adv = (((255 - info.li_opcode_base) / info.li_line_range)
9118 * info.li_min_insn_length);
9119 state_machine_regs.address += adv;
9120 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
9121 state_machine_regs.address);
9122 break;
18bd398b 9123
5b18a4bc
NC
9124 case DW_LNS_fixed_advance_pc:
9125 adv = byte_get (data, 2);
9126 data += 2;
9127 state_machine_regs.address += adv;
9128 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
9129 adv, state_machine_regs.address);
9130 break;
18bd398b 9131
5b18a4bc
NC
9132 case DW_LNS_set_prologue_end:
9133 printf (_(" Set prologue_end to true\n"));
9134 break;
18bd398b 9135
5b18a4bc
NC
9136 case DW_LNS_set_epilogue_begin:
9137 printf (_(" Set epilogue_begin to true\n"));
9138 break;
18bd398b 9139
5b18a4bc
NC
9140 case DW_LNS_set_isa:
9141 adv = read_leb128 (data, & bytes_read, 0);
9142 data += bytes_read;
9143 printf (_(" Set ISA to %d\n"), adv);
9144 break;
18bd398b 9145
5b18a4bc
NC
9146 default:
9147 printf (_(" Unknown opcode %d with operands: "), op_code);
18bd398b 9148
5b18a4bc
NC
9149 for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
9150 {
9151 printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
9152 i == 1 ? "" : ", ");
9153 data += bytes_read;
9154 }
9155 putchar ('\n');
9156 break;
9157 }
18bd398b 9158 }
5b18a4bc 9159 putchar ('\n');
18bd398b 9160 }
18bd398b 9161
5b18a4bc
NC
9162 return 1;
9163}
18bd398b 9164
5b18a4bc
NC
9165static int
9166display_debug_pubnames (Elf_Internal_Shdr *section,
9167 unsigned char *start,
9168 FILE *file ATTRIBUTE_UNUSED)
252b5132 9169{
5b18a4bc
NC
9170 DWARF2_Internal_PubNames pubnames;
9171 unsigned char *end;
252b5132 9172
5b18a4bc
NC
9173 end = start + section->sh_size;
9174
9175 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
9176
9177 while (start < end)
252b5132 9178 {
5b18a4bc
NC
9179 unsigned char *data;
9180 unsigned long offset;
9181 int offset_size, initial_length_size;
76da6bbe 9182
5b18a4bc
NC
9183 data = start;
9184
9185 pubnames.pn_length = byte_get (data, 4);
9186 data += 4;
9187 if (pubnames.pn_length == 0xffffffff)
ee42cf8c 9188 {
5b18a4bc
NC
9189 pubnames.pn_length = byte_get (data, 8);
9190 data += 8;
9191 offset_size = 8;
9192 initial_length_size = 12;
ee42cf8c
NC
9193 }
9194 else
ba2685cc 9195 {
5b18a4bc
NC
9196 offset_size = 4;
9197 initial_length_size = 4;
ee42cf8c 9198 }
252b5132 9199
5b18a4bc 9200 pubnames.pn_version = byte_get (data, 2);
252b5132 9201 data += 2;
5b18a4bc
NC
9202 pubnames.pn_offset = byte_get (data, offset_size);
9203 data += offset_size;
9204 pubnames.pn_size = byte_get (data, offset_size);
9205 data += offset_size;
252b5132 9206
5b18a4bc 9207 start += pubnames.pn_length + initial_length_size;
252b5132 9208
5b18a4bc
NC
9209 if (pubnames.pn_version != 2 && pubnames.pn_version != 3)
9210 {
9211 static int warned = 0;
252b5132 9212
5b18a4bc
NC
9213 if (! warned)
9214 {
9215 warn (_("Only DWARF 2 and 3 pubnames are currently supported\n"));
9216 warned = 1;
9217 }
252b5132 9218
5b18a4bc
NC
9219 continue;
9220 }
252b5132 9221
5b18a4bc
NC
9222 printf (_(" Length: %ld\n"),
9223 pubnames.pn_length);
9224 printf (_(" Version: %d\n"),
9225 pubnames.pn_version);
9226 printf (_(" Offset into .debug_info section: %ld\n"),
9227 pubnames.pn_offset);
9228 printf (_(" Size of area in .debug_info section: %ld\n"),
9229 pubnames.pn_size);
252b5132 9230
5b18a4bc 9231 printf (_("\n Offset\tName\n"));
ef5cdfc7 9232
5b18a4bc
NC
9233 do
9234 {
9235 offset = byte_get (data, offset_size);
252b5132 9236
5b18a4bc
NC
9237 if (offset != 0)
9238 {
9239 data += offset_size;
9240 printf (" %-6ld\t\t%s\n", offset, data);
9241 data += strlen ((char *) data) + 1;
9242 }
9243 }
9244 while (offset != 0);
252b5132
RH
9245 }
9246
5b18a4bc
NC
9247 printf ("\n");
9248 return 1;
9249}
9250
9251static int
9252display_debug_macinfo (Elf_Internal_Shdr *section,
9253 unsigned char *start,
9254 FILE *file ATTRIBUTE_UNUSED)
9255{
9256 unsigned char *end = start + section->sh_size;
9257 unsigned char *curr = start;
9258 unsigned int bytes_read;
9259 enum dwarf_macinfo_record_type op;
252b5132 9260
5b18a4bc 9261 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
252b5132 9262
5b18a4bc 9263 while (curr < end)
252b5132 9264 {
5b18a4bc
NC
9265 unsigned int lineno;
9266 const char *string;
9267
9268 op = *curr;
9269 curr++;
9270
9271 switch (op)
252b5132 9272 {
5b18a4bc
NC
9273 case DW_MACINFO_start_file:
9274 {
9275 unsigned int filenum;
9276
9277 lineno = read_leb128 (curr, & bytes_read, 0);
9278 curr += bytes_read;
9279 filenum = read_leb128 (curr, & bytes_read, 0);
9280 curr += bytes_read;
9281
9282 printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"),
9283 lineno, filenum);
9284 }
b34976b6 9285 break;
5b18a4bc
NC
9286
9287 case DW_MACINFO_end_file:
9288 printf (_(" DW_MACINFO_end_file\n"));
b34976b6 9289 break;
252b5132 9290
5b18a4bc
NC
9291 case DW_MACINFO_define:
9292 lineno = read_leb128 (curr, & bytes_read, 0);
9293 curr += bytes_read;
9294 string = curr;
9295 curr += strlen (string) + 1;
9296 printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"),
9297 lineno, string);
b34976b6 9298 break;
252b5132 9299
5b18a4bc
NC
9300 case DW_MACINFO_undef:
9301 lineno = read_leb128 (curr, & bytes_read, 0);
9302 curr += bytes_read;
9303 string = curr;
9304 curr += strlen (string) + 1;
9305 printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"),
9306 lineno, string);
252b5132 9307 break;
252b5132 9308
5b18a4bc
NC
9309 case DW_MACINFO_vendor_ext:
9310 {
9311 unsigned int constant;
9312
9313 constant = read_leb128 (curr, & bytes_read, 0);
9314 curr += bytes_read;
9315 string = curr;
9316 curr += strlen (string) + 1;
9317 printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"),
9318 constant, string);
9319 }
b34976b6 9320 break;
252b5132 9321 }
5b18a4bc 9322 }
252b5132 9323
5b18a4bc
NC
9324 return 1;
9325}
252b5132 9326
252b5132 9327
5b18a4bc
NC
9328static int
9329display_debug_abbrev (Elf_Internal_Shdr *section,
9330 unsigned char *start,
9331 FILE *file ATTRIBUTE_UNUSED)
9332{
9333 abbrev_entry *entry;
9334 unsigned char *end = start + section->sh_size;
252b5132 9335
5b18a4bc 9336 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
252b5132 9337
5b18a4bc
NC
9338 do
9339 {
9340 start = process_abbrev_section (start, end);
12ab83a9 9341
5b18a4bc
NC
9342 if (first_abbrev == NULL)
9343 continue;
18bd398b 9344
5b18a4bc 9345 printf (_(" Number TAG\n"));
18bd398b 9346
5b18a4bc
NC
9347 for (entry = first_abbrev; entry; entry = entry->next)
9348 {
9349 abbrev_attr *attr;
18bd398b 9350
5b18a4bc
NC
9351 printf (_(" %ld %s [%s]\n"),
9352 entry->entry,
9353 get_TAG_name (entry->tag),
9354 entry->children ? _("has children") : _("no children"));
252b5132 9355
5b18a4bc
NC
9356 for (attr = entry->first_attr; attr; attr = attr->next)
9357 printf (_(" %-18s %s\n"),
9358 get_AT_name (attr->attribute),
9359 get_FORM_name (attr->form));
9360 }
252b5132 9361
5b18a4bc
NC
9362 free_abbrevs ();
9363 }
9364 while (start);
81766fca 9365
252b5132 9366 printf ("\n");
252b5132 9367
5b18a4bc
NC
9368 return 1;
9369}
d84de024
AM
9370
9371static int
5b18a4bc
NC
9372display_debug_loc (Elf_Internal_Shdr *section,
9373 unsigned char *start, FILE *file)
d84de024 9374{
5b18a4bc
NC
9375 unsigned char *section_end;
9376 unsigned long bytes;
9377 unsigned char *section_begin = start;
5b18a4bc
NC
9378 unsigned int num_loc_list = 0;
9379 unsigned long last_offset = 0;
9380 unsigned int first = 0;
9381 unsigned int i;
9382 unsigned int j;
9383 int seen_first_offset = 0;
9384 int use_debug_info = 1;
9385 unsigned char *next;
d84de024 9386
5b18a4bc
NC
9387 bytes = section->sh_size;
9388 section_end = start + bytes;
d84de024 9389
5b18a4bc 9390 if (bytes == 0)
d84de024 9391 {
5b18a4bc
NC
9392 printf (_("\nThe .debug_loc section is empty.\n"));
9393 return 0;
9394 }
d84de024 9395
5b18a4bc 9396 get_debug_info (file);
d84de024 9397
5b18a4bc
NC
9398 /* Check the order of location list in .debug_info section. If
9399 offsets of location lists are in the ascending order, we can
9400 use `debug_information' directly. */
9401 for (i = 0; i < num_debug_info_entries; i++)
9402 {
9403 unsigned int num;
d84de024 9404
5b18a4bc
NC
9405 num = debug_information [i].num_loc_offsets;
9406 num_loc_list += num;
d84de024 9407
5b18a4bc
NC
9408 /* Check if we can use `debug_information' directly. */
9409 if (use_debug_info && num != 0)
d84de024 9410 {
5b18a4bc 9411 if (!seen_first_offset)
d84de024 9412 {
5b18a4bc
NC
9413 /* This is the first location list. */
9414 last_offset = debug_information [i].loc_offsets [0];
9415 first = i;
9416 seen_first_offset = 1;
9417 j = 1;
d84de024
AM
9418 }
9419 else
5b18a4bc 9420 j = 0;
d84de024 9421
5b18a4bc
NC
9422 for (; j < num; j++)
9423 {
9424 if (last_offset >
9425 debug_information [i].loc_offsets [j])
d84de024 9426 {
5b18a4bc
NC
9427 use_debug_info = 0;
9428 break;
d84de024 9429 }
5b18a4bc 9430 last_offset = debug_information [i].loc_offsets [j];
d84de024 9431 }
d84de024 9432 }
d84de024 9433 }
d84de024 9434
5b18a4bc
NC
9435 if (!use_debug_info)
9436 /* FIXME: Should we handle this case? */
9437 error (_("Location lists in .debug_info section aren't in ascending order!\n"));
252b5132 9438
5b18a4bc
NC
9439 if (!seen_first_offset)
9440 error (_("No location lists in .debug_info section!\n"));
252b5132 9441
5b18a4bc
NC
9442 if (debug_information [first].loc_offsets [0] != 0)
9443 warn (_("Location lists in .debug_loc section start at 0x%lx\n"),
9444 debug_information [first].loc_offsets [0]);
ef5cdfc7 9445
5b18a4bc
NC
9446 printf (_("Contents of the .debug_loc section:\n\n"));
9447 printf (_(" Offset Begin End Expression\n"));
9448
9449 seen_first_offset = 0;
9450 for (i = first; i < num_debug_info_entries; i++)
252b5132 9451 {
5b18a4bc
NC
9452 unsigned long begin;
9453 unsigned long end;
9454 unsigned short length;
9455 unsigned long offset;
9456 unsigned int pointer_size;
b34976b6 9457 unsigned long cu_offset;
b38c7015
L
9458 unsigned long base_address;
9459 int need_frame_base;
9460 int has_frame_base;
252b5132 9461
5b18a4bc
NC
9462 pointer_size = debug_information [i].pointer_size;
9463 cu_offset = debug_information [i].cu_offset;
252b5132 9464
5b18a4bc 9465 for (j = 0; j < debug_information [i].num_loc_offsets; j++)
428409d5 9466 {
b38c7015 9467 has_frame_base = debug_information [i].have_frame_base [j];
5b18a4bc
NC
9468 offset = debug_information [i].loc_offsets [j];
9469 next = section_begin + offset;
b38c7015 9470 base_address = debug_information [i].base_address;
428409d5 9471
5b18a4bc
NC
9472 if (!seen_first_offset)
9473 seen_first_offset = 1;
9474 else
9475 {
9476 if (start < next)
9477 warn (_("There is a hole [0x%lx - 0x%lx] in .debug_loc section.\n"),
b0660586 9478 start - section_begin, next - section_begin);
5b18a4bc
NC
9479 else if (start > next)
9480 warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_loc section.\n"),
b0660586 9481 start - section_begin, next - section_begin);
5b18a4bc
NC
9482 }
9483 start = next;
ee42cf8c 9484
5b18a4bc
NC
9485 while (1)
9486 {
9487 begin = byte_get (start, pointer_size);
9488 start += pointer_size;
9489 end = byte_get (start, pointer_size);
9490 start += pointer_size;
c0e047e0 9491
5b18a4bc 9492 if (begin == 0 && end == 0)
904c75ac
L
9493 {
9494 printf (_(" %8.8lx <End of list>\n"), offset);
9495 break;
9496 }
c0e047e0 9497
b38c7015
L
9498 /* Check base address specifiers. */
9499 if (begin == -1UL && end != -1UL)
9500 {
9501 base_address = end;
e54b12b7
L
9502 printf (" %8.8lx %8.8lx %8.8lx (base address)\n",
9503 offset, begin, end);
b38c7015
L
9504 continue;
9505 }
adab8cdc 9506
5b18a4bc
NC
9507 length = byte_get (start, 2);
9508 start += 2;
252b5132 9509
5b18a4bc 9510 printf (" %8.8lx %8.8lx %8.8lx (",
b38c7015
L
9511 offset, begin + base_address, end + base_address);
9512 need_frame_base = decode_location_expression (start,
9513 pointer_size,
9514 length,
9515 cu_offset);
9516 putchar (')');
09fd7e38 9517
b38c7015
L
9518 if (need_frame_base && !has_frame_base)
9519 printf (_(" [without DW_AT_frame_base]"));
9520
9521 if (begin == end)
9522 fputs (_(" (start == end)"), stdout);
9523 else if (begin > end)
9524 fputs (_(" (start > end)"), stdout);
9525
9526 putchar ('\n');
252b5132 9527
5b18a4bc
NC
9528 start += length;
9529 }
5b18a4bc
NC
9530 }
9531 }
9532 return 1;
9533}
252b5132 9534
5b18a4bc
NC
9535static int
9536display_debug_str (Elf_Internal_Shdr *section,
9537 unsigned char *start,
9538 FILE *file ATTRIBUTE_UNUSED)
9539{
9540 unsigned long bytes;
9541 bfd_vma addr;
252b5132 9542
5b18a4bc
NC
9543 addr = section->sh_addr;
9544 bytes = section->sh_size;
252b5132 9545
5b18a4bc
NC
9546 if (bytes == 0)
9547 {
9548 printf (_("\nThe .debug_str section is empty.\n"));
9549 return 0;
9550 }
252b5132 9551
5b18a4bc 9552 printf (_("Contents of the .debug_str section:\n\n"));
252b5132 9553
5b18a4bc
NC
9554 while (bytes)
9555 {
9556 int j;
9557 int k;
9558 int lbytes;
252b5132 9559
5b18a4bc 9560 lbytes = (bytes > 16 ? 16 : bytes);
252b5132 9561
5b18a4bc 9562 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132 9563
5b18a4bc
NC
9564 for (j = 0; j < 16; j++)
9565 {
9566 if (j < lbytes)
9567 printf ("%2.2x", start[j]);
9568 else
9569 printf (" ");
252b5132 9570
5b18a4bc
NC
9571 if ((j & 3) == 3)
9572 printf (" ");
9573 }
252b5132 9574
5b18a4bc
NC
9575 for (j = 0; j < lbytes; j++)
9576 {
9577 k = start[j];
9578 if (k >= ' ' && k < 0x80)
9579 printf ("%c", k);
9580 else
9581 printf (".");
9582 }
252b5132 9583
5b18a4bc 9584 putchar ('\n');
252b5132 9585
5b18a4bc
NC
9586 start += lbytes;
9587 addr += lbytes;
9588 bytes -= lbytes;
252b5132
RH
9589 }
9590
b0660586
L
9591 putchar ('\n');
9592
5b18a4bc
NC
9593 return 1;
9594}
ef5cdfc7 9595
252b5132 9596
5b18a4bc
NC
9597static int
9598display_debug_info (Elf_Internal_Shdr * section,
9599 unsigned char * start, FILE * file)
9600{
9601 return process_debug_info (section, start, file, 0);
252b5132
RH
9602}
9603
5b18a4bc 9604
252b5132 9605static int
d3ba0551
AM
9606display_debug_aranges (Elf_Internal_Shdr *section,
9607 unsigned char *start,
9608 FILE *file ATTRIBUTE_UNUSED)
252b5132 9609{
b34976b6 9610 unsigned char *end = start + section->sh_size;
252b5132
RH
9611
9612 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
9613
9614 while (start < end)
9615 {
ee42cf8c 9616 unsigned char *hdrptr;
b34976b6
AM
9617 DWARF2_Internal_ARange arange;
9618 unsigned char *ranges;
9619 unsigned long length;
9620 unsigned long address;
9621 int excess;
ee42cf8c
NC
9622 int offset_size;
9623 int initial_length_size;
252b5132 9624
ee42cf8c 9625 hdrptr = start;
252b5132 9626
ee42cf8c
NC
9627 arange.ar_length = byte_get (hdrptr, 4);
9628 hdrptr += 4;
252b5132 9629
e414a165
NC
9630 if (arange.ar_length == 0xffffffff)
9631 {
ee42cf8c
NC
9632 arange.ar_length = byte_get (hdrptr, 8);
9633 hdrptr += 8;
9634 offset_size = 8;
9635 initial_length_size = 12;
9636 }
9637 else
ba2685cc 9638 {
ee42cf8c
NC
9639 offset_size = 4;
9640 initial_length_size = 4;
e414a165
NC
9641 }
9642
ee42cf8c
NC
9643 arange.ar_version = byte_get (hdrptr, 2);
9644 hdrptr += 2;
9645
9646 arange.ar_info_offset = byte_get (hdrptr, offset_size);
9647 hdrptr += offset_size;
9648
9649 arange.ar_pointer_size = byte_get (hdrptr, 1);
9650 hdrptr += 1;
9651
9652 arange.ar_segment_size = byte_get (hdrptr, 1);
9653 hdrptr += 1;
9654
9655 if (arange.ar_version != 2 && arange.ar_version != 3)
3f215a10 9656 {
ee42cf8c 9657 warn (_("Only DWARF 2 and 3 aranges are currently supported.\n"));
3f215a10
NC
9658 break;
9659 }
9660
252b5132
RH
9661 printf (_(" Length: %ld\n"), arange.ar_length);
9662 printf (_(" Version: %d\n"), arange.ar_version);
9663 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
9664 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
9665 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
9666
9667 printf (_("\n Address Length\n"));
9668
ee42cf8c 9669 ranges = hdrptr;
252b5132 9670
7a4b7442 9671 /* Must pad to an alignment boundary that is twice the pointer size. */
ee42cf8c 9672 excess = (hdrptr - start) % (2 * arange.ar_pointer_size);
7a4b7442
NC
9673 if (excess)
9674 ranges += (2 * arange.ar_pointer_size) - excess;
9675
252b5132
RH
9676 for (;;)
9677 {
9678 address = byte_get (ranges, arange.ar_pointer_size);
9679
252b5132
RH
9680 ranges += arange.ar_pointer_size;
9681
9682 length = byte_get (ranges, arange.ar_pointer_size);
9683
9684 ranges += arange.ar_pointer_size;
9685
7a4b7442
NC
9686 /* A pair of zeros marks the end of the list. */
9687 if (address == 0 && length == 0)
9688 break;
103f02d3 9689
252b5132
RH
9690 printf (" %8.8lx %lu\n", address, length);
9691 }
9692
ee42cf8c 9693 start += arange.ar_length + initial_length_size;
252b5132
RH
9694 }
9695
9696 printf ("\n");
9697
9698 return 1;
9699}
9700
18bd398b 9701static int
0853c092
L
9702display_debug_ranges (Elf_Internal_Shdr *section,
9703 unsigned char *start,
9704 FILE *file ATTRIBUTE_UNUSED)
18bd398b 9705{
0853c092
L
9706 unsigned char *section_end;
9707 unsigned long bytes;
9708 unsigned char *section_begin = start;
9709 unsigned int num_range_list = 0;
9710 unsigned long last_offset = 0;
9711 unsigned int first = 0;
9712 unsigned int i;
9713 unsigned int j;
9714 int seen_first_offset = 0;
9715 int use_debug_info = 1;
9716 unsigned char *next;
18bd398b 9717
0853c092
L
9718 bytes = section->sh_size;
9719 section_end = start + bytes;
9720
9721 if (bytes == 0)
18bd398b 9722 {
0853c092
L
9723 printf (_("\nThe .debug_ranges section is empty.\n"));
9724 return 0;
9725 }
18bd398b 9726
0853c092 9727 get_debug_info (file);
18bd398b 9728
0853c092
L
9729 /* Check the order of range list in .debug_info section. If
9730 offsets of range lists are in the ascending order, we can
9731 use `debug_information' directly. */
9732 for (i = 0; i < num_debug_info_entries; i++)
9733 {
9734 unsigned int num;
9735
9736 num = debug_information [i].num_range_lists;
9737 num_range_list += num;
9738
9739 /* Check if we can use `debug_information' directly. */
9740 if (use_debug_info && num != 0)
18bd398b 9741 {
0853c092
L
9742 if (!seen_first_offset)
9743 {
9744 /* This is the first range list. */
9745 last_offset = debug_information [i].range_lists [0];
9746 first = i;
9747 seen_first_offset = 1;
9748 j = 1;
9749 }
9750 else
9751 j = 0;
18bd398b 9752
0853c092
L
9753 for (; j < num; j++)
9754 {
9755 if (last_offset >
9756 debug_information [i].range_lists [j])
9757 {
9758 use_debug_info = 0;
9759 break;
9760 }
9761 last_offset = debug_information [i].range_lists [j];
9762 }
9763 }
18bd398b
NC
9764 }
9765
0853c092
L
9766 if (!use_debug_info)
9767 /* FIXME: Should we handle this case? */
9768 error (_("Range lists in .debug_info section aren't in ascending order!\n"));
18bd398b 9769
0853c092
L
9770 if (!seen_first_offset)
9771 error (_("No range lists in .debug_info section!\n"));
18bd398b 9772
0853c092
L
9773 if (debug_information [first].range_lists [0] != 0)
9774 warn (_("Range lists in .debug_ranges section start at 0x%lx\n"),
9775 debug_information [first].range_lists [0]);
18bd398b 9776
0853c092
L
9777 printf (_("Contents of the .debug_ranges section:\n\n"));
9778 printf (_(" Offset Begin End\n"));
9779
9780 seen_first_offset = 0;
9781 for (i = first; i < num_debug_info_entries; i++)
18bd398b 9782 {
0853c092
L
9783 unsigned long begin;
9784 unsigned long end;
9785 unsigned long offset;
9786 unsigned int pointer_size;
9787 unsigned long base_address;
18bd398b 9788
0853c092 9789 pointer_size = debug_information [i].pointer_size;
18bd398b 9790
0853c092 9791 for (j = 0; j < debug_information [i].num_range_lists; j++)
18bd398b 9792 {
0853c092
L
9793 offset = debug_information [i].range_lists [j];
9794 next = section_begin + offset;
9795 base_address = debug_information [i].base_address;
18bd398b 9796
0853c092
L
9797 if (!seen_first_offset)
9798 seen_first_offset = 1;
9799 else
9800 {
9801 if (start < next)
9802 warn (_("There is a hole [0x%lx - 0x%lx] in .debug_ranges section.\n"),
9803 start - section_begin, next - section_begin);
9804 else if (start > next)
9805 warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_ranges section.\n"),
9806 start - section_begin, next - section_begin);
9807 }
9808 start = next;
9809
9810 while (1)
9811 {
9812 begin = byte_get (start, pointer_size);
9813 start += pointer_size;
9814 end = byte_get (start, pointer_size);
9815 start += pointer_size;
9816
9817 if (begin == 0 && end == 0)
9818 break;
9819
9820 /* Check base address specifiers. */
9821 if (begin == -1UL && end != -1UL)
9822 {
9823 base_address = end;
9824 printf (" %8.8lx %8.8lx %8.8lx (base address)\n",
9825 offset, begin, end);
9826 continue;
9827 }
9828
9829 printf (" %8.8lx %8.8lx %8.8lx",
9830 offset, begin + base_address, end + base_address);
9831
9832 if (begin == end)
9833 fputs (_(" (start == end)"), stdout);
9834 else if (begin > end)
9835 fputs (_(" (start > end)"), stdout);
18bd398b 9836
0853c092
L
9837 putchar ('\n');
9838 }
9839 fputs (_(" <End of list>\n"), stdout);
9840 }
9841 }
9842 putchar ('\n');
18bd398b
NC
9843 return 1;
9844}
9845
c47d488e
DD
9846typedef struct Frame_Chunk
9847{
b34976b6
AM
9848 struct Frame_Chunk *next;
9849 unsigned char *chunk_start;
9850 int ncols;
a98cc2b2 9851 /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */
b34976b6
AM
9852 short int *col_type;
9853 int *col_offset;
9854 char *augmentation;
9855 unsigned int code_factor;
9856 int data_factor;
9857 unsigned long pc_begin;
9858 unsigned long pc_range;
9859 int cfa_reg;
9860 int cfa_offset;
9861 int ra;
9862 unsigned char fde_encoding;
63044634 9863 unsigned char cfa_exp;
c47d488e
DD
9864}
9865Frame_Chunk;
9866
a98cc2b2
AH
9867/* A marker for a col_type that means this column was never referenced
9868 in the frame info. */
9869#define DW_CFA_unreferenced (-1)
9870
c47d488e 9871static void
d3ba0551 9872frame_need_space (Frame_Chunk *fc, int reg)
c47d488e
DD
9873{
9874 int prev = fc->ncols;
9875
9876 if (reg < fc->ncols)
9877 return;
584da044 9878
c47d488e 9879 fc->ncols = reg + 1;
d3ba0551
AM
9880 fc->col_type = xrealloc (fc->col_type, fc->ncols * sizeof (short int));
9881 fc->col_offset = xrealloc (fc->col_offset, fc->ncols * sizeof (int));
c47d488e
DD
9882
9883 while (prev < fc->ncols)
9884 {
a98cc2b2 9885 fc->col_type[prev] = DW_CFA_unreferenced;
c47d488e
DD
9886 fc->col_offset[prev] = 0;
9887 prev++;
9888 }
9889}
9890
9891static void
d3ba0551 9892frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
c47d488e
DD
9893{
9894 int r;
9895 char tmp[100];
9896
b34976b6
AM
9897 if (*max_regs < fc->ncols)
9898 *max_regs = fc->ncols;
584da044 9899
b34976b6 9900 if (*need_col_headers)
c47d488e 9901 {
b34976b6 9902 *need_col_headers = 0;
584da044 9903
c47d488e 9904 printf (" LOC CFA ");
584da044 9905
b34976b6 9906 for (r = 0; r < *max_regs; r++)
a98cc2b2
AH
9907 if (fc->col_type[r] != DW_CFA_unreferenced)
9908 {
9909 if (r == fc->ra)
9910 printf ("ra ");
9911 else
9912 printf ("r%-4d", r);
9913 }
584da044 9914
c47d488e
DD
9915 printf ("\n");
9916 }
584da044 9917
31b6fca6 9918 printf ("%08lx ", fc->pc_begin);
63044634
RH
9919 if (fc->cfa_exp)
9920 strcpy (tmp, "exp");
9921 else
9922 sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
c47d488e 9923 printf ("%-8s ", tmp);
584da044
NC
9924
9925 for (r = 0; r < fc->ncols; r++)
c47d488e 9926 {
a98cc2b2 9927 if (fc->col_type[r] != DW_CFA_unreferenced)
c47d488e 9928 {
a98cc2b2
AH
9929 switch (fc->col_type[r])
9930 {
9931 case DW_CFA_undefined:
9932 strcpy (tmp, "u");
9933 break;
9934 case DW_CFA_same_value:
9935 strcpy (tmp, "s");
9936 break;
9937 case DW_CFA_offset:
9938 sprintf (tmp, "c%+d", fc->col_offset[r]);
9939 break;
9940 case DW_CFA_register:
9941 sprintf (tmp, "r%d", fc->col_offset[r]);
9942 break;
63044634
RH
9943 case DW_CFA_expression:
9944 strcpy (tmp, "exp");
9945 break;
a98cc2b2
AH
9946 default:
9947 strcpy (tmp, "n/a");
9948 break;
9949 }
9950 printf ("%-5s", tmp);
c47d488e 9951 }
c47d488e
DD
9952 }
9953 printf ("\n");
9954}
9955
31b6fca6 9956static int
d3ba0551 9957size_of_encoded_value (int encoding)
31b6fca6
RH
9958{
9959 switch (encoding & 0x7)
9960 {
9961 default: /* ??? */
89fac5e3 9962 case 0: return eh_addr_size;
31b6fca6
RH
9963 case 2: return 2;
9964 case 3: return 4;
9965 case 4: return 8;
9966 }
9967}
9968
38fafa6d 9969static bfd_vma
d3ba0551 9970get_encoded_value (unsigned char *data, int encoding)
38fafa6d
RH
9971{
9972 int size = size_of_encoded_value (encoding);
9973 if (encoding & DW_EH_PE_signed)
9974 return byte_get_signed (data, size);
9975 else
9976 return byte_get (data, size);
9977}
9978
c47d488e 9979#define GET(N) byte_get (start, N); start += N
584da044
NC
9980#define LEB() read_leb128 (start, & length_return, 0); start += length_return
9981#define SLEB() read_leb128 (start, & length_return, 1); start += length_return
c47d488e
DD
9982
9983static int
d3ba0551
AM
9984display_debug_frames (Elf_Internal_Shdr *section,
9985 unsigned char *start,
9986 FILE *file ATTRIBUTE_UNUSED)
c47d488e 9987{
b34976b6
AM
9988 unsigned char *end = start + section->sh_size;
9989 unsigned char *section_start = start;
9990 Frame_Chunk *chunks = 0;
9991 Frame_Chunk *remembered_state = 0;
9992 Frame_Chunk *rs;
18bd398b 9993 int is_eh = streq (SECTION_NAME (section), ".eh_frame");
b34976b6
AM
9994 int length_return;
9995 int max_regs = 0;
c47d488e
DD
9996
9997 printf (_("The section %s contains:\n"), SECTION_NAME (section));
9998
9999 while (start < end)
10000 {
b34976b6
AM
10001 unsigned char *saved_start;
10002 unsigned char *block_end;
10003 unsigned long length;
10004 unsigned long cie_id;
10005 Frame_Chunk *fc;
10006 Frame_Chunk *cie;
10007 int need_col_headers = 1;
10008 unsigned char *augmentation_data = NULL;
10009 unsigned long augmentation_data_len = 0;
89fac5e3 10010 int encoded_ptr_size = eh_addr_size;
ee42cf8c
NC
10011 int offset_size;
10012 int initial_length_size;
c47d488e
DD
10013
10014 saved_start = start;
10015 length = byte_get (start, 4); start += 4;
10016
10017 if (length == 0)
f1ef08cb
AM
10018 {
10019 printf ("\n%08lx ZERO terminator\n\n",
10020 (unsigned long)(saved_start - section_start));
10021 return 1;
10022 }
c47d488e 10023
428409d5
NC
10024 if (length == 0xffffffff)
10025 {
ee42cf8c
NC
10026 length = byte_get (start, 8);
10027 start += 8;
10028 offset_size = 8;
10029 initial_length_size = 12;
10030 }
10031 else
10032 {
10033 offset_size = 4;
10034 initial_length_size = 4;
428409d5
NC
10035 }
10036
ee42cf8c
NC
10037 block_end = saved_start + length + initial_length_size;
10038 cie_id = byte_get (start, offset_size); start += offset_size;
c47d488e 10039
d84de024
AM
10040 if (elf_header.e_type == ET_REL
10041 && !debug_apply_rela_addends (file, section, offset_size,
10042 section_start, start, block_end))
10043 return 0;
10044
c47d488e
DD
10045 if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
10046 {
31b6fca6
RH
10047 int version;
10048
d3ba0551 10049 fc = xmalloc (sizeof (Frame_Chunk));
c47d488e
DD
10050 memset (fc, 0, sizeof (Frame_Chunk));
10051
10052 fc->next = chunks;
10053 chunks = fc;
10054 fc->chunk_start = saved_start;
10055 fc->ncols = 0;
d3ba0551
AM
10056 fc->col_type = xmalloc (sizeof (short int));
10057 fc->col_offset = xmalloc (sizeof (int));
c47d488e
DD
10058 frame_need_space (fc, max_regs-1);
10059
31b6fca6 10060 version = *start++;
584da044 10061
31b6fca6
RH
10062 fc->augmentation = start;
10063 start = strchr (start, '\0') + 1;
584da044 10064
c47d488e
DD
10065 if (fc->augmentation[0] == 'z')
10066 {
c47d488e
DD
10067 fc->code_factor = LEB ();
10068 fc->data_factor = SLEB ();
0da76f83
NC
10069 if (version == 1)
10070 {
10071 fc->ra = GET (1);
10072 }
10073 else
10074 {
10075 fc->ra = LEB ();
10076 }
31b6fca6
RH
10077 augmentation_data_len = LEB ();
10078 augmentation_data = start;
10079 start += augmentation_data_len;
c47d488e 10080 }
18bd398b 10081 else if (streq (fc->augmentation, "eh"))
c47d488e 10082 {
89fac5e3 10083 start += eh_addr_size;
c47d488e
DD
10084 fc->code_factor = LEB ();
10085 fc->data_factor = SLEB ();
0da76f83
NC
10086 if (version == 1)
10087 {
10088 fc->ra = GET (1);
10089 }
10090 else
10091 {
10092 fc->ra = LEB ();
10093 }
c47d488e
DD
10094 }
10095 else
10096 {
10097 fc->code_factor = LEB ();
10098 fc->data_factor = SLEB ();
0da76f83
NC
10099 if (version == 1)
10100 {
10101 fc->ra = GET (1);
10102 }
10103 else
10104 {
10105 fc->ra = LEB ();
10106 }
c47d488e
DD
10107 }
10108 cie = fc;
31b6fca6
RH
10109
10110 if (do_debug_frames_interp)
10111 printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
7036c0e1 10112 (unsigned long)(saved_start - section_start), length, cie_id,
31b6fca6
RH
10113 fc->augmentation, fc->code_factor, fc->data_factor,
10114 fc->ra);
10115 else
10116 {
10117 printf ("\n%08lx %08lx %08lx CIE\n",
7036c0e1 10118 (unsigned long)(saved_start - section_start), length, cie_id);
31b6fca6
RH
10119 printf (" Version: %d\n", version);
10120 printf (" Augmentation: \"%s\"\n", fc->augmentation);
10121 printf (" Code alignment factor: %u\n", fc->code_factor);
10122 printf (" Data alignment factor: %d\n", fc->data_factor);
10123 printf (" Return address column: %d\n", fc->ra);
10124
10125 if (augmentation_data_len)
10126 {
10127 unsigned long i;
10128 printf (" Augmentation data: ");
10129 for (i = 0; i < augmentation_data_len; ++i)
10130 printf (" %02x", augmentation_data[i]);
10131 putchar ('\n');
10132 }
10133 putchar ('\n');
10134 }
10135
10136 if (augmentation_data_len)
10137 {
10138 unsigned char *p, *q;
10139 p = fc->augmentation + 1;
10140 q = augmentation_data;
10141
10142 while (1)
10143 {
10144 if (*p == 'L')
7036c0e1 10145 q++;
31b6fca6
RH
10146 else if (*p == 'P')
10147 q += 1 + size_of_encoded_value (*q);
10148 else if (*p == 'R')
10149 fc->fde_encoding = *q++;
10150 else
10151 break;
10152 p++;
10153 }
10154
10155 if (fc->fde_encoding)
10156 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
10157 }
c47d488e
DD
10158
10159 frame_need_space (fc, fc->ra);
10160 }
10161 else
10162 {
b34976b6 10163 unsigned char *look_for;
c47d488e 10164 static Frame_Chunk fde_fc;
584da044
NC
10165
10166 fc = & fde_fc;
c47d488e
DD
10167 memset (fc, 0, sizeof (Frame_Chunk));
10168
31b6fca6 10169 look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
c47d488e 10170
428409d5 10171 for (cie = chunks; cie ; cie = cie->next)
31b6fca6
RH
10172 if (cie->chunk_start == look_for)
10173 break;
c47d488e 10174
c47d488e
DD
10175 if (!cie)
10176 {
31b6fca6
RH
10177 warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
10178 cie_id, saved_start);
c47d488e
DD
10179 start = block_end;
10180 fc->ncols = 0;
d3ba0551
AM
10181 fc->col_type = xmalloc (sizeof (short int));
10182 fc->col_offset = xmalloc (sizeof (int));
584da044 10183 frame_need_space (fc, max_regs - 1);
c47d488e
DD
10184 cie = fc;
10185 fc->augmentation = "";
31b6fca6 10186 fc->fde_encoding = 0;
c47d488e
DD
10187 }
10188 else
10189 {
10190 fc->ncols = cie->ncols;
d3ba0551
AM
10191 fc->col_type = xmalloc (fc->ncols * sizeof (short int));
10192 fc->col_offset = xmalloc (fc->ncols * sizeof (int));
a98cc2b2 10193 memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
c47d488e
DD
10194 memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
10195 fc->augmentation = cie->augmentation;
10196 fc->code_factor = cie->code_factor;
10197 fc->data_factor = cie->data_factor;
10198 fc->cfa_reg = cie->cfa_reg;
10199 fc->cfa_offset = cie->cfa_offset;
10200 fc->ra = cie->ra;
10201 frame_need_space (fc, max_regs-1);
31b6fca6 10202 fc->fde_encoding = cie->fde_encoding;
c47d488e
DD
10203 }
10204
31b6fca6
RH
10205 if (fc->fde_encoding)
10206 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
10207
38fafa6d 10208 fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
d84de024
AM
10209 if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
10210 /* Don't adjust for ET_REL since there's invariably a pcrel
10211 reloc here, which we haven't applied. */
10212 && elf_header.e_type != ET_REL)
f1ef08cb 10213 fc->pc_begin += section->sh_addr + (start - section_start);
31b6fca6
RH
10214 start += encoded_ptr_size;
10215 fc->pc_range = byte_get (start, encoded_ptr_size);
10216 start += encoded_ptr_size;
10217
c47d488e
DD
10218 if (cie->augmentation[0] == 'z')
10219 {
31b6fca6
RH
10220 augmentation_data_len = LEB ();
10221 augmentation_data = start;
10222 start += augmentation_data_len;
c47d488e
DD
10223 }
10224
410f7a12 10225 printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
7036c0e1 10226 (unsigned long)(saved_start - section_start), length, cie_id,
410f7a12
L
10227 (unsigned long)(cie->chunk_start - section_start),
10228 fc->pc_begin, fc->pc_begin + fc->pc_range);
31b6fca6
RH
10229 if (! do_debug_frames_interp && augmentation_data_len)
10230 {
10231 unsigned long i;
5b18a4bc 10232
31b6fca6
RH
10233 printf (" Augmentation data: ");
10234 for (i = 0; i < augmentation_data_len; ++i)
ba2685cc 10235 printf (" %02x", augmentation_data[i]);
31b6fca6
RH
10236 putchar ('\n');
10237 putchar ('\n');
10238 }
c47d488e
DD
10239 }
10240
18bd398b
NC
10241 /* At this point, fc is the current chunk, cie (if any) is set, and
10242 we're about to interpret instructions for the chunk. */
38fafa6d
RH
10243 /* ??? At present we need to do this always, since this sizes the
10244 fc->col_type and fc->col_offset arrays, which we write into always.
10245 We should probably split the interpreted and non-interpreted bits
10246 into two different routines, since there's so much that doesn't
10247 really overlap between them. */
10248 if (1 || do_debug_frames_interp)
53c7db4b
KH
10249 {
10250 /* Start by making a pass over the chunk, allocating storage
10251 and taking note of what registers are used. */
b34976b6 10252 unsigned char *tmp = start;
a98cc2b2 10253
53c7db4b
KH
10254 while (start < block_end)
10255 {
10256 unsigned op, opa;
63044634 10257 unsigned long reg, tmp;
7036c0e1 10258
b34976b6 10259 op = *start++;
53c7db4b
KH
10260 opa = op & 0x3f;
10261 if (op & 0xc0)
10262 op &= 0xc0;
7036c0e1 10263
53c7db4b 10264 /* Warning: if you add any more cases to this switch, be
ba2685cc 10265 sure to add them to the corresponding switch below. */
53c7db4b
KH
10266 switch (op)
10267 {
10268 case DW_CFA_advance_loc:
10269 break;
10270 case DW_CFA_offset:
10271 LEB ();
10272 frame_need_space (fc, opa);
10273 fc->col_type[opa] = DW_CFA_undefined;
10274 break;
10275 case DW_CFA_restore:
10276 frame_need_space (fc, opa);
10277 fc->col_type[opa] = DW_CFA_undefined;
10278 break;
10279 case DW_CFA_set_loc:
10280 start += encoded_ptr_size;
10281 break;
10282 case DW_CFA_advance_loc1:
10283 start += 1;
10284 break;
10285 case DW_CFA_advance_loc2:
10286 start += 2;
10287 break;
10288 case DW_CFA_advance_loc4:
10289 start += 4;
10290 break;
10291 case DW_CFA_offset_extended:
10292 reg = LEB (); LEB ();
10293 frame_need_space (fc, reg);
10294 fc->col_type[reg] = DW_CFA_undefined;
10295 break;
10296 case DW_CFA_restore_extended:
10297 reg = LEB ();
10298 frame_need_space (fc, reg);
10299 fc->col_type[reg] = DW_CFA_undefined;
10300 break;
10301 case DW_CFA_undefined:
10302 reg = LEB ();
10303 frame_need_space (fc, reg);
10304 fc->col_type[reg] = DW_CFA_undefined;
10305 break;
10306 case DW_CFA_same_value:
10307 reg = LEB ();
10308 frame_need_space (fc, reg);
10309 fc->col_type[reg] = DW_CFA_undefined;
10310 break;
10311 case DW_CFA_register:
10312 reg = LEB (); LEB ();
10313 frame_need_space (fc, reg);
10314 fc->col_type[reg] = DW_CFA_undefined;
10315 break;
10316 case DW_CFA_def_cfa:
10317 LEB (); LEB ();
10318 break;
10319 case DW_CFA_def_cfa_register:
10320 LEB ();
10321 break;
10322 case DW_CFA_def_cfa_offset:
10323 LEB ();
10324 break;
63044634
RH
10325 case DW_CFA_def_cfa_expression:
10326 tmp = LEB ();
10327 start += tmp;
10328 break;
10329 case DW_CFA_expression:
10330 reg = LEB ();
10331 tmp = LEB ();
10332 start += tmp;
10333 frame_need_space (fc, reg);
10334 fc->col_type[reg] = DW_CFA_undefined;
10335 break;
91a106e6
L
10336 case DW_CFA_offset_extended_sf:
10337 reg = LEB (); SLEB ();
10338 frame_need_space (fc, reg);
10339 fc->col_type[reg] = DW_CFA_undefined;
10340 break;
10341 case DW_CFA_def_cfa_sf:
10342 LEB (); SLEB ();
10343 break;
10344 case DW_CFA_def_cfa_offset_sf:
10345 SLEB ();
10346 break;
63044634
RH
10347 case DW_CFA_MIPS_advance_loc8:
10348 start += 8;
10349 break;
53c7db4b
KH
10350 case DW_CFA_GNU_args_size:
10351 LEB ();
10352 break;
53c7db4b
KH
10353 case DW_CFA_GNU_negative_offset_extended:
10354 reg = LEB (); LEB ();
10355 frame_need_space (fc, reg);
10356 fc->col_type[reg] = DW_CFA_undefined;
7036c0e1 10357
53c7db4b
KH
10358 default:
10359 break;
10360 }
10361 }
10362 start = tmp;
10363 }
a98cc2b2
AH
10364
10365 /* Now we know what registers are used, make a second pass over
ba2685cc 10366 the chunk, this time actually printing out the info. */
a98cc2b2 10367
c47d488e
DD
10368 while (start < block_end)
10369 {
10370 unsigned op, opa;
10371 unsigned long ul, reg, roffs;
10372 long l, ofs;
10373 bfd_vma vma;
10374
b34976b6 10375 op = *start++;
c47d488e
DD
10376 opa = op & 0x3f;
10377 if (op & 0xc0)
10378 op &= 0xc0;
10379
53c7db4b
KH
10380 /* Warning: if you add any more cases to this switch, be
10381 sure to add them to the corresponding switch above. */
c47d488e
DD
10382 switch (op)
10383 {
10384 case DW_CFA_advance_loc:
31b6fca6 10385 if (do_debug_frames_interp)
53c7db4b 10386 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 10387 else
53c7db4b
KH
10388 printf (" DW_CFA_advance_loc: %d to %08lx\n",
10389 opa * fc->code_factor,
31b6fca6 10390 fc->pc_begin + opa * fc->code_factor);
c47d488e
DD
10391 fc->pc_begin += opa * fc->code_factor;
10392 break;
10393
10394 case DW_CFA_offset:
c47d488e 10395 roffs = LEB ();
31b6fca6 10396 if (! do_debug_frames_interp)
53c7db4b 10397 printf (" DW_CFA_offset: r%d at cfa%+ld\n",
31b6fca6 10398 opa, roffs * fc->data_factor);
c47d488e
DD
10399 fc->col_type[opa] = DW_CFA_offset;
10400 fc->col_offset[opa] = roffs * fc->data_factor;
10401 break;
10402
10403 case DW_CFA_restore:
31b6fca6 10404 if (! do_debug_frames_interp)
53c7db4b 10405 printf (" DW_CFA_restore: r%d\n", opa);
c47d488e
DD
10406 fc->col_type[opa] = cie->col_type[opa];
10407 fc->col_offset[opa] = cie->col_offset[opa];
10408 break;
10409
10410 case DW_CFA_set_loc:
38fafa6d 10411 vma = get_encoded_value (start, fc->fde_encoding);
d84de024
AM
10412 if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
10413 && elf_header.e_type != ET_REL)
f1ef08cb 10414 vma += section->sh_addr + (start - section_start);
31b6fca6
RH
10415 start += encoded_ptr_size;
10416 if (do_debug_frames_interp)
53c7db4b 10417 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 10418 else
53c7db4b 10419 printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
c47d488e
DD
10420 fc->pc_begin = vma;
10421 break;
10422
10423 case DW_CFA_advance_loc1:
c47d488e 10424 ofs = byte_get (start, 1); start += 1;
31b6fca6 10425 if (do_debug_frames_interp)
53c7db4b 10426 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 10427 else
53c7db4b
KH
10428 printf (" DW_CFA_advance_loc1: %ld to %08lx\n",
10429 ofs * fc->code_factor,
31b6fca6 10430 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
10431 fc->pc_begin += ofs * fc->code_factor;
10432 break;
10433
10434 case DW_CFA_advance_loc2:
c47d488e 10435 ofs = byte_get (start, 2); start += 2;
31b6fca6 10436 if (do_debug_frames_interp)
53c7db4b 10437 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 10438 else
53c7db4b
KH
10439 printf (" DW_CFA_advance_loc2: %ld to %08lx\n",
10440 ofs * fc->code_factor,
31b6fca6 10441 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
10442 fc->pc_begin += ofs * fc->code_factor;
10443 break;
10444
10445 case DW_CFA_advance_loc4:
c47d488e 10446 ofs = byte_get (start, 4); start += 4;
31b6fca6 10447 if (do_debug_frames_interp)
53c7db4b 10448 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 10449 else
53c7db4b
KH
10450 printf (" DW_CFA_advance_loc4: %ld to %08lx\n",
10451 ofs * fc->code_factor,
31b6fca6 10452 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
10453 fc->pc_begin += ofs * fc->code_factor;
10454 break;
10455
10456 case DW_CFA_offset_extended:
10457 reg = LEB ();
10458 roffs = LEB ();
31b6fca6 10459 if (! do_debug_frames_interp)
7036c0e1 10460 printf (" DW_CFA_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 10461 reg, roffs * fc->data_factor);
c47d488e
DD
10462 fc->col_type[reg] = DW_CFA_offset;
10463 fc->col_offset[reg] = roffs * fc->data_factor;
10464 break;
10465
10466 case DW_CFA_restore_extended:
10467 reg = LEB ();
31b6fca6 10468 if (! do_debug_frames_interp)
53c7db4b 10469 printf (" DW_CFA_restore_extended: r%ld\n", reg);
c47d488e
DD
10470 fc->col_type[reg] = cie->col_type[reg];
10471 fc->col_offset[reg] = cie->col_offset[reg];
10472 break;
10473
10474 case DW_CFA_undefined:
10475 reg = LEB ();
31b6fca6 10476 if (! do_debug_frames_interp)
53c7db4b 10477 printf (" DW_CFA_undefined: r%ld\n", reg);
c47d488e
DD
10478 fc->col_type[reg] = DW_CFA_undefined;
10479 fc->col_offset[reg] = 0;
10480 break;
10481
10482 case DW_CFA_same_value:
10483 reg = LEB ();
31b6fca6 10484 if (! do_debug_frames_interp)
53c7db4b 10485 printf (" DW_CFA_same_value: r%ld\n", reg);
c47d488e
DD
10486 fc->col_type[reg] = DW_CFA_same_value;
10487 fc->col_offset[reg] = 0;
10488 break;
10489
10490 case DW_CFA_register:
10491 reg = LEB ();
10492 roffs = LEB ();
31b6fca6 10493 if (! do_debug_frames_interp)
636fc387 10494 printf (" DW_CFA_register: r%ld in r%ld\n", reg, roffs);
c47d488e
DD
10495 fc->col_type[reg] = DW_CFA_register;
10496 fc->col_offset[reg] = roffs;
10497 break;
10498
10499 case DW_CFA_remember_state:
31b6fca6 10500 if (! do_debug_frames_interp)
53c7db4b 10501 printf (" DW_CFA_remember_state\n");
d3ba0551 10502 rs = xmalloc (sizeof (Frame_Chunk));
c47d488e 10503 rs->ncols = fc->ncols;
d3ba0551
AM
10504 rs->col_type = xmalloc (rs->ncols * sizeof (short int));
10505 rs->col_offset = xmalloc (rs->ncols * sizeof (int));
c47d488e
DD
10506 memcpy (rs->col_type, fc->col_type, rs->ncols);
10507 memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
10508 rs->next = remembered_state;
10509 remembered_state = rs;
10510 break;
10511
10512 case DW_CFA_restore_state:
31b6fca6 10513 if (! do_debug_frames_interp)
53c7db4b 10514 printf (" DW_CFA_restore_state\n");
c47d488e 10515 rs = remembered_state;
8c9a9879
RH
10516 if (rs)
10517 {
10518 remembered_state = rs->next;
10519 frame_need_space (fc, rs->ncols-1);
10520 memcpy (fc->col_type, rs->col_type, rs->ncols);
10521 memcpy (fc->col_offset, rs->col_offset,
10522 rs->ncols * sizeof (int));
10523 free (rs->col_type);
10524 free (rs->col_offset);
10525 free (rs);
10526 }
10527 else if (do_debug_frames_interp)
10528 printf ("Mismatched DW_CFA_restore_state\n");
c47d488e
DD
10529 break;
10530
10531 case DW_CFA_def_cfa:
10532 fc->cfa_reg = LEB ();
10533 fc->cfa_offset = LEB ();
63044634 10534 fc->cfa_exp = 0;
31b6fca6 10535 if (! do_debug_frames_interp)
53c7db4b 10536 printf (" DW_CFA_def_cfa: r%d ofs %d\n",
31b6fca6 10537 fc->cfa_reg, fc->cfa_offset);
c47d488e
DD
10538 break;
10539
10540 case DW_CFA_def_cfa_register:
10541 fc->cfa_reg = LEB ();
63044634 10542 fc->cfa_exp = 0;
31b6fca6 10543 if (! do_debug_frames_interp)
53c7db4b 10544 printf (" DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
c47d488e
DD
10545 break;
10546
10547 case DW_CFA_def_cfa_offset:
10548 fc->cfa_offset = LEB ();
31b6fca6 10549 if (! do_debug_frames_interp)
53c7db4b 10550 printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
c47d488e
DD
10551 break;
10552
10553 case DW_CFA_nop:
31b6fca6 10554 if (! do_debug_frames_interp)
53c7db4b 10555 printf (" DW_CFA_nop\n");
c47d488e
DD
10556 break;
10557
63044634
RH
10558 case DW_CFA_def_cfa_expression:
10559 ul = LEB ();
10560 if (! do_debug_frames_interp)
10561 {
10562 printf (" DW_CFA_def_cfa_expression (");
89fac5e3 10563 decode_location_expression (start, eh_addr_size, ul, 0);
63044634
RH
10564 printf (")\n");
10565 }
10566 fc->cfa_exp = 1;
10567 start += ul;
10568 break;
10569
10570 case DW_CFA_expression:
10571 reg = LEB ();
10572 ul = LEB ();
10573 if (! do_debug_frames_interp)
10574 {
10575 printf (" DW_CFA_expression: r%ld (", reg);
89fac5e3 10576 decode_location_expression (start, eh_addr_size, ul, 0);
63044634
RH
10577 printf (")\n");
10578 }
10579 fc->col_type[reg] = DW_CFA_expression;
10580 start += ul;
10581 break;
10582
91a106e6
L
10583 case DW_CFA_offset_extended_sf:
10584 reg = LEB ();
10585 l = SLEB ();
10586 frame_need_space (fc, reg);
10587 if (! do_debug_frames_interp)
10588 printf (" DW_CFA_offset_extended_sf: r%ld at cfa%+ld\n",
10589 reg, l * fc->data_factor);
10590 fc->col_type[reg] = DW_CFA_offset;
10591 fc->col_offset[reg] = l * fc->data_factor;
10592 break;
10593
10594 case DW_CFA_def_cfa_sf:
10595 fc->cfa_reg = LEB ();
10596 fc->cfa_offset = SLEB ();
63044634 10597 fc->cfa_exp = 0;
91a106e6
L
10598 if (! do_debug_frames_interp)
10599 printf (" DW_CFA_def_cfa_sf: r%d ofs %d\n",
10600 fc->cfa_reg, fc->cfa_offset);
10601 break;
10602
10603 case DW_CFA_def_cfa_offset_sf:
10604 fc->cfa_offset = SLEB ();
10605 if (! do_debug_frames_interp)
10606 printf (" DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset);
10607 break;
10608
63044634
RH
10609 case DW_CFA_MIPS_advance_loc8:
10610 ofs = byte_get (start, 8); start += 8;
10611 if (do_debug_frames_interp)
10612 frame_display_row (fc, &need_col_headers, &max_regs);
10613 else
10614 printf (" DW_CFA_MIPS_advance_loc8: %ld to %08lx\n",
10615 ofs * fc->code_factor,
10616 fc->pc_begin + ofs * fc->code_factor);
10617 fc->pc_begin += ofs * fc->code_factor;
10618 break;
10619
c47d488e 10620 case DW_CFA_GNU_window_save:
31b6fca6 10621 if (! do_debug_frames_interp)
53c7db4b 10622 printf (" DW_CFA_GNU_window_save\n");
c47d488e
DD
10623 break;
10624
c47d488e
DD
10625 case DW_CFA_GNU_args_size:
10626 ul = LEB ();
31b6fca6 10627 if (! do_debug_frames_interp)
53c7db4b 10628 printf (" DW_CFA_GNU_args_size: %ld\n", ul);
c47d488e
DD
10629 break;
10630
c47d488e
DD
10631 case DW_CFA_GNU_negative_offset_extended:
10632 reg = LEB ();
10633 l = - LEB ();
10634 frame_need_space (fc, reg);
31b6fca6 10635 if (! do_debug_frames_interp)
53c7db4b 10636 printf (" DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 10637 reg, l * fc->data_factor);
c47d488e
DD
10638 fc->col_type[reg] = DW_CFA_offset;
10639 fc->col_offset[reg] = l * fc->data_factor;
10640 break;
10641
10642 default:
18bd398b 10643 warn (_("unsupported or unknown DW_CFA_%d\n"), op);
c47d488e
DD
10644 start = block_end;
10645 }
10646 }
10647
31b6fca6 10648 if (do_debug_frames_interp)
53c7db4b 10649 frame_display_row (fc, &need_col_headers, &max_regs);
c47d488e
DD
10650
10651 start = block_end;
10652 }
10653
10654 printf ("\n");
10655
10656 return 1;
10657}
10658
10659#undef GET
10660#undef LEB
10661#undef SLEB
252b5132
RH
10662
10663static int
d3ba0551
AM
10664display_debug_not_supported (Elf_Internal_Shdr *section,
10665 unsigned char *start ATTRIBUTE_UNUSED,
10666 FILE *file ATTRIBUTE_UNUSED)
252b5132
RH
10667{
10668 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
10669 SECTION_NAME (section));
10670
10671 return 1;
10672}
10673
d9296b18
NC
10674/* A structure containing the name of a debug section
10675 and a pointer to a function that can decode it. */
252b5132
RH
10676struct
10677{
b34976b6 10678 const char *const name;
d3ba0551 10679 int (*display) (Elf_Internal_Shdr *, unsigned char *, FILE *);
252b5132
RH
10680}
10681debug_displays[] =
10682{
d9296b18
NC
10683 { ".debug_abbrev", display_debug_abbrev },
10684 { ".debug_aranges", display_debug_aranges },
10685 { ".debug_frame", display_debug_frames },
10686 { ".debug_info", display_debug_info },
10687 { ".debug_line", display_debug_lines },
10688 { ".debug_pubnames", display_debug_pubnames },
10689 { ".eh_frame", display_debug_frames },
10690 { ".debug_macinfo", display_debug_macinfo },
10691 { ".debug_str", display_debug_str },
10692 { ".debug_loc", display_debug_loc },
935a41f5 10693 { ".debug_pubtypes", display_debug_pubnames },
18bd398b 10694 { ".debug_ranges", display_debug_ranges },
d9296b18
NC
10695 { ".debug_static_func", display_debug_not_supported },
10696 { ".debug_static_vars", display_debug_not_supported },
10697 { ".debug_types", display_debug_not_supported },
10698 { ".debug_weaknames", display_debug_not_supported }
252b5132
RH
10699};
10700
10701static int
d3ba0551 10702display_debug_section (Elf_Internal_Shdr *section, FILE *file)
252b5132 10703{
b34976b6
AM
10704 char *name = SECTION_NAME (section);
10705 bfd_size_type length;
18bd398b 10706 int result = 1;
b34976b6 10707 int i;
252b5132
RH
10708
10709 length = section->sh_size;
10710 if (length == 0)
10711 {
10712 printf (_("\nSection '%s' has no debugging data.\n"), name);
10713 return 0;
10714 }
10715
18bd398b 10716 if (strneq (name, ".gnu.linkonce.wi.", 17))
7036c0e1 10717 name = ".debug_info";
584da044 10718
18bd398b 10719 /* See if we know how to display the contents of this section. */
252b5132 10720 for (i = NUM_ELEM (debug_displays); i--;)
18bd398b 10721 if (streq (debug_displays[i].name, name))
252b5132 10722 {
18bd398b
NC
10723 unsigned char *start;
10724
10725 start = get_data (NULL, file, section->sh_offset, length,
10726 _("debug section data"));
10727 if (start == NULL)
10728 {
10729 result = 0;
10730 break;
10731 }
10732
10733 result &= debug_displays[i].display (section, start, file);
10734 free (start);
10735
10736 /* If we loaded in the abbrev section
10737 at some point, we must release it here. */
10738 free_abbrevs ();
10739
252b5132
RH
10740 break;
10741 }
10742
10743 if (i == -1)
18bd398b
NC
10744 {
10745 printf (_("Unrecognized debug section: %s\n"), name);
10746 result = 0;
10747 }
252b5132 10748
18bd398b 10749 return result;
252b5132
RH
10750}
10751
18bd398b 10752static void
d3ba0551 10753process_section_contents (FILE *file)
252b5132 10754{
b34976b6
AM
10755 Elf_Internal_Shdr *section;
10756 unsigned int i;
252b5132
RH
10757
10758 if (! do_dump)
18bd398b 10759 return;
252b5132
RH
10760
10761 for (i = 0, section = section_headers;
3590ea00 10762 i < elf_header.e_shnum && i < num_dump_sects;
b34976b6 10763 i++, section++)
252b5132
RH
10764 {
10765#ifdef SUPPORT_DISASSEMBLY
10766 if (dump_sects[i] & DISASS_DUMP)
10767 disassemble_section (section, file);
10768#endif
10769 if (dump_sects[i] & HEX_DUMP)
10770 dump_section (section, file);
10771
10772 if (dump_sects[i] & DEBUG_DUMP)
10773 display_debug_section (section, file);
10774 }
10775
18bd398b
NC
10776 /* Check to see if the user requested a
10777 dump of a section that does not exist. */
10778 while (i++ < num_dump_sects)
10779 if (dump_sects[i])
10780 warn (_("Section %d was not dumped because it does not exist!\n"), i);
252b5132
RH
10781}
10782
10783static void
d3ba0551 10784process_mips_fpe_exception (int mask)
252b5132
RH
10785{
10786 if (mask)
10787 {
10788 int first = 1;
10789 if (mask & OEX_FPU_INEX)
10790 fputs ("INEX", stdout), first = 0;
10791 if (mask & OEX_FPU_UFLO)
10792 printf ("%sUFLO", first ? "" : "|"), first = 0;
10793 if (mask & OEX_FPU_OFLO)
10794 printf ("%sOFLO", first ? "" : "|"), first = 0;
10795 if (mask & OEX_FPU_DIV0)
10796 printf ("%sDIV0", first ? "" : "|"), first = 0;
10797 if (mask & OEX_FPU_INVAL)
10798 printf ("%sINVAL", first ? "" : "|");
10799 }
10800 else
10801 fputs ("0", stdout);
10802}
10803
10804static int
d3ba0551 10805process_mips_specific (FILE *file)
252b5132 10806{
b34976b6 10807 Elf_Internal_Dyn *entry;
252b5132
RH
10808 size_t liblist_offset = 0;
10809 size_t liblistno = 0;
10810 size_t conflictsno = 0;
10811 size_t options_offset = 0;
10812 size_t conflicts_offset = 0;
10813
10814 /* We have a lot of special sections. Thanks SGI! */
b2d38a17 10815 if (dynamic_section == NULL)
252b5132
RH
10816 /* No information available. */
10817 return 0;
10818
b2d38a17 10819 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
10820 switch (entry->d_tag)
10821 {
10822 case DT_MIPS_LIBLIST:
d93f0186
NC
10823 liblist_offset
10824 = offset_from_vma (file, entry->d_un.d_val,
10825 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
10826 break;
10827 case DT_MIPS_LIBLISTNO:
10828 liblistno = entry->d_un.d_val;
10829 break;
10830 case DT_MIPS_OPTIONS:
d93f0186 10831 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
10832 break;
10833 case DT_MIPS_CONFLICT:
d93f0186
NC
10834 conflicts_offset
10835 = offset_from_vma (file, entry->d_un.d_val,
10836 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
10837 break;
10838 case DT_MIPS_CONFLICTNO:
10839 conflictsno = entry->d_un.d_val;
10840 break;
10841 default:
10842 break;
10843 }
10844
10845 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
10846 {
b34976b6 10847 Elf32_External_Lib *elib;
252b5132
RH
10848 size_t cnt;
10849
d3ba0551
AM
10850 elib = get_data (NULL, file, liblist_offset,
10851 liblistno * sizeof (Elf32_External_Lib),
10852 _("liblist"));
a6e9f9df 10853 if (elib)
252b5132 10854 {
a6e9f9df
AM
10855 printf ("\nSection '.liblist' contains %lu entries:\n",
10856 (unsigned long) liblistno);
10857 fputs (" Library Time Stamp Checksum Version Flags\n",
10858 stdout);
10859
10860 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 10861 {
a6e9f9df
AM
10862 Elf32_Lib liblist;
10863 time_t time;
10864 char timebuf[20];
b34976b6 10865 struct tm *tmp;
a6e9f9df
AM
10866
10867 liblist.l_name = BYTE_GET (elib[cnt].l_name);
10868 time = BYTE_GET (elib[cnt].l_time_stamp);
10869 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
10870 liblist.l_version = BYTE_GET (elib[cnt].l_version);
10871 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
10872
10873 tmp = gmtime (&time);
10874 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
10875 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10876 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
10877
31104126 10878 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
10879 if (VALID_DYNAMIC_NAME (liblist.l_name))
10880 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
10881 else
10882 printf ("<corrupt: %9ld>", liblist.l_name);
31104126
NC
10883 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
10884 liblist.l_version);
a6e9f9df
AM
10885
10886 if (liblist.l_flags == 0)
10887 puts (" NONE");
10888 else
10889 {
10890 static const struct
252b5132 10891 {
b34976b6 10892 const char *name;
a6e9f9df 10893 int bit;
252b5132 10894 }
a6e9f9df
AM
10895 l_flags_vals[] =
10896 {
10897 { " EXACT_MATCH", LL_EXACT_MATCH },
10898 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
10899 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
10900 { " EXPORTS", LL_EXPORTS },
10901 { " DELAY_LOAD", LL_DELAY_LOAD },
10902 { " DELTA", LL_DELTA }
10903 };
10904 int flags = liblist.l_flags;
10905 size_t fcnt;
10906
10907 for (fcnt = 0;
10908 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
10909 ++fcnt)
10910 if ((flags & l_flags_vals[fcnt].bit) != 0)
10911 {
10912 fputs (l_flags_vals[fcnt].name, stdout);
10913 flags ^= l_flags_vals[fcnt].bit;
10914 }
10915 if (flags != 0)
10916 printf (" %#x", (unsigned int) flags);
252b5132 10917
a6e9f9df
AM
10918 puts ("");
10919 }
252b5132 10920 }
252b5132 10921
a6e9f9df
AM
10922 free (elib);
10923 }
252b5132
RH
10924 }
10925
10926 if (options_offset != 0)
10927 {
b34976b6
AM
10928 Elf_External_Options *eopt;
10929 Elf_Internal_Shdr *sect = section_headers;
10930 Elf_Internal_Options *iopt;
10931 Elf_Internal_Options *option;
252b5132
RH
10932 size_t offset;
10933 int cnt;
10934
10935 /* Find the section header so that we get the size. */
10936 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 10937 ++sect;
252b5132 10938
d3ba0551
AM
10939 eopt = get_data (NULL, file, options_offset, sect->sh_size,
10940 _("options"));
a6e9f9df 10941 if (eopt)
252b5132 10942 {
d3ba0551 10943 iopt = malloc ((sect->sh_size / sizeof (eopt)) * sizeof (*iopt));
a6e9f9df
AM
10944 if (iopt == NULL)
10945 {
10946 error (_("Out of memory"));
10947 return 0;
10948 }
76da6bbe 10949
a6e9f9df
AM
10950 offset = cnt = 0;
10951 option = iopt;
252b5132 10952
a6e9f9df
AM
10953 while (offset < sect->sh_size)
10954 {
b34976b6 10955 Elf_External_Options *eoption;
252b5132 10956
a6e9f9df 10957 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 10958
a6e9f9df
AM
10959 option->kind = BYTE_GET (eoption->kind);
10960 option->size = BYTE_GET (eoption->size);
10961 option->section = BYTE_GET (eoption->section);
10962 option->info = BYTE_GET (eoption->info);
76da6bbe 10963
a6e9f9df 10964 offset += option->size;
252b5132 10965
a6e9f9df
AM
10966 ++option;
10967 ++cnt;
10968 }
252b5132 10969
a6e9f9df
AM
10970 printf (_("\nSection '%s' contains %d entries:\n"),
10971 SECTION_NAME (sect), cnt);
76da6bbe 10972
a6e9f9df 10973 option = iopt;
252b5132 10974
a6e9f9df 10975 while (cnt-- > 0)
252b5132 10976 {
a6e9f9df
AM
10977 size_t len;
10978
10979 switch (option->kind)
252b5132 10980 {
a6e9f9df
AM
10981 case ODK_NULL:
10982 /* This shouldn't happen. */
10983 printf (" NULL %d %lx", option->section, option->info);
10984 break;
10985 case ODK_REGINFO:
10986 printf (" REGINFO ");
10987 if (elf_header.e_machine == EM_MIPS)
10988 {
10989 /* 32bit form. */
b34976b6
AM
10990 Elf32_External_RegInfo *ereg;
10991 Elf32_RegInfo reginfo;
a6e9f9df
AM
10992
10993 ereg = (Elf32_External_RegInfo *) (option + 1);
10994 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
10995 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
10996 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
10997 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
10998 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
10999 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
11000
11001 printf ("GPR %08lx GP 0x%lx\n",
11002 reginfo.ri_gprmask,
11003 (unsigned long) reginfo.ri_gp_value);
11004 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11005 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11006 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11007 }
11008 else
11009 {
11010 /* 64 bit form. */
b34976b6 11011 Elf64_External_RegInfo *ereg;
a6e9f9df
AM
11012 Elf64_Internal_RegInfo reginfo;
11013
11014 ereg = (Elf64_External_RegInfo *) (option + 1);
11015 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11016 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11017 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11018 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11019 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
11020 reginfo.ri_gp_value = BYTE_GET8 (ereg->ri_gp_value);
11021
11022 printf ("GPR %08lx GP 0x",
11023 reginfo.ri_gprmask);
11024 printf_vma (reginfo.ri_gp_value);
11025 printf ("\n");
11026
11027 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11028 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11029 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11030 }
11031 ++option;
11032 continue;
11033 case ODK_EXCEPTIONS:
11034 fputs (" EXCEPTIONS fpe_min(", stdout);
11035 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
11036 fputs (") fpe_max(", stdout);
11037 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
11038 fputs (")", stdout);
11039
11040 if (option->info & OEX_PAGE0)
11041 fputs (" PAGE0", stdout);
11042 if (option->info & OEX_SMM)
11043 fputs (" SMM", stdout);
11044 if (option->info & OEX_FPDBUG)
11045 fputs (" FPDBUG", stdout);
11046 if (option->info & OEX_DISMISS)
11047 fputs (" DISMISS", stdout);
11048 break;
11049 case ODK_PAD:
11050 fputs (" PAD ", stdout);
11051 if (option->info & OPAD_PREFIX)
11052 fputs (" PREFIX", stdout);
11053 if (option->info & OPAD_POSTFIX)
11054 fputs (" POSTFIX", stdout);
11055 if (option->info & OPAD_SYMBOL)
11056 fputs (" SYMBOL", stdout);
11057 break;
11058 case ODK_HWPATCH:
11059 fputs (" HWPATCH ", stdout);
11060 if (option->info & OHW_R4KEOP)
11061 fputs (" R4KEOP", stdout);
11062 if (option->info & OHW_R8KPFETCH)
11063 fputs (" R8KPFETCH", stdout);
11064 if (option->info & OHW_R5KEOP)
11065 fputs (" R5KEOP", stdout);
11066 if (option->info & OHW_R5KCVTL)
11067 fputs (" R5KCVTL", stdout);
11068 break;
11069 case ODK_FILL:
11070 fputs (" FILL ", stdout);
11071 /* XXX Print content of info word? */
11072 break;
11073 case ODK_TAGS:
11074 fputs (" TAGS ", stdout);
11075 /* XXX Print content of info word? */
11076 break;
11077 case ODK_HWAND:
11078 fputs (" HWAND ", stdout);
11079 if (option->info & OHWA0_R4KEOP_CHECKED)
11080 fputs (" R4KEOP_CHECKED", stdout);
11081 if (option->info & OHWA0_R4KEOP_CLEAN)
11082 fputs (" R4KEOP_CLEAN", stdout);
11083 break;
11084 case ODK_HWOR:
11085 fputs (" HWOR ", stdout);
11086 if (option->info & OHWA0_R4KEOP_CHECKED)
11087 fputs (" R4KEOP_CHECKED", stdout);
11088 if (option->info & OHWA0_R4KEOP_CLEAN)
11089 fputs (" R4KEOP_CLEAN", stdout);
11090 break;
11091 case ODK_GP_GROUP:
11092 printf (" GP_GROUP %#06lx self-contained %#06lx",
11093 option->info & OGP_GROUP,
11094 (option->info & OGP_SELF) >> 16);
11095 break;
11096 case ODK_IDENT:
11097 printf (" IDENT %#06lx self-contained %#06lx",
11098 option->info & OGP_GROUP,
11099 (option->info & OGP_SELF) >> 16);
11100 break;
11101 default:
11102 /* This shouldn't happen. */
11103 printf (" %3d ??? %d %lx",
11104 option->kind, option->section, option->info);
11105 break;
252b5132 11106 }
a6e9f9df 11107
b34976b6 11108 len = sizeof (*eopt);
a6e9f9df
AM
11109 while (len < option->size)
11110 if (((char *) option)[len] >= ' '
11111 && ((char *) option)[len] < 0x7f)
11112 printf ("%c", ((char *) option)[len++]);
11113 else
11114 printf ("\\%03o", ((char *) option)[len++]);
11115
11116 fputs ("\n", stdout);
252b5132 11117 ++option;
252b5132
RH
11118 }
11119
a6e9f9df 11120 free (eopt);
252b5132 11121 }
252b5132
RH
11122 }
11123
11124 if (conflicts_offset != 0 && conflictsno != 0)
11125 {
b34976b6 11126 Elf32_Conflict *iconf;
252b5132
RH
11127 size_t cnt;
11128
11129 if (dynamic_symbols == NULL)
11130 {
3a1a2036 11131 error (_("conflict list found without a dynamic symbol table"));
252b5132
RH
11132 return 0;
11133 }
11134
d3ba0551 11135 iconf = malloc (conflictsno * sizeof (*iconf));
252b5132
RH
11136 if (iconf == NULL)
11137 {
11138 error (_("Out of memory"));
11139 return 0;
11140 }
11141
9ea033b2 11142 if (is_32bit_elf)
252b5132 11143 {
b34976b6 11144 Elf32_External_Conflict *econf32;
a6e9f9df 11145
d3ba0551
AM
11146 econf32 = get_data (NULL, file, conflicts_offset,
11147 conflictsno * sizeof (*econf32), _("conflict"));
a6e9f9df
AM
11148 if (!econf32)
11149 return 0;
252b5132
RH
11150
11151 for (cnt = 0; cnt < conflictsno; ++cnt)
11152 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
11153
11154 free (econf32);
252b5132
RH
11155 }
11156 else
11157 {
b34976b6 11158 Elf64_External_Conflict *econf64;
a6e9f9df 11159
d3ba0551
AM
11160 econf64 = get_data (NULL, file, conflicts_offset,
11161 conflictsno * sizeof (*econf64), _("conflict"));
a6e9f9df
AM
11162 if (!econf64)
11163 return 0;
252b5132
RH
11164
11165 for (cnt = 0; cnt < conflictsno; ++cnt)
11166 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
11167
11168 free (econf64);
252b5132
RH
11169 }
11170
c7e7ca54
NC
11171 printf (_("\nSection '.conflict' contains %lu entries:\n"),
11172 (unsigned long) conflictsno);
252b5132
RH
11173 puts (_(" Num: Index Value Name"));
11174
11175 for (cnt = 0; cnt < conflictsno; ++cnt)
11176 {
b34976b6 11177 Elf_Internal_Sym *psym = & dynamic_symbols[iconf[cnt]];
252b5132 11178
b34976b6 11179 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 11180 print_vma (psym->st_value, FULL_HEX);
31104126 11181 putchar (' ');
d79b3d50
NC
11182 if (VALID_DYNAMIC_NAME (psym->st_name))
11183 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
11184 else
11185 printf ("<corrupt: %14ld>", psym->st_name);
31104126 11186 putchar ('\n');
252b5132
RH
11187 }
11188
252b5132
RH
11189 free (iconf);
11190 }
11191
11192 return 1;
11193}
11194
047b2264 11195static int
d3ba0551 11196process_gnu_liblist (FILE *file)
047b2264 11197{
b34976b6
AM
11198 Elf_Internal_Shdr *section, *string_sec;
11199 Elf32_External_Lib *elib;
11200 char *strtab;
047b2264
JJ
11201 size_t cnt;
11202 unsigned i;
11203
11204 if (! do_arch)
11205 return 0;
11206
11207 for (i = 0, section = section_headers;
11208 i < elf_header.e_shnum;
b34976b6 11209 i++, section++)
047b2264
JJ
11210 {
11211 switch (section->sh_type)
11212 {
11213 case SHT_GNU_LIBLIST:
d3ba0551
AM
11214 elib = get_data (NULL, file, section->sh_offset, section->sh_size,
11215 _("liblist"));
047b2264
JJ
11216
11217 if (elib == NULL)
11218 break;
11219 string_sec = SECTION_HEADER (section->sh_link);
11220
d3ba0551
AM
11221 strtab = get_data (NULL, file, string_sec->sh_offset,
11222 string_sec->sh_size, _("liblist string table"));
047b2264
JJ
11223
11224 if (strtab == NULL
11225 || section->sh_entsize != sizeof (Elf32_External_Lib))
11226 {
11227 free (elib);
11228 break;
11229 }
11230
11231 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
11232 SECTION_NAME (section),
11233 (long) (section->sh_size / sizeof (Elf32_External_Lib)));
11234
11235 puts (" Library Time Stamp Checksum Version Flags");
11236
11237 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
11238 ++cnt)
11239 {
11240 Elf32_Lib liblist;
11241 time_t time;
11242 char timebuf[20];
b34976b6 11243 struct tm *tmp;
047b2264
JJ
11244
11245 liblist.l_name = BYTE_GET (elib[cnt].l_name);
11246 time = BYTE_GET (elib[cnt].l_time_stamp);
11247 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
11248 liblist.l_version = BYTE_GET (elib[cnt].l_version);
11249 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
11250
11251 tmp = gmtime (&time);
11252 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
11253 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11254 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
11255
11256 printf ("%3lu: ", (unsigned long) cnt);
11257 if (do_wide)
11258 printf ("%-20s", strtab + liblist.l_name);
11259 else
11260 printf ("%-20.20s", strtab + liblist.l_name);
11261 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
11262 liblist.l_version, liblist.l_flags);
11263 }
11264
11265 free (elib);
11266 }
11267 }
11268
11269 return 1;
11270}
11271
9437c45b 11272static const char *
d3ba0551 11273get_note_type (unsigned e_type)
779fe533
NC
11274{
11275 static char buff[64];
103f02d3 11276
1ec5cd37
NC
11277 if (elf_header.e_type == ET_CORE)
11278 switch (e_type)
11279 {
57346661 11280 case NT_AUXV:
1ec5cd37 11281 return _("NT_AUXV (auxiliary vector)");
57346661 11282 case NT_PRSTATUS:
1ec5cd37 11283 return _("NT_PRSTATUS (prstatus structure)");
57346661 11284 case NT_FPREGSET:
1ec5cd37 11285 return _("NT_FPREGSET (floating point registers)");
57346661 11286 case NT_PRPSINFO:
1ec5cd37 11287 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 11288 case NT_TASKSTRUCT:
1ec5cd37 11289 return _("NT_TASKSTRUCT (task structure)");
57346661 11290 case NT_PRXFPREG:
1ec5cd37 11291 return _("NT_PRXFPREG (user_xfpregs structure)");
57346661 11292 case NT_PSTATUS:
1ec5cd37 11293 return _("NT_PSTATUS (pstatus structure)");
57346661 11294 case NT_FPREGS:
1ec5cd37 11295 return _("NT_FPREGS (floating point registers)");
57346661 11296 case NT_PSINFO:
1ec5cd37 11297 return _("NT_PSINFO (psinfo structure)");
57346661 11298 case NT_LWPSTATUS:
1ec5cd37 11299 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 11300 case NT_LWPSINFO:
1ec5cd37 11301 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 11302 case NT_WIN32PSTATUS:
1ec5cd37
NC
11303 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
11304 default:
11305 break;
11306 }
11307 else
11308 switch (e_type)
11309 {
11310 case NT_VERSION:
11311 return _("NT_VERSION (version)");
11312 case NT_ARCH:
11313 return _("NT_ARCH (architecture)");
11314 default:
11315 break;
11316 }
11317
11318 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
11319 return buff;
779fe533
NC
11320}
11321
9437c45b 11322static const char *
d3ba0551 11323get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
11324{
11325 static char buff[64];
11326
b4db1224 11327 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
11328 {
11329 /* NetBSD core "procinfo" structure. */
11330 return _("NetBSD procinfo structure");
11331 }
11332
11333 /* As of Jan 2002 there are no other machine-independent notes
11334 defined for NetBSD core files. If the note type is less
11335 than the start of the machine-dependent note types, we don't
11336 understand it. */
11337
b4db1224 11338 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b
JT
11339 {
11340 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
11341 return buff;
11342 }
11343
11344 switch (elf_header.e_machine)
11345 {
11346 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
11347 and PT_GETFPREGS == mach+2. */
11348
11349 case EM_OLD_ALPHA:
11350 case EM_ALPHA:
11351 case EM_SPARC:
11352 case EM_SPARC32PLUS:
11353 case EM_SPARCV9:
11354 switch (e_type)
11355 {
b4db1224
JT
11356 case NT_NETBSDCORE_FIRSTMACH+0:
11357 return _("PT_GETREGS (reg structure)");
11358 case NT_NETBSDCORE_FIRSTMACH+2:
11359 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
11360 default:
11361 break;
11362 }
11363 break;
11364
11365 /* On all other arch's, PT_GETREGS == mach+1 and
11366 PT_GETFPREGS == mach+3. */
11367 default:
11368 switch (e_type)
11369 {
b4db1224
JT
11370 case NT_NETBSDCORE_FIRSTMACH+1:
11371 return _("PT_GETREGS (reg structure)");
11372 case NT_NETBSDCORE_FIRSTMACH+3:
11373 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
11374 default:
11375 break;
11376 }
11377 }
11378
b4db1224 11379 sprintf (buff, _("PT_FIRSTMACH+%d"), e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
11380 return buff;
11381}
11382
6d118b09
NC
11383/* Note that by the ELF standard, the name field is already null byte
11384 terminated, and namesz includes the terminating null byte.
11385 I.E. the value of namesz for the name "FSF" is 4.
11386
e3c8793a 11387 If the value of namesz is zero, there is no name present. */
779fe533 11388static int
d3ba0551 11389process_note (Elf_Internal_Note *pnote)
779fe533 11390{
9437c45b
JT
11391 const char *nt;
11392
11393 if (pnote->namesz == 0)
1ec5cd37
NC
11394 /* If there is no note name, then use the default set of
11395 note type strings. */
11396 nt = get_note_type (pnote->type);
11397
18bd398b 11398 else if (strneq (pnote->namedata, "NetBSD-CORE", 11))
1ec5cd37
NC
11399 /* NetBSD-specific core file notes. */
11400 nt = get_netbsd_elfcore_note_type (pnote->type);
11401
9437c45b 11402 else
1ec5cd37
NC
11403 /* Don't recognize this note name; just use the default set of
11404 note type strings. */
9437c45b 11405 nt = get_note_type (pnote->type);
9437c45b 11406
103f02d3 11407 printf (" %s\t\t0x%08lx\t%s\n",
6d118b09 11408 pnote->namesz ? pnote->namedata : "(NONE)",
9437c45b 11409 pnote->descsz, nt);
779fe533
NC
11410 return 1;
11411}
11412
6d118b09 11413
779fe533 11414static int
d3ba0551 11415process_corefile_note_segment (FILE *file, bfd_vma offset, bfd_vma length)
779fe533 11416{
b34976b6
AM
11417 Elf_External_Note *pnotes;
11418 Elf_External_Note *external;
11419 int res = 1;
103f02d3 11420
779fe533
NC
11421 if (length <= 0)
11422 return 0;
103f02d3 11423
d3ba0551 11424 pnotes = get_data (NULL, file, offset, length, _("notes"));
a6e9f9df
AM
11425 if (!pnotes)
11426 return 0;
779fe533 11427
103f02d3 11428 external = pnotes;
103f02d3 11429
305c7206 11430 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 11431 (unsigned long) offset, (unsigned long) length);
779fe533 11432 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 11433
6d118b09 11434 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 11435 {
b34976b6
AM
11436 Elf_External_Note *next;
11437 Elf_Internal_Note inote;
11438 char *temp = NULL;
6d118b09
NC
11439
11440 inote.type = BYTE_GET (external->type);
11441 inote.namesz = BYTE_GET (external->namesz);
11442 inote.namedata = external->name;
11443 inote.descsz = BYTE_GET (external->descsz);
11444 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
11445 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 11446
3e55a963
NC
11447 next = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
11448
11449 if (((char *) next) > (((char *) pnotes) + length))
11450 {
11451 warn (_("corrupt note found at offset %x into core notes\n"),
11452 ((char *) external) - ((char *) pnotes));
11453 warn (_(" type: %x, namesize: %08lx, descsize: %08lx\n"),
11454 inote.type, inote.namesz, inote.descsz);
11455 break;
11456 }
11457
11458 external = next;
6d118b09
NC
11459
11460 /* Verify that name is null terminated. It appears that at least
11461 one version of Linux (RedHat 6.0) generates corefiles that don't
11462 comply with the ELF spec by failing to include the null byte in
11463 namesz. */
11464 if (inote.namedata[inote.namesz] != '\0')
11465 {
11466 temp = malloc (inote.namesz + 1);
76da6bbe 11467
6d118b09
NC
11468 if (temp == NULL)
11469 {
11470 error (_("Out of memory\n"));
11471 res = 0;
11472 break;
11473 }
76da6bbe 11474
6d118b09
NC
11475 strncpy (temp, inote.namedata, inote.namesz);
11476 temp[inote.namesz] = 0;
76da6bbe 11477
6d118b09
NC
11478 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
11479 inote.namedata = temp;
11480 }
11481
11482 res &= process_note (& inote);
103f02d3 11483
6d118b09
NC
11484 if (temp != NULL)
11485 {
11486 free (temp);
11487 temp = NULL;
11488 }
779fe533
NC
11489 }
11490
11491 free (pnotes);
103f02d3 11492
779fe533
NC
11493 return res;
11494}
11495
11496static int
d3ba0551 11497process_corefile_note_segments (FILE *file)
779fe533 11498{
b34976b6
AM
11499 Elf_Internal_Phdr *segment;
11500 unsigned int i;
11501 int res = 1;
103f02d3 11502
d93f0186 11503 if (! get_program_headers (file))
779fe533 11504 return 0;
103f02d3 11505
779fe533
NC
11506 for (i = 0, segment = program_headers;
11507 i < elf_header.e_phnum;
b34976b6 11508 i++, segment++)
779fe533
NC
11509 {
11510 if (segment->p_type == PT_NOTE)
103f02d3 11511 res &= process_corefile_note_segment (file,
30800947
NC
11512 (bfd_vma) segment->p_offset,
11513 (bfd_vma) segment->p_filesz);
779fe533 11514 }
103f02d3 11515
779fe533
NC
11516 return res;
11517}
11518
11519static int
1ec5cd37
NC
11520process_note_sections (FILE *file)
11521{
11522 Elf_Internal_Shdr *section;
11523 unsigned long i;
11524 int res = 1;
11525
11526 for (i = 0, section = section_headers;
11527 i < elf_header.e_shnum;
11528 i++, section++)
11529 if (section->sh_type == SHT_NOTE)
11530 res &= process_corefile_note_segment (file,
11531 (bfd_vma) section->sh_offset,
11532 (bfd_vma) section->sh_size);
11533
11534 return res;
11535}
11536
11537static int
11538process_notes (FILE *file)
779fe533
NC
11539{
11540 /* If we have not been asked to display the notes then do nothing. */
11541 if (! do_notes)
11542 return 1;
103f02d3 11543
779fe533 11544 if (elf_header.e_type != ET_CORE)
1ec5cd37 11545 return process_note_sections (file);
103f02d3 11546
779fe533 11547 /* No program headers means no NOTE segment. */
1ec5cd37
NC
11548 if (elf_header.e_phnum > 0)
11549 return process_corefile_note_segments (file);
779fe533 11550
1ec5cd37
NC
11551 printf (_("No note segments present in the core file.\n"));
11552 return 1;
779fe533
NC
11553}
11554
252b5132 11555static int
d3ba0551 11556process_arch_specific (FILE *file)
252b5132 11557{
a952a375
NC
11558 if (! do_arch)
11559 return 1;
11560
252b5132
RH
11561 switch (elf_header.e_machine)
11562 {
11563 case EM_MIPS:
4fe85591 11564 case EM_MIPS_RS3_LE:
252b5132
RH
11565 return process_mips_specific (file);
11566 break;
11567 default:
11568 break;
11569 }
11570 return 1;
11571}
11572
11573static int
d3ba0551 11574get_file_header (FILE *file)
252b5132 11575{
9ea033b2
NC
11576 /* Read in the identity array. */
11577 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
11578 return 0;
11579
9ea033b2 11580 /* Determine how to read the rest of the header. */
b34976b6 11581 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
11582 {
11583 default: /* fall through */
11584 case ELFDATANONE: /* fall through */
adab8cdc
AO
11585 case ELFDATA2LSB:
11586 byte_get = byte_get_little_endian;
11587 byte_put = byte_put_little_endian;
11588 break;
11589 case ELFDATA2MSB:
11590 byte_get = byte_get_big_endian;
11591 byte_put = byte_put_big_endian;
11592 break;
9ea033b2
NC
11593 }
11594
11595 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 11596 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
11597
11598 /* Read in the rest of the header. */
11599 if (is_32bit_elf)
11600 {
11601 Elf32_External_Ehdr ehdr32;
252b5132 11602
9ea033b2
NC
11603 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
11604 return 0;
103f02d3 11605
9ea033b2
NC
11606 elf_header.e_type = BYTE_GET (ehdr32.e_type);
11607 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
11608 elf_header.e_version = BYTE_GET (ehdr32.e_version);
11609 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
11610 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
11611 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
11612 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
11613 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
11614 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
11615 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
11616 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
11617 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
11618 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
11619 }
252b5132 11620 else
9ea033b2
NC
11621 {
11622 Elf64_External_Ehdr ehdr64;
a952a375
NC
11623
11624 /* If we have been compiled with sizeof (bfd_vma) == 4, then
11625 we will not be able to cope with the 64bit data found in
11626 64 ELF files. Detect this now and abort before we start
50c2245b 11627 overwriting things. */
a952a375
NC
11628 if (sizeof (bfd_vma) < 8)
11629 {
e3c8793a
NC
11630 error (_("This instance of readelf has been built without support for a\n\
1163164 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
11632 return 0;
11633 }
103f02d3 11634
9ea033b2
NC
11635 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
11636 return 0;
103f02d3 11637
9ea033b2
NC
11638 elf_header.e_type = BYTE_GET (ehdr64.e_type);
11639 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
11640 elf_header.e_version = BYTE_GET (ehdr64.e_version);
11641 elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry);
11642 elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff);
11643 elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff);
11644 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
11645 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
11646 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
11647 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
11648 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
11649 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
11650 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
11651 }
252b5132 11652
7ece0d85
JJ
11653 if (elf_header.e_shoff)
11654 {
11655 /* There may be some extensions in the first section header. Don't
11656 bomb if we can't read it. */
11657 if (is_32bit_elf)
11658 get_32bit_section_headers (file, 1);
11659 else
11660 get_64bit_section_headers (file, 1);
11661 }
560f3c1c 11662
252b5132
RH
11663 return 1;
11664}
11665
fb52b2f4
NC
11666/* Process one ELF object file according to the command line options.
11667 This file may actually be stored in an archive. The file is
11668 positioned at the start of the ELF object. */
11669
ff78d6d6 11670static int
fb52b2f4 11671process_object (char *file_name, FILE *file)
252b5132 11672{
252b5132
RH
11673 unsigned int i;
11674
252b5132
RH
11675 if (! get_file_header (file))
11676 {
11677 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 11678 return 1;
252b5132
RH
11679 }
11680
11681 /* Initialise per file variables. */
11682 for (i = NUM_ELEM (version_info); i--;)
11683 version_info[i] = 0;
11684
11685 for (i = NUM_ELEM (dynamic_info); i--;)
11686 dynamic_info[i] = 0;
11687
11688 /* Process the file. */
11689 if (show_name)
11690 printf (_("\nFile: %s\n"), file_name);
11691
18bd398b
NC
11692 /* Initialise the dump_sects array from the cmdline_dump_sects array.
11693 Note we do this even if cmdline_dump_sects is empty because we
11694 must make sure that the dump_sets array is zeroed out before each
11695 object file is processed. */
11696 if (num_dump_sects > num_cmdline_dump_sects)
11697 memset (dump_sects, 0, num_dump_sects);
11698
11699 if (num_cmdline_dump_sects > 0)
11700 {
11701 if (num_dump_sects == 0)
11702 /* A sneaky way of allocating the dump_sects array. */
11703 request_dump (num_cmdline_dump_sects, 0);
11704
11705 assert (num_dump_sects >= num_cmdline_dump_sects);
11706 memcpy (dump_sects, cmdline_dump_sects, num_cmdline_dump_sects);
11707 }
11708
252b5132 11709 if (! process_file_header ())
fb52b2f4 11710 return 1;
252b5132 11711
d1f5c6e3 11712 if (! process_section_headers (file))
2f62977e 11713 {
d1f5c6e3
L
11714 /* Without loaded section headers we cannot process lots of
11715 things. */
2f62977e 11716 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 11717
2f62977e
NC
11718 if (! do_using_dynamic)
11719 do_syms = do_reloc = 0;
11720 }
252b5132 11721
d1f5c6e3
L
11722 if (! process_section_groups (file))
11723 {
11724 /* Without loaded section groups we cannot process unwind. */
11725 do_unwind = 0;
11726 }
11727
2f62977e 11728 if (process_program_headers (file))
b2d38a17 11729 process_dynamic_section (file);
252b5132
RH
11730
11731 process_relocs (file);
11732
4d6ed7c8
NC
11733 process_unwind (file);
11734
252b5132
RH
11735 process_symbol_table (file);
11736
11737 process_syminfo (file);
11738
11739 process_version_sections (file);
11740
11741 process_section_contents (file);
f5842774 11742
1ec5cd37 11743 process_notes (file);
103f02d3 11744
047b2264
JJ
11745 process_gnu_liblist (file);
11746
252b5132
RH
11747 process_arch_specific (file);
11748
d93f0186
NC
11749 if (program_headers)
11750 {
11751 free (program_headers);
11752 program_headers = NULL;
11753 }
11754
252b5132
RH
11755 if (section_headers)
11756 {
11757 free (section_headers);
11758 section_headers = NULL;
11759 }
11760
11761 if (string_table)
11762 {
11763 free (string_table);
11764 string_table = NULL;
d40ac9bd 11765 string_table_length = 0;
252b5132
RH
11766 }
11767
11768 if (dynamic_strings)
11769 {
11770 free (dynamic_strings);
11771 dynamic_strings = NULL;
d79b3d50 11772 dynamic_strings_length = 0;
252b5132
RH
11773 }
11774
11775 if (dynamic_symbols)
11776 {
11777 free (dynamic_symbols);
11778 dynamic_symbols = NULL;
19936277 11779 num_dynamic_syms = 0;
252b5132
RH
11780 }
11781
11782 if (dynamic_syminfo)
11783 {
11784 free (dynamic_syminfo);
11785 dynamic_syminfo = NULL;
11786 }
ff78d6d6 11787
e4b17d5c
L
11788 if (section_headers_groups)
11789 {
11790 free (section_headers_groups);
11791 section_headers_groups = NULL;
11792 }
11793
11794 if (section_groups)
11795 {
11796 struct group_list *g, *next;
11797
11798 for (i = 0; i < group_count; i++)
11799 {
11800 for (g = section_groups [i].root; g != NULL; g = next)
11801 {
11802 next = g->next;
11803 free (g);
11804 }
11805 }
11806
11807 free (section_groups);
11808 section_groups = NULL;
11809 }
11810
18bd398b
NC
11811 if (debug_information)
11812 {
5b18a4bc 11813 for (i = 0; i < num_debug_info_entries; i++)
0853c092
L
11814 {
11815 if (!debug_information [i].max_loc_offsets)
11816 {
11817 free (debug_information [i].loc_offsets);
11818 free (debug_information [i].have_frame_base);
11819 }
11820 if (!debug_information [i].max_range_lists)
11821 free (debug_information [i].range_lists);
11822 }
18bd398b
NC
11823 free (debug_information);
11824 debug_information = NULL;
11825 num_debug_info_entries = 0;
11826 }
11827
ff78d6d6 11828 return 0;
252b5132
RH
11829}
11830
fb52b2f4
NC
11831/* Process an ELF archive. The file is positioned just after the
11832 ARMAG string. */
11833
11834static int
11835process_archive (char *file_name, FILE *file)
11836{
11837 struct ar_hdr arhdr;
11838 size_t got;
11839 unsigned long size;
11840 char *longnames = NULL;
11841 unsigned long longnames_size = 0;
11842 size_t file_name_size;
d989285c 11843 int ret;
fb52b2f4
NC
11844
11845 show_name = 1;
11846
11847 got = fread (&arhdr, 1, sizeof arhdr, file);
11848 if (got != sizeof arhdr)
11849 {
11850 if (got == 0)
11851 return 0;
11852
11853 error (_("%s: failed to read archive header\n"), file_name);
11854 return 1;
11855 }
11856
11857 if (memcmp (arhdr.ar_name, "/ ", 16) == 0)
11858 {
11859 /* This is the archive symbol table. Skip it.
11860 FIXME: We should have an option to dump it. */
11861 size = strtoul (arhdr.ar_size, NULL, 10);
11862 if (fseek (file, size + (size & 1), SEEK_CUR) != 0)
11863 {
11864 error (_("%s: failed to skip archive symbol table\n"), file_name);
11865 return 1;
11866 }
11867
11868 got = fread (&arhdr, 1, sizeof arhdr, file);
11869 if (got != sizeof arhdr)
11870 {
11871 if (got == 0)
11872 return 0;
11873
11874 error (_("%s: failed to read archive header\n"), file_name);
11875 return 1;
11876 }
11877 }
11878
11879 if (memcmp (arhdr.ar_name, "// ", 16) == 0)
11880 {
11881 /* This is the archive string table holding long member
11882 names. */
11883
11884 longnames_size = strtoul (arhdr.ar_size, NULL, 10);
11885
11886 longnames = malloc (longnames_size);
11887 if (longnames == NULL)
11888 {
11889 error (_("Out of memory\n"));
11890 return 1;
11891 }
11892
11893 if (fread (longnames, longnames_size, 1, file) != 1)
11894 {
d989285c 11895 free (longnames);
18bd398b 11896 error (_("%s: failed to read string table\n"), file_name);
fb52b2f4
NC
11897 return 1;
11898 }
11899
11900 if ((longnames_size & 1) != 0)
11901 getc (file);
11902
11903 got = fread (&arhdr, 1, sizeof arhdr, file);
11904 if (got != sizeof arhdr)
11905 {
d989285c
ILT
11906 free (longnames);
11907
fb52b2f4
NC
11908 if (got == 0)
11909 return 0;
11910
11911 error (_("%s: failed to read archive header\n"), file_name);
11912 return 1;
11913 }
11914 }
11915
11916 file_name_size = strlen (file_name);
d989285c 11917 ret = 0;
fb52b2f4
NC
11918
11919 while (1)
11920 {
11921 char *name;
11922 char *nameend;
11923 char *namealc;
11924
11925 if (arhdr.ar_name[0] == '/')
11926 {
11927 unsigned long off;
11928
11929 off = strtoul (arhdr.ar_name + 1, NULL, 10);
11930 if (off >= longnames_size)
11931 {
11932 error (_("%s: invalid archive string table offset %lu\n"), off);
d989285c
ILT
11933 ret = 1;
11934 break;
fb52b2f4
NC
11935 }
11936
11937 name = longnames + off;
11938 nameend = memchr (name, '/', longnames_size - off);
11939 }
11940 else
11941 {
11942 name = arhdr.ar_name;
11943 nameend = memchr (name, '/', 16);
11944 }
11945
11946 if (nameend == NULL)
11947 {
11948 error (_("%s: bad archive file name\n"));
d989285c
ILT
11949 ret = 1;
11950 break;
fb52b2f4
NC
11951 }
11952
11953 namealc = malloc (file_name_size + (nameend - name) + 3);
11954 if (namealc == NULL)
11955 {
11956 error (_("Out of memory\n"));
d989285c
ILT
11957 ret = 1;
11958 break;
fb52b2f4
NC
11959 }
11960
11961 memcpy (namealc, file_name, file_name_size);
11962 namealc[file_name_size] = '(';
11963 memcpy (namealc + file_name_size + 1, name, nameend - name);
11964 namealc[file_name_size + 1 + (nameend - name)] = ')';
11965 namealc[file_name_size + 2 + (nameend - name)] = '\0';
11966
11967 archive_file_offset = ftell (file);
11968 archive_file_size = strtoul (arhdr.ar_size, NULL, 10);
18bd398b 11969
d989285c 11970 ret |= process_object (namealc, file);
fb52b2f4
NC
11971
11972 free (namealc);
11973
11974 if (fseek (file,
11975 (archive_file_offset
11976 + archive_file_size
11977 + (archive_file_size & 1)),
11978 SEEK_SET) != 0)
11979 {
11980 error (_("%s: failed to seek to next archive header\n"), file_name);
d989285c
ILT
11981 ret = 1;
11982 break;
fb52b2f4
NC
11983 }
11984
11985 got = fread (&arhdr, 1, sizeof arhdr, file);
11986 if (got != sizeof arhdr)
11987 {
11988 if (got == 0)
d989285c 11989 break;
fb52b2f4
NC
11990
11991 error (_("%s: failed to read archive header\n"), file_name);
d989285c
ILT
11992 ret = 1;
11993 break;
fb52b2f4
NC
11994 }
11995 }
11996
11997 if (longnames != 0)
11998 free (longnames);
11999
d989285c 12000 return ret;
fb52b2f4
NC
12001}
12002
12003static int
12004process_file (char *file_name)
12005{
12006 FILE *file;
12007 struct stat statbuf;
12008 char armag[SARMAG];
12009 int ret;
12010
12011 if (stat (file_name, &statbuf) < 0)
12012 {
f24ddbdd
NC
12013 if (errno == ENOENT)
12014 error (_("'%s': No such file\n"), file_name);
12015 else
12016 error (_("Could not locate '%s'. System error message: %s\n"),
12017 file_name, strerror (errno));
12018 return 1;
12019 }
12020
12021 if (! S_ISREG (statbuf.st_mode))
12022 {
12023 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
12024 return 1;
12025 }
12026
12027 file = fopen (file_name, "rb");
12028 if (file == NULL)
12029 {
f24ddbdd 12030 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
12031 return 1;
12032 }
12033
12034 if (fread (armag, SARMAG, 1, file) != 1)
12035 {
12036 error (_("%s: Failed to read file header\n"), file_name);
12037 fclose (file);
12038 return 1;
12039 }
12040
12041 if (memcmp (armag, ARMAG, SARMAG) == 0)
12042 ret = process_archive (file_name, file);
12043 else
12044 {
12045 rewind (file);
12046 archive_file_size = archive_file_offset = 0;
12047 ret = process_object (file_name, file);
12048 }
12049
12050 fclose (file);
12051
12052 return ret;
12053}
12054
252b5132
RH
12055#ifdef SUPPORT_DISASSEMBLY
12056/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 12057 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 12058 symbols. */
252b5132
RH
12059
12060void
b34976b6 12061print_address (unsigned int addr, FILE *outfile)
252b5132
RH
12062{
12063 fprintf (outfile,"0x%8.8x", addr);
12064}
12065
e3c8793a 12066/* Needed by the i386 disassembler. */
252b5132
RH
12067void
12068db_task_printsym (unsigned int addr)
12069{
12070 print_address (addr, stderr);
12071}
12072#endif
12073
12074int
d3ba0551 12075main (int argc, char **argv)
252b5132 12076{
ff78d6d6
L
12077 int err;
12078
252b5132
RH
12079#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
12080 setlocale (LC_MESSAGES, "");
3882b010
L
12081#endif
12082#if defined (HAVE_SETLOCALE)
12083 setlocale (LC_CTYPE, "");
252b5132
RH
12084#endif
12085 bindtextdomain (PACKAGE, LOCALEDIR);
12086 textdomain (PACKAGE);
12087
12088 parse_args (argc, argv);
12089
18bd398b 12090 if (num_dump_sects > 0)
59f14fc0 12091 {
18bd398b 12092 /* Make a copy of the dump_sects array. */
59f14fc0
AS
12093 cmdline_dump_sects = malloc (num_dump_sects);
12094 if (cmdline_dump_sects == NULL)
12095 error (_("Out of memory allocating dump request table."));
12096 else
12097 {
12098 memcpy (cmdline_dump_sects, dump_sects, num_dump_sects);
12099 num_cmdline_dump_sects = num_dump_sects;
12100 }
12101 }
12102
18bd398b
NC
12103 if (optind < (argc - 1))
12104 show_name = 1;
12105
ff78d6d6 12106 err = 0;
252b5132 12107 while (optind < argc)
18bd398b 12108 err |= process_file (argv[optind++]);
252b5132
RH
12109
12110 if (dump_sects != NULL)
12111 free (dump_sects);
59f14fc0
AS
12112 if (cmdline_dump_sects != NULL)
12113 free (cmdline_dump_sects);
252b5132 12114
ff78d6d6 12115 return err;
252b5132 12116}
This page took 1.039302 seconds and 4 git commands to generate.