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