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