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