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