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