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