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