]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
2005-02-18 Andrew Cagney <cagney@gnu.org>
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
5b18a4bc 2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
74013231 3 Free Software Foundation, Inc.
252b5132
RH
4
5 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 6 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
7
8 This file is part of GNU Binutils.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23 02111-1307, USA. */
24\f
9eb20dd8 25/* The difference between readelf and objdump:
252b5132 26
74013231 27 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 28 so why does the binutils project have two file dumpers ?
0de14b54 29
9eb20dd8
NC
30 The reason is that objdump sees an ELF file through a BFD filter of the
31 world; if BFD has a bug where, say, it disagrees about a machine constant
32 in e_flags, then the odds are good that it will remain internally
33 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
34 GAS sees it the BFD way. There was need for a tool to go find out what
35 the file actually says.
36
37 This is why the readelf program does not link against the BFD library - it
38 exists as an independent program to help verify the correct working of BFD.
39
40 There is also the case that readelf can provide more information about an
41 ELF file than is provided by objdump. In particular it can display DWARF
42 debugging information which (at the moment) objdump cannot. */
43\f
252b5132 44#include <assert.h>
00ed88bd 45#include <sys/types.h>
252b5132
RH
46#include <sys/stat.h>
47#include <stdio.h>
48#include <time.h>
49
a952a375 50#if __GNUC__ >= 2
19936277 51/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 52 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 53 Only do this if we believe that the compiler can support a 64 bit
a952a375 54 data type. For now we only rely on GCC being able to do this. */
19936277 55#define BFD64
a952a375
NC
56#endif
57
252b5132
RH
58#include "bfd.h"
59
60#include "elf/common.h"
61#include "elf/external.h"
62#include "elf/internal.h"
63#include "elf/dwarf2.h"
64
65/* The following headers use the elf/reloc-macros.h file to
66 automatically generate relocation recognition functions
67 such as elf_mips_reloc_type() */
68
69#define RELOC_MACROS_GEN_FUNC
70
252b5132 71#include "elf/alpha.h"
3b16e843 72#include "elf/arc.h"
252b5132 73#include "elf/arm.h"
3b16e843
NC
74#include "elf/avr.h"
75#include "elf/cris.h"
252b5132
RH
76#include "elf/d10v.h"
77#include "elf/d30v.h"
d172d4ba 78#include "elf/dlx.h"
252b5132 79#include "elf/fr30.h"
5c70f934 80#include "elf/frv.h"
3b16e843
NC
81#include "elf/h8.h"
82#include "elf/hppa.h"
83#include "elf/i386.h"
35b1837e 84#include "elf/i370.h"
3b16e843
NC
85#include "elf/i860.h"
86#include "elf/i960.h"
87#include "elf/ia64.h"
1e4cf259 88#include "elf/ip2k.h"
3b16e843
NC
89#include "elf/m32r.h"
90#include "elf/m68k.h"
75751cd9 91#include "elf/m68hc11.h"
252b5132 92#include "elf/mcore.h"
3b16e843 93#include "elf/mips.h"
3c3bdf30 94#include "elf/mmix.h"
3b16e843
NC
95#include "elf/mn10200.h"
96#include "elf/mn10300.h"
2469cfa2 97#include "elf/msp430.h"
3b16e843 98#include "elf/or32.h"
7d466069 99#include "elf/pj.h"
3b16e843 100#include "elf/ppc.h"
c833c019 101#include "elf/ppc64.h"
a85d7ed0 102#include "elf/s390.h"
3b16e843
NC
103#include "elf/sh.h"
104#include "elf/sparc.h"
105#include "elf/v850.h"
179d3252 106#include "elf/vax.h"
3b16e843 107#include "elf/x86-64.h"
93fbbb04 108#include "elf/xstormy16.h"
1fe1f39c 109#include "elf/crx.h"
3b36097d 110#include "elf/iq2000.h"
88da6820 111#include "elf/xtensa.h"
252b5132 112
fb52b2f4
NC
113#include "aout/ar.h"
114
252b5132
RH
115#include "bucomm.h"
116#include "getopt.h"
566b0d53 117#include "libiberty.h"
252b5132 118
b34976b6 119char *program_name = "readelf";
fb52b2f4
NC
120long archive_file_offset;
121unsigned long archive_file_size;
3e8bba36 122unsigned long dynamic_addr;
b34976b6 123bfd_size_type dynamic_size;
86dba8ee 124unsigned int dynamic_nent;
b34976b6 125char *dynamic_strings;
d79b3d50 126unsigned long dynamic_strings_length;
b34976b6
AM
127char *string_table;
128unsigned long string_table_length;
129unsigned long num_dynamic_syms;
130Elf_Internal_Sym *dynamic_symbols;
131Elf_Internal_Syminfo *dynamic_syminfo;
132unsigned long dynamic_syminfo_offset;
133unsigned int dynamic_syminfo_nent;
134char program_interpreter[64];
d93f0186
NC
135bfd_vma dynamic_info[DT_JMPREL + 1];
136bfd_vma version_info[16];
b34976b6
AM
137Elf_Internal_Ehdr elf_header;
138Elf_Internal_Shdr *section_headers;
d93f0186 139Elf_Internal_Phdr *program_headers;
b2d38a17 140Elf_Internal_Dyn *dynamic_section;
b34976b6
AM
141Elf_Internal_Shdr *symtab_shndx_hdr;
142int show_name;
143int do_dynamic;
144int do_syms;
145int do_reloc;
146int do_sections;
f5842774 147int do_section_groups;
b34976b6
AM
148int do_segments;
149int do_unwind;
150int do_using_dynamic;
151int do_header;
152int do_dump;
153int do_version;
154int do_wide;
155int do_histogram;
156int do_debugging;
157int do_debug_info;
158int do_debug_abbrevs;
159int do_debug_lines;
160int do_debug_pubnames;
161int do_debug_aranges;
18bd398b 162int do_debug_ranges;
b34976b6
AM
163int do_debug_frames;
164int do_debug_frames_interp;
165int do_debug_macinfo;
166int do_debug_str;
167int do_debug_loc;
168int do_arch;
169int do_notes;
170int is_32bit_elf;
b38c7015
L
171int have_frame_base;
172int need_base_address;
89fac5e3 173bfd_vma eh_addr_size;
252b5132 174
e4b17d5c
L
175struct group_list
176{
177 struct group_list *next;
178 unsigned int section_index;
179};
180
181struct group
182{
183 struct group_list *root;
184 unsigned int group_index;
185};
186
187struct group *section_groups;
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
NC
9492 if (begin == 0 && end == 0)
9493 break;
c0e047e0 9494
b38c7015
L
9495 /* Check base address specifiers. */
9496 if (begin == -1UL && end != -1UL)
9497 {
9498 base_address = end;
e54b12b7
L
9499 printf (" %8.8lx %8.8lx %8.8lx (base address)\n",
9500 offset, begin, end);
b38c7015
L
9501 continue;
9502 }
adab8cdc 9503
5b18a4bc
NC
9504 length = byte_get (start, 2);
9505 start += 2;
252b5132 9506
5b18a4bc 9507 printf (" %8.8lx %8.8lx %8.8lx (",
b38c7015
L
9508 offset, begin + base_address, end + base_address);
9509 need_frame_base = decode_location_expression (start,
9510 pointer_size,
9511 length,
9512 cu_offset);
9513 putchar (')');
09fd7e38 9514
b38c7015
L
9515 if (need_frame_base && !has_frame_base)
9516 printf (_(" [without DW_AT_frame_base]"));
9517
9518 if (begin == end)
9519 fputs (_(" (start == end)"), stdout);
9520 else if (begin > end)
9521 fputs (_(" (start > end)"), stdout);
9522
9523 putchar ('\n');
252b5132 9524
5b18a4bc
NC
9525 start += length;
9526 }
252b5132 9527
e54b12b7 9528 fputs (_(" <End of list>\n"), stdout);
5b18a4bc
NC
9529 }
9530 }
9531 return 1;
9532}
252b5132 9533
5b18a4bc
NC
9534static int
9535display_debug_str (Elf_Internal_Shdr *section,
9536 unsigned char *start,
9537 FILE *file ATTRIBUTE_UNUSED)
9538{
9539 unsigned long bytes;
9540 bfd_vma addr;
252b5132 9541
5b18a4bc
NC
9542 addr = section->sh_addr;
9543 bytes = section->sh_size;
252b5132 9544
5b18a4bc
NC
9545 if (bytes == 0)
9546 {
9547 printf (_("\nThe .debug_str section is empty.\n"));
9548 return 0;
9549 }
252b5132 9550
5b18a4bc 9551 printf (_("Contents of the .debug_str section:\n\n"));
252b5132 9552
5b18a4bc
NC
9553 while (bytes)
9554 {
9555 int j;
9556 int k;
9557 int lbytes;
252b5132 9558
5b18a4bc 9559 lbytes = (bytes > 16 ? 16 : bytes);
252b5132 9560
5b18a4bc 9561 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132 9562
5b18a4bc
NC
9563 for (j = 0; j < 16; j++)
9564 {
9565 if (j < lbytes)
9566 printf ("%2.2x", start[j]);
9567 else
9568 printf (" ");
252b5132 9569
5b18a4bc
NC
9570 if ((j & 3) == 3)
9571 printf (" ");
9572 }
252b5132 9573
5b18a4bc
NC
9574 for (j = 0; j < lbytes; j++)
9575 {
9576 k = start[j];
9577 if (k >= ' ' && k < 0x80)
9578 printf ("%c", k);
9579 else
9580 printf (".");
9581 }
252b5132 9582
5b18a4bc 9583 putchar ('\n');
252b5132 9584
5b18a4bc
NC
9585 start += lbytes;
9586 addr += lbytes;
9587 bytes -= lbytes;
252b5132
RH
9588 }
9589
b0660586
L
9590 putchar ('\n');
9591
5b18a4bc
NC
9592 return 1;
9593}
ef5cdfc7 9594
252b5132 9595
5b18a4bc
NC
9596static int
9597display_debug_info (Elf_Internal_Shdr * section,
9598 unsigned char * start, FILE * file)
9599{
9600 return process_debug_info (section, start, file, 0);
252b5132
RH
9601}
9602
5b18a4bc 9603
252b5132 9604static int
d3ba0551
AM
9605display_debug_aranges (Elf_Internal_Shdr *section,
9606 unsigned char *start,
9607 FILE *file ATTRIBUTE_UNUSED)
252b5132 9608{
b34976b6 9609 unsigned char *end = start + section->sh_size;
252b5132
RH
9610
9611 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
9612
9613 while (start < end)
9614 {
ee42cf8c 9615 unsigned char *hdrptr;
b34976b6
AM
9616 DWARF2_Internal_ARange arange;
9617 unsigned char *ranges;
9618 unsigned long length;
9619 unsigned long address;
9620 int excess;
ee42cf8c
NC
9621 int offset_size;
9622 int initial_length_size;
252b5132 9623
ee42cf8c 9624 hdrptr = start;
252b5132 9625
ee42cf8c
NC
9626 arange.ar_length = byte_get (hdrptr, 4);
9627 hdrptr += 4;
252b5132 9628
e414a165
NC
9629 if (arange.ar_length == 0xffffffff)
9630 {
ee42cf8c
NC
9631 arange.ar_length = byte_get (hdrptr, 8);
9632 hdrptr += 8;
9633 offset_size = 8;
9634 initial_length_size = 12;
9635 }
9636 else
ba2685cc 9637 {
ee42cf8c
NC
9638 offset_size = 4;
9639 initial_length_size = 4;
e414a165
NC
9640 }
9641
ee42cf8c
NC
9642 arange.ar_version = byte_get (hdrptr, 2);
9643 hdrptr += 2;
9644
9645 arange.ar_info_offset = byte_get (hdrptr, offset_size);
9646 hdrptr += offset_size;
9647
9648 arange.ar_pointer_size = byte_get (hdrptr, 1);
9649 hdrptr += 1;
9650
9651 arange.ar_segment_size = byte_get (hdrptr, 1);
9652 hdrptr += 1;
9653
9654 if (arange.ar_version != 2 && arange.ar_version != 3)
3f215a10 9655 {
ee42cf8c 9656 warn (_("Only DWARF 2 and 3 aranges are currently supported.\n"));
3f215a10
NC
9657 break;
9658 }
9659
252b5132
RH
9660 printf (_(" Length: %ld\n"), arange.ar_length);
9661 printf (_(" Version: %d\n"), arange.ar_version);
9662 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
9663 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
9664 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
9665
9666 printf (_("\n Address Length\n"));
9667
ee42cf8c 9668 ranges = hdrptr;
252b5132 9669
7a4b7442 9670 /* Must pad to an alignment boundary that is twice the pointer size. */
ee42cf8c 9671 excess = (hdrptr - start) % (2 * arange.ar_pointer_size);
7a4b7442
NC
9672 if (excess)
9673 ranges += (2 * arange.ar_pointer_size) - excess;
9674
252b5132
RH
9675 for (;;)
9676 {
9677 address = byte_get (ranges, arange.ar_pointer_size);
9678
252b5132
RH
9679 ranges += arange.ar_pointer_size;
9680
9681 length = byte_get (ranges, arange.ar_pointer_size);
9682
9683 ranges += arange.ar_pointer_size;
9684
7a4b7442
NC
9685 /* A pair of zeros marks the end of the list. */
9686 if (address == 0 && length == 0)
9687 break;
103f02d3 9688
252b5132
RH
9689 printf (" %8.8lx %lu\n", address, length);
9690 }
9691
ee42cf8c 9692 start += arange.ar_length + initial_length_size;
252b5132
RH
9693 }
9694
9695 printf ("\n");
9696
9697 return 1;
9698}
9699
18bd398b 9700static int
0853c092
L
9701display_debug_ranges (Elf_Internal_Shdr *section,
9702 unsigned char *start,
9703 FILE *file ATTRIBUTE_UNUSED)
18bd398b 9704{
0853c092
L
9705 unsigned char *section_end;
9706 unsigned long bytes;
9707 unsigned char *section_begin = start;
9708 unsigned int num_range_list = 0;
9709 unsigned long last_offset = 0;
9710 unsigned int first = 0;
9711 unsigned int i;
9712 unsigned int j;
9713 int seen_first_offset = 0;
9714 int use_debug_info = 1;
9715 unsigned char *next;
18bd398b 9716
0853c092
L
9717 bytes = section->sh_size;
9718 section_end = start + bytes;
9719
9720 if (bytes == 0)
18bd398b 9721 {
0853c092
L
9722 printf (_("\nThe .debug_ranges section is empty.\n"));
9723 return 0;
9724 }
18bd398b 9725
0853c092 9726 get_debug_info (file);
18bd398b 9727
0853c092
L
9728 /* Check the order of range list in .debug_info section. If
9729 offsets of range lists are in the ascending order, we can
9730 use `debug_information' directly. */
9731 for (i = 0; i < num_debug_info_entries; i++)
9732 {
9733 unsigned int num;
9734
9735 num = debug_information [i].num_range_lists;
9736 num_range_list += num;
9737
9738 /* Check if we can use `debug_information' directly. */
9739 if (use_debug_info && num != 0)
18bd398b 9740 {
0853c092
L
9741 if (!seen_first_offset)
9742 {
9743 /* This is the first range list. */
9744 last_offset = debug_information [i].range_lists [0];
9745 first = i;
9746 seen_first_offset = 1;
9747 j = 1;
9748 }
9749 else
9750 j = 0;
18bd398b 9751
0853c092
L
9752 for (; j < num; j++)
9753 {
9754 if (last_offset >
9755 debug_information [i].range_lists [j])
9756 {
9757 use_debug_info = 0;
9758 break;
9759 }
9760 last_offset = debug_information [i].range_lists [j];
9761 }
9762 }
18bd398b
NC
9763 }
9764
0853c092
L
9765 if (!use_debug_info)
9766 /* FIXME: Should we handle this case? */
9767 error (_("Range lists in .debug_info section aren't in ascending order!\n"));
18bd398b 9768
0853c092
L
9769 if (!seen_first_offset)
9770 error (_("No range lists in .debug_info section!\n"));
18bd398b 9771
0853c092
L
9772 if (debug_information [first].range_lists [0] != 0)
9773 warn (_("Range lists in .debug_ranges section start at 0x%lx\n"),
9774 debug_information [first].range_lists [0]);
18bd398b 9775
0853c092
L
9776 printf (_("Contents of the .debug_ranges section:\n\n"));
9777 printf (_(" Offset Begin End\n"));
9778
9779 seen_first_offset = 0;
9780 for (i = first; i < num_debug_info_entries; i++)
18bd398b 9781 {
0853c092
L
9782 unsigned long begin;
9783 unsigned long end;
9784 unsigned long offset;
9785 unsigned int pointer_size;
9786 unsigned long base_address;
18bd398b 9787
0853c092 9788 pointer_size = debug_information [i].pointer_size;
18bd398b 9789
0853c092 9790 for (j = 0; j < debug_information [i].num_range_lists; j++)
18bd398b 9791 {
0853c092
L
9792 offset = debug_information [i].range_lists [j];
9793 next = section_begin + offset;
9794 base_address = debug_information [i].base_address;
18bd398b 9795
0853c092
L
9796 if (!seen_first_offset)
9797 seen_first_offset = 1;
9798 else
9799 {
9800 if (start < next)
9801 warn (_("There is a hole [0x%lx - 0x%lx] in .debug_ranges section.\n"),
9802 start - section_begin, next - section_begin);
9803 else if (start > next)
9804 warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_ranges section.\n"),
9805 start - section_begin, next - section_begin);
9806 }
9807 start = next;
9808
9809 while (1)
9810 {
9811 begin = byte_get (start, pointer_size);
9812 start += pointer_size;
9813 end = byte_get (start, pointer_size);
9814 start += pointer_size;
9815
9816 if (begin == 0 && end == 0)
9817 break;
9818
9819 /* Check base address specifiers. */
9820 if (begin == -1UL && end != -1UL)
9821 {
9822 base_address = end;
9823 printf (" %8.8lx %8.8lx %8.8lx (base address)\n",
9824 offset, begin, end);
9825 continue;
9826 }
9827
9828 printf (" %8.8lx %8.8lx %8.8lx",
9829 offset, begin + base_address, end + base_address);
9830
9831 if (begin == end)
9832 fputs (_(" (start == end)"), stdout);
9833 else if (begin > end)
9834 fputs (_(" (start > end)"), stdout);
18bd398b 9835
0853c092
L
9836 putchar ('\n');
9837 }
9838 fputs (_(" <End of list>\n"), stdout);
9839 }
9840 }
9841 putchar ('\n');
18bd398b
NC
9842 return 1;
9843}
9844
c47d488e
DD
9845typedef struct Frame_Chunk
9846{
b34976b6
AM
9847 struct Frame_Chunk *next;
9848 unsigned char *chunk_start;
9849 int ncols;
a98cc2b2 9850 /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */
b34976b6
AM
9851 short int *col_type;
9852 int *col_offset;
9853 char *augmentation;
9854 unsigned int code_factor;
9855 int data_factor;
9856 unsigned long pc_begin;
9857 unsigned long pc_range;
9858 int cfa_reg;
9859 int cfa_offset;
9860 int ra;
9861 unsigned char fde_encoding;
63044634 9862 unsigned char cfa_exp;
c47d488e
DD
9863}
9864Frame_Chunk;
9865
a98cc2b2
AH
9866/* A marker for a col_type that means this column was never referenced
9867 in the frame info. */
9868#define DW_CFA_unreferenced (-1)
9869
c47d488e 9870static void
d3ba0551 9871frame_need_space (Frame_Chunk *fc, int reg)
c47d488e
DD
9872{
9873 int prev = fc->ncols;
9874
9875 if (reg < fc->ncols)
9876 return;
584da044 9877
c47d488e 9878 fc->ncols = reg + 1;
d3ba0551
AM
9879 fc->col_type = xrealloc (fc->col_type, fc->ncols * sizeof (short int));
9880 fc->col_offset = xrealloc (fc->col_offset, fc->ncols * sizeof (int));
c47d488e
DD
9881
9882 while (prev < fc->ncols)
9883 {
a98cc2b2 9884 fc->col_type[prev] = DW_CFA_unreferenced;
c47d488e
DD
9885 fc->col_offset[prev] = 0;
9886 prev++;
9887 }
9888}
9889
9890static void
d3ba0551 9891frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
c47d488e
DD
9892{
9893 int r;
9894 char tmp[100];
9895
b34976b6
AM
9896 if (*max_regs < fc->ncols)
9897 *max_regs = fc->ncols;
584da044 9898
b34976b6 9899 if (*need_col_headers)
c47d488e 9900 {
b34976b6 9901 *need_col_headers = 0;
584da044 9902
c47d488e 9903 printf (" LOC CFA ");
584da044 9904
b34976b6 9905 for (r = 0; r < *max_regs; r++)
a98cc2b2
AH
9906 if (fc->col_type[r] != DW_CFA_unreferenced)
9907 {
9908 if (r == fc->ra)
9909 printf ("ra ");
9910 else
9911 printf ("r%-4d", r);
9912 }
584da044 9913
c47d488e
DD
9914 printf ("\n");
9915 }
584da044 9916
31b6fca6 9917 printf ("%08lx ", fc->pc_begin);
63044634
RH
9918 if (fc->cfa_exp)
9919 strcpy (tmp, "exp");
9920 else
9921 sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
c47d488e 9922 printf ("%-8s ", tmp);
584da044
NC
9923
9924 for (r = 0; r < fc->ncols; r++)
c47d488e 9925 {
a98cc2b2 9926 if (fc->col_type[r] != DW_CFA_unreferenced)
c47d488e 9927 {
a98cc2b2
AH
9928 switch (fc->col_type[r])
9929 {
9930 case DW_CFA_undefined:
9931 strcpy (tmp, "u");
9932 break;
9933 case DW_CFA_same_value:
9934 strcpy (tmp, "s");
9935 break;
9936 case DW_CFA_offset:
9937 sprintf (tmp, "c%+d", fc->col_offset[r]);
9938 break;
9939 case DW_CFA_register:
9940 sprintf (tmp, "r%d", fc->col_offset[r]);
9941 break;
63044634
RH
9942 case DW_CFA_expression:
9943 strcpy (tmp, "exp");
9944 break;
a98cc2b2
AH
9945 default:
9946 strcpy (tmp, "n/a");
9947 break;
9948 }
9949 printf ("%-5s", tmp);
c47d488e 9950 }
c47d488e
DD
9951 }
9952 printf ("\n");
9953}
9954
31b6fca6 9955static int
d3ba0551 9956size_of_encoded_value (int encoding)
31b6fca6
RH
9957{
9958 switch (encoding & 0x7)
9959 {
9960 default: /* ??? */
89fac5e3 9961 case 0: return eh_addr_size;
31b6fca6
RH
9962 case 2: return 2;
9963 case 3: return 4;
9964 case 4: return 8;
9965 }
9966}
9967
38fafa6d 9968static bfd_vma
d3ba0551 9969get_encoded_value (unsigned char *data, int encoding)
38fafa6d
RH
9970{
9971 int size = size_of_encoded_value (encoding);
9972 if (encoding & DW_EH_PE_signed)
9973 return byte_get_signed (data, size);
9974 else
9975 return byte_get (data, size);
9976}
9977
c47d488e 9978#define GET(N) byte_get (start, N); start += N
584da044
NC
9979#define LEB() read_leb128 (start, & length_return, 0); start += length_return
9980#define SLEB() read_leb128 (start, & length_return, 1); start += length_return
c47d488e
DD
9981
9982static int
d3ba0551
AM
9983display_debug_frames (Elf_Internal_Shdr *section,
9984 unsigned char *start,
9985 FILE *file ATTRIBUTE_UNUSED)
c47d488e 9986{
b34976b6
AM
9987 unsigned char *end = start + section->sh_size;
9988 unsigned char *section_start = start;
9989 Frame_Chunk *chunks = 0;
9990 Frame_Chunk *remembered_state = 0;
9991 Frame_Chunk *rs;
18bd398b 9992 int is_eh = streq (SECTION_NAME (section), ".eh_frame");
b34976b6
AM
9993 int length_return;
9994 int max_regs = 0;
c47d488e
DD
9995
9996 printf (_("The section %s contains:\n"), SECTION_NAME (section));
9997
9998 while (start < end)
9999 {
b34976b6
AM
10000 unsigned char *saved_start;
10001 unsigned char *block_end;
10002 unsigned long length;
10003 unsigned long cie_id;
10004 Frame_Chunk *fc;
10005 Frame_Chunk *cie;
10006 int need_col_headers = 1;
10007 unsigned char *augmentation_data = NULL;
10008 unsigned long augmentation_data_len = 0;
89fac5e3 10009 int encoded_ptr_size = eh_addr_size;
ee42cf8c
NC
10010 int offset_size;
10011 int initial_length_size;
c47d488e
DD
10012
10013 saved_start = start;
10014 length = byte_get (start, 4); start += 4;
10015
10016 if (length == 0)
f1ef08cb
AM
10017 {
10018 printf ("\n%08lx ZERO terminator\n\n",
10019 (unsigned long)(saved_start - section_start));
10020 return 1;
10021 }
c47d488e 10022
428409d5
NC
10023 if (length == 0xffffffff)
10024 {
ee42cf8c
NC
10025 length = byte_get (start, 8);
10026 start += 8;
10027 offset_size = 8;
10028 initial_length_size = 12;
10029 }
10030 else
10031 {
10032 offset_size = 4;
10033 initial_length_size = 4;
428409d5
NC
10034 }
10035
ee42cf8c
NC
10036 block_end = saved_start + length + initial_length_size;
10037 cie_id = byte_get (start, offset_size); start += offset_size;
c47d488e 10038
d84de024
AM
10039 if (elf_header.e_type == ET_REL
10040 && !debug_apply_rela_addends (file, section, offset_size,
10041 section_start, start, block_end))
10042 return 0;
10043
c47d488e
DD
10044 if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
10045 {
31b6fca6
RH
10046 int version;
10047
d3ba0551 10048 fc = xmalloc (sizeof (Frame_Chunk));
c47d488e
DD
10049 memset (fc, 0, sizeof (Frame_Chunk));
10050
10051 fc->next = chunks;
10052 chunks = fc;
10053 fc->chunk_start = saved_start;
10054 fc->ncols = 0;
d3ba0551
AM
10055 fc->col_type = xmalloc (sizeof (short int));
10056 fc->col_offset = xmalloc (sizeof (int));
c47d488e
DD
10057 frame_need_space (fc, max_regs-1);
10058
31b6fca6 10059 version = *start++;
584da044 10060
31b6fca6
RH
10061 fc->augmentation = start;
10062 start = strchr (start, '\0') + 1;
584da044 10063
c47d488e
DD
10064 if (fc->augmentation[0] == 'z')
10065 {
c47d488e
DD
10066 fc->code_factor = LEB ();
10067 fc->data_factor = SLEB ();
0da76f83
NC
10068 if (version == 1)
10069 {
10070 fc->ra = GET (1);
10071 }
10072 else
10073 {
10074 fc->ra = LEB ();
10075 }
31b6fca6
RH
10076 augmentation_data_len = LEB ();
10077 augmentation_data = start;
10078 start += augmentation_data_len;
c47d488e 10079 }
18bd398b 10080 else if (streq (fc->augmentation, "eh"))
c47d488e 10081 {
89fac5e3 10082 start += eh_addr_size;
c47d488e
DD
10083 fc->code_factor = LEB ();
10084 fc->data_factor = SLEB ();
0da76f83
NC
10085 if (version == 1)
10086 {
10087 fc->ra = GET (1);
10088 }
10089 else
10090 {
10091 fc->ra = LEB ();
10092 }
c47d488e
DD
10093 }
10094 else
10095 {
10096 fc->code_factor = LEB ();
10097 fc->data_factor = SLEB ();
0da76f83
NC
10098 if (version == 1)
10099 {
10100 fc->ra = GET (1);
10101 }
10102 else
10103 {
10104 fc->ra = LEB ();
10105 }
c47d488e
DD
10106 }
10107 cie = fc;
31b6fca6
RH
10108
10109 if (do_debug_frames_interp)
10110 printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
7036c0e1 10111 (unsigned long)(saved_start - section_start), length, cie_id,
31b6fca6
RH
10112 fc->augmentation, fc->code_factor, fc->data_factor,
10113 fc->ra);
10114 else
10115 {
10116 printf ("\n%08lx %08lx %08lx CIE\n",
7036c0e1 10117 (unsigned long)(saved_start - section_start), length, cie_id);
31b6fca6
RH
10118 printf (" Version: %d\n", version);
10119 printf (" Augmentation: \"%s\"\n", fc->augmentation);
10120 printf (" Code alignment factor: %u\n", fc->code_factor);
10121 printf (" Data alignment factor: %d\n", fc->data_factor);
10122 printf (" Return address column: %d\n", fc->ra);
10123
10124 if (augmentation_data_len)
10125 {
10126 unsigned long i;
10127 printf (" Augmentation data: ");
10128 for (i = 0; i < augmentation_data_len; ++i)
10129 printf (" %02x", augmentation_data[i]);
10130 putchar ('\n');
10131 }
10132 putchar ('\n');
10133 }
10134
10135 if (augmentation_data_len)
10136 {
10137 unsigned char *p, *q;
10138 p = fc->augmentation + 1;
10139 q = augmentation_data;
10140
10141 while (1)
10142 {
10143 if (*p == 'L')
7036c0e1 10144 q++;
31b6fca6
RH
10145 else if (*p == 'P')
10146 q += 1 + size_of_encoded_value (*q);
10147 else if (*p == 'R')
10148 fc->fde_encoding = *q++;
10149 else
10150 break;
10151 p++;
10152 }
10153
10154 if (fc->fde_encoding)
10155 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
10156 }
c47d488e
DD
10157
10158 frame_need_space (fc, fc->ra);
10159 }
10160 else
10161 {
b34976b6 10162 unsigned char *look_for;
c47d488e 10163 static Frame_Chunk fde_fc;
584da044
NC
10164
10165 fc = & fde_fc;
c47d488e
DD
10166 memset (fc, 0, sizeof (Frame_Chunk));
10167
31b6fca6 10168 look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
c47d488e 10169
428409d5 10170 for (cie = chunks; cie ; cie = cie->next)
31b6fca6
RH
10171 if (cie->chunk_start == look_for)
10172 break;
c47d488e 10173
c47d488e
DD
10174 if (!cie)
10175 {
31b6fca6
RH
10176 warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
10177 cie_id, saved_start);
c47d488e
DD
10178 start = block_end;
10179 fc->ncols = 0;
d3ba0551
AM
10180 fc->col_type = xmalloc (sizeof (short int));
10181 fc->col_offset = xmalloc (sizeof (int));
584da044 10182 frame_need_space (fc, max_regs - 1);
c47d488e
DD
10183 cie = fc;
10184 fc->augmentation = "";
31b6fca6 10185 fc->fde_encoding = 0;
c47d488e
DD
10186 }
10187 else
10188 {
10189 fc->ncols = cie->ncols;
d3ba0551
AM
10190 fc->col_type = xmalloc (fc->ncols * sizeof (short int));
10191 fc->col_offset = xmalloc (fc->ncols * sizeof (int));
a98cc2b2 10192 memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
c47d488e
DD
10193 memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
10194 fc->augmentation = cie->augmentation;
10195 fc->code_factor = cie->code_factor;
10196 fc->data_factor = cie->data_factor;
10197 fc->cfa_reg = cie->cfa_reg;
10198 fc->cfa_offset = cie->cfa_offset;
10199 fc->ra = cie->ra;
10200 frame_need_space (fc, max_regs-1);
31b6fca6 10201 fc->fde_encoding = cie->fde_encoding;
c47d488e
DD
10202 }
10203
31b6fca6
RH
10204 if (fc->fde_encoding)
10205 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
10206
38fafa6d 10207 fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
d84de024
AM
10208 if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
10209 /* Don't adjust for ET_REL since there's invariably a pcrel
10210 reloc here, which we haven't applied. */
10211 && elf_header.e_type != ET_REL)
f1ef08cb 10212 fc->pc_begin += section->sh_addr + (start - section_start);
31b6fca6
RH
10213 start += encoded_ptr_size;
10214 fc->pc_range = byte_get (start, encoded_ptr_size);
10215 start += encoded_ptr_size;
10216
c47d488e
DD
10217 if (cie->augmentation[0] == 'z')
10218 {
31b6fca6
RH
10219 augmentation_data_len = LEB ();
10220 augmentation_data = start;
10221 start += augmentation_data_len;
c47d488e
DD
10222 }
10223
410f7a12 10224 printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
7036c0e1 10225 (unsigned long)(saved_start - section_start), length, cie_id,
410f7a12
L
10226 (unsigned long)(cie->chunk_start - section_start),
10227 fc->pc_begin, fc->pc_begin + fc->pc_range);
31b6fca6
RH
10228 if (! do_debug_frames_interp && augmentation_data_len)
10229 {
10230 unsigned long i;
5b18a4bc 10231
31b6fca6
RH
10232 printf (" Augmentation data: ");
10233 for (i = 0; i < augmentation_data_len; ++i)
ba2685cc 10234 printf (" %02x", augmentation_data[i]);
31b6fca6
RH
10235 putchar ('\n');
10236 putchar ('\n');
10237 }
c47d488e
DD
10238 }
10239
18bd398b
NC
10240 /* At this point, fc is the current chunk, cie (if any) is set, and
10241 we're about to interpret instructions for the chunk. */
38fafa6d
RH
10242 /* ??? At present we need to do this always, since this sizes the
10243 fc->col_type and fc->col_offset arrays, which we write into always.
10244 We should probably split the interpreted and non-interpreted bits
10245 into two different routines, since there's so much that doesn't
10246 really overlap between them. */
10247 if (1 || do_debug_frames_interp)
53c7db4b
KH
10248 {
10249 /* Start by making a pass over the chunk, allocating storage
10250 and taking note of what registers are used. */
b34976b6 10251 unsigned char *tmp = start;
a98cc2b2 10252
53c7db4b
KH
10253 while (start < block_end)
10254 {
10255 unsigned op, opa;
63044634 10256 unsigned long reg, tmp;
7036c0e1 10257
b34976b6 10258 op = *start++;
53c7db4b
KH
10259 opa = op & 0x3f;
10260 if (op & 0xc0)
10261 op &= 0xc0;
7036c0e1 10262
53c7db4b 10263 /* Warning: if you add any more cases to this switch, be
ba2685cc 10264 sure to add them to the corresponding switch below. */
53c7db4b
KH
10265 switch (op)
10266 {
10267 case DW_CFA_advance_loc:
10268 break;
10269 case DW_CFA_offset:
10270 LEB ();
10271 frame_need_space (fc, opa);
10272 fc->col_type[opa] = DW_CFA_undefined;
10273 break;
10274 case DW_CFA_restore:
10275 frame_need_space (fc, opa);
10276 fc->col_type[opa] = DW_CFA_undefined;
10277 break;
10278 case DW_CFA_set_loc:
10279 start += encoded_ptr_size;
10280 break;
10281 case DW_CFA_advance_loc1:
10282 start += 1;
10283 break;
10284 case DW_CFA_advance_loc2:
10285 start += 2;
10286 break;
10287 case DW_CFA_advance_loc4:
10288 start += 4;
10289 break;
10290 case DW_CFA_offset_extended:
10291 reg = LEB (); LEB ();
10292 frame_need_space (fc, reg);
10293 fc->col_type[reg] = DW_CFA_undefined;
10294 break;
10295 case DW_CFA_restore_extended:
10296 reg = LEB ();
10297 frame_need_space (fc, reg);
10298 fc->col_type[reg] = DW_CFA_undefined;
10299 break;
10300 case DW_CFA_undefined:
10301 reg = LEB ();
10302 frame_need_space (fc, reg);
10303 fc->col_type[reg] = DW_CFA_undefined;
10304 break;
10305 case DW_CFA_same_value:
10306 reg = LEB ();
10307 frame_need_space (fc, reg);
10308 fc->col_type[reg] = DW_CFA_undefined;
10309 break;
10310 case DW_CFA_register:
10311 reg = LEB (); LEB ();
10312 frame_need_space (fc, reg);
10313 fc->col_type[reg] = DW_CFA_undefined;
10314 break;
10315 case DW_CFA_def_cfa:
10316 LEB (); LEB ();
10317 break;
10318 case DW_CFA_def_cfa_register:
10319 LEB ();
10320 break;
10321 case DW_CFA_def_cfa_offset:
10322 LEB ();
10323 break;
63044634
RH
10324 case DW_CFA_def_cfa_expression:
10325 tmp = LEB ();
10326 start += tmp;
10327 break;
10328 case DW_CFA_expression:
10329 reg = LEB ();
10330 tmp = LEB ();
10331 start += tmp;
10332 frame_need_space (fc, reg);
10333 fc->col_type[reg] = DW_CFA_undefined;
10334 break;
91a106e6
L
10335 case DW_CFA_offset_extended_sf:
10336 reg = LEB (); SLEB ();
10337 frame_need_space (fc, reg);
10338 fc->col_type[reg] = DW_CFA_undefined;
10339 break;
10340 case DW_CFA_def_cfa_sf:
10341 LEB (); SLEB ();
10342 break;
10343 case DW_CFA_def_cfa_offset_sf:
10344 SLEB ();
10345 break;
63044634
RH
10346 case DW_CFA_MIPS_advance_loc8:
10347 start += 8;
10348 break;
53c7db4b
KH
10349 case DW_CFA_GNU_args_size:
10350 LEB ();
10351 break;
53c7db4b
KH
10352 case DW_CFA_GNU_negative_offset_extended:
10353 reg = LEB (); LEB ();
10354 frame_need_space (fc, reg);
10355 fc->col_type[reg] = DW_CFA_undefined;
7036c0e1 10356
53c7db4b
KH
10357 default:
10358 break;
10359 }
10360 }
10361 start = tmp;
10362 }
a98cc2b2
AH
10363
10364 /* Now we know what registers are used, make a second pass over
ba2685cc 10365 the chunk, this time actually printing out the info. */
a98cc2b2 10366
c47d488e
DD
10367 while (start < block_end)
10368 {
10369 unsigned op, opa;
10370 unsigned long ul, reg, roffs;
10371 long l, ofs;
10372 bfd_vma vma;
10373
b34976b6 10374 op = *start++;
c47d488e
DD
10375 opa = op & 0x3f;
10376 if (op & 0xc0)
10377 op &= 0xc0;
10378
53c7db4b
KH
10379 /* Warning: if you add any more cases to this switch, be
10380 sure to add them to the corresponding switch above. */
c47d488e
DD
10381 switch (op)
10382 {
10383 case DW_CFA_advance_loc:
31b6fca6 10384 if (do_debug_frames_interp)
53c7db4b 10385 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 10386 else
53c7db4b
KH
10387 printf (" DW_CFA_advance_loc: %d to %08lx\n",
10388 opa * fc->code_factor,
31b6fca6 10389 fc->pc_begin + opa * fc->code_factor);
c47d488e
DD
10390 fc->pc_begin += opa * fc->code_factor;
10391 break;
10392
10393 case DW_CFA_offset:
c47d488e 10394 roffs = LEB ();
31b6fca6 10395 if (! do_debug_frames_interp)
53c7db4b 10396 printf (" DW_CFA_offset: r%d at cfa%+ld\n",
31b6fca6 10397 opa, roffs * fc->data_factor);
c47d488e
DD
10398 fc->col_type[opa] = DW_CFA_offset;
10399 fc->col_offset[opa] = roffs * fc->data_factor;
10400 break;
10401
10402 case DW_CFA_restore:
31b6fca6 10403 if (! do_debug_frames_interp)
53c7db4b 10404 printf (" DW_CFA_restore: r%d\n", opa);
c47d488e
DD
10405 fc->col_type[opa] = cie->col_type[opa];
10406 fc->col_offset[opa] = cie->col_offset[opa];
10407 break;
10408
10409 case DW_CFA_set_loc:
38fafa6d 10410 vma = get_encoded_value (start, fc->fde_encoding);
d84de024
AM
10411 if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
10412 && elf_header.e_type != ET_REL)
f1ef08cb 10413 vma += section->sh_addr + (start - section_start);
31b6fca6
RH
10414 start += encoded_ptr_size;
10415 if (do_debug_frames_interp)
53c7db4b 10416 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 10417 else
53c7db4b 10418 printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
c47d488e
DD
10419 fc->pc_begin = vma;
10420 break;
10421
10422 case DW_CFA_advance_loc1:
c47d488e 10423 ofs = byte_get (start, 1); start += 1;
31b6fca6 10424 if (do_debug_frames_interp)
53c7db4b 10425 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 10426 else
53c7db4b
KH
10427 printf (" DW_CFA_advance_loc1: %ld to %08lx\n",
10428 ofs * fc->code_factor,
31b6fca6 10429 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
10430 fc->pc_begin += ofs * fc->code_factor;
10431 break;
10432
10433 case DW_CFA_advance_loc2:
c47d488e 10434 ofs = byte_get (start, 2); start += 2;
31b6fca6 10435 if (do_debug_frames_interp)
53c7db4b 10436 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 10437 else
53c7db4b
KH
10438 printf (" DW_CFA_advance_loc2: %ld to %08lx\n",
10439 ofs * fc->code_factor,
31b6fca6 10440 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
10441 fc->pc_begin += ofs * fc->code_factor;
10442 break;
10443
10444 case DW_CFA_advance_loc4:
c47d488e 10445 ofs = byte_get (start, 4); start += 4;
31b6fca6 10446 if (do_debug_frames_interp)
53c7db4b 10447 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 10448 else
53c7db4b
KH
10449 printf (" DW_CFA_advance_loc4: %ld to %08lx\n",
10450 ofs * fc->code_factor,
31b6fca6 10451 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
10452 fc->pc_begin += ofs * fc->code_factor;
10453 break;
10454
10455 case DW_CFA_offset_extended:
10456 reg = LEB ();
10457 roffs = LEB ();
31b6fca6 10458 if (! do_debug_frames_interp)
7036c0e1 10459 printf (" DW_CFA_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 10460 reg, roffs * fc->data_factor);
c47d488e
DD
10461 fc->col_type[reg] = DW_CFA_offset;
10462 fc->col_offset[reg] = roffs * fc->data_factor;
10463 break;
10464
10465 case DW_CFA_restore_extended:
10466 reg = LEB ();
31b6fca6 10467 if (! do_debug_frames_interp)
53c7db4b 10468 printf (" DW_CFA_restore_extended: r%ld\n", reg);
c47d488e
DD
10469 fc->col_type[reg] = cie->col_type[reg];
10470 fc->col_offset[reg] = cie->col_offset[reg];
10471 break;
10472
10473 case DW_CFA_undefined:
10474 reg = LEB ();
31b6fca6 10475 if (! do_debug_frames_interp)
53c7db4b 10476 printf (" DW_CFA_undefined: r%ld\n", reg);
c47d488e
DD
10477 fc->col_type[reg] = DW_CFA_undefined;
10478 fc->col_offset[reg] = 0;
10479 break;
10480
10481 case DW_CFA_same_value:
10482 reg = LEB ();
31b6fca6 10483 if (! do_debug_frames_interp)
53c7db4b 10484 printf (" DW_CFA_same_value: r%ld\n", reg);
c47d488e
DD
10485 fc->col_type[reg] = DW_CFA_same_value;
10486 fc->col_offset[reg] = 0;
10487 break;
10488
10489 case DW_CFA_register:
10490 reg = LEB ();
10491 roffs = LEB ();
31b6fca6 10492 if (! do_debug_frames_interp)
636fc387 10493 printf (" DW_CFA_register: r%ld in r%ld\n", reg, roffs);
c47d488e
DD
10494 fc->col_type[reg] = DW_CFA_register;
10495 fc->col_offset[reg] = roffs;
10496 break;
10497
10498 case DW_CFA_remember_state:
31b6fca6 10499 if (! do_debug_frames_interp)
53c7db4b 10500 printf (" DW_CFA_remember_state\n");
d3ba0551 10501 rs = xmalloc (sizeof (Frame_Chunk));
c47d488e 10502 rs->ncols = fc->ncols;
d3ba0551
AM
10503 rs->col_type = xmalloc (rs->ncols * sizeof (short int));
10504 rs->col_offset = xmalloc (rs->ncols * sizeof (int));
c47d488e
DD
10505 memcpy (rs->col_type, fc->col_type, rs->ncols);
10506 memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
10507 rs->next = remembered_state;
10508 remembered_state = rs;
10509 break;
10510
10511 case DW_CFA_restore_state:
31b6fca6 10512 if (! do_debug_frames_interp)
53c7db4b 10513 printf (" DW_CFA_restore_state\n");
c47d488e 10514 rs = remembered_state;
8c9a9879
RH
10515 if (rs)
10516 {
10517 remembered_state = rs->next;
10518 frame_need_space (fc, rs->ncols-1);
10519 memcpy (fc->col_type, rs->col_type, rs->ncols);
10520 memcpy (fc->col_offset, rs->col_offset,
10521 rs->ncols * sizeof (int));
10522 free (rs->col_type);
10523 free (rs->col_offset);
10524 free (rs);
10525 }
10526 else if (do_debug_frames_interp)
10527 printf ("Mismatched DW_CFA_restore_state\n");
c47d488e
DD
10528 break;
10529
10530 case DW_CFA_def_cfa:
10531 fc->cfa_reg = LEB ();
10532 fc->cfa_offset = LEB ();
63044634 10533 fc->cfa_exp = 0;
31b6fca6 10534 if (! do_debug_frames_interp)
53c7db4b 10535 printf (" DW_CFA_def_cfa: r%d ofs %d\n",
31b6fca6 10536 fc->cfa_reg, fc->cfa_offset);
c47d488e
DD
10537 break;
10538
10539 case DW_CFA_def_cfa_register:
10540 fc->cfa_reg = LEB ();
63044634 10541 fc->cfa_exp = 0;
31b6fca6 10542 if (! do_debug_frames_interp)
53c7db4b 10543 printf (" DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
c47d488e
DD
10544 break;
10545
10546 case DW_CFA_def_cfa_offset:
10547 fc->cfa_offset = LEB ();
31b6fca6 10548 if (! do_debug_frames_interp)
53c7db4b 10549 printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
c47d488e
DD
10550 break;
10551
10552 case DW_CFA_nop:
31b6fca6 10553 if (! do_debug_frames_interp)
53c7db4b 10554 printf (" DW_CFA_nop\n");
c47d488e
DD
10555 break;
10556
63044634
RH
10557 case DW_CFA_def_cfa_expression:
10558 ul = LEB ();
10559 if (! do_debug_frames_interp)
10560 {
10561 printf (" DW_CFA_def_cfa_expression (");
89fac5e3 10562 decode_location_expression (start, eh_addr_size, ul, 0);
63044634
RH
10563 printf (")\n");
10564 }
10565 fc->cfa_exp = 1;
10566 start += ul;
10567 break;
10568
10569 case DW_CFA_expression:
10570 reg = LEB ();
10571 ul = LEB ();
10572 if (! do_debug_frames_interp)
10573 {
10574 printf (" DW_CFA_expression: r%ld (", reg);
89fac5e3 10575 decode_location_expression (start, eh_addr_size, ul, 0);
63044634
RH
10576 printf (")\n");
10577 }
10578 fc->col_type[reg] = DW_CFA_expression;
10579 start += ul;
10580 break;
10581
91a106e6
L
10582 case DW_CFA_offset_extended_sf:
10583 reg = LEB ();
10584 l = SLEB ();
10585 frame_need_space (fc, reg);
10586 if (! do_debug_frames_interp)
10587 printf (" DW_CFA_offset_extended_sf: r%ld at cfa%+ld\n",
10588 reg, l * fc->data_factor);
10589 fc->col_type[reg] = DW_CFA_offset;
10590 fc->col_offset[reg] = l * fc->data_factor;
10591 break;
10592
10593 case DW_CFA_def_cfa_sf:
10594 fc->cfa_reg = LEB ();
10595 fc->cfa_offset = SLEB ();
63044634 10596 fc->cfa_exp = 0;
91a106e6
L
10597 if (! do_debug_frames_interp)
10598 printf (" DW_CFA_def_cfa_sf: r%d ofs %d\n",
10599 fc->cfa_reg, fc->cfa_offset);
10600 break;
10601
10602 case DW_CFA_def_cfa_offset_sf:
10603 fc->cfa_offset = SLEB ();
10604 if (! do_debug_frames_interp)
10605 printf (" DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset);
10606 break;
10607
63044634
RH
10608 case DW_CFA_MIPS_advance_loc8:
10609 ofs = byte_get (start, 8); start += 8;
10610 if (do_debug_frames_interp)
10611 frame_display_row (fc, &need_col_headers, &max_regs);
10612 else
10613 printf (" DW_CFA_MIPS_advance_loc8: %ld to %08lx\n",
10614 ofs * fc->code_factor,
10615 fc->pc_begin + ofs * fc->code_factor);
10616 fc->pc_begin += ofs * fc->code_factor;
10617 break;
10618
c47d488e 10619 case DW_CFA_GNU_window_save:
31b6fca6 10620 if (! do_debug_frames_interp)
53c7db4b 10621 printf (" DW_CFA_GNU_window_save\n");
c47d488e
DD
10622 break;
10623
c47d488e
DD
10624 case DW_CFA_GNU_args_size:
10625 ul = LEB ();
31b6fca6 10626 if (! do_debug_frames_interp)
53c7db4b 10627 printf (" DW_CFA_GNU_args_size: %ld\n", ul);
c47d488e
DD
10628 break;
10629
c47d488e
DD
10630 case DW_CFA_GNU_negative_offset_extended:
10631 reg = LEB ();
10632 l = - LEB ();
10633 frame_need_space (fc, reg);
31b6fca6 10634 if (! do_debug_frames_interp)
53c7db4b 10635 printf (" DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 10636 reg, l * fc->data_factor);
c47d488e
DD
10637 fc->col_type[reg] = DW_CFA_offset;
10638 fc->col_offset[reg] = l * fc->data_factor;
10639 break;
10640
10641 default:
18bd398b 10642 warn (_("unsupported or unknown DW_CFA_%d\n"), op);
c47d488e
DD
10643 start = block_end;
10644 }
10645 }
10646
31b6fca6 10647 if (do_debug_frames_interp)
53c7db4b 10648 frame_display_row (fc, &need_col_headers, &max_regs);
c47d488e
DD
10649
10650 start = block_end;
10651 }
10652
10653 printf ("\n");
10654
10655 return 1;
10656}
10657
10658#undef GET
10659#undef LEB
10660#undef SLEB
252b5132
RH
10661
10662static int
d3ba0551
AM
10663display_debug_not_supported (Elf_Internal_Shdr *section,
10664 unsigned char *start ATTRIBUTE_UNUSED,
10665 FILE *file ATTRIBUTE_UNUSED)
252b5132
RH
10666{
10667 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
10668 SECTION_NAME (section));
10669
10670 return 1;
10671}
10672
d9296b18
NC
10673/* A structure containing the name of a debug section
10674 and a pointer to a function that can decode it. */
252b5132
RH
10675struct
10676{
b34976b6 10677 const char *const name;
d3ba0551 10678 int (*display) (Elf_Internal_Shdr *, unsigned char *, FILE *);
252b5132
RH
10679}
10680debug_displays[] =
10681{
d9296b18
NC
10682 { ".debug_abbrev", display_debug_abbrev },
10683 { ".debug_aranges", display_debug_aranges },
10684 { ".debug_frame", display_debug_frames },
10685 { ".debug_info", display_debug_info },
10686 { ".debug_line", display_debug_lines },
10687 { ".debug_pubnames", display_debug_pubnames },
10688 { ".eh_frame", display_debug_frames },
10689 { ".debug_macinfo", display_debug_macinfo },
10690 { ".debug_str", display_debug_str },
10691 { ".debug_loc", display_debug_loc },
935a41f5 10692 { ".debug_pubtypes", display_debug_pubnames },
18bd398b 10693 { ".debug_ranges", display_debug_ranges },
d9296b18
NC
10694 { ".debug_static_func", display_debug_not_supported },
10695 { ".debug_static_vars", display_debug_not_supported },
10696 { ".debug_types", display_debug_not_supported },
10697 { ".debug_weaknames", display_debug_not_supported }
252b5132
RH
10698};
10699
10700static int
d3ba0551 10701display_debug_section (Elf_Internal_Shdr *section, FILE *file)
252b5132 10702{
b34976b6
AM
10703 char *name = SECTION_NAME (section);
10704 bfd_size_type length;
18bd398b 10705 int result = 1;
b34976b6 10706 int i;
252b5132
RH
10707
10708 length = section->sh_size;
10709 if (length == 0)
10710 {
10711 printf (_("\nSection '%s' has no debugging data.\n"), name);
10712 return 0;
10713 }
10714
18bd398b 10715 if (strneq (name, ".gnu.linkonce.wi.", 17))
7036c0e1 10716 name = ".debug_info";
584da044 10717
18bd398b 10718 /* See if we know how to display the contents of this section. */
252b5132 10719 for (i = NUM_ELEM (debug_displays); i--;)
18bd398b 10720 if (streq (debug_displays[i].name, name))
252b5132 10721 {
18bd398b
NC
10722 unsigned char *start;
10723
10724 start = get_data (NULL, file, section->sh_offset, length,
10725 _("debug section data"));
10726 if (start == NULL)
10727 {
10728 result = 0;
10729 break;
10730 }
10731
10732 result &= debug_displays[i].display (section, start, file);
10733 free (start);
10734
10735 /* If we loaded in the abbrev section
10736 at some point, we must release it here. */
10737 free_abbrevs ();
10738
252b5132
RH
10739 break;
10740 }
10741
10742 if (i == -1)
18bd398b
NC
10743 {
10744 printf (_("Unrecognized debug section: %s\n"), name);
10745 result = 0;
10746 }
252b5132 10747
18bd398b 10748 return result;
252b5132
RH
10749}
10750
18bd398b 10751static void
d3ba0551 10752process_section_contents (FILE *file)
252b5132 10753{
b34976b6
AM
10754 Elf_Internal_Shdr *section;
10755 unsigned int i;
252b5132
RH
10756
10757 if (! do_dump)
18bd398b 10758 return;
252b5132
RH
10759
10760 for (i = 0, section = section_headers;
3590ea00 10761 i < elf_header.e_shnum && i < num_dump_sects;
b34976b6 10762 i++, section++)
252b5132
RH
10763 {
10764#ifdef SUPPORT_DISASSEMBLY
10765 if (dump_sects[i] & DISASS_DUMP)
10766 disassemble_section (section, file);
10767#endif
10768 if (dump_sects[i] & HEX_DUMP)
10769 dump_section (section, file);
10770
10771 if (dump_sects[i] & DEBUG_DUMP)
10772 display_debug_section (section, file);
10773 }
10774
18bd398b
NC
10775 /* Check to see if the user requested a
10776 dump of a section that does not exist. */
10777 while (i++ < num_dump_sects)
10778 if (dump_sects[i])
10779 warn (_("Section %d was not dumped because it does not exist!\n"), i);
252b5132
RH
10780}
10781
10782static void
d3ba0551 10783process_mips_fpe_exception (int mask)
252b5132
RH
10784{
10785 if (mask)
10786 {
10787 int first = 1;
10788 if (mask & OEX_FPU_INEX)
10789 fputs ("INEX", stdout), first = 0;
10790 if (mask & OEX_FPU_UFLO)
10791 printf ("%sUFLO", first ? "" : "|"), first = 0;
10792 if (mask & OEX_FPU_OFLO)
10793 printf ("%sOFLO", first ? "" : "|"), first = 0;
10794 if (mask & OEX_FPU_DIV0)
10795 printf ("%sDIV0", first ? "" : "|"), first = 0;
10796 if (mask & OEX_FPU_INVAL)
10797 printf ("%sINVAL", first ? "" : "|");
10798 }
10799 else
10800 fputs ("0", stdout);
10801}
10802
10803static int
d3ba0551 10804process_mips_specific (FILE *file)
252b5132 10805{
b34976b6 10806 Elf_Internal_Dyn *entry;
252b5132
RH
10807 size_t liblist_offset = 0;
10808 size_t liblistno = 0;
10809 size_t conflictsno = 0;
10810 size_t options_offset = 0;
10811 size_t conflicts_offset = 0;
10812
10813 /* We have a lot of special sections. Thanks SGI! */
b2d38a17 10814 if (dynamic_section == NULL)
252b5132
RH
10815 /* No information available. */
10816 return 0;
10817
b2d38a17 10818 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
10819 switch (entry->d_tag)
10820 {
10821 case DT_MIPS_LIBLIST:
d93f0186
NC
10822 liblist_offset
10823 = offset_from_vma (file, entry->d_un.d_val,
10824 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
10825 break;
10826 case DT_MIPS_LIBLISTNO:
10827 liblistno = entry->d_un.d_val;
10828 break;
10829 case DT_MIPS_OPTIONS:
d93f0186 10830 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
10831 break;
10832 case DT_MIPS_CONFLICT:
d93f0186
NC
10833 conflicts_offset
10834 = offset_from_vma (file, entry->d_un.d_val,
10835 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
10836 break;
10837 case DT_MIPS_CONFLICTNO:
10838 conflictsno = entry->d_un.d_val;
10839 break;
10840 default:
10841 break;
10842 }
10843
10844 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
10845 {
b34976b6 10846 Elf32_External_Lib *elib;
252b5132
RH
10847 size_t cnt;
10848
d3ba0551
AM
10849 elib = get_data (NULL, file, liblist_offset,
10850 liblistno * sizeof (Elf32_External_Lib),
10851 _("liblist"));
a6e9f9df 10852 if (elib)
252b5132 10853 {
a6e9f9df
AM
10854 printf ("\nSection '.liblist' contains %lu entries:\n",
10855 (unsigned long) liblistno);
10856 fputs (" Library Time Stamp Checksum Version Flags\n",
10857 stdout);
10858
10859 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 10860 {
a6e9f9df
AM
10861 Elf32_Lib liblist;
10862 time_t time;
10863 char timebuf[20];
b34976b6 10864 struct tm *tmp;
a6e9f9df
AM
10865
10866 liblist.l_name = BYTE_GET (elib[cnt].l_name);
10867 time = BYTE_GET (elib[cnt].l_time_stamp);
10868 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
10869 liblist.l_version = BYTE_GET (elib[cnt].l_version);
10870 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
10871
10872 tmp = gmtime (&time);
10873 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
10874 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10875 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
10876
31104126 10877 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
10878 if (VALID_DYNAMIC_NAME (liblist.l_name))
10879 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
10880 else
10881 printf ("<corrupt: %9ld>", liblist.l_name);
31104126
NC
10882 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
10883 liblist.l_version);
a6e9f9df
AM
10884
10885 if (liblist.l_flags == 0)
10886 puts (" NONE");
10887 else
10888 {
10889 static const struct
252b5132 10890 {
b34976b6 10891 const char *name;
a6e9f9df 10892 int bit;
252b5132 10893 }
a6e9f9df
AM
10894 l_flags_vals[] =
10895 {
10896 { " EXACT_MATCH", LL_EXACT_MATCH },
10897 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
10898 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
10899 { " EXPORTS", LL_EXPORTS },
10900 { " DELAY_LOAD", LL_DELAY_LOAD },
10901 { " DELTA", LL_DELTA }
10902 };
10903 int flags = liblist.l_flags;
10904 size_t fcnt;
10905
10906 for (fcnt = 0;
10907 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
10908 ++fcnt)
10909 if ((flags & l_flags_vals[fcnt].bit) != 0)
10910 {
10911 fputs (l_flags_vals[fcnt].name, stdout);
10912 flags ^= l_flags_vals[fcnt].bit;
10913 }
10914 if (flags != 0)
10915 printf (" %#x", (unsigned int) flags);
252b5132 10916
a6e9f9df
AM
10917 puts ("");
10918 }
252b5132 10919 }
252b5132 10920
a6e9f9df
AM
10921 free (elib);
10922 }
252b5132
RH
10923 }
10924
10925 if (options_offset != 0)
10926 {
b34976b6
AM
10927 Elf_External_Options *eopt;
10928 Elf_Internal_Shdr *sect = section_headers;
10929 Elf_Internal_Options *iopt;
10930 Elf_Internal_Options *option;
252b5132
RH
10931 size_t offset;
10932 int cnt;
10933
10934 /* Find the section header so that we get the size. */
10935 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 10936 ++sect;
252b5132 10937
d3ba0551
AM
10938 eopt = get_data (NULL, file, options_offset, sect->sh_size,
10939 _("options"));
a6e9f9df 10940 if (eopt)
252b5132 10941 {
d3ba0551 10942 iopt = malloc ((sect->sh_size / sizeof (eopt)) * sizeof (*iopt));
a6e9f9df
AM
10943 if (iopt == NULL)
10944 {
10945 error (_("Out of memory"));
10946 return 0;
10947 }
76da6bbe 10948
a6e9f9df
AM
10949 offset = cnt = 0;
10950 option = iopt;
252b5132 10951
a6e9f9df
AM
10952 while (offset < sect->sh_size)
10953 {
b34976b6 10954 Elf_External_Options *eoption;
252b5132 10955
a6e9f9df 10956 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 10957
a6e9f9df
AM
10958 option->kind = BYTE_GET (eoption->kind);
10959 option->size = BYTE_GET (eoption->size);
10960 option->section = BYTE_GET (eoption->section);
10961 option->info = BYTE_GET (eoption->info);
76da6bbe 10962
a6e9f9df 10963 offset += option->size;
252b5132 10964
a6e9f9df
AM
10965 ++option;
10966 ++cnt;
10967 }
252b5132 10968
a6e9f9df
AM
10969 printf (_("\nSection '%s' contains %d entries:\n"),
10970 SECTION_NAME (sect), cnt);
76da6bbe 10971
a6e9f9df 10972 option = iopt;
252b5132 10973
a6e9f9df 10974 while (cnt-- > 0)
252b5132 10975 {
a6e9f9df
AM
10976 size_t len;
10977
10978 switch (option->kind)
252b5132 10979 {
a6e9f9df
AM
10980 case ODK_NULL:
10981 /* This shouldn't happen. */
10982 printf (" NULL %d %lx", option->section, option->info);
10983 break;
10984 case ODK_REGINFO:
10985 printf (" REGINFO ");
10986 if (elf_header.e_machine == EM_MIPS)
10987 {
10988 /* 32bit form. */
b34976b6
AM
10989 Elf32_External_RegInfo *ereg;
10990 Elf32_RegInfo reginfo;
a6e9f9df
AM
10991
10992 ereg = (Elf32_External_RegInfo *) (option + 1);
10993 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
10994 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
10995 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
10996 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
10997 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
10998 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
10999
11000 printf ("GPR %08lx GP 0x%lx\n",
11001 reginfo.ri_gprmask,
11002 (unsigned long) reginfo.ri_gp_value);
11003 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11004 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11005 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11006 }
11007 else
11008 {
11009 /* 64 bit form. */
b34976b6 11010 Elf64_External_RegInfo *ereg;
a6e9f9df
AM
11011 Elf64_Internal_RegInfo reginfo;
11012
11013 ereg = (Elf64_External_RegInfo *) (option + 1);
11014 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11015 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11016 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11017 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11018 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
11019 reginfo.ri_gp_value = BYTE_GET8 (ereg->ri_gp_value);
11020
11021 printf ("GPR %08lx GP 0x",
11022 reginfo.ri_gprmask);
11023 printf_vma (reginfo.ri_gp_value);
11024 printf ("\n");
11025
11026 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11027 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11028 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11029 }
11030 ++option;
11031 continue;
11032 case ODK_EXCEPTIONS:
11033 fputs (" EXCEPTIONS fpe_min(", stdout);
11034 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
11035 fputs (") fpe_max(", stdout);
11036 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
11037 fputs (")", stdout);
11038
11039 if (option->info & OEX_PAGE0)
11040 fputs (" PAGE0", stdout);
11041 if (option->info & OEX_SMM)
11042 fputs (" SMM", stdout);
11043 if (option->info & OEX_FPDBUG)
11044 fputs (" FPDBUG", stdout);
11045 if (option->info & OEX_DISMISS)
11046 fputs (" DISMISS", stdout);
11047 break;
11048 case ODK_PAD:
11049 fputs (" PAD ", stdout);
11050 if (option->info & OPAD_PREFIX)
11051 fputs (" PREFIX", stdout);
11052 if (option->info & OPAD_POSTFIX)
11053 fputs (" POSTFIX", stdout);
11054 if (option->info & OPAD_SYMBOL)
11055 fputs (" SYMBOL", stdout);
11056 break;
11057 case ODK_HWPATCH:
11058 fputs (" HWPATCH ", stdout);
11059 if (option->info & OHW_R4KEOP)
11060 fputs (" R4KEOP", stdout);
11061 if (option->info & OHW_R8KPFETCH)
11062 fputs (" R8KPFETCH", stdout);
11063 if (option->info & OHW_R5KEOP)
11064 fputs (" R5KEOP", stdout);
11065 if (option->info & OHW_R5KCVTL)
11066 fputs (" R5KCVTL", stdout);
11067 break;
11068 case ODK_FILL:
11069 fputs (" FILL ", stdout);
11070 /* XXX Print content of info word? */
11071 break;
11072 case ODK_TAGS:
11073 fputs (" TAGS ", stdout);
11074 /* XXX Print content of info word? */
11075 break;
11076 case ODK_HWAND:
11077 fputs (" HWAND ", stdout);
11078 if (option->info & OHWA0_R4KEOP_CHECKED)
11079 fputs (" R4KEOP_CHECKED", stdout);
11080 if (option->info & OHWA0_R4KEOP_CLEAN)
11081 fputs (" R4KEOP_CLEAN", stdout);
11082 break;
11083 case ODK_HWOR:
11084 fputs (" HWOR ", stdout);
11085 if (option->info & OHWA0_R4KEOP_CHECKED)
11086 fputs (" R4KEOP_CHECKED", stdout);
11087 if (option->info & OHWA0_R4KEOP_CLEAN)
11088 fputs (" R4KEOP_CLEAN", stdout);
11089 break;
11090 case ODK_GP_GROUP:
11091 printf (" GP_GROUP %#06lx self-contained %#06lx",
11092 option->info & OGP_GROUP,
11093 (option->info & OGP_SELF) >> 16);
11094 break;
11095 case ODK_IDENT:
11096 printf (" IDENT %#06lx self-contained %#06lx",
11097 option->info & OGP_GROUP,
11098 (option->info & OGP_SELF) >> 16);
11099 break;
11100 default:
11101 /* This shouldn't happen. */
11102 printf (" %3d ??? %d %lx",
11103 option->kind, option->section, option->info);
11104 break;
252b5132 11105 }
a6e9f9df 11106
b34976b6 11107 len = sizeof (*eopt);
a6e9f9df
AM
11108 while (len < option->size)
11109 if (((char *) option)[len] >= ' '
11110 && ((char *) option)[len] < 0x7f)
11111 printf ("%c", ((char *) option)[len++]);
11112 else
11113 printf ("\\%03o", ((char *) option)[len++]);
11114
11115 fputs ("\n", stdout);
252b5132 11116 ++option;
252b5132
RH
11117 }
11118
a6e9f9df 11119 free (eopt);
252b5132 11120 }
252b5132
RH
11121 }
11122
11123 if (conflicts_offset != 0 && conflictsno != 0)
11124 {
b34976b6 11125 Elf32_Conflict *iconf;
252b5132
RH
11126 size_t cnt;
11127
11128 if (dynamic_symbols == NULL)
11129 {
3a1a2036 11130 error (_("conflict list found without a dynamic symbol table"));
252b5132
RH
11131 return 0;
11132 }
11133
d3ba0551 11134 iconf = malloc (conflictsno * sizeof (*iconf));
252b5132
RH
11135 if (iconf == NULL)
11136 {
11137 error (_("Out of memory"));
11138 return 0;
11139 }
11140
9ea033b2 11141 if (is_32bit_elf)
252b5132 11142 {
b34976b6 11143 Elf32_External_Conflict *econf32;
a6e9f9df 11144
d3ba0551
AM
11145 econf32 = get_data (NULL, file, conflicts_offset,
11146 conflictsno * sizeof (*econf32), _("conflict"));
a6e9f9df
AM
11147 if (!econf32)
11148 return 0;
252b5132
RH
11149
11150 for (cnt = 0; cnt < conflictsno; ++cnt)
11151 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
11152
11153 free (econf32);
252b5132
RH
11154 }
11155 else
11156 {
b34976b6 11157 Elf64_External_Conflict *econf64;
a6e9f9df 11158
d3ba0551
AM
11159 econf64 = get_data (NULL, file, conflicts_offset,
11160 conflictsno * sizeof (*econf64), _("conflict"));
a6e9f9df
AM
11161 if (!econf64)
11162 return 0;
252b5132
RH
11163
11164 for (cnt = 0; cnt < conflictsno; ++cnt)
11165 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
11166
11167 free (econf64);
252b5132
RH
11168 }
11169
c7e7ca54
NC
11170 printf (_("\nSection '.conflict' contains %lu entries:\n"),
11171 (unsigned long) conflictsno);
252b5132
RH
11172 puts (_(" Num: Index Value Name"));
11173
11174 for (cnt = 0; cnt < conflictsno; ++cnt)
11175 {
b34976b6 11176 Elf_Internal_Sym *psym = & dynamic_symbols[iconf[cnt]];
252b5132 11177
b34976b6 11178 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 11179 print_vma (psym->st_value, FULL_HEX);
31104126 11180 putchar (' ');
d79b3d50
NC
11181 if (VALID_DYNAMIC_NAME (psym->st_name))
11182 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
11183 else
11184 printf ("<corrupt: %14ld>", psym->st_name);
31104126 11185 putchar ('\n');
252b5132
RH
11186 }
11187
252b5132
RH
11188 free (iconf);
11189 }
11190
11191 return 1;
11192}
11193
047b2264 11194static int
d3ba0551 11195process_gnu_liblist (FILE *file)
047b2264 11196{
b34976b6
AM
11197 Elf_Internal_Shdr *section, *string_sec;
11198 Elf32_External_Lib *elib;
11199 char *strtab;
047b2264
JJ
11200 size_t cnt;
11201 unsigned i;
11202
11203 if (! do_arch)
11204 return 0;
11205
11206 for (i = 0, section = section_headers;
11207 i < elf_header.e_shnum;
b34976b6 11208 i++, section++)
047b2264
JJ
11209 {
11210 switch (section->sh_type)
11211 {
11212 case SHT_GNU_LIBLIST:
d3ba0551
AM
11213 elib = get_data (NULL, file, section->sh_offset, section->sh_size,
11214 _("liblist"));
047b2264
JJ
11215
11216 if (elib == NULL)
11217 break;
11218 string_sec = SECTION_HEADER (section->sh_link);
11219
d3ba0551
AM
11220 strtab = get_data (NULL, file, string_sec->sh_offset,
11221 string_sec->sh_size, _("liblist string table"));
047b2264
JJ
11222
11223 if (strtab == NULL
11224 || section->sh_entsize != sizeof (Elf32_External_Lib))
11225 {
11226 free (elib);
11227 break;
11228 }
11229
11230 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
11231 SECTION_NAME (section),
11232 (long) (section->sh_size / sizeof (Elf32_External_Lib)));
11233
11234 puts (" Library Time Stamp Checksum Version Flags");
11235
11236 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
11237 ++cnt)
11238 {
11239 Elf32_Lib liblist;
11240 time_t time;
11241 char timebuf[20];
b34976b6 11242 struct tm *tmp;
047b2264
JJ
11243
11244 liblist.l_name = BYTE_GET (elib[cnt].l_name);
11245 time = BYTE_GET (elib[cnt].l_time_stamp);
11246 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
11247 liblist.l_version = BYTE_GET (elib[cnt].l_version);
11248 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
11249
11250 tmp = gmtime (&time);
11251 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
11252 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11253 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
11254
11255 printf ("%3lu: ", (unsigned long) cnt);
11256 if (do_wide)
11257 printf ("%-20s", strtab + liblist.l_name);
11258 else
11259 printf ("%-20.20s", strtab + liblist.l_name);
11260 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
11261 liblist.l_version, liblist.l_flags);
11262 }
11263
11264 free (elib);
11265 }
11266 }
11267
11268 return 1;
11269}
11270
9437c45b 11271static const char *
d3ba0551 11272get_note_type (unsigned e_type)
779fe533
NC
11273{
11274 static char buff[64];
103f02d3 11275
1ec5cd37
NC
11276 if (elf_header.e_type == ET_CORE)
11277 switch (e_type)
11278 {
57346661 11279 case NT_AUXV:
1ec5cd37 11280 return _("NT_AUXV (auxiliary vector)");
57346661 11281 case NT_PRSTATUS:
1ec5cd37 11282 return _("NT_PRSTATUS (prstatus structure)");
57346661 11283 case NT_FPREGSET:
1ec5cd37 11284 return _("NT_FPREGSET (floating point registers)");
57346661 11285 case NT_PRPSINFO:
1ec5cd37 11286 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 11287 case NT_TASKSTRUCT:
1ec5cd37 11288 return _("NT_TASKSTRUCT (task structure)");
57346661 11289 case NT_PRXFPREG:
1ec5cd37 11290 return _("NT_PRXFPREG (user_xfpregs structure)");
57346661 11291 case NT_PSTATUS:
1ec5cd37 11292 return _("NT_PSTATUS (pstatus structure)");
57346661 11293 case NT_FPREGS:
1ec5cd37 11294 return _("NT_FPREGS (floating point registers)");
57346661 11295 case NT_PSINFO:
1ec5cd37 11296 return _("NT_PSINFO (psinfo structure)");
57346661 11297 case NT_LWPSTATUS:
1ec5cd37 11298 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 11299 case NT_LWPSINFO:
1ec5cd37 11300 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 11301 case NT_WIN32PSTATUS:
1ec5cd37
NC
11302 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
11303 default:
11304 break;
11305 }
11306 else
11307 switch (e_type)
11308 {
11309 case NT_VERSION:
11310 return _("NT_VERSION (version)");
11311 case NT_ARCH:
11312 return _("NT_ARCH (architecture)");
11313 default:
11314 break;
11315 }
11316
11317 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
11318 return buff;
779fe533
NC
11319}
11320
9437c45b 11321static const char *
d3ba0551 11322get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
11323{
11324 static char buff[64];
11325
b4db1224 11326 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
11327 {
11328 /* NetBSD core "procinfo" structure. */
11329 return _("NetBSD procinfo structure");
11330 }
11331
11332 /* As of Jan 2002 there are no other machine-independent notes
11333 defined for NetBSD core files. If the note type is less
11334 than the start of the machine-dependent note types, we don't
11335 understand it. */
11336
b4db1224 11337 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b
JT
11338 {
11339 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
11340 return buff;
11341 }
11342
11343 switch (elf_header.e_machine)
11344 {
11345 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
11346 and PT_GETFPREGS == mach+2. */
11347
11348 case EM_OLD_ALPHA:
11349 case EM_ALPHA:
11350 case EM_SPARC:
11351 case EM_SPARC32PLUS:
11352 case EM_SPARCV9:
11353 switch (e_type)
11354 {
b4db1224
JT
11355 case NT_NETBSDCORE_FIRSTMACH+0:
11356 return _("PT_GETREGS (reg structure)");
11357 case NT_NETBSDCORE_FIRSTMACH+2:
11358 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
11359 default:
11360 break;
11361 }
11362 break;
11363
11364 /* On all other arch's, PT_GETREGS == mach+1 and
11365 PT_GETFPREGS == mach+3. */
11366 default:
11367 switch (e_type)
11368 {
b4db1224
JT
11369 case NT_NETBSDCORE_FIRSTMACH+1:
11370 return _("PT_GETREGS (reg structure)");
11371 case NT_NETBSDCORE_FIRSTMACH+3:
11372 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
11373 default:
11374 break;
11375 }
11376 }
11377
b4db1224 11378 sprintf (buff, _("PT_FIRSTMACH+%d"), e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
11379 return buff;
11380}
11381
6d118b09
NC
11382/* Note that by the ELF standard, the name field is already null byte
11383 terminated, and namesz includes the terminating null byte.
11384 I.E. the value of namesz for the name "FSF" is 4.
11385
e3c8793a 11386 If the value of namesz is zero, there is no name present. */
779fe533 11387static int
d3ba0551 11388process_note (Elf_Internal_Note *pnote)
779fe533 11389{
9437c45b
JT
11390 const char *nt;
11391
11392 if (pnote->namesz == 0)
1ec5cd37
NC
11393 /* If there is no note name, then use the default set of
11394 note type strings. */
11395 nt = get_note_type (pnote->type);
11396
18bd398b 11397 else if (strneq (pnote->namedata, "NetBSD-CORE", 11))
1ec5cd37
NC
11398 /* NetBSD-specific core file notes. */
11399 nt = get_netbsd_elfcore_note_type (pnote->type);
11400
9437c45b 11401 else
1ec5cd37
NC
11402 /* Don't recognize this note name; just use the default set of
11403 note type strings. */
9437c45b 11404 nt = get_note_type (pnote->type);
9437c45b 11405
103f02d3 11406 printf (" %s\t\t0x%08lx\t%s\n",
6d118b09 11407 pnote->namesz ? pnote->namedata : "(NONE)",
9437c45b 11408 pnote->descsz, nt);
779fe533
NC
11409 return 1;
11410}
11411
6d118b09 11412
779fe533 11413static int
d3ba0551 11414process_corefile_note_segment (FILE *file, bfd_vma offset, bfd_vma length)
779fe533 11415{
b34976b6
AM
11416 Elf_External_Note *pnotes;
11417 Elf_External_Note *external;
11418 int res = 1;
103f02d3 11419
779fe533
NC
11420 if (length <= 0)
11421 return 0;
103f02d3 11422
d3ba0551 11423 pnotes = get_data (NULL, file, offset, length, _("notes"));
a6e9f9df
AM
11424 if (!pnotes)
11425 return 0;
779fe533 11426
103f02d3 11427 external = pnotes;
103f02d3 11428
305c7206 11429 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 11430 (unsigned long) offset, (unsigned long) length);
779fe533 11431 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 11432
6d118b09 11433 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 11434 {
b34976b6
AM
11435 Elf_External_Note *next;
11436 Elf_Internal_Note inote;
11437 char *temp = NULL;
6d118b09
NC
11438
11439 inote.type = BYTE_GET (external->type);
11440 inote.namesz = BYTE_GET (external->namesz);
11441 inote.namedata = external->name;
11442 inote.descsz = BYTE_GET (external->descsz);
11443 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
11444 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 11445
3e55a963
NC
11446 next = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
11447
11448 if (((char *) next) > (((char *) pnotes) + length))
11449 {
11450 warn (_("corrupt note found at offset %x into core notes\n"),
11451 ((char *) external) - ((char *) pnotes));
11452 warn (_(" type: %x, namesize: %08lx, descsize: %08lx\n"),
11453 inote.type, inote.namesz, inote.descsz);
11454 break;
11455 }
11456
11457 external = next;
6d118b09
NC
11458
11459 /* Verify that name is null terminated. It appears that at least
11460 one version of Linux (RedHat 6.0) generates corefiles that don't
11461 comply with the ELF spec by failing to include the null byte in
11462 namesz. */
11463 if (inote.namedata[inote.namesz] != '\0')
11464 {
11465 temp = malloc (inote.namesz + 1);
76da6bbe 11466
6d118b09
NC
11467 if (temp == NULL)
11468 {
11469 error (_("Out of memory\n"));
11470 res = 0;
11471 break;
11472 }
76da6bbe 11473
6d118b09
NC
11474 strncpy (temp, inote.namedata, inote.namesz);
11475 temp[inote.namesz] = 0;
76da6bbe 11476
6d118b09
NC
11477 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
11478 inote.namedata = temp;
11479 }
11480
11481 res &= process_note (& inote);
103f02d3 11482
6d118b09
NC
11483 if (temp != NULL)
11484 {
11485 free (temp);
11486 temp = NULL;
11487 }
779fe533
NC
11488 }
11489
11490 free (pnotes);
103f02d3 11491
779fe533
NC
11492 return res;
11493}
11494
11495static int
d3ba0551 11496process_corefile_note_segments (FILE *file)
779fe533 11497{
b34976b6
AM
11498 Elf_Internal_Phdr *segment;
11499 unsigned int i;
11500 int res = 1;
103f02d3 11501
d93f0186 11502 if (! get_program_headers (file))
779fe533 11503 return 0;
103f02d3 11504
779fe533
NC
11505 for (i = 0, segment = program_headers;
11506 i < elf_header.e_phnum;
b34976b6 11507 i++, segment++)
779fe533
NC
11508 {
11509 if (segment->p_type == PT_NOTE)
103f02d3 11510 res &= process_corefile_note_segment (file,
30800947
NC
11511 (bfd_vma) segment->p_offset,
11512 (bfd_vma) segment->p_filesz);
779fe533 11513 }
103f02d3 11514
779fe533
NC
11515 return res;
11516}
11517
11518static int
1ec5cd37
NC
11519process_note_sections (FILE *file)
11520{
11521 Elf_Internal_Shdr *section;
11522 unsigned long i;
11523 int res = 1;
11524
11525 for (i = 0, section = section_headers;
11526 i < elf_header.e_shnum;
11527 i++, section++)
11528 if (section->sh_type == SHT_NOTE)
11529 res &= process_corefile_note_segment (file,
11530 (bfd_vma) section->sh_offset,
11531 (bfd_vma) section->sh_size);
11532
11533 return res;
11534}
11535
11536static int
11537process_notes (FILE *file)
779fe533
NC
11538{
11539 /* If we have not been asked to display the notes then do nothing. */
11540 if (! do_notes)
11541 return 1;
103f02d3 11542
779fe533 11543 if (elf_header.e_type != ET_CORE)
1ec5cd37 11544 return process_note_sections (file);
103f02d3 11545
779fe533 11546 /* No program headers means no NOTE segment. */
1ec5cd37
NC
11547 if (elf_header.e_phnum > 0)
11548 return process_corefile_note_segments (file);
779fe533 11549
1ec5cd37
NC
11550 printf (_("No note segments present in the core file.\n"));
11551 return 1;
779fe533
NC
11552}
11553
252b5132 11554static int
d3ba0551 11555process_arch_specific (FILE *file)
252b5132 11556{
a952a375
NC
11557 if (! do_arch)
11558 return 1;
11559
252b5132
RH
11560 switch (elf_header.e_machine)
11561 {
11562 case EM_MIPS:
4fe85591 11563 case EM_MIPS_RS3_LE:
252b5132
RH
11564 return process_mips_specific (file);
11565 break;
11566 default:
11567 break;
11568 }
11569 return 1;
11570}
11571
11572static int
d3ba0551 11573get_file_header (FILE *file)
252b5132 11574{
9ea033b2
NC
11575 /* Read in the identity array. */
11576 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
11577 return 0;
11578
9ea033b2 11579 /* Determine how to read the rest of the header. */
b34976b6 11580 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
11581 {
11582 default: /* fall through */
11583 case ELFDATANONE: /* fall through */
adab8cdc
AO
11584 case ELFDATA2LSB:
11585 byte_get = byte_get_little_endian;
11586 byte_put = byte_put_little_endian;
11587 break;
11588 case ELFDATA2MSB:
11589 byte_get = byte_get_big_endian;
11590 byte_put = byte_put_big_endian;
11591 break;
9ea033b2
NC
11592 }
11593
11594 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 11595 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
11596
11597 /* Read in the rest of the header. */
11598 if (is_32bit_elf)
11599 {
11600 Elf32_External_Ehdr ehdr32;
252b5132 11601
9ea033b2
NC
11602 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
11603 return 0;
103f02d3 11604
9ea033b2
NC
11605 elf_header.e_type = BYTE_GET (ehdr32.e_type);
11606 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
11607 elf_header.e_version = BYTE_GET (ehdr32.e_version);
11608 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
11609 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
11610 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
11611 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
11612 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
11613 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
11614 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
11615 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
11616 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
11617 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
11618 }
252b5132 11619 else
9ea033b2
NC
11620 {
11621 Elf64_External_Ehdr ehdr64;
a952a375
NC
11622
11623 /* If we have been compiled with sizeof (bfd_vma) == 4, then
11624 we will not be able to cope with the 64bit data found in
11625 64 ELF files. Detect this now and abort before we start
50c2245b 11626 overwriting things. */
a952a375
NC
11627 if (sizeof (bfd_vma) < 8)
11628 {
e3c8793a
NC
11629 error (_("This instance of readelf has been built without support for a\n\
1163064 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
11631 return 0;
11632 }
103f02d3 11633
9ea033b2
NC
11634 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
11635 return 0;
103f02d3 11636
9ea033b2
NC
11637 elf_header.e_type = BYTE_GET (ehdr64.e_type);
11638 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
11639 elf_header.e_version = BYTE_GET (ehdr64.e_version);
11640 elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry);
11641 elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff);
11642 elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff);
11643 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
11644 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
11645 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
11646 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
11647 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
11648 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
11649 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
11650 }
252b5132 11651
7ece0d85
JJ
11652 if (elf_header.e_shoff)
11653 {
11654 /* There may be some extensions in the first section header. Don't
11655 bomb if we can't read it. */
11656 if (is_32bit_elf)
11657 get_32bit_section_headers (file, 1);
11658 else
11659 get_64bit_section_headers (file, 1);
11660 }
560f3c1c 11661
252b5132
RH
11662 return 1;
11663}
11664
fb52b2f4
NC
11665/* Process one ELF object file according to the command line options.
11666 This file may actually be stored in an archive. The file is
11667 positioned at the start of the ELF object. */
11668
ff78d6d6 11669static int
fb52b2f4 11670process_object (char *file_name, FILE *file)
252b5132 11671{
252b5132
RH
11672 unsigned int i;
11673
252b5132
RH
11674 if (! get_file_header (file))
11675 {
11676 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 11677 return 1;
252b5132
RH
11678 }
11679
11680 /* Initialise per file variables. */
11681 for (i = NUM_ELEM (version_info); i--;)
11682 version_info[i] = 0;
11683
11684 for (i = NUM_ELEM (dynamic_info); i--;)
11685 dynamic_info[i] = 0;
11686
11687 /* Process the file. */
11688 if (show_name)
11689 printf (_("\nFile: %s\n"), file_name);
11690
18bd398b
NC
11691 /* Initialise the dump_sects array from the cmdline_dump_sects array.
11692 Note we do this even if cmdline_dump_sects is empty because we
11693 must make sure that the dump_sets array is zeroed out before each
11694 object file is processed. */
11695 if (num_dump_sects > num_cmdline_dump_sects)
11696 memset (dump_sects, 0, num_dump_sects);
11697
11698 if (num_cmdline_dump_sects > 0)
11699 {
11700 if (num_dump_sects == 0)
11701 /* A sneaky way of allocating the dump_sects array. */
11702 request_dump (num_cmdline_dump_sects, 0);
11703
11704 assert (num_dump_sects >= num_cmdline_dump_sects);
11705 memcpy (dump_sects, cmdline_dump_sects, num_cmdline_dump_sects);
11706 }
11707
252b5132 11708 if (! process_file_header ())
fb52b2f4 11709 return 1;
252b5132 11710
d1f5c6e3 11711 if (! process_section_headers (file))
2f62977e 11712 {
d1f5c6e3
L
11713 /* Without loaded section headers we cannot process lots of
11714 things. */
2f62977e 11715 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 11716
2f62977e
NC
11717 if (! do_using_dynamic)
11718 do_syms = do_reloc = 0;
11719 }
252b5132 11720
d1f5c6e3
L
11721 if (! process_section_groups (file))
11722 {
11723 /* Without loaded section groups we cannot process unwind. */
11724 do_unwind = 0;
11725 }
11726
2f62977e 11727 if (process_program_headers (file))
b2d38a17 11728 process_dynamic_section (file);
252b5132
RH
11729
11730 process_relocs (file);
11731
4d6ed7c8
NC
11732 process_unwind (file);
11733
252b5132
RH
11734 process_symbol_table (file);
11735
11736 process_syminfo (file);
11737
11738 process_version_sections (file);
11739
11740 process_section_contents (file);
f5842774 11741
1ec5cd37 11742 process_notes (file);
103f02d3 11743
047b2264
JJ
11744 process_gnu_liblist (file);
11745
252b5132
RH
11746 process_arch_specific (file);
11747
d93f0186
NC
11748 if (program_headers)
11749 {
11750 free (program_headers);
11751 program_headers = NULL;
11752 }
11753
252b5132
RH
11754 if (section_headers)
11755 {
11756 free (section_headers);
11757 section_headers = NULL;
11758 }
11759
11760 if (string_table)
11761 {
11762 free (string_table);
11763 string_table = NULL;
d40ac9bd 11764 string_table_length = 0;
252b5132
RH
11765 }
11766
11767 if (dynamic_strings)
11768 {
11769 free (dynamic_strings);
11770 dynamic_strings = NULL;
d79b3d50 11771 dynamic_strings_length = 0;
252b5132
RH
11772 }
11773
11774 if (dynamic_symbols)
11775 {
11776 free (dynamic_symbols);
11777 dynamic_symbols = NULL;
19936277 11778 num_dynamic_syms = 0;
252b5132
RH
11779 }
11780
11781 if (dynamic_syminfo)
11782 {
11783 free (dynamic_syminfo);
11784 dynamic_syminfo = NULL;
11785 }
ff78d6d6 11786
e4b17d5c
L
11787 if (section_headers_groups)
11788 {
11789 free (section_headers_groups);
11790 section_headers_groups = NULL;
11791 }
11792
11793 if (section_groups)
11794 {
11795 struct group_list *g, *next;
11796
11797 for (i = 0; i < group_count; i++)
11798 {
11799 for (g = section_groups [i].root; g != NULL; g = next)
11800 {
11801 next = g->next;
11802 free (g);
11803 }
11804 }
11805
11806 free (section_groups);
11807 section_groups = NULL;
11808 }
11809
18bd398b
NC
11810 if (debug_information)
11811 {
5b18a4bc 11812 for (i = 0; i < num_debug_info_entries; i++)
0853c092
L
11813 {
11814 if (!debug_information [i].max_loc_offsets)
11815 {
11816 free (debug_information [i].loc_offsets);
11817 free (debug_information [i].have_frame_base);
11818 }
11819 if (!debug_information [i].max_range_lists)
11820 free (debug_information [i].range_lists);
11821 }
18bd398b
NC
11822 free (debug_information);
11823 debug_information = NULL;
11824 num_debug_info_entries = 0;
11825 }
11826
ff78d6d6 11827 return 0;
252b5132
RH
11828}
11829
fb52b2f4
NC
11830/* Process an ELF archive. The file is positioned just after the
11831 ARMAG string. */
11832
11833static int
11834process_archive (char *file_name, FILE *file)
11835{
11836 struct ar_hdr arhdr;
11837 size_t got;
11838 unsigned long size;
11839 char *longnames = NULL;
11840 unsigned long longnames_size = 0;
11841 size_t file_name_size;
d989285c 11842 int ret;
fb52b2f4
NC
11843
11844 show_name = 1;
11845
11846 got = fread (&arhdr, 1, sizeof arhdr, file);
11847 if (got != sizeof arhdr)
11848 {
11849 if (got == 0)
11850 return 0;
11851
11852 error (_("%s: failed to read archive header\n"), file_name);
11853 return 1;
11854 }
11855
11856 if (memcmp (arhdr.ar_name, "/ ", 16) == 0)
11857 {
11858 /* This is the archive symbol table. Skip it.
11859 FIXME: We should have an option to dump it. */
11860 size = strtoul (arhdr.ar_size, NULL, 10);
11861 if (fseek (file, size + (size & 1), SEEK_CUR) != 0)
11862 {
11863 error (_("%s: failed to skip archive symbol table\n"), file_name);
11864 return 1;
11865 }
11866
11867 got = fread (&arhdr, 1, sizeof arhdr, file);
11868 if (got != sizeof arhdr)
11869 {
11870 if (got == 0)
11871 return 0;
11872
11873 error (_("%s: failed to read archive header\n"), file_name);
11874 return 1;
11875 }
11876 }
11877
11878 if (memcmp (arhdr.ar_name, "// ", 16) == 0)
11879 {
11880 /* This is the archive string table holding long member
11881 names. */
11882
11883 longnames_size = strtoul (arhdr.ar_size, NULL, 10);
11884
11885 longnames = malloc (longnames_size);
11886 if (longnames == NULL)
11887 {
11888 error (_("Out of memory\n"));
11889 return 1;
11890 }
11891
11892 if (fread (longnames, longnames_size, 1, file) != 1)
11893 {
d989285c 11894 free (longnames);
18bd398b 11895 error (_("%s: failed to read string table\n"), file_name);
fb52b2f4
NC
11896 return 1;
11897 }
11898
11899 if ((longnames_size & 1) != 0)
11900 getc (file);
11901
11902 got = fread (&arhdr, 1, sizeof arhdr, file);
11903 if (got != sizeof arhdr)
11904 {
d989285c
ILT
11905 free (longnames);
11906
fb52b2f4
NC
11907 if (got == 0)
11908 return 0;
11909
11910 error (_("%s: failed to read archive header\n"), file_name);
11911 return 1;
11912 }
11913 }
11914
11915 file_name_size = strlen (file_name);
d989285c 11916 ret = 0;
fb52b2f4
NC
11917
11918 while (1)
11919 {
11920 char *name;
11921 char *nameend;
11922 char *namealc;
11923
11924 if (arhdr.ar_name[0] == '/')
11925 {
11926 unsigned long off;
11927
11928 off = strtoul (arhdr.ar_name + 1, NULL, 10);
11929 if (off >= longnames_size)
11930 {
11931 error (_("%s: invalid archive string table offset %lu\n"), off);
d989285c
ILT
11932 ret = 1;
11933 break;
fb52b2f4
NC
11934 }
11935
11936 name = longnames + off;
11937 nameend = memchr (name, '/', longnames_size - off);
11938 }
11939 else
11940 {
11941 name = arhdr.ar_name;
11942 nameend = memchr (name, '/', 16);
11943 }
11944
11945 if (nameend == NULL)
11946 {
11947 error (_("%s: bad archive file name\n"));
d989285c
ILT
11948 ret = 1;
11949 break;
fb52b2f4
NC
11950 }
11951
11952 namealc = malloc (file_name_size + (nameend - name) + 3);
11953 if (namealc == NULL)
11954 {
11955 error (_("Out of memory\n"));
d989285c
ILT
11956 ret = 1;
11957 break;
fb52b2f4
NC
11958 }
11959
11960 memcpy (namealc, file_name, file_name_size);
11961 namealc[file_name_size] = '(';
11962 memcpy (namealc + file_name_size + 1, name, nameend - name);
11963 namealc[file_name_size + 1 + (nameend - name)] = ')';
11964 namealc[file_name_size + 2 + (nameend - name)] = '\0';
11965
11966 archive_file_offset = ftell (file);
11967 archive_file_size = strtoul (arhdr.ar_size, NULL, 10);
18bd398b 11968
d989285c 11969 ret |= process_object (namealc, file);
fb52b2f4
NC
11970
11971 free (namealc);
11972
11973 if (fseek (file,
11974 (archive_file_offset
11975 + archive_file_size
11976 + (archive_file_size & 1)),
11977 SEEK_SET) != 0)
11978 {
11979 error (_("%s: failed to seek to next archive header\n"), file_name);
d989285c
ILT
11980 ret = 1;
11981 break;
fb52b2f4
NC
11982 }
11983
11984 got = fread (&arhdr, 1, sizeof arhdr, file);
11985 if (got != sizeof arhdr)
11986 {
11987 if (got == 0)
d989285c 11988 break;
fb52b2f4
NC
11989
11990 error (_("%s: failed to read archive header\n"), file_name);
d989285c
ILT
11991 ret = 1;
11992 break;
fb52b2f4
NC
11993 }
11994 }
11995
11996 if (longnames != 0)
11997 free (longnames);
11998
d989285c 11999 return ret;
fb52b2f4
NC
12000}
12001
12002static int
12003process_file (char *file_name)
12004{
12005 FILE *file;
12006 struct stat statbuf;
12007 char armag[SARMAG];
12008 int ret;
12009
12010 if (stat (file_name, &statbuf) < 0)
12011 {
f24ddbdd
NC
12012 if (errno == ENOENT)
12013 error (_("'%s': No such file\n"), file_name);
12014 else
12015 error (_("Could not locate '%s'. System error message: %s\n"),
12016 file_name, strerror (errno));
12017 return 1;
12018 }
12019
12020 if (! S_ISREG (statbuf.st_mode))
12021 {
12022 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
12023 return 1;
12024 }
12025
12026 file = fopen (file_name, "rb");
12027 if (file == NULL)
12028 {
f24ddbdd 12029 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
12030 return 1;
12031 }
12032
12033 if (fread (armag, SARMAG, 1, file) != 1)
12034 {
12035 error (_("%s: Failed to read file header\n"), file_name);
12036 fclose (file);
12037 return 1;
12038 }
12039
12040 if (memcmp (armag, ARMAG, SARMAG) == 0)
12041 ret = process_archive (file_name, file);
12042 else
12043 {
12044 rewind (file);
12045 archive_file_size = archive_file_offset = 0;
12046 ret = process_object (file_name, file);
12047 }
12048
12049 fclose (file);
12050
12051 return ret;
12052}
12053
252b5132
RH
12054#ifdef SUPPORT_DISASSEMBLY
12055/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 12056 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 12057 symbols. */
252b5132
RH
12058
12059void
b34976b6 12060print_address (unsigned int addr, FILE *outfile)
252b5132
RH
12061{
12062 fprintf (outfile,"0x%8.8x", addr);
12063}
12064
e3c8793a 12065/* Needed by the i386 disassembler. */
252b5132
RH
12066void
12067db_task_printsym (unsigned int addr)
12068{
12069 print_address (addr, stderr);
12070}
12071#endif
12072
12073int
d3ba0551 12074main (int argc, char **argv)
252b5132 12075{
ff78d6d6
L
12076 int err;
12077
252b5132
RH
12078#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
12079 setlocale (LC_MESSAGES, "");
3882b010
L
12080#endif
12081#if defined (HAVE_SETLOCALE)
12082 setlocale (LC_CTYPE, "");
252b5132
RH
12083#endif
12084 bindtextdomain (PACKAGE, LOCALEDIR);
12085 textdomain (PACKAGE);
12086
12087 parse_args (argc, argv);
12088
18bd398b 12089 if (num_dump_sects > 0)
59f14fc0 12090 {
18bd398b 12091 /* Make a copy of the dump_sects array. */
59f14fc0
AS
12092 cmdline_dump_sects = malloc (num_dump_sects);
12093 if (cmdline_dump_sects == NULL)
12094 error (_("Out of memory allocating dump request table."));
12095 else
12096 {
12097 memcpy (cmdline_dump_sects, dump_sects, num_dump_sects);
12098 num_cmdline_dump_sects = num_dump_sects;
12099 }
12100 }
12101
18bd398b
NC
12102 if (optind < (argc - 1))
12103 show_name = 1;
12104
ff78d6d6 12105 err = 0;
252b5132 12106 while (optind < argc)
18bd398b 12107 err |= process_file (argv[optind++]);
252b5132
RH
12108
12109 if (dump_sects != NULL)
12110 free (dump_sects);
59f14fc0
AS
12111 if (cmdline_dump_sects != NULL)
12112 free (cmdline_dump_sects);
252b5132 12113
ff78d6d6 12114 return err;
252b5132 12115}