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