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