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