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