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