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