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