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