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