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