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