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