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