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