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