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