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