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