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