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