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