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