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