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