]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
bfd/
[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
252b5132
RH
3874 for (i = 0, section = section_headers;
3875 i < elf_header.e_shnum;
b34976b6 3876 i++, section++)
252b5132 3877 {
b34976b6 3878 char *name = SECTION_NAME (section);
252b5132
RH
3879
3880 if (section->sh_type == SHT_DYNSYM)
3881 {
3882 if (dynamic_symbols != NULL)
3883 {
3884 error (_("File contains multiple dynamic symbol tables\n"));
3885 continue;
3886 }
3887
19936277 3888 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 3889 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
3890 }
3891 else if (section->sh_type == SHT_STRTAB
18bd398b 3892 && streq (name, ".dynstr"))
252b5132
RH
3893 {
3894 if (dynamic_strings != NULL)
3895 {
3896 error (_("File contains multiple dynamic string tables\n"));
3897 continue;
3898 }
3899
d3ba0551 3900 dynamic_strings = get_data (NULL, file, section->sh_offset,
c256ffe7 3901 1, section->sh_size, _("dynamic strings"));
d79b3d50 3902 dynamic_strings_length = section->sh_size;
252b5132 3903 }
9ad5cbcf
AM
3904 else if (section->sh_type == SHT_SYMTAB_SHNDX)
3905 {
3906 if (symtab_shndx_hdr != NULL)
3907 {
3908 error (_("File contains multiple symtab shndx tables\n"));
3909 continue;
3910 }
3911 symtab_shndx_hdr = section;
3912 }
252b5132 3913 else if ((do_debugging || do_debug_info || do_debug_abbrevs
31b6fca6 3914 || do_debug_lines || do_debug_pubnames || do_debug_aranges
a2f14207 3915 || do_debug_frames || do_debug_macinfo || do_debug_str
18bd398b
NC
3916 || do_debug_loc || do_debug_ranges)
3917 && strneq (name, ".debug_", 7))
252b5132
RH
3918 {
3919 name += 7;
3920
3921 if (do_debugging
18bd398b
NC
3922 || (do_debug_info && streq (name, "info"))
3923 || (do_debug_abbrevs && streq (name, "abbrev"))
3924 || (do_debug_lines && streq (name, "line"))
3925 || (do_debug_pubnames && streq (name, "pubnames"))
3926 || (do_debug_aranges && streq (name, "aranges"))
3927 || (do_debug_ranges && streq (name, "ranges"))
3928 || (do_debug_frames && streq (name, "frame"))
3929 || (do_debug_macinfo && streq (name, "macinfo"))
3930 || (do_debug_str && streq (name, "str"))
3931 || (do_debug_loc && streq (name, "loc"))
252b5132
RH
3932 )
3933 request_dump (i, DEBUG_DUMP);
3934 }
09fd7e38
JM
3935 /* linkonce section to be combined with .debug_info at link time. */
3936 else if ((do_debugging || do_debug_info)
18bd398b 3937 && strneq (name, ".gnu.linkonce.wi.", 17))
09fd7e38 3938 request_dump (i, DEBUG_DUMP);
18bd398b 3939 else if (do_debug_frames && streq (name, ".eh_frame"))
c47d488e 3940 request_dump (i, DEBUG_DUMP);
252b5132
RH
3941 }
3942
3943 if (! do_sections)
3944 return 1;
3945
3a1a2036
NC
3946 if (elf_header.e_shnum > 1)
3947 printf (_("\nSection Headers:\n"));
3948 else
3949 printf (_("\nSection Header:\n"));
76da6bbe 3950
f7a99963 3951 if (is_32bit_elf)
595cf52e
L
3952 {
3953 if (do_full_section_name)
3954 {
3955 printf (_(" [Nr] Name\n"));
3956 printf (_(" Type Addr Off Size ES Flg Lk Inf Al\n"));
3957 }
3958 else
3959 printf
3960 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
3961 }
d974e256 3962 else if (do_wide)
595cf52e
L
3963 {
3964 if (do_full_section_name)
3965 {
3966 printf (_(" [Nr] Name\n"));
3967 printf (_(" Type Address Off Size ES Flg Lk Inf Al\n"));
3968 }
3969 else
3970 printf
3971 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
3972 }
f7a99963
NC
3973 else
3974 {
595cf52e
L
3975 if (do_full_section_name)
3976 {
3977 printf (_(" [Nr] Name\n"));
3978 printf (_(" Flags Type Address Offset\n"));
3979 printf (_(" Size EntSize Link Info Align\n"));
3980 }
3981 else
3982 {
3983 printf (_(" [Nr] Name Type Address Offset\n"));
3984 printf (_(" Size EntSize Flags Link Info Align\n"));
3985 }
f7a99963 3986 }
252b5132
RH
3987
3988 for (i = 0, section = section_headers;
3989 i < elf_header.e_shnum;
b34976b6 3990 i++, section++)
252b5132 3991 {
595cf52e
L
3992 if (do_full_section_name)
3993 {
3994 printf (" [%2u] %s\n",
3995 SECTION_HEADER_NUM (i),
3996 SECTION_NAME (section));
3997 if (is_32bit_elf || do_wide)
3998 printf (" %-15.15s ",
3999 get_section_type_name (section->sh_type));
4000 }
4001 else
4002 printf (" [%2u] %-17.17s %-15.15s ",
4003 SECTION_HEADER_NUM (i),
4004 SECTION_NAME (section),
4005 get_section_type_name (section->sh_type));
252b5132 4006
f7a99963
NC
4007 if (is_32bit_elf)
4008 {
4009 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4010
f7a99963
NC
4011 printf ( " %6.6lx %6.6lx %2.2lx",
4012 (unsigned long) section->sh_offset,
4013 (unsigned long) section->sh_size,
4014 (unsigned long) section->sh_entsize);
d1133906
NC
4015
4016 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4017
f2da459f 4018 printf ("%2ld %3lu %2ld\n",
f7a99963
NC
4019 (unsigned long) section->sh_link,
4020 (unsigned long) section->sh_info,
4021 (unsigned long) section->sh_addralign);
4022 }
d974e256
JJ
4023 else if (do_wide)
4024 {
4025 print_vma (section->sh_addr, LONG_HEX);
4026
4027 if ((long) section->sh_offset == section->sh_offset)
4028 printf (" %6.6lx", (unsigned long) section->sh_offset);
4029 else
4030 {
4031 putchar (' ');
4032 print_vma (section->sh_offset, LONG_HEX);
4033 }
4034
4035 if ((unsigned long) section->sh_size == section->sh_size)
4036 printf (" %6.6lx", (unsigned long) section->sh_size);
4037 else
4038 {
4039 putchar (' ');
4040 print_vma (section->sh_size, LONG_HEX);
4041 }
4042
4043 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4044 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4045 else
4046 {
4047 putchar (' ');
4048 print_vma (section->sh_entsize, LONG_HEX);
4049 }
4050
4051 printf (" %3s ", get_elf_section_flags (section->sh_flags));
4052
f2da459f 4053 printf ("%2ld %3lu ",
d974e256
JJ
4054 (unsigned long) section->sh_link,
4055 (unsigned long) section->sh_info);
4056
4057 if ((unsigned long) section->sh_addralign == section->sh_addralign)
4058 printf ("%2ld\n", (unsigned long) section->sh_addralign);
4059 else
4060 {
4061 print_vma (section->sh_addralign, DEC);
4062 putchar ('\n');
4063 }
4064 }
595cf52e
L
4065 else if (do_full_section_name)
4066 {
4067 printf (" %-15.15s %-15.15s ",
4068 get_elf_section_flags (section->sh_flags),
4069 get_section_type_name (section->sh_type));
4070 putchar (' ');
4071 print_vma (section->sh_addr, LONG_HEX);
4072 if ((long) section->sh_offset == section->sh_offset)
4073 printf (" %8.8lx", (unsigned long) section->sh_offset);
4074 else
4075 {
4076 printf (" ");
4077 print_vma (section->sh_offset, LONG_HEX);
4078 }
4079 printf ("\n ");
4080 print_vma (section->sh_size, LONG_HEX);
4081 printf (" ");
4082 print_vma (section->sh_entsize, LONG_HEX);
4083
4084 printf (" %2ld %3lu %ld\n",
4085 (unsigned long) section->sh_link,
4086 (unsigned long) section->sh_info,
4087 (unsigned long) section->sh_addralign);
4088 }
f7a99963
NC
4089 else
4090 {
4091 putchar (' ');
4092 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4093 if ((long) section->sh_offset == section->sh_offset)
4094 printf (" %8.8lx", (unsigned long) section->sh_offset);
4095 else
4096 {
4097 printf (" ");
4098 print_vma (section->sh_offset, LONG_HEX);
4099 }
f7a99963
NC
4100 printf ("\n ");
4101 print_vma (section->sh_size, LONG_HEX);
4102 printf (" ");
4103 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4104
d1133906 4105 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4106
f2da459f 4107 printf (" %2ld %3lu %ld\n",
f7a99963
NC
4108 (unsigned long) section->sh_link,
4109 (unsigned long) section->sh_info,
4110 (unsigned long) section->sh_addralign);
4111 }
252b5132
RH
4112 }
4113
e3c8793a
NC
4114 printf (_("Key to Flags:\n\
4115 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
4116 I (info), L (link order), G (group), x (unknown)\n\
4117 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
d1133906 4118
252b5132
RH
4119 return 1;
4120}
4121
f5842774
L
4122static const char *
4123get_group_flags (unsigned int flags)
4124{
4125 static char buff[32];
4126 switch (flags)
4127 {
4128 case GRP_COMDAT:
4129 return "COMDAT";
4130
4131 default:
e9e44622 4132 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x]"), flags);
f5842774
L
4133 break;
4134 }
4135 return buff;
4136}
4137
4138static int
4139process_section_groups (FILE *file)
4140{
4141 Elf_Internal_Shdr *section;
4142 unsigned int i;
e4b17d5c 4143 struct group *group;
d1f5c6e3
L
4144 Elf_Internal_Shdr *symtab_sec, *strtab_sec;
4145 Elf_Internal_Sym *symtab;
4146 char *strtab;
c256ffe7 4147 size_t strtab_size;
d1f5c6e3
L
4148
4149 /* Don't process section groups unless needed. */
4150 if (!do_unwind && !do_section_groups)
4151 return 1;
f5842774
L
4152
4153 if (elf_header.e_shnum == 0)
4154 {
4155 if (do_section_groups)
d1f5c6e3 4156 printf (_("\nThere are no sections in this file.\n"));
f5842774
L
4157
4158 return 1;
4159 }
4160
4161 if (section_headers == NULL)
4162 {
4163 error (_("Section headers are not available!\n"));
4164 abort ();
4165 }
4166
e4b17d5c
L
4167 section_headers_groups = calloc (elf_header.e_shnum,
4168 sizeof (struct group *));
4169
4170 if (section_headers_groups == NULL)
4171 {
4172 error (_("Out of memory\n"));
4173 return 0;
4174 }
4175
f5842774 4176 /* Scan the sections for the group section. */
d1f5c6e3 4177 group_count = 0;
f5842774
L
4178 for (i = 0, section = section_headers;
4179 i < elf_header.e_shnum;
4180 i++, section++)
e4b17d5c
L
4181 if (section->sh_type == SHT_GROUP)
4182 group_count++;
4183
d1f5c6e3
L
4184 if (group_count == 0)
4185 {
4186 if (do_section_groups)
4187 printf (_("\nThere are no section groups in this file.\n"));
4188
4189 return 1;
4190 }
4191
e4b17d5c
L
4192 section_groups = calloc (group_count, sizeof (struct group));
4193
4194 if (section_groups == NULL)
4195 {
4196 error (_("Out of memory\n"));
4197 return 0;
4198 }
4199
d1f5c6e3
L
4200 symtab_sec = NULL;
4201 strtab_sec = NULL;
4202 symtab = NULL;
4203 strtab = NULL;
c256ffe7 4204 strtab_size = 0;
e4b17d5c
L
4205 for (i = 0, section = section_headers, group = section_groups;
4206 i < elf_header.e_shnum;
4207 i++, section++)
f5842774
L
4208 {
4209 if (section->sh_type == SHT_GROUP)
4210 {
4211 char *name = SECTION_NAME (section);
dc3c06c2
AM
4212 char *group_name;
4213 unsigned char *start, *indices;
f5842774 4214 unsigned int entry, j, size;
d1f5c6e3 4215 Elf_Internal_Shdr *sec;
f5842774 4216 Elf_Internal_Sym *sym;
f5842774
L
4217
4218 /* Get the symbol table. */
c256ffe7
JJ
4219 if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum
4220 || ((sec = SECTION_HEADER (section->sh_link))->sh_type
4221 != SHT_SYMTAB))
f5842774
L
4222 {
4223 error (_("Bad sh_link in group section `%s'\n"), name);
4224 continue;
4225 }
d1f5c6e3
L
4226
4227 if (symtab_sec != sec)
4228 {
4229 symtab_sec = sec;
4230 if (symtab)
4231 free (symtab);
4232 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
4233 }
f5842774
L
4234
4235 sym = symtab + section->sh_info;
4236
4237 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4238 {
4239 bfd_vma sec_index = SECTION_HEADER_INDEX (sym->st_shndx);
4240 if (sec_index == 0)
4241 {
4242 error (_("Bad sh_info in group section `%s'\n"), name);
4243 continue;
4244 }
ba2685cc 4245
f5842774 4246 group_name = SECTION_NAME (section_headers + sec_index);
c256ffe7
JJ
4247 strtab_sec = NULL;
4248 if (strtab)
4249 free (strtab);
f5842774 4250 strtab = NULL;
c256ffe7 4251 strtab_size = 0;
f5842774
L
4252 }
4253 else
4254 {
4255 /* Get the string table. */
c256ffe7
JJ
4256 if (SECTION_HEADER_INDEX (symtab_sec->sh_link)
4257 >= elf_header.e_shnum)
4258 {
4259 strtab_sec = NULL;
4260 if (strtab)
4261 free (strtab);
4262 strtab = NULL;
4263 strtab_size = 0;
4264 }
4265 else if (strtab_sec
4266 != (sec = SECTION_HEADER (symtab_sec->sh_link)))
d1f5c6e3
L
4267 {
4268 strtab_sec = sec;
4269 if (strtab)
4270 free (strtab);
4271 strtab = get_data (NULL, file, strtab_sec->sh_offset,
c256ffe7 4272 1, strtab_sec->sh_size,
d1f5c6e3 4273 _("string table"));
c256ffe7 4274 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 4275 }
c256ffe7
JJ
4276 group_name = sym->st_name < strtab_size
4277 ? strtab + sym->st_name : "<corrupt>";
f5842774
L
4278 }
4279
4280 start = get_data (NULL, file, section->sh_offset,
c256ffe7 4281 1, section->sh_size, _("section data"));
f5842774
L
4282
4283 indices = start;
4284 size = (section->sh_size / section->sh_entsize) - 1;
4285 entry = byte_get (indices, 4);
4286 indices += 4;
e4b17d5c
L
4287
4288 if (do_section_groups)
4289 {
391cb864
L
4290 printf ("\n%s group section [%5u] `%s' [%s] contains %u sections:\n",
4291 get_group_flags (entry), i, name, group_name, size);
ba2685cc 4292
e4b17d5c
L
4293 printf (_(" [Index] Name\n"));
4294 }
4295
4296 group->group_index = i;
4297
f5842774
L
4298 for (j = 0; j < size; j++)
4299 {
e4b17d5c
L
4300 struct group_list *g;
4301
f5842774
L
4302 entry = byte_get (indices, 4);
4303 indices += 4;
4304
c256ffe7 4305 if (SECTION_HEADER_INDEX (entry) >= elf_header.e_shnum)
391cb864
L
4306 {
4307 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
4308 entry, i, elf_header.e_shnum - 1);
4309 continue;
4310 }
4311 else if (entry >= SHN_LORESERVE && entry <= SHN_HIRESERVE)
4312 {
4313 error (_("invalid section [%5u] in group section [%5u]\n"),
4314 entry, i);
4315 continue;
4316 }
4317
e4b17d5c
L
4318 if (section_headers_groups [SECTION_HEADER_INDEX (entry)]
4319 != NULL)
4320 {
d1f5c6e3
L
4321 if (entry)
4322 {
391cb864
L
4323 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
4324 entry, i,
d1f5c6e3
L
4325 section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
4326 continue;
4327 }
4328 else
4329 {
4330 /* Intel C/C++ compiler may put section 0 in a
4331 section group. We just warn it the first time
4332 and ignore it afterwards. */
4333 static int warned = 0;
4334 if (!warned)
4335 {
4336 error (_("section 0 in group section [%5u]\n"),
4337 section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
4338 warned++;
4339 }
4340 }
e4b17d5c
L
4341 }
4342
4343 section_headers_groups [SECTION_HEADER_INDEX (entry)]
4344 = group;
4345
4346 if (do_section_groups)
4347 {
4348 sec = SECTION_HEADER (entry);
c256ffe7 4349 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
4350 }
4351
e4b17d5c
L
4352 g = xmalloc (sizeof (struct group_list));
4353 g->section_index = entry;
4354 g->next = group->root;
4355 group->root = g;
f5842774
L
4356 }
4357
f5842774
L
4358 if (start)
4359 free (start);
e4b17d5c
L
4360
4361 group++;
f5842774
L
4362 }
4363 }
4364
d1f5c6e3
L
4365 if (symtab)
4366 free (symtab);
4367 if (strtab)
4368 free (strtab);
f5842774
L
4369 return 1;
4370}
4371
85b1c36d 4372static struct
566b0d53
L
4373{
4374 const char *name;
4375 int reloc;
4376 int size;
4377 int rela;
4378} dynamic_relocations [] =
4379{
4380 { "REL", DT_REL, DT_RELSZ, FALSE },
4381 { "RELA", DT_RELA, DT_RELASZ, TRUE },
4382 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
4383};
4384
252b5132 4385/* Process the reloc section. */
18bd398b 4386
252b5132 4387static int
d3ba0551 4388process_relocs (FILE *file)
252b5132 4389{
b34976b6
AM
4390 unsigned long rel_size;
4391 unsigned long rel_offset;
252b5132
RH
4392
4393
4394 if (!do_reloc)
4395 return 1;
4396
4397 if (do_using_dynamic)
4398 {
566b0d53
L
4399 int is_rela;
4400 const char *name;
4401 int has_dynamic_reloc;
4402 unsigned int i;
0de14b54 4403
566b0d53 4404 has_dynamic_reloc = 0;
252b5132 4405
566b0d53 4406 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 4407 {
566b0d53
L
4408 is_rela = dynamic_relocations [i].rela;
4409 name = dynamic_relocations [i].name;
4410 rel_size = dynamic_info [dynamic_relocations [i].size];
4411 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 4412
566b0d53
L
4413 has_dynamic_reloc |= rel_size;
4414
4415 if (is_rela == UNKNOWN)
aa903cfb 4416 {
566b0d53
L
4417 if (dynamic_relocations [i].reloc == DT_JMPREL)
4418 switch (dynamic_info[DT_PLTREL])
4419 {
4420 case DT_REL:
4421 is_rela = FALSE;
4422 break;
4423 case DT_RELA:
4424 is_rela = TRUE;
4425 break;
4426 }
aa903cfb 4427 }
252b5132 4428
566b0d53
L
4429 if (rel_size)
4430 {
4431 printf
4432 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
4433 name, rel_offset, rel_size);
252b5132 4434
d93f0186
NC
4435 dump_relocations (file,
4436 offset_from_vma (file, rel_offset, rel_size),
4437 rel_size,
566b0d53 4438 dynamic_symbols, num_dynamic_syms,
d79b3d50 4439 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 4440 }
252b5132 4441 }
566b0d53
L
4442
4443 if (! has_dynamic_reloc)
252b5132
RH
4444 printf (_("\nThere are no dynamic relocations in this file.\n"));
4445 }
4446 else
4447 {
b34976b6
AM
4448 Elf_Internal_Shdr *section;
4449 unsigned long i;
4450 int found = 0;
252b5132
RH
4451
4452 for (i = 0, section = section_headers;
4453 i < elf_header.e_shnum;
b34976b6 4454 i++, section++)
252b5132
RH
4455 {
4456 if ( section->sh_type != SHT_RELA
4457 && section->sh_type != SHT_REL)
4458 continue;
4459
4460 rel_offset = section->sh_offset;
4461 rel_size = section->sh_size;
4462
4463 if (rel_size)
4464 {
b34976b6 4465 Elf_Internal_Shdr *strsec;
b34976b6 4466 int is_rela;
103f02d3 4467
252b5132
RH
4468 printf (_("\nRelocation section "));
4469
4470 if (string_table == NULL)
19936277 4471 printf ("%d", section->sh_name);
252b5132 4472 else
3a1a2036 4473 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
4474
4475 printf (_(" at offset 0x%lx contains %lu entries:\n"),
4476 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
4477
d79b3d50
NC
4478 is_rela = section->sh_type == SHT_RELA;
4479
c256ffe7
JJ
4480 if (section->sh_link
4481 && SECTION_HEADER_INDEX (section->sh_link)
4482 < elf_header.e_shnum)
af3fc3bc 4483 {
b34976b6 4484 Elf_Internal_Shdr *symsec;
d79b3d50
NC
4485 Elf_Internal_Sym *symtab;
4486 unsigned long nsyms;
c256ffe7 4487 unsigned long strtablen = 0;
d79b3d50 4488 char *strtab = NULL;
57346661 4489
9ad5cbcf 4490 symsec = SECTION_HEADER (section->sh_link);
af3fc3bc 4491 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 4492 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 4493
af3fc3bc
AM
4494 if (symtab == NULL)
4495 continue;
252b5132 4496
c256ffe7
JJ
4497 if (SECTION_HEADER_INDEX (symsec->sh_link)
4498 < elf_header.e_shnum)
4499 {
4500 strsec = SECTION_HEADER (symsec->sh_link);
103f02d3 4501
c256ffe7
JJ
4502 strtab = get_data (NULL, file, strsec->sh_offset,
4503 1, strsec->sh_size,
4504 _("string table"));
4505 strtablen = strtab == NULL ? 0 : strsec->sh_size;
4506 }
252b5132 4507
d79b3d50
NC
4508 dump_relocations (file, rel_offset, rel_size,
4509 symtab, nsyms, strtab, strtablen, is_rela);
4510 if (strtab)
4511 free (strtab);
4512 free (symtab);
4513 }
4514 else
4515 dump_relocations (file, rel_offset, rel_size,
4516 NULL, 0, NULL, 0, is_rela);
252b5132
RH
4517
4518 found = 1;
4519 }
4520 }
4521
4522 if (! found)
4523 printf (_("\nThere are no relocations in this file.\n"));
4524 }
4525
4526 return 1;
4527}
4528
57346661
AM
4529/* Process the unwind section. */
4530
4d6ed7c8
NC
4531#include "unwind-ia64.h"
4532
4533/* An absolute address consists of a section and an offset. If the
4534 section is NULL, the offset itself is the address, otherwise, the
4535 address equals to LOAD_ADDRESS(section) + offset. */
4536
4537struct absaddr
4538 {
4539 unsigned short section;
4540 bfd_vma offset;
4541 };
4542
57346661 4543struct ia64_unw_aux_info
4d6ed7c8 4544 {
57346661 4545 struct ia64_unw_table_entry
4d6ed7c8 4546 {
b34976b6
AM
4547 struct absaddr start;
4548 struct absaddr end;
4549 struct absaddr info;
4d6ed7c8 4550 }
b34976b6
AM
4551 *table; /* Unwind table. */
4552 unsigned long table_len; /* Length of unwind table. */
4553 unsigned char *info; /* Unwind info. */
4554 unsigned long info_size; /* Size of unwind info. */
4555 bfd_vma info_addr; /* starting address of unwind info. */
4556 bfd_vma seg_base; /* Starting address of segment. */
4557 Elf_Internal_Sym *symtab; /* The symbol table. */
4558 unsigned long nsyms; /* Number of symbols. */
4559 char *strtab; /* The string table. */
4560 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
4561 };
4562
4d6ed7c8 4563static void
57346661
AM
4564find_symbol_for_address (Elf_Internal_Sym *symtab,
4565 unsigned long nsyms,
4566 const char *strtab,
4567 unsigned long strtab_size,
d3ba0551
AM
4568 struct absaddr addr,
4569 const char **symname,
4570 bfd_vma *offset)
4d6ed7c8 4571{
d3ba0551 4572 bfd_vma dist = 0x100000;
4d6ed7c8
NC
4573 Elf_Internal_Sym *sym, *best = NULL;
4574 unsigned long i;
4575
57346661 4576 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8
NC
4577 {
4578 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
4579 && sym->st_name != 0
4580 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
4581 && addr.offset >= sym->st_value
4582 && addr.offset - sym->st_value < dist)
4583 {
4584 best = sym;
4585 dist = addr.offset - sym->st_value;
4586 if (!dist)
4587 break;
4588 }
4589 }
4590 if (best)
4591 {
57346661
AM
4592 *symname = (best->st_name >= strtab_size
4593 ? "<corrupt>" : strtab + best->st_name);
4d6ed7c8
NC
4594 *offset = dist;
4595 return;
4596 }
4597 *symname = NULL;
4598 *offset = addr.offset;
4599}
4600
4601static void
57346661 4602dump_ia64_unwind (struct ia64_unw_aux_info *aux)
4d6ed7c8 4603{
57346661 4604 struct ia64_unw_table_entry *tp;
4d6ed7c8 4605 int in_body;
7036c0e1 4606
4d6ed7c8
NC
4607 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
4608 {
4609 bfd_vma stamp;
4610 bfd_vma offset;
b34976b6
AM
4611 const unsigned char *dp;
4612 const unsigned char *head;
4613 const char *procname;
4d6ed7c8 4614
57346661
AM
4615 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
4616 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
4617
4618 fputs ("\n<", stdout);
4619
4620 if (procname)
4621 {
4622 fputs (procname, stdout);
4623
4624 if (offset)
4625 printf ("+%lx", (unsigned long) offset);
4626 }
4627
4628 fputs (">: [", stdout);
4629 print_vma (tp->start.offset, PREFIX_HEX);
4630 fputc ('-', stdout);
4631 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 4632 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
4633 (unsigned long) (tp->info.offset - aux->seg_base));
4634
4635 head = aux->info + (tp->info.offset - aux->info_addr);
a4a00738 4636 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 4637
86f55779 4638 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
4639 (unsigned) UNW_VER (stamp),
4640 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
4641 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
4642 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 4643 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
4644
4645 if (UNW_VER (stamp) != 1)
4646 {
4647 printf ("\tUnknown version.\n");
4648 continue;
4649 }
4650
4651 in_body = 0;
89fac5e3 4652 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
4653 dp = unw_decode (dp, in_body, & in_body);
4654 }
4655}
4656
4657static int
d3ba0551 4658slurp_ia64_unwind_table (FILE *file,
57346661 4659 struct ia64_unw_aux_info *aux,
d3ba0551 4660 Elf_Internal_Shdr *sec)
4d6ed7c8 4661{
89fac5e3 4662 unsigned long size, nrelas, i;
d93f0186 4663 Elf_Internal_Phdr *seg;
57346661 4664 struct ia64_unw_table_entry *tep;
c8286bd1 4665 Elf_Internal_Shdr *relsec;
4d6ed7c8
NC
4666 Elf_Internal_Rela *rela, *rp;
4667 unsigned char *table, *tp;
4668 Elf_Internal_Sym *sym;
4669 const char *relname;
4d6ed7c8 4670
4d6ed7c8
NC
4671 /* First, find the starting address of the segment that includes
4672 this section: */
4673
4674 if (elf_header.e_phnum)
4675 {
d93f0186 4676 if (! get_program_headers (file))
4d6ed7c8 4677 return 0;
4d6ed7c8 4678
d93f0186
NC
4679 for (seg = program_headers;
4680 seg < program_headers + elf_header.e_phnum;
4681 ++seg)
4d6ed7c8
NC
4682 {
4683 if (seg->p_type != PT_LOAD)
4684 continue;
4685
4686 if (sec->sh_addr >= seg->p_vaddr
4687 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
4688 {
4689 aux->seg_base = seg->p_vaddr;
4690 break;
4691 }
4692 }
4d6ed7c8
NC
4693 }
4694
4695 /* Second, build the unwind table from the contents of the unwind section: */
4696 size = sec->sh_size;
c256ffe7 4697 table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
a6e9f9df
AM
4698 if (!table)
4699 return 0;
4d6ed7c8 4700
c256ffe7 4701 aux->table = xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3
RS
4702 tep = aux->table;
4703 for (tp = table; tp < table + size; tp += 3 * eh_addr_size, ++tep)
4d6ed7c8
NC
4704 {
4705 tep->start.section = SHN_UNDEF;
4706 tep->end.section = SHN_UNDEF;
4707 tep->info.section = SHN_UNDEF;
4708 if (is_32bit_elf)
4709 {
4710 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
4711 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
4712 tep->info.offset = byte_get ((unsigned char *) tp + 8, 4);
4713 }
4714 else
4715 {
66543521
AM
4716 tep->start.offset = BYTE_GET ((unsigned char *) tp + 0);
4717 tep->end.offset = BYTE_GET ((unsigned char *) tp + 8);
4718 tep->info.offset = BYTE_GET ((unsigned char *) tp + 16);
4d6ed7c8
NC
4719 }
4720 tep->start.offset += aux->seg_base;
4721 tep->end.offset += aux->seg_base;
4722 tep->info.offset += aux->seg_base;
4723 }
4724 free (table);
4725
4726 /* Third, apply any relocations to the unwind table: */
4727
4728 for (relsec = section_headers;
4729 relsec < section_headers + elf_header.e_shnum;
4730 ++relsec)
4731 {
4732 if (relsec->sh_type != SHT_RELA
c256ffe7 4733 || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
9ad5cbcf 4734 || SECTION_HEADER (relsec->sh_info) != sec)
4d6ed7c8
NC
4735 continue;
4736
4737 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
4738 & rela, & nrelas))
4739 return 0;
4740
4741 for (rp = rela; rp < rela + nrelas; ++rp)
4742 {
4743 if (is_32bit_elf)
4744 {
4745 relname = elf_ia64_reloc_type (ELF32_R_TYPE (rp->r_info));
4746 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
4d6ed7c8
NC
4747 }
4748 else
4749 {
4750 relname = elf_ia64_reloc_type (ELF64_R_TYPE (rp->r_info));
4751 sym = aux->symtab + ELF64_R_SYM (rp->r_info);
4d6ed7c8
NC
4752 }
4753
18bd398b 4754 if (! strneq (relname, "R_IA64_SEGREL", 13))
4d6ed7c8 4755 {
e5fb9629 4756 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
4757 continue;
4758 }
4759
89fac5e3 4760 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 4761
89fac5e3 4762 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
4763 {
4764 case 0:
4765 aux->table[i].start.section = sym->st_shndx;
1ffa9a18 4766 aux->table[i].start.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
4767 break;
4768 case 1:
4769 aux->table[i].end.section = sym->st_shndx;
1ffa9a18 4770 aux->table[i].end.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
4771 break;
4772 case 2:
4773 aux->table[i].info.section = sym->st_shndx;
1ffa9a18 4774 aux->table[i].info.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
4775 break;
4776 default:
4777 break;
4778 }
4779 }
4780
4781 free (rela);
4782 }
4783
89fac5e3 4784 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
4785 return 1;
4786}
4787
4788static int
57346661 4789ia64_process_unwind (FILE *file)
4d6ed7c8 4790{
c8286bd1 4791 Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
89fac5e3 4792 unsigned long i, unwcount = 0, unwstart = 0;
57346661 4793 struct ia64_unw_aux_info aux;
f1467e33 4794
4d6ed7c8
NC
4795 memset (& aux, 0, sizeof (aux));
4796
4d6ed7c8
NC
4797 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
4798 {
c256ffe7
JJ
4799 if (sec->sh_type == SHT_SYMTAB
4800 && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum)
4d6ed7c8
NC
4801 {
4802 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 4803 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 4804
9ad5cbcf 4805 strsec = SECTION_HEADER (sec->sh_link);
d3ba0551 4806 aux.strtab = get_data (NULL, file, strsec->sh_offset,
c256ffe7
JJ
4807 1, strsec->sh_size, _("string table"));
4808 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
4809 }
4810 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
4811 unwcount++;
4812 }
4813
4814 if (!unwcount)
4815 printf (_("\nThere are no unwind sections in this file.\n"));
4816
4817 while (unwcount-- > 0)
4818 {
4819 char *suffix;
4820 size_t len, len2;
4821
4822 for (i = unwstart, sec = section_headers + unwstart;
4823 i < elf_header.e_shnum; ++i, ++sec)
4824 if (sec->sh_type == SHT_IA_64_UNWIND)
4825 {
4826 unwsec = sec;
4827 break;
4828 }
4829
4830 unwstart = i + 1;
4831 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
4832
e4b17d5c
L
4833 if ((unwsec->sh_flags & SHF_GROUP) != 0)
4834 {
4835 /* We need to find which section group it is in. */
4836 struct group_list *g = section_headers_groups [i]->root;
4837
4838 for (; g != NULL; g = g->next)
4839 {
4840 sec = SECTION_HEADER (g->section_index);
18bd398b
NC
4841
4842 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 4843 break;
e4b17d5c
L
4844 }
4845
4846 if (g == NULL)
4847 i = elf_header.e_shnum;
4848 }
18bd398b 4849 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 4850 {
18bd398b 4851 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
4852 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
4853 suffix = SECTION_NAME (unwsec) + len;
4854 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
4855 ++i, ++sec)
18bd398b
NC
4856 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
4857 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
4858 break;
4859 }
4860 else
4861 {
4862 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 4863 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
4864 len = sizeof (ELF_STRING_ia64_unwind) - 1;
4865 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
4866 suffix = "";
18bd398b 4867 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
4868 suffix = SECTION_NAME (unwsec) + len;
4869 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
4870 ++i, ++sec)
18bd398b
NC
4871 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
4872 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
4873 break;
4874 }
4875
4876 if (i == elf_header.e_shnum)
4877 {
4878 printf (_("\nCould not find unwind info section for "));
4879
4880 if (string_table == NULL)
4881 printf ("%d", unwsec->sh_name);
4882 else
3a1a2036 4883 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
4884 }
4885 else
4d6ed7c8
NC
4886 {
4887 aux.info_size = sec->sh_size;
4888 aux.info_addr = sec->sh_addr;
c256ffe7 4889 aux.info = get_data (NULL, file, sec->sh_offset, 1, aux.info_size,
d3ba0551 4890 _("unwind info"));
4d6ed7c8 4891
579f31ac 4892 printf (_("\nUnwind section "));
4d6ed7c8 4893
579f31ac
JJ
4894 if (string_table == NULL)
4895 printf ("%d", unwsec->sh_name);
4896 else
3a1a2036 4897 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 4898
579f31ac 4899 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 4900 (unsigned long) unwsec->sh_offset,
89fac5e3 4901 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 4902
579f31ac 4903 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 4904
579f31ac
JJ
4905 if (aux.table_len > 0)
4906 dump_ia64_unwind (& aux);
4907
4908 if (aux.table)
4909 free ((char *) aux.table);
4910 if (aux.info)
4911 free ((char *) aux.info);
4912 aux.table = NULL;
4913 aux.info = NULL;
4914 }
4d6ed7c8 4915 }
4d6ed7c8 4916
4d6ed7c8
NC
4917 if (aux.symtab)
4918 free (aux.symtab);
4919 if (aux.strtab)
4920 free ((char *) aux.strtab);
4921
4922 return 1;
4923}
4924
57346661
AM
4925struct hppa_unw_aux_info
4926 {
4927 struct hppa_unw_table_entry
4928 {
4929 struct absaddr start;
4930 struct absaddr end;
4931 unsigned int Cannot_unwind:1; /* 0 */
4932 unsigned int Millicode:1; /* 1 */
4933 unsigned int Millicode_save_sr0:1; /* 2 */
4934 unsigned int Region_description:2; /* 3..4 */
4935 unsigned int reserved1:1; /* 5 */
4936 unsigned int Entry_SR:1; /* 6 */
4937 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
4938 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
4939 unsigned int Args_stored:1; /* 16 */
4940 unsigned int Variable_Frame:1; /* 17 */
4941 unsigned int Separate_Package_Body:1; /* 18 */
4942 unsigned int Frame_Extension_Millicode:1; /* 19 */
4943 unsigned int Stack_Overflow_Check:1; /* 20 */
4944 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
4945 unsigned int Ada_Region:1; /* 22 */
4946 unsigned int cxx_info:1; /* 23 */
4947 unsigned int cxx_try_catch:1; /* 24 */
4948 unsigned int sched_entry_seq:1; /* 25 */
4949 unsigned int reserved2:1; /* 26 */
4950 unsigned int Save_SP:1; /* 27 */
4951 unsigned int Save_RP:1; /* 28 */
4952 unsigned int Save_MRP_in_frame:1; /* 29 */
4953 unsigned int extn_ptr_defined:1; /* 30 */
4954 unsigned int Cleanup_defined:1; /* 31 */
4955
4956 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
4957 unsigned int HP_UX_interrupt_marker:1; /* 1 */
4958 unsigned int Large_frame:1; /* 2 */
4959 unsigned int Pseudo_SP_Set:1; /* 3 */
4960 unsigned int reserved4:1; /* 4 */
4961 unsigned int Total_frame_size:27; /* 5..31 */
4962 }
4963 *table; /* Unwind table. */
4964 unsigned long table_len; /* Length of unwind table. */
4965 bfd_vma seg_base; /* Starting address of segment. */
4966 Elf_Internal_Sym *symtab; /* The symbol table. */
4967 unsigned long nsyms; /* Number of symbols. */
4968 char *strtab; /* The string table. */
4969 unsigned long strtab_size; /* Size of string table. */
4970 };
4971
4972static void
4973dump_hppa_unwind (struct hppa_unw_aux_info *aux)
4974{
57346661
AM
4975 struct hppa_unw_table_entry *tp;
4976
57346661
AM
4977 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
4978 {
4979 bfd_vma offset;
4980 const char *procname;
4981
4982 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
4983 aux->strtab_size, tp->start, &procname,
4984 &offset);
4985
4986 fputs ("\n<", stdout);
4987
4988 if (procname)
4989 {
4990 fputs (procname, stdout);
4991
4992 if (offset)
4993 printf ("+%lx", (unsigned long) offset);
4994 }
4995
4996 fputs (">: [", stdout);
4997 print_vma (tp->start.offset, PREFIX_HEX);
4998 fputc ('-', stdout);
4999 print_vma (tp->end.offset, PREFIX_HEX);
5000 printf ("]\n\t");
5001
18bd398b
NC
5002#define PF(_m) if (tp->_m) printf (#_m " ");
5003#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5004 PF(Cannot_unwind);
5005 PF(Millicode);
5006 PF(Millicode_save_sr0);
18bd398b 5007 /* PV(Region_description); */
57346661
AM
5008 PF(Entry_SR);
5009 PV(Entry_FR);
5010 PV(Entry_GR);
5011 PF(Args_stored);
5012 PF(Variable_Frame);
5013 PF(Separate_Package_Body);
5014 PF(Frame_Extension_Millicode);
5015 PF(Stack_Overflow_Check);
5016 PF(Two_Instruction_SP_Increment);
5017 PF(Ada_Region);
5018 PF(cxx_info);
5019 PF(cxx_try_catch);
5020 PF(sched_entry_seq);
5021 PF(Save_SP);
5022 PF(Save_RP);
5023 PF(Save_MRP_in_frame);
5024 PF(extn_ptr_defined);
5025 PF(Cleanup_defined);
5026 PF(MPE_XL_interrupt_marker);
5027 PF(HP_UX_interrupt_marker);
5028 PF(Large_frame);
5029 PF(Pseudo_SP_Set);
5030 PV(Total_frame_size);
5031#undef PF
5032#undef PV
5033 }
5034
18bd398b 5035 printf ("\n");
57346661
AM
5036}
5037
5038static int
5039slurp_hppa_unwind_table (FILE *file,
5040 struct hppa_unw_aux_info *aux,
5041 Elf_Internal_Shdr *sec)
5042{
89fac5e3 5043 unsigned long size, unw_ent_size, nrelas, i;
57346661
AM
5044 Elf_Internal_Phdr *seg;
5045 struct hppa_unw_table_entry *tep;
5046 Elf_Internal_Shdr *relsec;
5047 Elf_Internal_Rela *rela, *rp;
5048 unsigned char *table, *tp;
5049 Elf_Internal_Sym *sym;
5050 const char *relname;
5051
57346661
AM
5052 /* First, find the starting address of the segment that includes
5053 this section. */
5054
5055 if (elf_header.e_phnum)
5056 {
5057 if (! get_program_headers (file))
5058 return 0;
5059
5060 for (seg = program_headers;
5061 seg < program_headers + elf_header.e_phnum;
5062 ++seg)
5063 {
5064 if (seg->p_type != PT_LOAD)
5065 continue;
5066
5067 if (sec->sh_addr >= seg->p_vaddr
5068 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5069 {
5070 aux->seg_base = seg->p_vaddr;
5071 break;
5072 }
5073 }
5074 }
5075
5076 /* Second, build the unwind table from the contents of the unwind
5077 section. */
5078 size = sec->sh_size;
c256ffe7 5079 table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
57346661
AM
5080 if (!table)
5081 return 0;
5082
89fac5e3 5083 unw_ent_size = 2 * eh_addr_size + 8;
57346661 5084
c256ffe7 5085 tep = aux->table = xcmalloc (size / unw_ent_size, sizeof (aux->table[0]));
57346661 5086
89fac5e3 5087 for (tp = table; tp < table + size; tp += (2 * eh_addr_size + 8), ++tep)
57346661
AM
5088 {
5089 unsigned int tmp1, tmp2;
5090
5091 tep->start.section = SHN_UNDEF;
5092 tep->end.section = SHN_UNDEF;
5093
5094 if (is_32bit_elf)
5095 {
5096 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
5097 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
5098 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
5099 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
5100 }
5101 else
5102 {
66543521
AM
5103 tep->start.offset = BYTE_GET ((unsigned char *) tp + 0);
5104 tep->end.offset = BYTE_GET ((unsigned char *) tp + 8);
57346661
AM
5105 tmp1 = byte_get ((unsigned char *) tp + 16, 4);
5106 tmp2 = byte_get ((unsigned char *) tp + 20, 4);
5107 }
5108
5109 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
5110 tep->Millicode = (tmp1 >> 30) & 0x1;
5111 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
5112 tep->Region_description = (tmp1 >> 27) & 0x3;
5113 tep->reserved1 = (tmp1 >> 26) & 0x1;
5114 tep->Entry_SR = (tmp1 >> 25) & 0x1;
5115 tep->Entry_FR = (tmp1 >> 21) & 0xf;
5116 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
5117 tep->Args_stored = (tmp1 >> 15) & 0x1;
5118 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
5119 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
5120 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
5121 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
5122 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
5123 tep->Ada_Region = (tmp1 >> 9) & 0x1;
5124 tep->cxx_info = (tmp1 >> 8) & 0x1;
5125 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
5126 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
5127 tep->reserved2 = (tmp1 >> 5) & 0x1;
5128 tep->Save_SP = (tmp1 >> 4) & 0x1;
5129 tep->Save_RP = (tmp1 >> 3) & 0x1;
5130 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
5131 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
5132 tep->Cleanup_defined = tmp1 & 0x1;
5133
5134 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
5135 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
5136 tep->Large_frame = (tmp2 >> 29) & 0x1;
5137 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
5138 tep->reserved4 = (tmp2 >> 27) & 0x1;
5139 tep->Total_frame_size = tmp2 & 0x7ffffff;
5140
5141 tep->start.offset += aux->seg_base;
5142 tep->end.offset += aux->seg_base;
5143 }
5144 free (table);
5145
5146 /* Third, apply any relocations to the unwind table. */
5147
5148 for (relsec = section_headers;
5149 relsec < section_headers + elf_header.e_shnum;
5150 ++relsec)
5151 {
5152 if (relsec->sh_type != SHT_RELA
c256ffe7 5153 || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
57346661
AM
5154 || SECTION_HEADER (relsec->sh_info) != sec)
5155 continue;
5156
5157 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5158 & rela, & nrelas))
5159 return 0;
5160
5161 for (rp = rela; rp < rela + nrelas; ++rp)
5162 {
5163 if (is_32bit_elf)
5164 {
5165 relname = elf_hppa_reloc_type (ELF32_R_TYPE (rp->r_info));
5166 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
5167 }
5168 else
5169 {
5170 relname = elf_hppa_reloc_type (ELF64_R_TYPE (rp->r_info));
5171 sym = aux->symtab + ELF64_R_SYM (rp->r_info);
5172 }
5173
5174 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
5175 if (strncmp (relname, "R_PARISC_SEGREL", 15) != 0)
5176 {
5177 warn (_("Skipping unexpected relocation type %s\n"), relname);
5178 continue;
5179 }
5180
5181 i = rp->r_offset / unw_ent_size;
5182
89fac5e3 5183 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
5184 {
5185 case 0:
5186 aux->table[i].start.section = sym->st_shndx;
5187 aux->table[i].start.offset += sym->st_value + rp->r_addend;
5188 break;
5189 case 1:
5190 aux->table[i].end.section = sym->st_shndx;
5191 aux->table[i].end.offset += sym->st_value + rp->r_addend;
5192 break;
5193 default:
5194 break;
5195 }
5196 }
5197
5198 free (rela);
5199 }
5200
5201 aux->table_len = size / unw_ent_size;
5202
5203 return 1;
5204}
5205
5206static int
5207hppa_process_unwind (FILE *file)
5208{
57346661 5209 struct hppa_unw_aux_info aux;
18bd398b
NC
5210 Elf_Internal_Shdr *unwsec = NULL;
5211 Elf_Internal_Shdr *strsec;
5212 Elf_Internal_Shdr *sec;
18bd398b 5213 unsigned long i;
57346661
AM
5214
5215 memset (& aux, 0, sizeof (aux));
5216
c256ffe7
JJ
5217 if (string_table == NULL)
5218 return 1;
57346661
AM
5219
5220 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5221 {
c256ffe7
JJ
5222 if (sec->sh_type == SHT_SYMTAB
5223 && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum)
57346661
AM
5224 {
5225 aux.nsyms = sec->sh_size / sec->sh_entsize;
5226 aux.symtab = GET_ELF_SYMBOLS (file, sec);
5227
5228 strsec = SECTION_HEADER (sec->sh_link);
57346661 5229 aux.strtab = get_data (NULL, file, strsec->sh_offset,
c256ffe7
JJ
5230 1, strsec->sh_size, _("string table"));
5231 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 5232 }
18bd398b 5233 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
5234 unwsec = sec;
5235 }
5236
5237 if (!unwsec)
5238 printf (_("\nThere are no unwind sections in this file.\n"));
5239
5240 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5241 {
18bd398b 5242 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 5243 {
57346661
AM
5244 printf (_("\nUnwind section "));
5245 printf (_("'%s'"), SECTION_NAME (sec));
5246
5247 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5248 (unsigned long) sec->sh_offset,
89fac5e3 5249 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
5250
5251 slurp_hppa_unwind_table (file, &aux, sec);
5252 if (aux.table_len > 0)
5253 dump_hppa_unwind (&aux);
5254
5255 if (aux.table)
5256 free ((char *) aux.table);
5257 aux.table = NULL;
5258 }
5259 }
5260
5261 if (aux.symtab)
5262 free (aux.symtab);
5263 if (aux.strtab)
5264 free ((char *) aux.strtab);
5265
5266 return 1;
5267}
5268
5269static int
5270process_unwind (FILE *file)
5271{
5272 struct unwind_handler {
5273 int machtype;
5274 int (*handler)(FILE *file);
5275 } handlers[] = {
5276 { EM_IA_64, ia64_process_unwind },
5277 { EM_PARISC, hppa_process_unwind },
5278 { 0, 0 }
5279 };
5280 int i;
5281
5282 if (!do_unwind)
5283 return 1;
5284
5285 for (i = 0; handlers[i].handler != NULL; i++)
5286 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 5287 return handlers[i].handler (file);
57346661
AM
5288
5289 printf (_("\nThere are no unwind sections in this file.\n"));
5290 return 1;
5291}
5292
252b5132 5293static void
b2d38a17 5294dynamic_section_mips_val (Elf_Internal_Dyn *entry)
252b5132
RH
5295{
5296 switch (entry->d_tag)
5297 {
5298 case DT_MIPS_FLAGS:
5299 if (entry->d_un.d_val == 0)
5300 printf ("NONE\n");
5301 else
5302 {
5303 static const char * opts[] =
5304 {
5305 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
5306 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
5307 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
5308 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
5309 "RLD_ORDER_SAFE"
5310 };
5311 unsigned int cnt;
5312 int first = 1;
b34976b6 5313 for (cnt = 0; cnt < NUM_ELEM (opts); ++cnt)
252b5132
RH
5314 if (entry->d_un.d_val & (1 << cnt))
5315 {
5316 printf ("%s%s", first ? "" : " ", opts[cnt]);
5317 first = 0;
5318 }
5319 puts ("");
5320 }
5321 break;
103f02d3 5322
252b5132 5323 case DT_MIPS_IVERSION:
d79b3d50
NC
5324 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
5325 printf ("Interface Version: %s\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 5326 else
d79b3d50 5327 printf ("<corrupt: %ld>\n", (long) entry->d_un.d_ptr);
252b5132 5328 break;
103f02d3 5329
252b5132
RH
5330 case DT_MIPS_TIME_STAMP:
5331 {
5332 char timebuf[20];
b34976b6 5333 struct tm *tmp;
50da7a9c 5334
252b5132 5335 time_t time = entry->d_un.d_val;
50da7a9c 5336 tmp = gmtime (&time);
e9e44622
JJ
5337 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
5338 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
5339 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
5340 printf ("Time Stamp: %s\n", timebuf);
5341 }
5342 break;
103f02d3 5343
252b5132
RH
5344 case DT_MIPS_RLD_VERSION:
5345 case DT_MIPS_LOCAL_GOTNO:
5346 case DT_MIPS_CONFLICTNO:
5347 case DT_MIPS_LIBLISTNO:
5348 case DT_MIPS_SYMTABNO:
5349 case DT_MIPS_UNREFEXTNO:
5350 case DT_MIPS_HIPAGENO:
5351 case DT_MIPS_DELTA_CLASS_NO:
5352 case DT_MIPS_DELTA_INSTANCE_NO:
5353 case DT_MIPS_DELTA_RELOC_NO:
5354 case DT_MIPS_DELTA_SYM_NO:
5355 case DT_MIPS_DELTA_CLASSSYM_NO:
5356 case DT_MIPS_COMPACT_SIZE:
5357 printf ("%ld\n", (long) entry->d_un.d_ptr);
5358 break;
103f02d3
UD
5359
5360 default:
5361 printf ("%#lx\n", (long) entry->d_un.d_ptr);
5362 }
5363}
5364
5365
5366static void
b2d38a17 5367dynamic_section_parisc_val (Elf_Internal_Dyn *entry)
103f02d3
UD
5368{
5369 switch (entry->d_tag)
5370 {
5371 case DT_HP_DLD_FLAGS:
5372 {
5373 static struct
5374 {
5375 long int bit;
b34976b6 5376 const char *str;
5e220199
NC
5377 }
5378 flags[] =
5379 {
5380 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
5381 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
5382 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
5383 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
5384 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
5385 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
5386 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
5387 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
5388 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
5389 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
5390 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" }
5391 };
103f02d3 5392 int first = 1;
5e220199 5393 size_t cnt;
f7a99963 5394 bfd_vma val = entry->d_un.d_val;
103f02d3
UD
5395
5396 for (cnt = 0; cnt < sizeof (flags) / sizeof (flags[0]); ++cnt)
5397 if (val & flags[cnt].bit)
30800947
NC
5398 {
5399 if (! first)
5400 putchar (' ');
5401 fputs (flags[cnt].str, stdout);
5402 first = 0;
5403 val ^= flags[cnt].bit;
5404 }
76da6bbe 5405
103f02d3 5406 if (val != 0 || first)
f7a99963
NC
5407 {
5408 if (! first)
5409 putchar (' ');
5410 print_vma (val, HEX);
5411 }
103f02d3
UD
5412 }
5413 break;
76da6bbe 5414
252b5132 5415 default:
f7a99963
NC
5416 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5417 break;
252b5132 5418 }
35b1837e 5419 putchar ('\n');
252b5132
RH
5420}
5421
ecc51f48 5422static void
b2d38a17 5423dynamic_section_ia64_val (Elf_Internal_Dyn *entry)
ecc51f48
NC
5424{
5425 switch (entry->d_tag)
5426 {
0de14b54 5427 case DT_IA_64_PLT_RESERVE:
bdf4d63a 5428 /* First 3 slots reserved. */
ecc51f48
NC
5429 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5430 printf (" -- ");
5431 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
5432 break;
5433
5434 default:
5435 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5436 break;
ecc51f48 5437 }
bdf4d63a 5438 putchar ('\n');
ecc51f48
NC
5439}
5440
252b5132 5441static int
b2d38a17 5442get_32bit_dynamic_section (FILE *file)
252b5132 5443{
fb514b26 5444 Elf32_External_Dyn *edyn, *ext;
b34976b6 5445 Elf_Internal_Dyn *entry;
103f02d3 5446
c256ffe7 5447 edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
b2d38a17 5448 _("dynamic section"));
a6e9f9df
AM
5449 if (!edyn)
5450 return 0;
103f02d3 5451
ba2685cc
AM
5452/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5453 might not have the luxury of section headers. Look for the DT_NULL
5454 terminator to determine the number of entries. */
5455 for (ext = edyn, dynamic_nent = 0;
5456 (char *) ext < (char *) edyn + dynamic_size;
5457 ext++)
5458 {
5459 dynamic_nent++;
5460 if (BYTE_GET (ext->d_tag) == DT_NULL)
5461 break;
5462 }
252b5132 5463
c256ffe7 5464 dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
b2d38a17 5465 if (dynamic_section == NULL)
252b5132 5466 {
9ea033b2
NC
5467 error (_("Out of memory\n"));
5468 free (edyn);
5469 return 0;
5470 }
252b5132 5471
fb514b26 5472 for (ext = edyn, entry = dynamic_section;
ba2685cc 5473 entry < dynamic_section + dynamic_nent;
fb514b26 5474 ext++, entry++)
9ea033b2 5475 {
fb514b26
AM
5476 entry->d_tag = BYTE_GET (ext->d_tag);
5477 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
5478 }
5479
9ea033b2
NC
5480 free (edyn);
5481
5482 return 1;
5483}
5484
5485static int
b2d38a17 5486get_64bit_dynamic_section (FILE *file)
9ea033b2 5487{
fb514b26 5488 Elf64_External_Dyn *edyn, *ext;
b34976b6 5489 Elf_Internal_Dyn *entry;
103f02d3 5490
c256ffe7 5491 edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
b2d38a17 5492 _("dynamic section"));
a6e9f9df
AM
5493 if (!edyn)
5494 return 0;
103f02d3 5495
ba2685cc
AM
5496/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5497 might not have the luxury of section headers. Look for the DT_NULL
5498 terminator to determine the number of entries. */
5499 for (ext = edyn, dynamic_nent = 0;
5500 (char *) ext < (char *) edyn + dynamic_size;
5501 ext++)
5502 {
5503 dynamic_nent++;
66543521 5504 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
5505 break;
5506 }
252b5132 5507
c256ffe7 5508 dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
b2d38a17 5509 if (dynamic_section == NULL)
252b5132
RH
5510 {
5511 error (_("Out of memory\n"));
5512 free (edyn);
5513 return 0;
5514 }
5515
fb514b26 5516 for (ext = edyn, entry = dynamic_section;
ba2685cc 5517 entry < dynamic_section + dynamic_nent;
fb514b26 5518 ext++, entry++)
252b5132 5519 {
66543521
AM
5520 entry->d_tag = BYTE_GET (ext->d_tag);
5521 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
5522 }
5523
5524 free (edyn);
5525
9ea033b2
NC
5526 return 1;
5527}
5528
e9e44622
JJ
5529static void
5530print_dynamic_flags (bfd_vma flags)
d1133906 5531{
e9e44622 5532 int first = 1;
13ae64f3 5533
d1133906
NC
5534 while (flags)
5535 {
5536 bfd_vma flag;
5537
5538 flag = flags & - flags;
5539 flags &= ~ flag;
5540
e9e44622
JJ
5541 if (first)
5542 first = 0;
5543 else
5544 putc (' ', stdout);
13ae64f3 5545
d1133906
NC
5546 switch (flag)
5547 {
e9e44622
JJ
5548 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
5549 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
5550 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
5551 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
5552 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
5553 default: fputs ("unknown", stdout); break;
d1133906
NC
5554 }
5555 }
e9e44622 5556 puts ("");
d1133906
NC
5557}
5558
b2d38a17
NC
5559/* Parse and display the contents of the dynamic section. */
5560
9ea033b2 5561static int
b2d38a17 5562process_dynamic_section (FILE *file)
9ea033b2 5563{
b34976b6 5564 Elf_Internal_Dyn *entry;
9ea033b2
NC
5565
5566 if (dynamic_size == 0)
5567 {
5568 if (do_dynamic)
b2d38a17 5569 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
5570
5571 return 1;
5572 }
5573
5574 if (is_32bit_elf)
5575 {
b2d38a17 5576 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
5577 return 0;
5578 }
b2d38a17 5579 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
5580 return 0;
5581
252b5132
RH
5582 /* Find the appropriate symbol table. */
5583 if (dynamic_symbols == NULL)
5584 {
86dba8ee
AM
5585 for (entry = dynamic_section;
5586 entry < dynamic_section + dynamic_nent;
5587 ++entry)
252b5132 5588 {
c8286bd1 5589 Elf_Internal_Shdr section;
252b5132
RH
5590
5591 if (entry->d_tag != DT_SYMTAB)
5592 continue;
5593
5594 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
5595
5596 /* Since we do not know how big the symbol table is,
5597 we default to reading in the entire file (!) and
5598 processing that. This is overkill, I know, but it
e3c8793a 5599 should work. */
d93f0186 5600 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 5601
fb52b2f4
NC
5602 if (archive_file_offset != 0)
5603 section.sh_size = archive_file_size - section.sh_offset;
5604 else
5605 {
5606 if (fseek (file, 0, SEEK_END))
5607 error (_("Unable to seek to end of file!"));
5608
5609 section.sh_size = ftell (file) - section.sh_offset;
5610 }
252b5132 5611
9ea033b2 5612 if (is_32bit_elf)
9ad5cbcf 5613 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 5614 else
9ad5cbcf 5615 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 5616
9ad5cbcf 5617 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 5618 if (num_dynamic_syms < 1)
252b5132
RH
5619 {
5620 error (_("Unable to determine the number of symbols to load\n"));
5621 continue;
5622 }
5623
9ad5cbcf 5624 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
5625 }
5626 }
5627
5628 /* Similarly find a string table. */
5629 if (dynamic_strings == NULL)
5630 {
86dba8ee
AM
5631 for (entry = dynamic_section;
5632 entry < dynamic_section + dynamic_nent;
5633 ++entry)
252b5132
RH
5634 {
5635 unsigned long offset;
b34976b6 5636 long str_tab_len;
252b5132
RH
5637
5638 if (entry->d_tag != DT_STRTAB)
5639 continue;
5640
5641 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
5642
5643 /* Since we do not know how big the string table is,
5644 we default to reading in the entire file (!) and
5645 processing that. This is overkill, I know, but it
e3c8793a 5646 should work. */
252b5132 5647
d93f0186 5648 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
5649
5650 if (archive_file_offset != 0)
5651 str_tab_len = archive_file_size - offset;
5652 else
5653 {
5654 if (fseek (file, 0, SEEK_END))
5655 error (_("Unable to seek to end of file\n"));
5656 str_tab_len = ftell (file) - offset;
5657 }
252b5132
RH
5658
5659 if (str_tab_len < 1)
5660 {
5661 error
5662 (_("Unable to determine the length of the dynamic string table\n"));
5663 continue;
5664 }
5665
c256ffe7 5666 dynamic_strings = get_data (NULL, file, offset, 1, str_tab_len,
d3ba0551 5667 _("dynamic string table"));
d79b3d50 5668 dynamic_strings_length = str_tab_len;
252b5132
RH
5669 break;
5670 }
5671 }
5672
5673 /* And find the syminfo section if available. */
5674 if (dynamic_syminfo == NULL)
5675 {
3e8bba36 5676 unsigned long syminsz = 0;
252b5132 5677
86dba8ee
AM
5678 for (entry = dynamic_section;
5679 entry < dynamic_section + dynamic_nent;
5680 ++entry)
252b5132
RH
5681 {
5682 if (entry->d_tag == DT_SYMINENT)
5683 {
5684 /* Note: these braces are necessary to avoid a syntax
5685 error from the SunOS4 C compiler. */
5686 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
5687 }
5688 else if (entry->d_tag == DT_SYMINSZ)
5689 syminsz = entry->d_un.d_val;
5690 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
5691 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
5692 syminsz);
252b5132
RH
5693 }
5694
5695 if (dynamic_syminfo_offset != 0 && syminsz != 0)
5696 {
86dba8ee 5697 Elf_External_Syminfo *extsyminfo, *extsym;
b34976b6 5698 Elf_Internal_Syminfo *syminfo;
252b5132
RH
5699
5700 /* There is a syminfo section. Read the data. */
c256ffe7
JJ
5701 extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, 1,
5702 syminsz, _("symbol information"));
a6e9f9df
AM
5703 if (!extsyminfo)
5704 return 0;
252b5132 5705
d3ba0551 5706 dynamic_syminfo = malloc (syminsz);
252b5132
RH
5707 if (dynamic_syminfo == NULL)
5708 {
5709 error (_("Out of memory\n"));
5710 return 0;
5711 }
5712
5713 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
5714 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
5715 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
5716 ++syminfo, ++extsym)
252b5132 5717 {
86dba8ee
AM
5718 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
5719 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
5720 }
5721
5722 free (extsyminfo);
5723 }
5724 }
5725
5726 if (do_dynamic && dynamic_addr)
86dba8ee
AM
5727 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
5728 dynamic_addr, dynamic_nent);
252b5132
RH
5729 if (do_dynamic)
5730 printf (_(" Tag Type Name/Value\n"));
5731
86dba8ee
AM
5732 for (entry = dynamic_section;
5733 entry < dynamic_section + dynamic_nent;
5734 entry++)
252b5132
RH
5735 {
5736 if (do_dynamic)
f7a99963 5737 {
b34976b6 5738 const char *dtype;
e699b9ff 5739
f7a99963
NC
5740 putchar (' ');
5741 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
5742 dtype = get_dynamic_type (entry->d_tag);
5743 printf (" (%s)%*s", dtype,
5744 ((is_32bit_elf ? 27 : 19)
5745 - (int) strlen (dtype)),
f7a99963
NC
5746 " ");
5747 }
252b5132
RH
5748
5749 switch (entry->d_tag)
5750 {
d1133906
NC
5751 case DT_FLAGS:
5752 if (do_dynamic)
e9e44622 5753 print_dynamic_flags (entry->d_un.d_val);
d1133906 5754 break;
76da6bbe 5755
252b5132
RH
5756 case DT_AUXILIARY:
5757 case DT_FILTER:
019148e4
L
5758 case DT_CONFIG:
5759 case DT_DEPAUDIT:
5760 case DT_AUDIT:
252b5132
RH
5761 if (do_dynamic)
5762 {
019148e4 5763 switch (entry->d_tag)
b34976b6 5764 {
019148e4
L
5765 case DT_AUXILIARY:
5766 printf (_("Auxiliary library"));
5767 break;
5768
5769 case DT_FILTER:
5770 printf (_("Filter library"));
5771 break;
5772
b34976b6 5773 case DT_CONFIG:
019148e4
L
5774 printf (_("Configuration file"));
5775 break;
5776
5777 case DT_DEPAUDIT:
5778 printf (_("Dependency audit library"));
5779 break;
5780
5781 case DT_AUDIT:
5782 printf (_("Audit library"));
5783 break;
5784 }
252b5132 5785
d79b3d50
NC
5786 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
5787 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 5788 else
f7a99963
NC
5789 {
5790 printf (": ");
5791 print_vma (entry->d_un.d_val, PREFIX_HEX);
5792 putchar ('\n');
5793 }
252b5132
RH
5794 }
5795 break;
5796
dcefbbbd 5797 case DT_FEATURE:
252b5132
RH
5798 if (do_dynamic)
5799 {
5800 printf (_("Flags:"));
86f55779 5801
252b5132
RH
5802 if (entry->d_un.d_val == 0)
5803 printf (_(" None\n"));
5804 else
5805 {
5806 unsigned long int val = entry->d_un.d_val;
86f55779 5807
252b5132
RH
5808 if (val & DTF_1_PARINIT)
5809 {
5810 printf (" PARINIT");
5811 val ^= DTF_1_PARINIT;
5812 }
dcefbbbd
L
5813 if (val & DTF_1_CONFEXP)
5814 {
5815 printf (" CONFEXP");
5816 val ^= DTF_1_CONFEXP;
5817 }
252b5132
RH
5818 if (val != 0)
5819 printf (" %lx", val);
5820 puts ("");
5821 }
5822 }
5823 break;
5824
5825 case DT_POSFLAG_1:
5826 if (do_dynamic)
5827 {
5828 printf (_("Flags:"));
86f55779 5829
252b5132
RH
5830 if (entry->d_un.d_val == 0)
5831 printf (_(" None\n"));
5832 else
5833 {
5834 unsigned long int val = entry->d_un.d_val;
86f55779 5835
252b5132
RH
5836 if (val & DF_P1_LAZYLOAD)
5837 {
5838 printf (" LAZYLOAD");
5839 val ^= DF_P1_LAZYLOAD;
5840 }
5841 if (val & DF_P1_GROUPPERM)
5842 {
5843 printf (" GROUPPERM");
5844 val ^= DF_P1_GROUPPERM;
5845 }
5846 if (val != 0)
5847 printf (" %lx", val);
5848 puts ("");
5849 }
5850 }
5851 break;
5852
5853 case DT_FLAGS_1:
5854 if (do_dynamic)
5855 {
5856 printf (_("Flags:"));
5857 if (entry->d_un.d_val == 0)
5858 printf (_(" None\n"));
5859 else
5860 {
5861 unsigned long int val = entry->d_un.d_val;
86f55779 5862
252b5132
RH
5863 if (val & DF_1_NOW)
5864 {
5865 printf (" NOW");
5866 val ^= DF_1_NOW;
5867 }
5868 if (val & DF_1_GLOBAL)
5869 {
5870 printf (" GLOBAL");
5871 val ^= DF_1_GLOBAL;
5872 }
5873 if (val & DF_1_GROUP)
5874 {
5875 printf (" GROUP");
5876 val ^= DF_1_GROUP;
5877 }
5878 if (val & DF_1_NODELETE)
5879 {
5880 printf (" NODELETE");
5881 val ^= DF_1_NODELETE;
5882 }
5883 if (val & DF_1_LOADFLTR)
5884 {
5885 printf (" LOADFLTR");
5886 val ^= DF_1_LOADFLTR;
5887 }
5888 if (val & DF_1_INITFIRST)
5889 {
5890 printf (" INITFIRST");
5891 val ^= DF_1_INITFIRST;
5892 }
5893 if (val & DF_1_NOOPEN)
5894 {
5895 printf (" NOOPEN");
5896 val ^= DF_1_NOOPEN;
5897 }
5898 if (val & DF_1_ORIGIN)
5899 {
5900 printf (" ORIGIN");
5901 val ^= DF_1_ORIGIN;
5902 }
5903 if (val & DF_1_DIRECT)
5904 {
5905 printf (" DIRECT");
5906 val ^= DF_1_DIRECT;
5907 }
5908 if (val & DF_1_TRANS)
5909 {
5910 printf (" TRANS");
5911 val ^= DF_1_TRANS;
5912 }
5913 if (val & DF_1_INTERPOSE)
5914 {
5915 printf (" INTERPOSE");
5916 val ^= DF_1_INTERPOSE;
5917 }
f7db6139 5918 if (val & DF_1_NODEFLIB)
dcefbbbd 5919 {
f7db6139
L
5920 printf (" NODEFLIB");
5921 val ^= DF_1_NODEFLIB;
dcefbbbd
L
5922 }
5923 if (val & DF_1_NODUMP)
5924 {
5925 printf (" NODUMP");
5926 val ^= DF_1_NODUMP;
5927 }
5928 if (val & DF_1_CONLFAT)
5929 {
5930 printf (" CONLFAT");
5931 val ^= DF_1_CONLFAT;
5932 }
252b5132
RH
5933 if (val != 0)
5934 printf (" %lx", val);
5935 puts ("");
5936 }
5937 }
5938 break;
5939
5940 case DT_PLTREL:
566b0d53 5941 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
5942 if (do_dynamic)
5943 puts (get_dynamic_type (entry->d_un.d_val));
5944 break;
5945
5946 case DT_NULL :
5947 case DT_NEEDED :
5948 case DT_PLTGOT :
5949 case DT_HASH :
5950 case DT_STRTAB :
5951 case DT_SYMTAB :
5952 case DT_RELA :
5953 case DT_INIT :
5954 case DT_FINI :
5955 case DT_SONAME :
5956 case DT_RPATH :
5957 case DT_SYMBOLIC:
5958 case DT_REL :
5959 case DT_DEBUG :
5960 case DT_TEXTREL :
5961 case DT_JMPREL :
019148e4 5962 case DT_RUNPATH :
252b5132
RH
5963 dynamic_info[entry->d_tag] = entry->d_un.d_val;
5964
5965 if (do_dynamic)
5966 {
b34976b6 5967 char *name;
252b5132 5968
d79b3d50
NC
5969 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
5970 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 5971 else
d79b3d50 5972 name = NULL;
252b5132
RH
5973
5974 if (name)
5975 {
5976 switch (entry->d_tag)
5977 {
5978 case DT_NEEDED:
5979 printf (_("Shared library: [%s]"), name);
5980
18bd398b 5981 if (streq (name, program_interpreter))
f7a99963 5982 printf (_(" program interpreter"));
252b5132
RH
5983 break;
5984
5985 case DT_SONAME:
f7a99963 5986 printf (_("Library soname: [%s]"), name);
252b5132
RH
5987 break;
5988
5989 case DT_RPATH:
f7a99963 5990 printf (_("Library rpath: [%s]"), name);
252b5132
RH
5991 break;
5992
019148e4
L
5993 case DT_RUNPATH:
5994 printf (_("Library runpath: [%s]"), name);
5995 break;
5996
252b5132 5997 default:
f7a99963
NC
5998 print_vma (entry->d_un.d_val, PREFIX_HEX);
5999 break;
252b5132
RH
6000 }
6001 }
6002 else
f7a99963
NC
6003 print_vma (entry->d_un.d_val, PREFIX_HEX);
6004
6005 putchar ('\n');
252b5132
RH
6006 }
6007 break;
6008
6009 case DT_PLTRELSZ:
6010 case DT_RELASZ :
6011 case DT_STRSZ :
6012 case DT_RELSZ :
6013 case DT_RELAENT :
6014 case DT_SYMENT :
6015 case DT_RELENT :
566b0d53 6016 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
6017 case DT_PLTPADSZ:
6018 case DT_MOVEENT :
6019 case DT_MOVESZ :
6020 case DT_INIT_ARRAYSZ:
6021 case DT_FINI_ARRAYSZ:
047b2264
JJ
6022 case DT_GNU_CONFLICTSZ:
6023 case DT_GNU_LIBLISTSZ:
252b5132 6024 if (do_dynamic)
f7a99963
NC
6025 {
6026 print_vma (entry->d_un.d_val, UNSIGNED);
6027 printf (" (bytes)\n");
6028 }
252b5132
RH
6029 break;
6030
6031 case DT_VERDEFNUM:
6032 case DT_VERNEEDNUM:
6033 case DT_RELACOUNT:
6034 case DT_RELCOUNT:
6035 if (do_dynamic)
f7a99963
NC
6036 {
6037 print_vma (entry->d_un.d_val, UNSIGNED);
6038 putchar ('\n');
6039 }
252b5132
RH
6040 break;
6041
6042 case DT_SYMINSZ:
6043 case DT_SYMINENT:
6044 case DT_SYMINFO:
6045 case DT_USED:
6046 case DT_INIT_ARRAY:
6047 case DT_FINI_ARRAY:
6048 if (do_dynamic)
6049 {
d79b3d50
NC
6050 if (entry->d_tag == DT_USED
6051 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 6052 {
d79b3d50 6053 char *name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 6054
b34976b6 6055 if (*name)
252b5132
RH
6056 {
6057 printf (_("Not needed object: [%s]\n"), name);
6058 break;
6059 }
6060 }
103f02d3 6061
f7a99963
NC
6062 print_vma (entry->d_un.d_val, PREFIX_HEX);
6063 putchar ('\n');
252b5132
RH
6064 }
6065 break;
6066
6067 case DT_BIND_NOW:
6068 /* The value of this entry is ignored. */
35b1837e
AM
6069 if (do_dynamic)
6070 putchar ('\n');
252b5132 6071 break;
103f02d3 6072
047b2264
JJ
6073 case DT_GNU_PRELINKED:
6074 if (do_dynamic)
6075 {
b34976b6 6076 struct tm *tmp;
047b2264
JJ
6077 time_t time = entry->d_un.d_val;
6078
6079 tmp = gmtime (&time);
6080 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
6081 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
6082 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
6083
6084 }
6085 break;
6086
252b5132
RH
6087 default:
6088 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 6089 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
6090 entry->d_un.d_val;
6091
6092 if (do_dynamic)
6093 {
6094 switch (elf_header.e_machine)
6095 {
6096 case EM_MIPS:
4fe85591 6097 case EM_MIPS_RS3_LE:
b2d38a17 6098 dynamic_section_mips_val (entry);
252b5132 6099 break;
103f02d3 6100 case EM_PARISC:
b2d38a17 6101 dynamic_section_parisc_val (entry);
103f02d3 6102 break;
ecc51f48 6103 case EM_IA_64:
b2d38a17 6104 dynamic_section_ia64_val (entry);
ecc51f48 6105 break;
252b5132 6106 default:
f7a99963
NC
6107 print_vma (entry->d_un.d_val, PREFIX_HEX);
6108 putchar ('\n');
252b5132
RH
6109 }
6110 }
6111 break;
6112 }
6113 }
6114
6115 return 1;
6116}
6117
6118static char *
d3ba0551 6119get_ver_flags (unsigned int flags)
252b5132 6120{
b34976b6 6121 static char buff[32];
252b5132
RH
6122
6123 buff[0] = 0;
6124
6125 if (flags == 0)
6126 return _("none");
6127
6128 if (flags & VER_FLG_BASE)
6129 strcat (buff, "BASE ");
6130
6131 if (flags & VER_FLG_WEAK)
6132 {
6133 if (flags & VER_FLG_BASE)
6134 strcat (buff, "| ");
6135
6136 strcat (buff, "WEAK ");
6137 }
6138
6139 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
6140 strcat (buff, "| <unknown>");
6141
6142 return buff;
6143}
6144
6145/* Display the contents of the version sections. */
6146static int
d3ba0551 6147process_version_sections (FILE *file)
252b5132 6148{
b34976b6
AM
6149 Elf_Internal_Shdr *section;
6150 unsigned i;
6151 int found = 0;
252b5132
RH
6152
6153 if (! do_version)
6154 return 1;
6155
6156 for (i = 0, section = section_headers;
6157 i < elf_header.e_shnum;
b34976b6 6158 i++, section++)
252b5132
RH
6159 {
6160 switch (section->sh_type)
6161 {
6162 case SHT_GNU_verdef:
6163 {
b34976b6
AM
6164 Elf_External_Verdef *edefs;
6165 unsigned int idx;
6166 unsigned int cnt;
252b5132
RH
6167
6168 found = 1;
6169
6170 printf
6171 (_("\nVersion definition section '%s' contains %ld entries:\n"),
6172 SECTION_NAME (section), section->sh_info);
6173
6174 printf (_(" Addr: 0x"));
6175 printf_vma (section->sh_addr);
6176 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 6177 (unsigned long) section->sh_offset, section->sh_link,
c256ffe7
JJ
6178 SECTION_HEADER_INDEX (section->sh_link)
6179 < elf_header.e_shnum
6180 ? SECTION_NAME (SECTION_HEADER (section->sh_link))
6181 : "<corrupt>");
252b5132 6182
c256ffe7
JJ
6183 edefs = get_data (NULL, file, section->sh_offset, 1,
6184 section->sh_size,
d3ba0551 6185 _("version definition section"));
a6e9f9df
AM
6186 if (!edefs)
6187 break;
252b5132 6188
b34976b6 6189 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 6190 {
b34976b6
AM
6191 char *vstart;
6192 Elf_External_Verdef *edef;
6193 Elf_Internal_Verdef ent;
6194 Elf_External_Verdaux *eaux;
6195 Elf_Internal_Verdaux aux;
6196 int j;
6197 int isum;
103f02d3 6198
252b5132
RH
6199 vstart = ((char *) edefs) + idx;
6200
6201 edef = (Elf_External_Verdef *) vstart;
6202
6203 ent.vd_version = BYTE_GET (edef->vd_version);
6204 ent.vd_flags = BYTE_GET (edef->vd_flags);
6205 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
6206 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
6207 ent.vd_hash = BYTE_GET (edef->vd_hash);
6208 ent.vd_aux = BYTE_GET (edef->vd_aux);
6209 ent.vd_next = BYTE_GET (edef->vd_next);
6210
6211 printf (_(" %#06x: Rev: %d Flags: %s"),
6212 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
6213
6214 printf (_(" Index: %d Cnt: %d "),
6215 ent.vd_ndx, ent.vd_cnt);
6216
6217 vstart += ent.vd_aux;
6218
6219 eaux = (Elf_External_Verdaux *) vstart;
6220
6221 aux.vda_name = BYTE_GET (eaux->vda_name);
6222 aux.vda_next = BYTE_GET (eaux->vda_next);
6223
d79b3d50
NC
6224 if (VALID_DYNAMIC_NAME (aux.vda_name))
6225 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
6226 else
6227 printf (_("Name index: %ld\n"), aux.vda_name);
6228
6229 isum = idx + ent.vd_aux;
6230
b34976b6 6231 for (j = 1; j < ent.vd_cnt; j++)
252b5132
RH
6232 {
6233 isum += aux.vda_next;
6234 vstart += aux.vda_next;
6235
6236 eaux = (Elf_External_Verdaux *) vstart;
6237
6238 aux.vda_name = BYTE_GET (eaux->vda_name);
6239 aux.vda_next = BYTE_GET (eaux->vda_next);
6240
d79b3d50 6241 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 6242 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 6243 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
6244 else
6245 printf (_(" %#06x: Parent %d, name index: %ld\n"),
6246 isum, j, aux.vda_name);
6247 }
6248
6249 idx += ent.vd_next;
6250 }
6251
6252 free (edefs);
6253 }
6254 break;
103f02d3 6255
252b5132
RH
6256 case SHT_GNU_verneed:
6257 {
b34976b6
AM
6258 Elf_External_Verneed *eneed;
6259 unsigned int idx;
6260 unsigned int cnt;
252b5132
RH
6261
6262 found = 1;
6263
6264 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
6265 SECTION_NAME (section), section->sh_info);
6266
6267 printf (_(" Addr: 0x"));
6268 printf_vma (section->sh_addr);
6269 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
1b228002 6270 (unsigned long) section->sh_offset, section->sh_link,
c256ffe7
JJ
6271 SECTION_HEADER_INDEX (section->sh_link)
6272 < elf_header.e_shnum
6273 ? SECTION_NAME (SECTION_HEADER (section->sh_link))
6274 : "<corrupt>");
252b5132 6275
c256ffe7
JJ
6276 eneed = get_data (NULL, file, section->sh_offset, 1,
6277 section->sh_size,
d3ba0551 6278 _("version need section"));
a6e9f9df
AM
6279 if (!eneed)
6280 break;
252b5132
RH
6281
6282 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
6283 {
b34976b6
AM
6284 Elf_External_Verneed *entry;
6285 Elf_Internal_Verneed ent;
6286 int j;
6287 int isum;
6288 char *vstart;
252b5132
RH
6289
6290 vstart = ((char *) eneed) + idx;
6291
6292 entry = (Elf_External_Verneed *) vstart;
6293
6294 ent.vn_version = BYTE_GET (entry->vn_version);
6295 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
6296 ent.vn_file = BYTE_GET (entry->vn_file);
6297 ent.vn_aux = BYTE_GET (entry->vn_aux);
6298 ent.vn_next = BYTE_GET (entry->vn_next);
6299
6300 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
6301
d79b3d50
NC
6302 if (VALID_DYNAMIC_NAME (ent.vn_file))
6303 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
6304 else
6305 printf (_(" File: %lx"), ent.vn_file);
6306
6307 printf (_(" Cnt: %d\n"), ent.vn_cnt);
6308
6309 vstart += ent.vn_aux;
6310
6311 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
6312 {
b34976b6
AM
6313 Elf_External_Vernaux *eaux;
6314 Elf_Internal_Vernaux aux;
252b5132
RH
6315
6316 eaux = (Elf_External_Vernaux *) vstart;
6317
6318 aux.vna_hash = BYTE_GET (eaux->vna_hash);
6319 aux.vna_flags = BYTE_GET (eaux->vna_flags);
6320 aux.vna_other = BYTE_GET (eaux->vna_other);
6321 aux.vna_name = BYTE_GET (eaux->vna_name);
6322 aux.vna_next = BYTE_GET (eaux->vna_next);
6323
d79b3d50 6324 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 6325 printf (_(" %#06x: Name: %s"),
d79b3d50 6326 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 6327 else
ecc2063b 6328 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
6329 isum, aux.vna_name);
6330
6331 printf (_(" Flags: %s Version: %d\n"),
6332 get_ver_flags (aux.vna_flags), aux.vna_other);
6333
6334 isum += aux.vna_next;
6335 vstart += aux.vna_next;
6336 }
6337
6338 idx += ent.vn_next;
6339 }
103f02d3 6340
252b5132
RH
6341 free (eneed);
6342 }
6343 break;
6344
6345 case SHT_GNU_versym:
6346 {
b34976b6
AM
6347 Elf_Internal_Shdr *link_section;
6348 int total;
6349 int cnt;
6350 unsigned char *edata;
6351 unsigned short *data;
6352 char *strtab;
6353 Elf_Internal_Sym *symbols;
6354 Elf_Internal_Shdr *string_sec;
d3ba0551 6355 long off;
252b5132 6356
c256ffe7
JJ
6357 if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum)
6358 break;
6359
9ad5cbcf 6360 link_section = SECTION_HEADER (section->sh_link);
252b5132
RH
6361 total = section->sh_size / section->sh_entsize;
6362
c256ffe7
JJ
6363 if (SECTION_HEADER_INDEX (link_section->sh_link)
6364 >= elf_header.e_shnum)
6365 break;
6366
252b5132
RH
6367 found = 1;
6368
9ad5cbcf 6369 symbols = GET_ELF_SYMBOLS (file, link_section);
252b5132 6370
9ad5cbcf 6371 string_sec = SECTION_HEADER (link_section->sh_link);
252b5132 6372
c256ffe7 6373 strtab = get_data (NULL, file, string_sec->sh_offset, 1,
d3ba0551 6374 string_sec->sh_size, _("version string table"));
a6e9f9df
AM
6375 if (!strtab)
6376 break;
252b5132
RH
6377
6378 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
6379 SECTION_NAME (section), total);
6380
6381 printf (_(" Addr: "));
6382 printf_vma (section->sh_addr);
6383 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 6384 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
6385 SECTION_NAME (link_section));
6386
d3ba0551
AM
6387 off = offset_from_vma (file,
6388 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
6389 total * sizeof (short));
c256ffe7 6390 edata = get_data (NULL, file, off, total, sizeof (short),
d3ba0551 6391 _("version symbol data"));
a6e9f9df
AM
6392 if (!edata)
6393 {
6394 free (strtab);
6395 break;
6396 }
252b5132 6397
c256ffe7 6398 data = cmalloc (total, sizeof (short));
252b5132
RH
6399
6400 for (cnt = total; cnt --;)
b34976b6
AM
6401 data[cnt] = byte_get (edata + cnt * sizeof (short),
6402 sizeof (short));
252b5132
RH
6403
6404 free (edata);
6405
6406 for (cnt = 0; cnt < total; cnt += 4)
6407 {
6408 int j, nn;
00d93f34 6409 int check_def, check_need;
b34976b6 6410 char *name;
252b5132
RH
6411
6412 printf (" %03x:", cnt);
6413
6414 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 6415 switch (data[cnt + j])
252b5132
RH
6416 {
6417 case 0:
6418 fputs (_(" 0 (*local*) "), stdout);
6419 break;
6420
6421 case 1:
6422 fputs (_(" 1 (*global*) "), stdout);
6423 break;
6424
6425 default:
b34976b6
AM
6426 nn = printf ("%4x%c", data[cnt + j] & 0x7fff,
6427 data[cnt + j] & 0x8000 ? 'h' : ' ');
252b5132 6428
00d93f34
JJ
6429 check_def = 1;
6430 check_need = 1;
c256ffe7
JJ
6431 if (SECTION_HEADER_INDEX (symbols[cnt + j].st_shndx)
6432 >= elf_header.e_shnum
6433 || SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
6434 != SHT_NOBITS)
252b5132 6435 {
b34976b6 6436 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
6437 check_def = 0;
6438 else
6439 check_need = 0;
252b5132 6440 }
00d93f34
JJ
6441
6442 if (check_need
b34976b6 6443 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 6444 {
b34976b6
AM
6445 Elf_Internal_Verneed ivn;
6446 unsigned long offset;
252b5132 6447
d93f0186
NC
6448 offset = offset_from_vma
6449 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
6450 sizeof (Elf_External_Verneed));
252b5132 6451
b34976b6 6452 do
252b5132 6453 {
b34976b6
AM
6454 Elf_Internal_Vernaux ivna;
6455 Elf_External_Verneed evn;
6456 Elf_External_Vernaux evna;
6457 unsigned long a_off;
252b5132 6458
c256ffe7 6459 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 6460 _("version need"));
252b5132
RH
6461
6462 ivn.vn_aux = BYTE_GET (evn.vn_aux);
6463 ivn.vn_next = BYTE_GET (evn.vn_next);
6464
6465 a_off = offset + ivn.vn_aux;
6466
6467 do
6468 {
a6e9f9df 6469 get_data (&evna, file, a_off, sizeof (evna),
c256ffe7 6470 1, _("version need aux (2)"));
252b5132
RH
6471
6472 ivna.vna_next = BYTE_GET (evna.vna_next);
6473 ivna.vna_other = BYTE_GET (evna.vna_other);
6474
6475 a_off += ivna.vna_next;
6476 }
b34976b6 6477 while (ivna.vna_other != data[cnt + j]
252b5132
RH
6478 && ivna.vna_next != 0);
6479
b34976b6 6480 if (ivna.vna_other == data[cnt + j])
252b5132
RH
6481 {
6482 ivna.vna_name = BYTE_GET (evna.vna_name);
6483
16062207 6484 name = strtab + ivna.vna_name;
252b5132 6485 nn += printf ("(%s%-*s",
16062207
ILT
6486 name,
6487 12 - (int) strlen (name),
252b5132 6488 ")");
00d93f34 6489 check_def = 0;
252b5132
RH
6490 break;
6491 }
6492
6493 offset += ivn.vn_next;
6494 }
6495 while (ivn.vn_next);
6496 }
00d93f34 6497
b34976b6
AM
6498 if (check_def && data[cnt + j] != 0x8001
6499 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 6500 {
b34976b6
AM
6501 Elf_Internal_Verdef ivd;
6502 Elf_External_Verdef evd;
6503 unsigned long offset;
252b5132 6504
d93f0186
NC
6505 offset = offset_from_vma
6506 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
6507 sizeof evd);
252b5132
RH
6508
6509 do
6510 {
c256ffe7 6511 get_data (&evd, file, offset, sizeof (evd), 1,
a6e9f9df 6512 _("version def"));
252b5132
RH
6513
6514 ivd.vd_next = BYTE_GET (evd.vd_next);
6515 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
6516
6517 offset += ivd.vd_next;
6518 }
b34976b6 6519 while (ivd.vd_ndx != (data[cnt + j] & 0x7fff)
252b5132
RH
6520 && ivd.vd_next != 0);
6521
b34976b6 6522 if (ivd.vd_ndx == (data[cnt + j] & 0x7fff))
252b5132 6523 {
b34976b6
AM
6524 Elf_External_Verdaux evda;
6525 Elf_Internal_Verdaux ivda;
252b5132
RH
6526
6527 ivd.vd_aux = BYTE_GET (evd.vd_aux);
6528
a6e9f9df
AM
6529 get_data (&evda, file,
6530 offset - ivd.vd_next + ivd.vd_aux,
c256ffe7
JJ
6531 sizeof (evda), 1,
6532 _("version def aux"));
252b5132
RH
6533
6534 ivda.vda_name = BYTE_GET (evda.vda_name);
6535
16062207 6536 name = strtab + ivda.vda_name;
252b5132 6537 nn += printf ("(%s%-*s",
16062207
ILT
6538 name,
6539 12 - (int) strlen (name),
252b5132
RH
6540 ")");
6541 }
6542 }
6543
6544 if (nn < 18)
6545 printf ("%*c", 18 - nn, ' ');
6546 }
6547
6548 putchar ('\n');
6549 }
6550
6551 free (data);
6552 free (strtab);
6553 free (symbols);
6554 }
6555 break;
103f02d3 6556
252b5132
RH
6557 default:
6558 break;
6559 }
6560 }
6561
6562 if (! found)
6563 printf (_("\nNo version information found in this file.\n"));
6564
6565 return 1;
6566}
6567
d1133906 6568static const char *
d3ba0551 6569get_symbol_binding (unsigned int binding)
252b5132 6570{
b34976b6 6571 static char buff[32];
252b5132
RH
6572
6573 switch (binding)
6574 {
b34976b6
AM
6575 case STB_LOCAL: return "LOCAL";
6576 case STB_GLOBAL: return "GLOBAL";
6577 case STB_WEAK: return "WEAK";
252b5132
RH
6578 default:
6579 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
6580 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
6581 binding);
252b5132 6582 else if (binding >= STB_LOOS && binding <= STB_HIOS)
e9e44622 6583 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
252b5132 6584 else
e9e44622 6585 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
6586 return buff;
6587 }
6588}
6589
d1133906 6590static const char *
d3ba0551 6591get_symbol_type (unsigned int type)
252b5132 6592{
b34976b6 6593 static char buff[32];
252b5132
RH
6594
6595 switch (type)
6596 {
b34976b6
AM
6597 case STT_NOTYPE: return "NOTYPE";
6598 case STT_OBJECT: return "OBJECT";
6599 case STT_FUNC: return "FUNC";
6600 case STT_SECTION: return "SECTION";
6601 case STT_FILE: return "FILE";
6602 case STT_COMMON: return "COMMON";
6603 case STT_TLS: return "TLS";
252b5132
RH
6604 default:
6605 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
6606 {
6607 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
6608 return "THUMB_FUNC";
6609
351b4b40 6610 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
6611 return "REGISTER";
6612
6613 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
6614 return "PARISC_MILLI";
6615
e9e44622 6616 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 6617 }
252b5132 6618 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
6619 {
6620 if (elf_header.e_machine == EM_PARISC)
6621 {
6622 if (type == STT_HP_OPAQUE)
6623 return "HP_OPAQUE";
6624 if (type == STT_HP_STUB)
6625 return "HP_STUB";
6626 }
6627
e9e44622 6628 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 6629 }
252b5132 6630 else
e9e44622 6631 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
6632 return buff;
6633 }
6634}
6635
d1133906 6636static const char *
d3ba0551 6637get_symbol_visibility (unsigned int visibility)
d1133906
NC
6638{
6639 switch (visibility)
6640 {
b34976b6
AM
6641 case STV_DEFAULT: return "DEFAULT";
6642 case STV_INTERNAL: return "INTERNAL";
6643 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
6644 case STV_PROTECTED: return "PROTECTED";
6645 default: abort ();
6646 }
6647}
6648
6649static const char *
d3ba0551 6650get_symbol_index_type (unsigned int type)
252b5132 6651{
b34976b6 6652 static char buff[32];
5cf1065c 6653
252b5132
RH
6654 switch (type)
6655 {
b34976b6
AM
6656 case SHN_UNDEF: return "UND";
6657 case SHN_ABS: return "ABS";
6658 case SHN_COMMON: return "COM";
252b5132 6659 default:
9ce701e2
L
6660 if (type == SHN_IA_64_ANSI_COMMON
6661 && elf_header.e_machine == EM_IA_64
6662 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
6663 return "ANSI_COM";
6664 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
5cf1065c 6665 sprintf (buff, "PRC[0x%04x]", type);
252b5132 6666 else if (type >= SHN_LOOS && type <= SHN_HIOS)
5cf1065c 6667 sprintf (buff, "OS [0x%04x]", type);
9ad5cbcf 6668 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
5cf1065c 6669 sprintf (buff, "RSV[0x%04x]", type);
252b5132 6670 else
232e7cb8 6671 sprintf (buff, "%3d", type);
5cf1065c 6672 break;
252b5132 6673 }
5cf1065c
NC
6674
6675 return buff;
252b5132
RH
6676}
6677
66543521
AM
6678static bfd_vma *
6679get_dynamic_data (FILE *file, unsigned int number, unsigned int ent_size)
252b5132 6680{
b34976b6 6681 unsigned char *e_data;
66543521 6682 bfd_vma *i_data;
252b5132 6683
c256ffe7 6684 e_data = cmalloc (number, ent_size);
252b5132
RH
6685
6686 if (e_data == NULL)
6687 {
6688 error (_("Out of memory\n"));
6689 return NULL;
6690 }
6691
66543521 6692 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
6693 {
6694 error (_("Unable to read in dynamic data\n"));
6695 return NULL;
6696 }
6697
c256ffe7 6698 i_data = cmalloc (number, sizeof (*i_data));
252b5132
RH
6699
6700 if (i_data == NULL)
6701 {
6702 error (_("Out of memory\n"));
6703 free (e_data);
6704 return NULL;
6705 }
6706
6707 while (number--)
66543521 6708 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
6709
6710 free (e_data);
6711
6712 return i_data;
6713}
6714
e3c8793a 6715/* Dump the symbol table. */
252b5132 6716static int
d3ba0551 6717process_symbol_table (FILE *file)
252b5132 6718{
b34976b6 6719 Elf_Internal_Shdr *section;
66543521
AM
6720 bfd_vma nbuckets = 0;
6721 bfd_vma nchains = 0;
6722 bfd_vma *buckets = NULL;
6723 bfd_vma *chains = NULL;
252b5132
RH
6724
6725 if (! do_syms && !do_histogram)
6726 return 1;
6727
6728 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
6729 || do_histogram))
6730 {
66543521
AM
6731 unsigned char nb[8];
6732 unsigned char nc[8];
6733 int hash_ent_size = 4;
6734
6735 if ((elf_header.e_machine == EM_ALPHA
6736 || elf_header.e_machine == EM_S390
6737 || elf_header.e_machine == EM_S390_OLD)
6738 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
6739 hash_ent_size = 8;
6740
fb52b2f4
NC
6741 if (fseek (file,
6742 (archive_file_offset
6743 + offset_from_vma (file, dynamic_info[DT_HASH],
6744 sizeof nb + sizeof nc)),
d93f0186 6745 SEEK_SET))
252b5132
RH
6746 {
6747 error (_("Unable to seek to start of dynamic information"));
6748 return 0;
6749 }
6750
66543521 6751 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
6752 {
6753 error (_("Failed to read in number of buckets\n"));
6754 return 0;
6755 }
6756
66543521 6757 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
6758 {
6759 error (_("Failed to read in number of chains\n"));
6760 return 0;
6761 }
6762
66543521
AM
6763 nbuckets = byte_get (nb, hash_ent_size);
6764 nchains = byte_get (nc, hash_ent_size);
252b5132 6765
66543521
AM
6766 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
6767 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132
RH
6768
6769 if (buckets == NULL || chains == NULL)
6770 return 0;
6771 }
6772
6773 if (do_syms
6774 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
6775 {
66543521
AM
6776 unsigned long hn;
6777 bfd_vma si;
252b5132
RH
6778
6779 printf (_("\nSymbol table for image:\n"));
f7a99963 6780 if (is_32bit_elf)
ca47b30c 6781 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 6782 else
ca47b30c 6783 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
252b5132
RH
6784
6785 for (hn = 0; hn < nbuckets; hn++)
6786 {
b34976b6 6787 if (! buckets[hn])
252b5132
RH
6788 continue;
6789
b34976b6 6790 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
252b5132 6791 {
b34976b6 6792 Elf_Internal_Sym *psym;
66543521 6793 int n;
252b5132
RH
6794
6795 psym = dynamic_symbols + si;
6796
66543521
AM
6797 n = print_vma (si, DEC_5);
6798 if (n < 5)
6799 fputs (" " + n, stdout);
6800 printf (" %3lu: ", hn);
f7a99963 6801 print_vma (psym->st_value, LONG_HEX);
66543521 6802 putchar (' ');
d1133906 6803 print_vma (psym->st_size, DEC_5);
76da6bbe 6804
d1133906
NC
6805 printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
6806 printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
6807 printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126 6808 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
d79b3d50
NC
6809 if (VALID_DYNAMIC_NAME (psym->st_name))
6810 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
6811 else
6812 printf (" <corrupt: %14ld>", psym->st_name);
31104126 6813 putchar ('\n');
252b5132
RH
6814 }
6815 }
6816 }
6817 else if (do_syms && !do_using_dynamic)
6818 {
b34976b6 6819 unsigned int i;
252b5132
RH
6820
6821 for (i = 0, section = section_headers;
6822 i < elf_header.e_shnum;
6823 i++, section++)
6824 {
b34976b6 6825 unsigned int si;
c256ffe7
JJ
6826 char *strtab = NULL;
6827 unsigned long int strtab_size = 0;
b34976b6
AM
6828 Elf_Internal_Sym *symtab;
6829 Elf_Internal_Sym *psym;
252b5132
RH
6830
6831
6832 if ( section->sh_type != SHT_SYMTAB
6833 && section->sh_type != SHT_DYNSYM)
6834 continue;
6835
6836 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
6837 SECTION_NAME (section),
6838 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 6839 if (is_32bit_elf)
ca47b30c 6840 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 6841 else
ca47b30c 6842 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 6843
9ad5cbcf 6844 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
6845 if (symtab == NULL)
6846 continue;
6847
6848 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
6849 {
6850 strtab = string_table;
6851 strtab_size = string_table_length;
6852 }
6853 else if (SECTION_HEADER_INDEX (section->sh_link) < elf_header.e_shnum)
252b5132 6854 {
b34976b6 6855 Elf_Internal_Shdr *string_sec;
252b5132 6856
9ad5cbcf 6857 string_sec = SECTION_HEADER (section->sh_link);
252b5132 6858
d3ba0551 6859 strtab = get_data (NULL, file, string_sec->sh_offset,
c256ffe7
JJ
6860 1, string_sec->sh_size, _("string table"));
6861 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
6862 }
6863
6864 for (si = 0, psym = symtab;
6865 si < section->sh_size / section->sh_entsize;
b34976b6 6866 si++, psym++)
252b5132 6867 {
5e220199 6868 printf ("%6d: ", si);
f7a99963
NC
6869 print_vma (psym->st_value, LONG_HEX);
6870 putchar (' ');
6871 print_vma (psym->st_size, DEC_5);
d1133906
NC
6872 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
6873 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
6874 printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126 6875 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7
JJ
6876 print_symbol (25, psym->st_name < strtab_size
6877 ? strtab + psym->st_name : "<corrupt>");
252b5132
RH
6878
6879 if (section->sh_type == SHT_DYNSYM &&
b34976b6 6880 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 6881 {
b34976b6
AM
6882 unsigned char data[2];
6883 unsigned short vers_data;
6884 unsigned long offset;
6885 int is_nobits;
6886 int check_def;
252b5132 6887
d93f0186
NC
6888 offset = offset_from_vma
6889 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
6890 sizeof data + si * sizeof (vers_data));
252b5132 6891
a6e9f9df 6892 get_data (&data, file, offset + si * sizeof (vers_data),
c256ffe7 6893 sizeof (data), 1, _("version data"));
252b5132
RH
6894
6895 vers_data = byte_get (data, 2);
6896
c256ffe7
JJ
6897 is_nobits = (SECTION_HEADER_INDEX (psym->st_shndx)
6898 < elf_header.e_shnum
6899 && SECTION_HEADER (psym->st_shndx)->sh_type
6900 == SHT_NOBITS);
252b5132
RH
6901
6902 check_def = (psym->st_shndx != SHN_UNDEF);
6903
6904 if ((vers_data & 0x8000) || vers_data > 1)
6905 {
b34976b6 6906 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 6907 && (is_nobits || ! check_def))
252b5132 6908 {
b34976b6
AM
6909 Elf_External_Verneed evn;
6910 Elf_Internal_Verneed ivn;
6911 Elf_Internal_Vernaux ivna;
252b5132
RH
6912
6913 /* We must test both. */
d93f0186
NC
6914 offset = offset_from_vma
6915 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
6916 sizeof evn);
252b5132 6917
252b5132
RH
6918 do
6919 {
b34976b6 6920 unsigned long vna_off;
252b5132 6921
c256ffe7 6922 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 6923 _("version need"));
dd27201e
L
6924
6925 ivn.vn_aux = BYTE_GET (evn.vn_aux);
6926 ivn.vn_next = BYTE_GET (evn.vn_next);
6927
252b5132
RH
6928 vna_off = offset + ivn.vn_aux;
6929
6930 do
6931 {
b34976b6 6932 Elf_External_Vernaux evna;
252b5132 6933
a6e9f9df 6934 get_data (&evna, file, vna_off,
c256ffe7 6935 sizeof (evna), 1,
a6e9f9df 6936 _("version need aux (3)"));
252b5132
RH
6937
6938 ivna.vna_other = BYTE_GET (evna.vna_other);
6939 ivna.vna_next = BYTE_GET (evna.vna_next);
6940 ivna.vna_name = BYTE_GET (evna.vna_name);
6941
6942 vna_off += ivna.vna_next;
6943 }
6944 while (ivna.vna_other != vers_data
6945 && ivna.vna_next != 0);
6946
6947 if (ivna.vna_other == vers_data)
6948 break;
6949
6950 offset += ivn.vn_next;
6951 }
6952 while (ivn.vn_next != 0);
6953
6954 if (ivna.vna_other == vers_data)
6955 {
6956 printf ("@%s (%d)",
c256ffe7
JJ
6957 ivna.vna_name < strtab_size
6958 ? strtab + ivna.vna_name : "<corrupt>",
6959 ivna.vna_other);
252b5132
RH
6960 check_def = 0;
6961 }
6962 else if (! is_nobits)
6963 error (_("bad dynamic symbol"));
6964 else
6965 check_def = 1;
6966 }
6967
6968 if (check_def)
6969 {
00d93f34 6970 if (vers_data != 0x8001
b34976b6 6971 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 6972 {
b34976b6
AM
6973 Elf_Internal_Verdef ivd;
6974 Elf_Internal_Verdaux ivda;
6975 Elf_External_Verdaux evda;
6976 unsigned long offset;
252b5132 6977
d93f0186
NC
6978 offset = offset_from_vma
6979 (file,
6980 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
6981 sizeof (Elf_External_Verdef));
252b5132
RH
6982
6983 do
6984 {
b34976b6 6985 Elf_External_Verdef evd;
252b5132 6986
a6e9f9df 6987 get_data (&evd, file, offset, sizeof (evd),
c256ffe7 6988 1, _("version def"));
252b5132 6989
b34976b6
AM
6990 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
6991 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
6992 ivd.vd_next = BYTE_GET (evd.vd_next);
6993
6994 offset += ivd.vd_next;
6995 }
6996 while (ivd.vd_ndx != (vers_data & 0x7fff)
6997 && ivd.vd_next != 0);
6998
6999 offset -= ivd.vd_next;
7000 offset += ivd.vd_aux;
7001
a6e9f9df 7002 get_data (&evda, file, offset, sizeof (evda),
c256ffe7 7003 1, _("version def aux"));
252b5132
RH
7004
7005 ivda.vda_name = BYTE_GET (evda.vda_name);
7006
7007 if (psym->st_name != ivda.vda_name)
7008 printf ((vers_data & 0x8000)
7009 ? "@%s" : "@@%s",
c256ffe7
JJ
7010 ivda.vda_name < strtab_size
7011 ? strtab + ivda.vda_name : "<corrupt>");
252b5132
RH
7012 }
7013 }
7014 }
7015 }
7016
7017 putchar ('\n');
7018 }
7019
7020 free (symtab);
7021 if (strtab != string_table)
7022 free (strtab);
7023 }
7024 }
7025 else if (do_syms)
7026 printf
7027 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
7028
7029 if (do_histogram && buckets != NULL)
7030 {
66543521
AM
7031 unsigned long *lengths;
7032 unsigned long *counts;
7033 unsigned long hn;
7034 bfd_vma si;
7035 unsigned long maxlength = 0;
7036 unsigned long nzero_counts = 0;
7037 unsigned long nsyms = 0;
252b5132 7038
66543521
AM
7039 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
7040 (unsigned long) nbuckets);
252b5132
RH
7041 printf (_(" Length Number %% of total Coverage\n"));
7042
66543521 7043 lengths = calloc (nbuckets, sizeof (*lengths));
252b5132
RH
7044 if (lengths == NULL)
7045 {
7046 error (_("Out of memory"));
7047 return 0;
7048 }
7049 for (hn = 0; hn < nbuckets; ++hn)
7050 {
f7a99963 7051 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 7052 {
b34976b6 7053 ++nsyms;
252b5132 7054 if (maxlength < ++lengths[hn])
b34976b6 7055 ++maxlength;
252b5132
RH
7056 }
7057 }
7058
66543521 7059 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
7060 if (counts == NULL)
7061 {
7062 error (_("Out of memory"));
7063 return 0;
7064 }
7065
7066 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 7067 ++counts[lengths[hn]];
252b5132 7068
103f02d3 7069 if (nbuckets > 0)
252b5132 7070 {
66543521
AM
7071 unsigned long i;
7072 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 7073 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 7074 for (i = 1; i <= maxlength; ++i)
103f02d3 7075 {
66543521
AM
7076 nzero_counts += counts[i] * i;
7077 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
7078 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
7079 (nzero_counts * 100.0) / nsyms);
7080 }
252b5132
RH
7081 }
7082
7083 free (counts);
7084 free (lengths);
7085 }
7086
7087 if (buckets != NULL)
7088 {
7089 free (buckets);
7090 free (chains);
7091 }
7092
7093 return 1;
7094}
7095
7096static int
d3ba0551 7097process_syminfo (FILE *file ATTRIBUTE_UNUSED)
252b5132 7098{
b4c96d0d 7099 unsigned int i;
252b5132
RH
7100
7101 if (dynamic_syminfo == NULL
7102 || !do_dynamic)
7103 /* No syminfo, this is ok. */
7104 return 1;
7105
7106 /* There better should be a dynamic symbol section. */
7107 if (dynamic_symbols == NULL || dynamic_strings == NULL)
7108 return 0;
7109
7110 if (dynamic_addr)
7111 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
7112 dynamic_syminfo_offset, dynamic_syminfo_nent);
7113
7114 printf (_(" Num: Name BoundTo Flags\n"));
7115 for (i = 0; i < dynamic_syminfo_nent; ++i)
7116 {
7117 unsigned short int flags = dynamic_syminfo[i].si_flags;
7118
31104126 7119 printf ("%4d: ", i);
d79b3d50
NC
7120 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
7121 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
7122 else
7123 printf ("<corrupt: %19ld>", dynamic_symbols[i].st_name);
31104126 7124 putchar (' ');
252b5132
RH
7125
7126 switch (dynamic_syminfo[i].si_boundto)
7127 {
7128 case SYMINFO_BT_SELF:
7129 fputs ("SELF ", stdout);
7130 break;
7131 case SYMINFO_BT_PARENT:
7132 fputs ("PARENT ", stdout);
7133 break;
7134 default:
7135 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
7136 && dynamic_syminfo[i].si_boundto < dynamic_nent
7137 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 7138 {
d79b3d50 7139 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
7140 putchar (' ' );
7141 }
252b5132
RH
7142 else
7143 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
7144 break;
7145 }
7146
7147 if (flags & SYMINFO_FLG_DIRECT)
7148 printf (" DIRECT");
7149 if (flags & SYMINFO_FLG_PASSTHRU)
7150 printf (" PASSTHRU");
7151 if (flags & SYMINFO_FLG_COPY)
7152 printf (" COPY");
7153 if (flags & SYMINFO_FLG_LAZYLOAD)
7154 printf (" LAZYLOAD");
7155
7156 puts ("");
7157 }
7158
7159 return 1;
7160}
7161
7162#ifdef SUPPORT_DISASSEMBLY
18bd398b 7163static int
d3ba0551 7164disassemble_section (Elf_Internal_Shdr *section, FILE *file)
252b5132
RH
7165{
7166 printf (_("\nAssembly dump of section %s\n"),
7167 SECTION_NAME (section));
7168
7169 /* XXX -- to be done --- XXX */
7170
7171 return 1;
7172}
7173#endif
7174
7175static int
d3ba0551 7176dump_section (Elf_Internal_Shdr *section, FILE *file)
252b5132 7177{
b34976b6
AM
7178 bfd_size_type bytes;
7179 bfd_vma addr;
7180 unsigned char *data;
7181 unsigned char *start;
252b5132
RH
7182
7183 bytes = section->sh_size;
7184
e69f2d21 7185 if (bytes == 0 || section->sh_type == SHT_NOBITS)
252b5132
RH
7186 {
7187 printf (_("\nSection '%s' has no data to dump.\n"),
7188 SECTION_NAME (section));
7189 return 0;
7190 }
7191 else
7192 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
7193
7194 addr = section->sh_addr;
7195
c256ffe7
JJ
7196 start = get_data (NULL, file, section->sh_offset, 1, bytes,
7197 _("section data"));
a6e9f9df
AM
7198 if (!start)
7199 return 0;
252b5132
RH
7200
7201 data = start;
7202
7203 while (bytes)
7204 {
7205 int j;
7206 int k;
7207 int lbytes;
7208
7209 lbytes = (bytes > 16 ? 16 : bytes);
7210
148d3c43 7211 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132 7212
b34976b6 7213 switch (elf_header.e_ident[EI_DATA])
252b5132 7214 {
9ea033b2 7215 default:
252b5132
RH
7216 case ELFDATA2LSB:
7217 for (j = 15; j >= 0; j --)
7218 {
7219 if (j < lbytes)
b34976b6 7220 printf ("%2.2x", data[j]);
252b5132
RH
7221 else
7222 printf (" ");
7223
7224 if (!(j & 0x3))
7225 printf (" ");
7226 }
7227 break;
7228
7229 case ELFDATA2MSB:
7230 for (j = 0; j < 16; j++)
7231 {
7232 if (j < lbytes)
b34976b6 7233 printf ("%2.2x", data[j]);
252b5132
RH
7234 else
7235 printf (" ");
7236
7237 if ((j & 3) == 3)
7238 printf (" ");
7239 }
7240 break;
7241 }
7242
7243 for (j = 0; j < lbytes; j++)
7244 {
b34976b6 7245 k = data[j];
9376f0c7 7246 if (k >= ' ' && k < 0x7f)
252b5132
RH
7247 printf ("%c", k);
7248 else
7249 printf (".");
7250 }
7251
7252 putchar ('\n');
7253
7254 data += lbytes;
7255 addr += lbytes;
7256 bytes -= lbytes;
7257 }
7258
7259 free (start);
7260
7261 return 1;
7262}
7263
7264
7265static unsigned long int
dc3c06c2 7266read_leb128 (unsigned char *data, unsigned int *length_return, int sign)
252b5132
RH
7267{
7268 unsigned long int result = 0;
b34976b6 7269 unsigned int num_read = 0;
0c548fce 7270 unsigned int shift = 0;
b34976b6 7271 unsigned char byte;
252b5132
RH
7272
7273 do
7274 {
b34976b6
AM
7275 byte = *data++;
7276 num_read++;
252b5132 7277
0c548fce 7278 result |= ((unsigned long int) (byte & 0x7f)) << shift;
252b5132
RH
7279
7280 shift += 7;
7281
7282 }
7283 while (byte & 0x80);
7284
7285 if (length_return != NULL)
b34976b6 7286 *length_return = num_read;
252b5132 7287
0c548fce
L
7288 if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
7289 result |= -1L << shift;
252b5132
RH
7290
7291 return result;
7292}
7293
7294typedef struct State_Machine_Registers
7295{
b34976b6
AM
7296 unsigned long address;
7297 unsigned int file;
7298 unsigned int line;
7299 unsigned int column;
7300 int is_stmt;
7301 int basic_block;
7302 int end_sequence;
252b5132
RH
7303/* This variable hold the number of the last entry seen
7304 in the File Table. */
b34976b6 7305 unsigned int last_file_entry;
252b5132
RH
7306} SMR;
7307
7308static SMR state_machine_regs;
7309
7310static void
d3ba0551 7311reset_state_machine (int is_stmt)
252b5132
RH
7312{
7313 state_machine_regs.address = 0;
7314 state_machine_regs.file = 1;
7315 state_machine_regs.line = 1;
7316 state_machine_regs.column = 0;
7317 state_machine_regs.is_stmt = is_stmt;
7318 state_machine_regs.basic_block = 0;
7319 state_machine_regs.end_sequence = 0;
7320 state_machine_regs.last_file_entry = 0;
7321}
7322
52d1fb02
NC
7323/* Handled an extend line op.
7324 Returns the number of bytes read. */
18bd398b 7325
252b5132 7326static int
d3ba0551 7327process_extended_line_op (unsigned char *data, int is_stmt, int pointer_size)
252b5132 7328{
b34976b6 7329 unsigned char op_code;
dc3c06c2 7330 unsigned int bytes_read;
b34976b6
AM
7331 unsigned int len;
7332 unsigned char *name;
7333 unsigned long adr;
103f02d3 7334
252b5132
RH
7335 len = read_leb128 (data, & bytes_read, 0);
7336 data += bytes_read;
7337
7338 if (len == 0)
7339 {
e5fb9629 7340 warn (_("badly formed extended line op encountered!\n"));
252b5132
RH
7341 return bytes_read;
7342 }
7343
7344 len += bytes_read;
b34976b6 7345 op_code = *data++;
252b5132
RH
7346
7347 printf (_(" Extended opcode %d: "), op_code);
103f02d3 7348
252b5132
RH
7349 switch (op_code)
7350 {
7351 case DW_LNE_end_sequence:
7352 printf (_("End of Sequence\n\n"));
7353 reset_state_machine (is_stmt);
7354 break;
7355
7356 case DW_LNE_set_address:
3590ea00 7357 adr = byte_get (data, pointer_size);
252b5132
RH
7358 printf (_("set Address to 0x%lx\n"), adr);
7359 state_machine_regs.address = adr;
7360 break;
7361
7362 case DW_LNE_define_file:
7363 printf (_(" define new File Table entry\n"));
7364 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
103f02d3 7365
b34976b6 7366 printf (_(" %d\t"), ++state_machine_regs.last_file_entry);
252b5132 7367 name = data;
3c9f43b1 7368 data += strlen ((char *) data) + 1;
252b5132
RH
7369 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
7370 data += bytes_read;
7371 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
7372 data += bytes_read;
7373 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
7374 printf (_("%s\n\n"), name);
7375 break;
7376
7377 default:
7378 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
7379 break;
7380 }
7381
7382 return len;
7383}
7384
5b18a4bc
NC
7385static const char *debug_str_contents;
7386static bfd_vma debug_str_size;
7387
7388static void
7389load_debug_str (FILE *file)
18bd398b 7390{
5b18a4bc 7391 Elf_Internal_Shdr *sec;
18bd398b 7392
5b18a4bc
NC
7393 /* If it is already loaded, do nothing. */
7394 if (debug_str_contents != NULL)
7395 return;
18bd398b 7396
5b18a4bc
NC
7397 /* Locate the .debug_str section. */
7398 sec = find_section (".debug_str");
7399 if (sec == NULL)
7400 return;
7401
7402 debug_str_size = sec->sh_size;
7403
c256ffe7 7404 debug_str_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
5b18a4bc
NC
7405 _("debug_str section data"));
7406}
7407
7408static void
7409free_debug_str (void)
18bd398b 7410{
5b18a4bc
NC
7411 if (debug_str_contents == NULL)
7412 return;
76a56260 7413
5b18a4bc
NC
7414 free ((char *) debug_str_contents);
7415 debug_str_contents = NULL;
7416 debug_str_size = 0;
7417}
76a56260 7418
5b18a4bc
NC
7419static const char *
7420fetch_indirect_string (unsigned long offset)
7421{
7422 if (debug_str_contents == NULL)
7423 return _("<no .debug_str section>");
7424
7425 if (offset > debug_str_size)
41a865ba
NC
7426 {
7427 warn (_("DW_FORM_strp offset too big: %x\n"), offset);
7428 return _("<offset is too big>");
7429 }
18bd398b 7430
5b18a4bc 7431 return debug_str_contents + offset;
18bd398b 7432}
252b5132 7433
5b18a4bc
NC
7434static const char *debug_loc_contents;
7435static bfd_vma debug_loc_size;
d9296b18 7436
5b18a4bc
NC
7437static void
7438load_debug_loc (FILE *file)
d9296b18 7439{
5b18a4bc 7440 Elf_Internal_Shdr *sec;
76a56260 7441
5b18a4bc
NC
7442 /* If it is already loaded, do nothing. */
7443 if (debug_loc_contents != NULL)
7444 return;
18bd398b 7445
5b18a4bc
NC
7446 /* Locate the .debug_loc section. */
7447 sec = find_section (".debug_loc");
7448 if (sec == NULL)
7449 return;
d9296b18 7450
5b18a4bc 7451 debug_loc_size = sec->sh_size;
d9296b18 7452
c256ffe7 7453 debug_loc_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
5b18a4bc
NC
7454 _("debug_loc section data"));
7455}
d9296b18 7456
5b18a4bc
NC
7457static void
7458free_debug_loc (void)
7459{
7460 if (debug_loc_contents == NULL)
7461 return;
d9296b18 7462
5b18a4bc
NC
7463 free ((char *) debug_loc_contents);
7464 debug_loc_contents = NULL;
7465 debug_loc_size = 0;
7466}
d9296b18 7467
5b18a4bc
NC
7468static const char * debug_range_contents;
7469static unsigned long debug_range_size;
d9296b18 7470
5b18a4bc
NC
7471static void
7472load_debug_range (FILE *file)
7473{
7474 Elf_Internal_Shdr *sec;
d9296b18 7475
5b18a4bc
NC
7476 /* If it is already loaded, do nothing. */
7477 if (debug_range_contents != NULL)
7478 return;
d9296b18 7479
f59f7c79 7480 /* Locate the .debug_ranges section. */
5b18a4bc
NC
7481 sec = find_section (".debug_ranges");
7482 if (sec == NULL)
7483 return;
0de14b54 7484
5b18a4bc 7485 debug_range_size = sec->sh_size;
d9296b18 7486
c256ffe7 7487 debug_range_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
5b18a4bc
NC
7488 _("debug_range section data"));
7489}
d9296b18 7490
5b18a4bc
NC
7491static void
7492free_debug_range (void)
7493{
7494 if (debug_range_contents == NULL)
7495 return;
18bd398b 7496
5b18a4bc
NC
7497 free ((char *) debug_range_contents);
7498 debug_range_contents = NULL;
7499 debug_range_size = 0;
d9296b18
NC
7500}
7501
5b18a4bc
NC
7502/* Apply addends of RELA relocations. */
7503
252b5132 7504static int
5b18a4bc
NC
7505debug_apply_rela_addends (FILE *file,
7506 Elf_Internal_Shdr *section,
7507 int reloc_size,
7508 unsigned char *sec_data,
7509 unsigned char *start,
7510 unsigned char *end)
252b5132 7511{
5b18a4bc 7512 Elf_Internal_Shdr *relsec;
252b5132 7513
5b18a4bc
NC
7514 if (end - start < reloc_size)
7515 return 1;
d9296b18 7516
5b18a4bc
NC
7517 for (relsec = section_headers;
7518 relsec < section_headers + elf_header.e_shnum;
7519 ++relsec)
252b5132 7520 {
5b18a4bc
NC
7521 unsigned long nrelas;
7522 Elf_Internal_Rela *rela, *rp;
7523 Elf_Internal_Shdr *symsec;
7524 Elf_Internal_Sym *symtab;
7525 Elf_Internal_Sym *sym;
252b5132 7526
5b18a4bc 7527 if (relsec->sh_type != SHT_RELA
c256ffe7 7528 || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
5b18a4bc 7529 || SECTION_HEADER (relsec->sh_info) != section
c256ffe7
JJ
7530 || relsec->sh_size == 0
7531 || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum)
5b18a4bc 7532 continue;
428409d5 7533
5b18a4bc
NC
7534 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7535 &rela, &nrelas))
7536 return 0;
428409d5 7537
5b18a4bc
NC
7538 symsec = SECTION_HEADER (relsec->sh_link);
7539 symtab = GET_ELF_SYMBOLS (file, symsec);
103f02d3 7540
5b18a4bc 7541 for (rp = rela; rp < rela + nrelas; ++rp)
252b5132 7542 {
5b18a4bc 7543 unsigned char *loc;
103f02d3 7544
5b18a4bc
NC
7545 if (rp->r_offset >= (bfd_vma) (start - sec_data)
7546 && rp->r_offset < (bfd_vma) (end - sec_data) - reloc_size)
7547 loc = sec_data + rp->r_offset;
7548 else
7549 continue;
103f02d3 7550
5b18a4bc
NC
7551 if (is_32bit_elf)
7552 {
7553 sym = symtab + ELF32_R_SYM (rp->r_info);
103f02d3 7554
5b18a4bc
NC
7555 if (ELF32_R_SYM (rp->r_info) != 0
7556 && ELF32_ST_TYPE (sym->st_info) != STT_SECTION
7557 /* Relocations against object symbols can happen,
7558 eg when referencing a global array. For an
7559 example of this see the _clz.o binary in libgcc.a. */
7560 && ELF32_ST_TYPE (sym->st_info) != STT_OBJECT)
7561 {
520494b6 7562 warn (_("skipping unexpected symbol type %s in relocation in section .rela%s\n"),
5b18a4bc
NC
7563 get_symbol_type (ELF32_ST_TYPE (sym->st_info)),
7564 SECTION_NAME (section));
7565 continue;
7566 }
7567 }
7568 else
7569 {
a8b683fc
MR
7570 /* In MIPS little-endian objects, r_info isn't really a
7571 64-bit little-endian value: it has a 32-bit little-endian
7572 symbol index followed by four individual byte fields.
7573 Reorder INFO accordingly. */
7574 if (elf_header.e_machine == EM_MIPS
7575 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
7576 rp->r_info = (((rp->r_info & 0xffffffff) << 32)
7577 | ((rp->r_info >> 56) & 0xff)
7578 | ((rp->r_info >> 40) & 0xff00)
7579 | ((rp->r_info >> 24) & 0xff0000)
7580 | ((rp->r_info >> 8) & 0xff000000));
7581
5b18a4bc 7582 sym = symtab + ELF64_R_SYM (rp->r_info);
0e0c4098 7583
5b18a4bc
NC
7584 if (ELF64_R_SYM (rp->r_info) != 0
7585 && ELF64_ST_TYPE (sym->st_info) != STT_SECTION
7586 && ELF64_ST_TYPE (sym->st_info) != STT_OBJECT)
7587 {
7588 warn (_("skipping unexpected symbol type %s in relocation in section .rela.%s\n"),
7589 get_symbol_type (ELF64_ST_TYPE (sym->st_info)),
7590 SECTION_NAME (section));
7591 continue;
7592 }
7593 }
252b5132 7594
5b18a4bc
NC
7595 byte_put (loc, rp->r_addend, reloc_size);
7596 }
252b5132 7597
5b18a4bc
NC
7598 free (symtab);
7599 free (rela);
7600 break;
7601 }
7602 return 1;
7603}
103f02d3 7604
5b18a4bc
NC
7605/* FIXME: There are better and more efficient ways to handle
7606 these structures. For now though, I just want something that
7607 is simple to implement. */
7608typedef struct abbrev_attr
7609{
7610 unsigned long attribute;
7611 unsigned long form;
7612 struct abbrev_attr *next;
7613}
7614abbrev_attr;
103f02d3 7615
5b18a4bc
NC
7616typedef struct abbrev_entry
7617{
7618 unsigned long entry;
7619 unsigned long tag;
7620 int children;
7621 struct abbrev_attr *first_attr;
7622 struct abbrev_attr *last_attr;
7623 struct abbrev_entry *next;
7624}
7625abbrev_entry;
103f02d3 7626
5b18a4bc
NC
7627static abbrev_entry *first_abbrev = NULL;
7628static abbrev_entry *last_abbrev = NULL;
103f02d3 7629
5b18a4bc
NC
7630static void
7631free_abbrevs (void)
7632{
7633 abbrev_entry *abbrev;
103f02d3 7634
5b18a4bc
NC
7635 for (abbrev = first_abbrev; abbrev;)
7636 {
7637 abbrev_entry *next = abbrev->next;
7638 abbrev_attr *attr;
103f02d3 7639
5b18a4bc
NC
7640 for (attr = abbrev->first_attr; attr;)
7641 {
7642 abbrev_attr *next = attr->next;
103f02d3 7643
5b18a4bc
NC
7644 free (attr);
7645 attr = next;
252b5132 7646 }
103f02d3 7647
5b18a4bc
NC
7648 free (abbrev);
7649 abbrev = next;
7650 }
103f02d3 7651
5b18a4bc
NC
7652 last_abbrev = first_abbrev = NULL;
7653}
103f02d3 7654
5b18a4bc
NC
7655static void
7656add_abbrev (unsigned long number, unsigned long tag, int children)
7657{
7658 abbrev_entry *entry;
103f02d3 7659
5b18a4bc 7660 entry = malloc (sizeof (*entry));
103f02d3 7661
5b18a4bc
NC
7662 if (entry == NULL)
7663 /* ugg */
7664 return;
103f02d3 7665
5b18a4bc
NC
7666 entry->entry = number;
7667 entry->tag = tag;
7668 entry->children = children;
7669 entry->first_attr = NULL;
7670 entry->last_attr = NULL;
7671 entry->next = NULL;
103f02d3 7672
5b18a4bc
NC
7673 if (first_abbrev == NULL)
7674 first_abbrev = entry;
7675 else
7676 last_abbrev->next = entry;
103f02d3 7677
5b18a4bc
NC
7678 last_abbrev = entry;
7679}
103f02d3 7680
5b18a4bc
NC
7681static void
7682add_abbrev_attr (unsigned long attribute, unsigned long form)
7683{
7684 abbrev_attr *attr;
103f02d3 7685
5b18a4bc 7686 attr = malloc (sizeof (*attr));
103f02d3 7687
5b18a4bc
NC
7688 if (attr == NULL)
7689 /* ugg */
7690 return;
103f02d3 7691
5b18a4bc
NC
7692 attr->attribute = attribute;
7693 attr->form = form;
7694 attr->next = NULL;
103f02d3 7695
5b18a4bc
NC
7696 if (last_abbrev->first_attr == NULL)
7697 last_abbrev->first_attr = attr;
7698 else
7699 last_abbrev->last_attr->next = attr;
103f02d3 7700
5b18a4bc
NC
7701 last_abbrev->last_attr = attr;
7702}
103f02d3 7703
5b18a4bc
NC
7704/* Processes the (partial) contents of a .debug_abbrev section.
7705 Returns NULL if the end of the section was encountered.
7706 Returns the address after the last byte read if the end of
7707 an abbreviation set was found. */
103f02d3 7708
5b18a4bc
NC
7709static unsigned char *
7710process_abbrev_section (unsigned char *start, unsigned char *end)
7711{
7712 if (first_abbrev != NULL)
7713 return NULL;
103f02d3 7714
5b18a4bc
NC
7715 while (start < end)
7716 {
dc3c06c2 7717 unsigned int bytes_read;
5b18a4bc
NC
7718 unsigned long entry;
7719 unsigned long tag;
7720 unsigned long attribute;
7721 int children;
103f02d3 7722
5b18a4bc
NC
7723 entry = read_leb128 (start, & bytes_read, 0);
7724 start += bytes_read;
103f02d3 7725
5b18a4bc
NC
7726 /* A single zero is supposed to end the section according
7727 to the standard. If there's more, then signal that to
7728 the caller. */
7729 if (entry == 0)
7730 return start == end ? NULL : start;
252b5132 7731
5b18a4bc
NC
7732 tag = read_leb128 (start, & bytes_read, 0);
7733 start += bytes_read;
428409d5 7734
5b18a4bc 7735 children = *start++;
ee42cf8c 7736
5b18a4bc 7737 add_abbrev (entry, tag, children);
ee42cf8c 7738
5b18a4bc 7739 do
252b5132 7740 {
5b18a4bc 7741 unsigned long form;
252b5132 7742
5b18a4bc
NC
7743 attribute = read_leb128 (start, & bytes_read, 0);
7744 start += bytes_read;
252b5132 7745
5b18a4bc
NC
7746 form = read_leb128 (start, & bytes_read, 0);
7747 start += bytes_read;
252b5132 7748
5b18a4bc
NC
7749 if (attribute != 0)
7750 add_abbrev_attr (attribute, form);
252b5132 7751 }
5b18a4bc 7752 while (attribute != 0);
252b5132
RH
7753 }
7754
5b18a4bc 7755 return NULL;
252b5132
RH
7756}
7757
7758static char *
d3ba0551 7759get_TAG_name (unsigned long tag)
252b5132
RH
7760{
7761 switch (tag)
7762 {
b34976b6
AM
7763 case DW_TAG_padding: return "DW_TAG_padding";
7764 case DW_TAG_array_type: return "DW_TAG_array_type";
7765 case DW_TAG_class_type: return "DW_TAG_class_type";
7766 case DW_TAG_entry_point: return "DW_TAG_entry_point";
7767 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
7768 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
7769 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
7770 case DW_TAG_label: return "DW_TAG_label";
7771 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
7772 case DW_TAG_member: return "DW_TAG_member";
7773 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
7774 case DW_TAG_reference_type: return "DW_TAG_reference_type";
7775 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
7776 case DW_TAG_string_type: return "DW_TAG_string_type";
7777 case DW_TAG_structure_type: return "DW_TAG_structure_type";
7778 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
7779 case DW_TAG_typedef: return "DW_TAG_typedef";
7780 case DW_TAG_union_type: return "DW_TAG_union_type";
252b5132 7781 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
b34976b6
AM
7782 case DW_TAG_variant: return "DW_TAG_variant";
7783 case DW_TAG_common_block: return "DW_TAG_common_block";
7784 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
7785 case DW_TAG_inheritance: return "DW_TAG_inheritance";
7786 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
7787 case DW_TAG_module: return "DW_TAG_module";
7788 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
7789 case DW_TAG_set_type: return "DW_TAG_set_type";
7790 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
7791 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
7792 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
7793 case DW_TAG_base_type: return "DW_TAG_base_type";
7794 case DW_TAG_catch_block: return "DW_TAG_catch_block";
7795 case DW_TAG_const_type: return "DW_TAG_const_type";
7796 case DW_TAG_constant: return "DW_TAG_constant";
7797 case DW_TAG_enumerator: return "DW_TAG_enumerator";
7798 case DW_TAG_file_type: return "DW_TAG_file_type";
7799 case DW_TAG_friend: return "DW_TAG_friend";
7800 case DW_TAG_namelist: return "DW_TAG_namelist";
7801 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
7802 case DW_TAG_packed_type: return "DW_TAG_packed_type";
7803 case DW_TAG_subprogram: return "DW_TAG_subprogram";
7804 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
7805 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
7806 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
7807 case DW_TAG_try_block: return "DW_TAG_try_block";
7808 case DW_TAG_variant_part: return "DW_TAG_variant_part";
7809 case DW_TAG_variable: return "DW_TAG_variable";
7810 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
7811 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
7812 case DW_TAG_format_label: return "DW_TAG_format_label";
7813 case DW_TAG_function_template: return "DW_TAG_function_template";
7814 case DW_TAG_class_template: return "DW_TAG_class_template";
b811889f 7815 /* DWARF 2.1 values. */
b34976b6
AM
7816 case DW_TAG_dwarf_procedure: return "DW_TAG_dwarf_procedure";
7817 case DW_TAG_restrict_type: return "DW_TAG_restrict_type";
7818 case DW_TAG_interface_type: return "DW_TAG_interface_type";
7819 case DW_TAG_namespace: return "DW_TAG_namespace";
7820 case DW_TAG_imported_module: return "DW_TAG_imported_module";
7821 case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type";
7822 case DW_TAG_partial_unit: return "DW_TAG_partial_unit";
7823 case DW_TAG_imported_unit: return "DW_TAG_imported_unit";
84ad6ede 7824 /* UPC values. */
ba2685cc
AM
7825 case DW_TAG_upc_shared_type: return "DW_TAG_upc_shared_type";
7826 case DW_TAG_upc_strict_type: return "DW_TAG_upc_strict_type";
7827 case DW_TAG_upc_relaxed_type: return "DW_TAG_upc_relaxed_type";
252b5132
RH
7828 default:
7829 {
b34976b6 7830 static char buffer[100];
252b5132 7831
e9e44622 7832 snprintf (buffer, sizeof (buffer), _("Unknown TAG value: %lx"), tag);
252b5132
RH
7833 return buffer;
7834 }
7835 }
7836}
7837
252b5132 7838static char *
d3ba0551 7839get_FORM_name (unsigned long form)
252b5132
RH
7840{
7841 switch (form)
7842 {
b34976b6
AM
7843 case DW_FORM_addr: return "DW_FORM_addr";
7844 case DW_FORM_block2: return "DW_FORM_block2";
7845 case DW_FORM_block4: return "DW_FORM_block4";
7846 case DW_FORM_data2: return "DW_FORM_data2";
7847 case DW_FORM_data4: return "DW_FORM_data4";
7848 case DW_FORM_data8: return "DW_FORM_data8";
7849 case DW_FORM_string: return "DW_FORM_string";
7850 case DW_FORM_block: return "DW_FORM_block";
7851 case DW_FORM_block1: return "DW_FORM_block1";
7852 case DW_FORM_data1: return "DW_FORM_data1";
7853 case DW_FORM_flag: return "DW_FORM_flag";
7854 case DW_FORM_sdata: return "DW_FORM_sdata";
7855 case DW_FORM_strp: return "DW_FORM_strp";
7856 case DW_FORM_udata: return "DW_FORM_udata";
7857 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
7858 case DW_FORM_ref1: return "DW_FORM_ref1";
7859 case DW_FORM_ref2: return "DW_FORM_ref2";
7860 case DW_FORM_ref4: return "DW_FORM_ref4";
7861 case DW_FORM_ref8: return "DW_FORM_ref8";
7862 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
7863 case DW_FORM_indirect: return "DW_FORM_indirect";
252b5132
RH
7864 default:
7865 {
b34976b6 7866 static char buffer[100];
252b5132 7867
e9e44622 7868 snprintf (buffer, sizeof (buffer), _("Unknown FORM value: %lx"), form);
252b5132
RH
7869 return buffer;
7870 }
7871 }
7872}
7873
5b18a4bc
NC
7874static unsigned char *
7875display_block (unsigned char *data, unsigned long length)
252b5132 7876{
5b18a4bc 7877 printf (_(" %lu byte block: "), length);
252b5132 7878
5b18a4bc
NC
7879 while (length --)
7880 printf ("%lx ", (unsigned long) byte_get (data++, 1));
252b5132 7881
5b18a4bc 7882 return data;
252b5132
RH
7883}
7884
b38c7015 7885static int
5b18a4bc
NC
7886decode_location_expression (unsigned char * data,
7887 unsigned int pointer_size,
7888 unsigned long length,
7889 unsigned long cu_offset)
e0c60db2 7890{
5b18a4bc 7891 unsigned op;
dc3c06c2 7892 unsigned int bytes_read;
5b18a4bc
NC
7893 unsigned long uvalue;
7894 unsigned char *end = data + length;
b38c7015 7895 int need_frame_base = 0;
e0c60db2 7896
5b18a4bc 7897 while (data < end)
e0c60db2 7898 {
5b18a4bc 7899 op = *data++;
e0c60db2
NC
7900
7901 switch (op)
7902 {
5b18a4bc
NC
7903 case DW_OP_addr:
7904 printf ("DW_OP_addr: %lx",
7905 (unsigned long) byte_get (data, pointer_size));
7906 data += pointer_size;
e0c60db2 7907 break;
5b18a4bc
NC
7908 case DW_OP_deref:
7909 printf ("DW_OP_deref");
e0c60db2 7910 break;
5b18a4bc
NC
7911 case DW_OP_const1u:
7912 printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
e0c60db2 7913 break;
5b18a4bc
NC
7914 case DW_OP_const1s:
7915 printf ("DW_OP_const1s: %ld", (long) byte_get_signed (data++, 1));
e0c60db2 7916 break;
5b18a4bc
NC
7917 case DW_OP_const2u:
7918 printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
7919 data += 2;
eb6bd4d3
JM
7920 break;
7921 case DW_OP_const2s:
74013231 7922 printf ("DW_OP_const2s: %ld", (long) byte_get_signed (data, 2));
eb6bd4d3
JM
7923 data += 2;
7924 break;
7925 case DW_OP_const4u:
7926 printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
7927 data += 4;
7928 break;
7929 case DW_OP_const4s:
74013231 7930 printf ("DW_OP_const4s: %ld", (long) byte_get_signed (data, 4));
eb6bd4d3
JM
7931 data += 4;
7932 break;
7933 case DW_OP_const8u:
7934 printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
7935 (unsigned long) byte_get (data + 4, 4));
7936 data += 8;
7937 break;
7938 case DW_OP_const8s:
7939 printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
7940 (long) byte_get (data + 4, 4));
7941 data += 8;
7942 break;
7943 case DW_OP_constu:
7944 printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
7945 data += bytes_read;
7946 break;
7947 case DW_OP_consts:
7948 printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
7949 data += bytes_read;
7950 break;
7951 case DW_OP_dup:
7952 printf ("DW_OP_dup");
7953 break;
7954 case DW_OP_drop:
7955 printf ("DW_OP_drop");
7956 break;
7957 case DW_OP_over:
7958 printf ("DW_OP_over");
7959 break;
7960 case DW_OP_pick:
7961 printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
7962 break;
7963 case DW_OP_swap:
7964 printf ("DW_OP_swap");
7965 break;
7966 case DW_OP_rot:
7967 printf ("DW_OP_rot");
7968 break;
7969 case DW_OP_xderef:
7970 printf ("DW_OP_xderef");
7971 break;
7972 case DW_OP_abs:
7973 printf ("DW_OP_abs");
7974 break;
7975 case DW_OP_and:
7976 printf ("DW_OP_and");
7977 break;
7978 case DW_OP_div:
7979 printf ("DW_OP_div");
7980 break;
7981 case DW_OP_minus:
7982 printf ("DW_OP_minus");
7983 break;
7984 case DW_OP_mod:
7985 printf ("DW_OP_mod");
7986 break;
7987 case DW_OP_mul:
7988 printf ("DW_OP_mul");
7989 break;
7990 case DW_OP_neg:
7991 printf ("DW_OP_neg");
7992 break;
7993 case DW_OP_not:
7994 printf ("DW_OP_not");
7995 break;
7996 case DW_OP_or:
7997 printf ("DW_OP_or");
7998 break;
7999 case DW_OP_plus:
8000 printf ("DW_OP_plus");
8001 break;
8002 case DW_OP_plus_uconst:
8003 printf ("DW_OP_plus_uconst: %lu",
8004 read_leb128 (data, &bytes_read, 0));
8005 data += bytes_read;
8006 break;
8007 case DW_OP_shl:
8008 printf ("DW_OP_shl");
8009 break;
8010 case DW_OP_shr:
8011 printf ("DW_OP_shr");
8012 break;
8013 case DW_OP_shra:
8014 printf ("DW_OP_shra");
8015 break;
8016 case DW_OP_xor:
8017 printf ("DW_OP_xor");
8018 break;
8019 case DW_OP_bra:
74013231 8020 printf ("DW_OP_bra: %ld", (long) byte_get_signed (data, 2));
eb6bd4d3
JM
8021 data += 2;
8022 break;
8023 case DW_OP_eq:
8024 printf ("DW_OP_eq");
8025 break;
8026 case DW_OP_ge:
8027 printf ("DW_OP_ge");
8028 break;
8029 case DW_OP_gt:
8030 printf ("DW_OP_gt");
8031 break;
8032 case DW_OP_le:
8033 printf ("DW_OP_le");
8034 break;
8035 case DW_OP_lt:
8036 printf ("DW_OP_lt");
8037 break;
8038 case DW_OP_ne:
8039 printf ("DW_OP_ne");
8040 break;
8041 case DW_OP_skip:
74013231 8042 printf ("DW_OP_skip: %ld", (long) byte_get_signed (data, 2));
eb6bd4d3
JM
8043 data += 2;
8044 break;
8045
5b18a4bc
NC
8046 case DW_OP_lit0:
8047 case DW_OP_lit1:
8048 case DW_OP_lit2:
8049 case DW_OP_lit3:
8050 case DW_OP_lit4:
8051 case DW_OP_lit5:
8052 case DW_OP_lit6:
8053 case DW_OP_lit7:
8054 case DW_OP_lit8:
8055 case DW_OP_lit9:
8056 case DW_OP_lit10:
8057 case DW_OP_lit11:
8058 case DW_OP_lit12:
8059 case DW_OP_lit13:
8060 case DW_OP_lit14:
8061 case DW_OP_lit15:
8062 case DW_OP_lit16:
8063 case DW_OP_lit17:
8064 case DW_OP_lit18:
8065 case DW_OP_lit19:
8066 case DW_OP_lit20:
8067 case DW_OP_lit21:
8068 case DW_OP_lit22:
8069 case DW_OP_lit23:
8070 case DW_OP_lit24:
8071 case DW_OP_lit25:
8072 case DW_OP_lit26:
8073 case DW_OP_lit27:
8074 case DW_OP_lit28:
8075 case DW_OP_lit29:
8076 case DW_OP_lit30:
8077 case DW_OP_lit31:
8078 printf ("DW_OP_lit%d", op - DW_OP_lit0);
8079 break;
8080
8081 case DW_OP_reg0:
8082 case DW_OP_reg1:
8083 case DW_OP_reg2:
8084 case DW_OP_reg3:
8085 case DW_OP_reg4:
8086 case DW_OP_reg5:
8087 case DW_OP_reg6:
8088 case DW_OP_reg7:
8089 case DW_OP_reg8:
8090 case DW_OP_reg9:
8091 case DW_OP_reg10:
8092 case DW_OP_reg11:
8093 case DW_OP_reg12:
8094 case DW_OP_reg13:
8095 case DW_OP_reg14:
8096 case DW_OP_reg15:
8097 case DW_OP_reg16:
8098 case DW_OP_reg17:
8099 case DW_OP_reg18:
8100 case DW_OP_reg19:
8101 case DW_OP_reg20:
8102 case DW_OP_reg21:
8103 case DW_OP_reg22:
8104 case DW_OP_reg23:
8105 case DW_OP_reg24:
8106 case DW_OP_reg25:
8107 case DW_OP_reg26:
8108 case DW_OP_reg27:
8109 case DW_OP_reg28:
8110 case DW_OP_reg29:
8111 case DW_OP_reg30:
8112 case DW_OP_reg31:
8113 printf ("DW_OP_reg%d", op - DW_OP_reg0);
8114 break;
8115
8116 case DW_OP_breg0:
8117 case DW_OP_breg1:
8118 case DW_OP_breg2:
8119 case DW_OP_breg3:
8120 case DW_OP_breg4:
8121 case DW_OP_breg5:
8122 case DW_OP_breg6:
8123 case DW_OP_breg7:
8124 case DW_OP_breg8:
8125 case DW_OP_breg9:
8126 case DW_OP_breg10:
8127 case DW_OP_breg11:
8128 case DW_OP_breg12:
8129 case DW_OP_breg13:
8130 case DW_OP_breg14:
8131 case DW_OP_breg15:
8132 case DW_OP_breg16:
8133 case DW_OP_breg17:
8134 case DW_OP_breg18:
8135 case DW_OP_breg19:
8136 case DW_OP_breg20:
8137 case DW_OP_breg21:
8138 case DW_OP_breg22:
8139 case DW_OP_breg23:
8140 case DW_OP_breg24:
8141 case DW_OP_breg25:
8142 case DW_OP_breg26:
8143 case DW_OP_breg27:
8144 case DW_OP_breg28:
8145 case DW_OP_breg29:
8146 case DW_OP_breg30:
8147 case DW_OP_breg31:
8148 printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
8149 read_leb128 (data, &bytes_read, 1));
8150 data += bytes_read;
8151 break;
8152
8153 case DW_OP_regx:
8154 printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
8155 data += bytes_read;
8156 break;
8157 case DW_OP_fbreg:
b38c7015 8158 need_frame_base = 1;
5b18a4bc
NC
8159 printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
8160 data += bytes_read;
8161 break;
8162 case DW_OP_bregx:
8163 uvalue = read_leb128 (data, &bytes_read, 0);
8164 data += bytes_read;
8165 printf ("DW_OP_bregx: %lu %ld", uvalue,
8166 read_leb128 (data, &bytes_read, 1));
8167 data += bytes_read;
8168 break;
8169 case DW_OP_piece:
8170 printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
8171 data += bytes_read;
8172 break;
8173 case DW_OP_deref_size:
8174 printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
8175 break;
8176 case DW_OP_xderef_size:
8177 printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
8178 break;
8179 case DW_OP_nop:
8180 printf ("DW_OP_nop");
8181 break;
8182
8183 /* DWARF 3 extensions. */
8184 case DW_OP_push_object_address:
8185 printf ("DW_OP_push_object_address");
8186 break;
8187 case DW_OP_call2:
8188 /* XXX: Strictly speaking for 64-bit DWARF3 files
8189 this ought to be an 8-byte wide computation. */
8190 printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2) + cu_offset);
8191 data += 2;
8192 break;
8193 case DW_OP_call4:
8194 /* XXX: Strictly speaking for 64-bit DWARF3 files
8195 this ought to be an 8-byte wide computation. */
8196 printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4) + cu_offset);
8197 data += 4;
8198 break;
8199 case DW_OP_call_ref:
8200 printf ("DW_OP_call_ref");
8201 break;
8202
8203 /* GNU extensions. */
8204 case DW_OP_GNU_push_tls_address:
8205 printf ("DW_OP_GNU_push_tls_address");
8206 break;
8207
8208 default:
8209 if (op >= DW_OP_lo_user
8210 && op <= DW_OP_hi_user)
8211 printf (_("(User defined location op)"));
8212 else
8213 printf (_("(Unknown location op)"));
8214 /* No way to tell where the next op is, so just bail. */
b38c7015 8215 return need_frame_base;
5b18a4bc
NC
8216 }
8217
8218 /* Separate the ops. */
8219 if (data < end)
8220 printf ("; ");
8221 }
b38c7015
L
8222
8223 return need_frame_base;
5b18a4bc
NC
8224}
8225
5b18a4bc
NC
8226/* This structure records the information that
8227 we extract from the.debug_info section. */
8228typedef struct
8229{
8230 unsigned int pointer_size;
8231 unsigned long cu_offset;
b38c7015 8232 unsigned long base_address;
5b18a4bc
NC
8233 /* This is an array of offsets to the location list table. */
8234 unsigned long *loc_offsets;
b38c7015 8235 int *have_frame_base;
5b18a4bc
NC
8236 unsigned int num_loc_offsets;
8237 unsigned int max_loc_offsets;
0853c092
L
8238 unsigned long *range_lists;
8239 unsigned int num_range_lists;
8240 unsigned int max_range_lists;
5b18a4bc
NC
8241}
8242debug_info;
8243
8244static debug_info * debug_information = NULL;
8245static unsigned int num_debug_info_entries = 0;
8246static unsigned int last_pointer_size = 0;
8247static int warned_about_missing_comp_units = FALSE;
8248
8249static unsigned char *
8250read_and_display_attr_value (unsigned long attribute,
8251 unsigned long form,
8252 unsigned char *data,
8253 unsigned long cu_offset,
8254 unsigned long pointer_size,
8255 unsigned long offset_size,
8256 int dwarf_version,
8257 debug_info *debug_info_p,
8258 int do_loc)
8259{
5b18a4bc
NC
8260 unsigned long uvalue = 0;
8261 unsigned char *block_start = NULL;
dc3c06c2 8262 unsigned int bytes_read;
5b18a4bc
NC
8263
8264 switch (form)
8265 {
8266 default:
8267 break;
8268
8269 case DW_FORM_ref_addr:
8270 if (dwarf_version == 2)
8271 {
8272 uvalue = byte_get (data, pointer_size);
8273 data += pointer_size;
8274 }
8275 else if (dwarf_version == 3)
8276 {
8277 uvalue = byte_get (data, offset_size);
8278 data += offset_size;
8279 }
8280 else
8281 {
8282 error (_("Internal error: DWARF version is not 2 or 3.\n"));
8283 }
8284 break;
8285
8286 case DW_FORM_addr:
8287 uvalue = byte_get (data, pointer_size);
8288 data += pointer_size;
8289 break;
8290
8291 case DW_FORM_strp:
8292 uvalue = byte_get (data, offset_size);
8293 data += offset_size;
8294 break;
8295
8296 case DW_FORM_ref1:
8297 case DW_FORM_flag:
8298 case DW_FORM_data1:
8299 uvalue = byte_get (data++, 1);
8300 break;
8301
8302 case DW_FORM_ref2:
8303 case DW_FORM_data2:
8304 uvalue = byte_get (data, 2);
8305 data += 2;
8306 break;
8307
8308 case DW_FORM_ref4:
8309 case DW_FORM_data4:
8310 uvalue = byte_get (data, 4);
8311 data += 4;
8312 break;
8313
8314 case DW_FORM_sdata:
8315 uvalue = read_leb128 (data, & bytes_read, 1);
8316 data += bytes_read;
8317 break;
8318
8319 case DW_FORM_ref_udata:
8320 case DW_FORM_udata:
8321 uvalue = read_leb128 (data, & bytes_read, 0);
8322 data += bytes_read;
8323 break;
8324
8325 case DW_FORM_indirect:
8326 form = read_leb128 (data, & bytes_read, 0);
8327 data += bytes_read;
8328 if (!do_loc)
8329 printf (" %s", get_FORM_name (form));
8330 return read_and_display_attr_value (attribute, form, data,
8331 cu_offset, pointer_size,
8332 offset_size, dwarf_version,
8333 debug_info_p, do_loc);
8334 }
8335
8336 switch (form)
8337 {
8338 case DW_FORM_ref_addr:
8339 if (!do_loc)
8340 printf (" <#%lx>", uvalue);
8341 break;
8342
8343 case DW_FORM_ref1:
8344 case DW_FORM_ref2:
8345 case DW_FORM_ref4:
8346 case DW_FORM_ref_udata:
8347 if (!do_loc)
8348 printf (" <%lx>", uvalue + cu_offset);
8349 break;
8350
8351 case DW_FORM_data4:
8352 case DW_FORM_addr:
8353 if (!do_loc)
8354 printf (" %#lx", uvalue);
8355 break;
8356
8357 case DW_FORM_flag:
8358 case DW_FORM_data1:
8359 case DW_FORM_data2:
8360 case DW_FORM_sdata:
8361 case DW_FORM_udata:
8362 if (!do_loc)
8363 printf (" %ld", uvalue);
8364 break;
8365
8366 case DW_FORM_ref8:
8367 case DW_FORM_data8:
8368 if (!do_loc)
8369 {
8370 uvalue = byte_get (data, 4);
8371 printf (" %lx", uvalue);
8372 printf (" %lx", (unsigned long) byte_get (data + 4, 4));
8373 }
0853c092 8374 if ((do_loc || do_debug_loc || do_debug_ranges)
5b18a4bc
NC
8375 && num_debug_info_entries == 0)
8376 {
8377 if (sizeof (uvalue) == 8)
8378 uvalue = byte_get (data, 8);
8379 else
8380 error (_("DW_FORM_data8 is unsupported when sizeof (unsigned long) != 8\n"));
8381 }
8382 data += 8;
8383 break;
8384
8385 case DW_FORM_string:
8386 if (!do_loc)
8387 printf (" %s", data);
8388 data += strlen ((char *) data) + 1;
8389 break;
8390
8391 case DW_FORM_block:
8392 uvalue = read_leb128 (data, & bytes_read, 0);
8393 block_start = data + bytes_read;
8394 if (do_loc)
8395 data = block_start + uvalue;
8396 else
8397 data = display_block (block_start, uvalue);
8398 break;
8399
8400 case DW_FORM_block1:
8401 uvalue = byte_get (data, 1);
8402 block_start = data + 1;
8403 if (do_loc)
8404 data = block_start + uvalue;
8405 else
8406 data = display_block (block_start, uvalue);
8407 break;
8408
8409 case DW_FORM_block2:
8410 uvalue = byte_get (data, 2);
8411 block_start = data + 2;
8412 if (do_loc)
8413 data = block_start + uvalue;
8414 else
8415 data = display_block (block_start, uvalue);
8416 break;
8417
8418 case DW_FORM_block4:
8419 uvalue = byte_get (data, 4);
8420 block_start = data + 4;
8421 if (do_loc)
8422 data = block_start + uvalue;
8423 else
8424 data = display_block (block_start, uvalue);
8425 break;
8426
8427 case DW_FORM_strp:
8428 if (!do_loc)
8429 printf (_(" (indirect string, offset: 0x%lx): %s"),
8430 uvalue, fetch_indirect_string (uvalue));
8431 break;
8432
8433 case DW_FORM_indirect:
8434 /* Handled above. */
8435 break;
8436
8437 default:
8438 warn (_("Unrecognized form: %d\n"), form);
8439 break;
8440 }
8441
8442 /* For some attributes we can display further information. */
0853c092 8443 if ((do_loc || do_debug_loc || do_debug_ranges)
5b18a4bc
NC
8444 && num_debug_info_entries == 0)
8445 {
8446 switch (attribute)
8447 {
8448 case DW_AT_frame_base:
b38c7015 8449 have_frame_base = 1;
5b18a4bc
NC
8450 case DW_AT_location:
8451 case DW_AT_data_member_location:
8452 case DW_AT_vtable_elem_location:
8453 case DW_AT_allocated:
8454 case DW_AT_associated:
8455 case DW_AT_data_location:
8456 case DW_AT_stride:
8457 case DW_AT_upper_bound:
8458 case DW_AT_lower_bound:
8459 if (form == DW_FORM_data4 || form == DW_FORM_data8)
8460 {
8461 /* Process location list. */
8462 unsigned int max = debug_info_p->max_loc_offsets;
8463 unsigned int num = debug_info_p->num_loc_offsets;
8464
8465 if (max == 0 || num >= max)
8466 {
8467 max += 1024;
8468 debug_info_p->loc_offsets
c256ffe7
JJ
8469 = xcrealloc (debug_info_p->loc_offsets,
8470 max, sizeof (*debug_info_p->loc_offsets));
b38c7015 8471 debug_info_p->have_frame_base
c256ffe7
JJ
8472 = xcrealloc (debug_info_p->have_frame_base,
8473 max, sizeof (*debug_info_p->have_frame_base));
5b18a4bc
NC
8474 debug_info_p->max_loc_offsets = max;
8475 }
8476 debug_info_p->loc_offsets [num] = uvalue;
b38c7015 8477 debug_info_p->have_frame_base [num] = have_frame_base;
5b18a4bc
NC
8478 debug_info_p->num_loc_offsets++;
8479 }
8480 break;
b38c7015
L
8481
8482 case DW_AT_low_pc:
8483 if (need_base_address)
8484 debug_info_p->base_address = uvalue;
8485 break;
5b18a4bc 8486
0853c092
L
8487 case DW_AT_ranges:
8488 if (form == DW_FORM_data4 || form == DW_FORM_data8)
8489 {
8490 /* Process range list. */
8491 unsigned int max = debug_info_p->max_range_lists;
8492 unsigned int num = debug_info_p->num_range_lists;
8493
8494 if (max == 0 || num >= max)
8495 {
8496 max += 1024;
8497 debug_info_p->range_lists
c256ffe7
JJ
8498 = xcrealloc (debug_info_p->range_lists,
8499 max, sizeof (*debug_info_p->range_lists));
0853c092
L
8500 debug_info_p->max_range_lists = max;
8501 }
8502 debug_info_p->range_lists [num] = uvalue;
8503 debug_info_p->num_range_lists++;
8504 }
8505 break;
8506
5b18a4bc
NC
8507 default:
8508 break;
8509 }
8510 }
8511
8512 if (do_loc)
8513 return data;
8514
8515 printf ("\t");
8516
8517 switch (attribute)
8518 {
8519 case DW_AT_inline:
8520 switch (uvalue)
8521 {
8522 case DW_INL_not_inlined:
8523 printf (_("(not inlined)"));
8524 break;
8525 case DW_INL_inlined:
8526 printf (_("(inlined)"));
8527 break;
8528 case DW_INL_declared_not_inlined:
8529 printf (_("(declared as inline but ignored)"));
8530 break;
8531 case DW_INL_declared_inlined:
8532 printf (_("(declared as inline and inlined)"));
8533 break;
8534 default:
8535 printf (_(" (Unknown inline attribute value: %lx)"), uvalue);
8536 break;
8537 }
8538 break;
8539
8540 case DW_AT_language:
8541 switch (uvalue)
8542 {
8543 case DW_LANG_C: printf ("(non-ANSI C)"); break;
8544 case DW_LANG_C89: printf ("(ANSI C)"); break;
8545 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
8546 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
8547 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
8548 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
8549 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
8550 case DW_LANG_Ada83: printf ("(Ada)"); break;
8551 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
8552 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
8553 /* DWARF 2.1 values. */
8554 case DW_LANG_C99: printf ("(ANSI C99)"); break;
8555 case DW_LANG_Ada95: printf ("(ADA 95)"); break;
8556 case DW_LANG_Fortran95: printf ("(Fortran 95)"); break;
8557 /* MIPS extension. */
8558 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
8559 /* UPC extension. */
8560 case DW_LANG_Upc: printf ("(Unified Parallel C)"); break;
8561 default:
8562 printf ("(Unknown: %lx)", uvalue);
8563 break;
8564 }
8565 break;
8566
8567 case DW_AT_encoding:
8568 switch (uvalue)
8569 {
8570 case DW_ATE_void: printf ("(void)"); break;
8571 case DW_ATE_address: printf ("(machine address)"); break;
8572 case DW_ATE_boolean: printf ("(boolean)"); break;
8573 case DW_ATE_complex_float: printf ("(complex float)"); break;
8574 case DW_ATE_float: printf ("(float)"); break;
8575 case DW_ATE_signed: printf ("(signed)"); break;
8576 case DW_ATE_signed_char: printf ("(signed char)"); break;
8577 case DW_ATE_unsigned: printf ("(unsigned)"); break;
8578 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
8579 /* DWARF 2.1 value. */
8580 case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
d68f4033
BE
8581 /* GNU extension. */
8582 case DW_ATE_GNU_decimal_float: printf ("(decimal float)"); break;
5b18a4bc
NC
8583 default:
8584 if (uvalue >= DW_ATE_lo_user
8585 && uvalue <= DW_ATE_hi_user)
8586 printf ("(user defined type)");
8587 else
8588 printf ("(unknown type)");
8589 break;
8590 }
8591 break;
8592
8593 case DW_AT_accessibility:
8594 switch (uvalue)
8595 {
8596 case DW_ACCESS_public: printf ("(public)"); break;
8597 case DW_ACCESS_protected: printf ("(protected)"); break;
8598 case DW_ACCESS_private: printf ("(private)"); break;
8599 default:
8600 printf ("(unknown accessibility)");
8601 break;
8602 }
8603 break;
8604
8605 case DW_AT_visibility:
8606 switch (uvalue)
8607 {
8608 case DW_VIS_local: printf ("(local)"); break;
8609 case DW_VIS_exported: printf ("(exported)"); break;
8610 case DW_VIS_qualified: printf ("(qualified)"); break;
8611 default: printf ("(unknown visibility)"); break;
8612 }
8613 break;
8614
8615 case DW_AT_virtuality:
8616 switch (uvalue)
8617 {
8618 case DW_VIRTUALITY_none: printf ("(none)"); break;
8619 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
8620 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
8621 default: printf ("(unknown virtuality)"); break;
8622 }
8623 break;
8624
8625 case DW_AT_identifier_case:
8626 switch (uvalue)
8627 {
8628 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
8629 case DW_ID_up_case: printf ("(up_case)"); break;
8630 case DW_ID_down_case: printf ("(down_case)"); break;
8631 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
8632 default: printf ("(unknown case)"); break;
8633 }
8634 break;
8635
8636 case DW_AT_calling_convention:
8637 switch (uvalue)
8638 {
8639 case DW_CC_normal: printf ("(normal)"); break;
8640 case DW_CC_program: printf ("(program)"); break;
8641 case DW_CC_nocall: printf ("(nocall)"); break;
8642 default:
8643 if (uvalue >= DW_CC_lo_user
8644 && uvalue <= DW_CC_hi_user)
8645 printf ("(user defined)");
8646 else
8647 printf ("(unknown convention)");
8648 }
8649 break;
8650
8651 case DW_AT_ordering:
8652 switch (uvalue)
8653 {
8654 case -1: printf ("(undefined)"); break;
8655 case 0: printf ("(row major)"); break;
8656 case 1: printf ("(column major)"); break;
8657 }
8658 break;
8659
8660 case DW_AT_frame_base:
b38c7015 8661 have_frame_base = 1;
5b18a4bc
NC
8662 case DW_AT_location:
8663 case DW_AT_data_member_location:
8664 case DW_AT_vtable_elem_location:
8665 case DW_AT_allocated:
8666 case DW_AT_associated:
8667 case DW_AT_data_location:
8668 case DW_AT_stride:
8669 case DW_AT_upper_bound:
8670 case DW_AT_lower_bound:
8671 if (block_start)
8672 {
b38c7015
L
8673 int need_frame_base;
8674
5b18a4bc 8675 printf ("(");
b38c7015
L
8676 need_frame_base = decode_location_expression (block_start,
8677 pointer_size,
8678 uvalue,
8679 cu_offset);
5b18a4bc 8680 printf (")");
b38c7015
L
8681 if (need_frame_base && !have_frame_base)
8682 printf (_(" [without DW_AT_frame_base]"));
5b18a4bc
NC
8683 }
8684 else if (form == DW_FORM_data4 || form == DW_FORM_data8)
8685 printf (_("(location list)"));
8686
8687 break;
8688
5b18a4bc
NC
8689 default:
8690 break;
8691 }
8692
8693 return data;
8694}
8695
8696static char *
8697get_AT_name (unsigned long attribute)
8698{
8699 switch (attribute)
8700 {
8701 case DW_AT_sibling: return "DW_AT_sibling";
8702 case DW_AT_location: return "DW_AT_location";
8703 case DW_AT_name: return "DW_AT_name";
8704 case DW_AT_ordering: return "DW_AT_ordering";
8705 case DW_AT_subscr_data: return "DW_AT_subscr_data";
8706 case DW_AT_byte_size: return "DW_AT_byte_size";
8707 case DW_AT_bit_offset: return "DW_AT_bit_offset";
8708 case DW_AT_bit_size: return "DW_AT_bit_size";
8709 case DW_AT_element_list: return "DW_AT_element_list";
8710 case DW_AT_stmt_list: return "DW_AT_stmt_list";
8711 case DW_AT_low_pc: return "DW_AT_low_pc";
8712 case DW_AT_high_pc: return "DW_AT_high_pc";
8713 case DW_AT_language: return "DW_AT_language";
8714 case DW_AT_member: return "DW_AT_member";
8715 case DW_AT_discr: return "DW_AT_discr";
8716 case DW_AT_discr_value: return "DW_AT_discr_value";
8717 case DW_AT_visibility: return "DW_AT_visibility";
8718 case DW_AT_import: return "DW_AT_import";
8719 case DW_AT_string_length: return "DW_AT_string_length";
8720 case DW_AT_common_reference: return "DW_AT_common_reference";
8721 case DW_AT_comp_dir: return "DW_AT_comp_dir";
8722 case DW_AT_const_value: return "DW_AT_const_value";
8723 case DW_AT_containing_type: return "DW_AT_containing_type";
8724 case DW_AT_default_value: return "DW_AT_default_value";
8725 case DW_AT_inline: return "DW_AT_inline";
8726 case DW_AT_is_optional: return "DW_AT_is_optional";
8727 case DW_AT_lower_bound: return "DW_AT_lower_bound";
8728 case DW_AT_producer: return "DW_AT_producer";
8729 case DW_AT_prototyped: return "DW_AT_prototyped";
8730 case DW_AT_return_addr: return "DW_AT_return_addr";
8731 case DW_AT_start_scope: return "DW_AT_start_scope";
8732 case DW_AT_stride_size: return "DW_AT_stride_size";
8733 case DW_AT_upper_bound: return "DW_AT_upper_bound";
8734 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
8735 case DW_AT_accessibility: return "DW_AT_accessibility";
8736 case DW_AT_address_class: return "DW_AT_address_class";
8737 case DW_AT_artificial: return "DW_AT_artificial";
8738 case DW_AT_base_types: return "DW_AT_base_types";
8739 case DW_AT_calling_convention: return "DW_AT_calling_convention";
8740 case DW_AT_count: return "DW_AT_count";
8741 case DW_AT_data_member_location: return "DW_AT_data_member_location";
8742 case DW_AT_decl_column: return "DW_AT_decl_column";
8743 case DW_AT_decl_file: return "DW_AT_decl_file";
8744 case DW_AT_decl_line: return "DW_AT_decl_line";
8745 case DW_AT_declaration: return "DW_AT_declaration";
8746 case DW_AT_discr_list: return "DW_AT_discr_list";
8747 case DW_AT_encoding: return "DW_AT_encoding";
8748 case DW_AT_external: return "DW_AT_external";
8749 case DW_AT_frame_base: return "DW_AT_frame_base";
8750 case DW_AT_friend: return "DW_AT_friend";
8751 case DW_AT_identifier_case: return "DW_AT_identifier_case";
8752 case DW_AT_macro_info: return "DW_AT_macro_info";
8753 case DW_AT_namelist_items: return "DW_AT_namelist_items";
8754 case DW_AT_priority: return "DW_AT_priority";
8755 case DW_AT_segment: return "DW_AT_segment";
8756 case DW_AT_specification: return "DW_AT_specification";
8757 case DW_AT_static_link: return "DW_AT_static_link";
8758 case DW_AT_type: return "DW_AT_type";
8759 case DW_AT_use_location: return "DW_AT_use_location";
8760 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
8761 case DW_AT_virtuality: return "DW_AT_virtuality";
8762 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
8763 /* DWARF 2.1 values. */
8764 case DW_AT_allocated: return "DW_AT_allocated";
8765 case DW_AT_associated: return "DW_AT_associated";
8766 case DW_AT_data_location: return "DW_AT_data_location";
8767 case DW_AT_stride: return "DW_AT_stride";
8768 case DW_AT_entry_pc: return "DW_AT_entry_pc";
8769 case DW_AT_use_UTF8: return "DW_AT_use_UTF8";
8770 case DW_AT_extension: return "DW_AT_extension";
8771 case DW_AT_ranges: return "DW_AT_ranges";
8772 case DW_AT_trampoline: return "DW_AT_trampoline";
8773 case DW_AT_call_column: return "DW_AT_call_column";
8774 case DW_AT_call_file: return "DW_AT_call_file";
8775 case DW_AT_call_line: return "DW_AT_call_line";
8776 /* SGI/MIPS extensions. */
8777 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
8778 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
8779 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
8780 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
8781 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
8782 case DW_AT_MIPS_software_pipeline_depth:
8783 return "DW_AT_MIPS_software_pipeline_depth";
8784 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
8785 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
8786 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
8787 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
8788 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
8789 /* GNU extensions. */
8790 case DW_AT_sf_names: return "DW_AT_sf_names";
8791 case DW_AT_src_info: return "DW_AT_src_info";
8792 case DW_AT_mac_info: return "DW_AT_mac_info";
8793 case DW_AT_src_coords: return "DW_AT_src_coords";
8794 case DW_AT_body_begin: return "DW_AT_body_begin";
8795 case DW_AT_body_end: return "DW_AT_body_end";
8796 case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
8797 /* UPC extension. */
8798 case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled";
8799 default:
8800 {
8801 static char buffer[100];
8802
e9e44622
JJ
8803 snprintf (buffer, sizeof (buffer), _("Unknown AT value: %lx"),
8804 attribute);
5b18a4bc
NC
8805 return buffer;
8806 }
8807 }
8808}
eb6bd4d3 8809
5b18a4bc
NC
8810static unsigned char *
8811read_and_display_attr (unsigned long attribute,
8812 unsigned long form,
8813 unsigned char *data,
8814 unsigned long cu_offset,
8815 unsigned long pointer_size,
8816 unsigned long offset_size,
8817 int dwarf_version,
8818 debug_info *debug_info_p,
8819 int do_loc)
8820{
8821 if (!do_loc)
8822 printf (" %-18s:", get_AT_name (attribute));
8823 data = read_and_display_attr_value (attribute, form, data, cu_offset,
8824 pointer_size, offset_size,
8825 dwarf_version, debug_info_p,
8826 do_loc);
8827 if (!do_loc)
8828 printf ("\n");
8829 return data;
8830}
eb6bd4d3 8831
eb6bd4d3 8832
5b18a4bc
NC
8833/* Process the contents of a .debug_info section. If do_loc is non-zero
8834 then we are scanning for location lists and we do not want to display
8835 anything to the user. */
eb6bd4d3 8836
5b18a4bc
NC
8837static int
8838process_debug_info (Elf_Internal_Shdr *section, unsigned char *start,
8839 FILE *file, int do_loc)
8840{
8841 unsigned char *end = start + section->sh_size;
8842 unsigned char *section_begin;
8843 unsigned int unit;
8844 unsigned int num_units = 0;
065c959b 8845
0853c092 8846 if ((do_loc || do_debug_loc || do_debug_ranges)
5b18a4bc
NC
8847 && num_debug_info_entries == 0)
8848 {
8849 unsigned long length;
12ab83a9 8850
5b18a4bc
NC
8851 /* First scan the section to get the number of comp units. */
8852 for (section_begin = start, num_units = 0; section_begin < end;
8853 num_units ++)
8854 {
8855 /* Read the first 4 bytes. For a 32-bit DWARF section, this
8856 will be the length. For a 64-bit DWARF section, it'll be
8857 the escape code 0xffffffff followed by an 8 byte length. */
8858 length = byte_get (section_begin, 4);
8859
8860 if (length == 0xffffffff)
8861 {
8862 length = byte_get (section_begin + 4, 8);
8863 section_begin += length + 12;
8864 }
eb6bd4d3 8865 else
5b18a4bc 8866 section_begin += length + 4;
eb6bd4d3 8867 }
12ab83a9 8868
5b18a4bc
NC
8869 if (num_units == 0)
8870 {
8871 error (_("No comp units in .debug_info section ?"));
8872 return 0;
8873 }
8874
8875 /* Then allocate an array to hold the information. */
c256ffe7
JJ
8876 debug_information = cmalloc (num_units,
8877 sizeof (* debug_information));
5b18a4bc
NC
8878 if (debug_information == NULL)
8879 {
8880 error (_("Not enough memory for a debug info array of %u entries"),
8881 num_units);
8882 return 0;
8883 }
252b5132 8884 }
252b5132 8885
5b18a4bc
NC
8886 if (!do_loc)
8887 {
8888 printf (_("The section %s contains:\n\n"),
8889 SECTION_NAME (section));
a2f14207 8890
5b18a4bc
NC
8891 load_debug_str (file);
8892 load_debug_loc (file);
8893 load_debug_range (file);
8894 }
a2f14207 8895
5b18a4bc
NC
8896 for (section_begin = start, unit = 0; start < end; unit++)
8897 {
8898 DWARF2_Internal_CompUnit compunit;
8899 unsigned char *hdrptr;
8900 unsigned char *cu_abbrev_offset_ptr;
8901 unsigned char *tags;
8902 int level;
8903 unsigned long cu_offset;
8904 int offset_size;
8905 int initial_length_size;
a2f14207 8906
5b18a4bc 8907 hdrptr = start;
a2f14207 8908
5b18a4bc
NC
8909 compunit.cu_length = byte_get (hdrptr, 4);
8910 hdrptr += 4;
a2f14207 8911
5b18a4bc
NC
8912 if (compunit.cu_length == 0xffffffff)
8913 {
8914 compunit.cu_length = byte_get (hdrptr, 8);
8915 hdrptr += 8;
8916 offset_size = 8;
8917 initial_length_size = 12;
8918 }
8919 else
8920 {
8921 offset_size = 4;
8922 initial_length_size = 4;
8923 }
a2f14207 8924
5b18a4bc
NC
8925 compunit.cu_version = byte_get (hdrptr, 2);
8926 hdrptr += 2;
8927
8928 cu_offset = start - section_begin;
8929 start += compunit.cu_length + initial_length_size;
a2f14207 8930
5b18a4bc
NC
8931 if (elf_header.e_type == ET_REL
8932 && !debug_apply_rela_addends (file, section, offset_size,
8933 section_begin, hdrptr, start))
8934 return 0;
a2f14207 8935
5b18a4bc
NC
8936 cu_abbrev_offset_ptr = hdrptr;
8937 compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size);
8938 hdrptr += offset_size;
a2f14207 8939
5b18a4bc
NC
8940 compunit.cu_pointer_size = byte_get (hdrptr, 1);
8941 hdrptr += 1;
0853c092 8942 if ((do_loc || do_debug_loc || do_debug_ranges)
5b18a4bc
NC
8943 && num_debug_info_entries == 0)
8944 {
8945 debug_information [unit].cu_offset = cu_offset;
8946 debug_information [unit].pointer_size
8947 = compunit.cu_pointer_size;
b38c7015 8948 debug_information [unit].base_address = 0;
5b18a4bc 8949 debug_information [unit].loc_offsets = NULL;
b38c7015 8950 debug_information [unit].have_frame_base = NULL;
5b18a4bc
NC
8951 debug_information [unit].max_loc_offsets = 0;
8952 debug_information [unit].num_loc_offsets = 0;
0853c092
L
8953 debug_information [unit].range_lists = NULL;
8954 debug_information [unit].max_range_lists= 0;
8955 debug_information [unit].num_range_lists = 0;
5b18a4bc 8956 }
53c7db4b 8957
5b18a4bc 8958 tags = hdrptr;
065c959b 8959
5b18a4bc
NC
8960 if (!do_loc)
8961 {
41a865ba 8962 printf (_(" Compilation Unit @ offset 0x%lx:\n"), cu_offset);
5b18a4bc
NC
8963 printf (_(" Length: %ld\n"), compunit.cu_length);
8964 printf (_(" Version: %d\n"), compunit.cu_version);
8965 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
8966 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
8967 }
065c959b 8968
5b18a4bc
NC
8969 if (compunit.cu_version != 2 && compunit.cu_version != 3)
8970 {
8971 warn (_("Only version 2 and 3 DWARF debug information is currently supported.\n"));
8972 continue;
8973 }
d9296b18 8974
5b18a4bc 8975 free_abbrevs ();
065c959b 8976
5b18a4bc
NC
8977 /* Read in the abbrevs used by this compilation unit. */
8978 {
8979 Elf_Internal_Shdr *sec;
8980 unsigned char *begin;
a2f14207 8981
5b18a4bc
NC
8982 /* Locate the .debug_abbrev section and process it. */
8983 sec = find_section (".debug_abbrev");
8984 if (sec == NULL)
8985 {
8986 warn (_("Unable to locate .debug_abbrev section!\n"));
8987 return 0;
8988 }
a2f14207 8989
c256ffe7 8990 begin = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
5b18a4bc
NC
8991 _("debug_abbrev section data"));
8992 if (!begin)
8993 return 0;
76a56260 8994
5b18a4bc
NC
8995 process_abbrev_section (begin + compunit.cu_abbrev_offset,
8996 begin + sec->sh_size);
8997
8998 free (begin);
8999 }
0e0c4098 9000
5b18a4bc
NC
9001 level = 0;
9002 while (tags < start)
a2f14207 9003 {
dc3c06c2 9004 unsigned int bytes_read;
5b18a4bc
NC
9005 unsigned long abbrev_number;
9006 abbrev_entry *entry;
9007 abbrev_attr *attr;
53c7db4b 9008
5b18a4bc
NC
9009 abbrev_number = read_leb128 (tags, & bytes_read, 0);
9010 tags += bytes_read;
53c7db4b 9011
5b18a4bc
NC
9012 /* A null DIE marks the end of a list of children. */
9013 if (abbrev_number == 0)
9014 {
9015 --level;
9016 continue;
9017 }
8dde85fc 9018
5b18a4bc
NC
9019 /* Scan through the abbreviation list until we reach the
9020 correct entry. */
9021 for (entry = first_abbrev;
9022 entry && entry->entry != abbrev_number;
9023 entry = entry->next)
9024 continue;
53c7db4b 9025
5b18a4bc
NC
9026 if (entry == NULL)
9027 {
9028 warn (_("Unable to locate entry %lu in the abbreviation table\n"),
9029 abbrev_number);
9030 return 0;
9031 }
53c7db4b 9032
5b18a4bc
NC
9033 if (!do_loc)
9034 printf (_(" <%d><%lx>: Abbrev Number: %lu (%s)\n"),
9035 level,
9036 (unsigned long) (tags - section_begin
9037 - bytes_read),
9038 abbrev_number,
9039 get_TAG_name (entry->tag));
9040
b38c7015
L
9041 switch (entry->tag)
9042 {
9043 default:
9044 need_base_address = 0;
9045 break;
9046 case DW_TAG_compile_unit:
9047 need_base_address = 1;
b38c7015
L
9048 break;
9049 case DW_TAG_entry_point:
9050 case DW_TAG_inlined_subroutine:
9051 case DW_TAG_subprogram:
9052 need_base_address = 0;
9053 /* Assuming that there is no DW_AT_frame_base. */
9054 have_frame_base = 0;
9055 break;
9056 }
9057
5b18a4bc
NC
9058 for (attr = entry->first_attr; attr; attr = attr->next)
9059 tags = read_and_display_attr (attr->attribute,
9060 attr->form,
9061 tags, cu_offset,
9062 compunit.cu_pointer_size,
9063 offset_size,
9064 compunit.cu_version,
9065 &debug_information [unit],
9066 do_loc);
9067
9068 if (entry->children)
9069 ++level;
9070 }
9071 }
9072
0853c092 9073 /* Set num_debug_info_entries here so that it can be used to check if
f59f7c79 9074 we need to process .debug_loc and .debug_ranges sections. */
0853c092 9075 if ((do_loc || do_debug_loc || do_debug_ranges)
5b18a4bc
NC
9076 && num_debug_info_entries == 0)
9077 num_debug_info_entries = num_units;
9078
9079 if (!do_loc)
9080 {
9081 free_debug_range ();
9082 free_debug_str ();
9083 free_debug_loc ();
53c7db4b 9084
a2f14207
DB
9085 printf ("\n");
9086 }
5b18a4bc 9087
a2f14207
DB
9088 return 1;
9089}
252b5132 9090
5b18a4bc
NC
9091/* Retrieve the pointer size associated with the given compilation unit.
9092 Optionally the offset of this unit into the .debug_info section is
9093 also retutned. If there is no .debug_info section then an error
9094 message is issued and 0 is returned. If the requested comp unit has
9095 not been defined in the .debug_info section then a warning message
9096 is issued and the last know pointer size is returned. This message
9097 is only issued once per section dumped per file dumped. */
261a45ad 9098
5b18a4bc
NC
9099static unsigned int
9100get_pointer_size_and_offset_of_comp_unit (unsigned int comp_unit,
9101 const char * section_name,
9102 unsigned long * offset_return)
261a45ad 9103{
5b18a4bc 9104 unsigned long offset = 0;
261a45ad 9105
5b18a4bc
NC
9106 if (num_debug_info_entries == 0)
9107 error (_("%s section needs a populated .debug_info section\n"),
9108 section_name);
261a45ad 9109
5b18a4bc
NC
9110 else if (comp_unit >= num_debug_info_entries)
9111 {
9112 if (!warned_about_missing_comp_units)
9113 {
9114 warn (_("%s section has more comp units than .debug_info section\n"),
9115 section_name);
9116 warn (_("assuming that the pointer size is %d, from the last comp unit in .debug_info\n\n"),
9117 last_pointer_size);
9118 warned_about_missing_comp_units = TRUE;
9119 }
9120 }
9121 else
9122 {
9123 last_pointer_size = debug_information [comp_unit].pointer_size;
9124 offset = debug_information [comp_unit].cu_offset;
9125 }
261a45ad 9126
5b18a4bc
NC
9127 if (offset_return != NULL)
9128 * offset_return = offset;
261a45ad 9129
5b18a4bc 9130 return last_pointer_size;
261a45ad
NC
9131}
9132
5b18a4bc
NC
9133/* Locate and scan the .debug_info section in the file and record the pointer
9134 sizes and offsets for the compilation units in it. Usually an executable
9135 will have just one pointer size, but this is not guaranteed, and so we try
9136 not to make any assumptions. Returns zero upon failure, or the number of
9137 compilation units upon success. */
9138
9139static unsigned int
9140get_debug_info (FILE * file)
261a45ad 9141{
5b18a4bc
NC
9142 Elf_Internal_Shdr * section;
9143 unsigned char * start;
9144 int ret;
261a45ad 9145
5b18a4bc
NC
9146 /* Reset the last pointer size so that we can issue correct error
9147 messages if we are displaying the contents of more than one section. */
9148 last_pointer_size = 0;
9149 warned_about_missing_comp_units = FALSE;
261a45ad 9150
5b18a4bc
NC
9151 /* If we already have the information there is nothing else to do. */
9152 if (num_debug_info_entries > 0)
9153 return num_debug_info_entries;
261a45ad 9154
5b18a4bc
NC
9155 section = find_section (".debug_info");
9156 if (section == NULL)
9157 return 0;
261a45ad 9158
c256ffe7 9159 start = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
5b18a4bc
NC
9160 _("extracting information from .debug_info section"));
9161 if (start == NULL)
9162 return 0;
9163
9164 ret = process_debug_info (section, start, file, 1);
9165 free (start);
9166
9167 return ret ? num_debug_info_entries : 0;
261a45ad
NC
9168}
9169
261a45ad 9170static int
5b18a4bc
NC
9171display_debug_lines (Elf_Internal_Shdr *section,
9172 unsigned char *start, FILE *file)
261a45ad 9173{
5b18a4bc
NC
9174 unsigned char *data = start;
9175 unsigned char *end = start + section->sh_size;
9176 unsigned int comp_unit = 0;
261a45ad 9177
5b18a4bc
NC
9178 printf (_("\nDump of debug contents of section %s:\n\n"),
9179 SECTION_NAME (section));
261a45ad 9180
5b18a4bc
NC
9181 get_debug_info (file);
9182
9183 while (data < end)
261a45ad 9184 {
5b18a4bc
NC
9185 DWARF2_Internal_LineInfo info;
9186 unsigned char *standard_opcodes;
9187 unsigned char *end_of_sequence;
9188 unsigned char *hdrptr;
9189 unsigned int pointer_size;
9190 int initial_length_size;
9191 int offset_size;
9192 int i;
9193
9194 hdrptr = data;
9195
9196 /* Check the length of the block. */
9197 info.li_length = byte_get (hdrptr, 4);
9198 hdrptr += 4;
9199
9200 if (info.li_length == 0xffffffff)
9201 {
9202 /* This section is 64-bit DWARF 3. */
9203 info.li_length = byte_get (hdrptr, 8);
9204 hdrptr += 8;
9205 offset_size = 8;
9206 initial_length_size = 12;
9207 }
9208 else
9209 {
9210 offset_size = 4;
9211 initial_length_size = 4;
9212 }
9213
9214 if (info.li_length + initial_length_size > section->sh_size)
9215 {
9216 warn
9217 (_("The line info appears to be corrupt - the section is too small\n"));
9218 return 0;
9219 }
9220
9221 /* Check its version number. */
9222 info.li_version = byte_get (hdrptr, 2);
9223 hdrptr += 2;
9224 if (info.li_version != 2 && info.li_version != 3)
9225 {
9226 warn (_("Only DWARF version 2 and 3 line info is currently supported.\n"));
9227 return 0;
9228 }
9229
9230 info.li_prologue_length = byte_get (hdrptr, offset_size);
9231 hdrptr += offset_size;
9232 info.li_min_insn_length = byte_get (hdrptr, 1);
9233 hdrptr++;
9234 info.li_default_is_stmt = byte_get (hdrptr, 1);
9235 hdrptr++;
9236 info.li_line_base = byte_get (hdrptr, 1);
9237 hdrptr++;
9238 info.li_line_range = byte_get (hdrptr, 1);
9239 hdrptr++;
9240 info.li_opcode_base = byte_get (hdrptr, 1);
9241 hdrptr++;
261a45ad 9242
5b18a4bc
NC
9243 /* Sign extend the line base field. */
9244 info.li_line_base <<= 24;
9245 info.li_line_base >>= 24;
261a45ad 9246
5b18a4bc
NC
9247 /* Get the pointer size from the comp unit associated
9248 with this block of line number information. */
9249 pointer_size = get_pointer_size_and_offset_of_comp_unit
41a865ba 9250 (comp_unit, ".debug_line", NULL);
5b18a4bc 9251 comp_unit ++;
261a45ad 9252
5b18a4bc
NC
9253 printf (_(" Length: %ld\n"), info.li_length);
9254 printf (_(" DWARF Version: %d\n"), info.li_version);
9255 printf (_(" Prologue Length: %d\n"), info.li_prologue_length);
9256 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
9257 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
9258 printf (_(" Line Base: %d\n"), info.li_line_base);
9259 printf (_(" Line Range: %d\n"), info.li_line_range);
9260 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
52d1fb02
NC
9261 printf (_(" (Pointer size: %u)%s\n"),
9262 pointer_size,
9263 warned_about_missing_comp_units ? " [assumed]" : "" );
261a45ad 9264
5b18a4bc 9265 end_of_sequence = data + info.li_length + initial_length_size;
261a45ad 9266
5b18a4bc 9267 reset_state_machine (info.li_default_is_stmt);
261a45ad 9268
5b18a4bc
NC
9269 /* Display the contents of the Opcodes table. */
9270 standard_opcodes = hdrptr;
261a45ad 9271
5b18a4bc 9272 printf (_("\n Opcodes:\n"));
261a45ad 9273
5b18a4bc
NC
9274 for (i = 1; i < info.li_opcode_base; i++)
9275 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
261a45ad 9276
5b18a4bc
NC
9277 /* Display the contents of the Directory table. */
9278 data = standard_opcodes + info.li_opcode_base - 1;
261a45ad 9279
5b18a4bc
NC
9280 if (*data == 0)
9281 printf (_("\n The Directory Table is empty.\n"));
9282 else
9283 {
9284 printf (_("\n The Directory Table:\n"));
261a45ad 9285
5b18a4bc
NC
9286 while (*data != 0)
9287 {
9288 printf (_(" %s\n"), data);
18bd398b 9289
5b18a4bc
NC
9290 data += strlen ((char *) data) + 1;
9291 }
9292 }
18bd398b 9293
5b18a4bc
NC
9294 /* Skip the NUL at the end of the table. */
9295 data++;
18bd398b 9296
5b18a4bc
NC
9297 /* Display the contents of the File Name table. */
9298 if (*data == 0)
9299 printf (_("\n The File Name Table is empty.\n"));
9300 else
9301 {
9302 printf (_("\n The File Name Table:\n"));
9303 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
18bd398b 9304
5b18a4bc
NC
9305 while (*data != 0)
9306 {
9307 unsigned char *name;
dc3c06c2 9308 unsigned int bytes_read;
18bd398b 9309
5b18a4bc
NC
9310 printf (_(" %d\t"), ++state_machine_regs.last_file_entry);
9311 name = data;
18bd398b 9312
5b18a4bc 9313 data += strlen ((char *) data) + 1;
18bd398b 9314
5b18a4bc
NC
9315 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
9316 data += bytes_read;
9317 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
9318 data += bytes_read;
9319 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
9320 data += bytes_read;
9321 printf (_("%s\n"), name);
9322 }
9323 }
18bd398b 9324
5b18a4bc
NC
9325 /* Skip the NUL at the end of the table. */
9326 data++;
18bd398b 9327
5b18a4bc
NC
9328 /* Now display the statements. */
9329 printf (_("\n Line Number Statements:\n"));
18bd398b 9330
5b18a4bc
NC
9331 while (data < end_of_sequence)
9332 {
9333 unsigned char op_code;
9334 int adv;
dc3c06c2 9335 unsigned int bytes_read;
18bd398b 9336
5b18a4bc 9337 op_code = *data++;
18bd398b 9338
5b18a4bc
NC
9339 if (op_code >= info.li_opcode_base)
9340 {
9341 op_code -= info.li_opcode_base;
9342 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
9343 state_machine_regs.address += adv;
9344 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
9345 op_code, adv, state_machine_regs.address);
9346 adv = (op_code % info.li_line_range) + info.li_line_base;
9347 state_machine_regs.line += adv;
9348 printf (_(" and Line by %d to %d\n"),
9349 adv, state_machine_regs.line);
9350 }
9351 else switch (op_code)
9352 {
9353 case DW_LNS_extended_op:
52d1fb02
NC
9354 if (pointer_size == 0)
9355 {
1ec742ac 9356 warn (_("Extend line ops need a valid pointer size, guessing at 4\n"));
52d1fb02
NC
9357 pointer_size = 4;
9358 }
9359
5b18a4bc 9360 data += process_extended_line_op (data, info.li_default_is_stmt,
41a865ba 9361 pointer_size);
5b18a4bc 9362 break;
18bd398b 9363
5b18a4bc
NC
9364 case DW_LNS_copy:
9365 printf (_(" Copy\n"));
9366 break;
18bd398b 9367
5b18a4bc
NC
9368 case DW_LNS_advance_pc:
9369 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
9370 data += bytes_read;
9371 state_machine_regs.address += adv;
9372 printf (_(" Advance PC by %d to %lx\n"), adv,
9373 state_machine_regs.address);
9374 break;
18bd398b 9375
5b18a4bc
NC
9376 case DW_LNS_advance_line:
9377 adv = read_leb128 (data, & bytes_read, 1);
9378 data += bytes_read;
9379 state_machine_regs.line += adv;
9380 printf (_(" Advance Line by %d to %d\n"), adv,
9381 state_machine_regs.line);
9382 break;
18bd398b 9383
5b18a4bc
NC
9384 case DW_LNS_set_file:
9385 adv = read_leb128 (data, & bytes_read, 0);
9386 data += bytes_read;
9387 printf (_(" Set File Name to entry %d in the File Name Table\n"),
9388 adv);
9389 state_machine_regs.file = adv;
9390 break;
18bd398b 9391
5b18a4bc
NC
9392 case DW_LNS_set_column:
9393 adv = read_leb128 (data, & bytes_read, 0);
9394 data += bytes_read;
9395 printf (_(" Set column to %d\n"), adv);
9396 state_machine_regs.column = adv;
9397 break;
18bd398b 9398
5b18a4bc
NC
9399 case DW_LNS_negate_stmt:
9400 adv = state_machine_regs.is_stmt;
9401 adv = ! adv;
9402 printf (_(" Set is_stmt to %d\n"), adv);
9403 state_machine_regs.is_stmt = adv;
9404 break;
18bd398b 9405
5b18a4bc
NC
9406 case DW_LNS_set_basic_block:
9407 printf (_(" Set basic block\n"));
9408 state_machine_regs.basic_block = 1;
9409 break;
18bd398b 9410
5b18a4bc
NC
9411 case DW_LNS_const_add_pc:
9412 adv = (((255 - info.li_opcode_base) / info.li_line_range)
9413 * info.li_min_insn_length);
9414 state_machine_regs.address += adv;
9415 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
9416 state_machine_regs.address);
9417 break;
18bd398b 9418
5b18a4bc
NC
9419 case DW_LNS_fixed_advance_pc:
9420 adv = byte_get (data, 2);
9421 data += 2;
9422 state_machine_regs.address += adv;
9423 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
9424 adv, state_machine_regs.address);
9425 break;
18bd398b 9426
5b18a4bc
NC
9427 case DW_LNS_set_prologue_end:
9428 printf (_(" Set prologue_end to true\n"));
9429 break;
18bd398b 9430
5b18a4bc
NC
9431 case DW_LNS_set_epilogue_begin:
9432 printf (_(" Set epilogue_begin to true\n"));
9433 break;
18bd398b 9434
5b18a4bc
NC
9435 case DW_LNS_set_isa:
9436 adv = read_leb128 (data, & bytes_read, 0);
9437 data += bytes_read;
9438 printf (_(" Set ISA to %d\n"), adv);
9439 break;
18bd398b 9440
5b18a4bc
NC
9441 default:
9442 printf (_(" Unknown opcode %d with operands: "), op_code);
18bd398b 9443
5b18a4bc
NC
9444 for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
9445 {
9446 printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
9447 i == 1 ? "" : ", ");
9448 data += bytes_read;
9449 }
9450 putchar ('\n');
9451 break;
9452 }
18bd398b 9453 }
5b18a4bc 9454 putchar ('\n');
18bd398b 9455 }
18bd398b 9456
5b18a4bc
NC
9457 return 1;
9458}
18bd398b 9459
5b18a4bc
NC
9460static int
9461display_debug_pubnames (Elf_Internal_Shdr *section,
9462 unsigned char *start,
9463 FILE *file ATTRIBUTE_UNUSED)
252b5132 9464{
5b18a4bc
NC
9465 DWARF2_Internal_PubNames pubnames;
9466 unsigned char *end;
252b5132 9467
5b18a4bc
NC
9468 end = start + section->sh_size;
9469
9470 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
9471
9472 while (start < end)
252b5132 9473 {
5b18a4bc
NC
9474 unsigned char *data;
9475 unsigned long offset;
9476 int offset_size, initial_length_size;
76da6bbe 9477
5b18a4bc
NC
9478 data = start;
9479
9480 pubnames.pn_length = byte_get (data, 4);
9481 data += 4;
9482 if (pubnames.pn_length == 0xffffffff)
ee42cf8c 9483 {
5b18a4bc
NC
9484 pubnames.pn_length = byte_get (data, 8);
9485 data += 8;
9486 offset_size = 8;
9487 initial_length_size = 12;
ee42cf8c
NC
9488 }
9489 else
ba2685cc 9490 {
5b18a4bc
NC
9491 offset_size = 4;
9492 initial_length_size = 4;
ee42cf8c 9493 }
252b5132 9494
5b18a4bc 9495 pubnames.pn_version = byte_get (data, 2);
252b5132 9496 data += 2;
5b18a4bc
NC
9497 pubnames.pn_offset = byte_get (data, offset_size);
9498 data += offset_size;
9499 pubnames.pn_size = byte_get (data, offset_size);
9500 data += offset_size;
252b5132 9501
5b18a4bc 9502 start += pubnames.pn_length + initial_length_size;
252b5132 9503
5b18a4bc
NC
9504 if (pubnames.pn_version != 2 && pubnames.pn_version != 3)
9505 {
9506 static int warned = 0;
252b5132 9507
5b18a4bc
NC
9508 if (! warned)
9509 {
9510 warn (_("Only DWARF 2 and 3 pubnames are currently supported\n"));
9511 warned = 1;
9512 }
252b5132 9513
5b18a4bc
NC
9514 continue;
9515 }
252b5132 9516
5b18a4bc
NC
9517 printf (_(" Length: %ld\n"),
9518 pubnames.pn_length);
9519 printf (_(" Version: %d\n"),
9520 pubnames.pn_version);
9521 printf (_(" Offset into .debug_info section: %ld\n"),
9522 pubnames.pn_offset);
9523 printf (_(" Size of area in .debug_info section: %ld\n"),
9524 pubnames.pn_size);
252b5132 9525
5b18a4bc 9526 printf (_("\n Offset\tName\n"));
ef5cdfc7 9527
5b18a4bc
NC
9528 do
9529 {
9530 offset = byte_get (data, offset_size);
252b5132 9531
5b18a4bc
NC
9532 if (offset != 0)
9533 {
9534 data += offset_size;
9535 printf (" %-6ld\t\t%s\n", offset, data);
9536 data += strlen ((char *) data) + 1;
9537 }
9538 }
9539 while (offset != 0);
252b5132
RH
9540 }
9541
5b18a4bc
NC
9542 printf ("\n");
9543 return 1;
9544}
9545
9546static int
9547display_debug_macinfo (Elf_Internal_Shdr *section,
9548 unsigned char *start,
9549 FILE *file ATTRIBUTE_UNUSED)
9550{
9551 unsigned char *end = start + section->sh_size;
9552 unsigned char *curr = start;
9553 unsigned int bytes_read;
9554 enum dwarf_macinfo_record_type op;
252b5132 9555
5b18a4bc 9556 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
252b5132 9557
5b18a4bc 9558 while (curr < end)
252b5132 9559 {
5b18a4bc
NC
9560 unsigned int lineno;
9561 const char *string;
9562
9563 op = *curr;
9564 curr++;
9565
9566 switch (op)
252b5132 9567 {
5b18a4bc
NC
9568 case DW_MACINFO_start_file:
9569 {
9570 unsigned int filenum;
9571
9572 lineno = read_leb128 (curr, & bytes_read, 0);
9573 curr += bytes_read;
9574 filenum = read_leb128 (curr, & bytes_read, 0);
9575 curr += bytes_read;
9576
9577 printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"),
9578 lineno, filenum);
9579 }
b34976b6 9580 break;
5b18a4bc
NC
9581
9582 case DW_MACINFO_end_file:
9583 printf (_(" DW_MACINFO_end_file\n"));
b34976b6 9584 break;
252b5132 9585
5b18a4bc
NC
9586 case DW_MACINFO_define:
9587 lineno = read_leb128 (curr, & bytes_read, 0);
9588 curr += bytes_read;
dc3c06c2 9589 string = (char *) curr;
5b18a4bc
NC
9590 curr += strlen (string) + 1;
9591 printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"),
9592 lineno, string);
b34976b6 9593 break;
252b5132 9594
5b18a4bc
NC
9595 case DW_MACINFO_undef:
9596 lineno = read_leb128 (curr, & bytes_read, 0);
9597 curr += bytes_read;
dc3c06c2 9598 string = (char *) curr;
5b18a4bc
NC
9599 curr += strlen (string) + 1;
9600 printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"),
9601 lineno, string);
252b5132 9602 break;
252b5132 9603
5b18a4bc
NC
9604 case DW_MACINFO_vendor_ext:
9605 {
9606 unsigned int constant;
9607
9608 constant = read_leb128 (curr, & bytes_read, 0);
9609 curr += bytes_read;
dc3c06c2 9610 string = (char *) curr;
5b18a4bc
NC
9611 curr += strlen (string) + 1;
9612 printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"),
9613 constant, string);
9614 }
b34976b6 9615 break;
252b5132 9616 }
5b18a4bc 9617 }
252b5132 9618
5b18a4bc
NC
9619 return 1;
9620}
252b5132 9621
252b5132 9622
5b18a4bc
NC
9623static int
9624display_debug_abbrev (Elf_Internal_Shdr *section,
9625 unsigned char *start,
9626 FILE *file ATTRIBUTE_UNUSED)
9627{
9628 abbrev_entry *entry;
9629 unsigned char *end = start + section->sh_size;
252b5132 9630
5b18a4bc 9631 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
252b5132 9632
5b18a4bc
NC
9633 do
9634 {
9635 start = process_abbrev_section (start, end);
12ab83a9 9636
5b18a4bc
NC
9637 if (first_abbrev == NULL)
9638 continue;
18bd398b 9639
5b18a4bc 9640 printf (_(" Number TAG\n"));
18bd398b 9641
5b18a4bc
NC
9642 for (entry = first_abbrev; entry; entry = entry->next)
9643 {
9644 abbrev_attr *attr;
18bd398b 9645
5b18a4bc
NC
9646 printf (_(" %ld %s [%s]\n"),
9647 entry->entry,
9648 get_TAG_name (entry->tag),
9649 entry->children ? _("has children") : _("no children"));
252b5132 9650
5b18a4bc
NC
9651 for (attr = entry->first_attr; attr; attr = attr->next)
9652 printf (_(" %-18s %s\n"),
9653 get_AT_name (attr->attribute),
9654 get_FORM_name (attr->form));
9655 }
252b5132 9656
5b18a4bc
NC
9657 free_abbrevs ();
9658 }
9659 while (start);
81766fca 9660
252b5132 9661 printf ("\n");
252b5132 9662
5b18a4bc
NC
9663 return 1;
9664}
d84de024
AM
9665
9666static int
5b18a4bc
NC
9667display_debug_loc (Elf_Internal_Shdr *section,
9668 unsigned char *start, FILE *file)
d84de024 9669{
5b18a4bc
NC
9670 unsigned char *section_end;
9671 unsigned long bytes;
9672 unsigned char *section_begin = start;
5b18a4bc
NC
9673 unsigned int num_loc_list = 0;
9674 unsigned long last_offset = 0;
9675 unsigned int first = 0;
9676 unsigned int i;
9677 unsigned int j;
9678 int seen_first_offset = 0;
9679 int use_debug_info = 1;
9680 unsigned char *next;
d84de024 9681
5b18a4bc
NC
9682 bytes = section->sh_size;
9683 section_end = start + bytes;
d84de024 9684
5b18a4bc 9685 if (bytes == 0)
d84de024 9686 {
5b18a4bc
NC
9687 printf (_("\nThe .debug_loc section is empty.\n"));
9688 return 0;
9689 }
d84de024 9690
5b18a4bc 9691 get_debug_info (file);
d84de024 9692
5b18a4bc
NC
9693 /* Check the order of location list in .debug_info section. If
9694 offsets of location lists are in the ascending order, we can
9695 use `debug_information' directly. */
9696 for (i = 0; i < num_debug_info_entries; i++)
9697 {
9698 unsigned int num;
d84de024 9699
5b18a4bc
NC
9700 num = debug_information [i].num_loc_offsets;
9701 num_loc_list += num;
d84de024 9702
5b18a4bc
NC
9703 /* Check if we can use `debug_information' directly. */
9704 if (use_debug_info && num != 0)
d84de024 9705 {
5b18a4bc 9706 if (!seen_first_offset)
d84de024 9707 {
5b18a4bc
NC
9708 /* This is the first location list. */
9709 last_offset = debug_information [i].loc_offsets [0];
9710 first = i;
9711 seen_first_offset = 1;
9712 j = 1;
d84de024
AM
9713 }
9714 else
5b18a4bc 9715 j = 0;
d84de024 9716
5b18a4bc
NC
9717 for (; j < num; j++)
9718 {
9719 if (last_offset >
9720 debug_information [i].loc_offsets [j])
d84de024 9721 {
5b18a4bc
NC
9722 use_debug_info = 0;
9723 break;
d84de024 9724 }
5b18a4bc 9725 last_offset = debug_information [i].loc_offsets [j];
d84de024 9726 }
d84de024 9727 }
d84de024 9728 }
d84de024 9729
5b18a4bc
NC
9730 if (!use_debug_info)
9731 /* FIXME: Should we handle this case? */
9732 error (_("Location lists in .debug_info section aren't in ascending order!\n"));
252b5132 9733
5b18a4bc
NC
9734 if (!seen_first_offset)
9735 error (_("No location lists in .debug_info section!\n"));
252b5132 9736
5b18a4bc
NC
9737 if (debug_information [first].loc_offsets [0] != 0)
9738 warn (_("Location lists in .debug_loc section start at 0x%lx\n"),
9739 debug_information [first].loc_offsets [0]);
ef5cdfc7 9740
5b18a4bc
NC
9741 printf (_("Contents of the .debug_loc section:\n\n"));
9742 printf (_(" Offset Begin End Expression\n"));
9743
9744 seen_first_offset = 0;
9745 for (i = first; i < num_debug_info_entries; i++)
252b5132 9746 {
5b18a4bc
NC
9747 unsigned long begin;
9748 unsigned long end;
9749 unsigned short length;
9750 unsigned long offset;
9751 unsigned int pointer_size;
b34976b6 9752 unsigned long cu_offset;
b38c7015
L
9753 unsigned long base_address;
9754 int need_frame_base;
9755 int has_frame_base;
252b5132 9756
5b18a4bc
NC
9757 pointer_size = debug_information [i].pointer_size;
9758 cu_offset = debug_information [i].cu_offset;
252b5132 9759
5b18a4bc 9760 for (j = 0; j < debug_information [i].num_loc_offsets; j++)
428409d5 9761 {
b38c7015 9762 has_frame_base = debug_information [i].have_frame_base [j];
5b18a4bc
NC
9763 offset = debug_information [i].loc_offsets [j];
9764 next = section_begin + offset;
b38c7015 9765 base_address = debug_information [i].base_address;
428409d5 9766
5b18a4bc
NC
9767 if (!seen_first_offset)
9768 seen_first_offset = 1;
9769 else
9770 {
9771 if (start < next)
9772 warn (_("There is a hole [0x%lx - 0x%lx] in .debug_loc section.\n"),
b0660586 9773 start - section_begin, next - section_begin);
5b18a4bc
NC
9774 else if (start > next)
9775 warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_loc section.\n"),
b0660586 9776 start - section_begin, next - section_begin);
5b18a4bc
NC
9777 }
9778 start = next;
ee42cf8c 9779
c256ffe7
JJ
9780 if (offset >= bytes)
9781 {
9782 warn (_("Offset 0x%lx is bigger than .debug_loc section size.\n"),
9783 offset);
9784 continue;
9785 }
9786
5b18a4bc
NC
9787 while (1)
9788 {
c256ffe7
JJ
9789 if (start + 2 * pointer_size > section_end)
9790 {
9791 warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
9792 offset);
9793 break;
9794 }
9795
5b18a4bc
NC
9796 begin = byte_get (start, pointer_size);
9797 start += pointer_size;
9798 end = byte_get (start, pointer_size);
9799 start += pointer_size;
c0e047e0 9800
5b18a4bc 9801 if (begin == 0 && end == 0)
904c75ac
L
9802 {
9803 printf (_(" %8.8lx <End of list>\n"), offset);
9804 break;
9805 }
c0e047e0 9806
b38c7015
L
9807 /* Check base address specifiers. */
9808 if (begin == -1UL && end != -1UL)
9809 {
9810 base_address = end;
c256ffe7 9811 printf (_(" %8.8lx %8.8lx %8.8lx (base address)\n"),
e54b12b7 9812 offset, begin, end);
b38c7015
L
9813 continue;
9814 }
adab8cdc 9815
c256ffe7
JJ
9816 if (start + 2 > section_end)
9817 {
9818 warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
9819 offset);
9820 break;
9821 }
9822
5b18a4bc
NC
9823 length = byte_get (start, 2);
9824 start += 2;
252b5132 9825
c256ffe7
JJ
9826 if (start + length > section_end)
9827 {
9828 warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
9829 offset);
9830 break;
9831 }
9832
5b18a4bc 9833 printf (" %8.8lx %8.8lx %8.8lx (",
b38c7015
L
9834 offset, begin + base_address, end + base_address);
9835 need_frame_base = decode_location_expression (start,
9836 pointer_size,
9837 length,
9838 cu_offset);
9839 putchar (')');
09fd7e38 9840
b38c7015
L
9841 if (need_frame_base && !has_frame_base)
9842 printf (_(" [without DW_AT_frame_base]"));
9843
9844 if (begin == end)
9845 fputs (_(" (start == end)"), stdout);
9846 else if (begin > end)
9847 fputs (_(" (start > end)"), stdout);
9848
9849 putchar ('\n');
252b5132 9850
5b18a4bc
NC
9851 start += length;
9852 }
5b18a4bc
NC
9853 }
9854 }
9855 return 1;
9856}
252b5132 9857
5b18a4bc
NC
9858static int
9859display_debug_str (Elf_Internal_Shdr *section,
9860 unsigned char *start,
9861 FILE *file ATTRIBUTE_UNUSED)
9862{
9863 unsigned long bytes;
9864 bfd_vma addr;
252b5132 9865
5b18a4bc
NC
9866 addr = section->sh_addr;
9867 bytes = section->sh_size;
252b5132 9868
5b18a4bc
NC
9869 if (bytes == 0)
9870 {
9871 printf (_("\nThe .debug_str section is empty.\n"));
9872 return 0;
9873 }
252b5132 9874
5b18a4bc 9875 printf (_("Contents of the .debug_str section:\n\n"));
252b5132 9876
5b18a4bc
NC
9877 while (bytes)
9878 {
9879 int j;
9880 int k;
9881 int lbytes;
252b5132 9882
5b18a4bc 9883 lbytes = (bytes > 16 ? 16 : bytes);
252b5132 9884
5b18a4bc 9885 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132 9886
5b18a4bc
NC
9887 for (j = 0; j < 16; j++)
9888 {
9889 if (j < lbytes)
9890 printf ("%2.2x", start[j]);
9891 else
9892 printf (" ");
252b5132 9893
5b18a4bc
NC
9894 if ((j & 3) == 3)
9895 printf (" ");
9896 }
252b5132 9897
5b18a4bc
NC
9898 for (j = 0; j < lbytes; j++)
9899 {
9900 k = start[j];
9901 if (k >= ' ' && k < 0x80)
9902 printf ("%c", k);
9903 else
9904 printf (".");
9905 }
252b5132 9906
5b18a4bc 9907 putchar ('\n');
252b5132 9908
5b18a4bc
NC
9909 start += lbytes;
9910 addr += lbytes;
9911 bytes -= lbytes;
252b5132
RH
9912 }
9913
b0660586
L
9914 putchar ('\n');
9915
5b18a4bc
NC
9916 return 1;
9917}
ef5cdfc7 9918
252b5132 9919
5b18a4bc
NC
9920static int
9921display_debug_info (Elf_Internal_Shdr * section,
9922 unsigned char * start, FILE * file)
9923{
9924 return process_debug_info (section, start, file, 0);
252b5132
RH
9925}
9926
5b18a4bc 9927
252b5132 9928static int
d3ba0551
AM
9929display_debug_aranges (Elf_Internal_Shdr *section,
9930 unsigned char *start,
9931 FILE *file ATTRIBUTE_UNUSED)
252b5132 9932{
b34976b6 9933 unsigned char *end = start + section->sh_size;
252b5132
RH
9934
9935 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
9936
9937 while (start < end)
9938 {
ee42cf8c 9939 unsigned char *hdrptr;
b34976b6
AM
9940 DWARF2_Internal_ARange arange;
9941 unsigned char *ranges;
9942 unsigned long length;
9943 unsigned long address;
9944 int excess;
ee42cf8c
NC
9945 int offset_size;
9946 int initial_length_size;
252b5132 9947
ee42cf8c 9948 hdrptr = start;
252b5132 9949
ee42cf8c
NC
9950 arange.ar_length = byte_get (hdrptr, 4);
9951 hdrptr += 4;
252b5132 9952
e414a165
NC
9953 if (arange.ar_length == 0xffffffff)
9954 {
ee42cf8c
NC
9955 arange.ar_length = byte_get (hdrptr, 8);
9956 hdrptr += 8;
9957 offset_size = 8;
9958 initial_length_size = 12;
9959 }
9960 else
ba2685cc 9961 {
ee42cf8c
NC
9962 offset_size = 4;
9963 initial_length_size = 4;
e414a165
NC
9964 }
9965
ee42cf8c
NC
9966 arange.ar_version = byte_get (hdrptr, 2);
9967 hdrptr += 2;
9968
9969 arange.ar_info_offset = byte_get (hdrptr, offset_size);
9970 hdrptr += offset_size;
9971
9972 arange.ar_pointer_size = byte_get (hdrptr, 1);
9973 hdrptr += 1;
9974
9975 arange.ar_segment_size = byte_get (hdrptr, 1);
9976 hdrptr += 1;
9977
9978 if (arange.ar_version != 2 && arange.ar_version != 3)
3f215a10 9979 {
ee42cf8c 9980 warn (_("Only DWARF 2 and 3 aranges are currently supported.\n"));
3f215a10
NC
9981 break;
9982 }
9983
252b5132
RH
9984 printf (_(" Length: %ld\n"), arange.ar_length);
9985 printf (_(" Version: %d\n"), arange.ar_version);
9986 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
9987 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
9988 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
9989
9990 printf (_("\n Address Length\n"));
9991
ee42cf8c 9992 ranges = hdrptr;
252b5132 9993
7a4b7442 9994 /* Must pad to an alignment boundary that is twice the pointer size. */
ee42cf8c 9995 excess = (hdrptr - start) % (2 * arange.ar_pointer_size);
7a4b7442
NC
9996 if (excess)
9997 ranges += (2 * arange.ar_pointer_size) - excess;
9998
252b5132
RH
9999 for (;;)
10000 {
10001 address = byte_get (ranges, arange.ar_pointer_size);
10002
252b5132
RH
10003 ranges += arange.ar_pointer_size;
10004
10005 length = byte_get (ranges, arange.ar_pointer_size);
10006
10007 ranges += arange.ar_pointer_size;
10008
7a4b7442
NC
10009 /* A pair of zeros marks the end of the list. */
10010 if (address == 0 && length == 0)
10011 break;
103f02d3 10012
252b5132
RH
10013 printf (" %8.8lx %lu\n", address, length);
10014 }
10015
ee42cf8c 10016 start += arange.ar_length + initial_length_size;
252b5132
RH
10017 }
10018
10019 printf ("\n");
10020
10021 return 1;
10022}
10023
18bd398b 10024static int
0853c092
L
10025display_debug_ranges (Elf_Internal_Shdr *section,
10026 unsigned char *start,
10027 FILE *file ATTRIBUTE_UNUSED)
18bd398b 10028{
0853c092
L
10029 unsigned char *section_end;
10030 unsigned long bytes;
10031 unsigned char *section_begin = start;
10032 unsigned int num_range_list = 0;
10033 unsigned long last_offset = 0;
10034 unsigned int first = 0;
10035 unsigned int i;
10036 unsigned int j;
10037 int seen_first_offset = 0;
10038 int use_debug_info = 1;
10039 unsigned char *next;
18bd398b 10040
0853c092
L
10041 bytes = section->sh_size;
10042 section_end = start + bytes;
10043
10044 if (bytes == 0)
18bd398b 10045 {
0853c092
L
10046 printf (_("\nThe .debug_ranges section is empty.\n"));
10047 return 0;
10048 }
18bd398b 10049
0853c092 10050 get_debug_info (file);
18bd398b 10051
0853c092
L
10052 /* Check the order of range list in .debug_info section. If
10053 offsets of range lists are in the ascending order, we can
10054 use `debug_information' directly. */
10055 for (i = 0; i < num_debug_info_entries; i++)
10056 {
10057 unsigned int num;
10058
10059 num = debug_information [i].num_range_lists;
10060 num_range_list += num;
10061
10062 /* Check if we can use `debug_information' directly. */
10063 if (use_debug_info && num != 0)
18bd398b 10064 {
0853c092
L
10065 if (!seen_first_offset)
10066 {
10067 /* This is the first range list. */
10068 last_offset = debug_information [i].range_lists [0];
10069 first = i;
10070 seen_first_offset = 1;
10071 j = 1;
10072 }
10073 else
10074 j = 0;
18bd398b 10075
0853c092
L
10076 for (; j < num; j++)
10077 {
10078 if (last_offset >
10079 debug_information [i].range_lists [j])
10080 {
10081 use_debug_info = 0;
10082 break;
10083 }
10084 last_offset = debug_information [i].range_lists [j];
10085 }
10086 }
18bd398b
NC
10087 }
10088
0853c092
L
10089 if (!use_debug_info)
10090 /* FIXME: Should we handle this case? */
10091 error (_("Range lists in .debug_info section aren't in ascending order!\n"));
18bd398b 10092
0853c092
L
10093 if (!seen_first_offset)
10094 error (_("No range lists in .debug_info section!\n"));
18bd398b 10095
0853c092
L
10096 if (debug_information [first].range_lists [0] != 0)
10097 warn (_("Range lists in .debug_ranges section start at 0x%lx\n"),
10098 debug_information [first].range_lists [0]);
18bd398b 10099
0853c092
L
10100 printf (_("Contents of the .debug_ranges section:\n\n"));
10101 printf (_(" Offset Begin End\n"));
10102
10103 seen_first_offset = 0;
10104 for (i = first; i < num_debug_info_entries; i++)
18bd398b 10105 {
0853c092
L
10106 unsigned long begin;
10107 unsigned long end;
10108 unsigned long offset;
10109 unsigned int pointer_size;
10110 unsigned long base_address;
18bd398b 10111
0853c092 10112 pointer_size = debug_information [i].pointer_size;
18bd398b 10113
0853c092 10114 for (j = 0; j < debug_information [i].num_range_lists; j++)
18bd398b 10115 {
0853c092
L
10116 offset = debug_information [i].range_lists [j];
10117 next = section_begin + offset;
10118 base_address = debug_information [i].base_address;
18bd398b 10119
0853c092
L
10120 if (!seen_first_offset)
10121 seen_first_offset = 1;
10122 else
10123 {
10124 if (start < next)
10125 warn (_("There is a hole [0x%lx - 0x%lx] in .debug_ranges section.\n"),
10126 start - section_begin, next - section_begin);
10127 else if (start > next)
10128 warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_ranges section.\n"),
10129 start - section_begin, next - section_begin);
10130 }
10131 start = next;
10132
10133 while (1)
10134 {
10135 begin = byte_get (start, pointer_size);
10136 start += pointer_size;
10137 end = byte_get (start, pointer_size);
10138 start += pointer_size;
10139
10140 if (begin == 0 && end == 0)
35515c66
L
10141 {
10142 printf (_(" %8.8lx <End of list>\n"), offset);
10143 break;
10144 }
0853c092
L
10145
10146 /* Check base address specifiers. */
10147 if (begin == -1UL && end != -1UL)
10148 {
10149 base_address = end;
10150 printf (" %8.8lx %8.8lx %8.8lx (base address)\n",
10151 offset, begin, end);
10152 continue;
10153 }
10154
10155 printf (" %8.8lx %8.8lx %8.8lx",
10156 offset, begin + base_address, end + base_address);
10157
10158 if (begin == end)
10159 fputs (_(" (start == end)"), stdout);
10160 else if (begin > end)
10161 fputs (_(" (start > end)"), stdout);
18bd398b 10162
0853c092
L
10163 putchar ('\n');
10164 }
0853c092
L
10165 }
10166 }
10167 putchar ('\n');
18bd398b
NC
10168 return 1;
10169}
10170
c47d488e
DD
10171typedef struct Frame_Chunk
10172{
b34976b6
AM
10173 struct Frame_Chunk *next;
10174 unsigned char *chunk_start;
10175 int ncols;
a98cc2b2 10176 /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */
b34976b6
AM
10177 short int *col_type;
10178 int *col_offset;
10179 char *augmentation;
10180 unsigned int code_factor;
10181 int data_factor;
10182 unsigned long pc_begin;
10183 unsigned long pc_range;
10184 int cfa_reg;
10185 int cfa_offset;
10186 int ra;
10187 unsigned char fde_encoding;
63044634 10188 unsigned char cfa_exp;
c47d488e
DD
10189}
10190Frame_Chunk;
10191
a98cc2b2
AH
10192/* A marker for a col_type that means this column was never referenced
10193 in the frame info. */
10194#define DW_CFA_unreferenced (-1)
10195
c47d488e 10196static void
d3ba0551 10197frame_need_space (Frame_Chunk *fc, int reg)
c47d488e
DD
10198{
10199 int prev = fc->ncols;
10200
10201 if (reg < fc->ncols)
10202 return;
584da044 10203
c47d488e 10204 fc->ncols = reg + 1;
c256ffe7
JJ
10205 fc->col_type = xcrealloc (fc->col_type, fc->ncols, sizeof (short int));
10206 fc->col_offset = xcrealloc (fc->col_offset, fc->ncols, sizeof (int));
c47d488e
DD
10207
10208 while (prev < fc->ncols)
10209 {
a98cc2b2 10210 fc->col_type[prev] = DW_CFA_unreferenced;
c47d488e
DD
10211 fc->col_offset[prev] = 0;
10212 prev++;
10213 }
10214}
10215
10216static void
d3ba0551 10217frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
c47d488e
DD
10218{
10219 int r;
10220 char tmp[100];
10221
b34976b6
AM
10222 if (*max_regs < fc->ncols)
10223 *max_regs = fc->ncols;
584da044 10224
b34976b6 10225 if (*need_col_headers)
c47d488e 10226 {
b34976b6 10227 *need_col_headers = 0;
584da044 10228
c47d488e 10229 printf (" LOC CFA ");
584da044 10230
b34976b6 10231 for (r = 0; r < *max_regs; r++)
a98cc2b2
AH
10232 if (fc->col_type[r] != DW_CFA_unreferenced)
10233 {
10234 if (r == fc->ra)
10235 printf ("ra ");
10236 else
10237 printf ("r%-4d", r);
10238 }
584da044 10239
c47d488e
DD
10240 printf ("\n");
10241 }
584da044 10242
31b6fca6 10243 printf ("%08lx ", fc->pc_begin);
63044634
RH
10244 if (fc->cfa_exp)
10245 strcpy (tmp, "exp");
10246 else
10247 sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
c47d488e 10248 printf ("%-8s ", tmp);
584da044
NC
10249
10250 for (r = 0; r < fc->ncols; r++)
c47d488e 10251 {
a98cc2b2 10252 if (fc->col_type[r] != DW_CFA_unreferenced)
c47d488e 10253 {
a98cc2b2
AH
10254 switch (fc->col_type[r])
10255 {
10256 case DW_CFA_undefined:
10257 strcpy (tmp, "u");
10258 break;
10259 case DW_CFA_same_value:
10260 strcpy (tmp, "s");
10261 break;
10262 case DW_CFA_offset:
10263 sprintf (tmp, "c%+d", fc->col_offset[r]);
10264 break;
10265 case DW_CFA_register:
10266 sprintf (tmp, "r%d", fc->col_offset[r]);
10267 break;
63044634
RH
10268 case DW_CFA_expression:
10269 strcpy (tmp, "exp");
10270 break;
a98cc2b2
AH
10271 default:
10272 strcpy (tmp, "n/a");
10273 break;
10274 }
10275 printf ("%-5s", tmp);
c47d488e 10276 }
c47d488e
DD
10277 }
10278 printf ("\n");
10279}
10280
31b6fca6 10281static int
d3ba0551 10282size_of_encoded_value (int encoding)
31b6fca6
RH
10283{
10284 switch (encoding & 0x7)
10285 {
10286 default: /* ??? */
89fac5e3 10287 case 0: return eh_addr_size;
31b6fca6
RH
10288 case 2: return 2;
10289 case 3: return 4;
10290 case 4: return 8;
10291 }
10292}
10293
38fafa6d 10294static bfd_vma
d3ba0551 10295get_encoded_value (unsigned char *data, int encoding)
38fafa6d
RH
10296{
10297 int size = size_of_encoded_value (encoding);
10298 if (encoding & DW_EH_PE_signed)
10299 return byte_get_signed (data, size);
10300 else
10301 return byte_get (data, size);
10302}
10303
c47d488e 10304#define GET(N) byte_get (start, N); start += N
584da044
NC
10305#define LEB() read_leb128 (start, & length_return, 0); start += length_return
10306#define SLEB() read_leb128 (start, & length_return, 1); start += length_return
c47d488e
DD
10307
10308static int
d3ba0551
AM
10309display_debug_frames (Elf_Internal_Shdr *section,
10310 unsigned char *start,
10311 FILE *file ATTRIBUTE_UNUSED)
c47d488e 10312{
b34976b6
AM
10313 unsigned char *end = start + section->sh_size;
10314 unsigned char *section_start = start;
10315 Frame_Chunk *chunks = 0;
10316 Frame_Chunk *remembered_state = 0;
10317 Frame_Chunk *rs;
18bd398b 10318 int is_eh = streq (SECTION_NAME (section), ".eh_frame");
dc3c06c2 10319 unsigned int length_return;
b34976b6 10320 int max_regs = 0;
c47d488e
DD
10321
10322 printf (_("The section %s contains:\n"), SECTION_NAME (section));
10323
10324 while (start < end)
10325 {
b34976b6
AM
10326 unsigned char *saved_start;
10327 unsigned char *block_end;
10328 unsigned long length;
10329 unsigned long cie_id;
10330 Frame_Chunk *fc;
10331 Frame_Chunk *cie;
10332 int need_col_headers = 1;
10333 unsigned char *augmentation_data = NULL;
10334 unsigned long augmentation_data_len = 0;
89fac5e3 10335 int encoded_ptr_size = eh_addr_size;
ee42cf8c
NC
10336 int offset_size;
10337 int initial_length_size;
c47d488e
DD
10338
10339 saved_start = start;
10340 length = byte_get (start, 4); start += 4;
10341
10342 if (length == 0)
f1ef08cb
AM
10343 {
10344 printf ("\n%08lx ZERO terminator\n\n",
10345 (unsigned long)(saved_start - section_start));
10346 return 1;
10347 }
c47d488e 10348
428409d5
NC
10349 if (length == 0xffffffff)
10350 {
ee42cf8c
NC
10351 length = byte_get (start, 8);
10352 start += 8;
10353 offset_size = 8;
10354 initial_length_size = 12;
10355 }
10356 else
10357 {
10358 offset_size = 4;
10359 initial_length_size = 4;
428409d5
NC
10360 }
10361
ee42cf8c
NC
10362 block_end = saved_start + length + initial_length_size;
10363 cie_id = byte_get (start, offset_size); start += offset_size;
c47d488e 10364
d84de024
AM
10365 if (elf_header.e_type == ET_REL
10366 && !debug_apply_rela_addends (file, section, offset_size,
10367 section_start, start, block_end))
10368 return 0;
10369
c47d488e
DD
10370 if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
10371 {
31b6fca6
RH
10372 int version;
10373
d3ba0551 10374 fc = xmalloc (sizeof (Frame_Chunk));
c47d488e
DD
10375 memset (fc, 0, sizeof (Frame_Chunk));
10376
10377 fc->next = chunks;
10378 chunks = fc;
10379 fc->chunk_start = saved_start;
10380 fc->ncols = 0;
d3ba0551
AM
10381 fc->col_type = xmalloc (sizeof (short int));
10382 fc->col_offset = xmalloc (sizeof (int));
c47d488e
DD
10383 frame_need_space (fc, max_regs-1);
10384
31b6fca6 10385 version = *start++;
584da044 10386
dc3c06c2
AM
10387 fc->augmentation = (char *) start;
10388 start = (unsigned char *) strchr ((char *) start, '\0') + 1;
584da044 10389
c47d488e
DD
10390 if (fc->augmentation[0] == 'z')
10391 {
c47d488e
DD
10392 fc->code_factor = LEB ();
10393 fc->data_factor = SLEB ();
0da76f83
NC
10394 if (version == 1)
10395 {
10396 fc->ra = GET (1);
10397 }
10398 else
10399 {
10400 fc->ra = LEB ();
10401 }
31b6fca6
RH
10402 augmentation_data_len = LEB ();
10403 augmentation_data = start;
10404 start += augmentation_data_len;
c47d488e 10405 }
18bd398b 10406 else if (streq (fc->augmentation, "eh"))
c47d488e 10407 {
89fac5e3 10408 start += eh_addr_size;
c47d488e
DD
10409 fc->code_factor = LEB ();
10410 fc->data_factor = SLEB ();
0da76f83
NC
10411 if (version == 1)
10412 {
10413 fc->ra = GET (1);
10414 }
10415 else
10416 {
10417 fc->ra = LEB ();
10418 }
c47d488e
DD
10419 }
10420 else
10421 {
10422 fc->code_factor = LEB ();
10423 fc->data_factor = SLEB ();
0da76f83
NC
10424 if (version == 1)
10425 {
10426 fc->ra = GET (1);
10427 }
10428 else
10429 {
10430 fc->ra = LEB ();
10431 }
c47d488e
DD
10432 }
10433 cie = fc;
31b6fca6
RH
10434
10435 if (do_debug_frames_interp)
10436 printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
7036c0e1 10437 (unsigned long)(saved_start - section_start), length, cie_id,
31b6fca6
RH
10438 fc->augmentation, fc->code_factor, fc->data_factor,
10439 fc->ra);
10440 else
10441 {
10442 printf ("\n%08lx %08lx %08lx CIE\n",
7036c0e1 10443 (unsigned long)(saved_start - section_start), length, cie_id);
31b6fca6
RH
10444 printf (" Version: %d\n", version);
10445 printf (" Augmentation: \"%s\"\n", fc->augmentation);
10446 printf (" Code alignment factor: %u\n", fc->code_factor);
10447 printf (" Data alignment factor: %d\n", fc->data_factor);
10448 printf (" Return address column: %d\n", fc->ra);
10449
10450 if (augmentation_data_len)
10451 {
10452 unsigned long i;
10453 printf (" Augmentation data: ");
10454 for (i = 0; i < augmentation_data_len; ++i)
10455 printf (" %02x", augmentation_data[i]);
10456 putchar ('\n');
10457 }
10458 putchar ('\n');
10459 }
10460
10461 if (augmentation_data_len)
10462 {
10463 unsigned char *p, *q;
dc3c06c2 10464 p = (unsigned char *) fc->augmentation + 1;
31b6fca6
RH
10465 q = augmentation_data;
10466
10467 while (1)
10468 {
10469 if (*p == 'L')
7036c0e1 10470 q++;
31b6fca6
RH
10471 else if (*p == 'P')
10472 q += 1 + size_of_encoded_value (*q);
10473 else if (*p == 'R')
10474 fc->fde_encoding = *q++;
10475 else
10476 break;
10477 p++;
10478 }
10479
10480 if (fc->fde_encoding)
10481 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
10482 }
c47d488e
DD
10483
10484 frame_need_space (fc, fc->ra);
10485 }
10486 else
10487 {
b34976b6 10488 unsigned char *look_for;
c47d488e 10489 static Frame_Chunk fde_fc;
584da044
NC
10490
10491 fc = & fde_fc;
c47d488e
DD
10492 memset (fc, 0, sizeof (Frame_Chunk));
10493
31b6fca6 10494 look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
c47d488e 10495
428409d5 10496 for (cie = chunks; cie ; cie = cie->next)
31b6fca6
RH
10497 if (cie->chunk_start == look_for)
10498 break;
c47d488e 10499
c47d488e
DD
10500 if (!cie)
10501 {
31b6fca6
RH
10502 warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
10503 cie_id, saved_start);
c47d488e
DD
10504 start = block_end;
10505 fc->ncols = 0;
d3ba0551
AM
10506 fc->col_type = xmalloc (sizeof (short int));
10507 fc->col_offset = xmalloc (sizeof (int));
584da044 10508 frame_need_space (fc, max_regs - 1);
c47d488e
DD
10509 cie = fc;
10510 fc->augmentation = "";
31b6fca6 10511 fc->fde_encoding = 0;
c47d488e
DD
10512 }
10513 else
10514 {
10515 fc->ncols = cie->ncols;
c256ffe7
JJ
10516 fc->col_type = xcmalloc (fc->ncols, sizeof (short int));
10517 fc->col_offset = xcmalloc (fc->ncols, sizeof (int));
a98cc2b2 10518 memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
c47d488e
DD
10519 memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
10520 fc->augmentation = cie->augmentation;
10521 fc->code_factor = cie->code_factor;
10522 fc->data_factor = cie->data_factor;
10523 fc->cfa_reg = cie->cfa_reg;
10524 fc->cfa_offset = cie->cfa_offset;
10525 fc->ra = cie->ra;
10526 frame_need_space (fc, max_regs-1);
31b6fca6 10527 fc->fde_encoding = cie->fde_encoding;
c47d488e
DD
10528 }
10529
31b6fca6
RH
10530 if (fc->fde_encoding)
10531 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
10532
38fafa6d 10533 fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
d84de024
AM
10534 if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
10535 /* Don't adjust for ET_REL since there's invariably a pcrel
10536 reloc here, which we haven't applied. */
10537 && elf_header.e_type != ET_REL)
f1ef08cb 10538 fc->pc_begin += section->sh_addr + (start - section_start);
31b6fca6
RH
10539 start += encoded_ptr_size;
10540 fc->pc_range = byte_get (start, encoded_ptr_size);
10541 start += encoded_ptr_size;
10542
c47d488e
DD
10543 if (cie->augmentation[0] == 'z')
10544 {
31b6fca6
RH
10545 augmentation_data_len = LEB ();
10546 augmentation_data = start;
10547 start += augmentation_data_len;
c47d488e
DD
10548 }
10549
410f7a12 10550 printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
7036c0e1 10551 (unsigned long)(saved_start - section_start), length, cie_id,
410f7a12
L
10552 (unsigned long)(cie->chunk_start - section_start),
10553 fc->pc_begin, fc->pc_begin + fc->pc_range);
31b6fca6
RH
10554 if (! do_debug_frames_interp && augmentation_data_len)
10555 {
10556 unsigned long i;
5b18a4bc 10557
31b6fca6
RH
10558 printf (" Augmentation data: ");
10559 for (i = 0; i < augmentation_data_len; ++i)
ba2685cc 10560 printf (" %02x", augmentation_data[i]);
31b6fca6
RH
10561 putchar ('\n');
10562 putchar ('\n');
10563 }
c47d488e
DD
10564 }
10565
18bd398b
NC
10566 /* At this point, fc is the current chunk, cie (if any) is set, and
10567 we're about to interpret instructions for the chunk. */
38fafa6d
RH
10568 /* ??? At present we need to do this always, since this sizes the
10569 fc->col_type and fc->col_offset arrays, which we write into always.
10570 We should probably split the interpreted and non-interpreted bits
10571 into two different routines, since there's so much that doesn't
10572 really overlap between them. */
10573 if (1 || do_debug_frames_interp)
53c7db4b
KH
10574 {
10575 /* Start by making a pass over the chunk, allocating storage
10576 and taking note of what registers are used. */
b34976b6 10577 unsigned char *tmp = start;
a98cc2b2 10578
53c7db4b
KH
10579 while (start < block_end)
10580 {
10581 unsigned op, opa;
63044634 10582 unsigned long reg, tmp;
7036c0e1 10583
b34976b6 10584 op = *start++;
53c7db4b
KH
10585 opa = op & 0x3f;
10586 if (op & 0xc0)
10587 op &= 0xc0;
7036c0e1 10588
53c7db4b 10589 /* Warning: if you add any more cases to this switch, be
ba2685cc 10590 sure to add them to the corresponding switch below. */
53c7db4b
KH
10591 switch (op)
10592 {
10593 case DW_CFA_advance_loc:
10594 break;
10595 case DW_CFA_offset:
10596 LEB ();
10597 frame_need_space (fc, opa);
10598 fc->col_type[opa] = DW_CFA_undefined;
10599 break;
10600 case DW_CFA_restore:
10601 frame_need_space (fc, opa);
10602 fc->col_type[opa] = DW_CFA_undefined;
10603 break;
10604 case DW_CFA_set_loc:
10605 start += encoded_ptr_size;
10606 break;
10607 case DW_CFA_advance_loc1:
10608 start += 1;
10609 break;
10610 case DW_CFA_advance_loc2:
10611 start += 2;
10612 break;
10613 case DW_CFA_advance_loc4:
10614 start += 4;
10615 break;
10616 case DW_CFA_offset_extended:
10617 reg = LEB (); LEB ();
10618 frame_need_space (fc, reg);
10619 fc->col_type[reg] = DW_CFA_undefined;
10620 break;
10621 case DW_CFA_restore_extended:
10622 reg = LEB ();
10623 frame_need_space (fc, reg);
10624 fc->col_type[reg] = DW_CFA_undefined;
10625 break;
10626 case DW_CFA_undefined:
10627 reg = LEB ();
10628 frame_need_space (fc, reg);
10629 fc->col_type[reg] = DW_CFA_undefined;
10630 break;
10631 case DW_CFA_same_value:
10632 reg = LEB ();
10633 frame_need_space (fc, reg);
10634 fc->col_type[reg] = DW_CFA_undefined;
10635 break;
10636 case DW_CFA_register:
10637 reg = LEB (); LEB ();
10638 frame_need_space (fc, reg);
10639 fc->col_type[reg] = DW_CFA_undefined;
10640 break;
10641 case DW_CFA_def_cfa:
10642 LEB (); LEB ();
10643 break;
10644 case DW_CFA_def_cfa_register:
10645 LEB ();
10646 break;
10647 case DW_CFA_def_cfa_offset:
10648 LEB ();
10649 break;
63044634
RH
10650 case DW_CFA_def_cfa_expression:
10651 tmp = LEB ();
10652 start += tmp;
10653 break;
10654 case DW_CFA_expression:
10655 reg = LEB ();
10656 tmp = LEB ();
10657 start += tmp;
10658 frame_need_space (fc, reg);
10659 fc->col_type[reg] = DW_CFA_undefined;
10660 break;
91a106e6
L
10661 case DW_CFA_offset_extended_sf:
10662 reg = LEB (); SLEB ();
10663 frame_need_space (fc, reg);
10664 fc->col_type[reg] = DW_CFA_undefined;
10665 break;
10666 case DW_CFA_def_cfa_sf:
10667 LEB (); SLEB ();
10668 break;
10669 case DW_CFA_def_cfa_offset_sf:
10670 SLEB ();
10671 break;
63044634
RH
10672 case DW_CFA_MIPS_advance_loc8:
10673 start += 8;
10674 break;
53c7db4b
KH
10675 case DW_CFA_GNU_args_size:
10676 LEB ();
10677 break;
53c7db4b
KH
10678 case DW_CFA_GNU_negative_offset_extended:
10679 reg = LEB (); LEB ();
10680 frame_need_space (fc, reg);
10681 fc->col_type[reg] = DW_CFA_undefined;
7036c0e1 10682
53c7db4b
KH
10683 default:
10684 break;
10685 }
10686 }
10687 start = tmp;
10688 }
a98cc2b2
AH
10689
10690 /* Now we know what registers are used, make a second pass over
ba2685cc 10691 the chunk, this time actually printing out the info. */
a98cc2b2 10692
c47d488e
DD
10693 while (start < block_end)
10694 {
10695 unsigned op, opa;
10696 unsigned long ul, reg, roffs;
10697 long l, ofs;
10698 bfd_vma vma;
10699
b34976b6 10700 op = *start++;
c47d488e
DD
10701 opa = op & 0x3f;
10702 if (op & 0xc0)
10703 op &= 0xc0;
10704
53c7db4b
KH
10705 /* Warning: if you add any more cases to this switch, be
10706 sure to add them to the corresponding switch above. */
c47d488e
DD
10707 switch (op)
10708 {
10709 case DW_CFA_advance_loc:
31b6fca6 10710 if (do_debug_frames_interp)
53c7db4b 10711 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 10712 else
53c7db4b
KH
10713 printf (" DW_CFA_advance_loc: %d to %08lx\n",
10714 opa * fc->code_factor,
31b6fca6 10715 fc->pc_begin + opa * fc->code_factor);
c47d488e
DD
10716 fc->pc_begin += opa * fc->code_factor;
10717 break;
10718
10719 case DW_CFA_offset:
c47d488e 10720 roffs = LEB ();
31b6fca6 10721 if (! do_debug_frames_interp)
53c7db4b 10722 printf (" DW_CFA_offset: r%d at cfa%+ld\n",
31b6fca6 10723 opa, roffs * fc->data_factor);
c47d488e
DD
10724 fc->col_type[opa] = DW_CFA_offset;
10725 fc->col_offset[opa] = roffs * fc->data_factor;
10726 break;
10727
10728 case DW_CFA_restore:
31b6fca6 10729 if (! do_debug_frames_interp)
53c7db4b 10730 printf (" DW_CFA_restore: r%d\n", opa);
c47d488e
DD
10731 fc->col_type[opa] = cie->col_type[opa];
10732 fc->col_offset[opa] = cie->col_offset[opa];
10733 break;
10734
10735 case DW_CFA_set_loc:
38fafa6d 10736 vma = get_encoded_value (start, fc->fde_encoding);
d84de024
AM
10737 if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
10738 && elf_header.e_type != ET_REL)
f1ef08cb 10739 vma += section->sh_addr + (start - section_start);
31b6fca6
RH
10740 start += encoded_ptr_size;
10741 if (do_debug_frames_interp)
53c7db4b 10742 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 10743 else
53c7db4b 10744 printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
c47d488e
DD
10745 fc->pc_begin = vma;
10746 break;
10747
10748 case DW_CFA_advance_loc1:
c47d488e 10749 ofs = byte_get (start, 1); start += 1;
31b6fca6 10750 if (do_debug_frames_interp)
53c7db4b 10751 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 10752 else
53c7db4b
KH
10753 printf (" DW_CFA_advance_loc1: %ld to %08lx\n",
10754 ofs * fc->code_factor,
31b6fca6 10755 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
10756 fc->pc_begin += ofs * fc->code_factor;
10757 break;
10758
10759 case DW_CFA_advance_loc2:
c47d488e 10760 ofs = byte_get (start, 2); start += 2;
31b6fca6 10761 if (do_debug_frames_interp)
53c7db4b 10762 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 10763 else
53c7db4b
KH
10764 printf (" DW_CFA_advance_loc2: %ld to %08lx\n",
10765 ofs * fc->code_factor,
31b6fca6 10766 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
10767 fc->pc_begin += ofs * fc->code_factor;
10768 break;
10769
10770 case DW_CFA_advance_loc4:
c47d488e 10771 ofs = byte_get (start, 4); start += 4;
31b6fca6 10772 if (do_debug_frames_interp)
53c7db4b 10773 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 10774 else
53c7db4b
KH
10775 printf (" DW_CFA_advance_loc4: %ld to %08lx\n",
10776 ofs * fc->code_factor,
31b6fca6 10777 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
10778 fc->pc_begin += ofs * fc->code_factor;
10779 break;
10780
10781 case DW_CFA_offset_extended:
10782 reg = LEB ();
10783 roffs = LEB ();
31b6fca6 10784 if (! do_debug_frames_interp)
7036c0e1 10785 printf (" DW_CFA_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 10786 reg, roffs * fc->data_factor);
c47d488e
DD
10787 fc->col_type[reg] = DW_CFA_offset;
10788 fc->col_offset[reg] = roffs * fc->data_factor;
10789 break;
10790
10791 case DW_CFA_restore_extended:
10792 reg = LEB ();
31b6fca6 10793 if (! do_debug_frames_interp)
53c7db4b 10794 printf (" DW_CFA_restore_extended: r%ld\n", reg);
c47d488e
DD
10795 fc->col_type[reg] = cie->col_type[reg];
10796 fc->col_offset[reg] = cie->col_offset[reg];
10797 break;
10798
10799 case DW_CFA_undefined:
10800 reg = LEB ();
31b6fca6 10801 if (! do_debug_frames_interp)
53c7db4b 10802 printf (" DW_CFA_undefined: r%ld\n", reg);
c47d488e
DD
10803 fc->col_type[reg] = DW_CFA_undefined;
10804 fc->col_offset[reg] = 0;
10805 break;
10806
10807 case DW_CFA_same_value:
10808 reg = LEB ();
31b6fca6 10809 if (! do_debug_frames_interp)
53c7db4b 10810 printf (" DW_CFA_same_value: r%ld\n", reg);
c47d488e
DD
10811 fc->col_type[reg] = DW_CFA_same_value;
10812 fc->col_offset[reg] = 0;
10813 break;
10814
10815 case DW_CFA_register:
10816 reg = LEB ();
10817 roffs = LEB ();
31b6fca6 10818 if (! do_debug_frames_interp)
636fc387 10819 printf (" DW_CFA_register: r%ld in r%ld\n", reg, roffs);
c47d488e
DD
10820 fc->col_type[reg] = DW_CFA_register;
10821 fc->col_offset[reg] = roffs;
10822 break;
10823
10824 case DW_CFA_remember_state:
31b6fca6 10825 if (! do_debug_frames_interp)
53c7db4b 10826 printf (" DW_CFA_remember_state\n");
d3ba0551 10827 rs = xmalloc (sizeof (Frame_Chunk));
c47d488e 10828 rs->ncols = fc->ncols;
c256ffe7
JJ
10829 rs->col_type = xcmalloc (rs->ncols, sizeof (short int));
10830 rs->col_offset = xcmalloc (rs->ncols, sizeof (int));
c47d488e
DD
10831 memcpy (rs->col_type, fc->col_type, rs->ncols);
10832 memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
10833 rs->next = remembered_state;
10834 remembered_state = rs;
10835 break;
10836
10837 case DW_CFA_restore_state:
31b6fca6 10838 if (! do_debug_frames_interp)
53c7db4b 10839 printf (" DW_CFA_restore_state\n");
c47d488e 10840 rs = remembered_state;
8c9a9879
RH
10841 if (rs)
10842 {
10843 remembered_state = rs->next;
10844 frame_need_space (fc, rs->ncols-1);
10845 memcpy (fc->col_type, rs->col_type, rs->ncols);
10846 memcpy (fc->col_offset, rs->col_offset,
10847 rs->ncols * sizeof (int));
10848 free (rs->col_type);
10849 free (rs->col_offset);
10850 free (rs);
10851 }
10852 else if (do_debug_frames_interp)
10853 printf ("Mismatched DW_CFA_restore_state\n");
c47d488e
DD
10854 break;
10855
10856 case DW_CFA_def_cfa:
10857 fc->cfa_reg = LEB ();
10858 fc->cfa_offset = LEB ();
63044634 10859 fc->cfa_exp = 0;
31b6fca6 10860 if (! do_debug_frames_interp)
53c7db4b 10861 printf (" DW_CFA_def_cfa: r%d ofs %d\n",
31b6fca6 10862 fc->cfa_reg, fc->cfa_offset);
c47d488e
DD
10863 break;
10864
10865 case DW_CFA_def_cfa_register:
10866 fc->cfa_reg = LEB ();
63044634 10867 fc->cfa_exp = 0;
31b6fca6 10868 if (! do_debug_frames_interp)
53c7db4b 10869 printf (" DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
c47d488e
DD
10870 break;
10871
10872 case DW_CFA_def_cfa_offset:
10873 fc->cfa_offset = LEB ();
31b6fca6 10874 if (! do_debug_frames_interp)
53c7db4b 10875 printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
c47d488e
DD
10876 break;
10877
10878 case DW_CFA_nop:
31b6fca6 10879 if (! do_debug_frames_interp)
53c7db4b 10880 printf (" DW_CFA_nop\n");
c47d488e
DD
10881 break;
10882
63044634
RH
10883 case DW_CFA_def_cfa_expression:
10884 ul = LEB ();
10885 if (! do_debug_frames_interp)
10886 {
10887 printf (" DW_CFA_def_cfa_expression (");
89fac5e3 10888 decode_location_expression (start, eh_addr_size, ul, 0);
63044634
RH
10889 printf (")\n");
10890 }
10891 fc->cfa_exp = 1;
10892 start += ul;
10893 break;
10894
10895 case DW_CFA_expression:
10896 reg = LEB ();
10897 ul = LEB ();
10898 if (! do_debug_frames_interp)
10899 {
10900 printf (" DW_CFA_expression: r%ld (", reg);
89fac5e3 10901 decode_location_expression (start, eh_addr_size, ul, 0);
63044634
RH
10902 printf (")\n");
10903 }
10904 fc->col_type[reg] = DW_CFA_expression;
10905 start += ul;
10906 break;
10907
91a106e6
L
10908 case DW_CFA_offset_extended_sf:
10909 reg = LEB ();
10910 l = SLEB ();
10911 frame_need_space (fc, reg);
10912 if (! do_debug_frames_interp)
10913 printf (" DW_CFA_offset_extended_sf: r%ld at cfa%+ld\n",
10914 reg, l * fc->data_factor);
10915 fc->col_type[reg] = DW_CFA_offset;
10916 fc->col_offset[reg] = l * fc->data_factor;
10917 break;
10918
10919 case DW_CFA_def_cfa_sf:
10920 fc->cfa_reg = LEB ();
10921 fc->cfa_offset = SLEB ();
ae67fcb5 10922 fc->cfa_offset = fc->cfa_offset * fc->data_factor;
63044634 10923 fc->cfa_exp = 0;
91a106e6
L
10924 if (! do_debug_frames_interp)
10925 printf (" DW_CFA_def_cfa_sf: r%d ofs %d\n",
10926 fc->cfa_reg, fc->cfa_offset);
10927 break;
10928
10929 case DW_CFA_def_cfa_offset_sf:
10930 fc->cfa_offset = SLEB ();
ae67fcb5 10931 fc->cfa_offset = fc->cfa_offset * fc->data_factor;
91a106e6
L
10932 if (! do_debug_frames_interp)
10933 printf (" DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset);
10934 break;
10935
63044634
RH
10936 case DW_CFA_MIPS_advance_loc8:
10937 ofs = byte_get (start, 8); start += 8;
10938 if (do_debug_frames_interp)
10939 frame_display_row (fc, &need_col_headers, &max_regs);
10940 else
10941 printf (" DW_CFA_MIPS_advance_loc8: %ld to %08lx\n",
10942 ofs * fc->code_factor,
10943 fc->pc_begin + ofs * fc->code_factor);
10944 fc->pc_begin += ofs * fc->code_factor;
10945 break;
10946
c47d488e 10947 case DW_CFA_GNU_window_save:
31b6fca6 10948 if (! do_debug_frames_interp)
53c7db4b 10949 printf (" DW_CFA_GNU_window_save\n");
c47d488e
DD
10950 break;
10951
c47d488e
DD
10952 case DW_CFA_GNU_args_size:
10953 ul = LEB ();
31b6fca6 10954 if (! do_debug_frames_interp)
53c7db4b 10955 printf (" DW_CFA_GNU_args_size: %ld\n", ul);
c47d488e
DD
10956 break;
10957
c47d488e
DD
10958 case DW_CFA_GNU_negative_offset_extended:
10959 reg = LEB ();
10960 l = - LEB ();
10961 frame_need_space (fc, reg);
31b6fca6 10962 if (! do_debug_frames_interp)
53c7db4b 10963 printf (" DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 10964 reg, l * fc->data_factor);
c47d488e
DD
10965 fc->col_type[reg] = DW_CFA_offset;
10966 fc->col_offset[reg] = l * fc->data_factor;
10967 break;
10968
10969 default:
18bd398b 10970 warn (_("unsupported or unknown DW_CFA_%d\n"), op);
c47d488e
DD
10971 start = block_end;
10972 }
10973 }
10974
31b6fca6 10975 if (do_debug_frames_interp)
53c7db4b 10976 frame_display_row (fc, &need_col_headers, &max_regs);
c47d488e
DD
10977
10978 start = block_end;
10979 }
10980
10981 printf ("\n");
10982
10983 return 1;
10984}
10985
10986#undef GET
10987#undef LEB
10988#undef SLEB
252b5132
RH
10989
10990static int
d3ba0551
AM
10991display_debug_not_supported (Elf_Internal_Shdr *section,
10992 unsigned char *start ATTRIBUTE_UNUSED,
10993 FILE *file ATTRIBUTE_UNUSED)
252b5132
RH
10994{
10995 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
10996 SECTION_NAME (section));
10997
10998 return 1;
10999}
11000
d9296b18
NC
11001/* A structure containing the name of a debug section
11002 and a pointer to a function that can decode it. */
85b1c36d 11003static struct
252b5132 11004{
b34976b6 11005 const char *const name;
d3ba0551 11006 int (*display) (Elf_Internal_Shdr *, unsigned char *, FILE *);
252b5132
RH
11007}
11008debug_displays[] =
11009{
d9296b18
NC
11010 { ".debug_abbrev", display_debug_abbrev },
11011 { ".debug_aranges", display_debug_aranges },
11012 { ".debug_frame", display_debug_frames },
11013 { ".debug_info", display_debug_info },
11014 { ".debug_line", display_debug_lines },
11015 { ".debug_pubnames", display_debug_pubnames },
11016 { ".eh_frame", display_debug_frames },
11017 { ".debug_macinfo", display_debug_macinfo },
11018 { ".debug_str", display_debug_str },
11019 { ".debug_loc", display_debug_loc },
935a41f5 11020 { ".debug_pubtypes", display_debug_pubnames },
18bd398b 11021 { ".debug_ranges", display_debug_ranges },
d9296b18
NC
11022 { ".debug_static_func", display_debug_not_supported },
11023 { ".debug_static_vars", display_debug_not_supported },
11024 { ".debug_types", display_debug_not_supported },
11025 { ".debug_weaknames", display_debug_not_supported }
252b5132
RH
11026};
11027
11028static int
d3ba0551 11029display_debug_section (Elf_Internal_Shdr *section, FILE *file)
252b5132 11030{
b34976b6
AM
11031 char *name = SECTION_NAME (section);
11032 bfd_size_type length;
18bd398b 11033 int result = 1;
b34976b6 11034 int i;
252b5132
RH
11035
11036 length = section->sh_size;
11037 if (length == 0)
11038 {
11039 printf (_("\nSection '%s' has no debugging data.\n"), name);
11040 return 0;
11041 }
11042
18bd398b 11043 if (strneq (name, ".gnu.linkonce.wi.", 17))
7036c0e1 11044 name = ".debug_info";
584da044 11045
18bd398b 11046 /* See if we know how to display the contents of this section. */
252b5132 11047 for (i = NUM_ELEM (debug_displays); i--;)
18bd398b 11048 if (streq (debug_displays[i].name, name))
252b5132 11049 {
18bd398b
NC
11050 unsigned char *start;
11051
c256ffe7 11052 start = get_data (NULL, file, section->sh_offset, 1, length,
18bd398b
NC
11053 _("debug section data"));
11054 if (start == NULL)
11055 {
11056 result = 0;
11057 break;
11058 }
11059
11060 result &= debug_displays[i].display (section, start, file);
11061 free (start);
11062
11063 /* If we loaded in the abbrev section
11064 at some point, we must release it here. */
11065 free_abbrevs ();
11066
252b5132
RH
11067 break;
11068 }
11069
11070 if (i == -1)
18bd398b
NC
11071 {
11072 printf (_("Unrecognized debug section: %s\n"), name);
11073 result = 0;
11074 }
252b5132 11075
18bd398b 11076 return result;
252b5132
RH
11077}
11078
18bd398b 11079static void
d3ba0551 11080process_section_contents (FILE *file)
252b5132 11081{
b34976b6
AM
11082 Elf_Internal_Shdr *section;
11083 unsigned int i;
252b5132
RH
11084
11085 if (! do_dump)
18bd398b 11086 return;
252b5132
RH
11087
11088 for (i = 0, section = section_headers;
3590ea00 11089 i < elf_header.e_shnum && i < num_dump_sects;
b34976b6 11090 i++, section++)
252b5132
RH
11091 {
11092#ifdef SUPPORT_DISASSEMBLY
11093 if (dump_sects[i] & DISASS_DUMP)
11094 disassemble_section (section, file);
11095#endif
11096 if (dump_sects[i] & HEX_DUMP)
11097 dump_section (section, file);
11098
11099 if (dump_sects[i] & DEBUG_DUMP)
11100 display_debug_section (section, file);
11101 }
11102
18bd398b
NC
11103 /* Check to see if the user requested a
11104 dump of a section that does not exist. */
11105 while (i++ < num_dump_sects)
11106 if (dump_sects[i])
11107 warn (_("Section %d was not dumped because it does not exist!\n"), i);
252b5132
RH
11108}
11109
11110static void
d3ba0551 11111process_mips_fpe_exception (int mask)
252b5132
RH
11112{
11113 if (mask)
11114 {
11115 int first = 1;
11116 if (mask & OEX_FPU_INEX)
11117 fputs ("INEX", stdout), first = 0;
11118 if (mask & OEX_FPU_UFLO)
11119 printf ("%sUFLO", first ? "" : "|"), first = 0;
11120 if (mask & OEX_FPU_OFLO)
11121 printf ("%sOFLO", first ? "" : "|"), first = 0;
11122 if (mask & OEX_FPU_DIV0)
11123 printf ("%sDIV0", first ? "" : "|"), first = 0;
11124 if (mask & OEX_FPU_INVAL)
11125 printf ("%sINVAL", first ? "" : "|");
11126 }
11127 else
11128 fputs ("0", stdout);
11129}
11130
11131static int
d3ba0551 11132process_mips_specific (FILE *file)
252b5132 11133{
b34976b6 11134 Elf_Internal_Dyn *entry;
252b5132
RH
11135 size_t liblist_offset = 0;
11136 size_t liblistno = 0;
11137 size_t conflictsno = 0;
11138 size_t options_offset = 0;
11139 size_t conflicts_offset = 0;
11140
11141 /* We have a lot of special sections. Thanks SGI! */
b2d38a17 11142 if (dynamic_section == NULL)
252b5132
RH
11143 /* No information available. */
11144 return 0;
11145
b2d38a17 11146 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
11147 switch (entry->d_tag)
11148 {
11149 case DT_MIPS_LIBLIST:
d93f0186
NC
11150 liblist_offset
11151 = offset_from_vma (file, entry->d_un.d_val,
11152 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
11153 break;
11154 case DT_MIPS_LIBLISTNO:
11155 liblistno = entry->d_un.d_val;
11156 break;
11157 case DT_MIPS_OPTIONS:
d93f0186 11158 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
11159 break;
11160 case DT_MIPS_CONFLICT:
d93f0186
NC
11161 conflicts_offset
11162 = offset_from_vma (file, entry->d_un.d_val,
11163 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
11164 break;
11165 case DT_MIPS_CONFLICTNO:
11166 conflictsno = entry->d_un.d_val;
11167 break;
11168 default:
11169 break;
11170 }
11171
11172 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
11173 {
b34976b6 11174 Elf32_External_Lib *elib;
252b5132
RH
11175 size_t cnt;
11176
d3ba0551 11177 elib = get_data (NULL, file, liblist_offset,
c256ffe7 11178 liblistno, sizeof (Elf32_External_Lib),
d3ba0551 11179 _("liblist"));
a6e9f9df 11180 if (elib)
252b5132 11181 {
a6e9f9df
AM
11182 printf ("\nSection '.liblist' contains %lu entries:\n",
11183 (unsigned long) liblistno);
11184 fputs (" Library Time Stamp Checksum Version Flags\n",
11185 stdout);
11186
11187 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 11188 {
a6e9f9df
AM
11189 Elf32_Lib liblist;
11190 time_t time;
11191 char timebuf[20];
b34976b6 11192 struct tm *tmp;
a6e9f9df
AM
11193
11194 liblist.l_name = BYTE_GET (elib[cnt].l_name);
11195 time = BYTE_GET (elib[cnt].l_time_stamp);
11196 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
11197 liblist.l_version = BYTE_GET (elib[cnt].l_version);
11198 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
11199
11200 tmp = gmtime (&time);
e9e44622
JJ
11201 snprintf (timebuf, sizeof (timebuf),
11202 "%04u-%02u-%02uT%02u:%02u:%02u",
11203 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11204 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 11205
31104126 11206 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
11207 if (VALID_DYNAMIC_NAME (liblist.l_name))
11208 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
11209 else
11210 printf ("<corrupt: %9ld>", liblist.l_name);
31104126
NC
11211 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
11212 liblist.l_version);
a6e9f9df
AM
11213
11214 if (liblist.l_flags == 0)
11215 puts (" NONE");
11216 else
11217 {
11218 static const struct
252b5132 11219 {
b34976b6 11220 const char *name;
a6e9f9df 11221 int bit;
252b5132 11222 }
a6e9f9df
AM
11223 l_flags_vals[] =
11224 {
11225 { " EXACT_MATCH", LL_EXACT_MATCH },
11226 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
11227 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
11228 { " EXPORTS", LL_EXPORTS },
11229 { " DELAY_LOAD", LL_DELAY_LOAD },
11230 { " DELTA", LL_DELTA }
11231 };
11232 int flags = liblist.l_flags;
11233 size_t fcnt;
11234
11235 for (fcnt = 0;
11236 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
11237 ++fcnt)
11238 if ((flags & l_flags_vals[fcnt].bit) != 0)
11239 {
11240 fputs (l_flags_vals[fcnt].name, stdout);
11241 flags ^= l_flags_vals[fcnt].bit;
11242 }
11243 if (flags != 0)
11244 printf (" %#x", (unsigned int) flags);
252b5132 11245
a6e9f9df
AM
11246 puts ("");
11247 }
252b5132 11248 }
252b5132 11249
a6e9f9df
AM
11250 free (elib);
11251 }
252b5132
RH
11252 }
11253
11254 if (options_offset != 0)
11255 {
b34976b6
AM
11256 Elf_External_Options *eopt;
11257 Elf_Internal_Shdr *sect = section_headers;
11258 Elf_Internal_Options *iopt;
11259 Elf_Internal_Options *option;
252b5132
RH
11260 size_t offset;
11261 int cnt;
11262
11263 /* Find the section header so that we get the size. */
11264 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 11265 ++sect;
252b5132 11266
c256ffe7 11267 eopt = get_data (NULL, file, options_offset, 1, sect->sh_size,
d3ba0551 11268 _("options"));
a6e9f9df 11269 if (eopt)
252b5132 11270 {
c256ffe7 11271 iopt = cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (*iopt));
a6e9f9df
AM
11272 if (iopt == NULL)
11273 {
11274 error (_("Out of memory"));
11275 return 0;
11276 }
76da6bbe 11277
a6e9f9df
AM
11278 offset = cnt = 0;
11279 option = iopt;
252b5132 11280
a6e9f9df
AM
11281 while (offset < sect->sh_size)
11282 {
b34976b6 11283 Elf_External_Options *eoption;
252b5132 11284
a6e9f9df 11285 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 11286
a6e9f9df
AM
11287 option->kind = BYTE_GET (eoption->kind);
11288 option->size = BYTE_GET (eoption->size);
11289 option->section = BYTE_GET (eoption->section);
11290 option->info = BYTE_GET (eoption->info);
76da6bbe 11291
a6e9f9df 11292 offset += option->size;
252b5132 11293
a6e9f9df
AM
11294 ++option;
11295 ++cnt;
11296 }
252b5132 11297
a6e9f9df
AM
11298 printf (_("\nSection '%s' contains %d entries:\n"),
11299 SECTION_NAME (sect), cnt);
76da6bbe 11300
a6e9f9df 11301 option = iopt;
252b5132 11302
a6e9f9df 11303 while (cnt-- > 0)
252b5132 11304 {
a6e9f9df
AM
11305 size_t len;
11306
11307 switch (option->kind)
252b5132 11308 {
a6e9f9df
AM
11309 case ODK_NULL:
11310 /* This shouldn't happen. */
11311 printf (" NULL %d %lx", option->section, option->info);
11312 break;
11313 case ODK_REGINFO:
11314 printf (" REGINFO ");
11315 if (elf_header.e_machine == EM_MIPS)
11316 {
11317 /* 32bit form. */
b34976b6
AM
11318 Elf32_External_RegInfo *ereg;
11319 Elf32_RegInfo reginfo;
a6e9f9df
AM
11320
11321 ereg = (Elf32_External_RegInfo *) (option + 1);
11322 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11323 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11324 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11325 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11326 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
11327 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
11328
11329 printf ("GPR %08lx GP 0x%lx\n",
11330 reginfo.ri_gprmask,
11331 (unsigned long) reginfo.ri_gp_value);
11332 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11333 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11334 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11335 }
11336 else
11337 {
11338 /* 64 bit form. */
b34976b6 11339 Elf64_External_RegInfo *ereg;
a6e9f9df
AM
11340 Elf64_Internal_RegInfo reginfo;
11341
11342 ereg = (Elf64_External_RegInfo *) (option + 1);
11343 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11344 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11345 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11346 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11347 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 11348 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
11349
11350 printf ("GPR %08lx GP 0x",
11351 reginfo.ri_gprmask);
11352 printf_vma (reginfo.ri_gp_value);
11353 printf ("\n");
11354
11355 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11356 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11357 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11358 }
11359 ++option;
11360 continue;
11361 case ODK_EXCEPTIONS:
11362 fputs (" EXCEPTIONS fpe_min(", stdout);
11363 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
11364 fputs (") fpe_max(", stdout);
11365 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
11366 fputs (")", stdout);
11367
11368 if (option->info & OEX_PAGE0)
11369 fputs (" PAGE0", stdout);
11370 if (option->info & OEX_SMM)
11371 fputs (" SMM", stdout);
11372 if (option->info & OEX_FPDBUG)
11373 fputs (" FPDBUG", stdout);
11374 if (option->info & OEX_DISMISS)
11375 fputs (" DISMISS", stdout);
11376 break;
11377 case ODK_PAD:
11378 fputs (" PAD ", stdout);
11379 if (option->info & OPAD_PREFIX)
11380 fputs (" PREFIX", stdout);
11381 if (option->info & OPAD_POSTFIX)
11382 fputs (" POSTFIX", stdout);
11383 if (option->info & OPAD_SYMBOL)
11384 fputs (" SYMBOL", stdout);
11385 break;
11386 case ODK_HWPATCH:
11387 fputs (" HWPATCH ", stdout);
11388 if (option->info & OHW_R4KEOP)
11389 fputs (" R4KEOP", stdout);
11390 if (option->info & OHW_R8KPFETCH)
11391 fputs (" R8KPFETCH", stdout);
11392 if (option->info & OHW_R5KEOP)
11393 fputs (" R5KEOP", stdout);
11394 if (option->info & OHW_R5KCVTL)
11395 fputs (" R5KCVTL", stdout);
11396 break;
11397 case ODK_FILL:
11398 fputs (" FILL ", stdout);
11399 /* XXX Print content of info word? */
11400 break;
11401 case ODK_TAGS:
11402 fputs (" TAGS ", stdout);
11403 /* XXX Print content of info word? */
11404 break;
11405 case ODK_HWAND:
11406 fputs (" HWAND ", stdout);
11407 if (option->info & OHWA0_R4KEOP_CHECKED)
11408 fputs (" R4KEOP_CHECKED", stdout);
11409 if (option->info & OHWA0_R4KEOP_CLEAN)
11410 fputs (" R4KEOP_CLEAN", stdout);
11411 break;
11412 case ODK_HWOR:
11413 fputs (" HWOR ", stdout);
11414 if (option->info & OHWA0_R4KEOP_CHECKED)
11415 fputs (" R4KEOP_CHECKED", stdout);
11416 if (option->info & OHWA0_R4KEOP_CLEAN)
11417 fputs (" R4KEOP_CLEAN", stdout);
11418 break;
11419 case ODK_GP_GROUP:
11420 printf (" GP_GROUP %#06lx self-contained %#06lx",
11421 option->info & OGP_GROUP,
11422 (option->info & OGP_SELF) >> 16);
11423 break;
11424 case ODK_IDENT:
11425 printf (" IDENT %#06lx self-contained %#06lx",
11426 option->info & OGP_GROUP,
11427 (option->info & OGP_SELF) >> 16);
11428 break;
11429 default:
11430 /* This shouldn't happen. */
11431 printf (" %3d ??? %d %lx",
11432 option->kind, option->section, option->info);
11433 break;
252b5132 11434 }
a6e9f9df 11435
b34976b6 11436 len = sizeof (*eopt);
a6e9f9df
AM
11437 while (len < option->size)
11438 if (((char *) option)[len] >= ' '
11439 && ((char *) option)[len] < 0x7f)
11440 printf ("%c", ((char *) option)[len++]);
11441 else
11442 printf ("\\%03o", ((char *) option)[len++]);
11443
11444 fputs ("\n", stdout);
252b5132 11445 ++option;
252b5132
RH
11446 }
11447
a6e9f9df 11448 free (eopt);
252b5132 11449 }
252b5132
RH
11450 }
11451
11452 if (conflicts_offset != 0 && conflictsno != 0)
11453 {
b34976b6 11454 Elf32_Conflict *iconf;
252b5132
RH
11455 size_t cnt;
11456
11457 if (dynamic_symbols == NULL)
11458 {
3a1a2036 11459 error (_("conflict list found without a dynamic symbol table"));
252b5132
RH
11460 return 0;
11461 }
11462
c256ffe7 11463 iconf = cmalloc (conflictsno, sizeof (*iconf));
252b5132
RH
11464 if (iconf == NULL)
11465 {
11466 error (_("Out of memory"));
11467 return 0;
11468 }
11469
9ea033b2 11470 if (is_32bit_elf)
252b5132 11471 {
b34976b6 11472 Elf32_External_Conflict *econf32;
a6e9f9df 11473
d3ba0551 11474 econf32 = get_data (NULL, file, conflicts_offset,
c256ffe7 11475 conflictsno, sizeof (*econf32), _("conflict"));
a6e9f9df
AM
11476 if (!econf32)
11477 return 0;
252b5132
RH
11478
11479 for (cnt = 0; cnt < conflictsno; ++cnt)
11480 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
11481
11482 free (econf32);
252b5132
RH
11483 }
11484 else
11485 {
b34976b6 11486 Elf64_External_Conflict *econf64;
a6e9f9df 11487
d3ba0551 11488 econf64 = get_data (NULL, file, conflicts_offset,
c256ffe7 11489 conflictsno, sizeof (*econf64), _("conflict"));
a6e9f9df
AM
11490 if (!econf64)
11491 return 0;
252b5132
RH
11492
11493 for (cnt = 0; cnt < conflictsno; ++cnt)
11494 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
11495
11496 free (econf64);
252b5132
RH
11497 }
11498
c7e7ca54
NC
11499 printf (_("\nSection '.conflict' contains %lu entries:\n"),
11500 (unsigned long) conflictsno);
252b5132
RH
11501 puts (_(" Num: Index Value Name"));
11502
11503 for (cnt = 0; cnt < conflictsno; ++cnt)
11504 {
b34976b6 11505 Elf_Internal_Sym *psym = & dynamic_symbols[iconf[cnt]];
252b5132 11506
b34976b6 11507 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 11508 print_vma (psym->st_value, FULL_HEX);
31104126 11509 putchar (' ');
d79b3d50
NC
11510 if (VALID_DYNAMIC_NAME (psym->st_name))
11511 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
11512 else
11513 printf ("<corrupt: %14ld>", psym->st_name);
31104126 11514 putchar ('\n');
252b5132
RH
11515 }
11516
252b5132
RH
11517 free (iconf);
11518 }
11519
11520 return 1;
11521}
11522
047b2264 11523static int
d3ba0551 11524process_gnu_liblist (FILE *file)
047b2264 11525{
b34976b6
AM
11526 Elf_Internal_Shdr *section, *string_sec;
11527 Elf32_External_Lib *elib;
11528 char *strtab;
c256ffe7 11529 size_t strtab_size;
047b2264
JJ
11530 size_t cnt;
11531 unsigned i;
11532
11533 if (! do_arch)
11534 return 0;
11535
11536 for (i = 0, section = section_headers;
11537 i < elf_header.e_shnum;
b34976b6 11538 i++, section++)
047b2264
JJ
11539 {
11540 switch (section->sh_type)
11541 {
11542 case SHT_GNU_LIBLIST:
c256ffe7
JJ
11543 if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum)
11544 break;
11545
11546 elib = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
d3ba0551 11547 _("liblist"));
047b2264
JJ
11548
11549 if (elib == NULL)
11550 break;
11551 string_sec = SECTION_HEADER (section->sh_link);
11552
c256ffe7 11553 strtab = get_data (NULL, file, string_sec->sh_offset, 1,
d3ba0551 11554 string_sec->sh_size, _("liblist string table"));
c256ffe7 11555 strtab_size = string_sec->sh_size;
047b2264
JJ
11556
11557 if (strtab == NULL
11558 || section->sh_entsize != sizeof (Elf32_External_Lib))
11559 {
11560 free (elib);
11561 break;
11562 }
11563
11564 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
11565 SECTION_NAME (section),
11566 (long) (section->sh_size / sizeof (Elf32_External_Lib)));
11567
11568 puts (" Library Time Stamp Checksum Version Flags");
11569
11570 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
11571 ++cnt)
11572 {
11573 Elf32_Lib liblist;
11574 time_t time;
11575 char timebuf[20];
b34976b6 11576 struct tm *tmp;
047b2264
JJ
11577
11578 liblist.l_name = BYTE_GET (elib[cnt].l_name);
11579 time = BYTE_GET (elib[cnt].l_time_stamp);
11580 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
11581 liblist.l_version = BYTE_GET (elib[cnt].l_version);
11582 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
11583
11584 tmp = gmtime (&time);
e9e44622
JJ
11585 snprintf (timebuf, sizeof (timebuf),
11586 "%04u-%02u-%02uT%02u:%02u:%02u",
11587 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11588 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11589
11590 printf ("%3lu: ", (unsigned long) cnt);
11591 if (do_wide)
c256ffe7
JJ
11592 printf ("%-20s", liblist.l_name < strtab_size
11593 ? strtab + liblist.l_name : "<corrupt>");
047b2264 11594 else
c256ffe7
JJ
11595 printf ("%-20.20s", liblist.l_name < strtab_size
11596 ? strtab + liblist.l_name : "<corrupt>");
047b2264
JJ
11597 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
11598 liblist.l_version, liblist.l_flags);
11599 }
11600
11601 free (elib);
11602 }
11603 }
11604
11605 return 1;
11606}
11607
9437c45b 11608static const char *
d3ba0551 11609get_note_type (unsigned e_type)
779fe533
NC
11610{
11611 static char buff[64];
103f02d3 11612
1ec5cd37
NC
11613 if (elf_header.e_type == ET_CORE)
11614 switch (e_type)
11615 {
57346661 11616 case NT_AUXV:
1ec5cd37 11617 return _("NT_AUXV (auxiliary vector)");
57346661 11618 case NT_PRSTATUS:
1ec5cd37 11619 return _("NT_PRSTATUS (prstatus structure)");
57346661 11620 case NT_FPREGSET:
1ec5cd37 11621 return _("NT_FPREGSET (floating point registers)");
57346661 11622 case NT_PRPSINFO:
1ec5cd37 11623 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 11624 case NT_TASKSTRUCT:
1ec5cd37 11625 return _("NT_TASKSTRUCT (task structure)");
57346661 11626 case NT_PRXFPREG:
1ec5cd37 11627 return _("NT_PRXFPREG (user_xfpregs structure)");
57346661 11628 case NT_PSTATUS:
1ec5cd37 11629 return _("NT_PSTATUS (pstatus structure)");
57346661 11630 case NT_FPREGS:
1ec5cd37 11631 return _("NT_FPREGS (floating point registers)");
57346661 11632 case NT_PSINFO:
1ec5cd37 11633 return _("NT_PSINFO (psinfo structure)");
57346661 11634 case NT_LWPSTATUS:
1ec5cd37 11635 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 11636 case NT_LWPSINFO:
1ec5cd37 11637 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 11638 case NT_WIN32PSTATUS:
1ec5cd37
NC
11639 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
11640 default:
11641 break;
11642 }
11643 else
11644 switch (e_type)
11645 {
11646 case NT_VERSION:
11647 return _("NT_VERSION (version)");
11648 case NT_ARCH:
11649 return _("NT_ARCH (architecture)");
11650 default:
11651 break;
11652 }
11653
e9e44622 11654 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 11655 return buff;
779fe533
NC
11656}
11657
9437c45b 11658static const char *
d3ba0551 11659get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
11660{
11661 static char buff[64];
11662
b4db1224 11663 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
11664 {
11665 /* NetBSD core "procinfo" structure. */
11666 return _("NetBSD procinfo structure");
11667 }
11668
11669 /* As of Jan 2002 there are no other machine-independent notes
11670 defined for NetBSD core files. If the note type is less
11671 than the start of the machine-dependent note types, we don't
11672 understand it. */
11673
b4db1224 11674 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 11675 {
e9e44622 11676 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
11677 return buff;
11678 }
11679
11680 switch (elf_header.e_machine)
11681 {
11682 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
11683 and PT_GETFPREGS == mach+2. */
11684
11685 case EM_OLD_ALPHA:
11686 case EM_ALPHA:
11687 case EM_SPARC:
11688 case EM_SPARC32PLUS:
11689 case EM_SPARCV9:
11690 switch (e_type)
11691 {
b4db1224
JT
11692 case NT_NETBSDCORE_FIRSTMACH+0:
11693 return _("PT_GETREGS (reg structure)");
11694 case NT_NETBSDCORE_FIRSTMACH+2:
11695 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
11696 default:
11697 break;
11698 }
11699 break;
11700
11701 /* On all other arch's, PT_GETREGS == mach+1 and
11702 PT_GETFPREGS == mach+3. */
11703 default:
11704 switch (e_type)
11705 {
b4db1224
JT
11706 case NT_NETBSDCORE_FIRSTMACH+1:
11707 return _("PT_GETREGS (reg structure)");
11708 case NT_NETBSDCORE_FIRSTMACH+3:
11709 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
11710 default:
11711 break;
11712 }
11713 }
11714
e9e44622
JJ
11715 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
11716 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
11717 return buff;
11718}
11719
6d118b09
NC
11720/* Note that by the ELF standard, the name field is already null byte
11721 terminated, and namesz includes the terminating null byte.
11722 I.E. the value of namesz for the name "FSF" is 4.
11723
e3c8793a 11724 If the value of namesz is zero, there is no name present. */
779fe533 11725static int
d3ba0551 11726process_note (Elf_Internal_Note *pnote)
779fe533 11727{
9437c45b
JT
11728 const char *nt;
11729
11730 if (pnote->namesz == 0)
1ec5cd37
NC
11731 /* If there is no note name, then use the default set of
11732 note type strings. */
11733 nt = get_note_type (pnote->type);
11734
18bd398b 11735 else if (strneq (pnote->namedata, "NetBSD-CORE", 11))
1ec5cd37
NC
11736 /* NetBSD-specific core file notes. */
11737 nt = get_netbsd_elfcore_note_type (pnote->type);
11738
9437c45b 11739 else
1ec5cd37
NC
11740 /* Don't recognize this note name; just use the default set of
11741 note type strings. */
9437c45b 11742 nt = get_note_type (pnote->type);
9437c45b 11743
103f02d3 11744 printf (" %s\t\t0x%08lx\t%s\n",
6d118b09 11745 pnote->namesz ? pnote->namedata : "(NONE)",
9437c45b 11746 pnote->descsz, nt);
779fe533
NC
11747 return 1;
11748}
11749
6d118b09 11750
779fe533 11751static int
d3ba0551 11752process_corefile_note_segment (FILE *file, bfd_vma offset, bfd_vma length)
779fe533 11753{
b34976b6
AM
11754 Elf_External_Note *pnotes;
11755 Elf_External_Note *external;
11756 int res = 1;
103f02d3 11757
779fe533
NC
11758 if (length <= 0)
11759 return 0;
103f02d3 11760
c256ffe7 11761 pnotes = get_data (NULL, file, offset, 1, length, _("notes"));
a6e9f9df
AM
11762 if (!pnotes)
11763 return 0;
779fe533 11764
103f02d3 11765 external = pnotes;
103f02d3 11766
305c7206 11767 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 11768 (unsigned long) offset, (unsigned long) length);
779fe533 11769 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 11770
6d118b09 11771 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 11772 {
b34976b6
AM
11773 Elf_External_Note *next;
11774 Elf_Internal_Note inote;
11775 char *temp = NULL;
6d118b09
NC
11776
11777 inote.type = BYTE_GET (external->type);
11778 inote.namesz = BYTE_GET (external->namesz);
11779 inote.namedata = external->name;
11780 inote.descsz = BYTE_GET (external->descsz);
11781 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
11782 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 11783
3e55a963
NC
11784 next = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
11785
11786 if (((char *) next) > (((char *) pnotes) + length))
11787 {
11788 warn (_("corrupt note found at offset %x into core notes\n"),
11789 ((char *) external) - ((char *) pnotes));
11790 warn (_(" type: %x, namesize: %08lx, descsize: %08lx\n"),
11791 inote.type, inote.namesz, inote.descsz);
11792 break;
11793 }
11794
11795 external = next;
6d118b09
NC
11796
11797 /* Verify that name is null terminated. It appears that at least
11798 one version of Linux (RedHat 6.0) generates corefiles that don't
11799 comply with the ELF spec by failing to include the null byte in
11800 namesz. */
11801 if (inote.namedata[inote.namesz] != '\0')
11802 {
11803 temp = malloc (inote.namesz + 1);
76da6bbe 11804
6d118b09
NC
11805 if (temp == NULL)
11806 {
11807 error (_("Out of memory\n"));
11808 res = 0;
11809 break;
11810 }
76da6bbe 11811
6d118b09
NC
11812 strncpy (temp, inote.namedata, inote.namesz);
11813 temp[inote.namesz] = 0;
76da6bbe 11814
6d118b09
NC
11815 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
11816 inote.namedata = temp;
11817 }
11818
11819 res &= process_note (& inote);
103f02d3 11820
6d118b09
NC
11821 if (temp != NULL)
11822 {
11823 free (temp);
11824 temp = NULL;
11825 }
779fe533
NC
11826 }
11827
11828 free (pnotes);
103f02d3 11829
779fe533
NC
11830 return res;
11831}
11832
11833static int
d3ba0551 11834process_corefile_note_segments (FILE *file)
779fe533 11835{
b34976b6
AM
11836 Elf_Internal_Phdr *segment;
11837 unsigned int i;
11838 int res = 1;
103f02d3 11839
d93f0186 11840 if (! get_program_headers (file))
779fe533 11841 return 0;
103f02d3 11842
779fe533
NC
11843 for (i = 0, segment = program_headers;
11844 i < elf_header.e_phnum;
b34976b6 11845 i++, segment++)
779fe533
NC
11846 {
11847 if (segment->p_type == PT_NOTE)
103f02d3 11848 res &= process_corefile_note_segment (file,
30800947
NC
11849 (bfd_vma) segment->p_offset,
11850 (bfd_vma) segment->p_filesz);
779fe533 11851 }
103f02d3 11852
779fe533
NC
11853 return res;
11854}
11855
11856static int
1ec5cd37
NC
11857process_note_sections (FILE *file)
11858{
11859 Elf_Internal_Shdr *section;
11860 unsigned long i;
11861 int res = 1;
11862
11863 for (i = 0, section = section_headers;
11864 i < elf_header.e_shnum;
11865 i++, section++)
11866 if (section->sh_type == SHT_NOTE)
11867 res &= process_corefile_note_segment (file,
11868 (bfd_vma) section->sh_offset,
11869 (bfd_vma) section->sh_size);
11870
11871 return res;
11872}
11873
11874static int
11875process_notes (FILE *file)
779fe533
NC
11876{
11877 /* If we have not been asked to display the notes then do nothing. */
11878 if (! do_notes)
11879 return 1;
103f02d3 11880
779fe533 11881 if (elf_header.e_type != ET_CORE)
1ec5cd37 11882 return process_note_sections (file);
103f02d3 11883
779fe533 11884 /* No program headers means no NOTE segment. */
1ec5cd37
NC
11885 if (elf_header.e_phnum > 0)
11886 return process_corefile_note_segments (file);
779fe533 11887
1ec5cd37
NC
11888 printf (_("No note segments present in the core file.\n"));
11889 return 1;
779fe533
NC
11890}
11891
252b5132 11892static int
d3ba0551 11893process_arch_specific (FILE *file)
252b5132 11894{
a952a375
NC
11895 if (! do_arch)
11896 return 1;
11897
252b5132
RH
11898 switch (elf_header.e_machine)
11899 {
11900 case EM_MIPS:
4fe85591 11901 case EM_MIPS_RS3_LE:
252b5132
RH
11902 return process_mips_specific (file);
11903 break;
11904 default:
11905 break;
11906 }
11907 return 1;
11908}
11909
11910static int
d3ba0551 11911get_file_header (FILE *file)
252b5132 11912{
9ea033b2
NC
11913 /* Read in the identity array. */
11914 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
11915 return 0;
11916
9ea033b2 11917 /* Determine how to read the rest of the header. */
b34976b6 11918 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
11919 {
11920 default: /* fall through */
11921 case ELFDATANONE: /* fall through */
adab8cdc
AO
11922 case ELFDATA2LSB:
11923 byte_get = byte_get_little_endian;
11924 byte_put = byte_put_little_endian;
11925 break;
11926 case ELFDATA2MSB:
11927 byte_get = byte_get_big_endian;
11928 byte_put = byte_put_big_endian;
11929 break;
9ea033b2
NC
11930 }
11931
11932 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 11933 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
11934
11935 /* Read in the rest of the header. */
11936 if (is_32bit_elf)
11937 {
11938 Elf32_External_Ehdr ehdr32;
252b5132 11939
9ea033b2
NC
11940 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
11941 return 0;
103f02d3 11942
9ea033b2
NC
11943 elf_header.e_type = BYTE_GET (ehdr32.e_type);
11944 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
11945 elf_header.e_version = BYTE_GET (ehdr32.e_version);
11946 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
11947 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
11948 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
11949 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
11950 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
11951 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
11952 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
11953 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
11954 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
11955 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
11956 }
252b5132 11957 else
9ea033b2
NC
11958 {
11959 Elf64_External_Ehdr ehdr64;
a952a375
NC
11960
11961 /* If we have been compiled with sizeof (bfd_vma) == 4, then
11962 we will not be able to cope with the 64bit data found in
11963 64 ELF files. Detect this now and abort before we start
50c2245b 11964 overwriting things. */
a952a375
NC
11965 if (sizeof (bfd_vma) < 8)
11966 {
e3c8793a
NC
11967 error (_("This instance of readelf has been built without support for a\n\
1196864 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
11969 return 0;
11970 }
103f02d3 11971
9ea033b2
NC
11972 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
11973 return 0;
103f02d3 11974
9ea033b2
NC
11975 elf_header.e_type = BYTE_GET (ehdr64.e_type);
11976 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
11977 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
11978 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
11979 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
11980 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
11981 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
11982 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
11983 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
11984 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
11985 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
11986 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
11987 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
11988 }
252b5132 11989
7ece0d85
JJ
11990 if (elf_header.e_shoff)
11991 {
11992 /* There may be some extensions in the first section header. Don't
11993 bomb if we can't read it. */
11994 if (is_32bit_elf)
11995 get_32bit_section_headers (file, 1);
11996 else
11997 get_64bit_section_headers (file, 1);
11998 }
560f3c1c 11999
252b5132
RH
12000 return 1;
12001}
12002
fb52b2f4
NC
12003/* Process one ELF object file according to the command line options.
12004 This file may actually be stored in an archive. The file is
12005 positioned at the start of the ELF object. */
12006
ff78d6d6 12007static int
fb52b2f4 12008process_object (char *file_name, FILE *file)
252b5132 12009{
252b5132
RH
12010 unsigned int i;
12011
252b5132
RH
12012 if (! get_file_header (file))
12013 {
12014 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 12015 return 1;
252b5132
RH
12016 }
12017
12018 /* Initialise per file variables. */
12019 for (i = NUM_ELEM (version_info); i--;)
12020 version_info[i] = 0;
12021
12022 for (i = NUM_ELEM (dynamic_info); i--;)
12023 dynamic_info[i] = 0;
12024
12025 /* Process the file. */
12026 if (show_name)
12027 printf (_("\nFile: %s\n"), file_name);
12028
18bd398b
NC
12029 /* Initialise the dump_sects array from the cmdline_dump_sects array.
12030 Note we do this even if cmdline_dump_sects is empty because we
12031 must make sure that the dump_sets array is zeroed out before each
12032 object file is processed. */
12033 if (num_dump_sects > num_cmdline_dump_sects)
12034 memset (dump_sects, 0, num_dump_sects);
12035
12036 if (num_cmdline_dump_sects > 0)
12037 {
12038 if (num_dump_sects == 0)
12039 /* A sneaky way of allocating the dump_sects array. */
12040 request_dump (num_cmdline_dump_sects, 0);
12041
12042 assert (num_dump_sects >= num_cmdline_dump_sects);
12043 memcpy (dump_sects, cmdline_dump_sects, num_cmdline_dump_sects);
12044 }
12045
252b5132 12046 if (! process_file_header ())
fb52b2f4 12047 return 1;
252b5132 12048
d1f5c6e3 12049 if (! process_section_headers (file))
2f62977e 12050 {
d1f5c6e3
L
12051 /* Without loaded section headers we cannot process lots of
12052 things. */
2f62977e 12053 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 12054
2f62977e
NC
12055 if (! do_using_dynamic)
12056 do_syms = do_reloc = 0;
12057 }
252b5132 12058
d1f5c6e3
L
12059 if (! process_section_groups (file))
12060 {
12061 /* Without loaded section groups we cannot process unwind. */
12062 do_unwind = 0;
12063 }
12064
2f62977e 12065 if (process_program_headers (file))
b2d38a17 12066 process_dynamic_section (file);
252b5132
RH
12067
12068 process_relocs (file);
12069
4d6ed7c8
NC
12070 process_unwind (file);
12071
252b5132
RH
12072 process_symbol_table (file);
12073
12074 process_syminfo (file);
12075
12076 process_version_sections (file);
12077
12078 process_section_contents (file);
f5842774 12079
1ec5cd37 12080 process_notes (file);
103f02d3 12081
047b2264
JJ
12082 process_gnu_liblist (file);
12083
252b5132
RH
12084 process_arch_specific (file);
12085
d93f0186
NC
12086 if (program_headers)
12087 {
12088 free (program_headers);
12089 program_headers = NULL;
12090 }
12091
252b5132
RH
12092 if (section_headers)
12093 {
12094 free (section_headers);
12095 section_headers = NULL;
12096 }
12097
12098 if (string_table)
12099 {
12100 free (string_table);
12101 string_table = NULL;
d40ac9bd 12102 string_table_length = 0;
252b5132
RH
12103 }
12104
12105 if (dynamic_strings)
12106 {
12107 free (dynamic_strings);
12108 dynamic_strings = NULL;
d79b3d50 12109 dynamic_strings_length = 0;
252b5132
RH
12110 }
12111
12112 if (dynamic_symbols)
12113 {
12114 free (dynamic_symbols);
12115 dynamic_symbols = NULL;
19936277 12116 num_dynamic_syms = 0;
252b5132
RH
12117 }
12118
12119 if (dynamic_syminfo)
12120 {
12121 free (dynamic_syminfo);
12122 dynamic_syminfo = NULL;
12123 }
ff78d6d6 12124
e4b17d5c
L
12125 if (section_headers_groups)
12126 {
12127 free (section_headers_groups);
12128 section_headers_groups = NULL;
12129 }
12130
12131 if (section_groups)
12132 {
12133 struct group_list *g, *next;
12134
12135 for (i = 0; i < group_count; i++)
12136 {
12137 for (g = section_groups [i].root; g != NULL; g = next)
12138 {
12139 next = g->next;
12140 free (g);
12141 }
12142 }
12143
12144 free (section_groups);
12145 section_groups = NULL;
12146 }
12147
18bd398b
NC
12148 if (debug_information)
12149 {
5b18a4bc 12150 for (i = 0; i < num_debug_info_entries; i++)
0853c092
L
12151 {
12152 if (!debug_information [i].max_loc_offsets)
12153 {
12154 free (debug_information [i].loc_offsets);
12155 free (debug_information [i].have_frame_base);
12156 }
12157 if (!debug_information [i].max_range_lists)
12158 free (debug_information [i].range_lists);
12159 }
18bd398b
NC
12160 free (debug_information);
12161 debug_information = NULL;
12162 num_debug_info_entries = 0;
12163 }
12164
ff78d6d6 12165 return 0;
252b5132
RH
12166}
12167
fb52b2f4
NC
12168/* Process an ELF archive. The file is positioned just after the
12169 ARMAG string. */
12170
12171static int
12172process_archive (char *file_name, FILE *file)
12173{
12174 struct ar_hdr arhdr;
12175 size_t got;
12176 unsigned long size;
12177 char *longnames = NULL;
12178 unsigned long longnames_size = 0;
12179 size_t file_name_size;
d989285c 12180 int ret;
fb52b2f4
NC
12181
12182 show_name = 1;
12183
12184 got = fread (&arhdr, 1, sizeof arhdr, file);
12185 if (got != sizeof arhdr)
12186 {
12187 if (got == 0)
12188 return 0;
12189
12190 error (_("%s: failed to read archive header\n"), file_name);
12191 return 1;
12192 }
12193
12194 if (memcmp (arhdr.ar_name, "/ ", 16) == 0)
12195 {
12196 /* This is the archive symbol table. Skip it.
12197 FIXME: We should have an option to dump it. */
12198 size = strtoul (arhdr.ar_size, NULL, 10);
12199 if (fseek (file, size + (size & 1), SEEK_CUR) != 0)
12200 {
12201 error (_("%s: failed to skip archive symbol table\n"), file_name);
12202 return 1;
12203 }
12204
12205 got = fread (&arhdr, 1, sizeof arhdr, file);
12206 if (got != sizeof arhdr)
12207 {
12208 if (got == 0)
12209 return 0;
12210
12211 error (_("%s: failed to read archive header\n"), file_name);
12212 return 1;
12213 }
12214 }
12215
12216 if (memcmp (arhdr.ar_name, "// ", 16) == 0)
12217 {
12218 /* This is the archive string table holding long member
12219 names. */
12220
12221 longnames_size = strtoul (arhdr.ar_size, NULL, 10);
12222
12223 longnames = malloc (longnames_size);
12224 if (longnames == NULL)
12225 {
12226 error (_("Out of memory\n"));
12227 return 1;
12228 }
12229
12230 if (fread (longnames, longnames_size, 1, file) != 1)
12231 {
d989285c 12232 free (longnames);
18bd398b 12233 error (_("%s: failed to read string table\n"), file_name);
fb52b2f4
NC
12234 return 1;
12235 }
12236
12237 if ((longnames_size & 1) != 0)
12238 getc (file);
12239
12240 got = fread (&arhdr, 1, sizeof arhdr, file);
12241 if (got != sizeof arhdr)
12242 {
d989285c
ILT
12243 free (longnames);
12244
fb52b2f4
NC
12245 if (got == 0)
12246 return 0;
12247
12248 error (_("%s: failed to read archive header\n"), file_name);
12249 return 1;
12250 }
12251 }
12252
12253 file_name_size = strlen (file_name);
d989285c 12254 ret = 0;
fb52b2f4
NC
12255
12256 while (1)
12257 {
12258 char *name;
12259 char *nameend;
12260 char *namealc;
12261
12262 if (arhdr.ar_name[0] == '/')
12263 {
12264 unsigned long off;
12265
12266 off = strtoul (arhdr.ar_name + 1, NULL, 10);
12267 if (off >= longnames_size)
12268 {
12269 error (_("%s: invalid archive string table offset %lu\n"), off);
d989285c
ILT
12270 ret = 1;
12271 break;
fb52b2f4
NC
12272 }
12273
12274 name = longnames + off;
12275 nameend = memchr (name, '/', longnames_size - off);
12276 }
12277 else
12278 {
12279 name = arhdr.ar_name;
12280 nameend = memchr (name, '/', 16);
12281 }
12282
12283 if (nameend == NULL)
12284 {
12285 error (_("%s: bad archive file name\n"));
d989285c
ILT
12286 ret = 1;
12287 break;
fb52b2f4
NC
12288 }
12289
12290 namealc = malloc (file_name_size + (nameend - name) + 3);
12291 if (namealc == NULL)
12292 {
12293 error (_("Out of memory\n"));
d989285c
ILT
12294 ret = 1;
12295 break;
fb52b2f4
NC
12296 }
12297
12298 memcpy (namealc, file_name, file_name_size);
12299 namealc[file_name_size] = '(';
12300 memcpy (namealc + file_name_size + 1, name, nameend - name);
12301 namealc[file_name_size + 1 + (nameend - name)] = ')';
12302 namealc[file_name_size + 2 + (nameend - name)] = '\0';
12303
12304 archive_file_offset = ftell (file);
12305 archive_file_size = strtoul (arhdr.ar_size, NULL, 10);
18bd398b 12306
d989285c 12307 ret |= process_object (namealc, file);
fb52b2f4
NC
12308
12309 free (namealc);
12310
12311 if (fseek (file,
12312 (archive_file_offset
12313 + archive_file_size
12314 + (archive_file_size & 1)),
12315 SEEK_SET) != 0)
12316 {
12317 error (_("%s: failed to seek to next archive header\n"), file_name);
d989285c
ILT
12318 ret = 1;
12319 break;
fb52b2f4
NC
12320 }
12321
12322 got = fread (&arhdr, 1, sizeof arhdr, file);
12323 if (got != sizeof arhdr)
12324 {
12325 if (got == 0)
d989285c 12326 break;
fb52b2f4
NC
12327
12328 error (_("%s: failed to read archive header\n"), file_name);
d989285c
ILT
12329 ret = 1;
12330 break;
fb52b2f4
NC
12331 }
12332 }
12333
12334 if (longnames != 0)
12335 free (longnames);
12336
d989285c 12337 return ret;
fb52b2f4
NC
12338}
12339
12340static int
12341process_file (char *file_name)
12342{
12343 FILE *file;
12344 struct stat statbuf;
12345 char armag[SARMAG];
12346 int ret;
12347
12348 if (stat (file_name, &statbuf) < 0)
12349 {
f24ddbdd
NC
12350 if (errno == ENOENT)
12351 error (_("'%s': No such file\n"), file_name);
12352 else
12353 error (_("Could not locate '%s'. System error message: %s\n"),
12354 file_name, strerror (errno));
12355 return 1;
12356 }
12357
12358 if (! S_ISREG (statbuf.st_mode))
12359 {
12360 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
12361 return 1;
12362 }
12363
12364 file = fopen (file_name, "rb");
12365 if (file == NULL)
12366 {
f24ddbdd 12367 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
12368 return 1;
12369 }
12370
12371 if (fread (armag, SARMAG, 1, file) != 1)
12372 {
12373 error (_("%s: Failed to read file header\n"), file_name);
12374 fclose (file);
12375 return 1;
12376 }
12377
12378 if (memcmp (armag, ARMAG, SARMAG) == 0)
12379 ret = process_archive (file_name, file);
12380 else
12381 {
12382 rewind (file);
12383 archive_file_size = archive_file_offset = 0;
12384 ret = process_object (file_name, file);
12385 }
12386
12387 fclose (file);
12388
12389 return ret;
12390}
12391
252b5132
RH
12392#ifdef SUPPORT_DISASSEMBLY
12393/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 12394 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 12395 symbols. */
252b5132
RH
12396
12397void
b34976b6 12398print_address (unsigned int addr, FILE *outfile)
252b5132
RH
12399{
12400 fprintf (outfile,"0x%8.8x", addr);
12401}
12402
e3c8793a 12403/* Needed by the i386 disassembler. */
252b5132
RH
12404void
12405db_task_printsym (unsigned int addr)
12406{
12407 print_address (addr, stderr);
12408}
12409#endif
12410
12411int
d3ba0551 12412main (int argc, char **argv)
252b5132 12413{
ff78d6d6
L
12414 int err;
12415
252b5132
RH
12416#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
12417 setlocale (LC_MESSAGES, "");
3882b010
L
12418#endif
12419#if defined (HAVE_SETLOCALE)
12420 setlocale (LC_CTYPE, "");
252b5132
RH
12421#endif
12422 bindtextdomain (PACKAGE, LOCALEDIR);
12423 textdomain (PACKAGE);
12424
12425 parse_args (argc, argv);
12426
18bd398b 12427 if (num_dump_sects > 0)
59f14fc0 12428 {
18bd398b 12429 /* Make a copy of the dump_sects array. */
59f14fc0
AS
12430 cmdline_dump_sects = malloc (num_dump_sects);
12431 if (cmdline_dump_sects == NULL)
12432 error (_("Out of memory allocating dump request table."));
12433 else
12434 {
12435 memcpy (cmdline_dump_sects, dump_sects, num_dump_sects);
12436 num_cmdline_dump_sects = num_dump_sects;
12437 }
12438 }
12439
18bd398b
NC
12440 if (optind < (argc - 1))
12441 show_name = 1;
12442
ff78d6d6 12443 err = 0;
252b5132 12444 while (optind < argc)
18bd398b 12445 err |= process_file (argv[optind++]);
252b5132
RH
12446
12447 if (dump_sects != NULL)
12448 free (dump_sects);
59f14fc0
AS
12449 if (cmdline_dump_sects != NULL)
12450 free (cmdline_dump_sects);
252b5132 12451
ff78d6d6 12452 return err;
252b5132 12453}