]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
* symbols.c (colon) [!WORKING_DOT_WORD]: Don't declare
[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);
4d6ed7c8
NC
4424 }
4425 else
4426 {
4427 relname = elf_ia64_reloc_type (ELF64_R_TYPE (rp->r_info));
4428 sym = aux->symtab + ELF64_R_SYM (rp->r_info);
4d6ed7c8
NC
4429 }
4430
4431 if (strncmp (relname, "R_IA64_SEGREL", 13) != 0)
4432 {
e5fb9629 4433 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
4434 continue;
4435 }
4436
4437 i = rp->r_offset / (3 * addr_size);
4438
4439 switch (rp->r_offset/addr_size % 3)
4440 {
4441 case 0:
4442 aux->table[i].start.section = sym->st_shndx;
1ffa9a18 4443 aux->table[i].start.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
4444 break;
4445 case 1:
4446 aux->table[i].end.section = sym->st_shndx;
1ffa9a18 4447 aux->table[i].end.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
4448 break;
4449 case 2:
4450 aux->table[i].info.section = sym->st_shndx;
1ffa9a18 4451 aux->table[i].info.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
4452 break;
4453 default:
4454 break;
4455 }
4456 }
4457
4458 free (rela);
4459 }
4460
4461 aux->table_len = size / (3 * addr_size);
4462 return 1;
4463}
4464
4465static int
d3ba0551 4466process_unwind (FILE *file)
4d6ed7c8 4467{
c8286bd1 4468 Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
579f31ac 4469 unsigned long i, addr_size, unwcount = 0, unwstart = 0;
4d6ed7c8
NC
4470 struct unw_aux_info aux;
4471
e58d53af
L
4472 if (!do_unwind)
4473 return 1;
4474
f1467e33
L
4475 if (elf_header.e_machine != EM_IA_64)
4476 {
4477 printf (_("\nThere are no unwind sections in this file.\n"));
4478 return 1;
4479 }
4480
4d6ed7c8
NC
4481 memset (& aux, 0, sizeof (aux));
4482
4483 addr_size = is_32bit_elf ? 4 : 8;
4484
4d6ed7c8
NC
4485 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
4486 {
4487 if (sec->sh_type == SHT_SYMTAB)
4488 {
4489 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 4490 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 4491
9ad5cbcf 4492 strsec = SECTION_HEADER (sec->sh_link);
4d6ed7c8 4493 aux.strtab_size = strsec->sh_size;
d3ba0551
AM
4494 aux.strtab = get_data (NULL, file, strsec->sh_offset,
4495 aux.strtab_size, _("string table"));
4d6ed7c8
NC
4496 }
4497 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
4498 unwcount++;
4499 }
4500
4501 if (!unwcount)
4502 printf (_("\nThere are no unwind sections in this file.\n"));
4503
4504 while (unwcount-- > 0)
4505 {
4506 char *suffix;
4507 size_t len, len2;
4508
4509 for (i = unwstart, sec = section_headers + unwstart;
4510 i < elf_header.e_shnum; ++i, ++sec)
4511 if (sec->sh_type == SHT_IA_64_UNWIND)
4512 {
4513 unwsec = sec;
4514 break;
4515 }
4516
4517 unwstart = i + 1;
4518 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
4519
e4b17d5c
L
4520 if ((unwsec->sh_flags & SHF_GROUP) != 0)
4521 {
4522 /* We need to find which section group it is in. */
4523 struct group_list *g = section_headers_groups [i]->root;
4524
4525 for (; g != NULL; g = g->next)
4526 {
4527 sec = SECTION_HEADER (g->section_index);
4528 if (strcmp (SECTION_NAME (sec),
4529 ELF_STRING_ia64_unwind_info) == 0)
4530 break;
4531 }
4532
4533 if (g == NULL)
4534 i = elf_header.e_shnum;
4535 }
4536 else if (strncmp (SECTION_NAME (unwsec),
4537 ELF_STRING_ia64_unwind_once, len) == 0)
579f31ac
JJ
4538 {
4539 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO */
4540 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
4541 suffix = SECTION_NAME (unwsec) + len;
4542 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
4543 ++i, ++sec)
4544 if (strncmp (SECTION_NAME (sec),
4545 ELF_STRING_ia64_unwind_info_once, len2) == 0
4546 && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
4547 break;
4548 }
4549 else
4550 {
4551 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
4552 .IA_64.unwind or BAR -> .IA_64.unwind_info */
4553 len = sizeof (ELF_STRING_ia64_unwind) - 1;
4554 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
4555 suffix = "";
4556 if (strncmp (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind,
4557 len) == 0)
4558 suffix = SECTION_NAME (unwsec) + len;
4559 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
4560 ++i, ++sec)
4561 if (strncmp (SECTION_NAME (sec),
4562 ELF_STRING_ia64_unwind_info, len2) == 0
4563 && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
4564 break;
4565 }
4566
4567 if (i == elf_header.e_shnum)
4568 {
4569 printf (_("\nCould not find unwind info section for "));
4570
4571 if (string_table == NULL)
4572 printf ("%d", unwsec->sh_name);
4573 else
3a1a2036 4574 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
4575 }
4576 else
4d6ed7c8
NC
4577 {
4578 aux.info_size = sec->sh_size;
4579 aux.info_addr = sec->sh_addr;
d3ba0551
AM
4580 aux.info = get_data (NULL, file, sec->sh_offset, aux.info_size,
4581 _("unwind info"));
4d6ed7c8 4582
579f31ac 4583 printf (_("\nUnwind section "));
4d6ed7c8 4584
579f31ac
JJ
4585 if (string_table == NULL)
4586 printf ("%d", unwsec->sh_name);
4587 else
3a1a2036 4588 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 4589
579f31ac 4590 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 4591 (unsigned long) unwsec->sh_offset,
579f31ac 4592 (unsigned long) (unwsec->sh_size / (3 * addr_size)));
4d6ed7c8 4593
579f31ac 4594 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 4595
579f31ac
JJ
4596 if (aux.table_len > 0)
4597 dump_ia64_unwind (& aux);
4598
4599 if (aux.table)
4600 free ((char *) aux.table);
4601 if (aux.info)
4602 free ((char *) aux.info);
4603 aux.table = NULL;
4604 aux.info = NULL;
4605 }
4d6ed7c8 4606 }
4d6ed7c8 4607
4d6ed7c8
NC
4608 if (aux.symtab)
4609 free (aux.symtab);
4610 if (aux.strtab)
4611 free ((char *) aux.strtab);
4612
4613 return 1;
4614}
4615
252b5132 4616static void
b2d38a17 4617dynamic_section_mips_val (Elf_Internal_Dyn *entry)
252b5132
RH
4618{
4619 switch (entry->d_tag)
4620 {
4621 case DT_MIPS_FLAGS:
4622 if (entry->d_un.d_val == 0)
4623 printf ("NONE\n");
4624 else
4625 {
4626 static const char * opts[] =
4627 {
4628 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
4629 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
4630 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
4631 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
4632 "RLD_ORDER_SAFE"
4633 };
4634 unsigned int cnt;
4635 int first = 1;
b34976b6 4636 for (cnt = 0; cnt < NUM_ELEM (opts); ++cnt)
252b5132
RH
4637 if (entry->d_un.d_val & (1 << cnt))
4638 {
4639 printf ("%s%s", first ? "" : " ", opts[cnt]);
4640 first = 0;
4641 }
4642 puts ("");
4643 }
4644 break;
103f02d3 4645
252b5132 4646 case DT_MIPS_IVERSION:
d79b3d50
NC
4647 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4648 printf ("Interface Version: %s\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 4649 else
d79b3d50 4650 printf ("<corrupt: %ld>\n", (long) entry->d_un.d_ptr);
252b5132 4651 break;
103f02d3 4652
252b5132
RH
4653 case DT_MIPS_TIME_STAMP:
4654 {
4655 char timebuf[20];
b34976b6 4656 struct tm *tmp;
50da7a9c 4657
252b5132 4658 time_t time = entry->d_un.d_val;
50da7a9c
NC
4659 tmp = gmtime (&time);
4660 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
4661 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
4662 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
4663 printf ("Time Stamp: %s\n", timebuf);
4664 }
4665 break;
103f02d3 4666
252b5132
RH
4667 case DT_MIPS_RLD_VERSION:
4668 case DT_MIPS_LOCAL_GOTNO:
4669 case DT_MIPS_CONFLICTNO:
4670 case DT_MIPS_LIBLISTNO:
4671 case DT_MIPS_SYMTABNO:
4672 case DT_MIPS_UNREFEXTNO:
4673 case DT_MIPS_HIPAGENO:
4674 case DT_MIPS_DELTA_CLASS_NO:
4675 case DT_MIPS_DELTA_INSTANCE_NO:
4676 case DT_MIPS_DELTA_RELOC_NO:
4677 case DT_MIPS_DELTA_SYM_NO:
4678 case DT_MIPS_DELTA_CLASSSYM_NO:
4679 case DT_MIPS_COMPACT_SIZE:
4680 printf ("%ld\n", (long) entry->d_un.d_ptr);
4681 break;
103f02d3
UD
4682
4683 default:
4684 printf ("%#lx\n", (long) entry->d_un.d_ptr);
4685 }
4686}
4687
4688
4689static void
b2d38a17 4690dynamic_section_parisc_val (Elf_Internal_Dyn *entry)
103f02d3
UD
4691{
4692 switch (entry->d_tag)
4693 {
4694 case DT_HP_DLD_FLAGS:
4695 {
4696 static struct
4697 {
4698 long int bit;
b34976b6 4699 const char *str;
5e220199
NC
4700 }
4701 flags[] =
4702 {
4703 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
4704 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
4705 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
4706 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
4707 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
4708 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
4709 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
4710 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
4711 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
4712 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
4713 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" }
4714 };
103f02d3 4715 int first = 1;
5e220199 4716 size_t cnt;
f7a99963 4717 bfd_vma val = entry->d_un.d_val;
103f02d3
UD
4718
4719 for (cnt = 0; cnt < sizeof (flags) / sizeof (flags[0]); ++cnt)
4720 if (val & flags[cnt].bit)
30800947
NC
4721 {
4722 if (! first)
4723 putchar (' ');
4724 fputs (flags[cnt].str, stdout);
4725 first = 0;
4726 val ^= flags[cnt].bit;
4727 }
76da6bbe 4728
103f02d3 4729 if (val != 0 || first)
f7a99963
NC
4730 {
4731 if (! first)
4732 putchar (' ');
4733 print_vma (val, HEX);
4734 }
103f02d3
UD
4735 }
4736 break;
76da6bbe 4737
252b5132 4738 default:
f7a99963
NC
4739 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
4740 break;
252b5132 4741 }
35b1837e 4742 putchar ('\n');
252b5132
RH
4743}
4744
ecc51f48 4745static void
b2d38a17 4746dynamic_section_ia64_val (Elf_Internal_Dyn *entry)
ecc51f48
NC
4747{
4748 switch (entry->d_tag)
4749 {
0de14b54 4750 case DT_IA_64_PLT_RESERVE:
bdf4d63a 4751 /* First 3 slots reserved. */
ecc51f48
NC
4752 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
4753 printf (" -- ");
4754 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
4755 break;
4756
4757 default:
4758 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
4759 break;
ecc51f48 4760 }
bdf4d63a 4761 putchar ('\n');
ecc51f48
NC
4762}
4763
252b5132 4764static int
b2d38a17 4765get_32bit_dynamic_section (FILE *file)
252b5132 4766{
fb514b26 4767 Elf32_External_Dyn *edyn, *ext;
b34976b6 4768 Elf_Internal_Dyn *entry;
103f02d3 4769
d3ba0551 4770 edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
b2d38a17 4771 _("dynamic section"));
a6e9f9df
AM
4772 if (!edyn)
4773 return 0;
103f02d3 4774
ba2685cc
AM
4775/* SGI's ELF has more than one section in the DYNAMIC segment, and we
4776 might not have the luxury of section headers. Look for the DT_NULL
4777 terminator to determine the number of entries. */
4778 for (ext = edyn, dynamic_nent = 0;
4779 (char *) ext < (char *) edyn + dynamic_size;
4780 ext++)
4781 {
4782 dynamic_nent++;
4783 if (BYTE_GET (ext->d_tag) == DT_NULL)
4784 break;
4785 }
252b5132 4786
ba2685cc 4787 dynamic_section = malloc (dynamic_nent * sizeof (*entry));
b2d38a17 4788 if (dynamic_section == NULL)
252b5132 4789 {
9ea033b2
NC
4790 error (_("Out of memory\n"));
4791 free (edyn);
4792 return 0;
4793 }
252b5132 4794
fb514b26 4795 for (ext = edyn, entry = dynamic_section;
ba2685cc 4796 entry < dynamic_section + dynamic_nent;
fb514b26 4797 ext++, entry++)
9ea033b2 4798 {
fb514b26
AM
4799 entry->d_tag = BYTE_GET (ext->d_tag);
4800 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
4801 }
4802
9ea033b2
NC
4803 free (edyn);
4804
4805 return 1;
4806}
4807
4808static int
b2d38a17 4809get_64bit_dynamic_section (FILE *file)
9ea033b2 4810{
fb514b26 4811 Elf64_External_Dyn *edyn, *ext;
b34976b6 4812 Elf_Internal_Dyn *entry;
103f02d3 4813
d3ba0551 4814 edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
b2d38a17 4815 _("dynamic section"));
a6e9f9df
AM
4816 if (!edyn)
4817 return 0;
103f02d3 4818
ba2685cc
AM
4819/* SGI's ELF has more than one section in the DYNAMIC segment, and we
4820 might not have the luxury of section headers. Look for the DT_NULL
4821 terminator to determine the number of entries. */
4822 for (ext = edyn, dynamic_nent = 0;
4823 (char *) ext < (char *) edyn + dynamic_size;
4824 ext++)
4825 {
4826 dynamic_nent++;
4827 if (BYTE_GET8 (ext->d_tag) == DT_NULL)
4828 break;
4829 }
252b5132 4830
ba2685cc 4831 dynamic_section = malloc (dynamic_nent * sizeof (*entry));
b2d38a17 4832 if (dynamic_section == NULL)
252b5132
RH
4833 {
4834 error (_("Out of memory\n"));
4835 free (edyn);
4836 return 0;
4837 }
4838
fb514b26 4839 for (ext = edyn, entry = dynamic_section;
ba2685cc 4840 entry < dynamic_section + dynamic_nent;
fb514b26 4841 ext++, entry++)
252b5132 4842 {
fb514b26
AM
4843 entry->d_tag = BYTE_GET8 (ext->d_tag);
4844 entry->d_un.d_val = BYTE_GET8 (ext->d_un.d_val);
252b5132
RH
4845 }
4846
4847 free (edyn);
4848
9ea033b2
NC
4849 return 1;
4850}
4851
d1133906 4852static const char *
d3ba0551 4853get_dynamic_flags (bfd_vma flags)
d1133906 4854{
b34976b6 4855 static char buff[128];
13ae64f3
JJ
4856 char *p = buff;
4857
4858 *p = '\0';
d1133906
NC
4859 while (flags)
4860 {
4861 bfd_vma flag;
4862
4863 flag = flags & - flags;
4864 flags &= ~ flag;
4865
13ae64f3
JJ
4866 if (p != buff)
4867 *p++ = ' ';
4868
d1133906
NC
4869 switch (flag)
4870 {
b34976b6
AM
4871 case DF_ORIGIN: strcpy (p, "ORIGIN"); break;
4872 case DF_SYMBOLIC: strcpy (p, "SYMBOLIC"); break;
4873 case DF_TEXTREL: strcpy (p, "TEXTREL"); break;
4874 case DF_BIND_NOW: strcpy (p, "BIND_NOW"); break;
4875 case DF_STATIC_TLS: strcpy (p, "STATIC_TLS"); break;
4876 default: strcpy (p, "unknown"); break;
d1133906 4877 }
13ae64f3
JJ
4878
4879 p = strchr (p, '\0');
d1133906 4880 }
305c7206 4881 return buff;
d1133906
NC
4882}
4883
b2d38a17
NC
4884/* Parse and display the contents of the dynamic section. */
4885
9ea033b2 4886static int
b2d38a17 4887process_dynamic_section (FILE *file)
9ea033b2 4888{
b34976b6 4889 Elf_Internal_Dyn *entry;
9ea033b2
NC
4890
4891 if (dynamic_size == 0)
4892 {
4893 if (do_dynamic)
b2d38a17 4894 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
4895
4896 return 1;
4897 }
4898
4899 if (is_32bit_elf)
4900 {
b2d38a17 4901 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
4902 return 0;
4903 }
b2d38a17 4904 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
4905 return 0;
4906
252b5132
RH
4907 /* Find the appropriate symbol table. */
4908 if (dynamic_symbols == NULL)
4909 {
86dba8ee
AM
4910 for (entry = dynamic_section;
4911 entry < dynamic_section + dynamic_nent;
4912 ++entry)
252b5132 4913 {
c8286bd1 4914 Elf_Internal_Shdr section;
252b5132
RH
4915
4916 if (entry->d_tag != DT_SYMTAB)
4917 continue;
4918
4919 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
4920
4921 /* Since we do not know how big the symbol table is,
4922 we default to reading in the entire file (!) and
4923 processing that. This is overkill, I know, but it
e3c8793a 4924 should work. */
d93f0186 4925 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 4926
fb52b2f4
NC
4927 if (archive_file_offset != 0)
4928 section.sh_size = archive_file_size - section.sh_offset;
4929 else
4930 {
4931 if (fseek (file, 0, SEEK_END))
4932 error (_("Unable to seek to end of file!"));
4933
4934 section.sh_size = ftell (file) - section.sh_offset;
4935 }
252b5132 4936
9ea033b2 4937 if (is_32bit_elf)
9ad5cbcf 4938 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 4939 else
9ad5cbcf 4940 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 4941
9ad5cbcf 4942 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 4943 if (num_dynamic_syms < 1)
252b5132
RH
4944 {
4945 error (_("Unable to determine the number of symbols to load\n"));
4946 continue;
4947 }
4948
9ad5cbcf 4949 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
4950 }
4951 }
4952
4953 /* Similarly find a string table. */
4954 if (dynamic_strings == NULL)
4955 {
86dba8ee
AM
4956 for (entry = dynamic_section;
4957 entry < dynamic_section + dynamic_nent;
4958 ++entry)
252b5132
RH
4959 {
4960 unsigned long offset;
b34976b6 4961 long str_tab_len;
252b5132
RH
4962
4963 if (entry->d_tag != DT_STRTAB)
4964 continue;
4965
4966 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
4967
4968 /* Since we do not know how big the string table is,
4969 we default to reading in the entire file (!) and
4970 processing that. This is overkill, I know, but it
e3c8793a 4971 should work. */
252b5132 4972
d93f0186 4973 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
4974
4975 if (archive_file_offset != 0)
4976 str_tab_len = archive_file_size - offset;
4977 else
4978 {
4979 if (fseek (file, 0, SEEK_END))
4980 error (_("Unable to seek to end of file\n"));
4981 str_tab_len = ftell (file) - offset;
4982 }
252b5132
RH
4983
4984 if (str_tab_len < 1)
4985 {
4986 error
4987 (_("Unable to determine the length of the dynamic string table\n"));
4988 continue;
4989 }
4990
d3ba0551
AM
4991 dynamic_strings = get_data (NULL, file, offset, str_tab_len,
4992 _("dynamic string table"));
d79b3d50 4993 dynamic_strings_length = str_tab_len;
252b5132
RH
4994 break;
4995 }
4996 }
4997
4998 /* And find the syminfo section if available. */
4999 if (dynamic_syminfo == NULL)
5000 {
3e8bba36 5001 unsigned long syminsz = 0;
252b5132 5002
86dba8ee
AM
5003 for (entry = dynamic_section;
5004 entry < dynamic_section + dynamic_nent;
5005 ++entry)
252b5132
RH
5006 {
5007 if (entry->d_tag == DT_SYMINENT)
5008 {
5009 /* Note: these braces are necessary to avoid a syntax
5010 error from the SunOS4 C compiler. */
5011 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
5012 }
5013 else if (entry->d_tag == DT_SYMINSZ)
5014 syminsz = entry->d_un.d_val;
5015 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
5016 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
5017 syminsz);
252b5132
RH
5018 }
5019
5020 if (dynamic_syminfo_offset != 0 && syminsz != 0)
5021 {
86dba8ee 5022 Elf_External_Syminfo *extsyminfo, *extsym;
b34976b6 5023 Elf_Internal_Syminfo *syminfo;
252b5132
RH
5024
5025 /* There is a syminfo section. Read the data. */
d3ba0551
AM
5026 extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, syminsz,
5027 _("symbol information"));
a6e9f9df
AM
5028 if (!extsyminfo)
5029 return 0;
252b5132 5030
d3ba0551 5031 dynamic_syminfo = malloc (syminsz);
252b5132
RH
5032 if (dynamic_syminfo == NULL)
5033 {
5034 error (_("Out of memory\n"));
5035 return 0;
5036 }
5037
5038 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
5039 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
5040 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
5041 ++syminfo, ++extsym)
252b5132 5042 {
86dba8ee
AM
5043 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
5044 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
5045 }
5046
5047 free (extsyminfo);
5048 }
5049 }
5050
5051 if (do_dynamic && dynamic_addr)
86dba8ee
AM
5052 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
5053 dynamic_addr, dynamic_nent);
252b5132
RH
5054 if (do_dynamic)
5055 printf (_(" Tag Type Name/Value\n"));
5056
86dba8ee
AM
5057 for (entry = dynamic_section;
5058 entry < dynamic_section + dynamic_nent;
5059 entry++)
252b5132
RH
5060 {
5061 if (do_dynamic)
f7a99963 5062 {
b34976b6 5063 const char *dtype;
e699b9ff 5064
f7a99963
NC
5065 putchar (' ');
5066 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
5067 dtype = get_dynamic_type (entry->d_tag);
5068 printf (" (%s)%*s", dtype,
5069 ((is_32bit_elf ? 27 : 19)
5070 - (int) strlen (dtype)),
f7a99963
NC
5071 " ");
5072 }
252b5132
RH
5073
5074 switch (entry->d_tag)
5075 {
d1133906
NC
5076 case DT_FLAGS:
5077 if (do_dynamic)
13ae64f3 5078 puts (get_dynamic_flags (entry->d_un.d_val));
d1133906 5079 break;
76da6bbe 5080
252b5132
RH
5081 case DT_AUXILIARY:
5082 case DT_FILTER:
019148e4
L
5083 case DT_CONFIG:
5084 case DT_DEPAUDIT:
5085 case DT_AUDIT:
252b5132
RH
5086 if (do_dynamic)
5087 {
019148e4 5088 switch (entry->d_tag)
b34976b6 5089 {
019148e4
L
5090 case DT_AUXILIARY:
5091 printf (_("Auxiliary library"));
5092 break;
5093
5094 case DT_FILTER:
5095 printf (_("Filter library"));
5096 break;
5097
b34976b6 5098 case DT_CONFIG:
019148e4
L
5099 printf (_("Configuration file"));
5100 break;
5101
5102 case DT_DEPAUDIT:
5103 printf (_("Dependency audit library"));
5104 break;
5105
5106 case DT_AUDIT:
5107 printf (_("Audit library"));
5108 break;
5109 }
252b5132 5110
d79b3d50
NC
5111 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
5112 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 5113 else
f7a99963
NC
5114 {
5115 printf (": ");
5116 print_vma (entry->d_un.d_val, PREFIX_HEX);
5117 putchar ('\n');
5118 }
252b5132
RH
5119 }
5120 break;
5121
dcefbbbd 5122 case DT_FEATURE:
252b5132
RH
5123 if (do_dynamic)
5124 {
5125 printf (_("Flags:"));
86f55779 5126
252b5132
RH
5127 if (entry->d_un.d_val == 0)
5128 printf (_(" None\n"));
5129 else
5130 {
5131 unsigned long int val = entry->d_un.d_val;
86f55779 5132
252b5132
RH
5133 if (val & DTF_1_PARINIT)
5134 {
5135 printf (" PARINIT");
5136 val ^= DTF_1_PARINIT;
5137 }
dcefbbbd
L
5138 if (val & DTF_1_CONFEXP)
5139 {
5140 printf (" CONFEXP");
5141 val ^= DTF_1_CONFEXP;
5142 }
252b5132
RH
5143 if (val != 0)
5144 printf (" %lx", val);
5145 puts ("");
5146 }
5147 }
5148 break;
5149
5150 case DT_POSFLAG_1:
5151 if (do_dynamic)
5152 {
5153 printf (_("Flags:"));
86f55779 5154
252b5132
RH
5155 if (entry->d_un.d_val == 0)
5156 printf (_(" None\n"));
5157 else
5158 {
5159 unsigned long int val = entry->d_un.d_val;
86f55779 5160
252b5132
RH
5161 if (val & DF_P1_LAZYLOAD)
5162 {
5163 printf (" LAZYLOAD");
5164 val ^= DF_P1_LAZYLOAD;
5165 }
5166 if (val & DF_P1_GROUPPERM)
5167 {
5168 printf (" GROUPPERM");
5169 val ^= DF_P1_GROUPPERM;
5170 }
5171 if (val != 0)
5172 printf (" %lx", val);
5173 puts ("");
5174 }
5175 }
5176 break;
5177
5178 case DT_FLAGS_1:
5179 if (do_dynamic)
5180 {
5181 printf (_("Flags:"));
5182 if (entry->d_un.d_val == 0)
5183 printf (_(" None\n"));
5184 else
5185 {
5186 unsigned long int val = entry->d_un.d_val;
86f55779 5187
252b5132
RH
5188 if (val & DF_1_NOW)
5189 {
5190 printf (" NOW");
5191 val ^= DF_1_NOW;
5192 }
5193 if (val & DF_1_GLOBAL)
5194 {
5195 printf (" GLOBAL");
5196 val ^= DF_1_GLOBAL;
5197 }
5198 if (val & DF_1_GROUP)
5199 {
5200 printf (" GROUP");
5201 val ^= DF_1_GROUP;
5202 }
5203 if (val & DF_1_NODELETE)
5204 {
5205 printf (" NODELETE");
5206 val ^= DF_1_NODELETE;
5207 }
5208 if (val & DF_1_LOADFLTR)
5209 {
5210 printf (" LOADFLTR");
5211 val ^= DF_1_LOADFLTR;
5212 }
5213 if (val & DF_1_INITFIRST)
5214 {
5215 printf (" INITFIRST");
5216 val ^= DF_1_INITFIRST;
5217 }
5218 if (val & DF_1_NOOPEN)
5219 {
5220 printf (" NOOPEN");
5221 val ^= DF_1_NOOPEN;
5222 }
5223 if (val & DF_1_ORIGIN)
5224 {
5225 printf (" ORIGIN");
5226 val ^= DF_1_ORIGIN;
5227 }
5228 if (val & DF_1_DIRECT)
5229 {
5230 printf (" DIRECT");
5231 val ^= DF_1_DIRECT;
5232 }
5233 if (val & DF_1_TRANS)
5234 {
5235 printf (" TRANS");
5236 val ^= DF_1_TRANS;
5237 }
5238 if (val & DF_1_INTERPOSE)
5239 {
5240 printf (" INTERPOSE");
5241 val ^= DF_1_INTERPOSE;
5242 }
f7db6139 5243 if (val & DF_1_NODEFLIB)
dcefbbbd 5244 {
f7db6139
L
5245 printf (" NODEFLIB");
5246 val ^= DF_1_NODEFLIB;
dcefbbbd
L
5247 }
5248 if (val & DF_1_NODUMP)
5249 {
5250 printf (" NODUMP");
5251 val ^= DF_1_NODUMP;
5252 }
5253 if (val & DF_1_CONLFAT)
5254 {
5255 printf (" CONLFAT");
5256 val ^= DF_1_CONLFAT;
5257 }
252b5132
RH
5258 if (val != 0)
5259 printf (" %lx", val);
5260 puts ("");
5261 }
5262 }
5263 break;
5264
5265 case DT_PLTREL:
566b0d53 5266 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
5267 if (do_dynamic)
5268 puts (get_dynamic_type (entry->d_un.d_val));
5269 break;
5270
5271 case DT_NULL :
5272 case DT_NEEDED :
5273 case DT_PLTGOT :
5274 case DT_HASH :
5275 case DT_STRTAB :
5276 case DT_SYMTAB :
5277 case DT_RELA :
5278 case DT_INIT :
5279 case DT_FINI :
5280 case DT_SONAME :
5281 case DT_RPATH :
5282 case DT_SYMBOLIC:
5283 case DT_REL :
5284 case DT_DEBUG :
5285 case DT_TEXTREL :
5286 case DT_JMPREL :
019148e4 5287 case DT_RUNPATH :
252b5132
RH
5288 dynamic_info[entry->d_tag] = entry->d_un.d_val;
5289
5290 if (do_dynamic)
5291 {
b34976b6 5292 char *name;
252b5132 5293
d79b3d50
NC
5294 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
5295 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 5296 else
d79b3d50 5297 name = NULL;
252b5132
RH
5298
5299 if (name)
5300 {
5301 switch (entry->d_tag)
5302 {
5303 case DT_NEEDED:
5304 printf (_("Shared library: [%s]"), name);
5305
f7a99963
NC
5306 if (strcmp (name, program_interpreter) == 0)
5307 printf (_(" program interpreter"));
252b5132
RH
5308 break;
5309
5310 case DT_SONAME:
f7a99963 5311 printf (_("Library soname: [%s]"), name);
252b5132
RH
5312 break;
5313
5314 case DT_RPATH:
f7a99963 5315 printf (_("Library rpath: [%s]"), name);
252b5132
RH
5316 break;
5317
019148e4
L
5318 case DT_RUNPATH:
5319 printf (_("Library runpath: [%s]"), name);
5320 break;
5321
252b5132 5322 default:
f7a99963
NC
5323 print_vma (entry->d_un.d_val, PREFIX_HEX);
5324 break;
252b5132
RH
5325 }
5326 }
5327 else
f7a99963
NC
5328 print_vma (entry->d_un.d_val, PREFIX_HEX);
5329
5330 putchar ('\n');
252b5132
RH
5331 }
5332 break;
5333
5334 case DT_PLTRELSZ:
5335 case DT_RELASZ :
5336 case DT_STRSZ :
5337 case DT_RELSZ :
5338 case DT_RELAENT :
5339 case DT_SYMENT :
5340 case DT_RELENT :
566b0d53 5341 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
5342 case DT_PLTPADSZ:
5343 case DT_MOVEENT :
5344 case DT_MOVESZ :
5345 case DT_INIT_ARRAYSZ:
5346 case DT_FINI_ARRAYSZ:
047b2264
JJ
5347 case DT_GNU_CONFLICTSZ:
5348 case DT_GNU_LIBLISTSZ:
252b5132 5349 if (do_dynamic)
f7a99963
NC
5350 {
5351 print_vma (entry->d_un.d_val, UNSIGNED);
5352 printf (" (bytes)\n");
5353 }
252b5132
RH
5354 break;
5355
5356 case DT_VERDEFNUM:
5357 case DT_VERNEEDNUM:
5358 case DT_RELACOUNT:
5359 case DT_RELCOUNT:
5360 if (do_dynamic)
f7a99963
NC
5361 {
5362 print_vma (entry->d_un.d_val, UNSIGNED);
5363 putchar ('\n');
5364 }
252b5132
RH
5365 break;
5366
5367 case DT_SYMINSZ:
5368 case DT_SYMINENT:
5369 case DT_SYMINFO:
5370 case DT_USED:
5371 case DT_INIT_ARRAY:
5372 case DT_FINI_ARRAY:
5373 if (do_dynamic)
5374 {
d79b3d50
NC
5375 if (entry->d_tag == DT_USED
5376 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 5377 {
d79b3d50 5378 char *name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 5379
b34976b6 5380 if (*name)
252b5132
RH
5381 {
5382 printf (_("Not needed object: [%s]\n"), name);
5383 break;
5384 }
5385 }
103f02d3 5386
f7a99963
NC
5387 print_vma (entry->d_un.d_val, PREFIX_HEX);
5388 putchar ('\n');
252b5132
RH
5389 }
5390 break;
5391
5392 case DT_BIND_NOW:
5393 /* The value of this entry is ignored. */
35b1837e
AM
5394 if (do_dynamic)
5395 putchar ('\n');
252b5132 5396 break;
103f02d3 5397
047b2264
JJ
5398 case DT_GNU_PRELINKED:
5399 if (do_dynamic)
5400 {
b34976b6 5401 struct tm *tmp;
047b2264
JJ
5402 time_t time = entry->d_un.d_val;
5403
5404 tmp = gmtime (&time);
5405 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
5406 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
5407 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
5408
5409 }
5410 break;
5411
252b5132
RH
5412 default:
5413 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 5414 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
5415 entry->d_un.d_val;
5416
5417 if (do_dynamic)
5418 {
5419 switch (elf_header.e_machine)
5420 {
5421 case EM_MIPS:
4fe85591 5422 case EM_MIPS_RS3_LE:
b2d38a17 5423 dynamic_section_mips_val (entry);
252b5132 5424 break;
103f02d3 5425 case EM_PARISC:
b2d38a17 5426 dynamic_section_parisc_val (entry);
103f02d3 5427 break;
ecc51f48 5428 case EM_IA_64:
b2d38a17 5429 dynamic_section_ia64_val (entry);
ecc51f48 5430 break;
252b5132 5431 default:
f7a99963
NC
5432 print_vma (entry->d_un.d_val, PREFIX_HEX);
5433 putchar ('\n');
252b5132
RH
5434 }
5435 }
5436 break;
5437 }
5438 }
5439
5440 return 1;
5441}
5442
5443static char *
d3ba0551 5444get_ver_flags (unsigned int flags)
252b5132 5445{
b34976b6 5446 static char buff[32];
252b5132
RH
5447
5448 buff[0] = 0;
5449
5450 if (flags == 0)
5451 return _("none");
5452
5453 if (flags & VER_FLG_BASE)
5454 strcat (buff, "BASE ");
5455
5456 if (flags & VER_FLG_WEAK)
5457 {
5458 if (flags & VER_FLG_BASE)
5459 strcat (buff, "| ");
5460
5461 strcat (buff, "WEAK ");
5462 }
5463
5464 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
5465 strcat (buff, "| <unknown>");
5466
5467 return buff;
5468}
5469
5470/* Display the contents of the version sections. */
5471static int
d3ba0551 5472process_version_sections (FILE *file)
252b5132 5473{
b34976b6
AM
5474 Elf_Internal_Shdr *section;
5475 unsigned i;
5476 int found = 0;
252b5132
RH
5477
5478 if (! do_version)
5479 return 1;
5480
5481 for (i = 0, section = section_headers;
5482 i < elf_header.e_shnum;
b34976b6 5483 i++, section++)
252b5132
RH
5484 {
5485 switch (section->sh_type)
5486 {
5487 case SHT_GNU_verdef:
5488 {
b34976b6
AM
5489 Elf_External_Verdef *edefs;
5490 unsigned int idx;
5491 unsigned int cnt;
252b5132
RH
5492
5493 found = 1;
5494
5495 printf
5496 (_("\nVersion definition section '%s' contains %ld entries:\n"),
5497 SECTION_NAME (section), section->sh_info);
5498
5499 printf (_(" Addr: 0x"));
5500 printf_vma (section->sh_addr);
5501 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 5502 (unsigned long) section->sh_offset, section->sh_link,
9ad5cbcf 5503 SECTION_NAME (SECTION_HEADER (section->sh_link)));
252b5132 5504
d3ba0551
AM
5505 edefs = get_data (NULL, file, section->sh_offset, section->sh_size,
5506 _("version definition section"));
a6e9f9df
AM
5507 if (!edefs)
5508 break;
252b5132 5509
b34976b6 5510 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 5511 {
b34976b6
AM
5512 char *vstart;
5513 Elf_External_Verdef *edef;
5514 Elf_Internal_Verdef ent;
5515 Elf_External_Verdaux *eaux;
5516 Elf_Internal_Verdaux aux;
5517 int j;
5518 int isum;
103f02d3 5519
252b5132
RH
5520 vstart = ((char *) edefs) + idx;
5521
5522 edef = (Elf_External_Verdef *) vstart;
5523
5524 ent.vd_version = BYTE_GET (edef->vd_version);
5525 ent.vd_flags = BYTE_GET (edef->vd_flags);
5526 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
5527 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
5528 ent.vd_hash = BYTE_GET (edef->vd_hash);
5529 ent.vd_aux = BYTE_GET (edef->vd_aux);
5530 ent.vd_next = BYTE_GET (edef->vd_next);
5531
5532 printf (_(" %#06x: Rev: %d Flags: %s"),
5533 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
5534
5535 printf (_(" Index: %d Cnt: %d "),
5536 ent.vd_ndx, ent.vd_cnt);
5537
5538 vstart += ent.vd_aux;
5539
5540 eaux = (Elf_External_Verdaux *) vstart;
5541
5542 aux.vda_name = BYTE_GET (eaux->vda_name);
5543 aux.vda_next = BYTE_GET (eaux->vda_next);
5544
d79b3d50
NC
5545 if (VALID_DYNAMIC_NAME (aux.vda_name))
5546 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
5547 else
5548 printf (_("Name index: %ld\n"), aux.vda_name);
5549
5550 isum = idx + ent.vd_aux;
5551
b34976b6 5552 for (j = 1; j < ent.vd_cnt; j++)
252b5132
RH
5553 {
5554 isum += aux.vda_next;
5555 vstart += aux.vda_next;
5556
5557 eaux = (Elf_External_Verdaux *) vstart;
5558
5559 aux.vda_name = BYTE_GET (eaux->vda_name);
5560 aux.vda_next = BYTE_GET (eaux->vda_next);
5561
d79b3d50 5562 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 5563 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 5564 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
5565 else
5566 printf (_(" %#06x: Parent %d, name index: %ld\n"),
5567 isum, j, aux.vda_name);
5568 }
5569
5570 idx += ent.vd_next;
5571 }
5572
5573 free (edefs);
5574 }
5575 break;
103f02d3 5576
252b5132
RH
5577 case SHT_GNU_verneed:
5578 {
b34976b6
AM
5579 Elf_External_Verneed *eneed;
5580 unsigned int idx;
5581 unsigned int cnt;
252b5132
RH
5582
5583 found = 1;
5584
5585 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
5586 SECTION_NAME (section), section->sh_info);
5587
5588 printf (_(" Addr: 0x"));
5589 printf_vma (section->sh_addr);
5590 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
1b228002 5591 (unsigned long) section->sh_offset, section->sh_link,
9ad5cbcf 5592 SECTION_NAME (SECTION_HEADER (section->sh_link)));
252b5132 5593
d3ba0551
AM
5594 eneed = get_data (NULL, file, section->sh_offset, section->sh_size,
5595 _("version need section"));
a6e9f9df
AM
5596 if (!eneed)
5597 break;
252b5132
RH
5598
5599 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
5600 {
b34976b6
AM
5601 Elf_External_Verneed *entry;
5602 Elf_Internal_Verneed ent;
5603 int j;
5604 int isum;
5605 char *vstart;
252b5132
RH
5606
5607 vstart = ((char *) eneed) + idx;
5608
5609 entry = (Elf_External_Verneed *) vstart;
5610
5611 ent.vn_version = BYTE_GET (entry->vn_version);
5612 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
5613 ent.vn_file = BYTE_GET (entry->vn_file);
5614 ent.vn_aux = BYTE_GET (entry->vn_aux);
5615 ent.vn_next = BYTE_GET (entry->vn_next);
5616
5617 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
5618
d79b3d50
NC
5619 if (VALID_DYNAMIC_NAME (ent.vn_file))
5620 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
5621 else
5622 printf (_(" File: %lx"), ent.vn_file);
5623
5624 printf (_(" Cnt: %d\n"), ent.vn_cnt);
5625
5626 vstart += ent.vn_aux;
5627
5628 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
5629 {
b34976b6
AM
5630 Elf_External_Vernaux *eaux;
5631 Elf_Internal_Vernaux aux;
252b5132
RH
5632
5633 eaux = (Elf_External_Vernaux *) vstart;
5634
5635 aux.vna_hash = BYTE_GET (eaux->vna_hash);
5636 aux.vna_flags = BYTE_GET (eaux->vna_flags);
5637 aux.vna_other = BYTE_GET (eaux->vna_other);
5638 aux.vna_name = BYTE_GET (eaux->vna_name);
5639 aux.vna_next = BYTE_GET (eaux->vna_next);
5640
d79b3d50 5641 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 5642 printf (_(" %#06x: Name: %s"),
d79b3d50 5643 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 5644 else
ecc2063b 5645 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
5646 isum, aux.vna_name);
5647
5648 printf (_(" Flags: %s Version: %d\n"),
5649 get_ver_flags (aux.vna_flags), aux.vna_other);
5650
5651 isum += aux.vna_next;
5652 vstart += aux.vna_next;
5653 }
5654
5655 idx += ent.vn_next;
5656 }
103f02d3 5657
252b5132
RH
5658 free (eneed);
5659 }
5660 break;
5661
5662 case SHT_GNU_versym:
5663 {
b34976b6
AM
5664 Elf_Internal_Shdr *link_section;
5665 int total;
5666 int cnt;
5667 unsigned char *edata;
5668 unsigned short *data;
5669 char *strtab;
5670 Elf_Internal_Sym *symbols;
5671 Elf_Internal_Shdr *string_sec;
d3ba0551 5672 long off;
252b5132 5673
9ad5cbcf 5674 link_section = SECTION_HEADER (section->sh_link);
252b5132
RH
5675 total = section->sh_size / section->sh_entsize;
5676
5677 found = 1;
5678
9ad5cbcf 5679 symbols = GET_ELF_SYMBOLS (file, link_section);
252b5132 5680
9ad5cbcf 5681 string_sec = SECTION_HEADER (link_section->sh_link);
252b5132 5682
d3ba0551
AM
5683 strtab = get_data (NULL, file, string_sec->sh_offset,
5684 string_sec->sh_size, _("version string table"));
a6e9f9df
AM
5685 if (!strtab)
5686 break;
252b5132
RH
5687
5688 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
5689 SECTION_NAME (section), total);
5690
5691 printf (_(" Addr: "));
5692 printf_vma (section->sh_addr);
5693 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 5694 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
5695 SECTION_NAME (link_section));
5696
d3ba0551
AM
5697 off = offset_from_vma (file,
5698 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
5699 total * sizeof (short));
5700 edata = get_data (NULL, file, off, total * sizeof (short),
5701 _("version symbol data"));
a6e9f9df
AM
5702 if (!edata)
5703 {
5704 free (strtab);
5705 break;
5706 }
252b5132 5707
d3ba0551 5708 data = malloc (total * sizeof (short));
252b5132
RH
5709
5710 for (cnt = total; cnt --;)
b34976b6
AM
5711 data[cnt] = byte_get (edata + cnt * sizeof (short),
5712 sizeof (short));
252b5132
RH
5713
5714 free (edata);
5715
5716 for (cnt = 0; cnt < total; cnt += 4)
5717 {
5718 int j, nn;
00d93f34 5719 int check_def, check_need;
b34976b6 5720 char *name;
252b5132
RH
5721
5722 printf (" %03x:", cnt);
5723
5724 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 5725 switch (data[cnt + j])
252b5132
RH
5726 {
5727 case 0:
5728 fputs (_(" 0 (*local*) "), stdout);
5729 break;
5730
5731 case 1:
5732 fputs (_(" 1 (*global*) "), stdout);
5733 break;
5734
5735 default:
b34976b6
AM
5736 nn = printf ("%4x%c", data[cnt + j] & 0x7fff,
5737 data[cnt + j] & 0x8000 ? 'h' : ' ');
252b5132 5738
00d93f34
JJ
5739 check_def = 1;
5740 check_need = 1;
b34976b6 5741 if (SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
00d93f34 5742 != SHT_NOBITS)
252b5132 5743 {
b34976b6 5744 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
5745 check_def = 0;
5746 else
5747 check_need = 0;
252b5132 5748 }
00d93f34
JJ
5749
5750 if (check_need
b34976b6 5751 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 5752 {
b34976b6
AM
5753 Elf_Internal_Verneed ivn;
5754 unsigned long offset;
252b5132 5755
d93f0186
NC
5756 offset = offset_from_vma
5757 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
5758 sizeof (Elf_External_Verneed));
252b5132 5759
b34976b6 5760 do
252b5132 5761 {
b34976b6
AM
5762 Elf_Internal_Vernaux ivna;
5763 Elf_External_Verneed evn;
5764 Elf_External_Vernaux evna;
5765 unsigned long a_off;
252b5132 5766
a6e9f9df
AM
5767 get_data (&evn, file, offset, sizeof (evn),
5768 _("version need"));
252b5132
RH
5769
5770 ivn.vn_aux = BYTE_GET (evn.vn_aux);
5771 ivn.vn_next = BYTE_GET (evn.vn_next);
5772
5773 a_off = offset + ivn.vn_aux;
5774
5775 do
5776 {
a6e9f9df
AM
5777 get_data (&evna, file, a_off, sizeof (evna),
5778 _("version need aux (2)"));
252b5132
RH
5779
5780 ivna.vna_next = BYTE_GET (evna.vna_next);
5781 ivna.vna_other = BYTE_GET (evna.vna_other);
5782
5783 a_off += ivna.vna_next;
5784 }
b34976b6 5785 while (ivna.vna_other != data[cnt + j]
252b5132
RH
5786 && ivna.vna_next != 0);
5787
b34976b6 5788 if (ivna.vna_other == data[cnt + j])
252b5132
RH
5789 {
5790 ivna.vna_name = BYTE_GET (evna.vna_name);
5791
16062207 5792 name = strtab + ivna.vna_name;
252b5132 5793 nn += printf ("(%s%-*s",
16062207
ILT
5794 name,
5795 12 - (int) strlen (name),
252b5132 5796 ")");
00d93f34 5797 check_def = 0;
252b5132
RH
5798 break;
5799 }
5800
5801 offset += ivn.vn_next;
5802 }
5803 while (ivn.vn_next);
5804 }
00d93f34 5805
b34976b6
AM
5806 if (check_def && data[cnt + j] != 0x8001
5807 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 5808 {
b34976b6
AM
5809 Elf_Internal_Verdef ivd;
5810 Elf_External_Verdef evd;
5811 unsigned long offset;
252b5132 5812
d93f0186
NC
5813 offset = offset_from_vma
5814 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
5815 sizeof evd);
252b5132
RH
5816
5817 do
5818 {
a6e9f9df
AM
5819 get_data (&evd, file, offset, sizeof (evd),
5820 _("version def"));
252b5132
RH
5821
5822 ivd.vd_next = BYTE_GET (evd.vd_next);
5823 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
5824
5825 offset += ivd.vd_next;
5826 }
b34976b6 5827 while (ivd.vd_ndx != (data[cnt + j] & 0x7fff)
252b5132
RH
5828 && ivd.vd_next != 0);
5829
b34976b6 5830 if (ivd.vd_ndx == (data[cnt + j] & 0x7fff))
252b5132 5831 {
b34976b6
AM
5832 Elf_External_Verdaux evda;
5833 Elf_Internal_Verdaux ivda;
252b5132
RH
5834
5835 ivd.vd_aux = BYTE_GET (evd.vd_aux);
5836
a6e9f9df
AM
5837 get_data (&evda, file,
5838 offset - ivd.vd_next + ivd.vd_aux,
5839 sizeof (evda), _("version def aux"));
252b5132
RH
5840
5841 ivda.vda_name = BYTE_GET (evda.vda_name);
5842
16062207 5843 name = strtab + ivda.vda_name;
252b5132 5844 nn += printf ("(%s%-*s",
16062207
ILT
5845 name,
5846 12 - (int) strlen (name),
252b5132
RH
5847 ")");
5848 }
5849 }
5850
5851 if (nn < 18)
5852 printf ("%*c", 18 - nn, ' ');
5853 }
5854
5855 putchar ('\n');
5856 }
5857
5858 free (data);
5859 free (strtab);
5860 free (symbols);
5861 }
5862 break;
103f02d3 5863
252b5132
RH
5864 default:
5865 break;
5866 }
5867 }
5868
5869 if (! found)
5870 printf (_("\nNo version information found in this file.\n"));
5871
5872 return 1;
5873}
5874
d1133906 5875static const char *
d3ba0551 5876get_symbol_binding (unsigned int binding)
252b5132 5877{
b34976b6 5878 static char buff[32];
252b5132
RH
5879
5880 switch (binding)
5881 {
b34976b6
AM
5882 case STB_LOCAL: return "LOCAL";
5883 case STB_GLOBAL: return "GLOBAL";
5884 case STB_WEAK: return "WEAK";
252b5132
RH
5885 default:
5886 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
5887 sprintf (buff, _("<processor specific>: %d"), binding);
5888 else if (binding >= STB_LOOS && binding <= STB_HIOS)
5889 sprintf (buff, _("<OS specific>: %d"), binding);
5890 else
5891 sprintf (buff, _("<unknown>: %d"), binding);
5892 return buff;
5893 }
5894}
5895
d1133906 5896static const char *
d3ba0551 5897get_symbol_type (unsigned int type)
252b5132 5898{
b34976b6 5899 static char buff[32];
252b5132
RH
5900
5901 switch (type)
5902 {
b34976b6
AM
5903 case STT_NOTYPE: return "NOTYPE";
5904 case STT_OBJECT: return "OBJECT";
5905 case STT_FUNC: return "FUNC";
5906 case STT_SECTION: return "SECTION";
5907 case STT_FILE: return "FILE";
5908 case STT_COMMON: return "COMMON";
5909 case STT_TLS: return "TLS";
252b5132
RH
5910 default:
5911 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
5912 {
5913 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
5914 return "THUMB_FUNC";
5915
351b4b40 5916 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
5917 return "REGISTER";
5918
5919 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
5920 return "PARISC_MILLI";
5921
df75f1af
NC
5922 sprintf (buff, _("<processor specific>: %d"), type);
5923 }
252b5132 5924 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
5925 {
5926 if (elf_header.e_machine == EM_PARISC)
5927 {
5928 if (type == STT_HP_OPAQUE)
5929 return "HP_OPAQUE";
5930 if (type == STT_HP_STUB)
5931 return "HP_STUB";
5932 }
5933
5934 sprintf (buff, _("<OS specific>: %d"), type);
5935 }
252b5132
RH
5936 else
5937 sprintf (buff, _("<unknown>: %d"), type);
5938 return buff;
5939 }
5940}
5941
d1133906 5942static const char *
d3ba0551 5943get_symbol_visibility (unsigned int visibility)
d1133906
NC
5944{
5945 switch (visibility)
5946 {
b34976b6
AM
5947 case STV_DEFAULT: return "DEFAULT";
5948 case STV_INTERNAL: return "INTERNAL";
5949 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
5950 case STV_PROTECTED: return "PROTECTED";
5951 default: abort ();
5952 }
5953}
5954
5955static const char *
d3ba0551 5956get_symbol_index_type (unsigned int type)
252b5132 5957{
b34976b6 5958 static char buff[32];
5cf1065c 5959
252b5132
RH
5960 switch (type)
5961 {
b34976b6
AM
5962 case SHN_UNDEF: return "UND";
5963 case SHN_ABS: return "ABS";
5964 case SHN_COMMON: return "COM";
252b5132 5965 default:
9ce701e2
L
5966 if (type == SHN_IA_64_ANSI_COMMON
5967 && elf_header.e_machine == EM_IA_64
5968 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
5969 return "ANSI_COM";
5970 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
5cf1065c 5971 sprintf (buff, "PRC[0x%04x]", type);
252b5132 5972 else if (type >= SHN_LOOS && type <= SHN_HIOS)
5cf1065c 5973 sprintf (buff, "OS [0x%04x]", type);
9ad5cbcf 5974 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
5cf1065c 5975 sprintf (buff, "RSV[0x%04x]", type);
252b5132 5976 else
232e7cb8 5977 sprintf (buff, "%3d", type);
5cf1065c 5978 break;
252b5132 5979 }
5cf1065c
NC
5980
5981 return buff;
252b5132
RH
5982}
5983
252b5132 5984static int *
d3ba0551 5985get_dynamic_data (FILE *file, unsigned int number)
252b5132 5986{
b34976b6
AM
5987 unsigned char *e_data;
5988 int *i_data;
252b5132 5989
d3ba0551 5990 e_data = malloc (number * 4);
252b5132
RH
5991
5992 if (e_data == NULL)
5993 {
5994 error (_("Out of memory\n"));
5995 return NULL;
5996 }
5997
5998 if (fread (e_data, 4, number, file) != number)
5999 {
6000 error (_("Unable to read in dynamic data\n"));
6001 return NULL;
6002 }
6003
d3ba0551 6004 i_data = malloc (number * sizeof (*i_data));
252b5132
RH
6005
6006 if (i_data == NULL)
6007 {
6008 error (_("Out of memory\n"));
6009 free (e_data);
6010 return NULL;
6011 }
6012
6013 while (number--)
b34976b6 6014 i_data[number] = byte_get (e_data + number * 4, 4);
252b5132
RH
6015
6016 free (e_data);
6017
6018 return i_data;
6019}
6020
e3c8793a 6021/* Dump the symbol table. */
252b5132 6022static int
d3ba0551 6023process_symbol_table (FILE *file)
252b5132 6024{
b34976b6
AM
6025 Elf_Internal_Shdr *section;
6026 unsigned char nb[4];
6027 unsigned char nc[4];
6028 int nbuckets = 0;
6029 int nchains = 0;
6030 int *buckets = NULL;
6031 int *chains = NULL;
252b5132
RH
6032
6033 if (! do_syms && !do_histogram)
6034 return 1;
6035
6036 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
6037 || do_histogram))
6038 {
fb52b2f4
NC
6039 if (fseek (file,
6040 (archive_file_offset
6041 + offset_from_vma (file, dynamic_info[DT_HASH],
6042 sizeof nb + sizeof nc)),
d93f0186 6043 SEEK_SET))
252b5132
RH
6044 {
6045 error (_("Unable to seek to start of dynamic information"));
6046 return 0;
6047 }
6048
6049 if (fread (nb, sizeof (nb), 1, file) != 1)
6050 {
6051 error (_("Failed to read in number of buckets\n"));
6052 return 0;
6053 }
6054
6055 if (fread (nc, sizeof (nc), 1, file) != 1)
6056 {
6057 error (_("Failed to read in number of chains\n"));
6058 return 0;
6059 }
6060
6061 nbuckets = byte_get (nb, 4);
6062 nchains = byte_get (nc, 4);
6063
6064 buckets = get_dynamic_data (file, nbuckets);
6065 chains = get_dynamic_data (file, nchains);
6066
6067 if (buckets == NULL || chains == NULL)
6068 return 0;
6069 }
6070
6071 if (do_syms
6072 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
6073 {
b34976b6
AM
6074 int hn;
6075 int si;
252b5132
RH
6076
6077 printf (_("\nSymbol table for image:\n"));
f7a99963 6078 if (is_32bit_elf)
ca47b30c 6079 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 6080 else
ca47b30c 6081 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
252b5132
RH
6082
6083 for (hn = 0; hn < nbuckets; hn++)
6084 {
b34976b6 6085 if (! buckets[hn])
252b5132
RH
6086 continue;
6087
b34976b6 6088 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
252b5132 6089 {
b34976b6 6090 Elf_Internal_Sym *psym;
252b5132
RH
6091
6092 psym = dynamic_symbols + si;
6093
f7a99963
NC
6094 printf (" %3d %3d: ", si, hn);
6095 print_vma (psym->st_value, LONG_HEX);
6096 putchar (' ' );
d1133906 6097 print_vma (psym->st_size, DEC_5);
76da6bbe 6098
d1133906
NC
6099 printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
6100 printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
6101 printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126 6102 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
d79b3d50
NC
6103 if (VALID_DYNAMIC_NAME (psym->st_name))
6104 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
6105 else
6106 printf (" <corrupt: %14ld>", psym->st_name);
31104126 6107 putchar ('\n');
252b5132
RH
6108 }
6109 }
6110 }
6111 else if (do_syms && !do_using_dynamic)
6112 {
b34976b6 6113 unsigned int i;
252b5132
RH
6114
6115 for (i = 0, section = section_headers;
6116 i < elf_header.e_shnum;
6117 i++, section++)
6118 {
b34976b6
AM
6119 unsigned int si;
6120 char *strtab;
6121 Elf_Internal_Sym *symtab;
6122 Elf_Internal_Sym *psym;
252b5132
RH
6123
6124
6125 if ( section->sh_type != SHT_SYMTAB
6126 && section->sh_type != SHT_DYNSYM)
6127 continue;
6128
6129 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
6130 SECTION_NAME (section),
6131 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 6132 if (is_32bit_elf)
ca47b30c 6133 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 6134 else
ca47b30c 6135 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 6136
9ad5cbcf 6137 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
6138 if (symtab == NULL)
6139 continue;
6140
6141 if (section->sh_link == elf_header.e_shstrndx)
6142 strtab = string_table;
6143 else
6144 {
b34976b6 6145 Elf_Internal_Shdr *string_sec;
252b5132 6146
9ad5cbcf 6147 string_sec = SECTION_HEADER (section->sh_link);
252b5132 6148
d3ba0551
AM
6149 strtab = get_data (NULL, file, string_sec->sh_offset,
6150 string_sec->sh_size, _("string table"));
252b5132
RH
6151 }
6152
6153 for (si = 0, psym = symtab;
6154 si < section->sh_size / section->sh_entsize;
b34976b6 6155 si++, psym++)
252b5132 6156 {
5e220199 6157 printf ("%6d: ", si);
f7a99963
NC
6158 print_vma (psym->st_value, LONG_HEX);
6159 putchar (' ');
6160 print_vma (psym->st_size, DEC_5);
d1133906
NC
6161 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
6162 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
6163 printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126
NC
6164 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
6165 print_symbol (25, strtab + psym->st_name);
252b5132
RH
6166
6167 if (section->sh_type == SHT_DYNSYM &&
b34976b6 6168 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 6169 {
b34976b6
AM
6170 unsigned char data[2];
6171 unsigned short vers_data;
6172 unsigned long offset;
6173 int is_nobits;
6174 int check_def;
252b5132 6175
d93f0186
NC
6176 offset = offset_from_vma
6177 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
6178 sizeof data + si * sizeof (vers_data));
252b5132 6179
a6e9f9df
AM
6180 get_data (&data, file, offset + si * sizeof (vers_data),
6181 sizeof (data), _("version data"));
252b5132
RH
6182
6183 vers_data = byte_get (data, 2);
6184
9ad5cbcf
AM
6185 is_nobits = (SECTION_HEADER (psym->st_shndx)->sh_type
6186 == SHT_NOBITS);
252b5132
RH
6187
6188 check_def = (psym->st_shndx != SHN_UNDEF);
6189
6190 if ((vers_data & 0x8000) || vers_data > 1)
6191 {
b34976b6 6192 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 6193 && (is_nobits || ! check_def))
252b5132 6194 {
b34976b6
AM
6195 Elf_External_Verneed evn;
6196 Elf_Internal_Verneed ivn;
6197 Elf_Internal_Vernaux ivna;
252b5132
RH
6198
6199 /* We must test both. */
d93f0186
NC
6200 offset = offset_from_vma
6201 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
6202 sizeof evn);
252b5132 6203
252b5132
RH
6204 do
6205 {
b34976b6 6206 unsigned long vna_off;
252b5132 6207
a6e9f9df
AM
6208 get_data (&evn, file, offset, sizeof (evn),
6209 _("version need"));
dd27201e
L
6210
6211 ivn.vn_aux = BYTE_GET (evn.vn_aux);
6212 ivn.vn_next = BYTE_GET (evn.vn_next);
6213
252b5132
RH
6214 vna_off = offset + ivn.vn_aux;
6215
6216 do
6217 {
b34976b6 6218 Elf_External_Vernaux evna;
252b5132 6219
a6e9f9df
AM
6220 get_data (&evna, file, vna_off,
6221 sizeof (evna),
6222 _("version need aux (3)"));
252b5132
RH
6223
6224 ivna.vna_other = BYTE_GET (evna.vna_other);
6225 ivna.vna_next = BYTE_GET (evna.vna_next);
6226 ivna.vna_name = BYTE_GET (evna.vna_name);
6227
6228 vna_off += ivna.vna_next;
6229 }
6230 while (ivna.vna_other != vers_data
6231 && ivna.vna_next != 0);
6232
6233 if (ivna.vna_other == vers_data)
6234 break;
6235
6236 offset += ivn.vn_next;
6237 }
6238 while (ivn.vn_next != 0);
6239
6240 if (ivna.vna_other == vers_data)
6241 {
6242 printf ("@%s (%d)",
6243 strtab + ivna.vna_name, ivna.vna_other);
6244 check_def = 0;
6245 }
6246 else if (! is_nobits)
6247 error (_("bad dynamic symbol"));
6248 else
6249 check_def = 1;
6250 }
6251
6252 if (check_def)
6253 {
00d93f34 6254 if (vers_data != 0x8001
b34976b6 6255 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 6256 {
b34976b6
AM
6257 Elf_Internal_Verdef ivd;
6258 Elf_Internal_Verdaux ivda;
6259 Elf_External_Verdaux evda;
6260 unsigned long offset;
252b5132 6261
d93f0186
NC
6262 offset = offset_from_vma
6263 (file,
6264 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
6265 sizeof (Elf_External_Verdef));
252b5132
RH
6266
6267 do
6268 {
b34976b6 6269 Elf_External_Verdef evd;
252b5132 6270
a6e9f9df
AM
6271 get_data (&evd, file, offset, sizeof (evd),
6272 _("version def"));
252b5132 6273
b34976b6
AM
6274 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
6275 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
6276 ivd.vd_next = BYTE_GET (evd.vd_next);
6277
6278 offset += ivd.vd_next;
6279 }
6280 while (ivd.vd_ndx != (vers_data & 0x7fff)
6281 && ivd.vd_next != 0);
6282
6283 offset -= ivd.vd_next;
6284 offset += ivd.vd_aux;
6285
a6e9f9df
AM
6286 get_data (&evda, file, offset, sizeof (evda),
6287 _("version def aux"));
252b5132
RH
6288
6289 ivda.vda_name = BYTE_GET (evda.vda_name);
6290
6291 if (psym->st_name != ivda.vda_name)
6292 printf ((vers_data & 0x8000)
6293 ? "@%s" : "@@%s",
6294 strtab + ivda.vda_name);
6295 }
6296 }
6297 }
6298 }
6299
6300 putchar ('\n');
6301 }
6302
6303 free (symtab);
6304 if (strtab != string_table)
6305 free (strtab);
6306 }
6307 }
6308 else if (do_syms)
6309 printf
6310 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
6311
6312 if (do_histogram && buckets != NULL)
6313 {
b34976b6
AM
6314 int *lengths;
6315 int *counts;
6316 int hn;
6317 int si;
6318 int maxlength = 0;
6319 int nzero_counts = 0;
6320 int nsyms = 0;
252b5132
RH
6321
6322 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
6323 nbuckets);
6324 printf (_(" Length Number %% of total Coverage\n"));
6325
d3ba0551 6326 lengths = calloc (nbuckets, sizeof (int));
252b5132
RH
6327 if (lengths == NULL)
6328 {
6329 error (_("Out of memory"));
6330 return 0;
6331 }
6332 for (hn = 0; hn < nbuckets; ++hn)
6333 {
b34976b6 6334 if (! buckets[hn])
252b5132
RH
6335 continue;
6336
f7a99963 6337 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 6338 {
b34976b6 6339 ++nsyms;
252b5132 6340 if (maxlength < ++lengths[hn])
b34976b6 6341 ++maxlength;
252b5132
RH
6342 }
6343 }
6344
d3ba0551 6345 counts = calloc (maxlength + 1, sizeof (int));
252b5132
RH
6346 if (counts == NULL)
6347 {
6348 error (_("Out of memory"));
6349 return 0;
6350 }
6351
6352 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 6353 ++counts[lengths[hn]];
252b5132 6354
103f02d3 6355 if (nbuckets > 0)
252b5132 6356 {
103f02d3
UD
6357 printf (" 0 %-10d (%5.1f%%)\n",
6358 counts[0], (counts[0] * 100.0) / nbuckets);
6359 for (si = 1; si <= maxlength; ++si)
6360 {
6361 nzero_counts += counts[si] * si;
6362 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
6363 si, counts[si], (counts[si] * 100.0) / nbuckets,
6364 (nzero_counts * 100.0) / nsyms);
6365 }
252b5132
RH
6366 }
6367
6368 free (counts);
6369 free (lengths);
6370 }
6371
6372 if (buckets != NULL)
6373 {
6374 free (buckets);
6375 free (chains);
6376 }
6377
6378 return 1;
6379}
6380
6381static int
d3ba0551 6382process_syminfo (FILE *file ATTRIBUTE_UNUSED)
252b5132 6383{
b4c96d0d 6384 unsigned int i;
252b5132
RH
6385
6386 if (dynamic_syminfo == NULL
6387 || !do_dynamic)
6388 /* No syminfo, this is ok. */
6389 return 1;
6390
6391 /* There better should be a dynamic symbol section. */
6392 if (dynamic_symbols == NULL || dynamic_strings == NULL)
6393 return 0;
6394
6395 if (dynamic_addr)
6396 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
6397 dynamic_syminfo_offset, dynamic_syminfo_nent);
6398
6399 printf (_(" Num: Name BoundTo Flags\n"));
6400 for (i = 0; i < dynamic_syminfo_nent; ++i)
6401 {
6402 unsigned short int flags = dynamic_syminfo[i].si_flags;
6403
31104126 6404 printf ("%4d: ", i);
d79b3d50
NC
6405 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
6406 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
6407 else
6408 printf ("<corrupt: %19ld>", dynamic_symbols[i].st_name);
31104126 6409 putchar (' ');
252b5132
RH
6410
6411 switch (dynamic_syminfo[i].si_boundto)
6412 {
6413 case SYMINFO_BT_SELF:
6414 fputs ("SELF ", stdout);
6415 break;
6416 case SYMINFO_BT_PARENT:
6417 fputs ("PARENT ", stdout);
6418 break;
6419 default:
6420 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
6421 && dynamic_syminfo[i].si_boundto < dynamic_nent
6422 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 6423 {
d79b3d50 6424 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
6425 putchar (' ' );
6426 }
252b5132
RH
6427 else
6428 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
6429 break;
6430 }
6431
6432 if (flags & SYMINFO_FLG_DIRECT)
6433 printf (" DIRECT");
6434 if (flags & SYMINFO_FLG_PASSTHRU)
6435 printf (" PASSTHRU");
6436 if (flags & SYMINFO_FLG_COPY)
6437 printf (" COPY");
6438 if (flags & SYMINFO_FLG_LAZYLOAD)
6439 printf (" LAZYLOAD");
6440
6441 puts ("");
6442 }
6443
6444 return 1;
6445}
6446
6447#ifdef SUPPORT_DISASSEMBLY
6448static void
d3ba0551 6449disassemble_section (Elf_Internal_Shdr *section, FILE *file)
252b5132
RH
6450{
6451 printf (_("\nAssembly dump of section %s\n"),
6452 SECTION_NAME (section));
6453
6454 /* XXX -- to be done --- XXX */
6455
6456 return 1;
6457}
6458#endif
6459
6460static int
d3ba0551 6461dump_section (Elf_Internal_Shdr *section, FILE *file)
252b5132 6462{
b34976b6
AM
6463 bfd_size_type bytes;
6464 bfd_vma addr;
6465 unsigned char *data;
6466 unsigned char *start;
252b5132
RH
6467
6468 bytes = section->sh_size;
6469
e69f2d21 6470 if (bytes == 0 || section->sh_type == SHT_NOBITS)
252b5132
RH
6471 {
6472 printf (_("\nSection '%s' has no data to dump.\n"),
6473 SECTION_NAME (section));
6474 return 0;
6475 }
6476 else
6477 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
6478
6479 addr = section->sh_addr;
6480
d3ba0551 6481 start = get_data (NULL, file, section->sh_offset, bytes, _("section data"));
a6e9f9df
AM
6482 if (!start)
6483 return 0;
252b5132
RH
6484
6485 data = start;
6486
6487 while (bytes)
6488 {
6489 int j;
6490 int k;
6491 int lbytes;
6492
6493 lbytes = (bytes > 16 ? 16 : bytes);
6494
148d3c43 6495 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132 6496
b34976b6 6497 switch (elf_header.e_ident[EI_DATA])
252b5132 6498 {
9ea033b2 6499 default:
252b5132
RH
6500 case ELFDATA2LSB:
6501 for (j = 15; j >= 0; j --)
6502 {
6503 if (j < lbytes)
b34976b6 6504 printf ("%2.2x", data[j]);
252b5132
RH
6505 else
6506 printf (" ");
6507
6508 if (!(j & 0x3))
6509 printf (" ");
6510 }
6511 break;
6512
6513 case ELFDATA2MSB:
6514 for (j = 0; j < 16; j++)
6515 {
6516 if (j < lbytes)
b34976b6 6517 printf ("%2.2x", data[j]);
252b5132
RH
6518 else
6519 printf (" ");
6520
6521 if ((j & 3) == 3)
6522 printf (" ");
6523 }
6524 break;
6525 }
6526
6527 for (j = 0; j < lbytes; j++)
6528 {
b34976b6 6529 k = data[j];
9376f0c7 6530 if (k >= ' ' && k < 0x7f)
252b5132
RH
6531 printf ("%c", k);
6532 else
6533 printf (".");
6534 }
6535
6536 putchar ('\n');
6537
6538 data += lbytes;
6539 addr += lbytes;
6540 bytes -= lbytes;
6541 }
6542
6543 free (start);
6544
6545 return 1;
6546}
6547
6548
6549static unsigned long int
d3ba0551 6550read_leb128 (unsigned char *data, int *length_return, int sign)
252b5132
RH
6551{
6552 unsigned long int result = 0;
b34976b6
AM
6553 unsigned int num_read = 0;
6554 int shift = 0;
6555 unsigned char byte;
252b5132
RH
6556
6557 do
6558 {
b34976b6
AM
6559 byte = *data++;
6560 num_read++;
252b5132
RH
6561
6562 result |= (byte & 0x7f) << shift;
6563
6564 shift += 7;
6565
6566 }
6567 while (byte & 0x80);
6568
6569 if (length_return != NULL)
b34976b6 6570 *length_return = num_read;
252b5132
RH
6571
6572 if (sign && (shift < 32) && (byte & 0x40))
6573 result |= -1 << shift;
6574
6575 return result;
6576}
6577
6578typedef struct State_Machine_Registers
6579{
b34976b6
AM
6580 unsigned long address;
6581 unsigned int file;
6582 unsigned int line;
6583 unsigned int column;
6584 int is_stmt;
6585 int basic_block;
6586 int end_sequence;
252b5132
RH
6587/* This variable hold the number of the last entry seen
6588 in the File Table. */
b34976b6 6589 unsigned int last_file_entry;
252b5132
RH
6590} SMR;
6591
6592static SMR state_machine_regs;
6593
6594static void
d3ba0551 6595reset_state_machine (int is_stmt)
252b5132
RH
6596{
6597 state_machine_regs.address = 0;
6598 state_machine_regs.file = 1;
6599 state_machine_regs.line = 1;
6600 state_machine_regs.column = 0;
6601 state_machine_regs.is_stmt = is_stmt;
6602 state_machine_regs.basic_block = 0;
6603 state_machine_regs.end_sequence = 0;
6604 state_machine_regs.last_file_entry = 0;
6605}
6606
6607/* Handled an extend line op. Returns true if this is the end
6608 of sequence. */
6609static int
d3ba0551 6610process_extended_line_op (unsigned char *data, int is_stmt, int pointer_size)
252b5132 6611{
b34976b6
AM
6612 unsigned char op_code;
6613 int bytes_read;
6614 unsigned int len;
6615 unsigned char *name;
6616 unsigned long adr;
103f02d3 6617
252b5132
RH
6618 len = read_leb128 (data, & bytes_read, 0);
6619 data += bytes_read;
6620
6621 if (len == 0)
6622 {
e5fb9629 6623 warn (_("badly formed extended line op encountered!\n"));
252b5132
RH
6624 return bytes_read;
6625 }
6626
6627 len += bytes_read;
b34976b6 6628 op_code = *data++;
252b5132
RH
6629
6630 printf (_(" Extended opcode %d: "), op_code);
103f02d3 6631
252b5132
RH
6632 switch (op_code)
6633 {
6634 case DW_LNE_end_sequence:
6635 printf (_("End of Sequence\n\n"));
6636 reset_state_machine (is_stmt);
6637 break;
6638
6639 case DW_LNE_set_address:
3590ea00 6640 adr = byte_get (data, pointer_size);
252b5132
RH
6641 printf (_("set Address to 0x%lx\n"), adr);
6642 state_machine_regs.address = adr;
6643 break;
6644
6645 case DW_LNE_define_file:
6646 printf (_(" define new File Table entry\n"));
6647 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
103f02d3 6648
b34976b6 6649 printf (_(" %d\t"), ++state_machine_regs.last_file_entry);
252b5132 6650 name = data;
3c9f43b1 6651 data += strlen ((char *) data) + 1;
252b5132
RH
6652 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6653 data += bytes_read;
6654 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6655 data += bytes_read;
6656 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6657 printf (_("%s\n\n"), name);
6658 break;
6659
6660 default:
6661 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
6662 break;
6663 }
6664
6665 return len;
6666}
6667
d9296b18
NC
6668/* Finds section NAME inside FILE and returns a
6669 pointer to it, or NULL upon failure. */
6670
6671static Elf_Internal_Shdr *
6672find_section (const char * name)
6673{
6674 Elf_Internal_Shdr *sec;
6675 unsigned int i;
0de14b54 6676
d9296b18
NC
6677 for (i = elf_header.e_shnum, sec = section_headers + i - 1;
6678 i; --i, --sec)
6679 if (strcmp (SECTION_NAME (sec), name) == 0)
6680 break;
6681
6682 if (i && sec && sec->sh_size != 0)
6683 return sec;
6684
6685 return NULL;
6686}
6687
3590ea00
NC
6688/* Size of pointers in the .debug_line section. This information is not
6689 really present in that section. It's obtained before dumping the debug
6690 sections by doing some pre-scan of the .debug_info section. */
0e0c4098
NC
6691static unsigned int * debug_line_pointer_sizes = NULL;
6692static unsigned int num_debug_line_pointer_sizes = 0;
252b5132 6693
d9296b18
NC
6694/* Locate and scan the .debug_info section in the file and record the pointer
6695 sizes for the compilation units in it. Usually an executable will have
6696 just one pointer size, but this is not guaranteed, and so we try not to
6697 make any assumptions. Returns zero upon failure, or the number of
6698 compilation units upon success. */
6699
6700static unsigned int
6701get_debug_line_pointer_sizes (FILE * file)
6702{
6703 Elf_Internal_Shdr * section;
6704 unsigned char * start;
6705 unsigned char * end;
6706 unsigned char * begin;
6707 unsigned long length;
6708 unsigned int num_units;
6709 unsigned int unit;
6710
6711 section = find_section (".debug_info");
6712 if (section == NULL)
6713 return 0;
6714
6715 length = section->sh_size;
6716 start = get_data (NULL, file, section->sh_offset, section->sh_size,
6717 _("extracting pointer sizes from .debug_info section"));
6718 if (start == NULL)
6719 return 0;
6720
6721 end = start + section->sh_size;
6722 /* First scan the section to get the number of comp units. */
6723 for (begin = start, num_units = 0; begin < end; num_units++)
6724 {
6725 /* Read the first 4 bytes. For a 32-bit DWARF section, this will
6726 be the length. For a 64-bit DWARF section, it'll be the escape
6727 code 0xffffffff followed by an 8 byte length. */
6728 length = byte_get (begin, 4);
6729
6730 if (length == 0xffffffff)
6731 {
6732 length = byte_get (begin + 4, 8);
6733 begin += length + 12;
6734 }
6735 else
6736 begin += length + 4;
6737 }
6738
6739 if (num_units == 0)
6740 {
6741 error (_("No comp units in .debug_info section ?"));
6742 free (start);
6743 return 0;
6744 }
6745
6746 /* Then allocate an array to hold the pointer sizes. */
6747 debug_line_pointer_sizes = malloc (num_units * sizeof * debug_line_pointer_sizes);
6748 if (debug_line_pointer_sizes == NULL)
6749 {
6750 error (_("Not enough memory for a pointer size array of %u entries"),
6751 num_units);
6752 free (start);
6753 return 0;
6754 }
6755
6756 /* Populate the array. */
6757 for (begin = start, unit = 0; begin < end; unit++)
6758 {
6759 length = byte_get (begin, 4);
6760 if (length == 0xffffffff)
6761 {
6762 /* For 64-bit DWARF, the 1-byte address_size field is 22 bytes
6763 from the start of the section. This is computed as follows:
6764
6765 unit_length: 12 bytes
6766 version: 2 bytes
6767 debug_abbrev_offset: 8 bytes
6768 -----------------------------
6769 Total: 22 bytes */
6770
6771 debug_line_pointer_sizes [unit] = byte_get (begin + 22, 1);
6772 length = byte_get (begin + 4, 8);
6773 begin += length + 12;
6774 }
6775 else
6776 {
6777 /* For 32-bit DWARF, the 1-byte address_size field is 10 bytes from
6778 the start of the section:
0de14b54 6779
d9296b18
NC
6780 unit_length: 4 bytes
6781 version: 2 bytes
6782 debug_abbrev_offset: 4 bytes
6783 -----------------------------
6784 Total: 10 bytes */
6785
6786 debug_line_pointer_sizes [unit] = byte_get (begin + 10, 1);
6787 begin += length + 4;
6788 }
6789 }
6790
6791 free (start);
6792 num_debug_line_pointer_sizes = num_units;
6793 return num_units;
6794}
6795
252b5132 6796static int
d3ba0551 6797display_debug_lines (Elf_Internal_Shdr *section,
d9296b18 6798 unsigned char *start, FILE *file)
252b5132 6799{
ee42cf8c 6800 unsigned char *hdrptr;
b34976b6
AM
6801 DWARF2_Internal_LineInfo info;
6802 unsigned char *standard_opcodes;
6803 unsigned char *data = start;
6804 unsigned char *end = start + section->sh_size;
6805 unsigned char *end_of_sequence;
6806 int i;
ee42cf8c
NC
6807 int offset_size;
6808 int initial_length_size;
0e0c4098 6809 unsigned int comp_unit = 0;
252b5132
RH
6810
6811 printf (_("\nDump of debug contents of section %s:\n\n"),
6812 SECTION_NAME (section));
6813
d9296b18
NC
6814 if (num_debug_line_pointer_sizes == 0)
6815 get_debug_line_pointer_sizes (file);
6816
252b5132
RH
6817 while (data < end)
6818 {
0e0c4098
NC
6819 unsigned int pointer_size;
6820
ee42cf8c 6821 hdrptr = data;
252b5132
RH
6822
6823 /* Check the length of the block. */
ee42cf8c
NC
6824 info.li_length = byte_get (hdrptr, 4);
6825 hdrptr += 4;
428409d5
NC
6826
6827 if (info.li_length == 0xffffffff)
6828 {
ee42cf8c
NC
6829 /* This section is 64-bit DWARF 3. */
6830 info.li_length = byte_get (hdrptr, 8);
6831 hdrptr += 8;
6832 offset_size = 8;
6833 initial_length_size = 12;
6834 }
6835 else
6836 {
6837 offset_size = 4;
6838 initial_length_size = 4;
428409d5
NC
6839 }
6840
ee42cf8c 6841 if (info.li_length + initial_length_size > section->sh_size)
252b5132
RH
6842 {
6843 warn
6844 (_("The line info appears to be corrupt - the section is too small\n"));
6845 return 0;
6846 }
103f02d3 6847
252b5132 6848 /* Check its version number. */
ee42cf8c
NC
6849 info.li_version = byte_get (hdrptr, 2);
6850 hdrptr += 2;
6851 if (info.li_version != 2 && info.li_version != 3)
252b5132 6852 {
ee42cf8c 6853 warn (_("Only DWARF version 2 and 3 line info is currently supported.\n"));
252b5132
RH
6854 return 0;
6855 }
103f02d3 6856
ee42cf8c
NC
6857 info.li_prologue_length = byte_get (hdrptr, offset_size);
6858 hdrptr += offset_size;
6859 info.li_min_insn_length = byte_get (hdrptr, 1);
6860 hdrptr++;
6861 info.li_default_is_stmt = byte_get (hdrptr, 1);
6862 hdrptr++;
6863 info.li_line_base = byte_get (hdrptr, 1);
6864 hdrptr++;
6865 info.li_line_range = byte_get (hdrptr, 1);
6866 hdrptr++;
6867 info.li_opcode_base = byte_get (hdrptr, 1);
6868 hdrptr++;
103f02d3 6869
252b5132
RH
6870 /* Sign extend the line base field. */
6871 info.li_line_base <<= 24;
6872 info.li_line_base >>= 24;
103f02d3 6873
0e0c4098
NC
6874 /* Get the pointer size from the comp unit associated
6875 with this block of line number information. */
6876 if (comp_unit >= num_debug_line_pointer_sizes)
6877 {
935d0bca 6878 error (_("Not enough comp units for .debug_line section\n"));
0e0c4098
NC
6879 return 0;
6880 }
6881 else
6882 {
6883 pointer_size = debug_line_pointer_sizes [comp_unit];
6884 comp_unit ++;
6885 }
6886
252b5132
RH
6887 printf (_(" Length: %ld\n"), info.li_length);
6888 printf (_(" DWARF Version: %d\n"), info.li_version);
ff94ebf2 6889 printf (_(" Prologue Length: %d\n"), info.li_prologue_length);
252b5132
RH
6890 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
6891 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
6892 printf (_(" Line Base: %d\n"), info.li_line_base);
6893 printf (_(" Line Range: %d\n"), info.li_line_range);
6894 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
0e0c4098 6895 printf (_(" (Pointer size: %u)\n"), pointer_size);
252b5132 6896
ee42cf8c 6897 end_of_sequence = data + info.li_length + initial_length_size;
252b5132
RH
6898
6899 reset_state_machine (info.li_default_is_stmt);
103f02d3 6900
252b5132 6901 /* Display the contents of the Opcodes table. */
ee42cf8c 6902 standard_opcodes = hdrptr;
103f02d3 6903
252b5132 6904 printf (_("\n Opcodes:\n"));
103f02d3 6905
252b5132 6906 for (i = 1; i < info.li_opcode_base; i++)
7a4b7442 6907 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
103f02d3 6908
252b5132
RH
6909 /* Display the contents of the Directory table. */
6910 data = standard_opcodes + info.li_opcode_base - 1;
103f02d3 6911
b34976b6 6912 if (*data == 0)
252b5132
RH
6913 printf (_("\n The Directory Table is empty.\n"));
6914 else
6915 {
6916 printf (_("\n The Directory Table:\n"));
103f02d3 6917
b34976b6 6918 while (*data != 0)
252b5132
RH
6919 {
6920 printf (_(" %s\n"), data);
103f02d3 6921
3c9f43b1 6922 data += strlen ((char *) data) + 1;
252b5132
RH
6923 }
6924 }
103f02d3 6925
252b5132 6926 /* Skip the NUL at the end of the table. */
b34976b6 6927 data++;
103f02d3 6928
252b5132 6929 /* Display the contents of the File Name table. */
b34976b6 6930 if (*data == 0)
252b5132
RH
6931 printf (_("\n The File Name Table is empty.\n"));
6932 else
6933 {
6934 printf (_("\n The File Name Table:\n"));
6935 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
103f02d3 6936
b34976b6 6937 while (*data != 0)
252b5132 6938 {
b34976b6 6939 unsigned char *name;
252b5132 6940 int bytes_read;
103f02d3 6941
b34976b6 6942 printf (_(" %d\t"), ++state_machine_regs.last_file_entry);
252b5132 6943 name = data;
103f02d3 6944
3c9f43b1 6945 data += strlen ((char *) data) + 1;
103f02d3 6946
252b5132
RH
6947 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6948 data += bytes_read;
6949 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6950 data += bytes_read;
6951 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
6952 data += bytes_read;
6953 printf (_("%s\n"), name);
6954 }
6955 }
103f02d3 6956
252b5132 6957 /* Skip the NUL at the end of the table. */
b34976b6 6958 data++;
103f02d3 6959
252b5132
RH
6960 /* Now display the statements. */
6961 printf (_("\n Line Number Statements:\n"));
103f02d3
UD
6962
6963
252b5132
RH
6964 while (data < end_of_sequence)
6965 {
6966 unsigned char op_code;
b34976b6
AM
6967 int adv;
6968 int bytes_read;
103f02d3 6969
b34976b6 6970 op_code = *data++;
103f02d3 6971
1a509dcc
GK
6972 if (op_code >= info.li_opcode_base)
6973 {
6974 op_code -= info.li_opcode_base;
6975 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
6976 state_machine_regs.address += adv;
6977 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
6978 op_code, adv, state_machine_regs.address);
6979 adv = (op_code % info.li_line_range) + info.li_line_base;
6980 state_machine_regs.line += adv;
6981 printf (_(" and Line by %d to %d\n"),
6982 adv, state_machine_regs.line);
53c7db4b
KH
6983 }
6984 else switch (op_code)
252b5132
RH
6985 {
6986 case DW_LNS_extended_op:
3590ea00 6987 data += process_extended_line_op (data, info.li_default_is_stmt,
0e0c4098 6988 pointer_size);
252b5132 6989 break;
103f02d3 6990
252b5132
RH
6991 case DW_LNS_copy:
6992 printf (_(" Copy\n"));
6993 break;
103f02d3 6994
252b5132
RH
6995 case DW_LNS_advance_pc:
6996 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
6997 data += bytes_read;
6998 state_machine_regs.address += adv;
6999 printf (_(" Advance PC by %d to %lx\n"), adv,
7000 state_machine_regs.address);
7001 break;
103f02d3 7002
252b5132
RH
7003 case DW_LNS_advance_line:
7004 adv = read_leb128 (data, & bytes_read, 1);
7005 data += bytes_read;
7006 state_machine_regs.line += adv;
7007 printf (_(" Advance Line by %d to %d\n"), adv,
7008 state_machine_regs.line);
7009 break;
103f02d3 7010
252b5132
RH
7011 case DW_LNS_set_file:
7012 adv = read_leb128 (data, & bytes_read, 0);
7013 data += bytes_read;
7014 printf (_(" Set File Name to entry %d in the File Name Table\n"),
7015 adv);
7016 state_machine_regs.file = adv;
7017 break;
103f02d3 7018
252b5132
RH
7019 case DW_LNS_set_column:
7020 adv = read_leb128 (data, & bytes_read, 0);
7021 data += bytes_read;
7022 printf (_(" Set column to %d\n"), adv);
7023 state_machine_regs.column = adv;
7024 break;
103f02d3 7025
252b5132
RH
7026 case DW_LNS_negate_stmt:
7027 adv = state_machine_regs.is_stmt;
7028 adv = ! adv;
7029 printf (_(" Set is_stmt to %d\n"), adv);
7030 state_machine_regs.is_stmt = adv;
7031 break;
103f02d3 7032
252b5132
RH
7033 case DW_LNS_set_basic_block:
7034 printf (_(" Set basic block\n"));
7035 state_machine_regs.basic_block = 1;
7036 break;
103f02d3 7037
252b5132 7038 case DW_LNS_const_add_pc:
2366453a
NC
7039 adv = (((255 - info.li_opcode_base) / info.li_line_range)
7040 * info.li_min_insn_length);
252b5132
RH
7041 state_machine_regs.address += adv;
7042 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
7043 state_machine_regs.address);
7044 break;
103f02d3 7045
252b5132
RH
7046 case DW_LNS_fixed_advance_pc:
7047 adv = byte_get (data, 2);
7048 data += 2;
7049 state_machine_regs.address += adv;
7050 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
7051 adv, state_machine_regs.address);
7052 break;
103f02d3 7053
1a509dcc
GK
7054 case DW_LNS_set_prologue_end:
7055 printf (_(" Set prologue_end to true\n"));
7056 break;
53c7db4b 7057
1a509dcc
GK
7058 case DW_LNS_set_epilogue_begin:
7059 printf (_(" Set epilogue_begin to true\n"));
7060 break;
53c7db4b 7061
1a509dcc
GK
7062 case DW_LNS_set_isa:
7063 adv = read_leb128 (data, & bytes_read, 0);
7064 data += bytes_read;
7065 printf (_(" Set ISA to %d\n"), adv);
7066 break;
53c7db4b 7067
252b5132 7068 default:
1a509dcc
GK
7069 printf (_(" Unknown opcode %d with operands: "), op_code);
7070 {
7071 int i;
7072 for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
7073 {
7074 printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
7075 i == 1 ? "" : ", ");
7076 data += bytes_read;
7077 }
7078 putchar ('\n');
7079 }
252b5132
RH
7080 break;
7081 }
7082 }
1a509dcc 7083 putchar ('\n');
252b5132 7084 }
103f02d3 7085
252b5132
RH
7086 return 1;
7087}
7088
7089static int
d3ba0551
AM
7090display_debug_pubnames (Elf_Internal_Shdr *section,
7091 unsigned char *start,
7092 FILE *file ATTRIBUTE_UNUSED)
252b5132 7093{
b34976b6
AM
7094 DWARF2_Internal_PubNames pubnames;
7095 unsigned char *end;
252b5132
RH
7096
7097 end = start + section->sh_size;
7098
7099 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
7100
7101 while (start < end)
7102 {
b34976b6
AM
7103 unsigned char *data;
7104 unsigned long offset;
ee42cf8c 7105 int offset_size, initial_length_size;
252b5132 7106
ee42cf8c 7107 data = start;
252b5132 7108
ee42cf8c
NC
7109 pubnames.pn_length = byte_get (data, 4);
7110 data += 4;
428409d5
NC
7111 if (pubnames.pn_length == 0xffffffff)
7112 {
ee42cf8c
NC
7113 pubnames.pn_length = byte_get (data, 8);
7114 data += 8;
7115 offset_size = 8;
7116 initial_length_size = 12;
7117 }
7118 else
7119 {
7120 offset_size = 4;
7121 initial_length_size = 4;
428409d5
NC
7122 }
7123
ee42cf8c
NC
7124 pubnames.pn_version = byte_get (data, 2);
7125 data += 2;
7126 pubnames.pn_offset = byte_get (data, offset_size);
7127 data += offset_size;
7128 pubnames.pn_size = byte_get (data, offset_size);
7129 data += offset_size;
7130
7131 start += pubnames.pn_length + initial_length_size;
7132
7133 if (pubnames.pn_version != 2 && pubnames.pn_version != 3)
252b5132 7134 {
3f215a10
NC
7135 static int warned = 0;
7136
7137 if (! warned)
7138 {
ee42cf8c 7139 warn (_("Only DWARF 2 and 3 pubnames are currently supported\n"));
3f215a10
NC
7140 warned = 1;
7141 }
76da6bbe 7142
252b5132
RH
7143 continue;
7144 }
7145
7146 printf (_(" Length: %ld\n"),
7147 pubnames.pn_length);
7148 printf (_(" Version: %d\n"),
7149 pubnames.pn_version);
7150 printf (_(" Offset into .debug_info section: %ld\n"),
7151 pubnames.pn_offset);
7152 printf (_(" Size of area in .debug_info section: %ld\n"),
7153 pubnames.pn_size);
7154
7155 printf (_("\n Offset\tName\n"));
7156
7157 do
7158 {
ee42cf8c 7159 offset = byte_get (data, offset_size);
252b5132
RH
7160
7161 if (offset != 0)
7162 {
ee42cf8c 7163 data += offset_size;
935a41f5 7164 printf (" %-6ld\t\t%s\n", offset, data);
3c9f43b1 7165 data += strlen ((char *) data) + 1;
252b5132
RH
7166 }
7167 }
7168 while (offset != 0);
7169 }
7170
7171 printf ("\n");
7172 return 1;
7173}
7174
7175static char *
d3ba0551 7176get_TAG_name (unsigned long tag)
252b5132
RH
7177{
7178 switch (tag)
7179 {
b34976b6
AM
7180 case DW_TAG_padding: return "DW_TAG_padding";
7181 case DW_TAG_array_type: return "DW_TAG_array_type";
7182 case DW_TAG_class_type: return "DW_TAG_class_type";
7183 case DW_TAG_entry_point: return "DW_TAG_entry_point";
7184 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
7185 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
7186 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
7187 case DW_TAG_label: return "DW_TAG_label";
7188 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
7189 case DW_TAG_member: return "DW_TAG_member";
7190 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
7191 case DW_TAG_reference_type: return "DW_TAG_reference_type";
7192 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
7193 case DW_TAG_string_type: return "DW_TAG_string_type";
7194 case DW_TAG_structure_type: return "DW_TAG_structure_type";
7195 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
7196 case DW_TAG_typedef: return "DW_TAG_typedef";
7197 case DW_TAG_union_type: return "DW_TAG_union_type";
252b5132 7198 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
b34976b6
AM
7199 case DW_TAG_variant: return "DW_TAG_variant";
7200 case DW_TAG_common_block: return "DW_TAG_common_block";
7201 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
7202 case DW_TAG_inheritance: return "DW_TAG_inheritance";
7203 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
7204 case DW_TAG_module: return "DW_TAG_module";
7205 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
7206 case DW_TAG_set_type: return "DW_TAG_set_type";
7207 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
7208 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
7209 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
7210 case DW_TAG_base_type: return "DW_TAG_base_type";
7211 case DW_TAG_catch_block: return "DW_TAG_catch_block";
7212 case DW_TAG_const_type: return "DW_TAG_const_type";
7213 case DW_TAG_constant: return "DW_TAG_constant";
7214 case DW_TAG_enumerator: return "DW_TAG_enumerator";
7215 case DW_TAG_file_type: return "DW_TAG_file_type";
7216 case DW_TAG_friend: return "DW_TAG_friend";
7217 case DW_TAG_namelist: return "DW_TAG_namelist";
7218 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
7219 case DW_TAG_packed_type: return "DW_TAG_packed_type";
7220 case DW_TAG_subprogram: return "DW_TAG_subprogram";
7221 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
7222 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
7223 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
7224 case DW_TAG_try_block: return "DW_TAG_try_block";
7225 case DW_TAG_variant_part: return "DW_TAG_variant_part";
7226 case DW_TAG_variable: return "DW_TAG_variable";
7227 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
7228 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
7229 case DW_TAG_format_label: return "DW_TAG_format_label";
7230 case DW_TAG_function_template: return "DW_TAG_function_template";
7231 case DW_TAG_class_template: return "DW_TAG_class_template";
b811889f 7232 /* DWARF 2.1 values. */
b34976b6
AM
7233 case DW_TAG_dwarf_procedure: return "DW_TAG_dwarf_procedure";
7234 case DW_TAG_restrict_type: return "DW_TAG_restrict_type";
7235 case DW_TAG_interface_type: return "DW_TAG_interface_type";
7236 case DW_TAG_namespace: return "DW_TAG_namespace";
7237 case DW_TAG_imported_module: return "DW_TAG_imported_module";
7238 case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type";
7239 case DW_TAG_partial_unit: return "DW_TAG_partial_unit";
7240 case DW_TAG_imported_unit: return "DW_TAG_imported_unit";
84ad6ede 7241 /* UPC values. */
ba2685cc
AM
7242 case DW_TAG_upc_shared_type: return "DW_TAG_upc_shared_type";
7243 case DW_TAG_upc_strict_type: return "DW_TAG_upc_strict_type";
7244 case DW_TAG_upc_relaxed_type: return "DW_TAG_upc_relaxed_type";
252b5132
RH
7245 default:
7246 {
b34976b6 7247 static char buffer[100];
252b5132
RH
7248
7249 sprintf (buffer, _("Unknown TAG value: %lx"), tag);
7250 return buffer;
7251 }
7252 }
7253}
7254
7255static char *
d3ba0551 7256get_AT_name (unsigned long attribute)
252b5132
RH
7257{
7258 switch (attribute)
7259 {
b34976b6
AM
7260 case DW_AT_sibling: return "DW_AT_sibling";
7261 case DW_AT_location: return "DW_AT_location";
7262 case DW_AT_name: return "DW_AT_name";
7263 case DW_AT_ordering: return "DW_AT_ordering";
7264 case DW_AT_subscr_data: return "DW_AT_subscr_data";
7265 case DW_AT_byte_size: return "DW_AT_byte_size";
7266 case DW_AT_bit_offset: return "DW_AT_bit_offset";
7267 case DW_AT_bit_size: return "DW_AT_bit_size";
7268 case DW_AT_element_list: return "DW_AT_element_list";
7269 case DW_AT_stmt_list: return "DW_AT_stmt_list";
7270 case DW_AT_low_pc: return "DW_AT_low_pc";
7271 case DW_AT_high_pc: return "DW_AT_high_pc";
7272 case DW_AT_language: return "DW_AT_language";
7273 case DW_AT_member: return "DW_AT_member";
7274 case DW_AT_discr: return "DW_AT_discr";
7275 case DW_AT_discr_value: return "DW_AT_discr_value";
7276 case DW_AT_visibility: return "DW_AT_visibility";
7277 case DW_AT_import: return "DW_AT_import";
7278 case DW_AT_string_length: return "DW_AT_string_length";
7279 case DW_AT_common_reference: return "DW_AT_common_reference";
7280 case DW_AT_comp_dir: return "DW_AT_comp_dir";
7281 case DW_AT_const_value: return "DW_AT_const_value";
7282 case DW_AT_containing_type: return "DW_AT_containing_type";
7283 case DW_AT_default_value: return "DW_AT_default_value";
7284 case DW_AT_inline: return "DW_AT_inline";
7285 case DW_AT_is_optional: return "DW_AT_is_optional";
7286 case DW_AT_lower_bound: return "DW_AT_lower_bound";
7287 case DW_AT_producer: return "DW_AT_producer";
7288 case DW_AT_prototyped: return "DW_AT_prototyped";
7289 case DW_AT_return_addr: return "DW_AT_return_addr";
7290 case DW_AT_start_scope: return "DW_AT_start_scope";
7291 case DW_AT_stride_size: return "DW_AT_stride_size";
7292 case DW_AT_upper_bound: return "DW_AT_upper_bound";
7293 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
7294 case DW_AT_accessibility: return "DW_AT_accessibility";
7295 case DW_AT_address_class: return "DW_AT_address_class";
7296 case DW_AT_artificial: return "DW_AT_artificial";
7297 case DW_AT_base_types: return "DW_AT_base_types";
7298 case DW_AT_calling_convention: return "DW_AT_calling_convention";
7299 case DW_AT_count: return "DW_AT_count";
7300 case DW_AT_data_member_location: return "DW_AT_data_member_location";
7301 case DW_AT_decl_column: return "DW_AT_decl_column";
7302 case DW_AT_decl_file: return "DW_AT_decl_file";
7303 case DW_AT_decl_line: return "DW_AT_decl_line";
7304 case DW_AT_declaration: return "DW_AT_declaration";
7305 case DW_AT_discr_list: return "DW_AT_discr_list";
7306 case DW_AT_encoding: return "DW_AT_encoding";
7307 case DW_AT_external: return "DW_AT_external";
7308 case DW_AT_frame_base: return "DW_AT_frame_base";
7309 case DW_AT_friend: return "DW_AT_friend";
7310 case DW_AT_identifier_case: return "DW_AT_identifier_case";
7311 case DW_AT_macro_info: return "DW_AT_macro_info";
7312 case DW_AT_namelist_items: return "DW_AT_namelist_items";
7313 case DW_AT_priority: return "DW_AT_priority";
7314 case DW_AT_segment: return "DW_AT_segment";
7315 case DW_AT_specification: return "DW_AT_specification";
7316 case DW_AT_static_link: return "DW_AT_static_link";
7317 case DW_AT_type: return "DW_AT_type";
7318 case DW_AT_use_location: return "DW_AT_use_location";
7319 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
7320 case DW_AT_virtuality: return "DW_AT_virtuality";
7321 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
12ab83a9 7322 /* DWARF 2.1 values. */
b34976b6
AM
7323 case DW_AT_allocated: return "DW_AT_allocated";
7324 case DW_AT_associated: return "DW_AT_associated";
7325 case DW_AT_data_location: return "DW_AT_data_location";
7326 case DW_AT_stride: return "DW_AT_stride";
7327 case DW_AT_entry_pc: return "DW_AT_entry_pc";
7328 case DW_AT_use_UTF8: return "DW_AT_use_UTF8";
7329 case DW_AT_extension: return "DW_AT_extension";
7330 case DW_AT_ranges: return "DW_AT_ranges";
7331 case DW_AT_trampoline: return "DW_AT_trampoline";
7332 case DW_AT_call_column: return "DW_AT_call_column";
7333 case DW_AT_call_file: return "DW_AT_call_file";
7334 case DW_AT_call_line: return "DW_AT_call_line";
12ab83a9 7335 /* SGI/MIPS extensions. */
b34976b6
AM
7336 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
7337 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
7338 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
7339 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
252b5132 7340 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
b34976b6
AM
7341 case DW_AT_MIPS_software_pipeline_depth:
7342 return "DW_AT_MIPS_software_pipeline_depth";
7343 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
7344 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
7345 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
7346 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
7347 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
12ab83a9 7348 /* GNU extensions. */
b34976b6
AM
7349 case DW_AT_sf_names: return "DW_AT_sf_names";
7350 case DW_AT_src_info: return "DW_AT_src_info";
7351 case DW_AT_mac_info: return "DW_AT_mac_info";
7352 case DW_AT_src_coords: return "DW_AT_src_coords";
7353 case DW_AT_body_begin: return "DW_AT_body_begin";
7354 case DW_AT_body_end: return "DW_AT_body_end";
7355 case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
84ad6ede
NC
7356 /* UPC extension. */
7357 case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled";
252b5132
RH
7358 default:
7359 {
b34976b6 7360 static char buffer[100];
252b5132
RH
7361
7362 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
7363 return buffer;
7364 }
7365 }
7366}
7367
7368static char *
d3ba0551 7369get_FORM_name (unsigned long form)
252b5132
RH
7370{
7371 switch (form)
7372 {
b34976b6
AM
7373 case DW_FORM_addr: return "DW_FORM_addr";
7374 case DW_FORM_block2: return "DW_FORM_block2";
7375 case DW_FORM_block4: return "DW_FORM_block4";
7376 case DW_FORM_data2: return "DW_FORM_data2";
7377 case DW_FORM_data4: return "DW_FORM_data4";
7378 case DW_FORM_data8: return "DW_FORM_data8";
7379 case DW_FORM_string: return "DW_FORM_string";
7380 case DW_FORM_block: return "DW_FORM_block";
7381 case DW_FORM_block1: return "DW_FORM_block1";
7382 case DW_FORM_data1: return "DW_FORM_data1";
7383 case DW_FORM_flag: return "DW_FORM_flag";
7384 case DW_FORM_sdata: return "DW_FORM_sdata";
7385 case DW_FORM_strp: return "DW_FORM_strp";
7386 case DW_FORM_udata: return "DW_FORM_udata";
7387 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
7388 case DW_FORM_ref1: return "DW_FORM_ref1";
7389 case DW_FORM_ref2: return "DW_FORM_ref2";
7390 case DW_FORM_ref4: return "DW_FORM_ref4";
7391 case DW_FORM_ref8: return "DW_FORM_ref8";
7392 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
7393 case DW_FORM_indirect: return "DW_FORM_indirect";
252b5132
RH
7394 default:
7395 {
b34976b6 7396 static char buffer[100];
252b5132
RH
7397
7398 sprintf (buffer, _("Unknown FORM value: %lx"), form);
7399 return buffer;
7400 }
7401 }
7402}
7403
50c2245b 7404/* FIXME: There are better and more efficient ways to handle
252b5132
RH
7405 these structures. For now though, I just want something that
7406 is simple to implement. */
7407typedef struct abbrev_attr
7408{
b34976b6
AM
7409 unsigned long attribute;
7410 unsigned long form;
7411 struct abbrev_attr *next;
252b5132
RH
7412}
7413abbrev_attr;
7414
7415typedef struct abbrev_entry
7416{
b34976b6
AM
7417 unsigned long entry;
7418 unsigned long tag;
7419 int children;
7420 struct abbrev_attr *first_attr;
7421 struct abbrev_attr *last_attr;
7422 struct abbrev_entry *next;
252b5132
RH
7423}
7424abbrev_entry;
7425
b34976b6
AM
7426static abbrev_entry *first_abbrev = NULL;
7427static abbrev_entry *last_abbrev = NULL;
252b5132
RH
7428
7429static void
d3ba0551 7430free_abbrevs (void)
252b5132 7431{
b34976b6 7432 abbrev_entry *abbrev;
252b5132
RH
7433
7434 for (abbrev = first_abbrev; abbrev;)
7435 {
b34976b6
AM
7436 abbrev_entry *next = abbrev->next;
7437 abbrev_attr *attr;
252b5132
RH
7438
7439 for (attr = abbrev->first_attr; attr;)
7440 {
b34976b6 7441 abbrev_attr *next = attr->next;
252b5132
RH
7442
7443 free (attr);
7444 attr = next;
7445 }
7446
7447 free (abbrev);
7448 abbrev = next;
7449 }
7450
7451 last_abbrev = first_abbrev = NULL;
7452}
7453
7454static void
d3ba0551 7455add_abbrev (unsigned long number, unsigned long tag, int children)
252b5132 7456{
b34976b6 7457 abbrev_entry *entry;
252b5132 7458
d3ba0551 7459 entry = malloc (sizeof (*entry));
252b5132
RH
7460
7461 if (entry == NULL)
7462 /* ugg */
7463 return;
7464
7465 entry->entry = number;
7466 entry->tag = tag;
7467 entry->children = children;
7468 entry->first_attr = NULL;
7469 entry->last_attr = NULL;
7470 entry->next = NULL;
7471
7472 if (first_abbrev == NULL)
7473 first_abbrev = entry;
7474 else
7475 last_abbrev->next = entry;
7476
7477 last_abbrev = entry;
7478}
7479
7480static void
d3ba0551 7481add_abbrev_attr (unsigned long attribute, unsigned long form)
252b5132 7482{
b34976b6 7483 abbrev_attr *attr;
252b5132 7484
d3ba0551 7485 attr = malloc (sizeof (*attr));
252b5132
RH
7486
7487 if (attr == NULL)
7488 /* ugg */
7489 return;
7490
7491 attr->attribute = attribute;
7492 attr->form = form;
7493 attr->next = NULL;
7494
7495 if (last_abbrev->first_attr == NULL)
7496 last_abbrev->first_attr = attr;
7497 else
7498 last_abbrev->last_attr->next = attr;
7499
7500 last_abbrev->last_attr = attr;
7501}
7502
7503/* Processes the (partial) contents of a .debug_abbrev section.
7504 Returns NULL if the end of the section was encountered.
7505 Returns the address after the last byte read if the end of
7506 an abbreviation set was found. */
7507
7508static unsigned char *
d3ba0551 7509process_abbrev_section (unsigned char *start, unsigned char *end)
252b5132
RH
7510{
7511 if (first_abbrev != NULL)
7512 return NULL;
7513
7514 while (start < end)
7515 {
b34976b6 7516 int bytes_read;
252b5132
RH
7517 unsigned long entry;
7518 unsigned long tag;
7519 unsigned long attribute;
b34976b6 7520 int children;
252b5132
RH
7521
7522 entry = read_leb128 (start, & bytes_read, 0);
7523 start += bytes_read;
7524
a3f779db
NC
7525 /* A single zero is supposed to end the section according
7526 to the standard. If there's more, then signal that to
7527 the caller. */
252b5132 7528 if (entry == 0)
a3f779db 7529 return start == end ? NULL : start;
252b5132
RH
7530
7531 tag = read_leb128 (start, & bytes_read, 0);
7532 start += bytes_read;
7533
b34976b6 7534 children = *start++;
252b5132
RH
7535
7536 add_abbrev (entry, tag, children);
7537
7538 do
7539 {
7540 unsigned long form;
7541
7542 attribute = read_leb128 (start, & bytes_read, 0);
7543 start += bytes_read;
7544
7545 form = read_leb128 (start, & bytes_read, 0);
7546 start += bytes_read;
7547
7548 if (attribute != 0)
7549 add_abbrev_attr (attribute, form);
7550 }
7551 while (attribute != 0);
7552 }
7553
7554 return NULL;
7555}
7556
7557
e0c60db2 7558static int
d3ba0551
AM
7559display_debug_macinfo (Elf_Internal_Shdr *section,
7560 unsigned char *start,
7561 FILE *file ATTRIBUTE_UNUSED)
e0c60db2 7562{
b34976b6
AM
7563 unsigned char *end = start + section->sh_size;
7564 unsigned char *curr = start;
e0c60db2
NC
7565 unsigned int bytes_read;
7566 enum dwarf_macinfo_record_type op;
7567
7568 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
7569
7570 while (curr < end)
7571 {
7572 unsigned int lineno;
b34976b6 7573 const char *string;
e0c60db2 7574
b34976b6
AM
7575 op = *curr;
7576 curr++;
e0c60db2
NC
7577
7578 switch (op)
7579 {
7580 case DW_MACINFO_start_file:
7581 {
7582 unsigned int filenum;
7583
7584 lineno = read_leb128 (curr, & bytes_read, 0);
7585 curr += bytes_read;
7586 filenum = read_leb128 (curr, & bytes_read, 0);
7587 curr += bytes_read;
7588
7589 printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"), lineno, filenum);
7590 }
7591 break;
7592
7593 case DW_MACINFO_end_file:
7594 printf (_(" DW_MACINFO_end_file\n"));
7595 break;
7596
7597 case DW_MACINFO_define:
7598 lineno = read_leb128 (curr, & bytes_read, 0);
7599 curr += bytes_read;
7600 string = curr;
7601 curr += strlen (string) + 1;
7602 printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"), lineno, string);
7603 break;
7604
7605 case DW_MACINFO_undef:
7606 lineno = read_leb128 (curr, & bytes_read, 0);
7607 curr += bytes_read;
7608 string = curr;
7609 curr += strlen (string) + 1;
7610 printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"), lineno, string);
7611 break;
7612
7613 case DW_MACINFO_vendor_ext:
7614 {
7615 unsigned int constant;
7616
7617 constant = read_leb128 (curr, & bytes_read, 0);
7618 curr += bytes_read;
7619 string = curr;
7620 curr += strlen (string) + 1;
7621 printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"), constant, string);
7622 }
7623 break;
7624 }
7625 }
7626
7627 return 1;
7628}
0823fbca 7629
e0c60db2 7630
252b5132 7631static int
d3ba0551
AM
7632display_debug_abbrev (Elf_Internal_Shdr *section,
7633 unsigned char *start,
7634 FILE *file ATTRIBUTE_UNUSED)
252b5132 7635{
b34976b6
AM
7636 abbrev_entry *entry;
7637 unsigned char *end = start + section->sh_size;
252b5132
RH
7638
7639 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
7640
7641 do
7642 {
7643 start = process_abbrev_section (start, end);
7644
ef5cdfc7
JJ
7645 if (first_abbrev == NULL)
7646 continue;
7647
252b5132
RH
7648 printf (_(" Number TAG\n"));
7649
7650 for (entry = first_abbrev; entry; entry = entry->next)
7651 {
b34976b6 7652 abbrev_attr *attr;
252b5132
RH
7653
7654 printf (_(" %ld %s [%s]\n"),
7655 entry->entry,
7656 get_TAG_name (entry->tag),
7657 entry->children ? _("has children") : _("no children"));
7658
7659 for (attr = entry->first_attr; attr; attr = attr->next)
7660 {
7661 printf (_(" %-18s %s\n"),
7662 get_AT_name (attr->attribute),
7663 get_FORM_name (attr->form));
7664 }
7665 }
ef5cdfc7
JJ
7666
7667 free_abbrevs ();
252b5132
RH
7668 }
7669 while (start);
7670
7671 printf ("\n");
7672
7673 return 1;
7674}
7675
7676
7677static unsigned char *
d3ba0551 7678display_block (unsigned char *data, unsigned long length)
252b5132
RH
7679{
7680 printf (_(" %lu byte block: "), length);
7681
7682 while (length --)
b34976b6 7683 printf ("%lx ", (unsigned long) byte_get (data++, 1));
252b5132
RH
7684
7685 return data;
7686}
7687
7688static void
d3ba0551
AM
7689decode_location_expression (unsigned char * data,
7690 unsigned int pointer_size,
7691 unsigned long length)
252b5132 7692{
b34976b6
AM
7693 unsigned op;
7694 int bytes_read;
7695 unsigned long uvalue;
7696 unsigned char *end = data + length;
252b5132 7697
eb6bd4d3 7698 while (data < end)
252b5132 7699 {
b34976b6 7700 op = *data++;
252b5132 7701
eb6bd4d3
JM
7702 switch (op)
7703 {
7704 case DW_OP_addr:
7705 printf ("DW_OP_addr: %lx",
7706 (unsigned long) byte_get (data, pointer_size));
7707 data += pointer_size;
7708 break;
7709 case DW_OP_deref:
7710 printf ("DW_OP_deref");
7711 break;
7712 case DW_OP_const1u:
7713 printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
7714 break;
7715 case DW_OP_const1s:
74013231 7716 printf ("DW_OP_const1s: %ld", (long) byte_get_signed (data++, 1));
eb6bd4d3
JM
7717 break;
7718 case DW_OP_const2u:
7719 printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
7720 data += 2;
7721 break;
7722 case DW_OP_const2s:
74013231 7723 printf ("DW_OP_const2s: %ld", (long) byte_get_signed (data, 2));
eb6bd4d3
JM
7724 data += 2;
7725 break;
7726 case DW_OP_const4u:
7727 printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
7728 data += 4;
7729 break;
7730 case DW_OP_const4s:
74013231 7731 printf ("DW_OP_const4s: %ld", (long) byte_get_signed (data, 4));
eb6bd4d3
JM
7732 data += 4;
7733 break;
7734 case DW_OP_const8u:
7735 printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
7736 (unsigned long) byte_get (data + 4, 4));
7737 data += 8;
7738 break;
7739 case DW_OP_const8s:
7740 printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
7741 (long) byte_get (data + 4, 4));
7742 data += 8;
7743 break;
7744 case DW_OP_constu:
7745 printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
7746 data += bytes_read;
7747 break;
7748 case DW_OP_consts:
7749 printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
7750 data += bytes_read;
7751 break;
7752 case DW_OP_dup:
7753 printf ("DW_OP_dup");
7754 break;
7755 case DW_OP_drop:
7756 printf ("DW_OP_drop");
7757 break;
7758 case DW_OP_over:
7759 printf ("DW_OP_over");
7760 break;
7761 case DW_OP_pick:
7762 printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
7763 break;
7764 case DW_OP_swap:
7765 printf ("DW_OP_swap");
7766 break;
7767 case DW_OP_rot:
7768 printf ("DW_OP_rot");
7769 break;
7770 case DW_OP_xderef:
7771 printf ("DW_OP_xderef");
7772 break;
7773 case DW_OP_abs:
7774 printf ("DW_OP_abs");
7775 break;
7776 case DW_OP_and:
7777 printf ("DW_OP_and");
7778 break;
7779 case DW_OP_div:
7780 printf ("DW_OP_div");
7781 break;
7782 case DW_OP_minus:
7783 printf ("DW_OP_minus");
7784 break;
7785 case DW_OP_mod:
7786 printf ("DW_OP_mod");
7787 break;
7788 case DW_OP_mul:
7789 printf ("DW_OP_mul");
7790 break;
7791 case DW_OP_neg:
7792 printf ("DW_OP_neg");
7793 break;
7794 case DW_OP_not:
7795 printf ("DW_OP_not");
7796 break;
7797 case DW_OP_or:
7798 printf ("DW_OP_or");
7799 break;
7800 case DW_OP_plus:
7801 printf ("DW_OP_plus");
7802 break;
7803 case DW_OP_plus_uconst:
7804 printf ("DW_OP_plus_uconst: %lu",
7805 read_leb128 (data, &bytes_read, 0));
7806 data += bytes_read;
7807 break;
7808 case DW_OP_shl:
7809 printf ("DW_OP_shl");
7810 break;
7811 case DW_OP_shr:
7812 printf ("DW_OP_shr");
7813 break;
7814 case DW_OP_shra:
7815 printf ("DW_OP_shra");
7816 break;
7817 case DW_OP_xor:
7818 printf ("DW_OP_xor");
7819 break;
7820 case DW_OP_bra:
74013231 7821 printf ("DW_OP_bra: %ld", (long) byte_get_signed (data, 2));
eb6bd4d3
JM
7822 data += 2;
7823 break;
7824 case DW_OP_eq:
7825 printf ("DW_OP_eq");
7826 break;
7827 case DW_OP_ge:
7828 printf ("DW_OP_ge");
7829 break;
7830 case DW_OP_gt:
7831 printf ("DW_OP_gt");
7832 break;
7833 case DW_OP_le:
7834 printf ("DW_OP_le");
7835 break;
7836 case DW_OP_lt:
7837 printf ("DW_OP_lt");
7838 break;
7839 case DW_OP_ne:
7840 printf ("DW_OP_ne");
7841 break;
7842 case DW_OP_skip:
74013231 7843 printf ("DW_OP_skip: %ld", (long) byte_get_signed (data, 2));
eb6bd4d3
JM
7844 data += 2;
7845 break;
7846
7847 case DW_OP_lit0:
7848 case DW_OP_lit1:
7849 case DW_OP_lit2:
7850 case DW_OP_lit3:
7851 case DW_OP_lit4:
7852 case DW_OP_lit5:
7853 case DW_OP_lit6:
7854 case DW_OP_lit7:
7855 case DW_OP_lit8:
7856 case DW_OP_lit9:
7857 case DW_OP_lit10:
7858 case DW_OP_lit11:
7859 case DW_OP_lit12:
7860 case DW_OP_lit13:
7861 case DW_OP_lit14:
7862 case DW_OP_lit15:
7863 case DW_OP_lit16:
7864 case DW_OP_lit17:
7865 case DW_OP_lit18:
7866 case DW_OP_lit19:
7867 case DW_OP_lit20:
7868 case DW_OP_lit21:
7869 case DW_OP_lit22:
7870 case DW_OP_lit23:
7871 case DW_OP_lit24:
7872 case DW_OP_lit25:
7873 case DW_OP_lit26:
7874 case DW_OP_lit27:
7875 case DW_OP_lit28:
7876 case DW_OP_lit29:
7877 case DW_OP_lit30:
7878 case DW_OP_lit31:
7879 printf ("DW_OP_lit%d", op - DW_OP_lit0);
7880 break;
7881
7882 case DW_OP_reg0:
7883 case DW_OP_reg1:
7884 case DW_OP_reg2:
7885 case DW_OP_reg3:
7886 case DW_OP_reg4:
7887 case DW_OP_reg5:
7888 case DW_OP_reg6:
7889 case DW_OP_reg7:
7890 case DW_OP_reg8:
7891 case DW_OP_reg9:
7892 case DW_OP_reg10:
7893 case DW_OP_reg11:
7894 case DW_OP_reg12:
7895 case DW_OP_reg13:
7896 case DW_OP_reg14:
7897 case DW_OP_reg15:
7898 case DW_OP_reg16:
7899 case DW_OP_reg17:
7900 case DW_OP_reg18:
7901 case DW_OP_reg19:
7902 case DW_OP_reg20:
7903 case DW_OP_reg21:
7904 case DW_OP_reg22:
7905 case DW_OP_reg23:
7906 case DW_OP_reg24:
7907 case DW_OP_reg25:
7908 case DW_OP_reg26:
7909 case DW_OP_reg27:
7910 case DW_OP_reg28:
7911 case DW_OP_reg29:
7912 case DW_OP_reg30:
7913 case DW_OP_reg31:
7914 printf ("DW_OP_reg%d", op - DW_OP_reg0);
7915 break;
7916
7917 case DW_OP_breg0:
7918 case DW_OP_breg1:
7919 case DW_OP_breg2:
7920 case DW_OP_breg3:
7921 case DW_OP_breg4:
7922 case DW_OP_breg5:
7923 case DW_OP_breg6:
7924 case DW_OP_breg7:
7925 case DW_OP_breg8:
7926 case DW_OP_breg9:
7927 case DW_OP_breg10:
7928 case DW_OP_breg11:
7929 case DW_OP_breg12:
7930 case DW_OP_breg13:
7931 case DW_OP_breg14:
7932 case DW_OP_breg15:
7933 case DW_OP_breg16:
7934 case DW_OP_breg17:
7935 case DW_OP_breg18:
7936 case DW_OP_breg19:
7937 case DW_OP_breg20:
7938 case DW_OP_breg21:
7939 case DW_OP_breg22:
7940 case DW_OP_breg23:
7941 case DW_OP_breg24:
7942 case DW_OP_breg25:
7943 case DW_OP_breg26:
7944 case DW_OP_breg27:
7945 case DW_OP_breg28:
7946 case DW_OP_breg29:
7947 case DW_OP_breg30:
7948 case DW_OP_breg31:
7949 printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
7950 read_leb128 (data, &bytes_read, 1));
7951 data += bytes_read;
7952 break;
7953
7954 case DW_OP_regx:
7955 printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
7956 data += bytes_read;
7957 break;
7958 case DW_OP_fbreg:
7959 printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
7960 data += bytes_read;
7961 break;
7962 case DW_OP_bregx:
7963 uvalue = read_leb128 (data, &bytes_read, 0);
7964 data += bytes_read;
7965 printf ("DW_OP_bregx: %lu %ld", uvalue,
7966 read_leb128 (data, &bytes_read, 1));
7967 data += bytes_read;
7968 break;
7969 case DW_OP_piece:
7970 printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
7971 data += bytes_read;
7972 break;
7973 case DW_OP_deref_size:
7974 printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
7975 break;
7976 case DW_OP_xderef_size:
7977 printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
7978 break;
7979 case DW_OP_nop:
7980 printf ("DW_OP_nop");
7981 break;
7982
065c959b 7983 /* DWARF 3 extensions. */
12ab83a9
NC
7984 case DW_OP_push_object_address:
7985 printf ("DW_OP_push_object_address");
7986 break;
7987 case DW_OP_call2:
7988 printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2));
7989 data += 2;
7990 break;
7991 case DW_OP_call4:
7992 printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4));
7993 data += 4;
7994 break;
065c959b
NC
7995 case DW_OP_call_ref:
7996 printf ("DW_OP_call_ref");
7997 break;
7998
7999 /* GNU extensions. */
8000 case DW_OP_GNU_push_tls_address:
8001 printf ("DW_OP_GNU_push_tls_address");
12ab83a9
NC
8002 break;
8003
eb6bd4d3
JM
8004 default:
8005 if (op >= DW_OP_lo_user
8006 && op <= DW_OP_hi_user)
8007 printf (_("(User defined location op)"));
8008 else
8009 printf (_("(Unknown location op)"));
8010 /* No way to tell where the next op is, so just bail. */
8011 return;
8012 }
12ab83a9
NC
8013
8014 /* Separate the ops. */
3f7de0e7
NC
8015 if (data < end)
8016 printf ("; ");
252b5132
RH
8017 }
8018}
8019
b34976b6
AM
8020static const char *debug_loc_contents;
8021static bfd_vma debug_loc_size;
a2f14207
DB
8022
8023static void
d3ba0551 8024load_debug_loc (FILE *file)
a2f14207 8025{
b34976b6 8026 Elf_Internal_Shdr *sec;
a2f14207
DB
8027
8028 /* If it is already loaded, do nothing. */
8029 if (debug_loc_contents != NULL)
8030 return;
8031
8032 /* Locate the .debug_loc section. */
d9296b18
NC
8033 sec = find_section (".debug_loc");
8034 if (sec == NULL)
a2f14207
DB
8035 return;
8036
8037 debug_loc_size = sec->sh_size;
8038
d3ba0551
AM
8039 debug_loc_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
8040 _("debug_loc section data"));
a2f14207
DB
8041}
8042
8043static void
d3ba0551 8044free_debug_loc (void)
a2f14207
DB
8045{
8046 if (debug_loc_contents == NULL)
8047 return;
8048
8049 free ((char *) debug_loc_contents);
8050 debug_loc_contents = NULL;
8051 debug_loc_size = 0;
8052}
8053
a2f14207 8054
a2f14207 8055static int
d3ba0551 8056display_debug_loc (Elf_Internal_Shdr *section,
d9296b18 8057 unsigned char *start, FILE *file)
a2f14207
DB
8058{
8059 unsigned char *section_end;
8060 unsigned long bytes;
8061 unsigned char *section_begin = start;
8062 bfd_vma addr;
0e0c4098 8063 unsigned int comp_unit = 0;
53c7db4b 8064
a2f14207
DB
8065 addr = section->sh_addr;
8066 bytes = section->sh_size;
8067 section_end = start + bytes;
065c959b 8068
a2f14207
DB
8069 if (bytes == 0)
8070 {
8071 printf (_("\nThe .debug_loc section is empty.\n"));
8072 return 0;
8073 }
065c959b 8074
d9296b18
NC
8075 if (num_debug_line_pointer_sizes == 0)
8076 get_debug_line_pointer_sizes (file);
8077
a2f14207
DB
8078 printf (_("Contents of the .debug_loc section:\n\n"));
8079 printf (_("\n Offset Begin End Expression\n"));
065c959b 8080
a2f14207
DB
8081 while (start < section_end)
8082 {
8083 unsigned long begin;
8084 unsigned long end;
8085 unsigned short length;
8086 unsigned long offset;
0e0c4098 8087 unsigned int pointer_size;
a2f14207
DB
8088
8089 offset = start - section_begin;
8090
0e0c4098
NC
8091 /* Get the pointer size from the comp unit associated
8092 with this block of location information. */
8093 if (comp_unit >= num_debug_line_pointer_sizes)
8094 {
8095 error (_("Not enough comp units for .debug_loc section\n"));
8096 return 0;
8097 }
8098 else
8099 {
8100 pointer_size = debug_line_pointer_sizes [comp_unit];
8101 comp_unit ++;
8102 }
8103
a2f14207
DB
8104 while (1)
8105 {
0e0c4098
NC
8106 begin = byte_get (start, pointer_size);
8107 start += pointer_size;
8108 end = byte_get (start, pointer_size);
8109 start += pointer_size;
53c7db4b 8110
a2f14207
DB
8111 if (begin == 0 && end == 0)
8112 break;
53c7db4b 8113
8dde85fc
NC
8114 /* For now, skip any base address specifiers. */
8115 if (begin == 0xffffffff)
8116 continue;
8117
a2f14207
DB
8118 begin += addr;
8119 end += addr;
53c7db4b 8120
a2f14207
DB
8121 length = byte_get (start, 2);
8122 start += 2;
53c7db4b 8123
a2f14207 8124 printf (" %8.8lx %8.8lx %8.8lx (", offset, begin, end);
0e0c4098 8125 decode_location_expression (start, pointer_size, length);
a2f14207 8126 printf (")\n");
53c7db4b 8127
a2f14207
DB
8128 start += length;
8129 }
8130 printf ("\n");
8131 }
8132 return 1;
8133}
252b5132 8134
b34976b6
AM
8135static const char *debug_str_contents;
8136static bfd_vma debug_str_size;
261a45ad
NC
8137
8138static void
d3ba0551 8139load_debug_str (FILE *file)
261a45ad 8140{
b34976b6 8141 Elf_Internal_Shdr *sec;
261a45ad
NC
8142
8143 /* If it is already loaded, do nothing. */
8144 if (debug_str_contents != NULL)
8145 return;
8146
8147 /* Locate the .debug_str section. */
d9296b18
NC
8148 sec = find_section (".debug_str");
8149 if (sec == NULL)
261a45ad
NC
8150 return;
8151
8152 debug_str_size = sec->sh_size;
8153
d3ba0551
AM
8154 debug_str_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
8155 _("debug_str section data"));
261a45ad
NC
8156}
8157
8158static void
d3ba0551 8159free_debug_str (void)
261a45ad
NC
8160{
8161 if (debug_str_contents == NULL)
8162 return;
8163
8164 free ((char *) debug_str_contents);
8165 debug_str_contents = NULL;
8166 debug_str_size = 0;
8167}
8168
8169static const char *
d3ba0551 8170fetch_indirect_string (unsigned long offset)
261a45ad
NC
8171{
8172 if (debug_str_contents == NULL)
8173 return _("<no .debug_str section>");
8174
8175 if (offset > debug_str_size)
8176 return _("<offset is too big>");
8177
8178 return debug_str_contents + offset;
8179}
8180
261a45ad 8181static int
d3ba0551
AM
8182display_debug_str (Elf_Internal_Shdr *section,
8183 unsigned char *start,
8184 FILE *file ATTRIBUTE_UNUSED)
261a45ad 8185{
b34976b6
AM
8186 unsigned long bytes;
8187 bfd_vma addr;
261a45ad
NC
8188
8189 addr = section->sh_addr;
8190 bytes = section->sh_size;
8191
8192 if (bytes == 0)
8193 {
8194 printf (_("\nThe .debug_str section is empty.\n"));
8195 return 0;
8196 }
8197
8198 printf (_("Contents of the .debug_str section:\n\n"));
8199
8200 while (bytes)
8201 {
8202 int j;
8203 int k;
8204 int lbytes;
8205
8206 lbytes = (bytes > 16 ? 16 : bytes);
8207
8208 printf (" 0x%8.8lx ", (unsigned long) addr);
8209
8210 for (j = 0; j < 16; j++)
8211 {
8212 if (j < lbytes)
b34976b6 8213 printf ("%2.2x", start[j]);
261a45ad
NC
8214 else
8215 printf (" ");
8216
8217 if ((j & 3) == 3)
8218 printf (" ");
8219 }
8220
8221 for (j = 0; j < lbytes; j++)
8222 {
b34976b6 8223 k = start[j];
261a45ad
NC
8224 if (k >= ' ' && k < 0x80)
8225 printf ("%c", k);
8226 else
8227 printf (".");
8228 }
8229
8230 putchar ('\n');
8231
8232 start += lbytes;
8233 addr += lbytes;
8234 bytes -= lbytes;
8235 }
8236
8237 return 1;
8238}
8239
252b5132 8240static unsigned char *
d3ba0551
AM
8241read_and_display_attr_value (unsigned long attribute,
8242 unsigned long form,
8243 unsigned char *data,
8244 unsigned long cu_offset,
8245 unsigned long pointer_size,
8246 unsigned long offset_size,
8247 int dwarf_version)
252b5132 8248{
b34976b6
AM
8249 unsigned long uvalue = 0;
8250 unsigned char *block_start = NULL;
8251 int bytes_read;
252b5132 8252
252b5132
RH
8253 switch (form)
8254 {
60bcf0fa
NC
8255 default:
8256 break;
76da6bbe 8257
252b5132 8258 case DW_FORM_ref_addr:
ee42cf8c
NC
8259 if (dwarf_version == 2)
8260 {
8261 uvalue = byte_get (data, pointer_size);
8262 data += pointer_size;
8263 }
8264 else if (dwarf_version == 3)
8265 {
8266 uvalue = byte_get (data, offset_size);
8267 data += offset_size;
8268 }
8269 else
ba2685cc 8270 {
ee42cf8c
NC
8271 error (_("Internal error: DWARF version is not 2 or 3.\n"));
8272 }
8273 break;
8274
252b5132
RH
8275 case DW_FORM_addr:
8276 uvalue = byte_get (data, pointer_size);
252b5132
RH
8277 data += pointer_size;
8278 break;
8279
ef5cdfc7 8280 case DW_FORM_strp:
ee42cf8c
NC
8281 uvalue = byte_get (data, offset_size);
8282 data += offset_size;
ef5cdfc7
JJ
8283 break;
8284
252b5132
RH
8285 case DW_FORM_ref1:
8286 case DW_FORM_flag:
8287 case DW_FORM_data1:
b34976b6 8288 uvalue = byte_get (data++, 1);
252b5132
RH
8289 break;
8290
8291 case DW_FORM_ref2:
8292 case DW_FORM_data2:
8293 uvalue = byte_get (data, 2);
8294 data += 2;
252b5132
RH
8295 break;
8296
8297 case DW_FORM_ref4:
8298 case DW_FORM_data4:
8299 uvalue = byte_get (data, 4);
8300 data += 4;
1fa37306
JM
8301 break;
8302
8303 case DW_FORM_sdata:
8304 uvalue = read_leb128 (data, & bytes_read, 1);
8305 data += bytes_read;
8306 break;
8307
8308 case DW_FORM_ref_udata:
8309 case DW_FORM_udata:
8310 uvalue = read_leb128 (data, & bytes_read, 0);
8311 data += bytes_read;
8312 break;
81766fca
RH
8313
8314 case DW_FORM_indirect:
8315 form = read_leb128 (data, & bytes_read, 0);
8316 data += bytes_read;
8317 printf (" %s", get_FORM_name (form));
8318 return read_and_display_attr_value (attribute, form, data, cu_offset,
ee42cf8c
NC
8319 pointer_size, offset_size,
8320 dwarf_version);
1fa37306
JM
8321 }
8322
8323 switch (form)
8324 {
8325 case DW_FORM_ref_addr:
8326 printf (" <#%lx>", uvalue);
8327 break;
76da6bbe 8328
1fa37306
JM
8329 case DW_FORM_ref1:
8330 case DW_FORM_ref2:
8331 case DW_FORM_ref4:
8332 case DW_FORM_ref_udata:
8333 printf (" <%lx>", uvalue + cu_offset);
8334 break;
8335
8336 case DW_FORM_addr:
8337 printf (" %#lx", uvalue);
935a41f5 8338 break;
1fa37306
JM
8339
8340 case DW_FORM_flag:
8341 case DW_FORM_data1:
8342 case DW_FORM_data2:
8343 case DW_FORM_data4:
8344 case DW_FORM_sdata:
8345 case DW_FORM_udata:
8346 printf (" %ld", uvalue);
252b5132
RH
8347 break;
8348
8349 case DW_FORM_ref8:
8350 case DW_FORM_data8:
8351 uvalue = byte_get (data, 4);
8352 printf (" %lx", uvalue);
148d3c43 8353 printf (" %lx", (unsigned long) byte_get (data + 4, 4));
252b5132
RH
8354 data += 8;
8355 break;
8356
8357 case DW_FORM_string:
8358 printf (" %s", data);
3c9f43b1 8359 data += strlen ((char *) data) + 1;
252b5132
RH
8360 break;
8361
252b5132
RH
8362 case DW_FORM_block:
8363 uvalue = read_leb128 (data, & bytes_read, 0);
8364 block_start = data + bytes_read;
8365 data = display_block (block_start, uvalue);
252b5132
RH
8366 break;
8367
8368 case DW_FORM_block1:
8369 uvalue = byte_get (data, 1);
8370 block_start = data + 1;
8371 data = display_block (block_start, uvalue);
252b5132
RH
8372 break;
8373
8374 case DW_FORM_block2:
8375 uvalue = byte_get (data, 2);
8376 block_start = data + 2;
8377 data = display_block (block_start, uvalue);
252b5132
RH
8378 break;
8379
8380 case DW_FORM_block4:
8381 uvalue = byte_get (data, 4);
8382 block_start = data + 4;
8383 data = display_block (block_start, uvalue);
252b5132
RH
8384 break;
8385
8386 case DW_FORM_strp:
f1ef08cb
AM
8387 printf (_(" (indirect string, offset: 0x%lx): %s"),
8388 uvalue, fetch_indirect_string (uvalue));
ef5cdfc7
JJ
8389 break;
8390
252b5132 8391 case DW_FORM_indirect:
e3c8793a 8392 /* Handled above. */
252b5132
RH
8393 break;
8394
8395 default:
2c71103e 8396 warn (_("Unrecognized form: %d\n"), form);
252b5132
RH
8397 break;
8398 }
8399
50c2245b 8400 /* For some attributes we can display further information. */
252b5132
RH
8401
8402 printf ("\t");
8403
8404 switch (attribute)
8405 {
8406 case DW_AT_inline:
8407 switch (uvalue)
8408 {
b34976b6
AM
8409 case DW_INL_not_inlined:
8410 printf (_("(not inlined)"));
8411 break;
8412 case DW_INL_inlined:
8413 printf (_("(inlined)"));
8414 break;
8415 case DW_INL_declared_not_inlined:
8416 printf (_("(declared as inline but ignored)"));
8417 break;
8418 case DW_INL_declared_inlined:
8419 printf (_("(declared as inline and inlined)"));
8420 break;
8421 default:
8422 printf (_(" (Unknown inline attribute value: %lx)"), uvalue);
8423 break;
252b5132
RH
8424 }
8425 break;
8426
252b5132
RH
8427 case DW_AT_language:
8428 switch (uvalue)
8429 {
b34976b6
AM
8430 case DW_LANG_C: printf ("(non-ANSI C)"); break;
8431 case DW_LANG_C89: printf ("(ANSI C)"); break;
8432 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
8433 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
8434 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
8435 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
8436 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
8437 case DW_LANG_Ada83: printf ("(Ada)"); break;
8438 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
8439 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
8440 /* DWARF 2.1 values. */
8441 case DW_LANG_C99: printf ("(ANSI C99)"); break;
8442 case DW_LANG_Ada95: printf ("(ADA 95)"); break;
8443 case DW_LANG_Fortran95: printf ("(Fortran 95)"); break;
b811889f 8444 /* MIPS extension. */
b34976b6 8445 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
84ad6ede
NC
8446 /* UPC extension. */
8447 case DW_LANG_Upc: printf ("(Unified Parallel C)"); break;
b34976b6
AM
8448 default:
8449 printf ("(Unknown: %lx)", uvalue);
8450 break;
252b5132
RH
8451 }
8452 break;
8453
8454 case DW_AT_encoding:
8455 switch (uvalue)
8456 {
b34976b6
AM
8457 case DW_ATE_void: printf ("(void)"); break;
8458 case DW_ATE_address: printf ("(machine address)"); break;
8459 case DW_ATE_boolean: printf ("(boolean)"); break;
8460 case DW_ATE_complex_float: printf ("(complex float)"); break;
8461 case DW_ATE_float: printf ("(float)"); break;
8462 case DW_ATE_signed: printf ("(signed)"); break;
8463 case DW_ATE_signed_char: printf ("(signed char)"); break;
8464 case DW_ATE_unsigned: printf ("(unsigned)"); break;
8465 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
b811889f 8466 /* DWARF 2.1 value. */
b34976b6 8467 case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
252b5132
RH
8468 default:
8469 if (uvalue >= DW_ATE_lo_user
8470 && uvalue <= DW_ATE_hi_user)
8471 printf ("(user defined type)");
8472 else
8473 printf ("(unknown type)");
8474 break;
8475 }
8476 break;
8477
8478 case DW_AT_accessibility:
8479 switch (uvalue)
8480 {
8481 case DW_ACCESS_public: printf ("(public)"); break;
8482 case DW_ACCESS_protected: printf ("(protected)"); break;
8483 case DW_ACCESS_private: printf ("(private)"); break;
b34976b6
AM
8484 default:
8485 printf ("(unknown accessibility)");
8486 break;
252b5132
RH
8487 }
8488 break;
8489
8490 case DW_AT_visibility:
8491 switch (uvalue)
8492 {
b34976b6
AM
8493 case DW_VIS_local: printf ("(local)"); break;
8494 case DW_VIS_exported: printf ("(exported)"); break;
8495 case DW_VIS_qualified: printf ("(qualified)"); break;
8496 default: printf ("(unknown visibility)"); break;
252b5132
RH
8497 }
8498 break;
8499
8500 case DW_AT_virtuality:
8501 switch (uvalue)
8502 {
8503 case DW_VIRTUALITY_none: printf ("(none)"); break;
8504 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
8505 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
b34976b6 8506 default: printf ("(unknown virtuality)"); break;
252b5132
RH
8507 }
8508 break;
8509
8510 case DW_AT_identifier_case:
8511 switch (uvalue)
8512 {
8513 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
8514 case DW_ID_up_case: printf ("(up_case)"); break;
8515 case DW_ID_down_case: printf ("(down_case)"); break;
8516 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
b34976b6 8517 default: printf ("(unknown case)"); break;
252b5132
RH
8518 }
8519 break;
8520
8521 case DW_AT_calling_convention:
8522 switch (uvalue)
8523 {
8524 case DW_CC_normal: printf ("(normal)"); break;
8525 case DW_CC_program: printf ("(program)"); break;
8526 case DW_CC_nocall: printf ("(nocall)"); break;
8527 default:
8528 if (uvalue >= DW_CC_lo_user
8529 && uvalue <= DW_CC_hi_user)
8530 printf ("(user defined)");
8531 else
8532 printf ("(unknown convention)");
8533 }
8534 break;
8535
12ab83a9
NC
8536 case DW_AT_ordering:
8537 switch (uvalue)
8538 {
8539 case -1: printf ("(undefined)"); break;
8540 case 0: printf ("(row major)"); break;
8541 case 1: printf ("(column major)"); break;
8542 }
8543 break;
8544
eb6bd4d3 8545 case DW_AT_frame_base:
252b5132
RH
8546 case DW_AT_location:
8547 case DW_AT_data_member_location:
8548 case DW_AT_vtable_elem_location:
12ab83a9
NC
8549 case DW_AT_allocated:
8550 case DW_AT_associated:
8551 case DW_AT_data_location:
8552 case DW_AT_stride:
8553 case DW_AT_upper_bound:
8554 case DW_AT_lower_bound:
eb6bd4d3
JM
8555 if (block_start)
8556 {
8557 printf ("(");
8558 decode_location_expression (block_start, pointer_size, uvalue);
8559 printf (")");
8560 }
ee42cf8c 8561 else if (form == DW_FORM_data4 || form == DW_FORM_data8)
a2f14207
DB
8562 {
8563 printf ("(");
8564 printf ("location list");
8565 printf (")");
8566 }
252b5132
RH
8567 break;
8568
8569 default:
8570 break;
8571 }
8572
81766fca
RH
8573 return data;
8574}
8575
8576static unsigned char *
d3ba0551
AM
8577read_and_display_attr (unsigned long attribute,
8578 unsigned long form,
8579 unsigned char *data,
8580 unsigned long cu_offset,
8581 unsigned long pointer_size,
8582 unsigned long offset_size,
8583 int dwarf_version)
81766fca
RH
8584{
8585 printf (" %-18s:", get_AT_name (attribute));
8586 data = read_and_display_attr_value (attribute, form, data, cu_offset,
ee42cf8c 8587 pointer_size, offset_size, dwarf_version);
252b5132
RH
8588 printf ("\n");
8589 return data;
8590}
8591
d84de024
AM
8592/* Apply addends of RELA relocations. */
8593
8594static int
8595debug_apply_rela_addends (FILE *file,
8596 Elf_Internal_Shdr *section,
8597 int reloc_size,
8598 unsigned char *sec_data,
8599 unsigned char *start,
8600 unsigned char *end)
8601{
8602 Elf_Internal_Shdr *relsec;
8603
8604 if (end - start < reloc_size)
8605 return 1;
8606
8607 for (relsec = section_headers;
8608 relsec < section_headers + elf_header.e_shnum;
8609 ++relsec)
8610 {
8611 unsigned long nrelas;
8612 Elf_Internal_Rela *rela, *rp;
8613 Elf_Internal_Shdr *symsec;
8614 Elf_Internal_Sym *symtab;
8615 Elf_Internal_Sym *sym;
8616
8617 if (relsec->sh_type != SHT_RELA
8618 || SECTION_HEADER (relsec->sh_info) != section
8619 || relsec->sh_size == 0)
8620 continue;
8621
8622 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
8623 &rela, &nrelas))
8624 return 0;
8625
8626 symsec = SECTION_HEADER (relsec->sh_link);
8627 symtab = GET_ELF_SYMBOLS (file, symsec);
8628
8629 for (rp = rela; rp < rela + nrelas; ++rp)
8630 {
8631 unsigned char *loc;
8632
8633 if (rp->r_offset >= (bfd_vma) (start - sec_data)
8634 && rp->r_offset < (bfd_vma) (end - sec_data) - reloc_size)
8635 loc = sec_data + rp->r_offset;
8636 else
8637 continue;
8638
8639 if (is_32bit_elf)
8640 {
8641 sym = symtab + ELF32_R_SYM (rp->r_info);
8642
8643 if (ELF32_R_SYM (rp->r_info) != 0
8644 && ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
8645 {
8646 warn (_("Skipping unexpected symbol type %u\n"),
8647 ELF32_ST_TYPE (sym->st_info));
8648 continue;
8649 }
8650 }
8651 else
8652 {
8653 sym = symtab + ELF64_R_SYM (rp->r_info);
8654
8655 if (ELF64_R_SYM (rp->r_info) != 0
8656 && ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
8657 {
8658 warn (_("Skipping unexpected symbol type %u\n"),
8659 ELF64_ST_TYPE (sym->st_info));
8660 continue;
8661 }
8662 }
8663
8664 byte_put (loc, rp->r_addend, reloc_size);
8665 }
8666
8667 free (symtab);
8668 free (rela);
8669 break;
8670 }
8671 return 1;
8672}
8673
252b5132 8674static int
d3ba0551
AM
8675display_debug_info (Elf_Internal_Shdr *section,
8676 unsigned char *start,
8677 FILE *file)
252b5132 8678{
b34976b6
AM
8679 unsigned char *end = start + section->sh_size;
8680 unsigned char *section_begin = start;
252b5132
RH
8681
8682 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
8683
261a45ad 8684 load_debug_str (file);
a2f14207 8685 load_debug_loc (file);
ef5cdfc7 8686
252b5132
RH
8687 while (start < end)
8688 {
b34976b6 8689 DWARF2_Internal_CompUnit compunit;
ee42cf8c
NC
8690 unsigned char *hdrptr;
8691 unsigned char *cu_abbrev_offset_ptr;
b34976b6 8692 unsigned char *tags;
b34976b6
AM
8693 int level;
8694 unsigned long cu_offset;
ee42cf8c
NC
8695 int offset_size;
8696 int initial_length_size;
252b5132 8697
ee42cf8c 8698 hdrptr = start;
252b5132 8699
ee42cf8c
NC
8700 compunit.cu_length = byte_get (hdrptr, 4);
8701 hdrptr += 4;
252b5132 8702
428409d5
NC
8703 if (compunit.cu_length == 0xffffffff)
8704 {
ee42cf8c
NC
8705 compunit.cu_length = byte_get (hdrptr, 8);
8706 hdrptr += 8;
8707 offset_size = 8;
8708 initial_length_size = 12;
8709 }
8710 else
8711 {
8712 offset_size = 4;
8713 initial_length_size = 4;
428409d5
NC
8714 }
8715
ee42cf8c
NC
8716 compunit.cu_version = byte_get (hdrptr, 2);
8717 hdrptr += 2;
8718
d84de024
AM
8719 cu_offset = start - section_begin;
8720 start += compunit.cu_length + initial_length_size;
c0e047e0 8721
d84de024
AM
8722 if (elf_header.e_type == ET_REL
8723 && !debug_apply_rela_addends (file, section, offset_size,
8724 section_begin, hdrptr, start))
8725 return 0;
c0e047e0 8726
adab8cdc
AO
8727 cu_abbrev_offset_ptr = hdrptr;
8728 compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size);
8729 hdrptr += offset_size;
8730
8731 compunit.cu_pointer_size = byte_get (hdrptr, 1);
8732 hdrptr += 1;
8733
ee42cf8c 8734 tags = hdrptr;
252b5132 8735
09fd7e38
JM
8736 printf (_(" Compilation Unit @ %lx:\n"), cu_offset);
8737 printf (_(" Length: %ld\n"), compunit.cu_length);
8738 printf (_(" Version: %d\n"), compunit.cu_version);
8739 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
8740 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
8741
ee42cf8c 8742 if (compunit.cu_version != 2 && compunit.cu_version != 3)
252b5132 8743 {
ee42cf8c 8744 warn (_("Only version 2 and 3 DWARF debug information is currently supported.\n"));
252b5132
RH
8745 continue;
8746 }
8747
261a45ad 8748 free_abbrevs ();
252b5132
RH
8749
8750 /* Read in the abbrevs used by this compilation unit. */
252b5132 8751 {
b34976b6
AM
8752 Elf_Internal_Shdr *sec;
8753 unsigned char *begin;
252b5132
RH
8754
8755 /* Locate the .debug_abbrev section and process it. */
d9296b18
NC
8756 sec = find_section (".debug_abbrev");
8757 if (sec == NULL)
252b5132
RH
8758 {
8759 warn (_("Unable to locate .debug_abbrev section!\n"));
8760 return 0;
8761 }
8762
d3ba0551
AM
8763 begin = get_data (NULL, file, sec->sh_offset, sec->sh_size,
8764 _("debug_abbrev section data"));
a6e9f9df
AM
8765 if (!begin)
8766 return 0;
252b5132
RH
8767
8768 process_abbrev_section (begin + compunit.cu_abbrev_offset,
8769 begin + sec->sh_size);
8770
8771 free (begin);
8772 }
8773
8774 level = 0;
8775 while (tags < start)
8776 {
b34976b6
AM
8777 int bytes_read;
8778 unsigned long abbrev_number;
8779 abbrev_entry *entry;
8780 abbrev_attr *attr;
252b5132
RH
8781
8782 abbrev_number = read_leb128 (tags, & bytes_read, 0);
8783 tags += bytes_read;
8784
8785 /* A null DIE marks the end of a list of children. */
8786 if (abbrev_number == 0)
8787 {
8788 --level;
8789 continue;
8790 }
8791
8792 /* Scan through the abbreviation list until we reach the
8793 correct entry. */
8794 for (entry = first_abbrev;
8795 entry && entry->entry != abbrev_number;
8796 entry = entry->next)
8797 continue;
8798
8799 if (entry == NULL)
8800 {
b4c96d0d 8801 warn (_("Unable to locate entry %lu in the abbreviation table\n"),
252b5132
RH
8802 abbrev_number);
8803 return 0;
8804 }
8805
410f7a12
L
8806 printf (_(" <%d><%lx>: Abbrev Number: %lu (%s)\n"),
8807 level,
8808 (unsigned long) (tags - section_begin - bytes_read),
252b5132
RH
8809 abbrev_number,
8810 get_TAG_name (entry->tag));
8811
8812 for (attr = entry->first_attr; attr; attr = attr->next)
8813 tags = read_and_display_attr (attr->attribute,
8814 attr->form,
1fa37306 8815 tags, cu_offset,
ee42cf8c
NC
8816 compunit.cu_pointer_size,
8817 offset_size,
8818 compunit.cu_version);
252b5132
RH
8819
8820 if (entry->children)
8821 ++level;
8822 }
8823 }
8824
261a45ad 8825 free_debug_str ();
a2f14207 8826 free_debug_loc ();
ef5cdfc7 8827
252b5132
RH
8828 printf ("\n");
8829
8830 return 1;
8831}
8832
8833static int
d3ba0551
AM
8834display_debug_aranges (Elf_Internal_Shdr *section,
8835 unsigned char *start,
8836 FILE *file ATTRIBUTE_UNUSED)
252b5132 8837{
b34976b6 8838 unsigned char *end = start + section->sh_size;
252b5132
RH
8839
8840 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
8841
8842 while (start < end)
8843 {
ee42cf8c 8844 unsigned char *hdrptr;
b34976b6
AM
8845 DWARF2_Internal_ARange arange;
8846 unsigned char *ranges;
8847 unsigned long length;
8848 unsigned long address;
8849 int excess;
ee42cf8c
NC
8850 int offset_size;
8851 int initial_length_size;
252b5132 8852
ee42cf8c 8853 hdrptr = start;
252b5132 8854
ee42cf8c
NC
8855 arange.ar_length = byte_get (hdrptr, 4);
8856 hdrptr += 4;
252b5132 8857
e414a165
NC
8858 if (arange.ar_length == 0xffffffff)
8859 {
ee42cf8c
NC
8860 arange.ar_length = byte_get (hdrptr, 8);
8861 hdrptr += 8;
8862 offset_size = 8;
8863 initial_length_size = 12;
8864 }
8865 else
ba2685cc 8866 {
ee42cf8c
NC
8867 offset_size = 4;
8868 initial_length_size = 4;
e414a165
NC
8869 }
8870
ee42cf8c
NC
8871 arange.ar_version = byte_get (hdrptr, 2);
8872 hdrptr += 2;
8873
8874 arange.ar_info_offset = byte_get (hdrptr, offset_size);
8875 hdrptr += offset_size;
8876
8877 arange.ar_pointer_size = byte_get (hdrptr, 1);
8878 hdrptr += 1;
8879
8880 arange.ar_segment_size = byte_get (hdrptr, 1);
8881 hdrptr += 1;
8882
8883 if (arange.ar_version != 2 && arange.ar_version != 3)
3f215a10 8884 {
ee42cf8c 8885 warn (_("Only DWARF 2 and 3 aranges are currently supported.\n"));
3f215a10
NC
8886 break;
8887 }
8888
252b5132
RH
8889 printf (_(" Length: %ld\n"), arange.ar_length);
8890 printf (_(" Version: %d\n"), arange.ar_version);
8891 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
8892 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
8893 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
8894
8895 printf (_("\n Address Length\n"));
8896
ee42cf8c 8897 ranges = hdrptr;
252b5132 8898
7a4b7442 8899 /* Must pad to an alignment boundary that is twice the pointer size. */
ee42cf8c 8900 excess = (hdrptr - start) % (2 * arange.ar_pointer_size);
7a4b7442
NC
8901 if (excess)
8902 ranges += (2 * arange.ar_pointer_size) - excess;
8903
252b5132
RH
8904 for (;;)
8905 {
8906 address = byte_get (ranges, arange.ar_pointer_size);
8907
252b5132
RH
8908 ranges += arange.ar_pointer_size;
8909
8910 length = byte_get (ranges, arange.ar_pointer_size);
8911
8912 ranges += arange.ar_pointer_size;
8913
7a4b7442
NC
8914 /* A pair of zeros marks the end of the list. */
8915 if (address == 0 && length == 0)
8916 break;
103f02d3 8917
252b5132
RH
8918 printf (" %8.8lx %lu\n", address, length);
8919 }
8920
ee42cf8c 8921 start += arange.ar_length + initial_length_size;
252b5132
RH
8922 }
8923
8924 printf ("\n");
8925
8926 return 1;
8927}
8928
c47d488e
DD
8929typedef struct Frame_Chunk
8930{
b34976b6
AM
8931 struct Frame_Chunk *next;
8932 unsigned char *chunk_start;
8933 int ncols;
a98cc2b2 8934 /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */
b34976b6
AM
8935 short int *col_type;
8936 int *col_offset;
8937 char *augmentation;
8938 unsigned int code_factor;
8939 int data_factor;
8940 unsigned long pc_begin;
8941 unsigned long pc_range;
8942 int cfa_reg;
8943 int cfa_offset;
8944 int ra;
8945 unsigned char fde_encoding;
63044634 8946 unsigned char cfa_exp;
c47d488e
DD
8947}
8948Frame_Chunk;
8949
a98cc2b2
AH
8950/* A marker for a col_type that means this column was never referenced
8951 in the frame info. */
8952#define DW_CFA_unreferenced (-1)
8953
c47d488e 8954static void
d3ba0551 8955frame_need_space (Frame_Chunk *fc, int reg)
c47d488e
DD
8956{
8957 int prev = fc->ncols;
8958
8959 if (reg < fc->ncols)
8960 return;
584da044 8961
c47d488e 8962 fc->ncols = reg + 1;
d3ba0551
AM
8963 fc->col_type = xrealloc (fc->col_type, fc->ncols * sizeof (short int));
8964 fc->col_offset = xrealloc (fc->col_offset, fc->ncols * sizeof (int));
c47d488e
DD
8965
8966 while (prev < fc->ncols)
8967 {
a98cc2b2 8968 fc->col_type[prev] = DW_CFA_unreferenced;
c47d488e
DD
8969 fc->col_offset[prev] = 0;
8970 prev++;
8971 }
8972}
8973
8974static void
d3ba0551 8975frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
c47d488e
DD
8976{
8977 int r;
8978 char tmp[100];
8979
b34976b6
AM
8980 if (*max_regs < fc->ncols)
8981 *max_regs = fc->ncols;
584da044 8982
b34976b6 8983 if (*need_col_headers)
c47d488e 8984 {
b34976b6 8985 *need_col_headers = 0;
584da044 8986
c47d488e 8987 printf (" LOC CFA ");
584da044 8988
b34976b6 8989 for (r = 0; r < *max_regs; r++)
a98cc2b2
AH
8990 if (fc->col_type[r] != DW_CFA_unreferenced)
8991 {
8992 if (r == fc->ra)
8993 printf ("ra ");
8994 else
8995 printf ("r%-4d", r);
8996 }
584da044 8997
c47d488e
DD
8998 printf ("\n");
8999 }
584da044 9000
31b6fca6 9001 printf ("%08lx ", fc->pc_begin);
63044634
RH
9002 if (fc->cfa_exp)
9003 strcpy (tmp, "exp");
9004 else
9005 sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
c47d488e 9006 printf ("%-8s ", tmp);
584da044
NC
9007
9008 for (r = 0; r < fc->ncols; r++)
c47d488e 9009 {
a98cc2b2 9010 if (fc->col_type[r] != DW_CFA_unreferenced)
c47d488e 9011 {
a98cc2b2
AH
9012 switch (fc->col_type[r])
9013 {
9014 case DW_CFA_undefined:
9015 strcpy (tmp, "u");
9016 break;
9017 case DW_CFA_same_value:
9018 strcpy (tmp, "s");
9019 break;
9020 case DW_CFA_offset:
9021 sprintf (tmp, "c%+d", fc->col_offset[r]);
9022 break;
9023 case DW_CFA_register:
9024 sprintf (tmp, "r%d", fc->col_offset[r]);
9025 break;
63044634
RH
9026 case DW_CFA_expression:
9027 strcpy (tmp, "exp");
9028 break;
a98cc2b2
AH
9029 default:
9030 strcpy (tmp, "n/a");
9031 break;
9032 }
9033 printf ("%-5s", tmp);
c47d488e 9034 }
c47d488e
DD
9035 }
9036 printf ("\n");
9037}
9038
31b6fca6 9039static int
d3ba0551 9040size_of_encoded_value (int encoding)
31b6fca6
RH
9041{
9042 switch (encoding & 0x7)
9043 {
9044 default: /* ??? */
9045 case 0: return is_32bit_elf ? 4 : 8;
9046 case 2: return 2;
9047 case 3: return 4;
9048 case 4: return 8;
9049 }
9050}
9051
38fafa6d 9052static bfd_vma
d3ba0551 9053get_encoded_value (unsigned char *data, int encoding)
38fafa6d
RH
9054{
9055 int size = size_of_encoded_value (encoding);
9056 if (encoding & DW_EH_PE_signed)
9057 return byte_get_signed (data, size);
9058 else
9059 return byte_get (data, size);
9060}
9061
c47d488e 9062#define GET(N) byte_get (start, N); start += N
584da044
NC
9063#define LEB() read_leb128 (start, & length_return, 0); start += length_return
9064#define SLEB() read_leb128 (start, & length_return, 1); start += length_return
c47d488e
DD
9065
9066static int
d3ba0551
AM
9067display_debug_frames (Elf_Internal_Shdr *section,
9068 unsigned char *start,
9069 FILE *file ATTRIBUTE_UNUSED)
c47d488e 9070{
b34976b6
AM
9071 unsigned char *end = start + section->sh_size;
9072 unsigned char *section_start = start;
9073 Frame_Chunk *chunks = 0;
9074 Frame_Chunk *remembered_state = 0;
9075 Frame_Chunk *rs;
9076 int is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
9077 int length_return;
9078 int max_regs = 0;
9079 int addr_size = is_32bit_elf ? 4 : 8;
c47d488e
DD
9080
9081 printf (_("The section %s contains:\n"), SECTION_NAME (section));
9082
9083 while (start < end)
9084 {
b34976b6
AM
9085 unsigned char *saved_start;
9086 unsigned char *block_end;
9087 unsigned long length;
9088 unsigned long cie_id;
9089 Frame_Chunk *fc;
9090 Frame_Chunk *cie;
9091 int need_col_headers = 1;
9092 unsigned char *augmentation_data = NULL;
9093 unsigned long augmentation_data_len = 0;
9094 int encoded_ptr_size = addr_size;
ee42cf8c
NC
9095 int offset_size;
9096 int initial_length_size;
c47d488e
DD
9097
9098 saved_start = start;
9099 length = byte_get (start, 4); start += 4;
9100
9101 if (length == 0)
f1ef08cb
AM
9102 {
9103 printf ("\n%08lx ZERO terminator\n\n",
9104 (unsigned long)(saved_start - section_start));
9105 return 1;
9106 }
c47d488e 9107
428409d5
NC
9108 if (length == 0xffffffff)
9109 {
ee42cf8c
NC
9110 length = byte_get (start, 8);
9111 start += 8;
9112 offset_size = 8;
9113 initial_length_size = 12;
9114 }
9115 else
9116 {
9117 offset_size = 4;
9118 initial_length_size = 4;
428409d5
NC
9119 }
9120
ee42cf8c
NC
9121 block_end = saved_start + length + initial_length_size;
9122 cie_id = byte_get (start, offset_size); start += offset_size;
c47d488e 9123
d84de024
AM
9124 if (elf_header.e_type == ET_REL
9125 && !debug_apply_rela_addends (file, section, offset_size,
9126 section_start, start, block_end))
9127 return 0;
9128
c47d488e
DD
9129 if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
9130 {
31b6fca6
RH
9131 int version;
9132
d3ba0551 9133 fc = xmalloc (sizeof (Frame_Chunk));
c47d488e
DD
9134 memset (fc, 0, sizeof (Frame_Chunk));
9135
9136 fc->next = chunks;
9137 chunks = fc;
9138 fc->chunk_start = saved_start;
9139 fc->ncols = 0;
d3ba0551
AM
9140 fc->col_type = xmalloc (sizeof (short int));
9141 fc->col_offset = xmalloc (sizeof (int));
c47d488e
DD
9142 frame_need_space (fc, max_regs-1);
9143
31b6fca6 9144 version = *start++;
584da044 9145
31b6fca6
RH
9146 fc->augmentation = start;
9147 start = strchr (start, '\0') + 1;
584da044 9148
c47d488e
DD
9149 if (fc->augmentation[0] == 'z')
9150 {
c47d488e
DD
9151 fc->code_factor = LEB ();
9152 fc->data_factor = SLEB ();
0da76f83
NC
9153 if (version == 1)
9154 {
9155 fc->ra = GET (1);
9156 }
9157 else
9158 {
9159 fc->ra = LEB ();
9160 }
31b6fca6
RH
9161 augmentation_data_len = LEB ();
9162 augmentation_data = start;
9163 start += augmentation_data_len;
c47d488e
DD
9164 }
9165 else if (strcmp (fc->augmentation, "eh") == 0)
9166 {
31b6fca6 9167 start += addr_size;
c47d488e
DD
9168 fc->code_factor = LEB ();
9169 fc->data_factor = SLEB ();
0da76f83
NC
9170 if (version == 1)
9171 {
9172 fc->ra = GET (1);
9173 }
9174 else
9175 {
9176 fc->ra = LEB ();
9177 }
c47d488e
DD
9178 }
9179 else
9180 {
9181 fc->code_factor = LEB ();
9182 fc->data_factor = SLEB ();
0da76f83
NC
9183 if (version == 1)
9184 {
9185 fc->ra = GET (1);
9186 }
9187 else
9188 {
9189 fc->ra = LEB ();
9190 }
c47d488e
DD
9191 }
9192 cie = fc;
31b6fca6
RH
9193
9194 if (do_debug_frames_interp)
9195 printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
7036c0e1 9196 (unsigned long)(saved_start - section_start), length, cie_id,
31b6fca6
RH
9197 fc->augmentation, fc->code_factor, fc->data_factor,
9198 fc->ra);
9199 else
9200 {
9201 printf ("\n%08lx %08lx %08lx CIE\n",
7036c0e1 9202 (unsigned long)(saved_start - section_start), length, cie_id);
31b6fca6
RH
9203 printf (" Version: %d\n", version);
9204 printf (" Augmentation: \"%s\"\n", fc->augmentation);
9205 printf (" Code alignment factor: %u\n", fc->code_factor);
9206 printf (" Data alignment factor: %d\n", fc->data_factor);
9207 printf (" Return address column: %d\n", fc->ra);
9208
9209 if (augmentation_data_len)
9210 {
9211 unsigned long i;
9212 printf (" Augmentation data: ");
9213 for (i = 0; i < augmentation_data_len; ++i)
9214 printf (" %02x", augmentation_data[i]);
9215 putchar ('\n');
9216 }
9217 putchar ('\n');
9218 }
9219
9220 if (augmentation_data_len)
9221 {
9222 unsigned char *p, *q;
9223 p = fc->augmentation + 1;
9224 q = augmentation_data;
9225
9226 while (1)
9227 {
9228 if (*p == 'L')
7036c0e1 9229 q++;
31b6fca6
RH
9230 else if (*p == 'P')
9231 q += 1 + size_of_encoded_value (*q);
9232 else if (*p == 'R')
9233 fc->fde_encoding = *q++;
9234 else
9235 break;
9236 p++;
9237 }
9238
9239 if (fc->fde_encoding)
9240 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
9241 }
c47d488e
DD
9242
9243 frame_need_space (fc, fc->ra);
9244 }
9245 else
9246 {
b34976b6 9247 unsigned char *look_for;
c47d488e 9248 static Frame_Chunk fde_fc;
584da044
NC
9249
9250 fc = & fde_fc;
c47d488e
DD
9251 memset (fc, 0, sizeof (Frame_Chunk));
9252
31b6fca6 9253 look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
c47d488e 9254
428409d5 9255 for (cie = chunks; cie ; cie = cie->next)
31b6fca6
RH
9256 if (cie->chunk_start == look_for)
9257 break;
c47d488e 9258
c47d488e
DD
9259 if (!cie)
9260 {
31b6fca6
RH
9261 warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
9262 cie_id, saved_start);
c47d488e
DD
9263 start = block_end;
9264 fc->ncols = 0;
d3ba0551
AM
9265 fc->col_type = xmalloc (sizeof (short int));
9266 fc->col_offset = xmalloc (sizeof (int));
584da044 9267 frame_need_space (fc, max_regs - 1);
c47d488e
DD
9268 cie = fc;
9269 fc->augmentation = "";
31b6fca6 9270 fc->fde_encoding = 0;
c47d488e
DD
9271 }
9272 else
9273 {
9274 fc->ncols = cie->ncols;
d3ba0551
AM
9275 fc->col_type = xmalloc (fc->ncols * sizeof (short int));
9276 fc->col_offset = xmalloc (fc->ncols * sizeof (int));
a98cc2b2 9277 memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
c47d488e
DD
9278 memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
9279 fc->augmentation = cie->augmentation;
9280 fc->code_factor = cie->code_factor;
9281 fc->data_factor = cie->data_factor;
9282 fc->cfa_reg = cie->cfa_reg;
9283 fc->cfa_offset = cie->cfa_offset;
9284 fc->ra = cie->ra;
9285 frame_need_space (fc, max_regs-1);
31b6fca6 9286 fc->fde_encoding = cie->fde_encoding;
c47d488e
DD
9287 }
9288
31b6fca6
RH
9289 if (fc->fde_encoding)
9290 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
9291
38fafa6d 9292 fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
d84de024
AM
9293 if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
9294 /* Don't adjust for ET_REL since there's invariably a pcrel
9295 reloc here, which we haven't applied. */
9296 && elf_header.e_type != ET_REL)
f1ef08cb 9297 fc->pc_begin += section->sh_addr + (start - section_start);
31b6fca6
RH
9298 start += encoded_ptr_size;
9299 fc->pc_range = byte_get (start, encoded_ptr_size);
9300 start += encoded_ptr_size;
9301
c47d488e
DD
9302 if (cie->augmentation[0] == 'z')
9303 {
31b6fca6
RH
9304 augmentation_data_len = LEB ();
9305 augmentation_data = start;
9306 start += augmentation_data_len;
c47d488e
DD
9307 }
9308
410f7a12 9309 printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
7036c0e1 9310 (unsigned long)(saved_start - section_start), length, cie_id,
410f7a12
L
9311 (unsigned long)(cie->chunk_start - section_start),
9312 fc->pc_begin, fc->pc_begin + fc->pc_range);
31b6fca6
RH
9313 if (! do_debug_frames_interp && augmentation_data_len)
9314 {
9315 unsigned long i;
9316 printf (" Augmentation data: ");
9317 for (i = 0; i < augmentation_data_len; ++i)
ba2685cc 9318 printf (" %02x", augmentation_data[i]);
31b6fca6
RH
9319 putchar ('\n');
9320 putchar ('\n');
9321 }
c47d488e
DD
9322 }
9323
9324 /* At this point, fc is the current chunk, cie (if any) is set, and we're
9325 about to interpret instructions for the chunk. */
38fafa6d
RH
9326 /* ??? At present we need to do this always, since this sizes the
9327 fc->col_type and fc->col_offset arrays, which we write into always.
9328 We should probably split the interpreted and non-interpreted bits
9329 into two different routines, since there's so much that doesn't
9330 really overlap between them. */
9331 if (1 || do_debug_frames_interp)
53c7db4b
KH
9332 {
9333 /* Start by making a pass over the chunk, allocating storage
9334 and taking note of what registers are used. */
b34976b6 9335 unsigned char *tmp = start;
a98cc2b2 9336
53c7db4b
KH
9337 while (start < block_end)
9338 {
9339 unsigned op, opa;
63044634 9340 unsigned long reg, tmp;
7036c0e1 9341
b34976b6 9342 op = *start++;
53c7db4b
KH
9343 opa = op & 0x3f;
9344 if (op & 0xc0)
9345 op &= 0xc0;
7036c0e1 9346
53c7db4b 9347 /* Warning: if you add any more cases to this switch, be
ba2685cc 9348 sure to add them to the corresponding switch below. */
53c7db4b
KH
9349 switch (op)
9350 {
9351 case DW_CFA_advance_loc:
9352 break;
9353 case DW_CFA_offset:
9354 LEB ();
9355 frame_need_space (fc, opa);
9356 fc->col_type[opa] = DW_CFA_undefined;
9357 break;
9358 case DW_CFA_restore:
9359 frame_need_space (fc, opa);
9360 fc->col_type[opa] = DW_CFA_undefined;
9361 break;
9362 case DW_CFA_set_loc:
9363 start += encoded_ptr_size;
9364 break;
9365 case DW_CFA_advance_loc1:
9366 start += 1;
9367 break;
9368 case DW_CFA_advance_loc2:
9369 start += 2;
9370 break;
9371 case DW_CFA_advance_loc4:
9372 start += 4;
9373 break;
9374 case DW_CFA_offset_extended:
9375 reg = LEB (); LEB ();
9376 frame_need_space (fc, reg);
9377 fc->col_type[reg] = DW_CFA_undefined;
9378 break;
9379 case DW_CFA_restore_extended:
9380 reg = LEB ();
9381 frame_need_space (fc, reg);
9382 fc->col_type[reg] = DW_CFA_undefined;
9383 break;
9384 case DW_CFA_undefined:
9385 reg = LEB ();
9386 frame_need_space (fc, reg);
9387 fc->col_type[reg] = DW_CFA_undefined;
9388 break;
9389 case DW_CFA_same_value:
9390 reg = LEB ();
9391 frame_need_space (fc, reg);
9392 fc->col_type[reg] = DW_CFA_undefined;
9393 break;
9394 case DW_CFA_register:
9395 reg = LEB (); LEB ();
9396 frame_need_space (fc, reg);
9397 fc->col_type[reg] = DW_CFA_undefined;
9398 break;
9399 case DW_CFA_def_cfa:
9400 LEB (); LEB ();
9401 break;
9402 case DW_CFA_def_cfa_register:
9403 LEB ();
9404 break;
9405 case DW_CFA_def_cfa_offset:
9406 LEB ();
9407 break;
63044634
RH
9408 case DW_CFA_def_cfa_expression:
9409 tmp = LEB ();
9410 start += tmp;
9411 break;
9412 case DW_CFA_expression:
9413 reg = LEB ();
9414 tmp = LEB ();
9415 start += tmp;
9416 frame_need_space (fc, reg);
9417 fc->col_type[reg] = DW_CFA_undefined;
9418 break;
91a106e6
L
9419 case DW_CFA_offset_extended_sf:
9420 reg = LEB (); SLEB ();
9421 frame_need_space (fc, reg);
9422 fc->col_type[reg] = DW_CFA_undefined;
9423 break;
9424 case DW_CFA_def_cfa_sf:
9425 LEB (); SLEB ();
9426 break;
9427 case DW_CFA_def_cfa_offset_sf:
9428 SLEB ();
9429 break;
63044634
RH
9430 case DW_CFA_MIPS_advance_loc8:
9431 start += 8;
9432 break;
53c7db4b
KH
9433 case DW_CFA_GNU_args_size:
9434 LEB ();
9435 break;
53c7db4b
KH
9436 case DW_CFA_GNU_negative_offset_extended:
9437 reg = LEB (); LEB ();
9438 frame_need_space (fc, reg);
9439 fc->col_type[reg] = DW_CFA_undefined;
7036c0e1 9440
53c7db4b
KH
9441 default:
9442 break;
9443 }
9444 }
9445 start = tmp;
9446 }
a98cc2b2
AH
9447
9448 /* Now we know what registers are used, make a second pass over
ba2685cc 9449 the chunk, this time actually printing out the info. */
a98cc2b2 9450
c47d488e
DD
9451 while (start < block_end)
9452 {
9453 unsigned op, opa;
9454 unsigned long ul, reg, roffs;
9455 long l, ofs;
9456 bfd_vma vma;
9457
b34976b6 9458 op = *start++;
c47d488e
DD
9459 opa = op & 0x3f;
9460 if (op & 0xc0)
9461 op &= 0xc0;
9462
53c7db4b
KH
9463 /* Warning: if you add any more cases to this switch, be
9464 sure to add them to the corresponding switch above. */
c47d488e
DD
9465 switch (op)
9466 {
9467 case DW_CFA_advance_loc:
31b6fca6 9468 if (do_debug_frames_interp)
53c7db4b 9469 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9470 else
53c7db4b
KH
9471 printf (" DW_CFA_advance_loc: %d to %08lx\n",
9472 opa * fc->code_factor,
31b6fca6 9473 fc->pc_begin + opa * fc->code_factor);
c47d488e
DD
9474 fc->pc_begin += opa * fc->code_factor;
9475 break;
9476
9477 case DW_CFA_offset:
c47d488e 9478 roffs = LEB ();
31b6fca6 9479 if (! do_debug_frames_interp)
53c7db4b 9480 printf (" DW_CFA_offset: r%d at cfa%+ld\n",
31b6fca6 9481 opa, roffs * fc->data_factor);
c47d488e
DD
9482 fc->col_type[opa] = DW_CFA_offset;
9483 fc->col_offset[opa] = roffs * fc->data_factor;
9484 break;
9485
9486 case DW_CFA_restore:
31b6fca6 9487 if (! do_debug_frames_interp)
53c7db4b 9488 printf (" DW_CFA_restore: r%d\n", opa);
c47d488e
DD
9489 fc->col_type[opa] = cie->col_type[opa];
9490 fc->col_offset[opa] = cie->col_offset[opa];
9491 break;
9492
9493 case DW_CFA_set_loc:
38fafa6d 9494 vma = get_encoded_value (start, fc->fde_encoding);
d84de024
AM
9495 if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
9496 && elf_header.e_type != ET_REL)
f1ef08cb 9497 vma += section->sh_addr + (start - section_start);
31b6fca6
RH
9498 start += encoded_ptr_size;
9499 if (do_debug_frames_interp)
53c7db4b 9500 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9501 else
53c7db4b 9502 printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
c47d488e
DD
9503 fc->pc_begin = vma;
9504 break;
9505
9506 case DW_CFA_advance_loc1:
c47d488e 9507 ofs = byte_get (start, 1); start += 1;
31b6fca6 9508 if (do_debug_frames_interp)
53c7db4b 9509 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9510 else
53c7db4b
KH
9511 printf (" DW_CFA_advance_loc1: %ld to %08lx\n",
9512 ofs * fc->code_factor,
31b6fca6 9513 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
9514 fc->pc_begin += ofs * fc->code_factor;
9515 break;
9516
9517 case DW_CFA_advance_loc2:
c47d488e 9518 ofs = byte_get (start, 2); start += 2;
31b6fca6 9519 if (do_debug_frames_interp)
53c7db4b 9520 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9521 else
53c7db4b
KH
9522 printf (" DW_CFA_advance_loc2: %ld to %08lx\n",
9523 ofs * fc->code_factor,
31b6fca6 9524 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
9525 fc->pc_begin += ofs * fc->code_factor;
9526 break;
9527
9528 case DW_CFA_advance_loc4:
c47d488e 9529 ofs = byte_get (start, 4); start += 4;
31b6fca6 9530 if (do_debug_frames_interp)
53c7db4b 9531 frame_display_row (fc, &need_col_headers, &max_regs);
31b6fca6 9532 else
53c7db4b
KH
9533 printf (" DW_CFA_advance_loc4: %ld to %08lx\n",
9534 ofs * fc->code_factor,
31b6fca6 9535 fc->pc_begin + ofs * fc->code_factor);
c47d488e
DD
9536 fc->pc_begin += ofs * fc->code_factor;
9537 break;
9538
9539 case DW_CFA_offset_extended:
9540 reg = LEB ();
9541 roffs = LEB ();
31b6fca6 9542 if (! do_debug_frames_interp)
7036c0e1 9543 printf (" DW_CFA_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 9544 reg, roffs * fc->data_factor);
c47d488e
DD
9545 fc->col_type[reg] = DW_CFA_offset;
9546 fc->col_offset[reg] = roffs * fc->data_factor;
9547 break;
9548
9549 case DW_CFA_restore_extended:
9550 reg = LEB ();
31b6fca6 9551 if (! do_debug_frames_interp)
53c7db4b 9552 printf (" DW_CFA_restore_extended: r%ld\n", reg);
c47d488e
DD
9553 fc->col_type[reg] = cie->col_type[reg];
9554 fc->col_offset[reg] = cie->col_offset[reg];
9555 break;
9556
9557 case DW_CFA_undefined:
9558 reg = LEB ();
31b6fca6 9559 if (! do_debug_frames_interp)
53c7db4b 9560 printf (" DW_CFA_undefined: r%ld\n", reg);
c47d488e
DD
9561 fc->col_type[reg] = DW_CFA_undefined;
9562 fc->col_offset[reg] = 0;
9563 break;
9564
9565 case DW_CFA_same_value:
9566 reg = LEB ();
31b6fca6 9567 if (! do_debug_frames_interp)
53c7db4b 9568 printf (" DW_CFA_same_value: r%ld\n", reg);
c47d488e
DD
9569 fc->col_type[reg] = DW_CFA_same_value;
9570 fc->col_offset[reg] = 0;
9571 break;
9572
9573 case DW_CFA_register:
9574 reg = LEB ();
9575 roffs = LEB ();
31b6fca6 9576 if (! do_debug_frames_interp)
636fc387 9577 printf (" DW_CFA_register: r%ld in r%ld\n", reg, roffs);
c47d488e
DD
9578 fc->col_type[reg] = DW_CFA_register;
9579 fc->col_offset[reg] = roffs;
9580 break;
9581
9582 case DW_CFA_remember_state:
31b6fca6 9583 if (! do_debug_frames_interp)
53c7db4b 9584 printf (" DW_CFA_remember_state\n");
d3ba0551 9585 rs = xmalloc (sizeof (Frame_Chunk));
c47d488e 9586 rs->ncols = fc->ncols;
d3ba0551
AM
9587 rs->col_type = xmalloc (rs->ncols * sizeof (short int));
9588 rs->col_offset = xmalloc (rs->ncols * sizeof (int));
c47d488e
DD
9589 memcpy (rs->col_type, fc->col_type, rs->ncols);
9590 memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
9591 rs->next = remembered_state;
9592 remembered_state = rs;
9593 break;
9594
9595 case DW_CFA_restore_state:
31b6fca6 9596 if (! do_debug_frames_interp)
53c7db4b 9597 printf (" DW_CFA_restore_state\n");
c47d488e 9598 rs = remembered_state;
8c9a9879
RH
9599 if (rs)
9600 {
9601 remembered_state = rs->next;
9602 frame_need_space (fc, rs->ncols-1);
9603 memcpy (fc->col_type, rs->col_type, rs->ncols);
9604 memcpy (fc->col_offset, rs->col_offset,
9605 rs->ncols * sizeof (int));
9606 free (rs->col_type);
9607 free (rs->col_offset);
9608 free (rs);
9609 }
9610 else if (do_debug_frames_interp)
9611 printf ("Mismatched DW_CFA_restore_state\n");
c47d488e
DD
9612 break;
9613
9614 case DW_CFA_def_cfa:
9615 fc->cfa_reg = LEB ();
9616 fc->cfa_offset = LEB ();
63044634 9617 fc->cfa_exp = 0;
31b6fca6 9618 if (! do_debug_frames_interp)
53c7db4b 9619 printf (" DW_CFA_def_cfa: r%d ofs %d\n",
31b6fca6 9620 fc->cfa_reg, fc->cfa_offset);
c47d488e
DD
9621 break;
9622
9623 case DW_CFA_def_cfa_register:
9624 fc->cfa_reg = LEB ();
63044634 9625 fc->cfa_exp = 0;
31b6fca6 9626 if (! do_debug_frames_interp)
53c7db4b 9627 printf (" DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
c47d488e
DD
9628 break;
9629
9630 case DW_CFA_def_cfa_offset:
9631 fc->cfa_offset = LEB ();
31b6fca6 9632 if (! do_debug_frames_interp)
53c7db4b 9633 printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
c47d488e
DD
9634 break;
9635
9636 case DW_CFA_nop:
31b6fca6 9637 if (! do_debug_frames_interp)
53c7db4b 9638 printf (" DW_CFA_nop\n");
c47d488e
DD
9639 break;
9640
63044634
RH
9641 case DW_CFA_def_cfa_expression:
9642 ul = LEB ();
9643 if (! do_debug_frames_interp)
9644 {
9645 printf (" DW_CFA_def_cfa_expression (");
9646 decode_location_expression (start, addr_size, ul);
9647 printf (")\n");
9648 }
9649 fc->cfa_exp = 1;
9650 start += ul;
9651 break;
9652
9653 case DW_CFA_expression:
9654 reg = LEB ();
9655 ul = LEB ();
9656 if (! do_debug_frames_interp)
9657 {
9658 printf (" DW_CFA_expression: r%ld (", reg);
9659 decode_location_expression (start, addr_size, ul);
9660 printf (")\n");
9661 }
9662 fc->col_type[reg] = DW_CFA_expression;
9663 start += ul;
9664 break;
9665
91a106e6
L
9666 case DW_CFA_offset_extended_sf:
9667 reg = LEB ();
9668 l = SLEB ();
9669 frame_need_space (fc, reg);
9670 if (! do_debug_frames_interp)
9671 printf (" DW_CFA_offset_extended_sf: r%ld at cfa%+ld\n",
9672 reg, l * fc->data_factor);
9673 fc->col_type[reg] = DW_CFA_offset;
9674 fc->col_offset[reg] = l * fc->data_factor;
9675 break;
9676
9677 case DW_CFA_def_cfa_sf:
9678 fc->cfa_reg = LEB ();
9679 fc->cfa_offset = SLEB ();
63044634 9680 fc->cfa_exp = 0;
91a106e6
L
9681 if (! do_debug_frames_interp)
9682 printf (" DW_CFA_def_cfa_sf: r%d ofs %d\n",
9683 fc->cfa_reg, fc->cfa_offset);
9684 break;
9685
9686 case DW_CFA_def_cfa_offset_sf:
9687 fc->cfa_offset = SLEB ();
9688 if (! do_debug_frames_interp)
9689 printf (" DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset);
9690 break;
9691
63044634
RH
9692 case DW_CFA_MIPS_advance_loc8:
9693 ofs = byte_get (start, 8); start += 8;
9694 if (do_debug_frames_interp)
9695 frame_display_row (fc, &need_col_headers, &max_regs);
9696 else
9697 printf (" DW_CFA_MIPS_advance_loc8: %ld to %08lx\n",
9698 ofs * fc->code_factor,
9699 fc->pc_begin + ofs * fc->code_factor);
9700 fc->pc_begin += ofs * fc->code_factor;
9701 break;
9702
c47d488e 9703 case DW_CFA_GNU_window_save:
31b6fca6 9704 if (! do_debug_frames_interp)
53c7db4b 9705 printf (" DW_CFA_GNU_window_save\n");
c47d488e
DD
9706 break;
9707
c47d488e
DD
9708 case DW_CFA_GNU_args_size:
9709 ul = LEB ();
31b6fca6 9710 if (! do_debug_frames_interp)
53c7db4b 9711 printf (" DW_CFA_GNU_args_size: %ld\n", ul);
c47d488e
DD
9712 break;
9713
c47d488e
DD
9714 case DW_CFA_GNU_negative_offset_extended:
9715 reg = LEB ();
9716 l = - LEB ();
9717 frame_need_space (fc, reg);
31b6fca6 9718 if (! do_debug_frames_interp)
53c7db4b 9719 printf (" DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
31b6fca6 9720 reg, l * fc->data_factor);
c47d488e
DD
9721 fc->col_type[reg] = DW_CFA_offset;
9722 fc->col_offset[reg] = l * fc->data_factor;
9723 break;
9724
9725 default:
9726 fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
9727 start = block_end;
9728 }
9729 }
9730
31b6fca6 9731 if (do_debug_frames_interp)
53c7db4b 9732 frame_display_row (fc, &need_col_headers, &max_regs);
c47d488e
DD
9733
9734 start = block_end;
9735 }
9736
9737 printf ("\n");
9738
9739 return 1;
9740}
9741
9742#undef GET
9743#undef LEB
9744#undef SLEB
252b5132
RH
9745
9746static int
d3ba0551
AM
9747display_debug_not_supported (Elf_Internal_Shdr *section,
9748 unsigned char *start ATTRIBUTE_UNUSED,
9749 FILE *file ATTRIBUTE_UNUSED)
252b5132
RH
9750{
9751 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
9752 SECTION_NAME (section));
9753
9754 return 1;
9755}
9756
d9296b18
NC
9757/* A structure containing the name of a debug section
9758 and a pointer to a function that can decode it. */
252b5132
RH
9759struct
9760{
b34976b6 9761 const char *const name;
d3ba0551 9762 int (*display) (Elf_Internal_Shdr *, unsigned char *, FILE *);
252b5132
RH
9763}
9764debug_displays[] =
9765{
d9296b18
NC
9766 { ".debug_abbrev", display_debug_abbrev },
9767 { ".debug_aranges", display_debug_aranges },
9768 { ".debug_frame", display_debug_frames },
9769 { ".debug_info", display_debug_info },
9770 { ".debug_line", display_debug_lines },
9771 { ".debug_pubnames", display_debug_pubnames },
9772 { ".eh_frame", display_debug_frames },
9773 { ".debug_macinfo", display_debug_macinfo },
9774 { ".debug_str", display_debug_str },
9775 { ".debug_loc", display_debug_loc },
935a41f5 9776 { ".debug_pubtypes", display_debug_pubnames },
d9296b18
NC
9777 { ".debug_ranges", display_debug_not_supported },
9778 { ".debug_static_func", display_debug_not_supported },
9779 { ".debug_static_vars", display_debug_not_supported },
9780 { ".debug_types", display_debug_not_supported },
9781 { ".debug_weaknames", display_debug_not_supported }
252b5132
RH
9782};
9783
9784static int
d3ba0551 9785display_debug_section (Elf_Internal_Shdr *section, FILE *file)
252b5132 9786{
b34976b6
AM
9787 char *name = SECTION_NAME (section);
9788 bfd_size_type length;
9789 unsigned char *start;
9790 int i;
252b5132
RH
9791
9792 length = section->sh_size;
9793 if (length == 0)
9794 {
9795 printf (_("\nSection '%s' has no debugging data.\n"), name);
9796 return 0;
9797 }
9798
d3ba0551
AM
9799 start = get_data (NULL, file, section->sh_offset, length,
9800 _("debug section data"));
a6e9f9df
AM
9801 if (!start)
9802 return 0;
252b5132
RH
9803
9804 /* See if we know how to display the contents of this section. */
09fd7e38 9805 if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
7036c0e1 9806 name = ".debug_info";
584da044 9807
252b5132
RH
9808 for (i = NUM_ELEM (debug_displays); i--;)
9809 if (strcmp (debug_displays[i].name, name) == 0)
9810 {
9811 debug_displays[i].display (section, start, file);
9812 break;
9813 }
9814
9815 if (i == -1)
2c71103e 9816 printf (_("Unrecognized debug section: %s\n"), name);
252b5132
RH
9817
9818 free (start);
9819
9820 /* If we loaded in the abbrev section at some point,
9821 we must release it here. */
261a45ad 9822 free_abbrevs ();
252b5132
RH
9823
9824 return 1;
9825}
9826
9827static int
d3ba0551 9828process_section_contents (FILE *file)
252b5132 9829{
b34976b6
AM
9830 Elf_Internal_Shdr *section;
9831 unsigned int i;
252b5132
RH
9832
9833 if (! do_dump)
9834 return 1;
9835
9836 for (i = 0, section = section_headers;
3590ea00 9837 i < elf_header.e_shnum && i < num_dump_sects;
b34976b6 9838 i++, section++)
252b5132
RH
9839 {
9840#ifdef SUPPORT_DISASSEMBLY
9841 if (dump_sects[i] & DISASS_DUMP)
9842 disassemble_section (section, file);
9843#endif
9844 if (dump_sects[i] & HEX_DUMP)
9845 dump_section (section, file);
9846
9847 if (dump_sects[i] & DEBUG_DUMP)
9848 display_debug_section (section, file);
9849 }
9850
9851 if (i < num_dump_sects)
9852 warn (_("Some sections were not dumped because they do not exist!\n"));
9853
9854 return 1;
9855}
9856
9857static void
d3ba0551 9858process_mips_fpe_exception (int mask)
252b5132
RH
9859{
9860 if (mask)
9861 {
9862 int first = 1;
9863 if (mask & OEX_FPU_INEX)
9864 fputs ("INEX", stdout), first = 0;
9865 if (mask & OEX_FPU_UFLO)
9866 printf ("%sUFLO", first ? "" : "|"), first = 0;
9867 if (mask & OEX_FPU_OFLO)
9868 printf ("%sOFLO", first ? "" : "|"), first = 0;
9869 if (mask & OEX_FPU_DIV0)
9870 printf ("%sDIV0", first ? "" : "|"), first = 0;
9871 if (mask & OEX_FPU_INVAL)
9872 printf ("%sINVAL", first ? "" : "|");
9873 }
9874 else
9875 fputs ("0", stdout);
9876}
9877
9878static int
d3ba0551 9879process_mips_specific (FILE *file)
252b5132 9880{
b34976b6 9881 Elf_Internal_Dyn *entry;
252b5132
RH
9882 size_t liblist_offset = 0;
9883 size_t liblistno = 0;
9884 size_t conflictsno = 0;
9885 size_t options_offset = 0;
9886 size_t conflicts_offset = 0;
9887
9888 /* We have a lot of special sections. Thanks SGI! */
b2d38a17 9889 if (dynamic_section == NULL)
252b5132
RH
9890 /* No information available. */
9891 return 0;
9892
b2d38a17 9893 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
9894 switch (entry->d_tag)
9895 {
9896 case DT_MIPS_LIBLIST:
d93f0186
NC
9897 liblist_offset
9898 = offset_from_vma (file, entry->d_un.d_val,
9899 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
9900 break;
9901 case DT_MIPS_LIBLISTNO:
9902 liblistno = entry->d_un.d_val;
9903 break;
9904 case DT_MIPS_OPTIONS:
d93f0186 9905 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
9906 break;
9907 case DT_MIPS_CONFLICT:
d93f0186
NC
9908 conflicts_offset
9909 = offset_from_vma (file, entry->d_un.d_val,
9910 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
9911 break;
9912 case DT_MIPS_CONFLICTNO:
9913 conflictsno = entry->d_un.d_val;
9914 break;
9915 default:
9916 break;
9917 }
9918
9919 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
9920 {
b34976b6 9921 Elf32_External_Lib *elib;
252b5132
RH
9922 size_t cnt;
9923
d3ba0551
AM
9924 elib = get_data (NULL, file, liblist_offset,
9925 liblistno * sizeof (Elf32_External_Lib),
9926 _("liblist"));
a6e9f9df 9927 if (elib)
252b5132 9928 {
a6e9f9df
AM
9929 printf ("\nSection '.liblist' contains %lu entries:\n",
9930 (unsigned long) liblistno);
9931 fputs (" Library Time Stamp Checksum Version Flags\n",
9932 stdout);
9933
9934 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 9935 {
a6e9f9df
AM
9936 Elf32_Lib liblist;
9937 time_t time;
9938 char timebuf[20];
b34976b6 9939 struct tm *tmp;
a6e9f9df
AM
9940
9941 liblist.l_name = BYTE_GET (elib[cnt].l_name);
9942 time = BYTE_GET (elib[cnt].l_time_stamp);
9943 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
9944 liblist.l_version = BYTE_GET (elib[cnt].l_version);
9945 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
9946
9947 tmp = gmtime (&time);
9948 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
9949 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9950 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
9951
31104126 9952 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
9953 if (VALID_DYNAMIC_NAME (liblist.l_name))
9954 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
9955 else
9956 printf ("<corrupt: %9ld>", liblist.l_name);
31104126
NC
9957 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
9958 liblist.l_version);
a6e9f9df
AM
9959
9960 if (liblist.l_flags == 0)
9961 puts (" NONE");
9962 else
9963 {
9964 static const struct
252b5132 9965 {
b34976b6 9966 const char *name;
a6e9f9df 9967 int bit;
252b5132 9968 }
a6e9f9df
AM
9969 l_flags_vals[] =
9970 {
9971 { " EXACT_MATCH", LL_EXACT_MATCH },
9972 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
9973 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
9974 { " EXPORTS", LL_EXPORTS },
9975 { " DELAY_LOAD", LL_DELAY_LOAD },
9976 { " DELTA", LL_DELTA }
9977 };
9978 int flags = liblist.l_flags;
9979 size_t fcnt;
9980
9981 for (fcnt = 0;
9982 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
9983 ++fcnt)
9984 if ((flags & l_flags_vals[fcnt].bit) != 0)
9985 {
9986 fputs (l_flags_vals[fcnt].name, stdout);
9987 flags ^= l_flags_vals[fcnt].bit;
9988 }
9989 if (flags != 0)
9990 printf (" %#x", (unsigned int) flags);
252b5132 9991
a6e9f9df
AM
9992 puts ("");
9993 }
252b5132 9994 }
252b5132 9995
a6e9f9df
AM
9996 free (elib);
9997 }
252b5132
RH
9998 }
9999
10000 if (options_offset != 0)
10001 {
b34976b6
AM
10002 Elf_External_Options *eopt;
10003 Elf_Internal_Shdr *sect = section_headers;
10004 Elf_Internal_Options *iopt;
10005 Elf_Internal_Options *option;
252b5132
RH
10006 size_t offset;
10007 int cnt;
10008
10009 /* Find the section header so that we get the size. */
10010 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 10011 ++sect;
252b5132 10012
d3ba0551
AM
10013 eopt = get_data (NULL, file, options_offset, sect->sh_size,
10014 _("options"));
a6e9f9df 10015 if (eopt)
252b5132 10016 {
d3ba0551 10017 iopt = malloc ((sect->sh_size / sizeof (eopt)) * sizeof (*iopt));
a6e9f9df
AM
10018 if (iopt == NULL)
10019 {
10020 error (_("Out of memory"));
10021 return 0;
10022 }
76da6bbe 10023
a6e9f9df
AM
10024 offset = cnt = 0;
10025 option = iopt;
252b5132 10026
a6e9f9df
AM
10027 while (offset < sect->sh_size)
10028 {
b34976b6 10029 Elf_External_Options *eoption;
252b5132 10030
a6e9f9df 10031 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 10032
a6e9f9df
AM
10033 option->kind = BYTE_GET (eoption->kind);
10034 option->size = BYTE_GET (eoption->size);
10035 option->section = BYTE_GET (eoption->section);
10036 option->info = BYTE_GET (eoption->info);
76da6bbe 10037
a6e9f9df 10038 offset += option->size;
252b5132 10039
a6e9f9df
AM
10040 ++option;
10041 ++cnt;
10042 }
252b5132 10043
a6e9f9df
AM
10044 printf (_("\nSection '%s' contains %d entries:\n"),
10045 SECTION_NAME (sect), cnt);
76da6bbe 10046
a6e9f9df 10047 option = iopt;
252b5132 10048
a6e9f9df 10049 while (cnt-- > 0)
252b5132 10050 {
a6e9f9df
AM
10051 size_t len;
10052
10053 switch (option->kind)
252b5132 10054 {
a6e9f9df
AM
10055 case ODK_NULL:
10056 /* This shouldn't happen. */
10057 printf (" NULL %d %lx", option->section, option->info);
10058 break;
10059 case ODK_REGINFO:
10060 printf (" REGINFO ");
10061 if (elf_header.e_machine == EM_MIPS)
10062 {
10063 /* 32bit form. */
b34976b6
AM
10064 Elf32_External_RegInfo *ereg;
10065 Elf32_RegInfo reginfo;
a6e9f9df
AM
10066
10067 ereg = (Elf32_External_RegInfo *) (option + 1);
10068 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
10069 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
10070 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
10071 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
10072 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
10073 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
10074
10075 printf ("GPR %08lx GP 0x%lx\n",
10076 reginfo.ri_gprmask,
10077 (unsigned long) reginfo.ri_gp_value);
10078 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
10079 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
10080 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
10081 }
10082 else
10083 {
10084 /* 64 bit form. */
b34976b6 10085 Elf64_External_RegInfo *ereg;
a6e9f9df
AM
10086 Elf64_Internal_RegInfo reginfo;
10087
10088 ereg = (Elf64_External_RegInfo *) (option + 1);
10089 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
10090 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
10091 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
10092 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
10093 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
10094 reginfo.ri_gp_value = BYTE_GET8 (ereg->ri_gp_value);
10095
10096 printf ("GPR %08lx GP 0x",
10097 reginfo.ri_gprmask);
10098 printf_vma (reginfo.ri_gp_value);
10099 printf ("\n");
10100
10101 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
10102 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
10103 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
10104 }
10105 ++option;
10106 continue;
10107 case ODK_EXCEPTIONS:
10108 fputs (" EXCEPTIONS fpe_min(", stdout);
10109 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
10110 fputs (") fpe_max(", stdout);
10111 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
10112 fputs (")", stdout);
10113
10114 if (option->info & OEX_PAGE0)
10115 fputs (" PAGE0", stdout);
10116 if (option->info & OEX_SMM)
10117 fputs (" SMM", stdout);
10118 if (option->info & OEX_FPDBUG)
10119 fputs (" FPDBUG", stdout);
10120 if (option->info & OEX_DISMISS)
10121 fputs (" DISMISS", stdout);
10122 break;
10123 case ODK_PAD:
10124 fputs (" PAD ", stdout);
10125 if (option->info & OPAD_PREFIX)
10126 fputs (" PREFIX", stdout);
10127 if (option->info & OPAD_POSTFIX)
10128 fputs (" POSTFIX", stdout);
10129 if (option->info & OPAD_SYMBOL)
10130 fputs (" SYMBOL", stdout);
10131 break;
10132 case ODK_HWPATCH:
10133 fputs (" HWPATCH ", stdout);
10134 if (option->info & OHW_R4KEOP)
10135 fputs (" R4KEOP", stdout);
10136 if (option->info & OHW_R8KPFETCH)
10137 fputs (" R8KPFETCH", stdout);
10138 if (option->info & OHW_R5KEOP)
10139 fputs (" R5KEOP", stdout);
10140 if (option->info & OHW_R5KCVTL)
10141 fputs (" R5KCVTL", stdout);
10142 break;
10143 case ODK_FILL:
10144 fputs (" FILL ", stdout);
10145 /* XXX Print content of info word? */
10146 break;
10147 case ODK_TAGS:
10148 fputs (" TAGS ", stdout);
10149 /* XXX Print content of info word? */
10150 break;
10151 case ODK_HWAND:
10152 fputs (" HWAND ", stdout);
10153 if (option->info & OHWA0_R4KEOP_CHECKED)
10154 fputs (" R4KEOP_CHECKED", stdout);
10155 if (option->info & OHWA0_R4KEOP_CLEAN)
10156 fputs (" R4KEOP_CLEAN", stdout);
10157 break;
10158 case ODK_HWOR:
10159 fputs (" HWOR ", stdout);
10160 if (option->info & OHWA0_R4KEOP_CHECKED)
10161 fputs (" R4KEOP_CHECKED", stdout);
10162 if (option->info & OHWA0_R4KEOP_CLEAN)
10163 fputs (" R4KEOP_CLEAN", stdout);
10164 break;
10165 case ODK_GP_GROUP:
10166 printf (" GP_GROUP %#06lx self-contained %#06lx",
10167 option->info & OGP_GROUP,
10168 (option->info & OGP_SELF) >> 16);
10169 break;
10170 case ODK_IDENT:
10171 printf (" IDENT %#06lx self-contained %#06lx",
10172 option->info & OGP_GROUP,
10173 (option->info & OGP_SELF) >> 16);
10174 break;
10175 default:
10176 /* This shouldn't happen. */
10177 printf (" %3d ??? %d %lx",
10178 option->kind, option->section, option->info);
10179 break;
252b5132 10180 }
a6e9f9df 10181
b34976b6 10182 len = sizeof (*eopt);
a6e9f9df
AM
10183 while (len < option->size)
10184 if (((char *) option)[len] >= ' '
10185 && ((char *) option)[len] < 0x7f)
10186 printf ("%c", ((char *) option)[len++]);
10187 else
10188 printf ("\\%03o", ((char *) option)[len++]);
10189
10190 fputs ("\n", stdout);
252b5132 10191 ++option;
252b5132
RH
10192 }
10193
a6e9f9df 10194 free (eopt);
252b5132 10195 }
252b5132
RH
10196 }
10197
10198 if (conflicts_offset != 0 && conflictsno != 0)
10199 {
b34976b6 10200 Elf32_Conflict *iconf;
252b5132
RH
10201 size_t cnt;
10202
10203 if (dynamic_symbols == NULL)
10204 {
3a1a2036 10205 error (_("conflict list found without a dynamic symbol table"));
252b5132
RH
10206 return 0;
10207 }
10208
d3ba0551 10209 iconf = malloc (conflictsno * sizeof (*iconf));
252b5132
RH
10210 if (iconf == NULL)
10211 {
10212 error (_("Out of memory"));
10213 return 0;
10214 }
10215
9ea033b2 10216 if (is_32bit_elf)
252b5132 10217 {
b34976b6 10218 Elf32_External_Conflict *econf32;
a6e9f9df 10219
d3ba0551
AM
10220 econf32 = get_data (NULL, file, conflicts_offset,
10221 conflictsno * sizeof (*econf32), _("conflict"));
a6e9f9df
AM
10222 if (!econf32)
10223 return 0;
252b5132
RH
10224
10225 for (cnt = 0; cnt < conflictsno; ++cnt)
10226 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
10227
10228 free (econf32);
252b5132
RH
10229 }
10230 else
10231 {
b34976b6 10232 Elf64_External_Conflict *econf64;
a6e9f9df 10233
d3ba0551
AM
10234 econf64 = get_data (NULL, file, conflicts_offset,
10235 conflictsno * sizeof (*econf64), _("conflict"));
a6e9f9df
AM
10236 if (!econf64)
10237 return 0;
252b5132
RH
10238
10239 for (cnt = 0; cnt < conflictsno; ++cnt)
10240 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
10241
10242 free (econf64);
252b5132
RH
10243 }
10244
c7e7ca54
NC
10245 printf (_("\nSection '.conflict' contains %lu entries:\n"),
10246 (unsigned long) conflictsno);
252b5132
RH
10247 puts (_(" Num: Index Value Name"));
10248
10249 for (cnt = 0; cnt < conflictsno; ++cnt)
10250 {
b34976b6 10251 Elf_Internal_Sym *psym = & dynamic_symbols[iconf[cnt]];
252b5132 10252
b34976b6 10253 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 10254 print_vma (psym->st_value, FULL_HEX);
31104126 10255 putchar (' ');
d79b3d50
NC
10256 if (VALID_DYNAMIC_NAME (psym->st_name))
10257 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
10258 else
10259 printf ("<corrupt: %14ld>", psym->st_name);
31104126 10260 putchar ('\n');
252b5132
RH
10261 }
10262
252b5132
RH
10263 free (iconf);
10264 }
10265
10266 return 1;
10267}
10268
047b2264 10269static int
d3ba0551 10270process_gnu_liblist (FILE *file)
047b2264 10271{
b34976b6
AM
10272 Elf_Internal_Shdr *section, *string_sec;
10273 Elf32_External_Lib *elib;
10274 char *strtab;
047b2264
JJ
10275 size_t cnt;
10276 unsigned i;
10277
10278 if (! do_arch)
10279 return 0;
10280
10281 for (i = 0, section = section_headers;
10282 i < elf_header.e_shnum;
b34976b6 10283 i++, section++)
047b2264
JJ
10284 {
10285 switch (section->sh_type)
10286 {
10287 case SHT_GNU_LIBLIST:
d3ba0551
AM
10288 elib = get_data (NULL, file, section->sh_offset, section->sh_size,
10289 _("liblist"));
047b2264
JJ
10290
10291 if (elib == NULL)
10292 break;
10293 string_sec = SECTION_HEADER (section->sh_link);
10294
d3ba0551
AM
10295 strtab = get_data (NULL, file, string_sec->sh_offset,
10296 string_sec->sh_size, _("liblist string table"));
047b2264
JJ
10297
10298 if (strtab == NULL
10299 || section->sh_entsize != sizeof (Elf32_External_Lib))
10300 {
10301 free (elib);
10302 break;
10303 }
10304
10305 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
10306 SECTION_NAME (section),
10307 (long) (section->sh_size / sizeof (Elf32_External_Lib)));
10308
10309 puts (" Library Time Stamp Checksum Version Flags");
10310
10311 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
10312 ++cnt)
10313 {
10314 Elf32_Lib liblist;
10315 time_t time;
10316 char timebuf[20];
b34976b6 10317 struct tm *tmp;
047b2264
JJ
10318
10319 liblist.l_name = BYTE_GET (elib[cnt].l_name);
10320 time = BYTE_GET (elib[cnt].l_time_stamp);
10321 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
10322 liblist.l_version = BYTE_GET (elib[cnt].l_version);
10323 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
10324
10325 tmp = gmtime (&time);
10326 sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
10327 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10328 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
10329
10330 printf ("%3lu: ", (unsigned long) cnt);
10331 if (do_wide)
10332 printf ("%-20s", strtab + liblist.l_name);
10333 else
10334 printf ("%-20.20s", strtab + liblist.l_name);
10335 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
10336 liblist.l_version, liblist.l_flags);
10337 }
10338
10339 free (elib);
10340 }
10341 }
10342
10343 return 1;
10344}
10345
9437c45b 10346static const char *
d3ba0551 10347get_note_type (unsigned e_type)
779fe533
NC
10348{
10349 static char buff[64];
103f02d3 10350
1ec5cd37
NC
10351 if (elf_header.e_type == ET_CORE)
10352 switch (e_type)
10353 {
10354 case NT_AUXV:
10355 return _("NT_AUXV (auxiliary vector)");
10356 case NT_PRSTATUS:
10357 return _("NT_PRSTATUS (prstatus structure)");
10358 case NT_FPREGSET:
10359 return _("NT_FPREGSET (floating point registers)");
10360 case NT_PRPSINFO:
10361 return _("NT_PRPSINFO (prpsinfo structure)");
10362 case NT_TASKSTRUCT:
10363 return _("NT_TASKSTRUCT (task structure)");
10364 case NT_PRXFPREG:
10365 return _("NT_PRXFPREG (user_xfpregs structure)");
10366 case NT_PSTATUS:
10367 return _("NT_PSTATUS (pstatus structure)");
10368 case NT_FPREGS:
10369 return _("NT_FPREGS (floating point registers)");
10370 case NT_PSINFO:
10371 return _("NT_PSINFO (psinfo structure)");
10372 case NT_LWPSTATUS:
10373 return _("NT_LWPSTATUS (lwpstatus_t structure)");
10374 case NT_LWPSINFO:
10375 return _("NT_LWPSINFO (lwpsinfo_t structure)");
10376 case NT_WIN32PSTATUS:
10377 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
10378 default:
10379 break;
10380 }
10381 else
10382 switch (e_type)
10383 {
10384 case NT_VERSION:
10385 return _("NT_VERSION (version)");
10386 case NT_ARCH:
10387 return _("NT_ARCH (architecture)");
10388 default:
10389 break;
10390 }
10391
10392 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
10393 return buff;
779fe533
NC
10394}
10395
9437c45b 10396static const char *
d3ba0551 10397get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
10398{
10399 static char buff[64];
10400
b4db1224 10401 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
10402 {
10403 /* NetBSD core "procinfo" structure. */
10404 return _("NetBSD procinfo structure");
10405 }
10406
10407 /* As of Jan 2002 there are no other machine-independent notes
10408 defined for NetBSD core files. If the note type is less
10409 than the start of the machine-dependent note types, we don't
10410 understand it. */
10411
b4db1224 10412 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b
JT
10413 {
10414 sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
10415 return buff;
10416 }
10417
10418 switch (elf_header.e_machine)
10419 {
10420 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
10421 and PT_GETFPREGS == mach+2. */
10422
10423 case EM_OLD_ALPHA:
10424 case EM_ALPHA:
10425 case EM_SPARC:
10426 case EM_SPARC32PLUS:
10427 case EM_SPARCV9:
10428 switch (e_type)
10429 {
b4db1224
JT
10430 case NT_NETBSDCORE_FIRSTMACH+0:
10431 return _("PT_GETREGS (reg structure)");
10432 case NT_NETBSDCORE_FIRSTMACH+2:
10433 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
10434 default:
10435 break;
10436 }
10437 break;
10438
10439 /* On all other arch's, PT_GETREGS == mach+1 and
10440 PT_GETFPREGS == mach+3. */
10441 default:
10442 switch (e_type)
10443 {
b4db1224
JT
10444 case NT_NETBSDCORE_FIRSTMACH+1:
10445 return _("PT_GETREGS (reg structure)");
10446 case NT_NETBSDCORE_FIRSTMACH+3:
10447 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
10448 default:
10449 break;
10450 }
10451 }
10452
b4db1224 10453 sprintf (buff, _("PT_FIRSTMACH+%d"), e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
10454 return buff;
10455}
10456
6d118b09
NC
10457/* Note that by the ELF standard, the name field is already null byte
10458 terminated, and namesz includes the terminating null byte.
10459 I.E. the value of namesz for the name "FSF" is 4.
10460
e3c8793a 10461 If the value of namesz is zero, there is no name present. */
779fe533 10462static int
d3ba0551 10463process_note (Elf_Internal_Note *pnote)
779fe533 10464{
9437c45b
JT
10465 const char *nt;
10466
10467 if (pnote->namesz == 0)
1ec5cd37
NC
10468 /* If there is no note name, then use the default set of
10469 note type strings. */
10470 nt = get_note_type (pnote->type);
10471
9437c45b 10472 else if (strncmp (pnote->namedata, "NetBSD-CORE", 11) == 0)
1ec5cd37
NC
10473 /* NetBSD-specific core file notes. */
10474 nt = get_netbsd_elfcore_note_type (pnote->type);
10475
9437c45b 10476 else
1ec5cd37
NC
10477 /* Don't recognize this note name; just use the default set of
10478 note type strings. */
9437c45b 10479 nt = get_note_type (pnote->type);
9437c45b 10480
103f02d3 10481 printf (" %s\t\t0x%08lx\t%s\n",
6d118b09 10482 pnote->namesz ? pnote->namedata : "(NONE)",
9437c45b 10483 pnote->descsz, nt);
779fe533
NC
10484 return 1;
10485}
10486
6d118b09 10487
779fe533 10488static int
d3ba0551 10489process_corefile_note_segment (FILE *file, bfd_vma offset, bfd_vma length)
779fe533 10490{
b34976b6
AM
10491 Elf_External_Note *pnotes;
10492 Elf_External_Note *external;
10493 int res = 1;
103f02d3 10494
779fe533
NC
10495 if (length <= 0)
10496 return 0;
103f02d3 10497
d3ba0551 10498 pnotes = get_data (NULL, file, offset, length, _("notes"));
a6e9f9df
AM
10499 if (!pnotes)
10500 return 0;
779fe533 10501
103f02d3 10502 external = pnotes;
103f02d3 10503
305c7206 10504 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 10505 (unsigned long) offset, (unsigned long) length);
779fe533 10506 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 10507
6d118b09 10508 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 10509 {
b34976b6
AM
10510 Elf_External_Note *next;
10511 Elf_Internal_Note inote;
10512 char *temp = NULL;
6d118b09
NC
10513
10514 inote.type = BYTE_GET (external->type);
10515 inote.namesz = BYTE_GET (external->namesz);
10516 inote.namedata = external->name;
10517 inote.descsz = BYTE_GET (external->descsz);
10518 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
10519 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 10520
3e55a963
NC
10521 next = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
10522
10523 if (((char *) next) > (((char *) pnotes) + length))
10524 {
10525 warn (_("corrupt note found at offset %x into core notes\n"),
10526 ((char *) external) - ((char *) pnotes));
10527 warn (_(" type: %x, namesize: %08lx, descsize: %08lx\n"),
10528 inote.type, inote.namesz, inote.descsz);
10529 break;
10530 }
10531
10532 external = next;
6d118b09
NC
10533
10534 /* Verify that name is null terminated. It appears that at least
10535 one version of Linux (RedHat 6.0) generates corefiles that don't
10536 comply with the ELF spec by failing to include the null byte in
10537 namesz. */
10538 if (inote.namedata[inote.namesz] != '\0')
10539 {
10540 temp = malloc (inote.namesz + 1);
76da6bbe 10541
6d118b09
NC
10542 if (temp == NULL)
10543 {
10544 error (_("Out of memory\n"));
10545 res = 0;
10546 break;
10547 }
76da6bbe 10548
6d118b09
NC
10549 strncpy (temp, inote.namedata, inote.namesz);
10550 temp[inote.namesz] = 0;
76da6bbe 10551
6d118b09
NC
10552 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
10553 inote.namedata = temp;
10554 }
10555
10556 res &= process_note (& inote);
103f02d3 10557
6d118b09
NC
10558 if (temp != NULL)
10559 {
10560 free (temp);
10561 temp = NULL;
10562 }
779fe533
NC
10563 }
10564
10565 free (pnotes);
103f02d3 10566
779fe533
NC
10567 return res;
10568}
10569
10570static int
d3ba0551 10571process_corefile_note_segments (FILE *file)
779fe533 10572{
b34976b6
AM
10573 Elf_Internal_Phdr *segment;
10574 unsigned int i;
10575 int res = 1;
103f02d3 10576
d93f0186 10577 if (! get_program_headers (file))
779fe533 10578 return 0;
103f02d3 10579
779fe533
NC
10580 for (i = 0, segment = program_headers;
10581 i < elf_header.e_phnum;
b34976b6 10582 i++, segment++)
779fe533
NC
10583 {
10584 if (segment->p_type == PT_NOTE)
103f02d3 10585 res &= process_corefile_note_segment (file,
30800947
NC
10586 (bfd_vma) segment->p_offset,
10587 (bfd_vma) segment->p_filesz);
779fe533 10588 }
103f02d3 10589
779fe533
NC
10590 return res;
10591}
10592
10593static int
1ec5cd37
NC
10594process_note_sections (FILE *file)
10595{
10596 Elf_Internal_Shdr *section;
10597 unsigned long i;
10598 int res = 1;
10599
10600 for (i = 0, section = section_headers;
10601 i < elf_header.e_shnum;
10602 i++, section++)
10603 if (section->sh_type == SHT_NOTE)
10604 res &= process_corefile_note_segment (file,
10605 (bfd_vma) section->sh_offset,
10606 (bfd_vma) section->sh_size);
10607
10608 return res;
10609}
10610
10611static int
10612process_notes (FILE *file)
779fe533
NC
10613{
10614 /* If we have not been asked to display the notes then do nothing. */
10615 if (! do_notes)
10616 return 1;
103f02d3 10617
779fe533 10618 if (elf_header.e_type != ET_CORE)
1ec5cd37 10619 return process_note_sections (file);
103f02d3 10620
779fe533 10621 /* No program headers means no NOTE segment. */
1ec5cd37
NC
10622 if (elf_header.e_phnum > 0)
10623 return process_corefile_note_segments (file);
779fe533 10624
1ec5cd37
NC
10625 printf (_("No note segments present in the core file.\n"));
10626 return 1;
779fe533
NC
10627}
10628
252b5132 10629static int
d3ba0551 10630process_arch_specific (FILE *file)
252b5132 10631{
a952a375
NC
10632 if (! do_arch)
10633 return 1;
10634
252b5132
RH
10635 switch (elf_header.e_machine)
10636 {
10637 case EM_MIPS:
4fe85591 10638 case EM_MIPS_RS3_LE:
252b5132
RH
10639 return process_mips_specific (file);
10640 break;
10641 default:
10642 break;
10643 }
10644 return 1;
10645}
10646
10647static int
d3ba0551 10648get_file_header (FILE *file)
252b5132 10649{
9ea033b2
NC
10650 /* Read in the identity array. */
10651 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
10652 return 0;
10653
9ea033b2 10654 /* Determine how to read the rest of the header. */
b34976b6 10655 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
10656 {
10657 default: /* fall through */
10658 case ELFDATANONE: /* fall through */
adab8cdc
AO
10659 case ELFDATA2LSB:
10660 byte_get = byte_get_little_endian;
10661 byte_put = byte_put_little_endian;
10662 break;
10663 case ELFDATA2MSB:
10664 byte_get = byte_get_big_endian;
10665 byte_put = byte_put_big_endian;
10666 break;
9ea033b2
NC
10667 }
10668
10669 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 10670 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
10671
10672 /* Read in the rest of the header. */
10673 if (is_32bit_elf)
10674 {
10675 Elf32_External_Ehdr ehdr32;
252b5132 10676
9ea033b2
NC
10677 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
10678 return 0;
103f02d3 10679
9ea033b2
NC
10680 elf_header.e_type = BYTE_GET (ehdr32.e_type);
10681 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
10682 elf_header.e_version = BYTE_GET (ehdr32.e_version);
10683 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
10684 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
10685 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
10686 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
10687 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
10688 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
10689 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
10690 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
10691 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
10692 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
10693 }
252b5132 10694 else
9ea033b2
NC
10695 {
10696 Elf64_External_Ehdr ehdr64;
a952a375
NC
10697
10698 /* If we have been compiled with sizeof (bfd_vma) == 4, then
10699 we will not be able to cope with the 64bit data found in
10700 64 ELF files. Detect this now and abort before we start
50c2245b 10701 overwriting things. */
a952a375
NC
10702 if (sizeof (bfd_vma) < 8)
10703 {
e3c8793a
NC
10704 error (_("This instance of readelf has been built without support for a\n\
1070564 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
10706 return 0;
10707 }
103f02d3 10708
9ea033b2
NC
10709 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
10710 return 0;
103f02d3 10711
9ea033b2
NC
10712 elf_header.e_type = BYTE_GET (ehdr64.e_type);
10713 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
10714 elf_header.e_version = BYTE_GET (ehdr64.e_version);
10715 elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry);
10716 elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff);
10717 elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff);
10718 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
10719 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
10720 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
10721 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
10722 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
10723 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
10724 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
10725 }
252b5132 10726
7ece0d85
JJ
10727 if (elf_header.e_shoff)
10728 {
10729 /* There may be some extensions in the first section header. Don't
10730 bomb if we can't read it. */
10731 if (is_32bit_elf)
10732 get_32bit_section_headers (file, 1);
10733 else
10734 get_64bit_section_headers (file, 1);
10735 }
560f3c1c 10736
252b5132
RH
10737 return 1;
10738}
10739
fb52b2f4
NC
10740/* Process one ELF object file according to the command line options.
10741 This file may actually be stored in an archive. The file is
10742 positioned at the start of the ELF object. */
10743
ff78d6d6 10744static int
fb52b2f4 10745process_object (char *file_name, FILE *file)
252b5132 10746{
252b5132
RH
10747 unsigned int i;
10748
252b5132
RH
10749 if (! get_file_header (file))
10750 {
10751 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 10752 return 1;
252b5132
RH
10753 }
10754
10755 /* Initialise per file variables. */
10756 for (i = NUM_ELEM (version_info); i--;)
10757 version_info[i] = 0;
10758
10759 for (i = NUM_ELEM (dynamic_info); i--;)
10760 dynamic_info[i] = 0;
10761
10762 /* Process the file. */
10763 if (show_name)
10764 printf (_("\nFile: %s\n"), file_name);
10765
10766 if (! process_file_header ())
fb52b2f4 10767 return 1;
252b5132 10768
e4b17d5c
L
10769 if (! process_section_headers (file)
10770 || ! process_section_groups (file))
2f62977e 10771 {
e4b17d5c 10772 /* Without loaded section headers and section groups we
2f62977e
NC
10773 cannot process lots of things. */
10774 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 10775
2f62977e
NC
10776 if (! do_using_dynamic)
10777 do_syms = do_reloc = 0;
10778 }
252b5132 10779
2f62977e 10780 if (process_program_headers (file))
b2d38a17 10781 process_dynamic_section (file);
252b5132
RH
10782
10783 process_relocs (file);
10784
4d6ed7c8
NC
10785 process_unwind (file);
10786
252b5132
RH
10787 process_symbol_table (file);
10788
10789 process_syminfo (file);
10790
10791 process_version_sections (file);
10792
10793 process_section_contents (file);
f5842774 10794
1ec5cd37 10795 process_notes (file);
103f02d3 10796
047b2264
JJ
10797 process_gnu_liblist (file);
10798
252b5132
RH
10799 process_arch_specific (file);
10800
d93f0186
NC
10801 if (program_headers)
10802 {
10803 free (program_headers);
10804 program_headers = NULL;
10805 }
10806
252b5132
RH
10807 if (section_headers)
10808 {
10809 free (section_headers);
10810 section_headers = NULL;
10811 }
10812
10813 if (string_table)
10814 {
10815 free (string_table);
10816 string_table = NULL;
d40ac9bd 10817 string_table_length = 0;
252b5132
RH
10818 }
10819
10820 if (dynamic_strings)
10821 {
10822 free (dynamic_strings);
10823 dynamic_strings = NULL;
d79b3d50 10824 dynamic_strings_length = 0;
252b5132
RH
10825 }
10826
10827 if (dynamic_symbols)
10828 {
10829 free (dynamic_symbols);
10830 dynamic_symbols = NULL;
19936277 10831 num_dynamic_syms = 0;
252b5132
RH
10832 }
10833
10834 if (dynamic_syminfo)
10835 {
10836 free (dynamic_syminfo);
10837 dynamic_syminfo = NULL;
10838 }
ff78d6d6 10839
e4b17d5c
L
10840 if (section_headers_groups)
10841 {
10842 free (section_headers_groups);
10843 section_headers_groups = NULL;
10844 }
10845
10846 if (section_groups)
10847 {
10848 struct group_list *g, *next;
10849
10850 for (i = 0; i < group_count; i++)
10851 {
10852 for (g = section_groups [i].root; g != NULL; g = next)
10853 {
10854 next = g->next;
10855 free (g);
10856 }
10857 }
10858
10859 free (section_groups);
10860 section_groups = NULL;
10861 }
10862
ff78d6d6 10863 return 0;
252b5132
RH
10864}
10865
fb52b2f4
NC
10866/* Process an ELF archive. The file is positioned just after the
10867 ARMAG string. */
10868
10869static int
10870process_archive (char *file_name, FILE *file)
10871{
10872 struct ar_hdr arhdr;
10873 size_t got;
10874 unsigned long size;
10875 char *longnames = NULL;
10876 unsigned long longnames_size = 0;
10877 size_t file_name_size;
d989285c 10878 int ret;
fb52b2f4
NC
10879
10880 show_name = 1;
10881
10882 got = fread (&arhdr, 1, sizeof arhdr, file);
10883 if (got != sizeof arhdr)
10884 {
10885 if (got == 0)
10886 return 0;
10887
10888 error (_("%s: failed to read archive header\n"), file_name);
10889 return 1;
10890 }
10891
10892 if (memcmp (arhdr.ar_name, "/ ", 16) == 0)
10893 {
10894 /* This is the archive symbol table. Skip it.
10895 FIXME: We should have an option to dump it. */
10896 size = strtoul (arhdr.ar_size, NULL, 10);
10897 if (fseek (file, size + (size & 1), SEEK_CUR) != 0)
10898 {
10899 error (_("%s: failed to skip archive symbol table\n"), file_name);
10900 return 1;
10901 }
10902
10903 got = fread (&arhdr, 1, sizeof arhdr, file);
10904 if (got != sizeof arhdr)
10905 {
10906 if (got == 0)
10907 return 0;
10908
10909 error (_("%s: failed to read archive header\n"), file_name);
10910 return 1;
10911 }
10912 }
10913
10914 if (memcmp (arhdr.ar_name, "// ", 16) == 0)
10915 {
10916 /* This is the archive string table holding long member
10917 names. */
10918
10919 longnames_size = strtoul (arhdr.ar_size, NULL, 10);
10920
10921 longnames = malloc (longnames_size);
10922 if (longnames == NULL)
10923 {
10924 error (_("Out of memory\n"));
10925 return 1;
10926 }
10927
10928 if (fread (longnames, longnames_size, 1, file) != 1)
10929 {
d989285c 10930 free (longnames);
fb52b2f4
NC
10931 error(_("%s: failed to read string table\n"), file_name);
10932 return 1;
10933 }
10934
10935 if ((longnames_size & 1) != 0)
10936 getc (file);
10937
10938 got = fread (&arhdr, 1, sizeof arhdr, file);
10939 if (got != sizeof arhdr)
10940 {
d989285c
ILT
10941 free (longnames);
10942
fb52b2f4
NC
10943 if (got == 0)
10944 return 0;
10945
10946 error (_("%s: failed to read archive header\n"), file_name);
10947 return 1;
10948 }
10949 }
10950
10951 file_name_size = strlen (file_name);
d989285c 10952 ret = 0;
fb52b2f4
NC
10953
10954 while (1)
10955 {
10956 char *name;
10957 char *nameend;
10958 char *namealc;
10959
10960 if (arhdr.ar_name[0] == '/')
10961 {
10962 unsigned long off;
10963
10964 off = strtoul (arhdr.ar_name + 1, NULL, 10);
10965 if (off >= longnames_size)
10966 {
10967 error (_("%s: invalid archive string table offset %lu\n"), off);
d989285c
ILT
10968 ret = 1;
10969 break;
fb52b2f4
NC
10970 }
10971
10972 name = longnames + off;
10973 nameend = memchr (name, '/', longnames_size - off);
10974 }
10975 else
10976 {
10977 name = arhdr.ar_name;
10978 nameend = memchr (name, '/', 16);
10979 }
10980
10981 if (nameend == NULL)
10982 {
10983 error (_("%s: bad archive file name\n"));
d989285c
ILT
10984 ret = 1;
10985 break;
fb52b2f4
NC
10986 }
10987
10988 namealc = malloc (file_name_size + (nameend - name) + 3);
10989 if (namealc == NULL)
10990 {
10991 error (_("Out of memory\n"));
d989285c
ILT
10992 ret = 1;
10993 break;
fb52b2f4
NC
10994 }
10995
10996 memcpy (namealc, file_name, file_name_size);
10997 namealc[file_name_size] = '(';
10998 memcpy (namealc + file_name_size + 1, name, nameend - name);
10999 namealc[file_name_size + 1 + (nameend - name)] = ')';
11000 namealc[file_name_size + 2 + (nameend - name)] = '\0';
11001
11002 archive_file_offset = ftell (file);
11003 archive_file_size = strtoul (arhdr.ar_size, NULL, 10);
11004
d989285c 11005 ret |= process_object (namealc, file);
fb52b2f4
NC
11006
11007 free (namealc);
11008
11009 if (fseek (file,
11010 (archive_file_offset
11011 + archive_file_size
11012 + (archive_file_size & 1)),
11013 SEEK_SET) != 0)
11014 {
11015 error (_("%s: failed to seek to next archive header\n"), file_name);
d989285c
ILT
11016 ret = 1;
11017 break;
fb52b2f4
NC
11018 }
11019
11020 got = fread (&arhdr, 1, sizeof arhdr, file);
11021 if (got != sizeof arhdr)
11022 {
11023 if (got == 0)
d989285c 11024 break;
fb52b2f4
NC
11025
11026 error (_("%s: failed to read archive header\n"), file_name);
d989285c
ILT
11027 ret = 1;
11028 break;
fb52b2f4
NC
11029 }
11030 }
11031
11032 if (longnames != 0)
11033 free (longnames);
11034
d989285c 11035 return ret;
fb52b2f4
NC
11036}
11037
11038static int
11039process_file (char *file_name)
11040{
11041 FILE *file;
11042 struct stat statbuf;
11043 char armag[SARMAG];
11044 int ret;
11045
11046 if (stat (file_name, &statbuf) < 0)
11047 {
f24ddbdd
NC
11048 if (errno == ENOENT)
11049 error (_("'%s': No such file\n"), file_name);
11050 else
11051 error (_("Could not locate '%s'. System error message: %s\n"),
11052 file_name, strerror (errno));
11053 return 1;
11054 }
11055
11056 if (! S_ISREG (statbuf.st_mode))
11057 {
11058 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
11059 return 1;
11060 }
11061
11062 file = fopen (file_name, "rb");
11063 if (file == NULL)
11064 {
f24ddbdd 11065 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
11066 return 1;
11067 }
11068
11069 if (fread (armag, SARMAG, 1, file) != 1)
11070 {
11071 error (_("%s: Failed to read file header\n"), file_name);
11072 fclose (file);
11073 return 1;
11074 }
11075
11076 if (memcmp (armag, ARMAG, SARMAG) == 0)
11077 ret = process_archive (file_name, file);
11078 else
11079 {
11080 rewind (file);
11081 archive_file_size = archive_file_offset = 0;
11082 ret = process_object (file_name, file);
11083 }
11084
11085 fclose (file);
11086
11087 return ret;
11088}
11089
252b5132
RH
11090#ifdef SUPPORT_DISASSEMBLY
11091/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 11092 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 11093 symbols. */
252b5132
RH
11094
11095void
b34976b6 11096print_address (unsigned int addr, FILE *outfile)
252b5132
RH
11097{
11098 fprintf (outfile,"0x%8.8x", addr);
11099}
11100
e3c8793a 11101/* Needed by the i386 disassembler. */
252b5132
RH
11102void
11103db_task_printsym (unsigned int addr)
11104{
11105 print_address (addr, stderr);
11106}
11107#endif
11108
11109int
d3ba0551 11110main (int argc, char **argv)
252b5132 11111{
ff78d6d6 11112 int err;
59f14fc0
AS
11113 char *cmdline_dump_sects = NULL;
11114 unsigned num_cmdline_dump_sects = 0;
ff78d6d6 11115
252b5132
RH
11116#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
11117 setlocale (LC_MESSAGES, "");
3882b010
L
11118#endif
11119#if defined (HAVE_SETLOCALE)
11120 setlocale (LC_CTYPE, "");
252b5132
RH
11121#endif
11122 bindtextdomain (PACKAGE, LOCALEDIR);
11123 textdomain (PACKAGE);
11124
11125 parse_args (argc, argv);
11126
11127 if (optind < (argc - 1))
11128 show_name = 1;
11129
59f14fc0
AS
11130 /* When processing more than one file remember the dump requests
11131 issued on command line to reset them after each file. */
11132 if (optind + 1 < argc && dump_sects != NULL)
11133 {
11134 cmdline_dump_sects = malloc (num_dump_sects);
11135 if (cmdline_dump_sects == NULL)
11136 error (_("Out of memory allocating dump request table."));
11137 else
11138 {
11139 memcpy (cmdline_dump_sects, dump_sects, num_dump_sects);
11140 num_cmdline_dump_sects = num_dump_sects;
11141 }
11142 }
11143
ff78d6d6 11144 err = 0;
252b5132 11145 while (optind < argc)
59f14fc0
AS
11146 {
11147 err |= process_file (argv[optind++]);
11148
11149 /* Reset dump requests. */
11150 if (optind < argc && dump_sects != NULL)
11151 {
11152 num_dump_sects = num_cmdline_dump_sects;
11153 if (num_cmdline_dump_sects > 0)
11154 memcpy (dump_sects, cmdline_dump_sects, num_cmdline_dump_sects);
11155 }
11156 }
252b5132
RH
11157
11158 if (dump_sects != NULL)
11159 free (dump_sects);
59f14fc0
AS
11160 if (cmdline_dump_sects != NULL)
11161 free (cmdline_dump_sects);
252b5132 11162
ff78d6d6 11163 return err;
252b5132 11164}