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