]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
* m68hc11-tdep.c (m68hc11_pseudo_register_write): Use gdb_byte
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
5b18a4bc 2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
74013231 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
b43b5d5f
NC
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
23 02110-1301, USA. */
252b5132 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
19e6b90e 58#include "dwarf.h"
252b5132
RH
59
60#include "elf/common.h"
61#include "elf/external.h"
62#include "elf/internal.h"
252b5132
RH
63
64/* The following headers use the elf/reloc-macros.h file to
65 automatically generate relocation recognition functions
66 such as elf_mips_reloc_type() */
67
68#define RELOC_MACROS_GEN_FUNC
69
252b5132 70#include "elf/alpha.h"
3b16e843 71#include "elf/arc.h"
252b5132 72#include "elf/arm.h"
3b16e843 73#include "elf/avr.h"
1d65ded4 74#include "elf/bfin.h"
3b16e843 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"
49f58d10 89#include "elf/m32c.h"
3b16e843
NC
90#include "elf/m32r.h"
91#include "elf/m68k.h"
75751cd9 92#include "elf/m68hc11.h"
252b5132 93#include "elf/mcore.h"
3b16e843 94#include "elf/mips.h"
3c3bdf30 95#include "elf/mmix.h"
3b16e843
NC
96#include "elf/mn10200.h"
97#include "elf/mn10300.h"
1ae72221 98#include "elf/ms1.h"
2469cfa2 99#include "elf/msp430.h"
3b16e843 100#include "elf/or32.h"
7d466069 101#include "elf/pj.h"
3b16e843 102#include "elf/ppc.h"
c833c019 103#include "elf/ppc64.h"
a85d7ed0 104#include "elf/s390.h"
3b16e843
NC
105#include "elf/sh.h"
106#include "elf/sparc.h"
107#include "elf/v850.h"
179d3252 108#include "elf/vax.h"
3b16e843 109#include "elf/x86-64.h"
93fbbb04 110#include "elf/xstormy16.h"
1fe1f39c 111#include "elf/crx.h"
3b36097d 112#include "elf/iq2000.h"
88da6820 113#include "elf/xtensa.h"
252b5132 114
fb52b2f4
NC
115#include "aout/ar.h"
116
252b5132
RH
117#include "bucomm.h"
118#include "getopt.h"
566b0d53 119#include "libiberty.h"
252b5132 120
b34976b6 121char *program_name = "readelf";
85b1c36d
BE
122static long archive_file_offset;
123static unsigned long archive_file_size;
124static unsigned long dynamic_addr;
125static bfd_size_type dynamic_size;
126static unsigned int dynamic_nent;
127static char *dynamic_strings;
128static unsigned long dynamic_strings_length;
129static char *string_table;
130static unsigned long string_table_length;
131static unsigned long num_dynamic_syms;
132static Elf_Internal_Sym *dynamic_symbols;
133static Elf_Internal_Syminfo *dynamic_syminfo;
134static unsigned long dynamic_syminfo_offset;
135static unsigned int dynamic_syminfo_nent;
136static char program_interpreter[64];
137static bfd_vma dynamic_info[DT_JMPREL + 1];
138static bfd_vma version_info[16];
139static Elf_Internal_Ehdr elf_header;
140static Elf_Internal_Shdr *section_headers;
141static Elf_Internal_Phdr *program_headers;
142static Elf_Internal_Dyn *dynamic_section;
143static Elf_Internal_Shdr *symtab_shndx_hdr;
144static int show_name;
145static int do_dynamic;
146static int do_syms;
147static int do_reloc;
148static int do_sections;
149static int do_section_groups;
5477e8a0 150static int do_section_details;
85b1c36d
BE
151static int do_segments;
152static int do_unwind;
153static int do_using_dynamic;
154static int do_header;
155static int do_dump;
156static int do_version;
157static int do_wide;
158static int do_histogram;
159static int do_debugging;
85b1c36d
BE
160static int do_arch;
161static int do_notes;
162static int is_32bit_elf;
252b5132 163
e4b17d5c
L
164struct group_list
165{
166 struct group_list *next;
167 unsigned int section_index;
168};
169
170struct group
171{
172 struct group_list *root;
173 unsigned int group_index;
174};
175
85b1c36d
BE
176static size_t group_count;
177static struct group *section_groups;
178static struct group **section_headers_groups;
e4b17d5c 179
18bd398b
NC
180/* A dynamic array of flags indicating for which sections a hex dump
181 has been requested (via the -x switch) and/or a disassembly dump
182 (via the -i switch). */
183char *cmdline_dump_sects = NULL;
184unsigned num_cmdline_dump_sects = 0;
185
186/* A dynamic array of flags indicating for which sections a dump of
187 some kind has been requested. It is reset on a per-object file
188 basis and then initialised from the cmdline_dump_sects array and
189 the results of interpreting the -w switch. */
b34976b6
AM
190char *dump_sects = NULL;
191unsigned int num_dump_sects = 0;
252b5132
RH
192
193#define HEX_DUMP (1 << 0)
194#define DISASS_DUMP (1 << 1)
195#define DEBUG_DUMP (1 << 2)
196
c256ffe7 197/* How to print a vma value. */
843dd992
NC
198typedef enum print_mode
199{
200 HEX,
201 DEC,
202 DEC_5,
203 UNSIGNED,
204 PREFIX_HEX,
205 FULL_HEX,
206 LONG_HEX
207}
208print_mode;
209
d3ba0551 210static void (*byte_put) (unsigned char *, bfd_vma, int);
252b5132 211
9c19a809
NC
212#define UNKNOWN -1
213
7036c0e1 214#define SECTION_NAME(X) ((X) == NULL ? "<none>" : \
18bd398b
NC
215 ((X)->sh_name >= string_table_length \
216 ? "<corrupt>" : string_table + (X)->sh_name))
252b5132 217
9ad5cbcf
AM
218/* Given st_shndx I, map to section_headers index. */
219#define SECTION_HEADER_INDEX(I) \
220 ((I) < SHN_LORESERVE \
221 ? (I) \
222 : ((I) <= SHN_HIRESERVE \
223 ? 0 \
224 : (I) - (SHN_HIRESERVE + 1 - SHN_LORESERVE)))
225
226/* Reverse of the above. */
227#define SECTION_HEADER_NUM(N) \
228 ((N) < SHN_LORESERVE \
229 ? (N) \
230 : (N) + (SHN_HIRESERVE + 1 - SHN_LORESERVE))
231
232#define SECTION_HEADER(I) (section_headers + SECTION_HEADER_INDEX (I))
233
ee42cf8c 234#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 235
7036c0e1 236#define BYTE_GET(field) byte_get (field, sizeof (field))
a952a375 237
261a45ad 238#define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
252b5132 239
9ad5cbcf
AM
240#define GET_ELF_SYMBOLS(file, section) \
241 (is_32bit_elf ? get_32bit_elf_symbols (file, section) \
242 : get_64bit_elf_symbols (file, section))
9ea033b2 243
d79b3d50
NC
244#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
245/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
246 already been called and verified that the string exists. */
247#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b
NC
248
249/* This is just a bit of syntatic sugar. */
250#define streq(a,b) (strcmp ((a), (b)) == 0)
251#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
d79b3d50 252\f
c256ffe7
JJ
253static void *
254get_data (void *var, FILE *file, long offset, size_t size, size_t nmemb,
255 const char *reason)
a6e9f9df 256{
d3ba0551 257 void *mvar;
a6e9f9df 258
c256ffe7 259 if (size == 0 || nmemb == 0)
a6e9f9df
AM
260 return NULL;
261
fb52b2f4 262 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 263 {
0fd3a477 264 error (_("Unable to seek to 0x%lx for %s\n"),
fb52b2f4 265 archive_file_offset + offset, reason);
a6e9f9df
AM
266 return NULL;
267 }
268
269 mvar = var;
270 if (mvar == NULL)
271 {
c256ffe7
JJ
272 /* Check for overflow. */
273 if (nmemb < (~(size_t) 0 - 1) / size)
274 /* + 1 so that we can '\0' terminate invalid string table sections. */
275 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
276
277 if (mvar == NULL)
278 {
0fd3a477
JW
279 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
280 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
281 return NULL;
282 }
c256ffe7
JJ
283
284 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
285 }
286
c256ffe7 287 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 288 {
0fd3a477
JW
289 error (_("Unable to read in 0x%lx bytes of %s\n"),
290 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
291 if (mvar != var)
292 free (mvar);
293 return NULL;
294 }
295
296 return mvar;
297}
298
adab8cdc 299static void
d3ba0551 300byte_put_little_endian (unsigned char *field, bfd_vma value, int size)
adab8cdc
AO
301{
302 switch (size)
303 {
304 case 8:
305 field[7] = (((value >> 24) >> 24) >> 8) & 0xff;
306 field[6] = ((value >> 24) >> 24) & 0xff;
307 field[5] = ((value >> 24) >> 16) & 0xff;
308 field[4] = ((value >> 24) >> 8) & 0xff;
309 /* Fall through. */
310 case 4:
311 field[3] = (value >> 24) & 0xff;
312 field[2] = (value >> 16) & 0xff;
313 /* Fall through. */
314 case 2:
315 field[1] = (value >> 8) & 0xff;
316 /* Fall through. */
317 case 1:
318 field[0] = value & 0xff;
319 break;
320
321 default:
322 error (_("Unhandled data length: %d\n"), size);
323 abort ();
324 }
325}
326
66543521
AM
327#if defined BFD64 && !BFD_HOST_64BIT_LONG
328static int
329print_dec_vma (bfd_vma vma, int is_signed)
330{
331 char buf[40];
332 char *bufp = buf;
333 int nc = 0;
334
335 if (is_signed && (bfd_signed_vma) vma < 0)
336 {
337 vma = -vma;
338 putchar ('-');
339 nc = 1;
340 }
341
342 do
343 {
344 *bufp++ = '0' + vma % 10;
345 vma /= 10;
346 }
347 while (vma != 0);
348 nc += bufp - buf;
349
350 while (bufp > buf)
351 putchar (*--bufp);
352 return nc;
353}
354
355static int
356print_hex_vma (bfd_vma vma)
357{
358 char buf[32];
359 char *bufp = buf;
360 int nc;
361
362 do
363 {
364 char digit = '0' + (vma & 0x0f);
365 if (digit > '9')
366 digit += 'a' - '0' - 10;
367 *bufp++ = digit;
368 vma >>= 4;
369 }
370 while (vma != 0);
371 nc = bufp - buf;
372
373 while (bufp > buf)
374 putchar (*--bufp);
375 return nc;
376}
377#endif
378
f7a99963 379/* Print a VMA value. */
66543521 380static int
d3ba0551 381print_vma (bfd_vma vma, print_mode mode)
f7a99963
NC
382{
383#ifdef BFD64
384 if (is_32bit_elf)
385#endif
386 {
387 switch (mode)
388 {
b19aac67 389 case FULL_HEX:
66543521
AM
390 return printf ("0x%8.8lx", (unsigned long) vma);
391
b19aac67 392 case LONG_HEX:
66543521 393 return printf ("%8.8lx", (unsigned long) vma);
b19aac67
NC
394
395 case DEC_5:
396 if (vma <= 99999)
66543521 397 return printf ("%5ld", (long) vma);
b19aac67 398 /* Drop through. */
66543521 399
b19aac67 400 case PREFIX_HEX:
66543521
AM
401 return printf ("0x%lx", (unsigned long) vma);
402
b19aac67 403 case HEX:
66543521 404 return printf ("%lx", (unsigned long) vma);
b19aac67
NC
405
406 case DEC:
66543521 407 return printf ("%ld", (unsigned long) vma);
b19aac67
NC
408
409 case UNSIGNED:
66543521 410 return printf ("%lu", (unsigned long) vma);
f7a99963
NC
411 }
412 }
413#ifdef BFD64
414 else
415 {
66543521
AM
416 int nc = 0;
417
f7a99963
NC
418 switch (mode)
419 {
420 case FULL_HEX:
66543521 421 nc = printf ("0x");
b19aac67 422 /* Drop through. */
76da6bbe 423
f7a99963
NC
424 case LONG_HEX:
425 printf_vma (vma);
66543521 426 return nc + 16;
76da6bbe 427
f7a99963 428 case PREFIX_HEX:
66543521 429 nc = printf ("0x");
b19aac67 430 /* Drop through. */
76da6bbe 431
f7a99963
NC
432 case HEX:
433#if BFD_HOST_64BIT_LONG
66543521 434 return nc + printf ("%lx", vma);
f7a99963 435#else
66543521 436 return nc + print_hex_vma (vma);
f7a99963 437#endif
f7a99963
NC
438
439 case DEC:
2f528887 440#if BFD_HOST_64BIT_LONG
66543521 441 return printf ("%ld", vma);
2f528887 442#else
66543521 443 return print_dec_vma (vma, 1);
76da6bbe 444#endif
f7a99963
NC
445
446 case DEC_5:
2f528887 447#if BFD_HOST_64BIT_LONG
b19aac67 448 if (vma <= 99999)
66543521 449 return printf ("%5ld", vma);
b19aac67 450 else
66543521 451 return printf ("%#lx", vma);
2f528887 452#else
66543521
AM
453 if (vma <= 99999)
454 return printf ("%5ld", _bfd_int64_low (vma));
b19aac67 455 else
66543521 456 return print_hex_vma (vma);
76da6bbe 457#endif
76da6bbe 458
f7a99963 459 case UNSIGNED:
2f528887 460#if BFD_HOST_64BIT_LONG
66543521 461 return printf ("%lu", vma);
76da6bbe 462#else
66543521 463 return print_dec_vma (vma, 0);
2f528887 464#endif
f7a99963
NC
465 }
466 }
467#endif
66543521 468 return 0;
f7a99963
NC
469}
470
31104126
NC
471/* Display a symbol on stdout. If do_wide is not true then
472 format the symbol to be at most WIDTH characters,
047b2264 473 truncating as necessary. If WIDTH is negative then
31104126
NC
474 format the string to be exactly - WIDTH characters,
475 truncating or padding as necessary. */
476
477static void
d3ba0551 478print_symbol (int width, const char *symbol)
31104126
NC
479{
480 if (do_wide)
f1ef08cb 481 printf ("%s", symbol);
31104126
NC
482 else if (width < 0)
483 printf ("%-*.*s", width, width, symbol);
53c7db4b 484 else
31104126
NC
485 printf ("%-.*s", width, symbol);
486}
487
adab8cdc 488static void
d3ba0551 489byte_put_big_endian (unsigned char *field, bfd_vma value, int size)
adab8cdc
AO
490{
491 switch (size)
492 {
493 case 8:
494 field[7] = value & 0xff;
495 field[6] = (value >> 8) & 0xff;
496 field[5] = (value >> 16) & 0xff;
497 field[4] = (value >> 24) & 0xff;
498 value >>= 16;
499 value >>= 16;
500 /* Fall through. */
501 case 4:
502 field[3] = value & 0xff;
503 field[2] = (value >> 8) & 0xff;
504 value >>= 16;
505 /* Fall through. */
506 case 2:
507 field[1] = value & 0xff;
508 value >>= 8;
509 /* Fall through. */
510 case 1:
511 field[0] = value & 0xff;
512 break;
513
514 default:
515 error (_("Unhandled data length: %d\n"), size);
516 abort ();
517 }
518}
519
89fac5e3
RS
520/* Return a pointer to section NAME, or NULL if no such section exists. */
521
522static Elf_Internal_Shdr *
523find_section (const char *name)
524{
525 unsigned int i;
526
527 for (i = 0; i < elf_header.e_shnum; i++)
528 if (streq (SECTION_NAME (section_headers + i), name))
529 return section_headers + i;
530
531 return NULL;
532}
533
bcedfee6 534/* Guess the relocation size commonly used by the specific machines. */
252b5132 535
252b5132 536static int
d3ba0551 537guess_is_rela (unsigned long e_machine)
252b5132 538{
9c19a809 539 switch (e_machine)
252b5132
RH
540 {
541 /* Targets that use REL relocations. */
542 case EM_ARM:
543 case EM_386:
544 case EM_486:
63fcb9e9 545 case EM_960:
d172d4ba 546 case EM_DLX:
3b16e843
NC
547 case EM_OPENRISC:
548 case EM_OR32:
252b5132 549 case EM_CYGNUS_M32R:
2b0337b0 550 case EM_D10V:
252b5132
RH
551 case EM_CYGNUS_D10V:
552 case EM_MIPS:
4fe85591 553 case EM_MIPS_RS3_LE:
9c19a809 554 return FALSE;
103f02d3 555
252b5132
RH
556 /* Targets that use RELA relocations. */
557 case EM_68K:
b8720f9d
JL
558 case EM_H8_300:
559 case EM_H8_300H:
560 case EM_H8S:
351b4b40
RH
561 case EM_SPARC32PLUS:
562 case EM_SPARCV9:
252b5132
RH
563 case EM_SPARC:
564 case EM_PPC:
285d1771 565 case EM_PPC64:
2b0337b0 566 case EM_V850:
252b5132 567 case EM_CYGNUS_V850:
2b0337b0 568 case EM_D30V:
252b5132 569 case EM_CYGNUS_D30V:
2b0337b0 570 case EM_MN10200:
252b5132 571 case EM_CYGNUS_MN10200:
2b0337b0 572 case EM_MN10300:
252b5132 573 case EM_CYGNUS_MN10300:
2b0337b0 574 case EM_FR30:
252b5132 575 case EM_CYGNUS_FR30:
5c70f934 576 case EM_CYGNUS_FRV:
252b5132
RH
577 case EM_SH:
578 case EM_ALPHA:
579 case EM_MCORE:
800eeca4 580 case EM_IA_64:
dff14200 581 case EM_AVR:
2b0337b0 582 case EM_AVR_OLD:
1b61cf92 583 case EM_CRIS:
535c37ff 584 case EM_860:
bcedfee6 585 case EM_X86_64:
a85d7ed0 586 case EM_S390:
b7498e0e 587 case EM_S390_OLD:
3c3bdf30 588 case EM_MMIX:
2469cfa2
NC
589 case EM_MSP430:
590 case EM_MSP430_OLD:
93fbbb04 591 case EM_XSTORMY16:
1fe1f39c 592 case EM_CRX:
179d3252 593 case EM_VAX:
1e4cf259
NC
594 case EM_IP2K:
595 case EM_IP2K_OLD:
3b36097d 596 case EM_IQ2000:
88da6820
NC
597 case EM_XTENSA:
598 case EM_XTENSA_OLD:
6edf0760 599 case EM_M32R:
49f58d10 600 case EM_M32C:
a34e3ecb 601 case EM_MS1:
1d65ded4 602 case EM_BLACKFIN:
9c19a809 603 return TRUE;
103f02d3 604
d1133906
NC
605 case EM_MMA:
606 case EM_PCP:
607 case EM_NCPU:
608 case EM_NDR1:
609 case EM_STARCORE:
610 case EM_ME16:
611 case EM_ST100:
612 case EM_TINYJ:
613 case EM_FX66:
614 case EM_ST9PLUS:
615 case EM_ST7:
616 case EM_68HC16:
617 case EM_68HC11:
618 case EM_68HC08:
619 case EM_68HC05:
620 case EM_SVX:
621 case EM_ST19:
9c19a809
NC
622 default:
623 warn (_("Don't know about relocations on this machine architecture\n"));
624 return FALSE;
625 }
626}
252b5132 627
9c19a809 628static int
d3ba0551
AM
629slurp_rela_relocs (FILE *file,
630 unsigned long rel_offset,
631 unsigned long rel_size,
632 Elf_Internal_Rela **relasp,
633 unsigned long *nrelasp)
9c19a809 634{
4d6ed7c8
NC
635 Elf_Internal_Rela *relas;
636 unsigned long nrelas;
637 unsigned int i;
252b5132 638
4d6ed7c8
NC
639 if (is_32bit_elf)
640 {
b34976b6 641 Elf32_External_Rela *erelas;
103f02d3 642
c256ffe7 643 erelas = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
a6e9f9df
AM
644 if (!erelas)
645 return 0;
252b5132 646
4d6ed7c8 647 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 648
c256ffe7 649 relas = cmalloc (nrelas, sizeof (Elf_Internal_Rela));
103f02d3 650
4d6ed7c8
NC
651 if (relas == NULL)
652 {
c256ffe7 653 free (erelas);
18bd398b 654 error (_("out of memory parsing relocs"));
4d6ed7c8
NC
655 return 0;
656 }
103f02d3 657
4d6ed7c8
NC
658 for (i = 0; i < nrelas; i++)
659 {
660 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
661 relas[i].r_info = BYTE_GET (erelas[i].r_info);
662 relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
663 }
103f02d3 664
4d6ed7c8
NC
665 free (erelas);
666 }
667 else
668 {
b34976b6 669 Elf64_External_Rela *erelas;
103f02d3 670
c256ffe7 671 erelas = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
a6e9f9df
AM
672 if (!erelas)
673 return 0;
4d6ed7c8
NC
674
675 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 676
c256ffe7 677 relas = cmalloc (nrelas, sizeof (Elf_Internal_Rela));
103f02d3 678
4d6ed7c8
NC
679 if (relas == NULL)
680 {
c256ffe7 681 free (erelas);
18bd398b 682 error (_("out of memory parsing relocs"));
4d6ed7c8 683 return 0;
9c19a809 684 }
4d6ed7c8
NC
685
686 for (i = 0; i < nrelas; i++)
9c19a809 687 {
66543521
AM
688 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
689 relas[i].r_info = BYTE_GET (erelas[i].r_info);
690 relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
4d6ed7c8 691 }
103f02d3 692
4d6ed7c8
NC
693 free (erelas);
694 }
695 *relasp = relas;
696 *nrelasp = nrelas;
697 return 1;
698}
103f02d3 699
4d6ed7c8 700static int
d3ba0551
AM
701slurp_rel_relocs (FILE *file,
702 unsigned long rel_offset,
703 unsigned long rel_size,
704 Elf_Internal_Rela **relsp,
705 unsigned long *nrelsp)
4d6ed7c8 706{
c8286bd1 707 Elf_Internal_Rela *rels;
4d6ed7c8
NC
708 unsigned long nrels;
709 unsigned int i;
103f02d3 710
4d6ed7c8
NC
711 if (is_32bit_elf)
712 {
b34976b6 713 Elf32_External_Rel *erels;
103f02d3 714
c256ffe7 715 erels = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
a6e9f9df
AM
716 if (!erels)
717 return 0;
103f02d3 718
4d6ed7c8 719 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 720
c256ffe7 721 rels = cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 722
4d6ed7c8
NC
723 if (rels == NULL)
724 {
c256ffe7 725 free (erels);
18bd398b 726 error (_("out of memory parsing relocs"));
4d6ed7c8
NC
727 return 0;
728 }
729
730 for (i = 0; i < nrels; i++)
731 {
732 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
733 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 734 rels[i].r_addend = 0;
9ea033b2 735 }
4d6ed7c8
NC
736
737 free (erels);
9c19a809
NC
738 }
739 else
740 {
b34976b6 741 Elf64_External_Rel *erels;
9ea033b2 742
c256ffe7 743 erels = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
a6e9f9df
AM
744 if (!erels)
745 return 0;
103f02d3 746
4d6ed7c8 747 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 748
c256ffe7 749 rels = cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 750
4d6ed7c8 751 if (rels == NULL)
9c19a809 752 {
c256ffe7 753 free (erels);
18bd398b 754 error (_("out of memory parsing relocs"));
4d6ed7c8
NC
755 return 0;
756 }
103f02d3 757
4d6ed7c8
NC
758 for (i = 0; i < nrels; i++)
759 {
66543521
AM
760 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
761 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 762 rels[i].r_addend = 0;
4d6ed7c8 763 }
103f02d3 764
4d6ed7c8
NC
765 free (erels);
766 }
767 *relsp = rels;
768 *nrelsp = nrels;
769 return 1;
770}
103f02d3 771
d3ba0551
AM
772/* Display the contents of the relocation data found at the specified
773 offset. */
ee42cf8c 774
4d6ed7c8 775static int
d3ba0551
AM
776dump_relocations (FILE *file,
777 unsigned long rel_offset,
778 unsigned long rel_size,
779 Elf_Internal_Sym *symtab,
780 unsigned long nsyms,
781 char *strtab,
d79b3d50 782 unsigned long strtablen,
d3ba0551 783 int is_rela)
4d6ed7c8 784{
b34976b6
AM
785 unsigned int i;
786 Elf_Internal_Rela *rels;
103f02d3 787
103f02d3 788
4d6ed7c8
NC
789 if (is_rela == UNKNOWN)
790 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 791
4d6ed7c8
NC
792 if (is_rela)
793 {
c8286bd1 794 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
4d6ed7c8
NC
795 return 0;
796 }
797 else
798 {
799 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
800 return 0;
252b5132
RH
801 }
802
410f7a12
L
803 if (is_32bit_elf)
804 {
805 if (is_rela)
2c71103e
NC
806 {
807 if (do_wide)
808 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
809 else
810 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
811 }
410f7a12 812 else
2c71103e
NC
813 {
814 if (do_wide)
815 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
816 else
817 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
818 }
410f7a12 819 }
252b5132 820 else
410f7a12
L
821 {
822 if (is_rela)
2c71103e
NC
823 {
824 if (do_wide)
8beeaeb7 825 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
826 else
827 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
828 }
410f7a12 829 else
2c71103e
NC
830 {
831 if (do_wide)
8beeaeb7 832 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
833 else
834 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
835 }
410f7a12 836 }
252b5132
RH
837
838 for (i = 0; i < rel_size; i++)
839 {
b34976b6
AM
840 const char *rtype;
841 const char *rtype2 = NULL;
842 const char *rtype3 = NULL;
843 bfd_vma offset;
844 bfd_vma info;
845 bfd_vma symtab_index;
846 bfd_vma type;
d3ba0551
AM
847 bfd_vma type2 = 0;
848 bfd_vma type3 = 0;
103f02d3 849
b34976b6
AM
850 offset = rels[i].r_offset;
851 info = rels[i].r_info;
103f02d3 852
9ea033b2
NC
853 if (is_32bit_elf)
854 {
855 type = ELF32_R_TYPE (info);
856 symtab_index = ELF32_R_SYM (info);
857 }
858 else
859 {
1a677ea8
RS
860 /* The #ifdef BFD64 below is to prevent a compile time warning.
861 We know that if we do not have a 64 bit data type that we
862 will never execute this code anyway. */
863#ifdef BFD64
53c7db4b 864 if (elf_header.e_machine == EM_MIPS)
2c71103e 865 {
1a677ea8
RS
866 /* In little-endian objects, r_info isn't really a 64-bit
867 little-endian value: it has a 32-bit little-endian
868 symbol index followed by four individual byte fields.
869 Reorder INFO accordingly. */
870 if (elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
871 info = (((info & 0xffffffff) << 32)
872 | ((info >> 56) & 0xff)
873 | ((info >> 40) & 0xff00)
874 | ((info >> 24) & 0xff0000)
875 | ((info >> 8) & 0xff000000));
2c71103e
NC
876 type = ELF64_MIPS_R_TYPE (info);
877 type2 = ELF64_MIPS_R_TYPE2 (info);
878 type3 = ELF64_MIPS_R_TYPE3 (info);
879 }
880 else if (elf_header.e_machine == EM_SPARCV9)
881 type = ELF64_R_TYPE_ID (info);
351b4b40 882 else
2c71103e 883 type = ELF64_R_TYPE (info);
1a677ea8 884
9ea033b2 885 symtab_index = ELF64_R_SYM (info);
a952a375 886#endif
9ea033b2 887 }
252b5132 888
410f7a12
L
889 if (is_32bit_elf)
890 {
891#ifdef _bfd_int64_low
892 printf ("%8.8lx %8.8lx ", _bfd_int64_low (offset), _bfd_int64_low (info));
893#else
894 printf ("%8.8lx %8.8lx ", offset, info);
895#endif
896 }
897 else
898 {
9ea033b2 899#ifdef _bfd_int64_low
2c71103e
NC
900 printf (do_wide
901 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
902 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
903 _bfd_int64_high (offset),
904 _bfd_int64_low (offset),
905 _bfd_int64_high (info),
906 _bfd_int64_low (info));
9ea033b2 907#else
2c71103e 908 printf (do_wide
25345be5 909 ? "%16.16lx %16.16lx "
2c71103e
NC
910 : "%12.12lx %12.12lx ",
911 offset, info);
9ea033b2 912#endif
410f7a12 913 }
103f02d3 914
252b5132
RH
915 switch (elf_header.e_machine)
916 {
917 default:
918 rtype = NULL;
919 break;
920
2b0337b0 921 case EM_M32R:
252b5132 922 case EM_CYGNUS_M32R:
9ea033b2 923 rtype = elf_m32r_reloc_type (type);
252b5132
RH
924 break;
925
926 case EM_386:
927 case EM_486:
9ea033b2 928 rtype = elf_i386_reloc_type (type);
252b5132
RH
929 break;
930
ba2685cc
AM
931 case EM_68HC11:
932 case EM_68HC12:
933 rtype = elf_m68hc11_reloc_type (type);
934 break;
75751cd9 935
252b5132 936 case EM_68K:
9ea033b2 937 rtype = elf_m68k_reloc_type (type);
252b5132
RH
938 break;
939
63fcb9e9 940 case EM_960:
9ea033b2 941 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
942 break;
943
adde6300 944 case EM_AVR:
2b0337b0 945 case EM_AVR_OLD:
adde6300
AM
946 rtype = elf_avr_reloc_type (type);
947 break;
948
9ea033b2
NC
949 case EM_OLD_SPARCV9:
950 case EM_SPARC32PLUS:
951 case EM_SPARCV9:
252b5132 952 case EM_SPARC:
9ea033b2 953 rtype = elf_sparc_reloc_type (type);
252b5132
RH
954 break;
955
2b0337b0 956 case EM_V850:
252b5132 957 case EM_CYGNUS_V850:
9ea033b2 958 rtype = v850_reloc_type (type);
252b5132
RH
959 break;
960
2b0337b0 961 case EM_D10V:
252b5132 962 case EM_CYGNUS_D10V:
9ea033b2 963 rtype = elf_d10v_reloc_type (type);
252b5132
RH
964 break;
965
2b0337b0 966 case EM_D30V:
252b5132 967 case EM_CYGNUS_D30V:
9ea033b2 968 rtype = elf_d30v_reloc_type (type);
252b5132
RH
969 break;
970
d172d4ba
NC
971 case EM_DLX:
972 rtype = elf_dlx_reloc_type (type);
973 break;
974
252b5132 975 case EM_SH:
9ea033b2 976 rtype = elf_sh_reloc_type (type);
252b5132
RH
977 break;
978
2b0337b0 979 case EM_MN10300:
252b5132 980 case EM_CYGNUS_MN10300:
9ea033b2 981 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
982 break;
983
2b0337b0 984 case EM_MN10200:
252b5132 985 case EM_CYGNUS_MN10200:
9ea033b2 986 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
987 break;
988
2b0337b0 989 case EM_FR30:
252b5132 990 case EM_CYGNUS_FR30:
9ea033b2 991 rtype = elf_fr30_reloc_type (type);
252b5132
RH
992 break;
993
ba2685cc
AM
994 case EM_CYGNUS_FRV:
995 rtype = elf_frv_reloc_type (type);
996 break;
5c70f934 997
252b5132 998 case EM_MCORE:
9ea033b2 999 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1000 break;
1001
3c3bdf30
NC
1002 case EM_MMIX:
1003 rtype = elf_mmix_reloc_type (type);
1004 break;
1005
2469cfa2
NC
1006 case EM_MSP430:
1007 case EM_MSP430_OLD:
1008 rtype = elf_msp430_reloc_type (type);
1009 break;
1010
252b5132 1011 case EM_PPC:
9ea033b2 1012 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1013 break;
1014
c833c019
AM
1015 case EM_PPC64:
1016 rtype = elf_ppc64_reloc_type (type);
1017 break;
1018
252b5132 1019 case EM_MIPS:
4fe85591 1020 case EM_MIPS_RS3_LE:
9ea033b2 1021 rtype = elf_mips_reloc_type (type);
53c7db4b 1022 if (!is_32bit_elf)
2c71103e
NC
1023 {
1024 rtype2 = elf_mips_reloc_type (type2);
1025 rtype3 = elf_mips_reloc_type (type3);
1026 }
252b5132
RH
1027 break;
1028
1029 case EM_ALPHA:
9ea033b2 1030 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1031 break;
1032
1033 case EM_ARM:
9ea033b2 1034 rtype = elf_arm_reloc_type (type);
252b5132
RH
1035 break;
1036
584da044 1037 case EM_ARC:
9ea033b2 1038 rtype = elf_arc_reloc_type (type);
252b5132
RH
1039 break;
1040
1041 case EM_PARISC:
69e617ca 1042 rtype = elf_hppa_reloc_type (type);
252b5132 1043 break;
7d466069 1044
b8720f9d
JL
1045 case EM_H8_300:
1046 case EM_H8_300H:
1047 case EM_H8S:
1048 rtype = elf_h8_reloc_type (type);
1049 break;
1050
3b16e843
NC
1051 case EM_OPENRISC:
1052 case EM_OR32:
1053 rtype = elf_or32_reloc_type (type);
1054 break;
1055
7d466069 1056 case EM_PJ:
2b0337b0 1057 case EM_PJ_OLD:
7d466069
ILT
1058 rtype = elf_pj_reloc_type (type);
1059 break;
800eeca4
JW
1060 case EM_IA_64:
1061 rtype = elf_ia64_reloc_type (type);
1062 break;
1b61cf92
HPN
1063
1064 case EM_CRIS:
1065 rtype = elf_cris_reloc_type (type);
1066 break;
535c37ff
JE
1067
1068 case EM_860:
1069 rtype = elf_i860_reloc_type (type);
1070 break;
bcedfee6
NC
1071
1072 case EM_X86_64:
1073 rtype = elf_x86_64_reloc_type (type);
1074 break;
a85d7ed0 1075
35b1837e
AM
1076 case EM_S370:
1077 rtype = i370_reloc_type (type);
1078 break;
1079
53c7db4b
KH
1080 case EM_S390_OLD:
1081 case EM_S390:
1082 rtype = elf_s390_reloc_type (type);
1083 break;
93fbbb04
GK
1084
1085 case EM_XSTORMY16:
1086 rtype = elf_xstormy16_reloc_type (type);
1087 break;
179d3252 1088
1fe1f39c
NC
1089 case EM_CRX:
1090 rtype = elf_crx_reloc_type (type);
1091 break;
1092
179d3252
JT
1093 case EM_VAX:
1094 rtype = elf_vax_reloc_type (type);
1095 break;
1e4cf259
NC
1096
1097 case EM_IP2K:
1098 case EM_IP2K_OLD:
1099 rtype = elf_ip2k_reloc_type (type);
1100 break;
3b36097d
SC
1101
1102 case EM_IQ2000:
1103 rtype = elf_iq2000_reloc_type (type);
1104 break;
88da6820
NC
1105
1106 case EM_XTENSA_OLD:
1107 case EM_XTENSA:
1108 rtype = elf_xtensa_reloc_type (type);
1109 break;
a34e3ecb 1110
49f58d10
JB
1111 case EM_M32C:
1112 rtype = elf_m32c_reloc_type (type);
1113 break;
1114
a34e3ecb
EC
1115 case EM_MS1:
1116 rtype = elf_ms1_reloc_type (type);
1117 break;
1d65ded4
CM
1118
1119 case EM_BLACKFIN:
1120 rtype = elf_bfin_reloc_type (type);
1121 break;
1122
252b5132
RH
1123 }
1124
1125 if (rtype == NULL)
103f02d3 1126#ifdef _bfd_int64_low
2c71103e 1127 printf (_("unrecognized: %-7lx"), _bfd_int64_low (type));
9ea033b2 1128#else
2c71103e 1129 printf (_("unrecognized: %-7lx"), type);
9ea033b2 1130#endif
252b5132 1131 else
8beeaeb7 1132 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1133
7ace3541
RH
1134 if (elf_header.e_machine == EM_ALPHA
1135 && streq (rtype, "R_ALPHA_LITUSE")
1136 && is_rela)
1137 {
1138 switch (rels[i].r_addend)
1139 {
1140 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1141 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1142 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1143 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1144 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1145 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1146 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1147 default: rtype = NULL;
1148 }
1149 if (rtype)
1150 printf (" (%s)", rtype);
1151 else
1152 {
1153 putchar (' ');
1154 printf (_("<unknown addend: %lx>"),
1155 (unsigned long) rels[i].r_addend);
1156 }
1157 }
1158 else if (symtab_index)
252b5132 1159 {
af3fc3bc
AM
1160 if (symtab == NULL || symtab_index >= nsyms)
1161 printf (" bad symbol index: %08lx", (unsigned long) symtab_index);
1162 else
19936277 1163 {
b34976b6 1164 Elf_Internal_Sym *psym;
19936277 1165
af3fc3bc 1166 psym = symtab + symtab_index;
103f02d3 1167
af3fc3bc
AM
1168 printf (" ");
1169 print_vma (psym->st_value, LONG_HEX);
2c71103e 1170 printf (is_32bit_elf ? " " : " ");
103f02d3 1171
af3fc3bc 1172 if (psym->st_name == 0)
f1ef08cb
AM
1173 {
1174 const char *sec_name = "<null>";
1175 char name_buf[40];
1176
1177 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1178 {
1179 bfd_vma sec_index = (bfd_vma) -1;
1180
1181 if (psym->st_shndx < SHN_LORESERVE)
1182 sec_index = psym->st_shndx;
efcb5b0e 1183 else if (psym->st_shndx > SHN_HIRESERVE)
f1ef08cb
AM
1184 sec_index = psym->st_shndx - (SHN_HIRESERVE + 1
1185 - SHN_LORESERVE);
1186
1187 if (sec_index != (bfd_vma) -1)
1188 sec_name = SECTION_NAME (section_headers + sec_index);
1189 else if (psym->st_shndx == SHN_ABS)
1190 sec_name = "ABS";
1191 else if (psym->st_shndx == SHN_COMMON)
1192 sec_name = "COMMON";
3b22753a
L
1193 else if (elf_header.e_machine == EM_X86_64
1194 && psym->st_shndx == SHN_X86_64_LCOMMON)
1195 sec_name = "LARGE_COMMON";
9ce701e2
L
1196 else if (elf_header.e_machine == EM_IA_64
1197 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1198 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1199 sec_name = "ANSI_COM";
f1ef08cb
AM
1200 else
1201 {
1202 sprintf (name_buf, "<section 0x%x>",
1203 (unsigned int) psym->st_shndx);
1204 sec_name = name_buf;
1205 }
1206 }
1207 print_symbol (22, sec_name);
1208 }
af3fc3bc 1209 else if (strtab == NULL)
d79b3d50 1210 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1211 else if (psym->st_name >= strtablen)
d79b3d50 1212 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1213 else
2c71103e 1214 print_symbol (22, strtab + psym->st_name);
103f02d3 1215
af3fc3bc 1216 if (is_rela)
b34976b6 1217 printf (" + %lx", (unsigned long) rels[i].r_addend);
19936277 1218 }
252b5132 1219 }
1b228002 1220 else if (is_rela)
f7a99963 1221 {
18bd398b
NC
1222 printf ("%*c", is_32bit_elf ?
1223 (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' ');
c8286bd1 1224 print_vma (rels[i].r_addend, LONG_HEX);
f7a99963 1225 }
252b5132 1226
7ace3541 1227 if (elf_header.e_machine == EM_SPARCV9 && streq (rtype, "R_SPARC_OLO10"))
351b4b40
RH
1228 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (info));
1229
252b5132 1230 putchar ('\n');
2c71103e 1231
53c7db4b 1232 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e
NC
1233 {
1234 printf (" Type2: ");
1235
1236 if (rtype2 == NULL)
1237#ifdef _bfd_int64_low
1238 printf (_("unrecognized: %-7lx"), _bfd_int64_low (type2));
1239#else
1240 printf (_("unrecognized: %-7lx"), type2);
1241#endif
1242 else
1243 printf ("%-17.17s", rtype2);
1244
18bd398b 1245 printf ("\n Type3: ");
2c71103e
NC
1246
1247 if (rtype3 == NULL)
1248#ifdef _bfd_int64_low
1249 printf (_("unrecognized: %-7lx"), _bfd_int64_low (type3));
1250#else
1251 printf (_("unrecognized: %-7lx"), type3);
1252#endif
1253 else
1254 printf ("%-17.17s", rtype3);
1255
53c7db4b 1256 putchar ('\n');
2c71103e 1257 }
252b5132
RH
1258 }
1259
c8286bd1 1260 free (rels);
252b5132
RH
1261
1262 return 1;
1263}
1264
1265static const char *
d3ba0551 1266get_mips_dynamic_type (unsigned long type)
252b5132
RH
1267{
1268 switch (type)
1269 {
1270 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1271 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1272 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1273 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1274 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1275 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1276 case DT_MIPS_MSYM: return "MIPS_MSYM";
1277 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1278 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1279 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1280 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1281 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1282 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1283 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1284 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1285 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1286 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1287 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1288 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1289 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1290 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1291 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1292 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1293 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1294 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1295 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1296 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1297 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1298 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1299 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1300 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1301 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1302 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1303 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1304 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1305 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1306 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1307 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1308 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1309 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1310 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1311 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1312 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
1313 default:
1314 return NULL;
1315 }
1316}
1317
9a097730 1318static const char *
d3ba0551 1319get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1320{
1321 switch (type)
1322 {
1323 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1324 default:
1325 return NULL;
1326 }
103f02d3
UD
1327}
1328
7490d522
AM
1329static const char *
1330get_ppc_dynamic_type (unsigned long type)
1331{
1332 switch (type)
1333 {
1fe44d79 1334 case DT_PPC_GOT: return "PPC_GOT";
7490d522
AM
1335 default:
1336 return NULL;
1337 }
1338}
1339
f1cb7e17 1340static const char *
d3ba0551 1341get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1342{
1343 switch (type)
1344 {
1345 case DT_PPC64_GLINK: return "PPC64_GLINK";
19397422
AM
1346 case DT_PPC64_OPD: return "PPC64_OPD";
1347 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
f1cb7e17
AM
1348 default:
1349 return NULL;
1350 }
1351}
1352
103f02d3 1353static const char *
d3ba0551 1354get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1355{
1356 switch (type)
1357 {
1358 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1359 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1360 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1361 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1362 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1363 case DT_HP_PREINIT: return "HP_PREINIT";
1364 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1365 case DT_HP_NEEDED: return "HP_NEEDED";
1366 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1367 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1368 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1369 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1370 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1371 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1372 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1373 case DT_HP_FILTERED: return "HP_FILTERED";
1374 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1375 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1376 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1377 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1378 case DT_PLT: return "PLT";
1379 case DT_PLT_SIZE: return "PLT_SIZE";
1380 case DT_DLT: return "DLT";
1381 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1382 default:
1383 return NULL;
1384 }
1385}
9a097730 1386
ecc51f48 1387static const char *
d3ba0551 1388get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1389{
1390 switch (type)
1391 {
1392 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1393 default:
1394 return NULL;
1395 }
1396}
1397
fabcb361
RH
1398static const char *
1399get_alpha_dynamic_type (unsigned long type)
1400{
1401 switch (type)
1402 {
1403 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1404 default:
1405 return NULL;
1406 }
1407}
1408
252b5132 1409static const char *
d3ba0551 1410get_dynamic_type (unsigned long type)
252b5132 1411{
e9e44622 1412 static char buff[64];
252b5132
RH
1413
1414 switch (type)
1415 {
1416 case DT_NULL: return "NULL";
1417 case DT_NEEDED: return "NEEDED";
1418 case DT_PLTRELSZ: return "PLTRELSZ";
1419 case DT_PLTGOT: return "PLTGOT";
1420 case DT_HASH: return "HASH";
1421 case DT_STRTAB: return "STRTAB";
1422 case DT_SYMTAB: return "SYMTAB";
1423 case DT_RELA: return "RELA";
1424 case DT_RELASZ: return "RELASZ";
1425 case DT_RELAENT: return "RELAENT";
1426 case DT_STRSZ: return "STRSZ";
1427 case DT_SYMENT: return "SYMENT";
1428 case DT_INIT: return "INIT";
1429 case DT_FINI: return "FINI";
1430 case DT_SONAME: return "SONAME";
1431 case DT_RPATH: return "RPATH";
1432 case DT_SYMBOLIC: return "SYMBOLIC";
1433 case DT_REL: return "REL";
1434 case DT_RELSZ: return "RELSZ";
1435 case DT_RELENT: return "RELENT";
1436 case DT_PLTREL: return "PLTREL";
1437 case DT_DEBUG: return "DEBUG";
1438 case DT_TEXTREL: return "TEXTREL";
1439 case DT_JMPREL: return "JMPREL";
1440 case DT_BIND_NOW: return "BIND_NOW";
1441 case DT_INIT_ARRAY: return "INIT_ARRAY";
1442 case DT_FINI_ARRAY: return "FINI_ARRAY";
1443 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1444 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1445 case DT_RUNPATH: return "RUNPATH";
1446 case DT_FLAGS: return "FLAGS";
2d0e6f43 1447
d1133906
NC
1448 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1449 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1450
05107a46 1451 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1452 case DT_PLTPADSZ: return "PLTPADSZ";
1453 case DT_MOVEENT: return "MOVEENT";
1454 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1455 case DT_FEATURE: return "FEATURE";
252b5132
RH
1456 case DT_POSFLAG_1: return "POSFLAG_1";
1457 case DT_SYMINSZ: return "SYMINSZ";
1458 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1459
252b5132 1460 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1461 case DT_CONFIG: return "CONFIG";
1462 case DT_DEPAUDIT: return "DEPAUDIT";
1463 case DT_AUDIT: return "AUDIT";
1464 case DT_PLTPAD: return "PLTPAD";
1465 case DT_MOVETAB: return "MOVETAB";
252b5132 1466 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1467
252b5132 1468 case DT_VERSYM: return "VERSYM";
103f02d3 1469
252b5132
RH
1470 case DT_RELACOUNT: return "RELACOUNT";
1471 case DT_RELCOUNT: return "RELCOUNT";
1472 case DT_FLAGS_1: return "FLAGS_1";
1473 case DT_VERDEF: return "VERDEF";
1474 case DT_VERDEFNUM: return "VERDEFNUM";
1475 case DT_VERNEED: return "VERNEED";
1476 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1477
019148e4 1478 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1479 case DT_USED: return "USED";
1480 case DT_FILTER: return "FILTER";
103f02d3 1481
047b2264
JJ
1482 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1483 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1484 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1485 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1486 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
1487
252b5132
RH
1488 default:
1489 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1490 {
b34976b6 1491 const char *result;
103f02d3 1492
252b5132
RH
1493 switch (elf_header.e_machine)
1494 {
1495 case EM_MIPS:
4fe85591 1496 case EM_MIPS_RS3_LE:
252b5132
RH
1497 result = get_mips_dynamic_type (type);
1498 break;
9a097730
RH
1499 case EM_SPARCV9:
1500 result = get_sparc64_dynamic_type (type);
1501 break;
7490d522
AM
1502 case EM_PPC:
1503 result = get_ppc_dynamic_type (type);
1504 break;
f1cb7e17
AM
1505 case EM_PPC64:
1506 result = get_ppc64_dynamic_type (type);
1507 break;
ecc51f48
NC
1508 case EM_IA_64:
1509 result = get_ia64_dynamic_type (type);
1510 break;
fabcb361
RH
1511 case EM_ALPHA:
1512 result = get_alpha_dynamic_type (type);
1513 break;
252b5132
RH
1514 default:
1515 result = NULL;
1516 break;
1517 }
1518
1519 if (result != NULL)
1520 return result;
1521
e9e44622 1522 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1523 }
eec8f817
DA
1524 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1525 || (elf_header.e_machine == EM_PARISC
1526 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1527 {
b34976b6 1528 const char *result;
103f02d3
UD
1529
1530 switch (elf_header.e_machine)
1531 {
1532 case EM_PARISC:
1533 result = get_parisc_dynamic_type (type);
1534 break;
1535 default:
1536 result = NULL;
1537 break;
1538 }
1539
1540 if (result != NULL)
1541 return result;
1542
e9e44622
JJ
1543 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1544 type);
103f02d3 1545 }
252b5132 1546 else
e9e44622 1547 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1548
252b5132
RH
1549 return buff;
1550 }
1551}
1552
1553static char *
d3ba0551 1554get_file_type (unsigned e_type)
252b5132 1555{
b34976b6 1556 static char buff[32];
252b5132
RH
1557
1558 switch (e_type)
1559 {
1560 case ET_NONE: return _("NONE (None)");
1561 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1562 case ET_EXEC: return _("EXEC (Executable file)");
1563 case ET_DYN: return _("DYN (Shared object file)");
1564 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1565
1566 default:
1567 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1568 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1569 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1570 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1571 else
e9e44622 1572 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1573 return buff;
1574 }
1575}
1576
1577static char *
d3ba0551 1578get_machine_name (unsigned e_machine)
252b5132 1579{
b34976b6 1580 static char buff[64]; /* XXX */
252b5132
RH
1581
1582 switch (e_machine)
1583 {
c45021f2
NC
1584 case EM_NONE: return _("None");
1585 case EM_M32: return "WE32100";
1586 case EM_SPARC: return "Sparc";
1587 case EM_386: return "Intel 80386";
1588 case EM_68K: return "MC68000";
1589 case EM_88K: return "MC88000";
1590 case EM_486: return "Intel 80486";
1591 case EM_860: return "Intel 80860";
1592 case EM_MIPS: return "MIPS R3000";
1593 case EM_S370: return "IBM System/370";
7036c0e1 1594 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1595 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1596 case EM_PARISC: return "HPPA";
252b5132 1597 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1598 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1599 case EM_960: return "Intel 90860";
1600 case EM_PPC: return "PowerPC";
285d1771 1601 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1602 case EM_V800: return "NEC V800";
1603 case EM_FR20: return "Fujitsu FR20";
1604 case EM_RH32: return "TRW RH32";
b34976b6 1605 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1606 case EM_ARM: return "ARM";
1607 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1608 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1609 case EM_SPARCV9: return "Sparc v9";
1610 case EM_TRICORE: return "Siemens Tricore";
584da044 1611 case EM_ARC: return "ARC";
c2dcd04e
NC
1612 case EM_H8_300: return "Renesas H8/300";
1613 case EM_H8_300H: return "Renesas H8/300H";
1614 case EM_H8S: return "Renesas H8S";
1615 case EM_H8_500: return "Renesas H8/500";
30800947 1616 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1617 case EM_MIPS_X: return "Stanford MIPS-X";
1618 case EM_COLDFIRE: return "Motorola Coldfire";
1619 case EM_68HC12: return "Motorola M68HC12";
c45021f2 1620 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1621 case EM_CYGNUS_D10V:
1622 case EM_D10V: return "d10v";
1623 case EM_CYGNUS_D30V:
b34976b6 1624 case EM_D30V: return "d30v";
2b0337b0 1625 case EM_CYGNUS_M32R:
26597c86 1626 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0
AO
1627 case EM_CYGNUS_V850:
1628 case EM_V850: return "NEC v850";
1629 case EM_CYGNUS_MN10300:
1630 case EM_MN10300: return "mn10300";
1631 case EM_CYGNUS_MN10200:
1632 case EM_MN10200: return "mn10200";
1633 case EM_CYGNUS_FR30:
1634 case EM_FR30: return "Fujitsu FR30";
b34976b6 1635 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1636 case EM_PJ_OLD:
b34976b6 1637 case EM_PJ: return "picoJava";
7036c0e1
AJ
1638 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1639 case EM_PCP: return "Siemens PCP";
1640 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1641 case EM_NDR1: return "Denso NDR1 microprocesspr";
1642 case EM_STARCORE: return "Motorola Star*Core processor";
1643 case EM_ME16: return "Toyota ME16 processor";
1644 case EM_ST100: return "STMicroelectronics ST100 processor";
1645 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
1646 case EM_FX66: return "Siemens FX66 microcontroller";
1647 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1648 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1649 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
1650 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1651 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1652 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1653 case EM_SVX: return "Silicon Graphics SVx";
1654 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1655 case EM_VAX: return "Digital VAX";
2b0337b0 1656 case EM_AVR_OLD:
b34976b6 1657 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1658 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1659 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1660 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1661 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1662 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1663 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1664 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1665 case EM_X86_64: return "Advanced Micro Devices X86-64";
b7498e0e 1666 case EM_S390_OLD:
b34976b6 1667 case EM_S390: return "IBM S/390";
93fbbb04 1668 case EM_XSTORMY16: return "Sanyo Xstormy16 CPU core";
3b16e843
NC
1669 case EM_OPENRISC:
1670 case EM_OR32: return "OpenRISC";
1fe1f39c 1671 case EM_CRX: return "National Semiconductor CRX microprocessor";
d172d4ba 1672 case EM_DLX: return "OpenDLX";
1e4cf259 1673 case EM_IP2K_OLD:
b34976b6 1674 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1675 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1676 case EM_XTENSA_OLD:
1677 case EM_XTENSA: return "Tensilica Xtensa Processor";
49f58d10 1678 case EM_M32C: return "Renesas M32c";
a34e3ecb 1679 case EM_MS1: return "Morpho Techologies MS1 processor";
252b5132 1680 default:
e9e44622 1681 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_machine);
252b5132
RH
1682 return buff;
1683 }
1684}
1685
f3485b74 1686static void
d3ba0551 1687decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
1688{
1689 unsigned eabi;
1690 int unknown = 0;
1691
1692 eabi = EF_ARM_EABI_VERSION (e_flags);
1693 e_flags &= ~ EF_ARM_EABIMASK;
1694
1695 /* Handle "generic" ARM flags. */
1696 if (e_flags & EF_ARM_RELEXEC)
1697 {
1698 strcat (buf, ", relocatable executable");
1699 e_flags &= ~ EF_ARM_RELEXEC;
1700 }
76da6bbe 1701
f3485b74
NC
1702 if (e_flags & EF_ARM_HASENTRY)
1703 {
1704 strcat (buf, ", has entry point");
1705 e_flags &= ~ EF_ARM_HASENTRY;
1706 }
76da6bbe 1707
f3485b74
NC
1708 /* Now handle EABI specific flags. */
1709 switch (eabi)
1710 {
1711 default:
2c71103e 1712 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
1713 if (e_flags)
1714 unknown = 1;
1715 break;
1716
1717 case EF_ARM_EABI_VER1:
a5bcd848 1718 strcat (buf, ", Version1 EABI");
f3485b74
NC
1719 while (e_flags)
1720 {
1721 unsigned flag;
76da6bbe 1722
f3485b74
NC
1723 /* Process flags one bit at a time. */
1724 flag = e_flags & - e_flags;
1725 e_flags &= ~ flag;
76da6bbe 1726
f3485b74
NC
1727 switch (flag)
1728 {
a5bcd848 1729 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
1730 strcat (buf, ", sorted symbol tables");
1731 break;
76da6bbe 1732
f3485b74
NC
1733 default:
1734 unknown = 1;
1735 break;
1736 }
1737 }
1738 break;
76da6bbe 1739
a5bcd848
PB
1740 case EF_ARM_EABI_VER2:
1741 strcat (buf, ", Version2 EABI");
1742 while (e_flags)
1743 {
1744 unsigned flag;
1745
1746 /* Process flags one bit at a time. */
1747 flag = e_flags & - e_flags;
1748 e_flags &= ~ flag;
1749
1750 switch (flag)
1751 {
1752 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
1753 strcat (buf, ", sorted symbol tables");
1754 break;
1755
1756 case EF_ARM_DYNSYMSUSESEGIDX:
1757 strcat (buf, ", dynamic symbols use segment index");
1758 break;
1759
1760 case EF_ARM_MAPSYMSFIRST:
1761 strcat (buf, ", mapping symbols precede others");
1762 break;
1763
1764 default:
1765 unknown = 1;
1766 break;
1767 }
1768 }
1769 break;
1770
d507cf36
PB
1771 case EF_ARM_EABI_VER3:
1772 strcat (buf, ", Version3 EABI");
8cb51566
PB
1773 break;
1774
1775 case EF_ARM_EABI_VER4:
1776 strcat (buf, ", Version4 EABI");
d507cf36
PB
1777 while (e_flags)
1778 {
1779 unsigned flag;
1780
1781 /* Process flags one bit at a time. */
1782 flag = e_flags & - e_flags;
1783 e_flags &= ~ flag;
1784
1785 switch (flag)
1786 {
1787 case EF_ARM_BE8:
1788 strcat (buf, ", BE8");
1789 break;
1790
1791 case EF_ARM_LE8:
1792 strcat (buf, ", LE8");
1793 break;
1794
1795 default:
1796 unknown = 1;
1797 break;
1798 }
1799 }
1800 break;
1801
f3485b74 1802 case EF_ARM_EABI_UNKNOWN:
a5bcd848 1803 strcat (buf, ", GNU EABI");
f3485b74
NC
1804 while (e_flags)
1805 {
1806 unsigned flag;
76da6bbe 1807
f3485b74
NC
1808 /* Process flags one bit at a time. */
1809 flag = e_flags & - e_flags;
1810 e_flags &= ~ flag;
76da6bbe 1811
f3485b74
NC
1812 switch (flag)
1813 {
a5bcd848 1814 case EF_ARM_INTERWORK:
f3485b74
NC
1815 strcat (buf, ", interworking enabled");
1816 break;
76da6bbe 1817
a5bcd848 1818 case EF_ARM_APCS_26:
f3485b74
NC
1819 strcat (buf, ", uses APCS/26");
1820 break;
76da6bbe 1821
a5bcd848 1822 case EF_ARM_APCS_FLOAT:
f3485b74
NC
1823 strcat (buf, ", uses APCS/float");
1824 break;
76da6bbe 1825
a5bcd848 1826 case EF_ARM_PIC:
f3485b74
NC
1827 strcat (buf, ", position independent");
1828 break;
76da6bbe 1829
a5bcd848 1830 case EF_ARM_ALIGN8:
f3485b74
NC
1831 strcat (buf, ", 8 bit structure alignment");
1832 break;
76da6bbe 1833
a5bcd848 1834 case EF_ARM_NEW_ABI:
f3485b74
NC
1835 strcat (buf, ", uses new ABI");
1836 break;
76da6bbe 1837
a5bcd848 1838 case EF_ARM_OLD_ABI:
f3485b74
NC
1839 strcat (buf, ", uses old ABI");
1840 break;
76da6bbe 1841
a5bcd848 1842 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
1843 strcat (buf, ", software FP");
1844 break;
76da6bbe 1845
90e01f86
ILT
1846 case EF_ARM_VFP_FLOAT:
1847 strcat (buf, ", VFP");
1848 break;
1849
fde78edd
NC
1850 case EF_ARM_MAVERICK_FLOAT:
1851 strcat (buf, ", Maverick FP");
1852 break;
1853
f3485b74
NC
1854 default:
1855 unknown = 1;
1856 break;
1857 }
1858 }
1859 }
f3485b74
NC
1860
1861 if (unknown)
1862 strcat (buf,", <unknown>");
1863}
1864
252b5132 1865static char *
d3ba0551 1866get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 1867{
b34976b6 1868 static char buf[1024];
252b5132
RH
1869
1870 buf[0] = '\0';
76da6bbe 1871
252b5132
RH
1872 if (e_flags)
1873 {
1874 switch (e_machine)
1875 {
1876 default:
1877 break;
1878
f3485b74
NC
1879 case EM_ARM:
1880 decode_ARM_machine_flags (e_flags, buf);
1881 break;
76da6bbe 1882
ec2dfb42
AO
1883 case EM_CYGNUS_FRV:
1884 switch (e_flags & EF_FRV_CPU_MASK)
1885 {
1886 case EF_FRV_CPU_GENERIC:
1887 break;
1888
1889 default:
1890 strcat (buf, ", fr???");
1891 break;
57346661 1892
ec2dfb42
AO
1893 case EF_FRV_CPU_FR300:
1894 strcat (buf, ", fr300");
1895 break;
1896
1897 case EF_FRV_CPU_FR400:
1898 strcat (buf, ", fr400");
1899 break;
1900 case EF_FRV_CPU_FR405:
1901 strcat (buf, ", fr405");
1902 break;
1903
1904 case EF_FRV_CPU_FR450:
1905 strcat (buf, ", fr450");
1906 break;
1907
1908 case EF_FRV_CPU_FR500:
1909 strcat (buf, ", fr500");
1910 break;
1911 case EF_FRV_CPU_FR550:
1912 strcat (buf, ", fr550");
1913 break;
1914
1915 case EF_FRV_CPU_SIMPLE:
1916 strcat (buf, ", simple");
1917 break;
1918 case EF_FRV_CPU_TOMCAT:
1919 strcat (buf, ", tomcat");
1920 break;
1921 }
1c877e87 1922 break;
ec2dfb42 1923
53c7db4b
KH
1924 case EM_68K:
1925 if (e_flags & EF_CPU32)
1926 strcat (buf, ", cpu32");
76f57f3a
JT
1927 if (e_flags & EF_M68000)
1928 strcat (buf, ", m68000");
53c7db4b 1929 break;
33c63f9d 1930
252b5132
RH
1931 case EM_PPC:
1932 if (e_flags & EF_PPC_EMB)
1933 strcat (buf, ", emb");
1934
1935 if (e_flags & EF_PPC_RELOCATABLE)
1936 strcat (buf, ", relocatable");
1937
1938 if (e_flags & EF_PPC_RELOCATABLE_LIB)
1939 strcat (buf, ", relocatable-lib");
1940 break;
1941
2b0337b0 1942 case EM_V850:
252b5132
RH
1943 case EM_CYGNUS_V850:
1944 switch (e_flags & EF_V850_ARCH)
1945 {
8ad30312
NC
1946 case E_V850E1_ARCH:
1947 strcat (buf, ", v850e1");
1948 break;
252b5132
RH
1949 case E_V850E_ARCH:
1950 strcat (buf, ", v850e");
1951 break;
252b5132
RH
1952 case E_V850_ARCH:
1953 strcat (buf, ", v850");
1954 break;
1955 default:
1956 strcat (buf, ", unknown v850 architecture variant");
1957 break;
1958 }
1959 break;
1960
2b0337b0 1961 case EM_M32R:
252b5132
RH
1962 case EM_CYGNUS_M32R:
1963 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
1964 strcat (buf, ", m32r");
1965
1966 break;
1967
1968 case EM_MIPS:
4fe85591 1969 case EM_MIPS_RS3_LE:
252b5132
RH
1970 if (e_flags & EF_MIPS_NOREORDER)
1971 strcat (buf, ", noreorder");
1972
1973 if (e_flags & EF_MIPS_PIC)
1974 strcat (buf, ", pic");
1975
1976 if (e_flags & EF_MIPS_CPIC)
1977 strcat (buf, ", cpic");
1978
d1bdd336
TS
1979 if (e_flags & EF_MIPS_UCODE)
1980 strcat (buf, ", ugen_reserved");
1981
252b5132
RH
1982 if (e_flags & EF_MIPS_ABI2)
1983 strcat (buf, ", abi2");
1984
43521d43
TS
1985 if (e_flags & EF_MIPS_OPTIONS_FIRST)
1986 strcat (buf, ", odk first");
1987
a5d22d2a
TS
1988 if (e_flags & EF_MIPS_32BITMODE)
1989 strcat (buf, ", 32bitmode");
1990
156c2f8b
NC
1991 switch ((e_flags & EF_MIPS_MACH))
1992 {
1993 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
1994 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
1995 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 1996 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
1997 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
1998 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
1999 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2000 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2001 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2002 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
43521d43
TS
2003 case 0:
2004 /* We simply ignore the field in this case to avoid confusion:
2005 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2006 extension. */
2007 break;
2008 default: strcat (buf, ", unknown CPU"); break;
156c2f8b 2009 }
43521d43
TS
2010
2011 switch ((e_flags & EF_MIPS_ABI))
2012 {
2013 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2014 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2015 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2016 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2017 case 0:
2018 /* We simply ignore the field in this case to avoid confusion:
2019 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2020 This means it is likely to be an o32 file, but not for
2021 sure. */
2022 break;
2023 default: strcat (buf, ", unknown ABI"); break;
2024 }
2025
2026 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2027 strcat (buf, ", mdmx");
2028
2029 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2030 strcat (buf, ", mips16");
2031
2032 switch ((e_flags & EF_MIPS_ARCH))
2033 {
2034 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2035 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2036 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2037 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2038 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2039 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2040 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2041 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2042 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
43521d43
TS
2043 default: strcat (buf, ", unknown ISA"); break;
2044 }
2045
252b5132 2046 break;
351b4b40 2047
ccde1100
AO
2048 case EM_SH:
2049 switch ((e_flags & EF_SH_MACH_MASK))
2050 {
2051 case EF_SH1: strcat (buf, ", sh1"); break;
2052 case EF_SH2: strcat (buf, ", sh2"); break;
2053 case EF_SH3: strcat (buf, ", sh3"); break;
2054 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2055 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2056 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2057 case EF_SH3E: strcat (buf, ", sh3e"); break;
2058 case EF_SH4: strcat (buf, ", sh4"); break;
2059 case EF_SH5: strcat (buf, ", sh5"); break;
2060 case EF_SH2E: strcat (buf, ", sh2e"); break;
2061 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2062 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2063 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2064 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2065 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
dc85a459 2066 default: strcat (buf, ", unknown ISA"); break;
ccde1100
AO
2067 }
2068
2069 break;
57346661 2070
351b4b40
RH
2071 case EM_SPARCV9:
2072 if (e_flags & EF_SPARC_32PLUS)
2073 strcat (buf, ", v8+");
2074
2075 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2076 strcat (buf, ", ultrasparcI");
2077
2078 if (e_flags & EF_SPARC_SUN_US3)
2079 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2080
2081 if (e_flags & EF_SPARC_HAL_R1)
2082 strcat (buf, ", halr1");
2083
2084 if (e_flags & EF_SPARC_LEDATA)
2085 strcat (buf, ", ledata");
2086
2087 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2088 strcat (buf, ", tso");
2089
2090 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2091 strcat (buf, ", pso");
2092
2093 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2094 strcat (buf, ", rmo");
2095 break;
7d466069 2096
103f02d3
UD
2097 case EM_PARISC:
2098 switch (e_flags & EF_PARISC_ARCH)
2099 {
2100 case EFA_PARISC_1_0:
2101 strcpy (buf, ", PA-RISC 1.0");
2102 break;
2103 case EFA_PARISC_1_1:
2104 strcpy (buf, ", PA-RISC 1.1");
2105 break;
2106 case EFA_PARISC_2_0:
2107 strcpy (buf, ", PA-RISC 2.0");
2108 break;
2109 default:
2110 break;
2111 }
2112 if (e_flags & EF_PARISC_TRAPNIL)
2113 strcat (buf, ", trapnil");
2114 if (e_flags & EF_PARISC_EXT)
2115 strcat (buf, ", ext");
2116 if (e_flags & EF_PARISC_LSB)
2117 strcat (buf, ", lsb");
2118 if (e_flags & EF_PARISC_WIDE)
2119 strcat (buf, ", wide");
2120 if (e_flags & EF_PARISC_NO_KABP)
2121 strcat (buf, ", no kabp");
2122 if (e_flags & EF_PARISC_LAZYSWAP)
2123 strcat (buf, ", lazyswap");
30800947 2124 break;
76da6bbe 2125
7d466069 2126 case EM_PJ:
2b0337b0 2127 case EM_PJ_OLD:
7d466069
ILT
2128 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2129 strcat (buf, ", new calling convention");
2130
2131 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2132 strcat (buf, ", gnu calling convention");
2133 break;
4d6ed7c8
NC
2134
2135 case EM_IA_64:
2136 if ((e_flags & EF_IA_64_ABI64))
2137 strcat (buf, ", 64-bit");
2138 else
2139 strcat (buf, ", 32-bit");
2140 if ((e_flags & EF_IA_64_REDUCEDFP))
2141 strcat (buf, ", reduced fp model");
2142 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2143 strcat (buf, ", no function descriptors, constant gp");
2144 else if ((e_flags & EF_IA_64_CONS_GP))
2145 strcat (buf, ", constant gp");
2146 if ((e_flags & EF_IA_64_ABSOLUTE))
2147 strcat (buf, ", absolute");
2148 break;
179d3252
JT
2149
2150 case EM_VAX:
2151 if ((e_flags & EF_VAX_NONPIC))
2152 strcat (buf, ", non-PIC");
2153 if ((e_flags & EF_VAX_DFLOAT))
2154 strcat (buf, ", D-Float");
2155 if ((e_flags & EF_VAX_GFLOAT))
2156 strcat (buf, ", G-Float");
2157 break;
252b5132
RH
2158 }
2159 }
2160
2161 return buf;
2162}
2163
252b5132 2164static const char *
d3ba0551
AM
2165get_osabi_name (unsigned int osabi)
2166{
2167 static char buff[32];
2168
2169 switch (osabi)
2170 {
2171 case ELFOSABI_NONE: return "UNIX - System V";
2172 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2173 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
2174 case ELFOSABI_LINUX: return "UNIX - Linux";
2175 case ELFOSABI_HURD: return "GNU/Hurd";
2176 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2177 case ELFOSABI_AIX: return "UNIX - AIX";
2178 case ELFOSABI_IRIX: return "UNIX - IRIX";
2179 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2180 case ELFOSABI_TRU64: return "UNIX - TRU64";
2181 case ELFOSABI_MODESTO: return "Novell - Modesto";
2182 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2183 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2184 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
2185 case ELFOSABI_AROS: return "Amiga Research OS";
2186 case ELFOSABI_STANDALONE: return _("Standalone App");
2187 case ELFOSABI_ARM: return "ARM";
2188 default:
e9e44622 2189 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2190 return buff;
2191 }
2192}
2193
b294bdf8
MM
2194static const char *
2195get_arm_segment_type (unsigned long type)
2196{
2197 switch (type)
2198 {
2199 case PT_ARM_EXIDX:
2200 return "EXIDX";
2201 default:
2202 break;
2203 }
2204
2205 return NULL;
2206}
2207
d3ba0551
AM
2208static const char *
2209get_mips_segment_type (unsigned long type)
252b5132
RH
2210{
2211 switch (type)
2212 {
2213 case PT_MIPS_REGINFO:
2214 return "REGINFO";
2215 case PT_MIPS_RTPROC:
2216 return "RTPROC";
2217 case PT_MIPS_OPTIONS:
2218 return "OPTIONS";
2219 default:
2220 break;
2221 }
2222
2223 return NULL;
2224}
2225
103f02d3 2226static const char *
d3ba0551 2227get_parisc_segment_type (unsigned long type)
103f02d3
UD
2228{
2229 switch (type)
2230 {
2231 case PT_HP_TLS: return "HP_TLS";
2232 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2233 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2234 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2235 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2236 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2237 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2238 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2239 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2240 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2241 case PT_HP_PARALLEL: return "HP_PARALLEL";
2242 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2243 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2244 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2245 case PT_HP_STACK: return "HP_STACK";
2246 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2247 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2248 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2249 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
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 {
b294bdf8
MM
2303 case EM_ARM:
2304 result = get_arm_segment_type (p_type);
2305 break;
252b5132 2306 case EM_MIPS:
4fe85591 2307 case EM_MIPS_RS3_LE:
252b5132
RH
2308 result = get_mips_segment_type (p_type);
2309 break;
103f02d3
UD
2310 case EM_PARISC:
2311 result = get_parisc_segment_type (p_type);
2312 break;
4d6ed7c8
NC
2313 case EM_IA_64:
2314 result = get_ia64_segment_type (p_type);
2315 break;
252b5132
RH
2316 default:
2317 result = NULL;
2318 break;
2319 }
103f02d3 2320
252b5132
RH
2321 if (result != NULL)
2322 return result;
103f02d3 2323
252b5132
RH
2324 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2325 }
2326 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2327 {
b34976b6 2328 const char *result;
103f02d3
UD
2329
2330 switch (elf_header.e_machine)
2331 {
2332 case EM_PARISC:
2333 result = get_parisc_segment_type (p_type);
2334 break;
00428cca
AM
2335 case EM_IA_64:
2336 result = get_ia64_segment_type (p_type);
2337 break;
103f02d3
UD
2338 default:
2339 result = NULL;
2340 break;
2341 }
2342
2343 if (result != NULL)
2344 return result;
2345
2346 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
2347 }
252b5132 2348 else
e9e44622 2349 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
2350
2351 return buff;
2352 }
2353}
2354
2355static const char *
d3ba0551 2356get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
2357{
2358 switch (sh_type)
2359 {
b34976b6
AM
2360 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2361 case SHT_MIPS_MSYM: return "MIPS_MSYM";
2362 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2363 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
2364 case SHT_MIPS_UCODE: return "MIPS_UCODE";
2365 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
2366 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
2367 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
2368 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
2369 case SHT_MIPS_RELD: return "MIPS_RELD";
2370 case SHT_MIPS_IFACE: return "MIPS_IFACE";
2371 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
2372 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2373 case SHT_MIPS_SHDR: return "MIPS_SHDR";
2374 case SHT_MIPS_FDESC: return "MIPS_FDESC";
2375 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
2376 case SHT_MIPS_DENSE: return "MIPS_DENSE";
2377 case SHT_MIPS_PDESC: return "MIPS_PDESC";
2378 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
2379 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
2380 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
2381 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
2382 case SHT_MIPS_LINE: return "MIPS_LINE";
2383 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
2384 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
2385 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
2386 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
2387 case SHT_MIPS_DWARF: return "MIPS_DWARF";
2388 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
2389 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2390 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
2391 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
2392 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
2393 case SHT_MIPS_XLATE: return "MIPS_XLATE";
2394 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
2395 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
2396 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
2397 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
2398 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
2399 default:
2400 break;
2401 }
2402 return NULL;
2403}
2404
103f02d3 2405static const char *
d3ba0551 2406get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
2407{
2408 switch (sh_type)
2409 {
2410 case SHT_PARISC_EXT: return "PARISC_EXT";
2411 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
2412 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
2413 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
2414 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
2415 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 2416 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
2417 default:
2418 break;
2419 }
2420 return NULL;
2421}
2422
4d6ed7c8 2423static const char *
d3ba0551 2424get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 2425{
18bd398b 2426 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
2427 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
2428 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 2429
4d6ed7c8
NC
2430 switch (sh_type)
2431 {
ecc51f48
NC
2432 case SHT_IA_64_EXT: return "IA_64_EXT";
2433 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
2434 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4d6ed7c8
NC
2435 default:
2436 break;
2437 }
2438 return NULL;
2439}
2440
d2b2c203
DJ
2441static const char *
2442get_x86_64_section_type_name (unsigned int sh_type)
2443{
2444 switch (sh_type)
2445 {
2446 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
2447 default:
2448 break;
2449 }
2450 return NULL;
2451}
2452
40a18ebd
NC
2453static const char *
2454get_arm_section_type_name (unsigned int sh_type)
2455{
2456 switch (sh_type)
2457 {
2458 case SHT_ARM_EXIDX:
2459 return "ARM_EXIDX";
ec1c4759
RE
2460 case SHT_ARM_PREEMPTMAP:
2461 return "ARM_PREEMPTMAP";
2462 case SHT_ARM_ATTRIBUTES:
2463 return "ARM_ATTRIBUTES";
40a18ebd
NC
2464 default:
2465 break;
2466 }
2467 return NULL;
2468}
2469
252b5132 2470static const char *
d3ba0551 2471get_section_type_name (unsigned int sh_type)
252b5132 2472{
b34976b6 2473 static char buff[32];
252b5132
RH
2474
2475 switch (sh_type)
2476 {
2477 case SHT_NULL: return "NULL";
2478 case SHT_PROGBITS: return "PROGBITS";
2479 case SHT_SYMTAB: return "SYMTAB";
2480 case SHT_STRTAB: return "STRTAB";
2481 case SHT_RELA: return "RELA";
2482 case SHT_HASH: return "HASH";
2483 case SHT_DYNAMIC: return "DYNAMIC";
2484 case SHT_NOTE: return "NOTE";
2485 case SHT_NOBITS: return "NOBITS";
2486 case SHT_REL: return "REL";
2487 case SHT_SHLIB: return "SHLIB";
2488 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
2489 case SHT_INIT_ARRAY: return "INIT_ARRAY";
2490 case SHT_FINI_ARRAY: return "FINI_ARRAY";
2491 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
93ebe586
NC
2492 case SHT_GROUP: return "GROUP";
2493 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
2494 case SHT_GNU_verdef: return "VERDEF";
2495 case SHT_GNU_verneed: return "VERNEED";
2496 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
2497 case 0x6ffffff0: return "VERSYM";
2498 case 0x6ffffffc: return "VERDEF";
252b5132
RH
2499 case 0x7ffffffd: return "AUXILIARY";
2500 case 0x7fffffff: return "FILTER";
047b2264 2501 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
2502
2503 default:
2504 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
2505 {
b34976b6 2506 const char *result;
252b5132
RH
2507
2508 switch (elf_header.e_machine)
2509 {
2510 case EM_MIPS:
4fe85591 2511 case EM_MIPS_RS3_LE:
252b5132
RH
2512 result = get_mips_section_type_name (sh_type);
2513 break;
103f02d3
UD
2514 case EM_PARISC:
2515 result = get_parisc_section_type_name (sh_type);
2516 break;
4d6ed7c8
NC
2517 case EM_IA_64:
2518 result = get_ia64_section_type_name (sh_type);
2519 break;
d2b2c203
DJ
2520 case EM_X86_64:
2521 result = get_x86_64_section_type_name (sh_type);
2522 break;
40a18ebd
NC
2523 case EM_ARM:
2524 result = get_arm_section_type_name (sh_type);
2525 break;
252b5132
RH
2526 default:
2527 result = NULL;
2528 break;
2529 }
2530
2531 if (result != NULL)
2532 return result;
2533
c91d0dfb 2534 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
2535 }
2536 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
c91d0dfb 2537 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
252b5132 2538 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 2539 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 2540 else
e9e44622 2541 snprintf (buff, sizeof (buff), _("<unknown>: %x"), sh_type);
103f02d3 2542
252b5132
RH
2543 return buff;
2544 }
2545}
2546
2979dc34
JJ
2547#define OPTION_DEBUG_DUMP 512
2548
85b1c36d 2549static struct option options[] =
252b5132 2550{
b34976b6 2551 {"all", no_argument, 0, 'a'},
252b5132
RH
2552 {"file-header", no_argument, 0, 'h'},
2553 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
2554 {"headers", no_argument, 0, 'e'},
2555 {"histogram", no_argument, 0, 'I'},
2556 {"segments", no_argument, 0, 'l'},
2557 {"sections", no_argument, 0, 'S'},
252b5132 2558 {"section-headers", no_argument, 0, 'S'},
f5842774 2559 {"section-groups", no_argument, 0, 'g'},
5477e8a0 2560 {"section-details", no_argument, 0, 't'},
595cf52e 2561 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
2562 {"symbols", no_argument, 0, 's'},
2563 {"syms", no_argument, 0, 's'},
2564 {"relocs", no_argument, 0, 'r'},
2565 {"notes", no_argument, 0, 'n'},
2566 {"dynamic", no_argument, 0, 'd'},
a952a375 2567 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
2568 {"version-info", no_argument, 0, 'V'},
2569 {"use-dynamic", no_argument, 0, 'D'},
b34976b6 2570 {"hex-dump", required_argument, 0, 'x'},
2979dc34 2571 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
4d6ed7c8 2572 {"unwind", no_argument, 0, 'u'},
252b5132
RH
2573#ifdef SUPPORT_DISASSEMBLY
2574 {"instruction-dump", required_argument, 0, 'i'},
2575#endif
2576
b34976b6
AM
2577 {"version", no_argument, 0, 'v'},
2578 {"wide", no_argument, 0, 'W'},
2579 {"help", no_argument, 0, 'H'},
2580 {0, no_argument, 0, 0}
252b5132
RH
2581};
2582
2583static void
d3ba0551 2584usage (void)
252b5132 2585{
8b53311e
NC
2586 fprintf (stdout, _("Usage: readelf <option(s)> elf-file(s)\n"));
2587 fprintf (stdout, _(" Display information about the contents of ELF format files\n"));
2588 fprintf (stdout, _(" Options are:\n\
2589 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
2590 -h --file-header Display the ELF file header\n\
2591 -l --program-headers Display the program headers\n\
2592 --segments An alias for --program-headers\n\
2593 -S --section-headers Display the sections' header\n\
2594 --sections An alias for --section-headers\n\
f5842774 2595 -g --section-groups Display the section groups\n\
5477e8a0 2596 -t --section-details Display the section details\n\
8b53311e
NC
2597 -e --headers Equivalent to: -h -l -S\n\
2598 -s --syms Display the symbol table\n\
2599 --symbols An alias for --syms\n\
2600 -n --notes Display the core notes (if present)\n\
2601 -r --relocs Display the relocations (if present)\n\
2602 -u --unwind Display the unwind info (if present)\n\
b2d38a17 2603 -d --dynamic Display the dynamic section (if present)\n\
8b53311e
NC
2604 -V --version-info Display the version sections (if present)\n\
2605 -A --arch-specific Display architecture specific information (if any).\n\
2606 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
2607 -x --hex-dump=<number> Dump the contents of section <number>\n\
18bd398b
NC
2608 -w[liaprmfFsoR] or\n\
2609 --debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]\n\
8b53311e 2610 Display the contents of DWARF2 debug sections\n"));
252b5132 2611#ifdef SUPPORT_DISASSEMBLY
8b53311e
NC
2612 fprintf (stdout, _("\
2613 -i --instruction-dump=<number>\n\
2614 Disassemble the contents of section <number>\n"));
252b5132 2615#endif
8b53311e
NC
2616 fprintf (stdout, _("\
2617 -I --histogram Display histogram of bucket list lengths\n\
2618 -W --wide Allow output width to exceed 80 characters\n\
07012eee 2619 @<file> Read options from <file>\n\
8b53311e
NC
2620 -H --help Display this information\n\
2621 -v --version Display the version number of readelf\n"));
8ad3436c 2622 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
2623
2624 exit (0);
2625}
2626
18bd398b
NC
2627/* Record the fact that the user wants the contents of section number
2628 SECTION to be displayed using the method(s) encoded as flags bits
2629 in TYPE. Note, TYPE can be zero if we are creating the array for
2630 the first time. */
2631
252b5132 2632static void
d3ba0551 2633request_dump (unsigned int section, int type)
252b5132
RH
2634{
2635 if (section >= num_dump_sects)
2636 {
b34976b6 2637 char *new_dump_sects;
252b5132 2638
d3ba0551 2639 new_dump_sects = calloc (section + 1, 1);
252b5132
RH
2640
2641 if (new_dump_sects == NULL)
2642 error (_("Out of memory allocating dump request table."));
2643 else
2644 {
2645 /* Copy current flag settings. */
2646 memcpy (new_dump_sects, dump_sects, num_dump_sects);
2647
2648 free (dump_sects);
2649
2650 dump_sects = new_dump_sects;
2651 num_dump_sects = section + 1;
2652 }
2653 }
2654
2655 if (dump_sects)
b34976b6 2656 dump_sects[section] |= type;
252b5132
RH
2657
2658 return;
2659}
2660
2661static void
d3ba0551 2662parse_args (int argc, char **argv)
252b5132
RH
2663{
2664 int c;
2665
2666 if (argc < 2)
2667 usage ();
2668
2669 while ((c = getopt_long
5477e8a0 2670 (argc, argv, "ersuahnldSDAINtgw::x:i:vVWH", options, NULL)) != EOF)
252b5132 2671 {
b34976b6
AM
2672 char *cp;
2673 int section;
252b5132
RH
2674
2675 switch (c)
2676 {
2677 case 0:
2678 /* Long options. */
2679 break;
2680 case 'H':
2681 usage ();
2682 break;
2683
2684 case 'a':
b34976b6
AM
2685 do_syms++;
2686 do_reloc++;
2687 do_unwind++;
2688 do_dynamic++;
2689 do_header++;
2690 do_sections++;
f5842774 2691 do_section_groups++;
b34976b6
AM
2692 do_segments++;
2693 do_version++;
2694 do_histogram++;
2695 do_arch++;
2696 do_notes++;
252b5132 2697 break;
f5842774
L
2698 case 'g':
2699 do_section_groups++;
2700 break;
5477e8a0 2701 case 't':
595cf52e 2702 case 'N':
5477e8a0
L
2703 do_sections++;
2704 do_section_details++;
595cf52e 2705 break;
252b5132 2706 case 'e':
b34976b6
AM
2707 do_header++;
2708 do_sections++;
2709 do_segments++;
252b5132 2710 break;
a952a375 2711 case 'A':
b34976b6 2712 do_arch++;
a952a375 2713 break;
252b5132 2714 case 'D':
b34976b6 2715 do_using_dynamic++;
252b5132
RH
2716 break;
2717 case 'r':
b34976b6 2718 do_reloc++;
252b5132 2719 break;
4d6ed7c8 2720 case 'u':
b34976b6 2721 do_unwind++;
4d6ed7c8 2722 break;
252b5132 2723 case 'h':
b34976b6 2724 do_header++;
252b5132
RH
2725 break;
2726 case 'l':
b34976b6 2727 do_segments++;
252b5132
RH
2728 break;
2729 case 's':
b34976b6 2730 do_syms++;
252b5132
RH
2731 break;
2732 case 'S':
b34976b6 2733 do_sections++;
252b5132
RH
2734 break;
2735 case 'd':
b34976b6 2736 do_dynamic++;
252b5132 2737 break;
a952a375 2738 case 'I':
b34976b6 2739 do_histogram++;
a952a375 2740 break;
779fe533 2741 case 'n':
b34976b6 2742 do_notes++;
779fe533 2743 break;
252b5132 2744 case 'x':
b34976b6 2745 do_dump++;
252b5132 2746 section = strtoul (optarg, & cp, 0);
b34976b6 2747 if (! *cp && section >= 0)
252b5132
RH
2748 {
2749 request_dump (section, HEX_DUMP);
2750 break;
2751 }
2752 goto oops;
2753 case 'w':
b34976b6 2754 do_dump++;
252b5132
RH
2755 if (optarg == 0)
2756 do_debugging = 1;
2757 else
2758 {
f662939a 2759 unsigned int index = 0;
53c7db4b 2760
252b5132 2761 do_debugging = 0;
252b5132 2762
f662939a
NC
2763 while (optarg[index])
2764 switch (optarg[index++])
2765 {
2766 case 'i':
2767 case 'I':
2768 do_debug_info = 1;
2769 break;
2770
2771 case 'a':
2772 case 'A':
2773 do_debug_abbrevs = 1;
2774 break;
2775
2776 case 'l':
2777 case 'L':
2778 do_debug_lines = 1;
2779 break;
2780
2781 case 'p':
2782 case 'P':
2783 do_debug_pubnames = 1;
2784 break;
2785
2786 case 'r':
f662939a
NC
2787 do_debug_aranges = 1;
2788 break;
2789
18bd398b
NC
2790 case 'R':
2791 do_debug_ranges = 1;
2792 break;
2793
f662939a
NC
2794 case 'F':
2795 do_debug_frames_interp = 1;
2796 case 'f':
2797 do_debug_frames = 1;
2798 break;
2799
2800 case 'm':
2801 case 'M':
2802 do_debug_macinfo = 1;
2803 break;
2804
261a45ad
NC
2805 case 's':
2806 case 'S':
2807 do_debug_str = 1;
2808 break;
2809
a2f14207
DB
2810 case 'o':
2811 case 'O':
2812 do_debug_loc = 1;
2813 break;
53c7db4b 2814
f662939a 2815 default:
2c71103e 2816 warn (_("Unrecognized debug option '%s'\n"), optarg);
f662939a
NC
2817 break;
2818 }
252b5132
RH
2819 }
2820 break;
2979dc34 2821 case OPTION_DEBUG_DUMP:
b34976b6 2822 do_dump++;
2979dc34
JJ
2823 if (optarg == 0)
2824 do_debugging = 1;
2825 else
2826 {
18bd398b
NC
2827 typedef struct
2828 {
2829 const char * option;
2830 int * variable;
2831 }
2832 debug_dump_long_opts;
2833
2834 debug_dump_long_opts opts_table [] =
2835 {
2836 /* Please keep this table alpha- sorted. */
2837 { "Ranges", & do_debug_ranges },
2838 { "abbrev", & do_debug_abbrevs },
2839 { "aranges", & do_debug_aranges },
2840 { "frames", & do_debug_frames },
2841 { "frames-interp", & do_debug_frames_interp },
2842 { "info", & do_debug_info },
2843 { "line", & do_debug_lines },
2844 { "loc", & do_debug_loc },
2845 { "macro", & do_debug_macinfo },
2846 { "pubnames", & do_debug_pubnames },
2847 /* This entry is for compatability
2848 with earlier versions of readelf. */
2849 { "ranges", & do_debug_aranges },
2850 { "str", & do_debug_str },
2851 { NULL, NULL }
2852 };
2853
2979dc34
JJ
2854 const char *p;
2855
2856 do_debugging = 0;
2857
2858 p = optarg;
2859 while (*p)
2860 {
18bd398b
NC
2861 debug_dump_long_opts * entry;
2862
2863 for (entry = opts_table; entry->option; entry++)
2979dc34 2864 {
18bd398b 2865 size_t len = strlen (entry->option);
2979dc34 2866
18bd398b 2867 if (strneq (p, entry->option, len)
2979dc34
JJ
2868 && (p[len] == ',' || p[len] == '\0'))
2869 {
18bd398b
NC
2870 * entry->variable = 1;
2871
2872 /* The --debug-dump=frames-interp option also
2873 enables the --debug-dump=frames option. */
2874 if (do_debug_frames_interp)
2875 do_debug_frames = 1;
2979dc34
JJ
2876
2877 p += len;
2878 break;
2879 }
2880 }
2881
18bd398b 2882 if (entry->option == NULL)
2979dc34
JJ
2883 {
2884 warn (_("Unrecognized debug option '%s'\n"), p);
2885 p = strchr (p, ',');
2886 if (p == NULL)
2887 break;
2888 }
2889
2890 if (*p == ',')
2891 p++;
2892 }
2893 }
2894 break;
252b5132
RH
2895#ifdef SUPPORT_DISASSEMBLY
2896 case 'i':
b34976b6 2897 do_dump++;
252b5132 2898 section = strtoul (optarg, & cp, 0);
b34976b6 2899 if (! *cp && section >= 0)
252b5132
RH
2900 {
2901 request_dump (section, DISASS_DUMP);
2902 break;
2903 }
2904 goto oops;
2905#endif
2906 case 'v':
2907 print_version (program_name);
2908 break;
2909 case 'V':
b34976b6 2910 do_version++;
252b5132 2911 break;
d974e256 2912 case 'W':
b34976b6 2913 do_wide++;
d974e256 2914 break;
252b5132
RH
2915 default:
2916 oops:
2917 /* xgettext:c-format */
2918 error (_("Invalid option '-%c'\n"), c);
2919 /* Drop through. */
2920 case '?':
2921 usage ();
2922 }
2923 }
2924
4d6ed7c8 2925 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 2926 && !do_segments && !do_header && !do_dump && !do_version
f5842774
L
2927 && !do_histogram && !do_debugging && !do_arch && !do_notes
2928 && !do_section_groups)
252b5132
RH
2929 usage ();
2930 else if (argc < 3)
2931 {
2932 warn (_("Nothing to do.\n"));
18bd398b 2933 usage ();
252b5132
RH
2934 }
2935}
2936
2937static const char *
d3ba0551 2938get_elf_class (unsigned int elf_class)
252b5132 2939{
b34976b6 2940 static char buff[32];
103f02d3 2941
252b5132
RH
2942 switch (elf_class)
2943 {
2944 case ELFCLASSNONE: return _("none");
e3c8793a
NC
2945 case ELFCLASS32: return "ELF32";
2946 case ELFCLASS64: return "ELF64";
ab5e7794 2947 default:
e9e44622 2948 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 2949 return buff;
252b5132
RH
2950 }
2951}
2952
2953static const char *
d3ba0551 2954get_data_encoding (unsigned int encoding)
252b5132 2955{
b34976b6 2956 static char buff[32];
103f02d3 2957
252b5132
RH
2958 switch (encoding)
2959 {
2960 case ELFDATANONE: return _("none");
33c63f9d
CM
2961 case ELFDATA2LSB: return _("2's complement, little endian");
2962 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 2963 default:
e9e44622 2964 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 2965 return buff;
252b5132
RH
2966 }
2967}
2968
252b5132 2969/* Decode the data held in 'elf_header'. */
ee42cf8c 2970
252b5132 2971static int
d3ba0551 2972process_file_header (void)
252b5132 2973{
b34976b6
AM
2974 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
2975 || elf_header.e_ident[EI_MAG1] != ELFMAG1
2976 || elf_header.e_ident[EI_MAG2] != ELFMAG2
2977 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
2978 {
2979 error
2980 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
2981 return 0;
2982 }
2983
2984 if (do_header)
2985 {
2986 int i;
2987
2988 printf (_("ELF Header:\n"));
2989 printf (_(" Magic: "));
b34976b6
AM
2990 for (i = 0; i < EI_NIDENT; i++)
2991 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
2992 printf ("\n");
2993 printf (_(" Class: %s\n"),
b34976b6 2994 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 2995 printf (_(" Data: %s\n"),
b34976b6 2996 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 2997 printf (_(" Version: %d %s\n"),
b34976b6
AM
2998 elf_header.e_ident[EI_VERSION],
2999 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3000 ? "(current)"
b34976b6 3001 : (elf_header.e_ident[EI_VERSION] != EV_NONE
789be9f7
ILT
3002 ? "<unknown: %lx>"
3003 : "")));
252b5132 3004 printf (_(" OS/ABI: %s\n"),
b34976b6 3005 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3006 printf (_(" ABI Version: %d\n"),
b34976b6 3007 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3008 printf (_(" Type: %s\n"),
3009 get_file_type (elf_header.e_type));
3010 printf (_(" Machine: %s\n"),
3011 get_machine_name (elf_header.e_machine));
3012 printf (_(" Version: 0x%lx\n"),
3013 (unsigned long) elf_header.e_version);
76da6bbe 3014
f7a99963
NC
3015 printf (_(" Entry point address: "));
3016 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3017 printf (_("\n Start of program headers: "));
3018 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3019 printf (_(" (bytes into file)\n Start of section headers: "));
3020 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3021 printf (_(" (bytes into file)\n"));
76da6bbe 3022
252b5132
RH
3023 printf (_(" Flags: 0x%lx%s\n"),
3024 (unsigned long) elf_header.e_flags,
3025 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3026 printf (_(" Size of this header: %ld (bytes)\n"),
3027 (long) elf_header.e_ehsize);
3028 printf (_(" Size of program headers: %ld (bytes)\n"),
3029 (long) elf_header.e_phentsize);
3030 printf (_(" Number of program headers: %ld\n"),
3031 (long) elf_header.e_phnum);
3032 printf (_(" Size of section headers: %ld (bytes)\n"),
3033 (long) elf_header.e_shentsize);
560f3c1c 3034 printf (_(" Number of section headers: %ld"),
252b5132 3035 (long) elf_header.e_shnum);
560f3c1c
AM
3036 if (section_headers != NULL && elf_header.e_shnum == 0)
3037 printf (" (%ld)", (long) section_headers[0].sh_size);
3038 putc ('\n', stdout);
3039 printf (_(" Section header string table index: %ld"),
252b5132 3040 (long) elf_header.e_shstrndx);
560f3c1c
AM
3041 if (section_headers != NULL && elf_header.e_shstrndx == SHN_XINDEX)
3042 printf (" (%ld)", (long) section_headers[0].sh_link);
3043 putc ('\n', stdout);
3044 }
3045
3046 if (section_headers != NULL)
3047 {
3048 if (elf_header.e_shnum == 0)
3049 elf_header.e_shnum = section_headers[0].sh_size;
3050 if (elf_header.e_shstrndx == SHN_XINDEX)
3051 elf_header.e_shstrndx = section_headers[0].sh_link;
3052 free (section_headers);
3053 section_headers = NULL;
252b5132 3054 }
103f02d3 3055
9ea033b2
NC
3056 return 1;
3057}
3058
252b5132 3059
9ea033b2 3060static int
d3ba0551 3061get_32bit_program_headers (FILE *file, Elf_Internal_Phdr *program_headers)
9ea033b2 3062{
b34976b6
AM
3063 Elf32_External_Phdr *phdrs;
3064 Elf32_External_Phdr *external;
3065 Elf_Internal_Phdr *internal;
3066 unsigned int i;
103f02d3 3067
d3ba0551 3068 phdrs = get_data (NULL, file, elf_header.e_phoff,
c256ffe7 3069 elf_header.e_phentsize, elf_header.e_phnum,
d3ba0551 3070 _("program headers"));
a6e9f9df
AM
3071 if (!phdrs)
3072 return 0;
9ea033b2
NC
3073
3074 for (i = 0, internal = program_headers, external = phdrs;
3075 i < elf_header.e_phnum;
b34976b6 3076 i++, internal++, external++)
252b5132 3077 {
9ea033b2
NC
3078 internal->p_type = BYTE_GET (external->p_type);
3079 internal->p_offset = BYTE_GET (external->p_offset);
3080 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3081 internal->p_paddr = BYTE_GET (external->p_paddr);
3082 internal->p_filesz = BYTE_GET (external->p_filesz);
3083 internal->p_memsz = BYTE_GET (external->p_memsz);
3084 internal->p_flags = BYTE_GET (external->p_flags);
3085 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3086 }
3087
9ea033b2
NC
3088 free (phdrs);
3089
252b5132
RH
3090 return 1;
3091}
3092
9ea033b2 3093static int
d3ba0551 3094get_64bit_program_headers (FILE *file, Elf_Internal_Phdr *program_headers)
9ea033b2 3095{
b34976b6
AM
3096 Elf64_External_Phdr *phdrs;
3097 Elf64_External_Phdr *external;
3098 Elf_Internal_Phdr *internal;
3099 unsigned int i;
103f02d3 3100
d3ba0551 3101 phdrs = get_data (NULL, file, elf_header.e_phoff,
c256ffe7 3102 elf_header.e_phentsize, elf_header.e_phnum,
d3ba0551 3103 _("program headers"));
a6e9f9df
AM
3104 if (!phdrs)
3105 return 0;
9ea033b2
NC
3106
3107 for (i = 0, internal = program_headers, external = phdrs;
3108 i < elf_header.e_phnum;
b34976b6 3109 i++, internal++, external++)
9ea033b2
NC
3110 {
3111 internal->p_type = BYTE_GET (external->p_type);
3112 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3113 internal->p_offset = BYTE_GET (external->p_offset);
3114 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3115 internal->p_paddr = BYTE_GET (external->p_paddr);
3116 internal->p_filesz = BYTE_GET (external->p_filesz);
3117 internal->p_memsz = BYTE_GET (external->p_memsz);
3118 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3119 }
3120
3121 free (phdrs);
3122
3123 return 1;
3124}
252b5132 3125
d93f0186
NC
3126/* Returns 1 if the program headers were read into `program_headers'. */
3127
3128static int
d3ba0551 3129get_program_headers (FILE *file)
d93f0186
NC
3130{
3131 Elf_Internal_Phdr *phdrs;
3132
3133 /* Check cache of prior read. */
3134 if (program_headers != NULL)
3135 return 1;
3136
c256ffe7 3137 phdrs = cmalloc (elf_header.e_phnum, sizeof (Elf_Internal_Phdr));
d93f0186
NC
3138
3139 if (phdrs == NULL)
3140 {
3141 error (_("Out of memory\n"));
3142 return 0;
3143 }
3144
3145 if (is_32bit_elf
3146 ? get_32bit_program_headers (file, phdrs)
3147 : get_64bit_program_headers (file, phdrs))
3148 {
3149 program_headers = phdrs;
3150 return 1;
3151 }
3152
3153 free (phdrs);
3154 return 0;
3155}
3156
2f62977e
NC
3157/* Returns 1 if the program headers were loaded. */
3158
252b5132 3159static int
d3ba0551 3160process_program_headers (FILE *file)
252b5132 3161{
b34976b6
AM
3162 Elf_Internal_Phdr *segment;
3163 unsigned int i;
252b5132
RH
3164
3165 if (elf_header.e_phnum == 0)
3166 {
3167 if (do_segments)
3168 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3169 return 0;
252b5132
RH
3170 }
3171
3172 if (do_segments && !do_header)
3173 {
f7a99963
NC
3174 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3175 printf (_("Entry point "));
3176 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3177 printf (_("\nThere are %d program headers, starting at offset "),
3178 elf_header.e_phnum);
3179 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3180 printf ("\n");
252b5132
RH
3181 }
3182
d93f0186 3183 if (! get_program_headers (file))
252b5132 3184 return 0;
103f02d3 3185
252b5132
RH
3186 if (do_segments)
3187 {
3a1a2036
NC
3188 if (elf_header.e_phnum > 1)
3189 printf (_("\nProgram Headers:\n"));
3190 else
3191 printf (_("\nProgram Headers:\n"));
76da6bbe 3192
f7a99963
NC
3193 if (is_32bit_elf)
3194 printf
3195 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3196 else if (do_wide)
3197 printf
3198 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3199 else
3200 {
3201 printf
3202 (_(" Type Offset VirtAddr PhysAddr\n"));
3203 printf
3204 (_(" FileSiz MemSiz Flags Align\n"));
3205 }
252b5132
RH
3206 }
3207
252b5132 3208 dynamic_addr = 0;
1b228002 3209 dynamic_size = 0;
252b5132
RH
3210
3211 for (i = 0, segment = program_headers;
3212 i < elf_header.e_phnum;
b34976b6 3213 i++, segment++)
252b5132
RH
3214 {
3215 if (do_segments)
3216 {
103f02d3 3217 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3218
3219 if (is_32bit_elf)
3220 {
3221 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3222 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3223 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3224 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3225 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3226 printf ("%c%c%c ",
3227 (segment->p_flags & PF_R ? 'R' : ' '),
3228 (segment->p_flags & PF_W ? 'W' : ' '),
3229 (segment->p_flags & PF_X ? 'E' : ' '));
3230 printf ("%#lx", (unsigned long) segment->p_align);
3231 }
d974e256
JJ
3232 else if (do_wide)
3233 {
3234 if ((unsigned long) segment->p_offset == segment->p_offset)
3235 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3236 else
3237 {
3238 print_vma (segment->p_offset, FULL_HEX);
3239 putchar (' ');
3240 }
3241
3242 print_vma (segment->p_vaddr, FULL_HEX);
3243 putchar (' ');
3244 print_vma (segment->p_paddr, FULL_HEX);
3245 putchar (' ');
3246
3247 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3248 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3249 else
3250 {
3251 print_vma (segment->p_filesz, FULL_HEX);
3252 putchar (' ');
3253 }
3254
3255 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3256 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3257 else
3258 {
3259 print_vma (segment->p_offset, FULL_HEX);
3260 }
3261
3262 printf (" %c%c%c ",
3263 (segment->p_flags & PF_R ? 'R' : ' '),
3264 (segment->p_flags & PF_W ? 'W' : ' '),
3265 (segment->p_flags & PF_X ? 'E' : ' '));
3266
3267 if ((unsigned long) segment->p_align == segment->p_align)
3268 printf ("%#lx", (unsigned long) segment->p_align);
3269 else
3270 {
3271 print_vma (segment->p_align, PREFIX_HEX);
3272 }
3273 }
f7a99963
NC
3274 else
3275 {
3276 print_vma (segment->p_offset, FULL_HEX);
3277 putchar (' ');
3278 print_vma (segment->p_vaddr, FULL_HEX);
3279 putchar (' ');
3280 print_vma (segment->p_paddr, FULL_HEX);
3281 printf ("\n ");
3282 print_vma (segment->p_filesz, FULL_HEX);
3283 putchar (' ');
3284 print_vma (segment->p_memsz, FULL_HEX);
3285 printf (" %c%c%c ",
3286 (segment->p_flags & PF_R ? 'R' : ' '),
3287 (segment->p_flags & PF_W ? 'W' : ' '),
3288 (segment->p_flags & PF_X ? 'E' : ' '));
3289 print_vma (segment->p_align, HEX);
3290 }
252b5132
RH
3291 }
3292
3293 switch (segment->p_type)
3294 {
252b5132
RH
3295 case PT_DYNAMIC:
3296 if (dynamic_addr)
3297 error (_("more than one dynamic segment\n"));
3298
b2d38a17
NC
3299 /* Try to locate the .dynamic section. If there is
3300 a section header table, we can easily locate it. */
3301 if (section_headers != NULL)
3302 {
3303 Elf_Internal_Shdr *sec;
b2d38a17 3304
89fac5e3
RS
3305 sec = find_section (".dynamic");
3306 if (sec == NULL || sec->sh_size == 0)
b2d38a17
NC
3307 {
3308 error (_("no .dynamic section in the dynamic segment"));
3309 break;
3310 }
3311
3312 dynamic_addr = sec->sh_offset;
3313 dynamic_size = sec->sh_size;
3314
3315 if (dynamic_addr < segment->p_offset
3316 || dynamic_addr > segment->p_offset + segment->p_filesz)
3317 warn (_("the .dynamic section is not contained within the dynamic segment"));
3318 else if (dynamic_addr > segment->p_offset)
3319 warn (_("the .dynamic section is not the first section in the dynamic segment."));
3320 }
3321 else
3322 {
3323 /* Otherwise, we can only assume that the .dynamic
3324 section is the first section in the DYNAMIC segment. */
3325 dynamic_addr = segment->p_offset;
3326 dynamic_size = segment->p_filesz;
3327 }
252b5132
RH
3328 break;
3329
3330 case PT_INTERP:
fb52b2f4
NC
3331 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3332 SEEK_SET))
252b5132
RH
3333 error (_("Unable to find program interpreter name\n"));
3334 else
3335 {
3336 program_interpreter[0] = 0;
3337 fscanf (file, "%63s", program_interpreter);
3338
3339 if (do_segments)
3340 printf (_("\n [Requesting program interpreter: %s]"),
3341 program_interpreter);
3342 }
3343 break;
3344 }
3345
3346 if (do_segments)
3347 putc ('\n', stdout);
3348 }
3349
c256ffe7 3350 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
3351 {
3352 printf (_("\n Section to Segment mapping:\n"));
3353 printf (_(" Segment Sections...\n"));
3354
252b5132
RH
3355 for (i = 0; i < elf_header.e_phnum; i++)
3356 {
9ad5cbcf 3357 unsigned int j;
b34976b6 3358 Elf_Internal_Shdr *section;
252b5132
RH
3359
3360 segment = program_headers + i;
3361 section = section_headers;
3362
3363 printf (" %2.2d ", i);
3364
b34976b6 3365 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132
RH
3366 {
3367 if (section->sh_size > 0
3368 /* Compare allocated sections by VMA, unallocated
3369 sections by file offset. */
3370 && (section->sh_flags & SHF_ALLOC
3371 ? (section->sh_addr >= segment->p_vaddr
3372 && section->sh_addr + section->sh_size
3373 <= segment->p_vaddr + segment->p_memsz)
b4c96d0d 3374 : ((bfd_vma) section->sh_offset >= segment->p_offset
252b5132 3375 && (section->sh_offset + section->sh_size
cbaa0dc5
AM
3376 <= segment->p_offset + segment->p_filesz)))
3377 /* .tbss is special. It doesn't contribute memory space
3378 to normal segments. */
3379 && (!((section->sh_flags & SHF_TLS) != 0
3380 && section->sh_type == SHT_NOBITS)
3381 || segment->p_type == PT_TLS))
252b5132
RH
3382 printf ("%s ", SECTION_NAME (section));
3383 }
3384
3385 putc ('\n',stdout);
3386 }
3387 }
3388
252b5132
RH
3389 return 1;
3390}
3391
3392
d93f0186
NC
3393/* Find the file offset corresponding to VMA by using the program headers. */
3394
3395static long
d3ba0551 3396offset_from_vma (FILE *file, bfd_vma vma, bfd_size_type size)
d93f0186
NC
3397{
3398 Elf_Internal_Phdr *seg;
3399
3400 if (! get_program_headers (file))
3401 {
3402 warn (_("Cannot interpret virtual addresses without program headers.\n"));
3403 return (long) vma;
3404 }
3405
3406 for (seg = program_headers;
3407 seg < program_headers + elf_header.e_phnum;
3408 ++seg)
3409 {
3410 if (seg->p_type != PT_LOAD)
3411 continue;
3412
3413 if (vma >= (seg->p_vaddr & -seg->p_align)
3414 && vma + size <= seg->p_vaddr + seg->p_filesz)
3415 return vma - seg->p_vaddr + seg->p_offset;
3416 }
3417
3418 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
3419 (long) vma);
3420 return (long) vma;
3421}
3422
3423
252b5132 3424static int
d3ba0551 3425get_32bit_section_headers (FILE *file, unsigned int num)
252b5132 3426{
b34976b6
AM
3427 Elf32_External_Shdr *shdrs;
3428 Elf_Internal_Shdr *internal;
3429 unsigned int i;
252b5132 3430
d3ba0551 3431 shdrs = get_data (NULL, file, elf_header.e_shoff,
c256ffe7 3432 elf_header.e_shentsize, num, _("section headers"));
a6e9f9df
AM
3433 if (!shdrs)
3434 return 0;
252b5132 3435
c256ffe7 3436 section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
252b5132
RH
3437
3438 if (section_headers == NULL)
3439 {
3440 error (_("Out of memory\n"));
3441 return 0;
3442 }
3443
3444 for (i = 0, internal = section_headers;
560f3c1c 3445 i < num;
b34976b6 3446 i++, internal++)
252b5132
RH
3447 {
3448 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3449 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
3450 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3451 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3452 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3453 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3454 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3455 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3456 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3457 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
3458 }
3459
3460 free (shdrs);
3461
3462 return 1;
3463}
3464
9ea033b2 3465static int
d3ba0551 3466get_64bit_section_headers (FILE *file, unsigned int num)
9ea033b2 3467{
b34976b6
AM
3468 Elf64_External_Shdr *shdrs;
3469 Elf_Internal_Shdr *internal;
3470 unsigned int i;
9ea033b2 3471
d3ba0551 3472 shdrs = get_data (NULL, file, elf_header.e_shoff,
c256ffe7 3473 elf_header.e_shentsize, num, _("section headers"));
a6e9f9df
AM
3474 if (!shdrs)
3475 return 0;
9ea033b2 3476
c256ffe7 3477 section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
9ea033b2
NC
3478
3479 if (section_headers == NULL)
3480 {
3481 error (_("Out of memory\n"));
3482 return 0;
3483 }
3484
3485 for (i = 0, internal = section_headers;
560f3c1c 3486 i < num;
b34976b6 3487 i++, internal++)
9ea033b2
NC
3488 {
3489 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3490 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
3491 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3492 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3493 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3494 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
3495 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3496 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3497 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3498 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3499 }
3500
3501 free (shdrs);
3502
3503 return 1;
3504}
3505
252b5132 3506static Elf_Internal_Sym *
d3ba0551 3507get_32bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section)
252b5132 3508{
9ad5cbcf 3509 unsigned long number;
b34976b6 3510 Elf32_External_Sym *esyms;
9ad5cbcf 3511 Elf_External_Sym_Shndx *shndx;
b34976b6
AM
3512 Elf_Internal_Sym *isyms;
3513 Elf_Internal_Sym *psym;
3514 unsigned int j;
252b5132 3515
c256ffe7 3516 esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
d3ba0551 3517 _("symbols"));
a6e9f9df
AM
3518 if (!esyms)
3519 return NULL;
252b5132 3520
9ad5cbcf
AM
3521 shndx = NULL;
3522 if (symtab_shndx_hdr != NULL
3523 && (symtab_shndx_hdr->sh_link
3524 == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
3525 {
d3ba0551 3526 shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
c256ffe7 3527 1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
9ad5cbcf
AM
3528 if (!shndx)
3529 {
3530 free (esyms);
3531 return NULL;
3532 }
3533 }
3534
3535 number = section->sh_size / section->sh_entsize;
c256ffe7 3536 isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
3537
3538 if (isyms == NULL)
3539 {
3540 error (_("Out of memory\n"));
9ad5cbcf
AM
3541 if (shndx)
3542 free (shndx);
252b5132 3543 free (esyms);
252b5132
RH
3544 return NULL;
3545 }
3546
3547 for (j = 0, psym = isyms;
3548 j < number;
b34976b6 3549 j++, psym++)
252b5132
RH
3550 {
3551 psym->st_name = BYTE_GET (esyms[j].st_name);
3552 psym->st_value = BYTE_GET (esyms[j].st_value);
3553 psym->st_size = BYTE_GET (esyms[j].st_size);
3554 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
9ad5cbcf
AM
3555 if (psym->st_shndx == SHN_XINDEX && shndx != NULL)
3556 psym->st_shndx
3557 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
252b5132
RH
3558 psym->st_info = BYTE_GET (esyms[j].st_info);
3559 psym->st_other = BYTE_GET (esyms[j].st_other);
3560 }
3561
9ad5cbcf
AM
3562 if (shndx)
3563 free (shndx);
252b5132
RH
3564 free (esyms);
3565
3566 return isyms;
3567}
3568
9ea033b2 3569static Elf_Internal_Sym *
d3ba0551 3570get_64bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section)
9ea033b2 3571{
9ad5cbcf 3572 unsigned long number;
b34976b6 3573 Elf64_External_Sym *esyms;
9ad5cbcf 3574 Elf_External_Sym_Shndx *shndx;
b34976b6
AM
3575 Elf_Internal_Sym *isyms;
3576 Elf_Internal_Sym *psym;
3577 unsigned int j;
9ea033b2 3578
c256ffe7 3579 esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
d3ba0551 3580 _("symbols"));
a6e9f9df
AM
3581 if (!esyms)
3582 return NULL;
9ea033b2 3583
9ad5cbcf
AM
3584 shndx = NULL;
3585 if (symtab_shndx_hdr != NULL
3586 && (symtab_shndx_hdr->sh_link
3587 == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
3588 {
d3ba0551 3589 shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
c256ffe7 3590 1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
9ad5cbcf
AM
3591 if (!shndx)
3592 {
3593 free (esyms);
3594 return NULL;
3595 }
3596 }
3597
3598 number = section->sh_size / section->sh_entsize;
c256ffe7 3599 isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
3600
3601 if (isyms == NULL)
3602 {
3603 error (_("Out of memory\n"));
9ad5cbcf
AM
3604 if (shndx)
3605 free (shndx);
9ea033b2 3606 free (esyms);
9ea033b2
NC
3607 return NULL;
3608 }
3609
3610 for (j = 0, psym = isyms;
3611 j < number;
b34976b6 3612 j++, psym++)
9ea033b2
NC
3613 {
3614 psym->st_name = BYTE_GET (esyms[j].st_name);
3615 psym->st_info = BYTE_GET (esyms[j].st_info);
3616 psym->st_other = BYTE_GET (esyms[j].st_other);
3617 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
9ad5cbcf
AM
3618 if (psym->st_shndx == SHN_XINDEX && shndx != NULL)
3619 psym->st_shndx
3620 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
66543521
AM
3621 psym->st_value = BYTE_GET (esyms[j].st_value);
3622 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
3623 }
3624
9ad5cbcf
AM
3625 if (shndx)
3626 free (shndx);
9ea033b2
NC
3627 free (esyms);
3628
3629 return isyms;
3630}
3631
d1133906 3632static const char *
d3ba0551 3633get_elf_section_flags (bfd_vma sh_flags)
d1133906 3634{
5477e8a0 3635 static char buff[1024];
e9e44622 3636 char *p = buff;
8d5ff12c
L
3637 int field_size = is_32bit_elf ? 8 : 16;
3638 int index, size = sizeof (buff) - (field_size + 4 + 1);
3639 bfd_vma os_flags = 0;
3640 bfd_vma proc_flags = 0;
3641 bfd_vma unknown_flags = 0;
5477e8a0
L
3642 const struct
3643 {
3644 const char *str;
3645 int len;
3646 }
3647 flags [] =
3648 {
3649 { "WRITE", 5 },
3650 { "ALLOC", 5 },
3651 { "EXEC", 4 },
3652 { "MERGE", 5 },
3653 { "STRINGS", 7 },
3654 { "INFO LINK", 9 },
3655 { "LINK ORDER", 10 },
3656 { "OS NONCONF", 10 },
3657 { "GROUP", 5 },
3658 { "TLS", 3 }
3659 };
3660
3661 if (do_section_details)
3662 {
8d5ff12c
L
3663 sprintf (buff, "[%*.*lx]: ",
3664 field_size, field_size, (unsigned long) sh_flags);
3665 p += field_size + 4;
5477e8a0 3666 }
76da6bbe 3667
d1133906
NC
3668 while (sh_flags)
3669 {
3670 bfd_vma flag;
3671
3672 flag = sh_flags & - sh_flags;
3673 sh_flags &= ~ flag;
76da6bbe 3674
5477e8a0 3675 if (do_section_details)
d1133906 3676 {
5477e8a0
L
3677 switch (flag)
3678 {
3679 case SHF_WRITE: index = 0; break;
3680 case SHF_ALLOC: index = 1; break;
3681 case SHF_EXECINSTR: index = 2; break;
3682 case SHF_MERGE: index = 3; break;
3683 case SHF_STRINGS: index = 4; break;
3684 case SHF_INFO_LINK: index = 5; break;
3685 case SHF_LINK_ORDER: index = 6; break;
3686 case SHF_OS_NONCONFORMING: index = 7; break;
3687 case SHF_GROUP: index = 8; break;
3688 case SHF_TLS: index = 9; break;
76da6bbe 3689
5477e8a0
L
3690 default:
3691 index = -1;
3692 break;
3693 }
3694
5477e8a0
L
3695 if (index != -1)
3696 {
8d5ff12c
L
3697 if (p != buff + field_size + 4)
3698 {
3699 if (size < (10 + 2))
3700 abort ();
3701 size -= 2;
3702 *p++ = ',';
3703 *p++ = ' ';
3704 }
3705
5477e8a0
L
3706 size -= flags [index].len;
3707 p = stpcpy (p, flags [index].str);
3708 }
3b22753a 3709 else if (flag & SHF_MASKOS)
8d5ff12c 3710 os_flags |= flag;
d1133906 3711 else if (flag & SHF_MASKPROC)
8d5ff12c 3712 proc_flags |= flag;
d1133906 3713 else
8d5ff12c 3714 unknown_flags |= flag;
5477e8a0
L
3715 }
3716 else
3717 {
3718 switch (flag)
3719 {
3720 case SHF_WRITE: *p = 'W'; break;
3721 case SHF_ALLOC: *p = 'A'; break;
3722 case SHF_EXECINSTR: *p = 'X'; break;
3723 case SHF_MERGE: *p = 'M'; break;
3724 case SHF_STRINGS: *p = 'S'; break;
3725 case SHF_INFO_LINK: *p = 'I'; break;
3726 case SHF_LINK_ORDER: *p = 'L'; break;
3727 case SHF_OS_NONCONFORMING: *p = 'O'; break;
3728 case SHF_GROUP: *p = 'G'; break;
3729 case SHF_TLS: *p = 'T'; break;
3730
3731 default:
3732 if (elf_header.e_machine == EM_X86_64
3733 && flag == SHF_X86_64_LARGE)
3734 *p = 'l';
3735 else if (flag & SHF_MASKOS)
3736 {
3737 *p = 'o';
3738 sh_flags &= ~ SHF_MASKOS;
3739 }
3740 else if (flag & SHF_MASKPROC)
3741 {
3742 *p = 'p';
3743 sh_flags &= ~ SHF_MASKPROC;
3744 }
3745 else
3746 *p = 'x';
3747 break;
3748 }
3749 p++;
d1133906
NC
3750 }
3751 }
76da6bbe 3752
8d5ff12c
L
3753 if (do_section_details)
3754 {
3755 if (os_flags)
3756 {
3757 size -= 5 + field_size;
3758 if (p != buff + field_size + 4)
3759 {
3760 if (size < (2 + 1))
3761 abort ();
3762 size -= 2;
3763 *p++ = ',';
3764 *p++ = ' ';
3765 }
3766 sprintf (p, "OS (%*.*lx)", field_size, field_size,
3767 (unsigned long) os_flags);
3768 p += 5 + field_size;
3769 }
3770 if (proc_flags)
3771 {
3772 size -= 7 + field_size;
3773 if (p != buff + field_size + 4)
3774 {
3775 if (size < (2 + 1))
3776 abort ();
3777 size -= 2;
3778 *p++ = ',';
3779 *p++ = ' ';
3780 }
3781 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
3782 (unsigned long) proc_flags);
3783 p += 7 + field_size;
3784 }
3785 if (unknown_flags)
3786 {
3787 size -= 10 + field_size;
3788 if (p != buff + field_size + 4)
3789 {
3790 if (size < (2 + 1))
3791 abort ();
3792 size -= 2;
3793 *p++ = ',';
3794 *p++ = ' ';
3795 }
3796 sprintf (p, "UNKNOWN (%*.*lx)", field_size, field_size,
3797 (unsigned long) unknown_flags);
3798 p += 10 + field_size;
3799 }
3800 }
3801
e9e44622 3802 *p = '\0';
d1133906
NC
3803 return buff;
3804}
3805
252b5132 3806static int
d3ba0551 3807process_section_headers (FILE *file)
252b5132 3808{
b34976b6
AM
3809 Elf_Internal_Shdr *section;
3810 unsigned int i;
252b5132
RH
3811
3812 section_headers = NULL;
3813
3814 if (elf_header.e_shnum == 0)
3815 {
3816 if (do_sections)
3817 printf (_("\nThere are no sections in this file.\n"));
3818
3819 return 1;
3820 }
3821
3822 if (do_sections && !do_header)
9ea033b2 3823 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
3824 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
3825
9ea033b2
NC
3826 if (is_32bit_elf)
3827 {
560f3c1c 3828 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
3829 return 0;
3830 }
560f3c1c 3831 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
3832 return 0;
3833
3834 /* Read in the string table, so that we have names to display. */
c256ffe7 3835 if (SECTION_HEADER_INDEX (elf_header.e_shstrndx) < elf_header.e_shnum)
252b5132 3836 {
c256ffe7 3837 section = SECTION_HEADER (elf_header.e_shstrndx);
d40ac9bd 3838
c256ffe7
JJ
3839 if (section->sh_size != 0)
3840 {
3841 string_table = get_data (NULL, file, section->sh_offset,
3842 1, section->sh_size, _("string table"));
0de14b54 3843
c256ffe7
JJ
3844 string_table_length = string_table != NULL ? section->sh_size : 0;
3845 }
252b5132
RH
3846 }
3847
3848 /* Scan the sections for the dynamic symbol table
e3c8793a 3849 and dynamic string table and debug sections. */
252b5132
RH
3850 dynamic_symbols = NULL;
3851 dynamic_strings = NULL;
3852 dynamic_syminfo = NULL;
f1ef08cb 3853 symtab_shndx_hdr = NULL;
103f02d3 3854
89fac5e3
RS
3855 eh_addr_size = is_32bit_elf ? 4 : 8;
3856 switch (elf_header.e_machine)
3857 {
3858 case EM_MIPS:
3859 case EM_MIPS_RS3_LE:
3860 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
3861 FDE addresses. However, the ABI also has a semi-official ILP32
3862 variant for which the normal FDE address size rules apply.
3863
3864 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
3865 section, where XX is the size of longs in bits. Unfortunately,
3866 earlier compilers provided no way of distinguishing ILP32 objects
3867 from LP64 objects, so if there's any doubt, we should assume that
3868 the official LP64 form is being used. */
3869 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
3870 && find_section (".gcc_compiled_long32") == NULL)
3871 eh_addr_size = 8;
3872 break;
3873 }
3874
08d8fa11
JJ
3875#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
3876 do \
3877 { \
3878 size_t expected_entsize \
3879 = is_32bit_elf ? size32 : size64; \
3880 if (section->sh_entsize != expected_entsize) \
3881 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
3882 i, (unsigned long int) section->sh_entsize, \
3883 (unsigned long int) expected_entsize); \
3884 section->sh_entsize = expected_entsize; \
3885 } \
3886 while (0)
3887#define CHECK_ENTSIZE(section, i, type) \
3888 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
3889 sizeof (Elf64_External_##type))
3890
252b5132
RH
3891 for (i = 0, section = section_headers;
3892 i < elf_header.e_shnum;
b34976b6 3893 i++, section++)
252b5132 3894 {
b34976b6 3895 char *name = SECTION_NAME (section);
252b5132
RH
3896
3897 if (section->sh_type == SHT_DYNSYM)
3898 {
3899 if (dynamic_symbols != NULL)
3900 {
3901 error (_("File contains multiple dynamic symbol tables\n"));
3902 continue;
3903 }
3904
08d8fa11 3905 CHECK_ENTSIZE (section, i, Sym);
19936277 3906 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 3907 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
3908 }
3909 else if (section->sh_type == SHT_STRTAB
18bd398b 3910 && streq (name, ".dynstr"))
252b5132
RH
3911 {
3912 if (dynamic_strings != NULL)
3913 {
3914 error (_("File contains multiple dynamic string tables\n"));
3915 continue;
3916 }
3917
d3ba0551 3918 dynamic_strings = get_data (NULL, file, section->sh_offset,
c256ffe7 3919 1, section->sh_size, _("dynamic strings"));
d79b3d50 3920 dynamic_strings_length = section->sh_size;
252b5132 3921 }
9ad5cbcf
AM
3922 else if (section->sh_type == SHT_SYMTAB_SHNDX)
3923 {
3924 if (symtab_shndx_hdr != NULL)
3925 {
3926 error (_("File contains multiple symtab shndx tables\n"));
3927 continue;
3928 }
3929 symtab_shndx_hdr = section;
3930 }
08d8fa11
JJ
3931 else if (section->sh_type == SHT_SYMTAB)
3932 CHECK_ENTSIZE (section, i, Sym);
3933 else if (section->sh_type == SHT_GROUP)
3934 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
3935 else if (section->sh_type == SHT_REL)
3936 CHECK_ENTSIZE (section, i, Rel);
3937 else if (section->sh_type == SHT_RELA)
3938 CHECK_ENTSIZE (section, i, Rela);
252b5132 3939 else if ((do_debugging || do_debug_info || do_debug_abbrevs
31b6fca6 3940 || do_debug_lines || do_debug_pubnames || do_debug_aranges
a2f14207 3941 || do_debug_frames || do_debug_macinfo || do_debug_str
18bd398b
NC
3942 || do_debug_loc || do_debug_ranges)
3943 && strneq (name, ".debug_", 7))
252b5132
RH
3944 {
3945 name += 7;
3946
3947 if (do_debugging
18bd398b
NC
3948 || (do_debug_info && streq (name, "info"))
3949 || (do_debug_abbrevs && streq (name, "abbrev"))
3950 || (do_debug_lines && streq (name, "line"))
3951 || (do_debug_pubnames && streq (name, "pubnames"))
3952 || (do_debug_aranges && streq (name, "aranges"))
3953 || (do_debug_ranges && streq (name, "ranges"))
3954 || (do_debug_frames && streq (name, "frame"))
3955 || (do_debug_macinfo && streq (name, "macinfo"))
3956 || (do_debug_str && streq (name, "str"))
3957 || (do_debug_loc && streq (name, "loc"))
252b5132
RH
3958 )
3959 request_dump (i, DEBUG_DUMP);
3960 }
09fd7e38
JM
3961 /* linkonce section to be combined with .debug_info at link time. */
3962 else if ((do_debugging || do_debug_info)
18bd398b 3963 && strneq (name, ".gnu.linkonce.wi.", 17))
09fd7e38 3964 request_dump (i, DEBUG_DUMP);
18bd398b 3965 else if (do_debug_frames && streq (name, ".eh_frame"))
c47d488e 3966 request_dump (i, DEBUG_DUMP);
252b5132
RH
3967 }
3968
3969 if (! do_sections)
3970 return 1;
3971
3a1a2036
NC
3972 if (elf_header.e_shnum > 1)
3973 printf (_("\nSection Headers:\n"));
3974 else
3975 printf (_("\nSection Header:\n"));
76da6bbe 3976
f7a99963 3977 if (is_32bit_elf)
595cf52e 3978 {
5477e8a0 3979 if (do_section_details)
595cf52e
L
3980 {
3981 printf (_(" [Nr] Name\n"));
5477e8a0 3982 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
3983 }
3984 else
3985 printf
3986 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
3987 }
d974e256 3988 else if (do_wide)
595cf52e 3989 {
5477e8a0 3990 if (do_section_details)
595cf52e
L
3991 {
3992 printf (_(" [Nr] Name\n"));
5477e8a0 3993 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
3994 }
3995 else
3996 printf
3997 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
3998 }
f7a99963
NC
3999 else
4000 {
5477e8a0 4001 if (do_section_details)
595cf52e
L
4002 {
4003 printf (_(" [Nr] Name\n"));
5477e8a0
L
4004 printf (_(" Type Address Offset Link\n"));
4005 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4006 }
4007 else
4008 {
4009 printf (_(" [Nr] Name Type Address Offset\n"));
4010 printf (_(" Size EntSize Flags Link Info Align\n"));
4011 }
f7a99963 4012 }
252b5132 4013
5477e8a0
L
4014 if (do_section_details)
4015 printf (_(" Flags\n"));
4016
252b5132
RH
4017 for (i = 0, section = section_headers;
4018 i < elf_header.e_shnum;
b34976b6 4019 i++, section++)
252b5132 4020 {
5477e8a0 4021 if (do_section_details)
595cf52e
L
4022 {
4023 printf (" [%2u] %s\n",
4024 SECTION_HEADER_NUM (i),
4025 SECTION_NAME (section));
4026 if (is_32bit_elf || do_wide)
4027 printf (" %-15.15s ",
4028 get_section_type_name (section->sh_type));
4029 }
4030 else
4031 printf (" [%2u] %-17.17s %-15.15s ",
4032 SECTION_HEADER_NUM (i),
4033 SECTION_NAME (section),
4034 get_section_type_name (section->sh_type));
252b5132 4035
f7a99963
NC
4036 if (is_32bit_elf)
4037 {
4038 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4039
f7a99963
NC
4040 printf ( " %6.6lx %6.6lx %2.2lx",
4041 (unsigned long) section->sh_offset,
4042 (unsigned long) section->sh_size,
4043 (unsigned long) section->sh_entsize);
d1133906 4044
5477e8a0
L
4045 if (do_section_details)
4046 fputs (" ", stdout);
4047 else
4048 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4049
f2da459f 4050 printf ("%2ld %3lu %2ld\n",
f7a99963
NC
4051 (unsigned long) section->sh_link,
4052 (unsigned long) section->sh_info,
4053 (unsigned long) section->sh_addralign);
4054 }
d974e256
JJ
4055 else if (do_wide)
4056 {
4057 print_vma (section->sh_addr, LONG_HEX);
4058
4059 if ((long) section->sh_offset == section->sh_offset)
4060 printf (" %6.6lx", (unsigned long) section->sh_offset);
4061 else
4062 {
4063 putchar (' ');
4064 print_vma (section->sh_offset, LONG_HEX);
4065 }
4066
4067 if ((unsigned long) section->sh_size == section->sh_size)
4068 printf (" %6.6lx", (unsigned long) section->sh_size);
4069 else
4070 {
4071 putchar (' ');
4072 print_vma (section->sh_size, LONG_HEX);
4073 }
4074
4075 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4076 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4077 else
4078 {
4079 putchar (' ');
4080 print_vma (section->sh_entsize, LONG_HEX);
4081 }
4082
5477e8a0
L
4083 if (do_section_details)
4084 fputs (" ", stdout);
4085 else
4086 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4087
f2da459f 4088 printf ("%2ld %3lu ",
d974e256
JJ
4089 (unsigned long) section->sh_link,
4090 (unsigned long) section->sh_info);
4091
4092 if ((unsigned long) section->sh_addralign == section->sh_addralign)
4093 printf ("%2ld\n", (unsigned long) section->sh_addralign);
4094 else
4095 {
4096 print_vma (section->sh_addralign, DEC);
4097 putchar ('\n');
4098 }
4099 }
5477e8a0 4100 else if (do_section_details)
595cf52e 4101 {
5477e8a0 4102 printf (" %-15.15s ",
595cf52e 4103 get_section_type_name (section->sh_type));
595cf52e
L
4104 print_vma (section->sh_addr, LONG_HEX);
4105 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4106 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4107 else
4108 {
4109 printf (" ");
4110 print_vma (section->sh_offset, LONG_HEX);
4111 }
5477e8a0 4112 printf (" %ld\n ", (unsigned long) section->sh_link);
595cf52e 4113 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4114 putchar (' ');
595cf52e
L
4115 print_vma (section->sh_entsize, LONG_HEX);
4116
5477e8a0 4117 printf (" %-16lu %ld\n",
595cf52e
L
4118 (unsigned long) section->sh_info,
4119 (unsigned long) section->sh_addralign);
4120 }
f7a99963
NC
4121 else
4122 {
4123 putchar (' ');
4124 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4125 if ((long) section->sh_offset == section->sh_offset)
4126 printf (" %8.8lx", (unsigned long) section->sh_offset);
4127 else
4128 {
4129 printf (" ");
4130 print_vma (section->sh_offset, LONG_HEX);
4131 }
f7a99963
NC
4132 printf ("\n ");
4133 print_vma (section->sh_size, LONG_HEX);
4134 printf (" ");
4135 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4136
d1133906 4137 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4138
f2da459f 4139 printf (" %2ld %3lu %ld\n",
f7a99963
NC
4140 (unsigned long) section->sh_link,
4141 (unsigned long) section->sh_info,
4142 (unsigned long) section->sh_addralign);
4143 }
5477e8a0
L
4144
4145 if (do_section_details)
4146 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4147 }
4148
5477e8a0
L
4149 if (!do_section_details)
4150 printf (_("Key to Flags:\n\
e3c8793a
NC
4151 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
4152 I (info), L (link order), G (group), x (unknown)\n\
4153 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
d1133906 4154
252b5132
RH
4155 return 1;
4156}
4157
f5842774
L
4158static const char *
4159get_group_flags (unsigned int flags)
4160{
4161 static char buff[32];
4162 switch (flags)
4163 {
4164 case GRP_COMDAT:
4165 return "COMDAT";
4166
4167 default:
e9e44622 4168 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x]"), flags);
f5842774
L
4169 break;
4170 }
4171 return buff;
4172}
4173
4174static int
4175process_section_groups (FILE *file)
4176{
4177 Elf_Internal_Shdr *section;
4178 unsigned int i;
e4b17d5c 4179 struct group *group;
d1f5c6e3
L
4180 Elf_Internal_Shdr *symtab_sec, *strtab_sec;
4181 Elf_Internal_Sym *symtab;
4182 char *strtab;
c256ffe7 4183 size_t strtab_size;
d1f5c6e3
L
4184
4185 /* Don't process section groups unless needed. */
4186 if (!do_unwind && !do_section_groups)
4187 return 1;
f5842774
L
4188
4189 if (elf_header.e_shnum == 0)
4190 {
4191 if (do_section_groups)
d1f5c6e3 4192 printf (_("\nThere are no sections in this file.\n"));
f5842774
L
4193
4194 return 1;
4195 }
4196
4197 if (section_headers == NULL)
4198 {
4199 error (_("Section headers are not available!\n"));
4200 abort ();
4201 }
4202
e4b17d5c
L
4203 section_headers_groups = calloc (elf_header.e_shnum,
4204 sizeof (struct group *));
4205
4206 if (section_headers_groups == NULL)
4207 {
4208 error (_("Out of memory\n"));
4209 return 0;
4210 }
4211
f5842774 4212 /* Scan the sections for the group section. */
d1f5c6e3 4213 group_count = 0;
f5842774
L
4214 for (i = 0, section = section_headers;
4215 i < elf_header.e_shnum;
4216 i++, section++)
e4b17d5c
L
4217 if (section->sh_type == SHT_GROUP)
4218 group_count++;
4219
d1f5c6e3
L
4220 if (group_count == 0)
4221 {
4222 if (do_section_groups)
4223 printf (_("\nThere are no section groups in this file.\n"));
4224
4225 return 1;
4226 }
4227
e4b17d5c
L
4228 section_groups = calloc (group_count, sizeof (struct group));
4229
4230 if (section_groups == NULL)
4231 {
4232 error (_("Out of memory\n"));
4233 return 0;
4234 }
4235
d1f5c6e3
L
4236 symtab_sec = NULL;
4237 strtab_sec = NULL;
4238 symtab = NULL;
4239 strtab = NULL;
c256ffe7 4240 strtab_size = 0;
e4b17d5c
L
4241 for (i = 0, section = section_headers, group = section_groups;
4242 i < elf_header.e_shnum;
4243 i++, section++)
f5842774
L
4244 {
4245 if (section->sh_type == SHT_GROUP)
4246 {
4247 char *name = SECTION_NAME (section);
dc3c06c2
AM
4248 char *group_name;
4249 unsigned char *start, *indices;
f5842774 4250 unsigned int entry, j, size;
d1f5c6e3 4251 Elf_Internal_Shdr *sec;
f5842774 4252 Elf_Internal_Sym *sym;
f5842774
L
4253
4254 /* Get the symbol table. */
c256ffe7
JJ
4255 if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum
4256 || ((sec = SECTION_HEADER (section->sh_link))->sh_type
4257 != SHT_SYMTAB))
f5842774
L
4258 {
4259 error (_("Bad sh_link in group section `%s'\n"), name);
4260 continue;
4261 }
d1f5c6e3
L
4262
4263 if (symtab_sec != sec)
4264 {
4265 symtab_sec = sec;
4266 if (symtab)
4267 free (symtab);
4268 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
4269 }
f5842774
L
4270
4271 sym = symtab + section->sh_info;
4272
4273 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4274 {
4275 bfd_vma sec_index = SECTION_HEADER_INDEX (sym->st_shndx);
4276 if (sec_index == 0)
4277 {
4278 error (_("Bad sh_info in group section `%s'\n"), name);
4279 continue;
4280 }
ba2685cc 4281
f5842774 4282 group_name = SECTION_NAME (section_headers + sec_index);
c256ffe7
JJ
4283 strtab_sec = NULL;
4284 if (strtab)
4285 free (strtab);
f5842774 4286 strtab = NULL;
c256ffe7 4287 strtab_size = 0;
f5842774
L
4288 }
4289 else
4290 {
4291 /* Get the string table. */
c256ffe7
JJ
4292 if (SECTION_HEADER_INDEX (symtab_sec->sh_link)
4293 >= elf_header.e_shnum)
4294 {
4295 strtab_sec = NULL;
4296 if (strtab)
4297 free (strtab);
4298 strtab = NULL;
4299 strtab_size = 0;
4300 }
4301 else if (strtab_sec
4302 != (sec = SECTION_HEADER (symtab_sec->sh_link)))
d1f5c6e3
L
4303 {
4304 strtab_sec = sec;
4305 if (strtab)
4306 free (strtab);
4307 strtab = get_data (NULL, file, strtab_sec->sh_offset,
c256ffe7 4308 1, strtab_sec->sh_size,
d1f5c6e3 4309 _("string table"));
c256ffe7 4310 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 4311 }
c256ffe7
JJ
4312 group_name = sym->st_name < strtab_size
4313 ? strtab + sym->st_name : "<corrupt>";
f5842774
L
4314 }
4315
4316 start = get_data (NULL, file, section->sh_offset,
c256ffe7 4317 1, section->sh_size, _("section data"));
f5842774
L
4318
4319 indices = start;
4320 size = (section->sh_size / section->sh_entsize) - 1;
4321 entry = byte_get (indices, 4);
4322 indices += 4;
e4b17d5c
L
4323
4324 if (do_section_groups)
4325 {
391cb864
L
4326 printf ("\n%s group section [%5u] `%s' [%s] contains %u sections:\n",
4327 get_group_flags (entry), i, name, group_name, size);
ba2685cc 4328
e4b17d5c
L
4329 printf (_(" [Index] Name\n"));
4330 }
4331
4332 group->group_index = i;
4333
f5842774
L
4334 for (j = 0; j < size; j++)
4335 {
e4b17d5c
L
4336 struct group_list *g;
4337
f5842774
L
4338 entry = byte_get (indices, 4);
4339 indices += 4;
4340
c256ffe7 4341 if (SECTION_HEADER_INDEX (entry) >= elf_header.e_shnum)
391cb864
L
4342 {
4343 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
4344 entry, i, elf_header.e_shnum - 1);
4345 continue;
4346 }
4347 else if (entry >= SHN_LORESERVE && entry <= SHN_HIRESERVE)
4348 {
4349 error (_("invalid section [%5u] in group section [%5u]\n"),
4350 entry, i);
4351 continue;
4352 }
4353
e4b17d5c
L
4354 if (section_headers_groups [SECTION_HEADER_INDEX (entry)]
4355 != NULL)
4356 {
d1f5c6e3
L
4357 if (entry)
4358 {
391cb864
L
4359 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
4360 entry, i,
d1f5c6e3
L
4361 section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
4362 continue;
4363 }
4364 else
4365 {
4366 /* Intel C/C++ compiler may put section 0 in a
4367 section group. We just warn it the first time
4368 and ignore it afterwards. */
4369 static int warned = 0;
4370 if (!warned)
4371 {
4372 error (_("section 0 in group section [%5u]\n"),
4373 section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
4374 warned++;
4375 }
4376 }
e4b17d5c
L
4377 }
4378
4379 section_headers_groups [SECTION_HEADER_INDEX (entry)]
4380 = group;
4381
4382 if (do_section_groups)
4383 {
4384 sec = SECTION_HEADER (entry);
c256ffe7 4385 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
4386 }
4387
e4b17d5c
L
4388 g = xmalloc (sizeof (struct group_list));
4389 g->section_index = entry;
4390 g->next = group->root;
4391 group->root = g;
f5842774
L
4392 }
4393
f5842774
L
4394 if (start)
4395 free (start);
e4b17d5c
L
4396
4397 group++;
f5842774
L
4398 }
4399 }
4400
d1f5c6e3
L
4401 if (symtab)
4402 free (symtab);
4403 if (strtab)
4404 free (strtab);
f5842774
L
4405 return 1;
4406}
4407
85b1c36d 4408static struct
566b0d53
L
4409{
4410 const char *name;
4411 int reloc;
4412 int size;
4413 int rela;
4414} dynamic_relocations [] =
4415{
4416 { "REL", DT_REL, DT_RELSZ, FALSE },
4417 { "RELA", DT_RELA, DT_RELASZ, TRUE },
4418 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
4419};
4420
252b5132 4421/* Process the reloc section. */
18bd398b 4422
252b5132 4423static int
d3ba0551 4424process_relocs (FILE *file)
252b5132 4425{
b34976b6
AM
4426 unsigned long rel_size;
4427 unsigned long rel_offset;
252b5132
RH
4428
4429
4430 if (!do_reloc)
4431 return 1;
4432
4433 if (do_using_dynamic)
4434 {
566b0d53
L
4435 int is_rela;
4436 const char *name;
4437 int has_dynamic_reloc;
4438 unsigned int i;
0de14b54 4439
566b0d53 4440 has_dynamic_reloc = 0;
252b5132 4441
566b0d53 4442 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 4443 {
566b0d53
L
4444 is_rela = dynamic_relocations [i].rela;
4445 name = dynamic_relocations [i].name;
4446 rel_size = dynamic_info [dynamic_relocations [i].size];
4447 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 4448
566b0d53
L
4449 has_dynamic_reloc |= rel_size;
4450
4451 if (is_rela == UNKNOWN)
aa903cfb 4452 {
566b0d53
L
4453 if (dynamic_relocations [i].reloc == DT_JMPREL)
4454 switch (dynamic_info[DT_PLTREL])
4455 {
4456 case DT_REL:
4457 is_rela = FALSE;
4458 break;
4459 case DT_RELA:
4460 is_rela = TRUE;
4461 break;
4462 }
aa903cfb 4463 }
252b5132 4464
566b0d53
L
4465 if (rel_size)
4466 {
4467 printf
4468 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
4469 name, rel_offset, rel_size);
252b5132 4470
d93f0186
NC
4471 dump_relocations (file,
4472 offset_from_vma (file, rel_offset, rel_size),
4473 rel_size,
566b0d53 4474 dynamic_symbols, num_dynamic_syms,
d79b3d50 4475 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 4476 }
252b5132 4477 }
566b0d53
L
4478
4479 if (! has_dynamic_reloc)
252b5132
RH
4480 printf (_("\nThere are no dynamic relocations in this file.\n"));
4481 }
4482 else
4483 {
b34976b6
AM
4484 Elf_Internal_Shdr *section;
4485 unsigned long i;
4486 int found = 0;
252b5132
RH
4487
4488 for (i = 0, section = section_headers;
4489 i < elf_header.e_shnum;
b34976b6 4490 i++, section++)
252b5132
RH
4491 {
4492 if ( section->sh_type != SHT_RELA
4493 && section->sh_type != SHT_REL)
4494 continue;
4495
4496 rel_offset = section->sh_offset;
4497 rel_size = section->sh_size;
4498
4499 if (rel_size)
4500 {
b34976b6 4501 Elf_Internal_Shdr *strsec;
b34976b6 4502 int is_rela;
103f02d3 4503
252b5132
RH
4504 printf (_("\nRelocation section "));
4505
4506 if (string_table == NULL)
19936277 4507 printf ("%d", section->sh_name);
252b5132 4508 else
3a1a2036 4509 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
4510
4511 printf (_(" at offset 0x%lx contains %lu entries:\n"),
4512 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
4513
d79b3d50
NC
4514 is_rela = section->sh_type == SHT_RELA;
4515
c256ffe7
JJ
4516 if (section->sh_link
4517 && SECTION_HEADER_INDEX (section->sh_link)
4518 < elf_header.e_shnum)
af3fc3bc 4519 {
b34976b6 4520 Elf_Internal_Shdr *symsec;
d79b3d50
NC
4521 Elf_Internal_Sym *symtab;
4522 unsigned long nsyms;
c256ffe7 4523 unsigned long strtablen = 0;
d79b3d50 4524 char *strtab = NULL;
57346661 4525
9ad5cbcf 4526 symsec = SECTION_HEADER (section->sh_link);
08d8fa11
JJ
4527 if (symsec->sh_type != SHT_SYMTAB
4528 && symsec->sh_type != SHT_DYNSYM)
4529 continue;
4530
af3fc3bc 4531 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 4532 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 4533
af3fc3bc
AM
4534 if (symtab == NULL)
4535 continue;
252b5132 4536
c256ffe7
JJ
4537 if (SECTION_HEADER_INDEX (symsec->sh_link)
4538 < elf_header.e_shnum)
4539 {
4540 strsec = SECTION_HEADER (symsec->sh_link);
103f02d3 4541
c256ffe7
JJ
4542 strtab = get_data (NULL, file, strsec->sh_offset,
4543 1, strsec->sh_size,
4544 _("string table"));
4545 strtablen = strtab == NULL ? 0 : strsec->sh_size;
4546 }
252b5132 4547
d79b3d50
NC
4548 dump_relocations (file, rel_offset, rel_size,
4549 symtab, nsyms, strtab, strtablen, is_rela);
4550 if (strtab)
4551 free (strtab);
4552 free (symtab);
4553 }
4554 else
4555 dump_relocations (file, rel_offset, rel_size,
4556 NULL, 0, NULL, 0, is_rela);
252b5132
RH
4557
4558 found = 1;
4559 }
4560 }
4561
4562 if (! found)
4563 printf (_("\nThere are no relocations in this file.\n"));
4564 }
4565
4566 return 1;
4567}
4568
57346661
AM
4569/* Process the unwind section. */
4570
4d6ed7c8
NC
4571#include "unwind-ia64.h"
4572
4573/* An absolute address consists of a section and an offset. If the
4574 section is NULL, the offset itself is the address, otherwise, the
4575 address equals to LOAD_ADDRESS(section) + offset. */
4576
4577struct absaddr
4578 {
4579 unsigned short section;
4580 bfd_vma offset;
4581 };
4582
1949de15
L
4583#define ABSADDR(a) \
4584 ((a).section \
4585 ? section_headers [(a).section].sh_addr + (a).offset \
4586 : (a).offset)
4587
57346661 4588struct ia64_unw_aux_info
4d6ed7c8 4589 {
57346661 4590 struct ia64_unw_table_entry
4d6ed7c8 4591 {
b34976b6
AM
4592 struct absaddr start;
4593 struct absaddr end;
4594 struct absaddr info;
4d6ed7c8 4595 }
b34976b6
AM
4596 *table; /* Unwind table. */
4597 unsigned long table_len; /* Length of unwind table. */
4598 unsigned char *info; /* Unwind info. */
4599 unsigned long info_size; /* Size of unwind info. */
4600 bfd_vma info_addr; /* starting address of unwind info. */
4601 bfd_vma seg_base; /* Starting address of segment. */
4602 Elf_Internal_Sym *symtab; /* The symbol table. */
4603 unsigned long nsyms; /* Number of symbols. */
4604 char *strtab; /* The string table. */
4605 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
4606 };
4607
4d6ed7c8 4608static void
57346661
AM
4609find_symbol_for_address (Elf_Internal_Sym *symtab,
4610 unsigned long nsyms,
4611 const char *strtab,
4612 unsigned long strtab_size,
d3ba0551
AM
4613 struct absaddr addr,
4614 const char **symname,
4615 bfd_vma *offset)
4d6ed7c8 4616{
d3ba0551 4617 bfd_vma dist = 0x100000;
4d6ed7c8
NC
4618 Elf_Internal_Sym *sym, *best = NULL;
4619 unsigned long i;
4620
57346661 4621 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8
NC
4622 {
4623 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
4624 && sym->st_name != 0
4625 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
4626 && addr.offset >= sym->st_value
4627 && addr.offset - sym->st_value < dist)
4628 {
4629 best = sym;
4630 dist = addr.offset - sym->st_value;
4631 if (!dist)
4632 break;
4633 }
4634 }
4635 if (best)
4636 {
57346661
AM
4637 *symname = (best->st_name >= strtab_size
4638 ? "<corrupt>" : strtab + best->st_name);
4d6ed7c8
NC
4639 *offset = dist;
4640 return;
4641 }
4642 *symname = NULL;
4643 *offset = addr.offset;
4644}
4645
4646static void
57346661 4647dump_ia64_unwind (struct ia64_unw_aux_info *aux)
4d6ed7c8 4648{
57346661 4649 struct ia64_unw_table_entry *tp;
4d6ed7c8 4650 int in_body;
7036c0e1 4651
4d6ed7c8
NC
4652 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
4653 {
4654 bfd_vma stamp;
4655 bfd_vma offset;
b34976b6
AM
4656 const unsigned char *dp;
4657 const unsigned char *head;
4658 const char *procname;
4d6ed7c8 4659
57346661
AM
4660 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
4661 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
4662
4663 fputs ("\n<", stdout);
4664
4665 if (procname)
4666 {
4667 fputs (procname, stdout);
4668
4669 if (offset)
4670 printf ("+%lx", (unsigned long) offset);
4671 }
4672
4673 fputs (">: [", stdout);
4674 print_vma (tp->start.offset, PREFIX_HEX);
4675 fputc ('-', stdout);
4676 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 4677 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
4678 (unsigned long) (tp->info.offset - aux->seg_base));
4679
1949de15 4680 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 4681 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 4682
86f55779 4683 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
4684 (unsigned) UNW_VER (stamp),
4685 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
4686 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
4687 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 4688 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
4689
4690 if (UNW_VER (stamp) != 1)
4691 {
4692 printf ("\tUnknown version.\n");
4693 continue;
4694 }
4695
4696 in_body = 0;
89fac5e3 4697 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
4698 dp = unw_decode (dp, in_body, & in_body);
4699 }
4700}
4701
4702static int
d3ba0551 4703slurp_ia64_unwind_table (FILE *file,
57346661 4704 struct ia64_unw_aux_info *aux,
d3ba0551 4705 Elf_Internal_Shdr *sec)
4d6ed7c8 4706{
89fac5e3 4707 unsigned long size, nrelas, i;
d93f0186 4708 Elf_Internal_Phdr *seg;
57346661 4709 struct ia64_unw_table_entry *tep;
c8286bd1 4710 Elf_Internal_Shdr *relsec;
4d6ed7c8
NC
4711 Elf_Internal_Rela *rela, *rp;
4712 unsigned char *table, *tp;
4713 Elf_Internal_Sym *sym;
4714 const char *relname;
4d6ed7c8 4715
4d6ed7c8
NC
4716 /* First, find the starting address of the segment that includes
4717 this section: */
4718
4719 if (elf_header.e_phnum)
4720 {
d93f0186 4721 if (! get_program_headers (file))
4d6ed7c8 4722 return 0;
4d6ed7c8 4723
d93f0186
NC
4724 for (seg = program_headers;
4725 seg < program_headers + elf_header.e_phnum;
4726 ++seg)
4d6ed7c8
NC
4727 {
4728 if (seg->p_type != PT_LOAD)
4729 continue;
4730
4731 if (sec->sh_addr >= seg->p_vaddr
4732 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
4733 {
4734 aux->seg_base = seg->p_vaddr;
4735 break;
4736 }
4737 }
4d6ed7c8
NC
4738 }
4739
4740 /* Second, build the unwind table from the contents of the unwind section: */
4741 size = sec->sh_size;
c256ffe7 4742 table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
a6e9f9df
AM
4743 if (!table)
4744 return 0;
4d6ed7c8 4745
c256ffe7 4746 aux->table = xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3
RS
4747 tep = aux->table;
4748 for (tp = table; tp < table + size; tp += 3 * eh_addr_size, ++tep)
4d6ed7c8
NC
4749 {
4750 tep->start.section = SHN_UNDEF;
4751 tep->end.section = SHN_UNDEF;
4752 tep->info.section = SHN_UNDEF;
4753 if (is_32bit_elf)
4754 {
4755 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
4756 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
4757 tep->info.offset = byte_get ((unsigned char *) tp + 8, 4);
4758 }
4759 else
4760 {
66543521
AM
4761 tep->start.offset = BYTE_GET ((unsigned char *) tp + 0);
4762 tep->end.offset = BYTE_GET ((unsigned char *) tp + 8);
4763 tep->info.offset = BYTE_GET ((unsigned char *) tp + 16);
4d6ed7c8
NC
4764 }
4765 tep->start.offset += aux->seg_base;
4766 tep->end.offset += aux->seg_base;
4767 tep->info.offset += aux->seg_base;
4768 }
4769 free (table);
4770
4771 /* Third, apply any relocations to the unwind table: */
4772
4773 for (relsec = section_headers;
4774 relsec < section_headers + elf_header.e_shnum;
4775 ++relsec)
4776 {
4777 if (relsec->sh_type != SHT_RELA
c256ffe7 4778 || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
9ad5cbcf 4779 || SECTION_HEADER (relsec->sh_info) != sec)
4d6ed7c8
NC
4780 continue;
4781
4782 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
4783 & rela, & nrelas))
4784 return 0;
4785
4786 for (rp = rela; rp < rela + nrelas; ++rp)
4787 {
4788 if (is_32bit_elf)
4789 {
4790 relname = elf_ia64_reloc_type (ELF32_R_TYPE (rp->r_info));
4791 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
4d6ed7c8
NC
4792 }
4793 else
4794 {
4795 relname = elf_ia64_reloc_type (ELF64_R_TYPE (rp->r_info));
4796 sym = aux->symtab + ELF64_R_SYM (rp->r_info);
4d6ed7c8
NC
4797 }
4798
18bd398b 4799 if (! strneq (relname, "R_IA64_SEGREL", 13))
4d6ed7c8 4800 {
e5fb9629 4801 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
4802 continue;
4803 }
4804
89fac5e3 4805 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 4806
89fac5e3 4807 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
4808 {
4809 case 0:
4810 aux->table[i].start.section = sym->st_shndx;
1ffa9a18 4811 aux->table[i].start.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
4812 break;
4813 case 1:
4814 aux->table[i].end.section = sym->st_shndx;
1ffa9a18 4815 aux->table[i].end.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
4816 break;
4817 case 2:
4818 aux->table[i].info.section = sym->st_shndx;
1ffa9a18 4819 aux->table[i].info.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
4820 break;
4821 default:
4822 break;
4823 }
4824 }
4825
4826 free (rela);
4827 }
4828
89fac5e3 4829 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
4830 return 1;
4831}
4832
4833static int
57346661 4834ia64_process_unwind (FILE *file)
4d6ed7c8 4835{
c8286bd1 4836 Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
89fac5e3 4837 unsigned long i, unwcount = 0, unwstart = 0;
57346661 4838 struct ia64_unw_aux_info aux;
f1467e33 4839
4d6ed7c8
NC
4840 memset (& aux, 0, sizeof (aux));
4841
4d6ed7c8
NC
4842 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
4843 {
c256ffe7
JJ
4844 if (sec->sh_type == SHT_SYMTAB
4845 && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum)
4d6ed7c8
NC
4846 {
4847 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 4848 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 4849
9ad5cbcf 4850 strsec = SECTION_HEADER (sec->sh_link);
d3ba0551 4851 aux.strtab = get_data (NULL, file, strsec->sh_offset,
c256ffe7
JJ
4852 1, strsec->sh_size, _("string table"));
4853 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
4854 }
4855 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
4856 unwcount++;
4857 }
4858
4859 if (!unwcount)
4860 printf (_("\nThere are no unwind sections in this file.\n"));
4861
4862 while (unwcount-- > 0)
4863 {
4864 char *suffix;
4865 size_t len, len2;
4866
4867 for (i = unwstart, sec = section_headers + unwstart;
4868 i < elf_header.e_shnum; ++i, ++sec)
4869 if (sec->sh_type == SHT_IA_64_UNWIND)
4870 {
4871 unwsec = sec;
4872 break;
4873 }
4874
4875 unwstart = i + 1;
4876 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
4877
e4b17d5c
L
4878 if ((unwsec->sh_flags & SHF_GROUP) != 0)
4879 {
4880 /* We need to find which section group it is in. */
4881 struct group_list *g = section_headers_groups [i]->root;
4882
4883 for (; g != NULL; g = g->next)
4884 {
4885 sec = SECTION_HEADER (g->section_index);
18bd398b
NC
4886
4887 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 4888 break;
e4b17d5c
L
4889 }
4890
4891 if (g == NULL)
4892 i = elf_header.e_shnum;
4893 }
18bd398b 4894 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 4895 {
18bd398b 4896 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
4897 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
4898 suffix = SECTION_NAME (unwsec) + len;
4899 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
4900 ++i, ++sec)
18bd398b
NC
4901 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
4902 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
4903 break;
4904 }
4905 else
4906 {
4907 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 4908 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
4909 len = sizeof (ELF_STRING_ia64_unwind) - 1;
4910 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
4911 suffix = "";
18bd398b 4912 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
4913 suffix = SECTION_NAME (unwsec) + len;
4914 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
4915 ++i, ++sec)
18bd398b
NC
4916 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
4917 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
4918 break;
4919 }
4920
4921 if (i == elf_header.e_shnum)
4922 {
4923 printf (_("\nCould not find unwind info section for "));
4924
4925 if (string_table == NULL)
4926 printf ("%d", unwsec->sh_name);
4927 else
3a1a2036 4928 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
4929 }
4930 else
4d6ed7c8
NC
4931 {
4932 aux.info_size = sec->sh_size;
4933 aux.info_addr = sec->sh_addr;
c256ffe7 4934 aux.info = get_data (NULL, file, sec->sh_offset, 1, aux.info_size,
d3ba0551 4935 _("unwind info"));
4d6ed7c8 4936
579f31ac 4937 printf (_("\nUnwind section "));
4d6ed7c8 4938
579f31ac
JJ
4939 if (string_table == NULL)
4940 printf ("%d", unwsec->sh_name);
4941 else
3a1a2036 4942 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 4943
579f31ac 4944 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 4945 (unsigned long) unwsec->sh_offset,
89fac5e3 4946 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 4947
579f31ac 4948 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 4949
579f31ac
JJ
4950 if (aux.table_len > 0)
4951 dump_ia64_unwind (& aux);
4952
4953 if (aux.table)
4954 free ((char *) aux.table);
4955 if (aux.info)
4956 free ((char *) aux.info);
4957 aux.table = NULL;
4958 aux.info = NULL;
4959 }
4d6ed7c8 4960 }
4d6ed7c8 4961
4d6ed7c8
NC
4962 if (aux.symtab)
4963 free (aux.symtab);
4964 if (aux.strtab)
4965 free ((char *) aux.strtab);
4966
4967 return 1;
4968}
4969
57346661
AM
4970struct hppa_unw_aux_info
4971 {
4972 struct hppa_unw_table_entry
4973 {
4974 struct absaddr start;
4975 struct absaddr end;
4976 unsigned int Cannot_unwind:1; /* 0 */
4977 unsigned int Millicode:1; /* 1 */
4978 unsigned int Millicode_save_sr0:1; /* 2 */
4979 unsigned int Region_description:2; /* 3..4 */
4980 unsigned int reserved1:1; /* 5 */
4981 unsigned int Entry_SR:1; /* 6 */
4982 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
4983 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
4984 unsigned int Args_stored:1; /* 16 */
4985 unsigned int Variable_Frame:1; /* 17 */
4986 unsigned int Separate_Package_Body:1; /* 18 */
4987 unsigned int Frame_Extension_Millicode:1; /* 19 */
4988 unsigned int Stack_Overflow_Check:1; /* 20 */
4989 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
4990 unsigned int Ada_Region:1; /* 22 */
4991 unsigned int cxx_info:1; /* 23 */
4992 unsigned int cxx_try_catch:1; /* 24 */
4993 unsigned int sched_entry_seq:1; /* 25 */
4994 unsigned int reserved2:1; /* 26 */
4995 unsigned int Save_SP:1; /* 27 */
4996 unsigned int Save_RP:1; /* 28 */
4997 unsigned int Save_MRP_in_frame:1; /* 29 */
4998 unsigned int extn_ptr_defined:1; /* 30 */
4999 unsigned int Cleanup_defined:1; /* 31 */
5000
5001 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5002 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5003 unsigned int Large_frame:1; /* 2 */
5004 unsigned int Pseudo_SP_Set:1; /* 3 */
5005 unsigned int reserved4:1; /* 4 */
5006 unsigned int Total_frame_size:27; /* 5..31 */
5007 }
5008 *table; /* Unwind table. */
5009 unsigned long table_len; /* Length of unwind table. */
5010 bfd_vma seg_base; /* Starting address of segment. */
5011 Elf_Internal_Sym *symtab; /* The symbol table. */
5012 unsigned long nsyms; /* Number of symbols. */
5013 char *strtab; /* The string table. */
5014 unsigned long strtab_size; /* Size of string table. */
5015 };
5016
5017static void
5018dump_hppa_unwind (struct hppa_unw_aux_info *aux)
5019{
57346661
AM
5020 struct hppa_unw_table_entry *tp;
5021
57346661
AM
5022 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5023 {
5024 bfd_vma offset;
5025 const char *procname;
5026
5027 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5028 aux->strtab_size, tp->start, &procname,
5029 &offset);
5030
5031 fputs ("\n<", stdout);
5032
5033 if (procname)
5034 {
5035 fputs (procname, stdout);
5036
5037 if (offset)
5038 printf ("+%lx", (unsigned long) offset);
5039 }
5040
5041 fputs (">: [", stdout);
5042 print_vma (tp->start.offset, PREFIX_HEX);
5043 fputc ('-', stdout);
5044 print_vma (tp->end.offset, PREFIX_HEX);
5045 printf ("]\n\t");
5046
18bd398b
NC
5047#define PF(_m) if (tp->_m) printf (#_m " ");
5048#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5049 PF(Cannot_unwind);
5050 PF(Millicode);
5051 PF(Millicode_save_sr0);
18bd398b 5052 /* PV(Region_description); */
57346661
AM
5053 PF(Entry_SR);
5054 PV(Entry_FR);
5055 PV(Entry_GR);
5056 PF(Args_stored);
5057 PF(Variable_Frame);
5058 PF(Separate_Package_Body);
5059 PF(Frame_Extension_Millicode);
5060 PF(Stack_Overflow_Check);
5061 PF(Two_Instruction_SP_Increment);
5062 PF(Ada_Region);
5063 PF(cxx_info);
5064 PF(cxx_try_catch);
5065 PF(sched_entry_seq);
5066 PF(Save_SP);
5067 PF(Save_RP);
5068 PF(Save_MRP_in_frame);
5069 PF(extn_ptr_defined);
5070 PF(Cleanup_defined);
5071 PF(MPE_XL_interrupt_marker);
5072 PF(HP_UX_interrupt_marker);
5073 PF(Large_frame);
5074 PF(Pseudo_SP_Set);
5075 PV(Total_frame_size);
5076#undef PF
5077#undef PV
5078 }
5079
18bd398b 5080 printf ("\n");
57346661
AM
5081}
5082
5083static int
5084slurp_hppa_unwind_table (FILE *file,
5085 struct hppa_unw_aux_info *aux,
5086 Elf_Internal_Shdr *sec)
5087{
1c0751b2 5088 unsigned long size, unw_ent_size, nentries, nrelas, i;
57346661
AM
5089 Elf_Internal_Phdr *seg;
5090 struct hppa_unw_table_entry *tep;
5091 Elf_Internal_Shdr *relsec;
5092 Elf_Internal_Rela *rela, *rp;
5093 unsigned char *table, *tp;
5094 Elf_Internal_Sym *sym;
5095 const char *relname;
5096
57346661
AM
5097 /* First, find the starting address of the segment that includes
5098 this section. */
5099
5100 if (elf_header.e_phnum)
5101 {
5102 if (! get_program_headers (file))
5103 return 0;
5104
5105 for (seg = program_headers;
5106 seg < program_headers + elf_header.e_phnum;
5107 ++seg)
5108 {
5109 if (seg->p_type != PT_LOAD)
5110 continue;
5111
5112 if (sec->sh_addr >= seg->p_vaddr
5113 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5114 {
5115 aux->seg_base = seg->p_vaddr;
5116 break;
5117 }
5118 }
5119 }
5120
5121 /* Second, build the unwind table from the contents of the unwind
5122 section. */
5123 size = sec->sh_size;
c256ffe7 5124 table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
57346661
AM
5125 if (!table)
5126 return 0;
5127
1c0751b2
DA
5128 unw_ent_size = 16;
5129 nentries = size / unw_ent_size;
5130 size = unw_ent_size * nentries;
57346661 5131
1c0751b2 5132 tep = aux->table = xcmalloc (nentries, sizeof (aux->table[0]));
57346661 5133
1c0751b2 5134 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
5135 {
5136 unsigned int tmp1, tmp2;
5137
5138 tep->start.section = SHN_UNDEF;
5139 tep->end.section = SHN_UNDEF;
5140
1c0751b2
DA
5141 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
5142 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
5143 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
5144 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
5145
5146 tep->start.offset += aux->seg_base;
5147 tep->end.offset += aux->seg_base;
57346661
AM
5148
5149 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
5150 tep->Millicode = (tmp1 >> 30) & 0x1;
5151 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
5152 tep->Region_description = (tmp1 >> 27) & 0x3;
5153 tep->reserved1 = (tmp1 >> 26) & 0x1;
5154 tep->Entry_SR = (tmp1 >> 25) & 0x1;
5155 tep->Entry_FR = (tmp1 >> 21) & 0xf;
5156 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
5157 tep->Args_stored = (tmp1 >> 15) & 0x1;
5158 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
5159 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
5160 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
5161 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
5162 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
5163 tep->Ada_Region = (tmp1 >> 9) & 0x1;
5164 tep->cxx_info = (tmp1 >> 8) & 0x1;
5165 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
5166 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
5167 tep->reserved2 = (tmp1 >> 5) & 0x1;
5168 tep->Save_SP = (tmp1 >> 4) & 0x1;
5169 tep->Save_RP = (tmp1 >> 3) & 0x1;
5170 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
5171 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
5172 tep->Cleanup_defined = tmp1 & 0x1;
5173
5174 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
5175 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
5176 tep->Large_frame = (tmp2 >> 29) & 0x1;
5177 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
5178 tep->reserved4 = (tmp2 >> 27) & 0x1;
5179 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
5180 }
5181 free (table);
5182
5183 /* Third, apply any relocations to the unwind table. */
5184
5185 for (relsec = section_headers;
5186 relsec < section_headers + elf_header.e_shnum;
5187 ++relsec)
5188 {
5189 if (relsec->sh_type != SHT_RELA
c256ffe7 5190 || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
57346661
AM
5191 || SECTION_HEADER (relsec->sh_info) != sec)
5192 continue;
5193
5194 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5195 & rela, & nrelas))
5196 return 0;
5197
5198 for (rp = rela; rp < rela + nrelas; ++rp)
5199 {
5200 if (is_32bit_elf)
5201 {
5202 relname = elf_hppa_reloc_type (ELF32_R_TYPE (rp->r_info));
5203 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
5204 }
5205 else
5206 {
5207 relname = elf_hppa_reloc_type (ELF64_R_TYPE (rp->r_info));
5208 sym = aux->symtab + ELF64_R_SYM (rp->r_info);
5209 }
5210
5211 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
5212 if (strncmp (relname, "R_PARISC_SEGREL", 15) != 0)
5213 {
5214 warn (_("Skipping unexpected relocation type %s\n"), relname);
5215 continue;
5216 }
5217
5218 i = rp->r_offset / unw_ent_size;
5219
89fac5e3 5220 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
5221 {
5222 case 0:
5223 aux->table[i].start.section = sym->st_shndx;
5224 aux->table[i].start.offset += sym->st_value + rp->r_addend;
5225 break;
5226 case 1:
5227 aux->table[i].end.section = sym->st_shndx;
5228 aux->table[i].end.offset += sym->st_value + rp->r_addend;
5229 break;
5230 default:
5231 break;
5232 }
5233 }
5234
5235 free (rela);
5236 }
5237
1c0751b2 5238 aux->table_len = nentries;
57346661
AM
5239
5240 return 1;
5241}
5242
5243static int
5244hppa_process_unwind (FILE *file)
5245{
57346661 5246 struct hppa_unw_aux_info aux;
18bd398b
NC
5247 Elf_Internal_Shdr *unwsec = NULL;
5248 Elf_Internal_Shdr *strsec;
5249 Elf_Internal_Shdr *sec;
18bd398b 5250 unsigned long i;
57346661
AM
5251
5252 memset (& aux, 0, sizeof (aux));
5253
c256ffe7
JJ
5254 if (string_table == NULL)
5255 return 1;
57346661
AM
5256
5257 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5258 {
c256ffe7
JJ
5259 if (sec->sh_type == SHT_SYMTAB
5260 && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum)
57346661
AM
5261 {
5262 aux.nsyms = sec->sh_size / sec->sh_entsize;
5263 aux.symtab = GET_ELF_SYMBOLS (file, sec);
5264
5265 strsec = SECTION_HEADER (sec->sh_link);
57346661 5266 aux.strtab = get_data (NULL, file, strsec->sh_offset,
c256ffe7
JJ
5267 1, strsec->sh_size, _("string table"));
5268 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 5269 }
18bd398b 5270 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
5271 unwsec = sec;
5272 }
5273
5274 if (!unwsec)
5275 printf (_("\nThere are no unwind sections in this file.\n"));
5276
5277 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5278 {
18bd398b 5279 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 5280 {
57346661
AM
5281 printf (_("\nUnwind section "));
5282 printf (_("'%s'"), SECTION_NAME (sec));
5283
5284 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5285 (unsigned long) sec->sh_offset,
89fac5e3 5286 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
5287
5288 slurp_hppa_unwind_table (file, &aux, sec);
5289 if (aux.table_len > 0)
5290 dump_hppa_unwind (&aux);
5291
5292 if (aux.table)
5293 free ((char *) aux.table);
5294 aux.table = NULL;
5295 }
5296 }
5297
5298 if (aux.symtab)
5299 free (aux.symtab);
5300 if (aux.strtab)
5301 free ((char *) aux.strtab);
5302
5303 return 1;
5304}
5305
5306static int
5307process_unwind (FILE *file)
5308{
5309 struct unwind_handler {
5310 int machtype;
5311 int (*handler)(FILE *file);
5312 } handlers[] = {
5313 { EM_IA_64, ia64_process_unwind },
5314 { EM_PARISC, hppa_process_unwind },
5315 { 0, 0 }
5316 };
5317 int i;
5318
5319 if (!do_unwind)
5320 return 1;
5321
5322 for (i = 0; handlers[i].handler != NULL; i++)
5323 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 5324 return handlers[i].handler (file);
57346661
AM
5325
5326 printf (_("\nThere are no unwind sections in this file.\n"));
5327 return 1;
5328}
5329
252b5132 5330static void
b2d38a17 5331dynamic_section_mips_val (Elf_Internal_Dyn *entry)
252b5132
RH
5332{
5333 switch (entry->d_tag)
5334 {
5335 case DT_MIPS_FLAGS:
5336 if (entry->d_un.d_val == 0)
5337 printf ("NONE\n");
5338 else
5339 {
5340 static const char * opts[] =
5341 {
5342 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
5343 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
5344 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
5345 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
5346 "RLD_ORDER_SAFE"
5347 };
5348 unsigned int cnt;
5349 int first = 1;
b34976b6 5350 for (cnt = 0; cnt < NUM_ELEM (opts); ++cnt)
252b5132
RH
5351 if (entry->d_un.d_val & (1 << cnt))
5352 {
5353 printf ("%s%s", first ? "" : " ", opts[cnt]);
5354 first = 0;
5355 }
5356 puts ("");
5357 }
5358 break;
103f02d3 5359
252b5132 5360 case DT_MIPS_IVERSION:
d79b3d50
NC
5361 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
5362 printf ("Interface Version: %s\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 5363 else
d79b3d50 5364 printf ("<corrupt: %ld>\n", (long) entry->d_un.d_ptr);
252b5132 5365 break;
103f02d3 5366
252b5132
RH
5367 case DT_MIPS_TIME_STAMP:
5368 {
5369 char timebuf[20];
b34976b6 5370 struct tm *tmp;
50da7a9c 5371
252b5132 5372 time_t time = entry->d_un.d_val;
50da7a9c 5373 tmp = gmtime (&time);
e9e44622
JJ
5374 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
5375 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
5376 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
5377 printf ("Time Stamp: %s\n", timebuf);
5378 }
5379 break;
103f02d3 5380
252b5132
RH
5381 case DT_MIPS_RLD_VERSION:
5382 case DT_MIPS_LOCAL_GOTNO:
5383 case DT_MIPS_CONFLICTNO:
5384 case DT_MIPS_LIBLISTNO:
5385 case DT_MIPS_SYMTABNO:
5386 case DT_MIPS_UNREFEXTNO:
5387 case DT_MIPS_HIPAGENO:
5388 case DT_MIPS_DELTA_CLASS_NO:
5389 case DT_MIPS_DELTA_INSTANCE_NO:
5390 case DT_MIPS_DELTA_RELOC_NO:
5391 case DT_MIPS_DELTA_SYM_NO:
5392 case DT_MIPS_DELTA_CLASSSYM_NO:
5393 case DT_MIPS_COMPACT_SIZE:
5394 printf ("%ld\n", (long) entry->d_un.d_ptr);
5395 break;
103f02d3
UD
5396
5397 default:
5398 printf ("%#lx\n", (long) entry->d_un.d_ptr);
5399 }
5400}
5401
5402
5403static void
b2d38a17 5404dynamic_section_parisc_val (Elf_Internal_Dyn *entry)
103f02d3
UD
5405{
5406 switch (entry->d_tag)
5407 {
5408 case DT_HP_DLD_FLAGS:
5409 {
5410 static struct
5411 {
5412 long int bit;
b34976b6 5413 const char *str;
5e220199
NC
5414 }
5415 flags[] =
5416 {
5417 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
5418 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
5419 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
5420 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
5421 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
5422 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
5423 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
5424 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
5425 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
5426 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
5427 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
5428 { DT_HP_GST, "HP_GST" },
5429 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
5430 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
5431 { DT_HP_NODELETE, "HP_NODELETE" },
5432 { DT_HP_GROUP, "HP_GROUP" },
5433 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 5434 };
103f02d3 5435 int first = 1;
5e220199 5436 size_t cnt;
f7a99963 5437 bfd_vma val = entry->d_un.d_val;
103f02d3
UD
5438
5439 for (cnt = 0; cnt < sizeof (flags) / sizeof (flags[0]); ++cnt)
5440 if (val & flags[cnt].bit)
30800947
NC
5441 {
5442 if (! first)
5443 putchar (' ');
5444 fputs (flags[cnt].str, stdout);
5445 first = 0;
5446 val ^= flags[cnt].bit;
5447 }
76da6bbe 5448
103f02d3 5449 if (val != 0 || first)
f7a99963
NC
5450 {
5451 if (! first)
5452 putchar (' ');
5453 print_vma (val, HEX);
5454 }
103f02d3
UD
5455 }
5456 break;
76da6bbe 5457
252b5132 5458 default:
f7a99963
NC
5459 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5460 break;
252b5132 5461 }
35b1837e 5462 putchar ('\n');
252b5132
RH
5463}
5464
ecc51f48 5465static void
b2d38a17 5466dynamic_section_ia64_val (Elf_Internal_Dyn *entry)
ecc51f48
NC
5467{
5468 switch (entry->d_tag)
5469 {
0de14b54 5470 case DT_IA_64_PLT_RESERVE:
bdf4d63a 5471 /* First 3 slots reserved. */
ecc51f48
NC
5472 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5473 printf (" -- ");
5474 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
5475 break;
5476
5477 default:
5478 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5479 break;
ecc51f48 5480 }
bdf4d63a 5481 putchar ('\n');
ecc51f48
NC
5482}
5483
252b5132 5484static int
b2d38a17 5485get_32bit_dynamic_section (FILE *file)
252b5132 5486{
fb514b26 5487 Elf32_External_Dyn *edyn, *ext;
b34976b6 5488 Elf_Internal_Dyn *entry;
103f02d3 5489
c256ffe7 5490 edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
b2d38a17 5491 _("dynamic section"));
a6e9f9df
AM
5492 if (!edyn)
5493 return 0;
103f02d3 5494
ba2685cc
AM
5495/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5496 might not have the luxury of section headers. Look for the DT_NULL
5497 terminator to determine the number of entries. */
5498 for (ext = edyn, dynamic_nent = 0;
5499 (char *) ext < (char *) edyn + dynamic_size;
5500 ext++)
5501 {
5502 dynamic_nent++;
5503 if (BYTE_GET (ext->d_tag) == DT_NULL)
5504 break;
5505 }
252b5132 5506
c256ffe7 5507 dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
b2d38a17 5508 if (dynamic_section == NULL)
252b5132 5509 {
9ea033b2
NC
5510 error (_("Out of memory\n"));
5511 free (edyn);
5512 return 0;
5513 }
252b5132 5514
fb514b26 5515 for (ext = edyn, entry = dynamic_section;
ba2685cc 5516 entry < dynamic_section + dynamic_nent;
fb514b26 5517 ext++, entry++)
9ea033b2 5518 {
fb514b26
AM
5519 entry->d_tag = BYTE_GET (ext->d_tag);
5520 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
5521 }
5522
9ea033b2
NC
5523 free (edyn);
5524
5525 return 1;
5526}
5527
5528static int
b2d38a17 5529get_64bit_dynamic_section (FILE *file)
9ea033b2 5530{
fb514b26 5531 Elf64_External_Dyn *edyn, *ext;
b34976b6 5532 Elf_Internal_Dyn *entry;
103f02d3 5533
c256ffe7 5534 edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
b2d38a17 5535 _("dynamic section"));
a6e9f9df
AM
5536 if (!edyn)
5537 return 0;
103f02d3 5538
ba2685cc
AM
5539/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5540 might not have the luxury of section headers. Look for the DT_NULL
5541 terminator to determine the number of entries. */
5542 for (ext = edyn, dynamic_nent = 0;
5543 (char *) ext < (char *) edyn + dynamic_size;
5544 ext++)
5545 {
5546 dynamic_nent++;
66543521 5547 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
5548 break;
5549 }
252b5132 5550
c256ffe7 5551 dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
b2d38a17 5552 if (dynamic_section == NULL)
252b5132
RH
5553 {
5554 error (_("Out of memory\n"));
5555 free (edyn);
5556 return 0;
5557 }
5558
fb514b26 5559 for (ext = edyn, entry = dynamic_section;
ba2685cc 5560 entry < dynamic_section + dynamic_nent;
fb514b26 5561 ext++, entry++)
252b5132 5562 {
66543521
AM
5563 entry->d_tag = BYTE_GET (ext->d_tag);
5564 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
5565 }
5566
5567 free (edyn);
5568
9ea033b2
NC
5569 return 1;
5570}
5571
e9e44622
JJ
5572static void
5573print_dynamic_flags (bfd_vma flags)
d1133906 5574{
e9e44622 5575 int first = 1;
13ae64f3 5576
d1133906
NC
5577 while (flags)
5578 {
5579 bfd_vma flag;
5580
5581 flag = flags & - flags;
5582 flags &= ~ flag;
5583
e9e44622
JJ
5584 if (first)
5585 first = 0;
5586 else
5587 putc (' ', stdout);
13ae64f3 5588
d1133906
NC
5589 switch (flag)
5590 {
e9e44622
JJ
5591 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
5592 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
5593 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
5594 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
5595 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
5596 default: fputs ("unknown", stdout); break;
d1133906
NC
5597 }
5598 }
e9e44622 5599 puts ("");
d1133906
NC
5600}
5601
b2d38a17
NC
5602/* Parse and display the contents of the dynamic section. */
5603
9ea033b2 5604static int
b2d38a17 5605process_dynamic_section (FILE *file)
9ea033b2 5606{
b34976b6 5607 Elf_Internal_Dyn *entry;
9ea033b2
NC
5608
5609 if (dynamic_size == 0)
5610 {
5611 if (do_dynamic)
b2d38a17 5612 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
5613
5614 return 1;
5615 }
5616
5617 if (is_32bit_elf)
5618 {
b2d38a17 5619 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
5620 return 0;
5621 }
b2d38a17 5622 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
5623 return 0;
5624
252b5132
RH
5625 /* Find the appropriate symbol table. */
5626 if (dynamic_symbols == NULL)
5627 {
86dba8ee
AM
5628 for (entry = dynamic_section;
5629 entry < dynamic_section + dynamic_nent;
5630 ++entry)
252b5132 5631 {
c8286bd1 5632 Elf_Internal_Shdr section;
252b5132
RH
5633
5634 if (entry->d_tag != DT_SYMTAB)
5635 continue;
5636
5637 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
5638
5639 /* Since we do not know how big the symbol table is,
5640 we default to reading in the entire file (!) and
5641 processing that. This is overkill, I know, but it
e3c8793a 5642 should work. */
d93f0186 5643 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 5644
fb52b2f4
NC
5645 if (archive_file_offset != 0)
5646 section.sh_size = archive_file_size - section.sh_offset;
5647 else
5648 {
5649 if (fseek (file, 0, SEEK_END))
5650 error (_("Unable to seek to end of file!"));
5651
5652 section.sh_size = ftell (file) - section.sh_offset;
5653 }
252b5132 5654
9ea033b2 5655 if (is_32bit_elf)
9ad5cbcf 5656 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 5657 else
9ad5cbcf 5658 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 5659
9ad5cbcf 5660 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 5661 if (num_dynamic_syms < 1)
252b5132
RH
5662 {
5663 error (_("Unable to determine the number of symbols to load\n"));
5664 continue;
5665 }
5666
9ad5cbcf 5667 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
5668 }
5669 }
5670
5671 /* Similarly find a string table. */
5672 if (dynamic_strings == NULL)
5673 {
86dba8ee
AM
5674 for (entry = dynamic_section;
5675 entry < dynamic_section + dynamic_nent;
5676 ++entry)
252b5132
RH
5677 {
5678 unsigned long offset;
b34976b6 5679 long str_tab_len;
252b5132
RH
5680
5681 if (entry->d_tag != DT_STRTAB)
5682 continue;
5683
5684 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
5685
5686 /* Since we do not know how big the string table is,
5687 we default to reading in the entire file (!) and
5688 processing that. This is overkill, I know, but it
e3c8793a 5689 should work. */
252b5132 5690
d93f0186 5691 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
5692
5693 if (archive_file_offset != 0)
5694 str_tab_len = archive_file_size - offset;
5695 else
5696 {
5697 if (fseek (file, 0, SEEK_END))
5698 error (_("Unable to seek to end of file\n"));
5699 str_tab_len = ftell (file) - offset;
5700 }
252b5132
RH
5701
5702 if (str_tab_len < 1)
5703 {
5704 error
5705 (_("Unable to determine the length of the dynamic string table\n"));
5706 continue;
5707 }
5708
c256ffe7 5709 dynamic_strings = get_data (NULL, file, offset, 1, str_tab_len,
d3ba0551 5710 _("dynamic string table"));
d79b3d50 5711 dynamic_strings_length = str_tab_len;
252b5132
RH
5712 break;
5713 }
5714 }
5715
5716 /* And find the syminfo section if available. */
5717 if (dynamic_syminfo == NULL)
5718 {
3e8bba36 5719 unsigned long syminsz = 0;
252b5132 5720
86dba8ee
AM
5721 for (entry = dynamic_section;
5722 entry < dynamic_section + dynamic_nent;
5723 ++entry)
252b5132
RH
5724 {
5725 if (entry->d_tag == DT_SYMINENT)
5726 {
5727 /* Note: these braces are necessary to avoid a syntax
5728 error from the SunOS4 C compiler. */
5729 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
5730 }
5731 else if (entry->d_tag == DT_SYMINSZ)
5732 syminsz = entry->d_un.d_val;
5733 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
5734 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
5735 syminsz);
252b5132
RH
5736 }
5737
5738 if (dynamic_syminfo_offset != 0 && syminsz != 0)
5739 {
86dba8ee 5740 Elf_External_Syminfo *extsyminfo, *extsym;
b34976b6 5741 Elf_Internal_Syminfo *syminfo;
252b5132
RH
5742
5743 /* There is a syminfo section. Read the data. */
c256ffe7
JJ
5744 extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, 1,
5745 syminsz, _("symbol information"));
a6e9f9df
AM
5746 if (!extsyminfo)
5747 return 0;
252b5132 5748
d3ba0551 5749 dynamic_syminfo = malloc (syminsz);
252b5132
RH
5750 if (dynamic_syminfo == NULL)
5751 {
5752 error (_("Out of memory\n"));
5753 return 0;
5754 }
5755
5756 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
5757 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
5758 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
5759 ++syminfo, ++extsym)
252b5132 5760 {
86dba8ee
AM
5761 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
5762 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
5763 }
5764
5765 free (extsyminfo);
5766 }
5767 }
5768
5769 if (do_dynamic && dynamic_addr)
86dba8ee
AM
5770 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
5771 dynamic_addr, dynamic_nent);
252b5132
RH
5772 if (do_dynamic)
5773 printf (_(" Tag Type Name/Value\n"));
5774
86dba8ee
AM
5775 for (entry = dynamic_section;
5776 entry < dynamic_section + dynamic_nent;
5777 entry++)
252b5132
RH
5778 {
5779 if (do_dynamic)
f7a99963 5780 {
b34976b6 5781 const char *dtype;
e699b9ff 5782
f7a99963
NC
5783 putchar (' ');
5784 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
5785 dtype = get_dynamic_type (entry->d_tag);
5786 printf (" (%s)%*s", dtype,
5787 ((is_32bit_elf ? 27 : 19)
5788 - (int) strlen (dtype)),
f7a99963
NC
5789 " ");
5790 }
252b5132
RH
5791
5792 switch (entry->d_tag)
5793 {
d1133906
NC
5794 case DT_FLAGS:
5795 if (do_dynamic)
e9e44622 5796 print_dynamic_flags (entry->d_un.d_val);
d1133906 5797 break;
76da6bbe 5798
252b5132
RH
5799 case DT_AUXILIARY:
5800 case DT_FILTER:
019148e4
L
5801 case DT_CONFIG:
5802 case DT_DEPAUDIT:
5803 case DT_AUDIT:
252b5132
RH
5804 if (do_dynamic)
5805 {
019148e4 5806 switch (entry->d_tag)
b34976b6 5807 {
019148e4
L
5808 case DT_AUXILIARY:
5809 printf (_("Auxiliary library"));
5810 break;
5811
5812 case DT_FILTER:
5813 printf (_("Filter library"));
5814 break;
5815
b34976b6 5816 case DT_CONFIG:
019148e4
L
5817 printf (_("Configuration file"));
5818 break;
5819
5820 case DT_DEPAUDIT:
5821 printf (_("Dependency audit library"));
5822 break;
5823
5824 case DT_AUDIT:
5825 printf (_("Audit library"));
5826 break;
5827 }
252b5132 5828
d79b3d50
NC
5829 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
5830 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 5831 else
f7a99963
NC
5832 {
5833 printf (": ");
5834 print_vma (entry->d_un.d_val, PREFIX_HEX);
5835 putchar ('\n');
5836 }
252b5132
RH
5837 }
5838 break;
5839
dcefbbbd 5840 case DT_FEATURE:
252b5132
RH
5841 if (do_dynamic)
5842 {
5843 printf (_("Flags:"));
86f55779 5844
252b5132
RH
5845 if (entry->d_un.d_val == 0)
5846 printf (_(" None\n"));
5847 else
5848 {
5849 unsigned long int val = entry->d_un.d_val;
86f55779 5850
252b5132
RH
5851 if (val & DTF_1_PARINIT)
5852 {
5853 printf (" PARINIT");
5854 val ^= DTF_1_PARINIT;
5855 }
dcefbbbd
L
5856 if (val & DTF_1_CONFEXP)
5857 {
5858 printf (" CONFEXP");
5859 val ^= DTF_1_CONFEXP;
5860 }
252b5132
RH
5861 if (val != 0)
5862 printf (" %lx", val);
5863 puts ("");
5864 }
5865 }
5866 break;
5867
5868 case DT_POSFLAG_1:
5869 if (do_dynamic)
5870 {
5871 printf (_("Flags:"));
86f55779 5872
252b5132
RH
5873 if (entry->d_un.d_val == 0)
5874 printf (_(" None\n"));
5875 else
5876 {
5877 unsigned long int val = entry->d_un.d_val;
86f55779 5878
252b5132
RH
5879 if (val & DF_P1_LAZYLOAD)
5880 {
5881 printf (" LAZYLOAD");
5882 val ^= DF_P1_LAZYLOAD;
5883 }
5884 if (val & DF_P1_GROUPPERM)
5885 {
5886 printf (" GROUPPERM");
5887 val ^= DF_P1_GROUPPERM;
5888 }
5889 if (val != 0)
5890 printf (" %lx", val);
5891 puts ("");
5892 }
5893 }
5894 break;
5895
5896 case DT_FLAGS_1:
5897 if (do_dynamic)
5898 {
5899 printf (_("Flags:"));
5900 if (entry->d_un.d_val == 0)
5901 printf (_(" None\n"));
5902 else
5903 {
5904 unsigned long int val = entry->d_un.d_val;
86f55779 5905
252b5132
RH
5906 if (val & DF_1_NOW)
5907 {
5908 printf (" NOW");
5909 val ^= DF_1_NOW;
5910 }
5911 if (val & DF_1_GLOBAL)
5912 {
5913 printf (" GLOBAL");
5914 val ^= DF_1_GLOBAL;
5915 }
5916 if (val & DF_1_GROUP)
5917 {
5918 printf (" GROUP");
5919 val ^= DF_1_GROUP;
5920 }
5921 if (val & DF_1_NODELETE)
5922 {
5923 printf (" NODELETE");
5924 val ^= DF_1_NODELETE;
5925 }
5926 if (val & DF_1_LOADFLTR)
5927 {
5928 printf (" LOADFLTR");
5929 val ^= DF_1_LOADFLTR;
5930 }
5931 if (val & DF_1_INITFIRST)
5932 {
5933 printf (" INITFIRST");
5934 val ^= DF_1_INITFIRST;
5935 }
5936 if (val & DF_1_NOOPEN)
5937 {
5938 printf (" NOOPEN");
5939 val ^= DF_1_NOOPEN;
5940 }
5941 if (val & DF_1_ORIGIN)
5942 {
5943 printf (" ORIGIN");
5944 val ^= DF_1_ORIGIN;
5945 }
5946 if (val & DF_1_DIRECT)
5947 {
5948 printf (" DIRECT");
5949 val ^= DF_1_DIRECT;
5950 }
5951 if (val & DF_1_TRANS)
5952 {
5953 printf (" TRANS");
5954 val ^= DF_1_TRANS;
5955 }
5956 if (val & DF_1_INTERPOSE)
5957 {
5958 printf (" INTERPOSE");
5959 val ^= DF_1_INTERPOSE;
5960 }
f7db6139 5961 if (val & DF_1_NODEFLIB)
dcefbbbd 5962 {
f7db6139
L
5963 printf (" NODEFLIB");
5964 val ^= DF_1_NODEFLIB;
dcefbbbd
L
5965 }
5966 if (val & DF_1_NODUMP)
5967 {
5968 printf (" NODUMP");
5969 val ^= DF_1_NODUMP;
5970 }
5971 if (val & DF_1_CONLFAT)
5972 {
5973 printf (" CONLFAT");
5974 val ^= DF_1_CONLFAT;
5975 }
252b5132
RH
5976 if (val != 0)
5977 printf (" %lx", val);
5978 puts ("");
5979 }
5980 }
5981 break;
5982
5983 case DT_PLTREL:
566b0d53 5984 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
5985 if (do_dynamic)
5986 puts (get_dynamic_type (entry->d_un.d_val));
5987 break;
5988
5989 case DT_NULL :
5990 case DT_NEEDED :
5991 case DT_PLTGOT :
5992 case DT_HASH :
5993 case DT_STRTAB :
5994 case DT_SYMTAB :
5995 case DT_RELA :
5996 case DT_INIT :
5997 case DT_FINI :
5998 case DT_SONAME :
5999 case DT_RPATH :
6000 case DT_SYMBOLIC:
6001 case DT_REL :
6002 case DT_DEBUG :
6003 case DT_TEXTREL :
6004 case DT_JMPREL :
019148e4 6005 case DT_RUNPATH :
252b5132
RH
6006 dynamic_info[entry->d_tag] = entry->d_un.d_val;
6007
6008 if (do_dynamic)
6009 {
b34976b6 6010 char *name;
252b5132 6011
d79b3d50
NC
6012 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
6013 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 6014 else
d79b3d50 6015 name = NULL;
252b5132
RH
6016
6017 if (name)
6018 {
6019 switch (entry->d_tag)
6020 {
6021 case DT_NEEDED:
6022 printf (_("Shared library: [%s]"), name);
6023
18bd398b 6024 if (streq (name, program_interpreter))
f7a99963 6025 printf (_(" program interpreter"));
252b5132
RH
6026 break;
6027
6028 case DT_SONAME:
f7a99963 6029 printf (_("Library soname: [%s]"), name);
252b5132
RH
6030 break;
6031
6032 case DT_RPATH:
f7a99963 6033 printf (_("Library rpath: [%s]"), name);
252b5132
RH
6034 break;
6035
019148e4
L
6036 case DT_RUNPATH:
6037 printf (_("Library runpath: [%s]"), name);
6038 break;
6039
252b5132 6040 default:
f7a99963
NC
6041 print_vma (entry->d_un.d_val, PREFIX_HEX);
6042 break;
252b5132
RH
6043 }
6044 }
6045 else
f7a99963
NC
6046 print_vma (entry->d_un.d_val, PREFIX_HEX);
6047
6048 putchar ('\n');
252b5132
RH
6049 }
6050 break;
6051
6052 case DT_PLTRELSZ:
6053 case DT_RELASZ :
6054 case DT_STRSZ :
6055 case DT_RELSZ :
6056 case DT_RELAENT :
6057 case DT_SYMENT :
6058 case DT_RELENT :
566b0d53 6059 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
6060 case DT_PLTPADSZ:
6061 case DT_MOVEENT :
6062 case DT_MOVESZ :
6063 case DT_INIT_ARRAYSZ:
6064 case DT_FINI_ARRAYSZ:
047b2264
JJ
6065 case DT_GNU_CONFLICTSZ:
6066 case DT_GNU_LIBLISTSZ:
252b5132 6067 if (do_dynamic)
f7a99963
NC
6068 {
6069 print_vma (entry->d_un.d_val, UNSIGNED);
6070 printf (" (bytes)\n");
6071 }
252b5132
RH
6072 break;
6073
6074 case DT_VERDEFNUM:
6075 case DT_VERNEEDNUM:
6076 case DT_RELACOUNT:
6077 case DT_RELCOUNT:
6078 if (do_dynamic)
f7a99963
NC
6079 {
6080 print_vma (entry->d_un.d_val, UNSIGNED);
6081 putchar ('\n');
6082 }
252b5132
RH
6083 break;
6084
6085 case DT_SYMINSZ:
6086 case DT_SYMINENT:
6087 case DT_SYMINFO:
6088 case DT_USED:
6089 case DT_INIT_ARRAY:
6090 case DT_FINI_ARRAY:
6091 if (do_dynamic)
6092 {
d79b3d50
NC
6093 if (entry->d_tag == DT_USED
6094 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 6095 {
d79b3d50 6096 char *name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 6097
b34976b6 6098 if (*name)
252b5132
RH
6099 {
6100 printf (_("Not needed object: [%s]\n"), name);
6101 break;
6102 }
6103 }
103f02d3 6104
f7a99963
NC
6105 print_vma (entry->d_un.d_val, PREFIX_HEX);
6106 putchar ('\n');
252b5132
RH
6107 }
6108 break;
6109
6110 case DT_BIND_NOW:
6111 /* The value of this entry is ignored. */
35b1837e
AM
6112 if (do_dynamic)
6113 putchar ('\n');
252b5132 6114 break;
103f02d3 6115
047b2264
JJ
6116 case DT_GNU_PRELINKED:
6117 if (do_dynamic)
6118 {
b34976b6 6119 struct tm *tmp;
047b2264
JJ
6120 time_t time = entry->d_un.d_val;
6121
6122 tmp = gmtime (&time);
6123 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
6124 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
6125 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
6126
6127 }
6128 break;
6129
252b5132
RH
6130 default:
6131 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 6132 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
6133 entry->d_un.d_val;
6134
6135 if (do_dynamic)
6136 {
6137 switch (elf_header.e_machine)
6138 {
6139 case EM_MIPS:
4fe85591 6140 case EM_MIPS_RS3_LE:
b2d38a17 6141 dynamic_section_mips_val (entry);
252b5132 6142 break;
103f02d3 6143 case EM_PARISC:
b2d38a17 6144 dynamic_section_parisc_val (entry);
103f02d3 6145 break;
ecc51f48 6146 case EM_IA_64:
b2d38a17 6147 dynamic_section_ia64_val (entry);
ecc51f48 6148 break;
252b5132 6149 default:
f7a99963
NC
6150 print_vma (entry->d_un.d_val, PREFIX_HEX);
6151 putchar ('\n');
252b5132
RH
6152 }
6153 }
6154 break;
6155 }
6156 }
6157
6158 return 1;
6159}
6160
6161static char *
d3ba0551 6162get_ver_flags (unsigned int flags)
252b5132 6163{
b34976b6 6164 static char buff[32];
252b5132
RH
6165
6166 buff[0] = 0;
6167
6168 if (flags == 0)
6169 return _("none");
6170
6171 if (flags & VER_FLG_BASE)
6172 strcat (buff, "BASE ");
6173
6174 if (flags & VER_FLG_WEAK)
6175 {
6176 if (flags & VER_FLG_BASE)
6177 strcat (buff, "| ");
6178
6179 strcat (buff, "WEAK ");
6180 }
6181
6182 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
6183 strcat (buff, "| <unknown>");
6184
6185 return buff;
6186}
6187
6188/* Display the contents of the version sections. */
6189static int
d3ba0551 6190process_version_sections (FILE *file)
252b5132 6191{
b34976b6
AM
6192 Elf_Internal_Shdr *section;
6193 unsigned i;
6194 int found = 0;
252b5132
RH
6195
6196 if (! do_version)
6197 return 1;
6198
6199 for (i = 0, section = section_headers;
6200 i < elf_header.e_shnum;
b34976b6 6201 i++, section++)
252b5132
RH
6202 {
6203 switch (section->sh_type)
6204 {
6205 case SHT_GNU_verdef:
6206 {
b34976b6
AM
6207 Elf_External_Verdef *edefs;
6208 unsigned int idx;
6209 unsigned int cnt;
252b5132
RH
6210
6211 found = 1;
6212
6213 printf
6214 (_("\nVersion definition section '%s' contains %ld entries:\n"),
6215 SECTION_NAME (section), section->sh_info);
6216
6217 printf (_(" Addr: 0x"));
6218 printf_vma (section->sh_addr);
6219 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 6220 (unsigned long) section->sh_offset, section->sh_link,
c256ffe7
JJ
6221 SECTION_HEADER_INDEX (section->sh_link)
6222 < elf_header.e_shnum
6223 ? SECTION_NAME (SECTION_HEADER (section->sh_link))
6224 : "<corrupt>");
252b5132 6225
c256ffe7
JJ
6226 edefs = get_data (NULL, file, section->sh_offset, 1,
6227 section->sh_size,
d3ba0551 6228 _("version definition section"));
a6e9f9df
AM
6229 if (!edefs)
6230 break;
252b5132 6231
b34976b6 6232 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 6233 {
b34976b6
AM
6234 char *vstart;
6235 Elf_External_Verdef *edef;
6236 Elf_Internal_Verdef ent;
6237 Elf_External_Verdaux *eaux;
6238 Elf_Internal_Verdaux aux;
6239 int j;
6240 int isum;
103f02d3 6241
252b5132
RH
6242 vstart = ((char *) edefs) + idx;
6243
6244 edef = (Elf_External_Verdef *) vstart;
6245
6246 ent.vd_version = BYTE_GET (edef->vd_version);
6247 ent.vd_flags = BYTE_GET (edef->vd_flags);
6248 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
6249 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
6250 ent.vd_hash = BYTE_GET (edef->vd_hash);
6251 ent.vd_aux = BYTE_GET (edef->vd_aux);
6252 ent.vd_next = BYTE_GET (edef->vd_next);
6253
6254 printf (_(" %#06x: Rev: %d Flags: %s"),
6255 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
6256
6257 printf (_(" Index: %d Cnt: %d "),
6258 ent.vd_ndx, ent.vd_cnt);
6259
6260 vstart += ent.vd_aux;
6261
6262 eaux = (Elf_External_Verdaux *) vstart;
6263
6264 aux.vda_name = BYTE_GET (eaux->vda_name);
6265 aux.vda_next = BYTE_GET (eaux->vda_next);
6266
d79b3d50
NC
6267 if (VALID_DYNAMIC_NAME (aux.vda_name))
6268 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
6269 else
6270 printf (_("Name index: %ld\n"), aux.vda_name);
6271
6272 isum = idx + ent.vd_aux;
6273
b34976b6 6274 for (j = 1; j < ent.vd_cnt; j++)
252b5132
RH
6275 {
6276 isum += aux.vda_next;
6277 vstart += aux.vda_next;
6278
6279 eaux = (Elf_External_Verdaux *) vstart;
6280
6281 aux.vda_name = BYTE_GET (eaux->vda_name);
6282 aux.vda_next = BYTE_GET (eaux->vda_next);
6283
d79b3d50 6284 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 6285 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 6286 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
6287 else
6288 printf (_(" %#06x: Parent %d, name index: %ld\n"),
6289 isum, j, aux.vda_name);
6290 }
6291
6292 idx += ent.vd_next;
6293 }
6294
6295 free (edefs);
6296 }
6297 break;
103f02d3 6298
252b5132
RH
6299 case SHT_GNU_verneed:
6300 {
b34976b6
AM
6301 Elf_External_Verneed *eneed;
6302 unsigned int idx;
6303 unsigned int cnt;
252b5132
RH
6304
6305 found = 1;
6306
6307 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
6308 SECTION_NAME (section), section->sh_info);
6309
6310 printf (_(" Addr: 0x"));
6311 printf_vma (section->sh_addr);
6312 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
1b228002 6313 (unsigned long) section->sh_offset, section->sh_link,
c256ffe7
JJ
6314 SECTION_HEADER_INDEX (section->sh_link)
6315 < elf_header.e_shnum
6316 ? SECTION_NAME (SECTION_HEADER (section->sh_link))
6317 : "<corrupt>");
252b5132 6318
c256ffe7
JJ
6319 eneed = get_data (NULL, file, section->sh_offset, 1,
6320 section->sh_size,
d3ba0551 6321 _("version need section"));
a6e9f9df
AM
6322 if (!eneed)
6323 break;
252b5132
RH
6324
6325 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
6326 {
b34976b6
AM
6327 Elf_External_Verneed *entry;
6328 Elf_Internal_Verneed ent;
6329 int j;
6330 int isum;
6331 char *vstart;
252b5132
RH
6332
6333 vstart = ((char *) eneed) + idx;
6334
6335 entry = (Elf_External_Verneed *) vstart;
6336
6337 ent.vn_version = BYTE_GET (entry->vn_version);
6338 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
6339 ent.vn_file = BYTE_GET (entry->vn_file);
6340 ent.vn_aux = BYTE_GET (entry->vn_aux);
6341 ent.vn_next = BYTE_GET (entry->vn_next);
6342
6343 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
6344
d79b3d50
NC
6345 if (VALID_DYNAMIC_NAME (ent.vn_file))
6346 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
6347 else
6348 printf (_(" File: %lx"), ent.vn_file);
6349
6350 printf (_(" Cnt: %d\n"), ent.vn_cnt);
6351
6352 vstart += ent.vn_aux;
6353
6354 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
6355 {
b34976b6
AM
6356 Elf_External_Vernaux *eaux;
6357 Elf_Internal_Vernaux aux;
252b5132
RH
6358
6359 eaux = (Elf_External_Vernaux *) vstart;
6360
6361 aux.vna_hash = BYTE_GET (eaux->vna_hash);
6362 aux.vna_flags = BYTE_GET (eaux->vna_flags);
6363 aux.vna_other = BYTE_GET (eaux->vna_other);
6364 aux.vna_name = BYTE_GET (eaux->vna_name);
6365 aux.vna_next = BYTE_GET (eaux->vna_next);
6366
d79b3d50 6367 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 6368 printf (_(" %#06x: Name: %s"),
d79b3d50 6369 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 6370 else
ecc2063b 6371 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
6372 isum, aux.vna_name);
6373
6374 printf (_(" Flags: %s Version: %d\n"),
6375 get_ver_flags (aux.vna_flags), aux.vna_other);
6376
6377 isum += aux.vna_next;
6378 vstart += aux.vna_next;
6379 }
6380
6381 idx += ent.vn_next;
6382 }
103f02d3 6383
252b5132
RH
6384 free (eneed);
6385 }
6386 break;
6387
6388 case SHT_GNU_versym:
6389 {
b34976b6
AM
6390 Elf_Internal_Shdr *link_section;
6391 int total;
6392 int cnt;
6393 unsigned char *edata;
6394 unsigned short *data;
6395 char *strtab;
6396 Elf_Internal_Sym *symbols;
6397 Elf_Internal_Shdr *string_sec;
d3ba0551 6398 long off;
252b5132 6399
c256ffe7
JJ
6400 if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum)
6401 break;
6402
9ad5cbcf 6403 link_section = SECTION_HEADER (section->sh_link);
08d8fa11 6404 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 6405
c256ffe7
JJ
6406 if (SECTION_HEADER_INDEX (link_section->sh_link)
6407 >= elf_header.e_shnum)
6408 break;
6409
252b5132
RH
6410 found = 1;
6411
9ad5cbcf 6412 symbols = GET_ELF_SYMBOLS (file, link_section);
252b5132 6413
9ad5cbcf 6414 string_sec = SECTION_HEADER (link_section->sh_link);
252b5132 6415
c256ffe7 6416 strtab = get_data (NULL, file, string_sec->sh_offset, 1,
d3ba0551 6417 string_sec->sh_size, _("version string table"));
a6e9f9df
AM
6418 if (!strtab)
6419 break;
252b5132
RH
6420
6421 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
6422 SECTION_NAME (section), total);
6423
6424 printf (_(" Addr: "));
6425 printf_vma (section->sh_addr);
6426 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 6427 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
6428 SECTION_NAME (link_section));
6429
d3ba0551
AM
6430 off = offset_from_vma (file,
6431 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
6432 total * sizeof (short));
c256ffe7 6433 edata = get_data (NULL, file, off, total, sizeof (short),
d3ba0551 6434 _("version symbol data"));
a6e9f9df
AM
6435 if (!edata)
6436 {
6437 free (strtab);
6438 break;
6439 }
252b5132 6440
c256ffe7 6441 data = cmalloc (total, sizeof (short));
252b5132
RH
6442
6443 for (cnt = total; cnt --;)
b34976b6
AM
6444 data[cnt] = byte_get (edata + cnt * sizeof (short),
6445 sizeof (short));
252b5132
RH
6446
6447 free (edata);
6448
6449 for (cnt = 0; cnt < total; cnt += 4)
6450 {
6451 int j, nn;
00d93f34 6452 int check_def, check_need;
b34976b6 6453 char *name;
252b5132
RH
6454
6455 printf (" %03x:", cnt);
6456
6457 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 6458 switch (data[cnt + j])
252b5132
RH
6459 {
6460 case 0:
6461 fputs (_(" 0 (*local*) "), stdout);
6462 break;
6463
6464 case 1:
6465 fputs (_(" 1 (*global*) "), stdout);
6466 break;
6467
6468 default:
b34976b6
AM
6469 nn = printf ("%4x%c", data[cnt + j] & 0x7fff,
6470 data[cnt + j] & 0x8000 ? 'h' : ' ');
252b5132 6471
00d93f34
JJ
6472 check_def = 1;
6473 check_need = 1;
c256ffe7
JJ
6474 if (SECTION_HEADER_INDEX (symbols[cnt + j].st_shndx)
6475 >= elf_header.e_shnum
6476 || SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
6477 != SHT_NOBITS)
252b5132 6478 {
b34976b6 6479 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
6480 check_def = 0;
6481 else
6482 check_need = 0;
252b5132 6483 }
00d93f34
JJ
6484
6485 if (check_need
b34976b6 6486 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 6487 {
b34976b6
AM
6488 Elf_Internal_Verneed ivn;
6489 unsigned long offset;
252b5132 6490
d93f0186
NC
6491 offset = offset_from_vma
6492 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
6493 sizeof (Elf_External_Verneed));
252b5132 6494
b34976b6 6495 do
252b5132 6496 {
b34976b6
AM
6497 Elf_Internal_Vernaux ivna;
6498 Elf_External_Verneed evn;
6499 Elf_External_Vernaux evna;
6500 unsigned long a_off;
252b5132 6501
c256ffe7 6502 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 6503 _("version need"));
252b5132
RH
6504
6505 ivn.vn_aux = BYTE_GET (evn.vn_aux);
6506 ivn.vn_next = BYTE_GET (evn.vn_next);
6507
6508 a_off = offset + ivn.vn_aux;
6509
6510 do
6511 {
a6e9f9df 6512 get_data (&evna, file, a_off, sizeof (evna),
c256ffe7 6513 1, _("version need aux (2)"));
252b5132
RH
6514
6515 ivna.vna_next = BYTE_GET (evna.vna_next);
6516 ivna.vna_other = BYTE_GET (evna.vna_other);
6517
6518 a_off += ivna.vna_next;
6519 }
b34976b6 6520 while (ivna.vna_other != data[cnt + j]
252b5132
RH
6521 && ivna.vna_next != 0);
6522
b34976b6 6523 if (ivna.vna_other == data[cnt + j])
252b5132
RH
6524 {
6525 ivna.vna_name = BYTE_GET (evna.vna_name);
6526
16062207 6527 name = strtab + ivna.vna_name;
252b5132 6528 nn += printf ("(%s%-*s",
16062207
ILT
6529 name,
6530 12 - (int) strlen (name),
252b5132 6531 ")");
00d93f34 6532 check_def = 0;
252b5132
RH
6533 break;
6534 }
6535
6536 offset += ivn.vn_next;
6537 }
6538 while (ivn.vn_next);
6539 }
00d93f34 6540
b34976b6
AM
6541 if (check_def && data[cnt + j] != 0x8001
6542 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 6543 {
b34976b6
AM
6544 Elf_Internal_Verdef ivd;
6545 Elf_External_Verdef evd;
6546 unsigned long offset;
252b5132 6547
d93f0186
NC
6548 offset = offset_from_vma
6549 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
6550 sizeof evd);
252b5132
RH
6551
6552 do
6553 {
c256ffe7 6554 get_data (&evd, file, offset, sizeof (evd), 1,
a6e9f9df 6555 _("version def"));
252b5132
RH
6556
6557 ivd.vd_next = BYTE_GET (evd.vd_next);
6558 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
6559
6560 offset += ivd.vd_next;
6561 }
b34976b6 6562 while (ivd.vd_ndx != (data[cnt + j] & 0x7fff)
252b5132
RH
6563 && ivd.vd_next != 0);
6564
b34976b6 6565 if (ivd.vd_ndx == (data[cnt + j] & 0x7fff))
252b5132 6566 {
b34976b6
AM
6567 Elf_External_Verdaux evda;
6568 Elf_Internal_Verdaux ivda;
252b5132
RH
6569
6570 ivd.vd_aux = BYTE_GET (evd.vd_aux);
6571
a6e9f9df
AM
6572 get_data (&evda, file,
6573 offset - ivd.vd_next + ivd.vd_aux,
c256ffe7
JJ
6574 sizeof (evda), 1,
6575 _("version def aux"));
252b5132
RH
6576
6577 ivda.vda_name = BYTE_GET (evda.vda_name);
6578
16062207 6579 name = strtab + ivda.vda_name;
252b5132 6580 nn += printf ("(%s%-*s",
16062207
ILT
6581 name,
6582 12 - (int) strlen (name),
252b5132
RH
6583 ")");
6584 }
6585 }
6586
6587 if (nn < 18)
6588 printf ("%*c", 18 - nn, ' ');
6589 }
6590
6591 putchar ('\n');
6592 }
6593
6594 free (data);
6595 free (strtab);
6596 free (symbols);
6597 }
6598 break;
103f02d3 6599
252b5132
RH
6600 default:
6601 break;
6602 }
6603 }
6604
6605 if (! found)
6606 printf (_("\nNo version information found in this file.\n"));
6607
6608 return 1;
6609}
6610
d1133906 6611static const char *
d3ba0551 6612get_symbol_binding (unsigned int binding)
252b5132 6613{
b34976b6 6614 static char buff[32];
252b5132
RH
6615
6616 switch (binding)
6617 {
b34976b6
AM
6618 case STB_LOCAL: return "LOCAL";
6619 case STB_GLOBAL: return "GLOBAL";
6620 case STB_WEAK: return "WEAK";
252b5132
RH
6621 default:
6622 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
6623 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
6624 binding);
252b5132 6625 else if (binding >= STB_LOOS && binding <= STB_HIOS)
e9e44622 6626 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
252b5132 6627 else
e9e44622 6628 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
6629 return buff;
6630 }
6631}
6632
d1133906 6633static const char *
d3ba0551 6634get_symbol_type (unsigned int type)
252b5132 6635{
b34976b6 6636 static char buff[32];
252b5132
RH
6637
6638 switch (type)
6639 {
b34976b6
AM
6640 case STT_NOTYPE: return "NOTYPE";
6641 case STT_OBJECT: return "OBJECT";
6642 case STT_FUNC: return "FUNC";
6643 case STT_SECTION: return "SECTION";
6644 case STT_FILE: return "FILE";
6645 case STT_COMMON: return "COMMON";
6646 case STT_TLS: return "TLS";
252b5132
RH
6647 default:
6648 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
6649 {
6650 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
6651 return "THUMB_FUNC";
6652
351b4b40 6653 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
6654 return "REGISTER";
6655
6656 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
6657 return "PARISC_MILLI";
6658
e9e44622 6659 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 6660 }
252b5132 6661 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
6662 {
6663 if (elf_header.e_machine == EM_PARISC)
6664 {
6665 if (type == STT_HP_OPAQUE)
6666 return "HP_OPAQUE";
6667 if (type == STT_HP_STUB)
6668 return "HP_STUB";
6669 }
6670
e9e44622 6671 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 6672 }
252b5132 6673 else
e9e44622 6674 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
6675 return buff;
6676 }
6677}
6678
d1133906 6679static const char *
d3ba0551 6680get_symbol_visibility (unsigned int visibility)
d1133906
NC
6681{
6682 switch (visibility)
6683 {
b34976b6
AM
6684 case STV_DEFAULT: return "DEFAULT";
6685 case STV_INTERNAL: return "INTERNAL";
6686 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
6687 case STV_PROTECTED: return "PROTECTED";
6688 default: abort ();
6689 }
6690}
6691
6692static const char *
d3ba0551 6693get_symbol_index_type (unsigned int type)
252b5132 6694{
b34976b6 6695 static char buff[32];
5cf1065c 6696
252b5132
RH
6697 switch (type)
6698 {
b34976b6
AM
6699 case SHN_UNDEF: return "UND";
6700 case SHN_ABS: return "ABS";
6701 case SHN_COMMON: return "COM";
252b5132 6702 default:
9ce701e2
L
6703 if (type == SHN_IA_64_ANSI_COMMON
6704 && elf_header.e_machine == EM_IA_64
6705 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
6706 return "ANSI_COM";
3b22753a
L
6707 else if (elf_header.e_machine == EM_X86_64
6708 && type == SHN_X86_64_LCOMMON)
6709 return "LARGE_COM";
9ce701e2 6710 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
5cf1065c 6711 sprintf (buff, "PRC[0x%04x]", type);
252b5132 6712 else if (type >= SHN_LOOS && type <= SHN_HIOS)
5cf1065c 6713 sprintf (buff, "OS [0x%04x]", type);
9ad5cbcf 6714 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
5cf1065c 6715 sprintf (buff, "RSV[0x%04x]", type);
252b5132 6716 else
232e7cb8 6717 sprintf (buff, "%3d", type);
5cf1065c 6718 break;
252b5132 6719 }
5cf1065c
NC
6720
6721 return buff;
252b5132
RH
6722}
6723
66543521
AM
6724static bfd_vma *
6725get_dynamic_data (FILE *file, unsigned int number, unsigned int ent_size)
252b5132 6726{
b34976b6 6727 unsigned char *e_data;
66543521 6728 bfd_vma *i_data;
252b5132 6729
c256ffe7 6730 e_data = cmalloc (number, ent_size);
252b5132
RH
6731
6732 if (e_data == NULL)
6733 {
6734 error (_("Out of memory\n"));
6735 return NULL;
6736 }
6737
66543521 6738 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
6739 {
6740 error (_("Unable to read in dynamic data\n"));
6741 return NULL;
6742 }
6743
c256ffe7 6744 i_data = cmalloc (number, sizeof (*i_data));
252b5132
RH
6745
6746 if (i_data == NULL)
6747 {
6748 error (_("Out of memory\n"));
6749 free (e_data);
6750 return NULL;
6751 }
6752
6753 while (number--)
66543521 6754 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
6755
6756 free (e_data);
6757
6758 return i_data;
6759}
6760
e3c8793a 6761/* Dump the symbol table. */
252b5132 6762static int
d3ba0551 6763process_symbol_table (FILE *file)
252b5132 6764{
b34976b6 6765 Elf_Internal_Shdr *section;
66543521
AM
6766 bfd_vma nbuckets = 0;
6767 bfd_vma nchains = 0;
6768 bfd_vma *buckets = NULL;
6769 bfd_vma *chains = NULL;
252b5132
RH
6770
6771 if (! do_syms && !do_histogram)
6772 return 1;
6773
6774 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
6775 || do_histogram))
6776 {
66543521
AM
6777 unsigned char nb[8];
6778 unsigned char nc[8];
6779 int hash_ent_size = 4;
6780
6781 if ((elf_header.e_machine == EM_ALPHA
6782 || elf_header.e_machine == EM_S390
6783 || elf_header.e_machine == EM_S390_OLD)
6784 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
6785 hash_ent_size = 8;
6786
fb52b2f4
NC
6787 if (fseek (file,
6788 (archive_file_offset
6789 + offset_from_vma (file, dynamic_info[DT_HASH],
6790 sizeof nb + sizeof nc)),
d93f0186 6791 SEEK_SET))
252b5132
RH
6792 {
6793 error (_("Unable to seek to start of dynamic information"));
6794 return 0;
6795 }
6796
66543521 6797 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
6798 {
6799 error (_("Failed to read in number of buckets\n"));
6800 return 0;
6801 }
6802
66543521 6803 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
6804 {
6805 error (_("Failed to read in number of chains\n"));
6806 return 0;
6807 }
6808
66543521
AM
6809 nbuckets = byte_get (nb, hash_ent_size);
6810 nchains = byte_get (nc, hash_ent_size);
252b5132 6811
66543521
AM
6812 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
6813 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132
RH
6814
6815 if (buckets == NULL || chains == NULL)
6816 return 0;
6817 }
6818
6819 if (do_syms
6820 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
6821 {
66543521
AM
6822 unsigned long hn;
6823 bfd_vma si;
252b5132
RH
6824
6825 printf (_("\nSymbol table for image:\n"));
f7a99963 6826 if (is_32bit_elf)
ca47b30c 6827 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 6828 else
ca47b30c 6829 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
252b5132
RH
6830
6831 for (hn = 0; hn < nbuckets; hn++)
6832 {
b34976b6 6833 if (! buckets[hn])
252b5132
RH
6834 continue;
6835
b34976b6 6836 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
252b5132 6837 {
b34976b6 6838 Elf_Internal_Sym *psym;
66543521 6839 int n;
252b5132
RH
6840
6841 psym = dynamic_symbols + si;
6842
66543521
AM
6843 n = print_vma (si, DEC_5);
6844 if (n < 5)
6845 fputs (" " + n, stdout);
6846 printf (" %3lu: ", hn);
f7a99963 6847 print_vma (psym->st_value, LONG_HEX);
66543521 6848 putchar (' ');
d1133906 6849 print_vma (psym->st_size, DEC_5);
76da6bbe 6850
d1133906
NC
6851 printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
6852 printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
6853 printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126 6854 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
d79b3d50
NC
6855 if (VALID_DYNAMIC_NAME (psym->st_name))
6856 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
6857 else
6858 printf (" <corrupt: %14ld>", psym->st_name);
31104126 6859 putchar ('\n');
252b5132
RH
6860 }
6861 }
6862 }
6863 else if (do_syms && !do_using_dynamic)
6864 {
b34976b6 6865 unsigned int i;
252b5132
RH
6866
6867 for (i = 0, section = section_headers;
6868 i < elf_header.e_shnum;
6869 i++, section++)
6870 {
b34976b6 6871 unsigned int si;
c256ffe7
JJ
6872 char *strtab = NULL;
6873 unsigned long int strtab_size = 0;
b34976b6
AM
6874 Elf_Internal_Sym *symtab;
6875 Elf_Internal_Sym *psym;
252b5132
RH
6876
6877
6878 if ( section->sh_type != SHT_SYMTAB
6879 && section->sh_type != SHT_DYNSYM)
6880 continue;
6881
6882 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
6883 SECTION_NAME (section),
6884 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 6885 if (is_32bit_elf)
ca47b30c 6886 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 6887 else
ca47b30c 6888 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 6889
9ad5cbcf 6890 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
6891 if (symtab == NULL)
6892 continue;
6893
6894 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
6895 {
6896 strtab = string_table;
6897 strtab_size = string_table_length;
6898 }
6899 else if (SECTION_HEADER_INDEX (section->sh_link) < elf_header.e_shnum)
252b5132 6900 {
b34976b6 6901 Elf_Internal_Shdr *string_sec;
252b5132 6902
9ad5cbcf 6903 string_sec = SECTION_HEADER (section->sh_link);
252b5132 6904
d3ba0551 6905 strtab = get_data (NULL, file, string_sec->sh_offset,
c256ffe7
JJ
6906 1, string_sec->sh_size, _("string table"));
6907 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
6908 }
6909
6910 for (si = 0, psym = symtab;
6911 si < section->sh_size / section->sh_entsize;
b34976b6 6912 si++, psym++)
252b5132 6913 {
5e220199 6914 printf ("%6d: ", si);
f7a99963
NC
6915 print_vma (psym->st_value, LONG_HEX);
6916 putchar (' ');
6917 print_vma (psym->st_size, DEC_5);
d1133906
NC
6918 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
6919 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
6920 printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
31104126 6921 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7
JJ
6922 print_symbol (25, psym->st_name < strtab_size
6923 ? strtab + psym->st_name : "<corrupt>");
252b5132
RH
6924
6925 if (section->sh_type == SHT_DYNSYM &&
b34976b6 6926 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 6927 {
b34976b6
AM
6928 unsigned char data[2];
6929 unsigned short vers_data;
6930 unsigned long offset;
6931 int is_nobits;
6932 int check_def;
252b5132 6933
d93f0186
NC
6934 offset = offset_from_vma
6935 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
6936 sizeof data + si * sizeof (vers_data));
252b5132 6937
a6e9f9df 6938 get_data (&data, file, offset + si * sizeof (vers_data),
c256ffe7 6939 sizeof (data), 1, _("version data"));
252b5132
RH
6940
6941 vers_data = byte_get (data, 2);
6942
c256ffe7
JJ
6943 is_nobits = (SECTION_HEADER_INDEX (psym->st_shndx)
6944 < elf_header.e_shnum
6945 && SECTION_HEADER (psym->st_shndx)->sh_type
6946 == SHT_NOBITS);
252b5132
RH
6947
6948 check_def = (psym->st_shndx != SHN_UNDEF);
6949
6950 if ((vers_data & 0x8000) || vers_data > 1)
6951 {
b34976b6 6952 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 6953 && (is_nobits || ! check_def))
252b5132 6954 {
b34976b6
AM
6955 Elf_External_Verneed evn;
6956 Elf_Internal_Verneed ivn;
6957 Elf_Internal_Vernaux ivna;
252b5132
RH
6958
6959 /* We must test both. */
d93f0186
NC
6960 offset = offset_from_vma
6961 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
6962 sizeof evn);
252b5132 6963
252b5132
RH
6964 do
6965 {
b34976b6 6966 unsigned long vna_off;
252b5132 6967
c256ffe7 6968 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 6969 _("version need"));
dd27201e
L
6970
6971 ivn.vn_aux = BYTE_GET (evn.vn_aux);
6972 ivn.vn_next = BYTE_GET (evn.vn_next);
6973
252b5132
RH
6974 vna_off = offset + ivn.vn_aux;
6975
6976 do
6977 {
b34976b6 6978 Elf_External_Vernaux evna;
252b5132 6979
a6e9f9df 6980 get_data (&evna, file, vna_off,
c256ffe7 6981 sizeof (evna), 1,
a6e9f9df 6982 _("version need aux (3)"));
252b5132
RH
6983
6984 ivna.vna_other = BYTE_GET (evna.vna_other);
6985 ivna.vna_next = BYTE_GET (evna.vna_next);
6986 ivna.vna_name = BYTE_GET (evna.vna_name);
6987
6988 vna_off += ivna.vna_next;
6989 }
6990 while (ivna.vna_other != vers_data
6991 && ivna.vna_next != 0);
6992
6993 if (ivna.vna_other == vers_data)
6994 break;
6995
6996 offset += ivn.vn_next;
6997 }
6998 while (ivn.vn_next != 0);
6999
7000 if (ivna.vna_other == vers_data)
7001 {
7002 printf ("@%s (%d)",
c256ffe7
JJ
7003 ivna.vna_name < strtab_size
7004 ? strtab + ivna.vna_name : "<corrupt>",
7005 ivna.vna_other);
252b5132
RH
7006 check_def = 0;
7007 }
7008 else if (! is_nobits)
7009 error (_("bad dynamic symbol"));
7010 else
7011 check_def = 1;
7012 }
7013
7014 if (check_def)
7015 {
00d93f34 7016 if (vers_data != 0x8001
b34976b6 7017 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 7018 {
b34976b6
AM
7019 Elf_Internal_Verdef ivd;
7020 Elf_Internal_Verdaux ivda;
7021 Elf_External_Verdaux evda;
7022 unsigned long offset;
252b5132 7023
d93f0186
NC
7024 offset = offset_from_vma
7025 (file,
7026 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
7027 sizeof (Elf_External_Verdef));
252b5132
RH
7028
7029 do
7030 {
b34976b6 7031 Elf_External_Verdef evd;
252b5132 7032
a6e9f9df 7033 get_data (&evd, file, offset, sizeof (evd),
c256ffe7 7034 1, _("version def"));
252b5132 7035
b34976b6
AM
7036 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
7037 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
7038 ivd.vd_next = BYTE_GET (evd.vd_next);
7039
7040 offset += ivd.vd_next;
7041 }
7042 while (ivd.vd_ndx != (vers_data & 0x7fff)
7043 && ivd.vd_next != 0);
7044
7045 offset -= ivd.vd_next;
7046 offset += ivd.vd_aux;
7047
a6e9f9df 7048 get_data (&evda, file, offset, sizeof (evda),
c256ffe7 7049 1, _("version def aux"));
252b5132
RH
7050
7051 ivda.vda_name = BYTE_GET (evda.vda_name);
7052
7053 if (psym->st_name != ivda.vda_name)
7054 printf ((vers_data & 0x8000)
7055 ? "@%s" : "@@%s",
c256ffe7
JJ
7056 ivda.vda_name < strtab_size
7057 ? strtab + ivda.vda_name : "<corrupt>");
252b5132
RH
7058 }
7059 }
7060 }
7061 }
7062
7063 putchar ('\n');
7064 }
7065
7066 free (symtab);
7067 if (strtab != string_table)
7068 free (strtab);
7069 }
7070 }
7071 else if (do_syms)
7072 printf
7073 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
7074
7075 if (do_histogram && buckets != NULL)
7076 {
66543521
AM
7077 unsigned long *lengths;
7078 unsigned long *counts;
7079 unsigned long hn;
7080 bfd_vma si;
7081 unsigned long maxlength = 0;
7082 unsigned long nzero_counts = 0;
7083 unsigned long nsyms = 0;
252b5132 7084
66543521
AM
7085 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
7086 (unsigned long) nbuckets);
252b5132
RH
7087 printf (_(" Length Number %% of total Coverage\n"));
7088
66543521 7089 lengths = calloc (nbuckets, sizeof (*lengths));
252b5132
RH
7090 if (lengths == NULL)
7091 {
7092 error (_("Out of memory"));
7093 return 0;
7094 }
7095 for (hn = 0; hn < nbuckets; ++hn)
7096 {
f7a99963 7097 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 7098 {
b34976b6 7099 ++nsyms;
252b5132 7100 if (maxlength < ++lengths[hn])
b34976b6 7101 ++maxlength;
252b5132
RH
7102 }
7103 }
7104
66543521 7105 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
7106 if (counts == NULL)
7107 {
7108 error (_("Out of memory"));
7109 return 0;
7110 }
7111
7112 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 7113 ++counts[lengths[hn]];
252b5132 7114
103f02d3 7115 if (nbuckets > 0)
252b5132 7116 {
66543521
AM
7117 unsigned long i;
7118 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 7119 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 7120 for (i = 1; i <= maxlength; ++i)
103f02d3 7121 {
66543521
AM
7122 nzero_counts += counts[i] * i;
7123 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
7124 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
7125 (nzero_counts * 100.0) / nsyms);
7126 }
252b5132
RH
7127 }
7128
7129 free (counts);
7130 free (lengths);
7131 }
7132
7133 if (buckets != NULL)
7134 {
7135 free (buckets);
7136 free (chains);
7137 }
7138
7139 return 1;
7140}
7141
7142static int
d3ba0551 7143process_syminfo (FILE *file ATTRIBUTE_UNUSED)
252b5132 7144{
b4c96d0d 7145 unsigned int i;
252b5132
RH
7146
7147 if (dynamic_syminfo == NULL
7148 || !do_dynamic)
7149 /* No syminfo, this is ok. */
7150 return 1;
7151
7152 /* There better should be a dynamic symbol section. */
7153 if (dynamic_symbols == NULL || dynamic_strings == NULL)
7154 return 0;
7155
7156 if (dynamic_addr)
7157 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
7158 dynamic_syminfo_offset, dynamic_syminfo_nent);
7159
7160 printf (_(" Num: Name BoundTo Flags\n"));
7161 for (i = 0; i < dynamic_syminfo_nent; ++i)
7162 {
7163 unsigned short int flags = dynamic_syminfo[i].si_flags;
7164
31104126 7165 printf ("%4d: ", i);
d79b3d50
NC
7166 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
7167 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
7168 else
7169 printf ("<corrupt: %19ld>", dynamic_symbols[i].st_name);
31104126 7170 putchar (' ');
252b5132
RH
7171
7172 switch (dynamic_syminfo[i].si_boundto)
7173 {
7174 case SYMINFO_BT_SELF:
7175 fputs ("SELF ", stdout);
7176 break;
7177 case SYMINFO_BT_PARENT:
7178 fputs ("PARENT ", stdout);
7179 break;
7180 default:
7181 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
7182 && dynamic_syminfo[i].si_boundto < dynamic_nent
7183 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 7184 {
d79b3d50 7185 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
7186 putchar (' ' );
7187 }
252b5132
RH
7188 else
7189 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
7190 break;
7191 }
7192
7193 if (flags & SYMINFO_FLG_DIRECT)
7194 printf (" DIRECT");
7195 if (flags & SYMINFO_FLG_PASSTHRU)
7196 printf (" PASSTHRU");
7197 if (flags & SYMINFO_FLG_COPY)
7198 printf (" COPY");
7199 if (flags & SYMINFO_FLG_LAZYLOAD)
7200 printf (" LAZYLOAD");
7201
7202 puts ("");
7203 }
7204
7205 return 1;
7206}
7207
7208#ifdef SUPPORT_DISASSEMBLY
18bd398b 7209static int
d3ba0551 7210disassemble_section (Elf_Internal_Shdr *section, FILE *file)
252b5132
RH
7211{
7212 printf (_("\nAssembly dump of section %s\n"),
7213 SECTION_NAME (section));
7214
7215 /* XXX -- to be done --- XXX */
7216
7217 return 1;
7218}
7219#endif
7220
7221static int
d3ba0551 7222dump_section (Elf_Internal_Shdr *section, FILE *file)
252b5132 7223{
b34976b6
AM
7224 bfd_size_type bytes;
7225 bfd_vma addr;
7226 unsigned char *data;
7227 unsigned char *start;
252b5132
RH
7228
7229 bytes = section->sh_size;
7230
e69f2d21 7231 if (bytes == 0 || section->sh_type == SHT_NOBITS)
252b5132
RH
7232 {
7233 printf (_("\nSection '%s' has no data to dump.\n"),
7234 SECTION_NAME (section));
7235 return 0;
7236 }
7237 else
7238 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
7239
7240 addr = section->sh_addr;
7241
c256ffe7
JJ
7242 start = get_data (NULL, file, section->sh_offset, 1, bytes,
7243 _("section data"));
a6e9f9df
AM
7244 if (!start)
7245 return 0;
252b5132
RH
7246
7247 data = start;
7248
7249 while (bytes)
7250 {
7251 int j;
7252 int k;
7253 int lbytes;
7254
7255 lbytes = (bytes > 16 ? 16 : bytes);
7256
148d3c43 7257 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132 7258
b34976b6 7259 switch (elf_header.e_ident[EI_DATA])
252b5132 7260 {
9ea033b2 7261 default:
252b5132
RH
7262 case ELFDATA2LSB:
7263 for (j = 15; j >= 0; j --)
7264 {
7265 if (j < lbytes)
b34976b6 7266 printf ("%2.2x", data[j]);
252b5132
RH
7267 else
7268 printf (" ");
7269
7270 if (!(j & 0x3))
7271 printf (" ");
7272 }
7273 break;
7274
7275 case ELFDATA2MSB:
7276 for (j = 0; j < 16; j++)
7277 {
7278 if (j < lbytes)
b34976b6 7279 printf ("%2.2x", data[j]);
252b5132
RH
7280 else
7281 printf (" ");
7282
7283 if ((j & 3) == 3)
7284 printf (" ");
7285 }
7286 break;
7287 }
7288
7289 for (j = 0; j < lbytes; j++)
7290 {
b34976b6 7291 k = data[j];
9376f0c7 7292 if (k >= ' ' && k < 0x7f)
252b5132
RH
7293 printf ("%c", k);
7294 else
7295 printf (".");
7296 }
7297
7298 putchar ('\n');
7299
7300 data += lbytes;
7301 addr += lbytes;
7302 bytes -= lbytes;
7303 }
7304
7305 free (start);
7306
7307 return 1;
7308}
7309
1007acb3 7310/* Apply addends of RELA relocations. */
d9296b18 7311
1007acb3
L
7312static int
7313debug_apply_rela_addends (void *file,
7314 Elf_Internal_Shdr *section,
7315 unsigned char *start)
d9296b18 7316{
1007acb3
L
7317 Elf_Internal_Shdr *relsec;
7318 unsigned char *end = start + section->sh_size;
7319 /* FIXME: The relocation field size is relocation type dependent. */
7320 unsigned int reloc_size = 4;
18bd398b 7321
1007acb3
L
7322 if (!is_relocatable)
7323 return 1;
d9296b18 7324
1007acb3
L
7325 if (section->sh_size < reloc_size)
7326 return 1;
d9296b18 7327
5b18a4bc
NC
7328 for (relsec = section_headers;
7329 relsec < section_headers + elf_header.e_shnum;
7330 ++relsec)
252b5132 7331 {
5b18a4bc
NC
7332 unsigned long nrelas;
7333 Elf_Internal_Rela *rela, *rp;
7334 Elf_Internal_Shdr *symsec;
7335 Elf_Internal_Sym *symtab;
7336 Elf_Internal_Sym *sym;
252b5132 7337
5b18a4bc 7338 if (relsec->sh_type != SHT_RELA
c256ffe7 7339 || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
5b18a4bc 7340 || SECTION_HEADER (relsec->sh_info) != section
c256ffe7
JJ
7341 || relsec->sh_size == 0
7342 || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum)
5b18a4bc 7343 continue;
428409d5 7344
5b18a4bc
NC
7345 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7346 &rela, &nrelas))
7347 return 0;
428409d5 7348
5b18a4bc
NC
7349 symsec = SECTION_HEADER (relsec->sh_link);
7350 symtab = GET_ELF_SYMBOLS (file, symsec);
103f02d3 7351
5b18a4bc 7352 for (rp = rela; rp < rela + nrelas; ++rp)
252b5132 7353 {
5b18a4bc 7354 unsigned char *loc;
103f02d3 7355
700dd8b7
L
7356 loc = start + rp->r_offset;
7357 if ((loc + reloc_size) > end)
7358 {
7359 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
7360 (unsigned long) rp->r_offset,
7361 SECTION_NAME (section));
7362 continue;
7363 }
103f02d3 7364
5b18a4bc
NC
7365 if (is_32bit_elf)
7366 {
7367 sym = symtab + ELF32_R_SYM (rp->r_info);
103f02d3 7368
5b18a4bc
NC
7369 if (ELF32_R_SYM (rp->r_info) != 0
7370 && ELF32_ST_TYPE (sym->st_info) != STT_SECTION
7371 /* Relocations against object symbols can happen,
7372 eg when referencing a global array. For an
7373 example of this see the _clz.o binary in libgcc.a. */
7374 && ELF32_ST_TYPE (sym->st_info) != STT_OBJECT)
7375 {
520494b6 7376 warn (_("skipping unexpected symbol type %s in relocation in section .rela%s\n"),
5b18a4bc
NC
7377 get_symbol_type (ELF32_ST_TYPE (sym->st_info)),
7378 SECTION_NAME (section));
7379 continue;
7380 }
7381 }
7382 else
7383 {
a8b683fc
MR
7384 /* In MIPS little-endian objects, r_info isn't really a
7385 64-bit little-endian value: it has a 32-bit little-endian
7386 symbol index followed by four individual byte fields.
7387 Reorder INFO accordingly. */
7388 if (elf_header.e_machine == EM_MIPS
7389 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
7390 rp->r_info = (((rp->r_info & 0xffffffff) << 32)
7391 | ((rp->r_info >> 56) & 0xff)
7392 | ((rp->r_info >> 40) & 0xff00)
7393 | ((rp->r_info >> 24) & 0xff0000)
7394 | ((rp->r_info >> 8) & 0xff000000));
7395
5b18a4bc 7396 sym = symtab + ELF64_R_SYM (rp->r_info);
0e0c4098 7397
5b18a4bc
NC
7398 if (ELF64_R_SYM (rp->r_info) != 0
7399 && ELF64_ST_TYPE (sym->st_info) != STT_SECTION
7400 && ELF64_ST_TYPE (sym->st_info) != STT_OBJECT)
7401 {
7402 warn (_("skipping unexpected symbol type %s in relocation in section .rela.%s\n"),
7403 get_symbol_type (ELF64_ST_TYPE (sym->st_info)),
7404 SECTION_NAME (section));
7405 continue;
7406 }
7407 }
252b5132 7408
5b18a4bc
NC
7409 byte_put (loc, rp->r_addend, reloc_size);
7410 }
252b5132 7411
5b18a4bc
NC
7412 free (symtab);
7413 free (rela);
7414 break;
7415 }
7416 return 1;
7417}
103f02d3 7418
19e6b90e
L
7419int
7420load_debug_section (enum dwarf_section_display_enum debug, void *file)
1007acb3 7421{
19e6b90e
L
7422 struct dwarf_section *section = &debug_displays [debug].section;
7423 Elf_Internal_Shdr *sec;
7424 char buf [64];
1007acb3 7425
19e6b90e
L
7426 /* If it is already loaded, do nothing. */
7427 if (section->start != NULL)
7428 return 1;
1007acb3 7429
19e6b90e
L
7430 /* Locate the debug section. */
7431 sec = find_section (section->name);
7432 if (sec == NULL)
7433 return 0;
1007acb3 7434
19e6b90e
L
7435 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
7436 section->address = sec->sh_addr;
7437 section->size = sec->sh_size;
7438 section->start = get_data (NULL, file, sec->sh_offset, 1,
7439 sec->sh_size, buf);
1007acb3 7440
19e6b90e
L
7441 if (debug_displays [debug].relocate)
7442 debug_apply_rela_addends (file, sec, section->start);
1007acb3 7443
19e6b90e 7444 return section->start != NULL;
1007acb3
L
7445}
7446
19e6b90e
L
7447void
7448free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 7449{
19e6b90e 7450 struct dwarf_section *section = &debug_displays [debug].section;
1007acb3 7451
19e6b90e
L
7452 if (section->start == NULL)
7453 return;
1007acb3 7454
19e6b90e
L
7455 free ((char *) section->start);
7456 section->start = NULL;
7457 section->address = 0;
7458 section->size = 0;
1007acb3
L
7459}
7460
1007acb3 7461static int
19e6b90e 7462display_debug_section (Elf_Internal_Shdr *section, FILE *file)
1007acb3 7463{
19e6b90e
L
7464 char *name = SECTION_NAME (section);
7465 bfd_size_type length;
7466 int result = 1;
7467 enum dwarf_section_display_enum i;
1007acb3 7468
19e6b90e
L
7469 length = section->sh_size;
7470 if (length == 0)
1007acb3 7471 {
19e6b90e
L
7472 printf (_("\nSection '%s' has no debugging data.\n"), name);
7473 return 0;
1007acb3
L
7474 }
7475
19e6b90e
L
7476 if (strneq (name, ".gnu.linkonce.wi.", 17))
7477 name = ".debug_info";
1007acb3 7478
19e6b90e
L
7479 /* See if we know how to display the contents of this section. */
7480 for (i = 0; i < max; i++)
7481 if (streq (debug_displays[i].section.name, name))
7482 {
7483 struct dwarf_section *sec = &debug_displays [i].section;
1007acb3 7484
19e6b90e
L
7485 if (load_debug_section (i, file))
7486 {
7487 result &= debug_displays[i].display (sec, file);
1007acb3 7488
19e6b90e
L
7489 if (i != info && i != abbrev)
7490 free_debug_section (i);
7491 }
1007acb3 7492
19e6b90e
L
7493 break;
7494 }
1007acb3 7495
19e6b90e 7496 if (i == max)
1007acb3 7497 {
19e6b90e
L
7498 printf (_("Unrecognized debug section: %s\n"), name);
7499 result = 0;
1007acb3
L
7500 }
7501
19e6b90e 7502 return result;
5b18a4bc 7503}
103f02d3 7504
5b18a4bc 7505static void
19e6b90e 7506process_section_contents (FILE *file)
5b18a4bc 7507{
19e6b90e
L
7508 Elf_Internal_Shdr *section;
7509 unsigned int i;
103f02d3 7510
19e6b90e
L
7511 if (! do_dump)
7512 return;
103f02d3 7513
19e6b90e
L
7514 for (i = 0, section = section_headers;
7515 i < elf_header.e_shnum && i < num_dump_sects;
7516 i++, section++)
7517 {
7518#ifdef SUPPORT_DISASSEMBLY
7519 if (dump_sects[i] & DISASS_DUMP)
7520 disassemble_section (section, file);
7521#endif
7522 if (dump_sects[i] & HEX_DUMP)
7523 dump_section (section, file);
103f02d3 7524
19e6b90e
L
7525 if (dump_sects[i] & DEBUG_DUMP)
7526 display_debug_section (section, file);
5b18a4bc 7527 }
103f02d3 7528
19e6b90e
L
7529 /* Check to see if the user requested a
7530 dump of a section that does not exist. */
7531 while (i++ < num_dump_sects)
7532 if (dump_sects[i])
7533 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 7534}
103f02d3 7535
5b18a4bc 7536static void
19e6b90e 7537process_mips_fpe_exception (int mask)
5b18a4bc 7538{
19e6b90e
L
7539 if (mask)
7540 {
7541 int first = 1;
7542 if (mask & OEX_FPU_INEX)
7543 fputs ("INEX", stdout), first = 0;
7544 if (mask & OEX_FPU_UFLO)
7545 printf ("%sUFLO", first ? "" : "|"), first = 0;
7546 if (mask & OEX_FPU_OFLO)
7547 printf ("%sOFLO", first ? "" : "|"), first = 0;
7548 if (mask & OEX_FPU_DIV0)
7549 printf ("%sDIV0", first ? "" : "|"), first = 0;
7550 if (mask & OEX_FPU_INVAL)
7551 printf ("%sINVAL", first ? "" : "|");
7552 }
5b18a4bc 7553 else
19e6b90e 7554 fputs ("0", stdout);
5b18a4bc 7555}
103f02d3 7556
11c1ff18
PB
7557/* ARM EABI attributes section. */
7558typedef struct
7559{
7560 int tag;
7561 const char *name;
7562 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
7563 int type;
7564 const char **table;
7565} arm_attr_public_tag;
7566
7567static const char *arm_attr_tag_CPU_arch[] =
7568 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
7569 "v6K", "v7"};
7570static const char *arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
7571static const char *arm_attr_tag_THUMB_ISA_use[] =
7572 {"No", "Thumb-1", "Thumb-2"};
7573static const char *arm_attr_tag_VFP_arch[] = {"No", "VFPv1", "VFPv2"};
7574static const char *arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1"};
7575static const char *arm_attr_tag_NEON_arch[] = {"No", "NEONv1"};
7576static const char *arm_attr_tag_ABI_PCS_config[] =
7577 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
7578 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
7579static const char *arm_attr_tag_ABI_PCS_R9_use[] =
7580 {"V6", "SB", "TLS", "Unused"};
7581static const char *arm_attr_tag_ABI_PCS_RW_data[] =
7582 {"Absolute", "PC-relative", "SB-relative", "None"};
7583static const char *arm_attr_tag_ABI_PCS_RO_DATA[] =
7584 {"Absolute", "PC-relative", "None"};
7585static const char *arm_attr_tag_ABI_PCS_GOT_use[] =
7586 {"None", "direct", "GOT-indirect"};
7587static const char *arm_attr_tag_ABI_PCS_wchar_t[] =
7588 {"None", "??? 1", "2", "??? 3", "4"};
7589static const char *arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
7590static const char *arm_attr_tag_ABI_FP_denormal[] = {"Unused", "Needed"};
7591static const char *arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
7592static const char *arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
7593static const char *arm_attr_tag_ABI_FP_number_model[] =
7594 {"Unused", "Finite", "RTABI", "IEEE 754"};
7595static const char *arm_attr_tag_ABI_align8_needed[] = {"No", "Yes", "4-byte"};
7596static const char *arm_attr_tag_ABI_align8_preserved[] =
7597 {"No", "Yes, except leaf SP", "Yes"};
7598static const char *arm_attr_tag_ABI_enum_size[] =
7599 {"Unused", "small", "int", "forced to int"};
7600static const char *arm_attr_tag_ABI_HardFP_use[] =
7601 {"As Tag_VFP_arch", "SP only", "DP only", "SP and DP"};
7602static const char *arm_attr_tag_ABI_VFP_args[] =
7603 {"AAPCS", "VFP registers", "custom"};
7604static const char *arm_attr_tag_ABI_WMMX_args[] =
7605 {"AAPCS", "WMMX registers", "custom"};
7606static const char *arm_attr_tag_ABI_optimization_goals[] =
7607 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
7608 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
7609static const char *arm_attr_tag_ABI_FP_optimization_goals[] =
7610 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
7611 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
7612
7613#define LOOKUP(id, name) \
7614 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
7615static arm_attr_public_tag arm_attr_public_tags[] =
7616{
7617 {4, "CPU_raw_name", 1, NULL},
7618 {5, "CPU_name", 1, NULL},
7619 LOOKUP(6, CPU_arch),
7620 {7, "CPU_arch_profile", 0, NULL},
7621 LOOKUP(8, ARM_ISA_use),
7622 LOOKUP(9, THUMB_ISA_use),
7623 LOOKUP(10, VFP_arch),
7624 LOOKUP(11, WMMX_arch),
7625 LOOKUP(12, NEON_arch),
7626 LOOKUP(13, ABI_PCS_config),
7627 LOOKUP(14, ABI_PCS_R9_use),
7628 LOOKUP(15, ABI_PCS_RW_data),
7629 LOOKUP(16, ABI_PCS_RO_DATA),
7630 LOOKUP(17, ABI_PCS_GOT_use),
7631 LOOKUP(18, ABI_PCS_wchar_t),
7632 LOOKUP(19, ABI_FP_rounding),
7633 LOOKUP(20, ABI_FP_denormal),
7634 LOOKUP(21, ABI_FP_exceptions),
7635 LOOKUP(22, ABI_FP_user_exceptions),
7636 LOOKUP(23, ABI_FP_number_model),
7637 LOOKUP(24, ABI_align8_needed),
7638 LOOKUP(25, ABI_align8_preserved),
7639 LOOKUP(26, ABI_enum_size),
7640 LOOKUP(27, ABI_HardFP_use),
7641 LOOKUP(28, ABI_VFP_args),
7642 LOOKUP(29, ABI_WMMX_args),
7643 LOOKUP(30, ABI_optimization_goals),
7644 LOOKUP(31, ABI_FP_optimization_goals),
7645 {32, "compatibility", 0, NULL}
7646};
7647#undef LOOKUP
7648
7649/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
7650 bytes read. */
7651static unsigned int
7652read_uleb128 (unsigned char *p, unsigned int *plen)
7653{
7654 unsigned char c;
7655 unsigned int val;
7656 int shift;
7657 int len;
7658
7659 val = 0;
7660 shift = 0;
7661 len = 0;
7662 do
7663 {
7664 c = *(p++);
7665 len++;
7666 val |= ((unsigned int)c & 0x7f) << shift;
7667 shift += 7;
7668 }
7669 while (c & 0x80);
7670
7671 *plen = len;
7672 return val;
7673}
7674
7675static unsigned char *
7676display_arm_attribute (unsigned char *p)
7677{
7678 int tag;
7679 unsigned int len;
7680 int val;
7681 arm_attr_public_tag *attr;
7682 unsigned i;
7683 int type;
7684
7685 tag = read_uleb128 (p, &len);
7686 p += len;
7687 attr = NULL;
7688 for (i = 0; i < ARRAY_SIZE(arm_attr_public_tags); i++)
7689 {
7690 if (arm_attr_public_tags[i].tag == tag)
7691 {
7692 attr = &arm_attr_public_tags[i];
7693 break;
7694 }
7695 }
7696
7697 if (attr)
7698 {
7699 printf (" Tag_%s: ", attr->name);
7700 switch (attr->type)
7701 {
7702 case 0:
7703 switch (tag)
7704 {
7705 case 7: /* Tag_CPU_arch_profile. */
7706 val = read_uleb128 (p, &len);
7707 p += len;
7708 switch (val)
7709 {
7710 case 0: printf ("None\n"); break;
7711 case 'A': printf ("Application\n"); break;
7712 case 'R': printf ("Realtime\n"); break;
7713 case 'M': printf ("Microcontroller\n"); break;
7714 default: printf ("??? (%d)\n", val); break;
7715 }
7716 break;
7717
7718 case 32: /* Tag_compatibility. */
7719 val = read_uleb128 (p, &len);
7720 p += len;
7721 printf ("flag = %d, vendor = %s\n", val, p);
7722 p += strlen((char *)p) + 1;
7723 break;
7724
7725 default:
7726 abort();
7727 }
7728 return p;
7729
7730 case 1:
7731 case 2:
7732 type = attr->type;
7733 break;
7734
7735 default:
7736 assert (attr->type & 0x80);
7737 val = read_uleb128 (p, &len);
7738 p += len;
7739 type = attr->type & 0x7f;
7740 if (val >= type)
7741 printf ("??? (%d)\n", val);
7742 else
7743 printf ("%s\n", attr->table[val]);
7744 return p;
7745 }
7746 }
7747 else
7748 {
7749 if (tag & 1)
7750 type = 1; /* String. */
7751 else
7752 type = 2; /* uleb128. */
7753 printf (" Tag_unknown_%d: ", tag);
7754 }
7755
7756 if (type == 1)
7757 {
7758 printf ("\"%s\"\n", p);
7759 p += strlen((char *)p) + 1;
7760 }
7761 else
7762 {
7763 val = read_uleb128 (p, &len);
7764 p += len;
7765 printf ("%d (0x%x)\n", val, val);
7766 }
7767
7768 return p;
7769}
7770
7771static int
7772process_arm_specific (FILE *file)
7773{
7774 Elf_Internal_Shdr *sect;
7775 unsigned char *contents;
7776 unsigned char *p;
7777 unsigned char *end;
7778 bfd_vma section_len;
7779 bfd_vma len;
7780 unsigned i;
7781
7782 /* Find the section header so that we get the size. */
7783 for (i = 0, sect = section_headers;
7784 i < elf_header.e_shnum;
7785 i++, sect++)
7786 {
7787 if (sect->sh_type != SHT_ARM_ATTRIBUTES)
7788 continue;
7789
7790 contents = get_data (NULL, file, sect->sh_offset, 1, sect->sh_size,
7791 _("attributes"));
7792
7793 if (!contents)
7794 continue;
7795 p = contents;
7796 if (*p == 'A')
7797 {
7798 len = sect->sh_size - 1;
7799 p++;
7800 while (len > 0)
7801 {
7802 int namelen;
7803 bfd_boolean public_section;
7804
7805 section_len = byte_get (p, 4);
7806 p += 4;
7807 if (section_len > len)
7808 {
7809 printf (_("ERROR: Bad section length (%d > %d)\n"),
7810 (int)section_len, (int)len);
7811 section_len = len;
7812 }
7813 len -= section_len;
7814 printf ("Attribute Section: %s\n", p);
7815 if (strcmp ((char *)p, "aeabi") == 0)
7816 public_section = TRUE;
7817 else
7818 public_section = FALSE;
7819 namelen = strlen ((char *)p) + 1;
7820 p += namelen;
7821 section_len -= namelen + 4;
7822 while (section_len > 0)
7823 {
7824 int tag = *(p++);
7825 int val;
7826 bfd_vma size;
7827 size = byte_get (p, 4);
7828 if (size > section_len)
7829 {
7830 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
7831 (int)size, (int)section_len);
7832 size = section_len;
7833 }
7834 section_len -= size;
7835 end = p + size - 1;
7836 p += 4;
7837 switch (tag)
7838 {
7839 case 1:
7840 printf ("File Attributes\n");
7841 break;
7842 case 2:
7843 printf ("Section Attributes:");
7844 goto do_numlist;
7845 case 3:
7846 printf ("Symbol Attributes:");
7847 do_numlist:
7848 for (;;)
7849 {
7850 unsigned int i;
7851 val = read_uleb128 (p, &i);
7852 p += i;
7853 if (val == 0)
7854 break;
7855 printf (" %d", val);
7856 }
7857 printf ("\n");
7858 break;
7859 default:
7860 printf ("Unknown tag: %d\n", tag);
7861 public_section = FALSE;
7862 break;
7863 }
7864 if (public_section)
7865 {
7866 while (p < end)
7867 p = display_arm_attribute(p);
7868 }
7869 else
7870 {
7871 /* ??? Do something sensible, like dump hex. */
7872 printf (" Unknown section contexts\n");
7873 p = end;
7874 }
7875 }
7876 }
7877 }
7878 else
7879 {
7880 printf (_("Unknown format '%c'\n"), *p);
7881 }
7882
7883 free(contents);
7884 }
7885 return 1;
7886}
7887
19e6b90e
L
7888static int
7889process_mips_specific (FILE *file)
5b18a4bc 7890{
19e6b90e
L
7891 Elf_Internal_Dyn *entry;
7892 size_t liblist_offset = 0;
7893 size_t liblistno = 0;
7894 size_t conflictsno = 0;
7895 size_t options_offset = 0;
7896 size_t conflicts_offset = 0;
103f02d3 7897
19e6b90e
L
7898 /* We have a lot of special sections. Thanks SGI! */
7899 if (dynamic_section == NULL)
7900 /* No information available. */
7901 return 0;
252b5132 7902
b2d38a17 7903 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
7904 switch (entry->d_tag)
7905 {
7906 case DT_MIPS_LIBLIST:
d93f0186
NC
7907 liblist_offset
7908 = offset_from_vma (file, entry->d_un.d_val,
7909 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
7910 break;
7911 case DT_MIPS_LIBLISTNO:
7912 liblistno = entry->d_un.d_val;
7913 break;
7914 case DT_MIPS_OPTIONS:
d93f0186 7915 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
7916 break;
7917 case DT_MIPS_CONFLICT:
d93f0186
NC
7918 conflicts_offset
7919 = offset_from_vma (file, entry->d_un.d_val,
7920 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
7921 break;
7922 case DT_MIPS_CONFLICTNO:
7923 conflictsno = entry->d_un.d_val;
7924 break;
7925 default:
7926 break;
7927 }
7928
7929 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
7930 {
b34976b6 7931 Elf32_External_Lib *elib;
252b5132
RH
7932 size_t cnt;
7933
d3ba0551 7934 elib = get_data (NULL, file, liblist_offset,
c256ffe7 7935 liblistno, sizeof (Elf32_External_Lib),
d3ba0551 7936 _("liblist"));
a6e9f9df 7937 if (elib)
252b5132 7938 {
a6e9f9df
AM
7939 printf ("\nSection '.liblist' contains %lu entries:\n",
7940 (unsigned long) liblistno);
7941 fputs (" Library Time Stamp Checksum Version Flags\n",
7942 stdout);
7943
7944 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 7945 {
a6e9f9df
AM
7946 Elf32_Lib liblist;
7947 time_t time;
7948 char timebuf[20];
b34976b6 7949 struct tm *tmp;
a6e9f9df
AM
7950
7951 liblist.l_name = BYTE_GET (elib[cnt].l_name);
7952 time = BYTE_GET (elib[cnt].l_time_stamp);
7953 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
7954 liblist.l_version = BYTE_GET (elib[cnt].l_version);
7955 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
7956
7957 tmp = gmtime (&time);
e9e44622
JJ
7958 snprintf (timebuf, sizeof (timebuf),
7959 "%04u-%02u-%02uT%02u:%02u:%02u",
7960 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7961 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 7962
31104126 7963 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
7964 if (VALID_DYNAMIC_NAME (liblist.l_name))
7965 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
7966 else
7967 printf ("<corrupt: %9ld>", liblist.l_name);
31104126
NC
7968 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
7969 liblist.l_version);
a6e9f9df
AM
7970
7971 if (liblist.l_flags == 0)
7972 puts (" NONE");
7973 else
7974 {
7975 static const struct
252b5132 7976 {
b34976b6 7977 const char *name;
a6e9f9df 7978 int bit;
252b5132 7979 }
a6e9f9df
AM
7980 l_flags_vals[] =
7981 {
7982 { " EXACT_MATCH", LL_EXACT_MATCH },
7983 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
7984 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
7985 { " EXPORTS", LL_EXPORTS },
7986 { " DELAY_LOAD", LL_DELAY_LOAD },
7987 { " DELTA", LL_DELTA }
7988 };
7989 int flags = liblist.l_flags;
7990 size_t fcnt;
7991
7992 for (fcnt = 0;
7993 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
7994 ++fcnt)
7995 if ((flags & l_flags_vals[fcnt].bit) != 0)
7996 {
7997 fputs (l_flags_vals[fcnt].name, stdout);
7998 flags ^= l_flags_vals[fcnt].bit;
7999 }
8000 if (flags != 0)
8001 printf (" %#x", (unsigned int) flags);
252b5132 8002
a6e9f9df
AM
8003 puts ("");
8004 }
252b5132 8005 }
252b5132 8006
a6e9f9df
AM
8007 free (elib);
8008 }
252b5132
RH
8009 }
8010
8011 if (options_offset != 0)
8012 {
b34976b6
AM
8013 Elf_External_Options *eopt;
8014 Elf_Internal_Shdr *sect = section_headers;
8015 Elf_Internal_Options *iopt;
8016 Elf_Internal_Options *option;
252b5132
RH
8017 size_t offset;
8018 int cnt;
8019
8020 /* Find the section header so that we get the size. */
8021 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 8022 ++sect;
252b5132 8023
c256ffe7 8024 eopt = get_data (NULL, file, options_offset, 1, sect->sh_size,
d3ba0551 8025 _("options"));
a6e9f9df 8026 if (eopt)
252b5132 8027 {
c256ffe7 8028 iopt = cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (*iopt));
a6e9f9df
AM
8029 if (iopt == NULL)
8030 {
8031 error (_("Out of memory"));
8032 return 0;
8033 }
76da6bbe 8034
a6e9f9df
AM
8035 offset = cnt = 0;
8036 option = iopt;
252b5132 8037
a6e9f9df
AM
8038 while (offset < sect->sh_size)
8039 {
b34976b6 8040 Elf_External_Options *eoption;
252b5132 8041
a6e9f9df 8042 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 8043
a6e9f9df
AM
8044 option->kind = BYTE_GET (eoption->kind);
8045 option->size = BYTE_GET (eoption->size);
8046 option->section = BYTE_GET (eoption->section);
8047 option->info = BYTE_GET (eoption->info);
76da6bbe 8048
a6e9f9df 8049 offset += option->size;
252b5132 8050
a6e9f9df
AM
8051 ++option;
8052 ++cnt;
8053 }
252b5132 8054
a6e9f9df
AM
8055 printf (_("\nSection '%s' contains %d entries:\n"),
8056 SECTION_NAME (sect), cnt);
76da6bbe 8057
a6e9f9df 8058 option = iopt;
252b5132 8059
a6e9f9df 8060 while (cnt-- > 0)
252b5132 8061 {
a6e9f9df
AM
8062 size_t len;
8063
8064 switch (option->kind)
252b5132 8065 {
a6e9f9df
AM
8066 case ODK_NULL:
8067 /* This shouldn't happen. */
8068 printf (" NULL %d %lx", option->section, option->info);
8069 break;
8070 case ODK_REGINFO:
8071 printf (" REGINFO ");
8072 if (elf_header.e_machine == EM_MIPS)
8073 {
8074 /* 32bit form. */
b34976b6
AM
8075 Elf32_External_RegInfo *ereg;
8076 Elf32_RegInfo reginfo;
a6e9f9df
AM
8077
8078 ereg = (Elf32_External_RegInfo *) (option + 1);
8079 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8080 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8081 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8082 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8083 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8084 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
8085
8086 printf ("GPR %08lx GP 0x%lx\n",
8087 reginfo.ri_gprmask,
8088 (unsigned long) reginfo.ri_gp_value);
8089 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
8090 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8091 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8092 }
8093 else
8094 {
8095 /* 64 bit form. */
b34976b6 8096 Elf64_External_RegInfo *ereg;
a6e9f9df
AM
8097 Elf64_Internal_RegInfo reginfo;
8098
8099 ereg = (Elf64_External_RegInfo *) (option + 1);
8100 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8101 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8102 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8103 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8104 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 8105 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
8106
8107 printf ("GPR %08lx GP 0x",
8108 reginfo.ri_gprmask);
8109 printf_vma (reginfo.ri_gp_value);
8110 printf ("\n");
8111
8112 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
8113 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8114 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8115 }
8116 ++option;
8117 continue;
8118 case ODK_EXCEPTIONS:
8119 fputs (" EXCEPTIONS fpe_min(", stdout);
8120 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
8121 fputs (") fpe_max(", stdout);
8122 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
8123 fputs (")", stdout);
8124
8125 if (option->info & OEX_PAGE0)
8126 fputs (" PAGE0", stdout);
8127 if (option->info & OEX_SMM)
8128 fputs (" SMM", stdout);
8129 if (option->info & OEX_FPDBUG)
8130 fputs (" FPDBUG", stdout);
8131 if (option->info & OEX_DISMISS)
8132 fputs (" DISMISS", stdout);
8133 break;
8134 case ODK_PAD:
8135 fputs (" PAD ", stdout);
8136 if (option->info & OPAD_PREFIX)
8137 fputs (" PREFIX", stdout);
8138 if (option->info & OPAD_POSTFIX)
8139 fputs (" POSTFIX", stdout);
8140 if (option->info & OPAD_SYMBOL)
8141 fputs (" SYMBOL", stdout);
8142 break;
8143 case ODK_HWPATCH:
8144 fputs (" HWPATCH ", stdout);
8145 if (option->info & OHW_R4KEOP)
8146 fputs (" R4KEOP", stdout);
8147 if (option->info & OHW_R8KPFETCH)
8148 fputs (" R8KPFETCH", stdout);
8149 if (option->info & OHW_R5KEOP)
8150 fputs (" R5KEOP", stdout);
8151 if (option->info & OHW_R5KCVTL)
8152 fputs (" R5KCVTL", stdout);
8153 break;
8154 case ODK_FILL:
8155 fputs (" FILL ", stdout);
8156 /* XXX Print content of info word? */
8157 break;
8158 case ODK_TAGS:
8159 fputs (" TAGS ", stdout);
8160 /* XXX Print content of info word? */
8161 break;
8162 case ODK_HWAND:
8163 fputs (" HWAND ", stdout);
8164 if (option->info & OHWA0_R4KEOP_CHECKED)
8165 fputs (" R4KEOP_CHECKED", stdout);
8166 if (option->info & OHWA0_R4KEOP_CLEAN)
8167 fputs (" R4KEOP_CLEAN", stdout);
8168 break;
8169 case ODK_HWOR:
8170 fputs (" HWOR ", stdout);
8171 if (option->info & OHWA0_R4KEOP_CHECKED)
8172 fputs (" R4KEOP_CHECKED", stdout);
8173 if (option->info & OHWA0_R4KEOP_CLEAN)
8174 fputs (" R4KEOP_CLEAN", stdout);
8175 break;
8176 case ODK_GP_GROUP:
8177 printf (" GP_GROUP %#06lx self-contained %#06lx",
8178 option->info & OGP_GROUP,
8179 (option->info & OGP_SELF) >> 16);
8180 break;
8181 case ODK_IDENT:
8182 printf (" IDENT %#06lx self-contained %#06lx",
8183 option->info & OGP_GROUP,
8184 (option->info & OGP_SELF) >> 16);
8185 break;
8186 default:
8187 /* This shouldn't happen. */
8188 printf (" %3d ??? %d %lx",
8189 option->kind, option->section, option->info);
8190 break;
252b5132 8191 }
a6e9f9df 8192
b34976b6 8193 len = sizeof (*eopt);
a6e9f9df
AM
8194 while (len < option->size)
8195 if (((char *) option)[len] >= ' '
8196 && ((char *) option)[len] < 0x7f)
8197 printf ("%c", ((char *) option)[len++]);
8198 else
8199 printf ("\\%03o", ((char *) option)[len++]);
8200
8201 fputs ("\n", stdout);
252b5132 8202 ++option;
252b5132
RH
8203 }
8204
a6e9f9df 8205 free (eopt);
252b5132 8206 }
252b5132
RH
8207 }
8208
8209 if (conflicts_offset != 0 && conflictsno != 0)
8210 {
b34976b6 8211 Elf32_Conflict *iconf;
252b5132
RH
8212 size_t cnt;
8213
8214 if (dynamic_symbols == NULL)
8215 {
3a1a2036 8216 error (_("conflict list found without a dynamic symbol table"));
252b5132
RH
8217 return 0;
8218 }
8219
c256ffe7 8220 iconf = cmalloc (conflictsno, sizeof (*iconf));
252b5132
RH
8221 if (iconf == NULL)
8222 {
8223 error (_("Out of memory"));
8224 return 0;
8225 }
8226
9ea033b2 8227 if (is_32bit_elf)
252b5132 8228 {
b34976b6 8229 Elf32_External_Conflict *econf32;
a6e9f9df 8230
d3ba0551 8231 econf32 = get_data (NULL, file, conflicts_offset,
c256ffe7 8232 conflictsno, sizeof (*econf32), _("conflict"));
a6e9f9df
AM
8233 if (!econf32)
8234 return 0;
252b5132
RH
8235
8236 for (cnt = 0; cnt < conflictsno; ++cnt)
8237 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
8238
8239 free (econf32);
252b5132
RH
8240 }
8241 else
8242 {
b34976b6 8243 Elf64_External_Conflict *econf64;
a6e9f9df 8244
d3ba0551 8245 econf64 = get_data (NULL, file, conflicts_offset,
c256ffe7 8246 conflictsno, sizeof (*econf64), _("conflict"));
a6e9f9df
AM
8247 if (!econf64)
8248 return 0;
252b5132
RH
8249
8250 for (cnt = 0; cnt < conflictsno; ++cnt)
8251 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
8252
8253 free (econf64);
252b5132
RH
8254 }
8255
c7e7ca54
NC
8256 printf (_("\nSection '.conflict' contains %lu entries:\n"),
8257 (unsigned long) conflictsno);
252b5132
RH
8258 puts (_(" Num: Index Value Name"));
8259
8260 for (cnt = 0; cnt < conflictsno; ++cnt)
8261 {
b34976b6 8262 Elf_Internal_Sym *psym = & dynamic_symbols[iconf[cnt]];
252b5132 8263
b34976b6 8264 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 8265 print_vma (psym->st_value, FULL_HEX);
31104126 8266 putchar (' ');
d79b3d50
NC
8267 if (VALID_DYNAMIC_NAME (psym->st_name))
8268 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
8269 else
8270 printf ("<corrupt: %14ld>", psym->st_name);
31104126 8271 putchar ('\n');
252b5132
RH
8272 }
8273
252b5132
RH
8274 free (iconf);
8275 }
8276
8277 return 1;
8278}
8279
047b2264 8280static int
d3ba0551 8281process_gnu_liblist (FILE *file)
047b2264 8282{
b34976b6
AM
8283 Elf_Internal_Shdr *section, *string_sec;
8284 Elf32_External_Lib *elib;
8285 char *strtab;
c256ffe7 8286 size_t strtab_size;
047b2264
JJ
8287 size_t cnt;
8288 unsigned i;
8289
8290 if (! do_arch)
8291 return 0;
8292
8293 for (i = 0, section = section_headers;
8294 i < elf_header.e_shnum;
b34976b6 8295 i++, section++)
047b2264
JJ
8296 {
8297 switch (section->sh_type)
8298 {
8299 case SHT_GNU_LIBLIST:
c256ffe7
JJ
8300 if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum)
8301 break;
8302
8303 elib = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
d3ba0551 8304 _("liblist"));
047b2264
JJ
8305
8306 if (elib == NULL)
8307 break;
8308 string_sec = SECTION_HEADER (section->sh_link);
8309
c256ffe7 8310 strtab = get_data (NULL, file, string_sec->sh_offset, 1,
d3ba0551 8311 string_sec->sh_size, _("liblist string table"));
c256ffe7 8312 strtab_size = string_sec->sh_size;
047b2264
JJ
8313
8314 if (strtab == NULL
8315 || section->sh_entsize != sizeof (Elf32_External_Lib))
8316 {
8317 free (elib);
8318 break;
8319 }
8320
8321 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
8322 SECTION_NAME (section),
8323 (long) (section->sh_size / sizeof (Elf32_External_Lib)));
8324
8325 puts (" Library Time Stamp Checksum Version Flags");
8326
8327 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
8328 ++cnt)
8329 {
8330 Elf32_Lib liblist;
8331 time_t time;
8332 char timebuf[20];
b34976b6 8333 struct tm *tmp;
047b2264
JJ
8334
8335 liblist.l_name = BYTE_GET (elib[cnt].l_name);
8336 time = BYTE_GET (elib[cnt].l_time_stamp);
8337 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
8338 liblist.l_version = BYTE_GET (elib[cnt].l_version);
8339 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
8340
8341 tmp = gmtime (&time);
e9e44622
JJ
8342 snprintf (timebuf, sizeof (timebuf),
8343 "%04u-%02u-%02uT%02u:%02u:%02u",
8344 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8345 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
8346
8347 printf ("%3lu: ", (unsigned long) cnt);
8348 if (do_wide)
c256ffe7
JJ
8349 printf ("%-20s", liblist.l_name < strtab_size
8350 ? strtab + liblist.l_name : "<corrupt>");
047b2264 8351 else
c256ffe7
JJ
8352 printf ("%-20.20s", liblist.l_name < strtab_size
8353 ? strtab + liblist.l_name : "<corrupt>");
047b2264
JJ
8354 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
8355 liblist.l_version, liblist.l_flags);
8356 }
8357
8358 free (elib);
8359 }
8360 }
8361
8362 return 1;
8363}
8364
9437c45b 8365static const char *
d3ba0551 8366get_note_type (unsigned e_type)
779fe533
NC
8367{
8368 static char buff[64];
103f02d3 8369
1ec5cd37
NC
8370 if (elf_header.e_type == ET_CORE)
8371 switch (e_type)
8372 {
57346661 8373 case NT_AUXV:
1ec5cd37 8374 return _("NT_AUXV (auxiliary vector)");
57346661 8375 case NT_PRSTATUS:
1ec5cd37 8376 return _("NT_PRSTATUS (prstatus structure)");
57346661 8377 case NT_FPREGSET:
1ec5cd37 8378 return _("NT_FPREGSET (floating point registers)");
57346661 8379 case NT_PRPSINFO:
1ec5cd37 8380 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 8381 case NT_TASKSTRUCT:
1ec5cd37 8382 return _("NT_TASKSTRUCT (task structure)");
57346661 8383 case NT_PRXFPREG:
1ec5cd37 8384 return _("NT_PRXFPREG (user_xfpregs structure)");
57346661 8385 case NT_PSTATUS:
1ec5cd37 8386 return _("NT_PSTATUS (pstatus structure)");
57346661 8387 case NT_FPREGS:
1ec5cd37 8388 return _("NT_FPREGS (floating point registers)");
57346661 8389 case NT_PSINFO:
1ec5cd37 8390 return _("NT_PSINFO (psinfo structure)");
57346661 8391 case NT_LWPSTATUS:
1ec5cd37 8392 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 8393 case NT_LWPSINFO:
1ec5cd37 8394 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 8395 case NT_WIN32PSTATUS:
1ec5cd37
NC
8396 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
8397 default:
8398 break;
8399 }
8400 else
8401 switch (e_type)
8402 {
8403 case NT_VERSION:
8404 return _("NT_VERSION (version)");
8405 case NT_ARCH:
8406 return _("NT_ARCH (architecture)");
8407 default:
8408 break;
8409 }
8410
e9e44622 8411 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 8412 return buff;
779fe533
NC
8413}
8414
9437c45b 8415static const char *
d3ba0551 8416get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
8417{
8418 static char buff[64];
8419
b4db1224 8420 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
8421 {
8422 /* NetBSD core "procinfo" structure. */
8423 return _("NetBSD procinfo structure");
8424 }
8425
8426 /* As of Jan 2002 there are no other machine-independent notes
8427 defined for NetBSD core files. If the note type is less
8428 than the start of the machine-dependent note types, we don't
8429 understand it. */
8430
b4db1224 8431 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 8432 {
e9e44622 8433 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
8434 return buff;
8435 }
8436
8437 switch (elf_header.e_machine)
8438 {
8439 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
8440 and PT_GETFPREGS == mach+2. */
8441
8442 case EM_OLD_ALPHA:
8443 case EM_ALPHA:
8444 case EM_SPARC:
8445 case EM_SPARC32PLUS:
8446 case EM_SPARCV9:
8447 switch (e_type)
8448 {
b4db1224
JT
8449 case NT_NETBSDCORE_FIRSTMACH+0:
8450 return _("PT_GETREGS (reg structure)");
8451 case NT_NETBSDCORE_FIRSTMACH+2:
8452 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
8453 default:
8454 break;
8455 }
8456 break;
8457
8458 /* On all other arch's, PT_GETREGS == mach+1 and
8459 PT_GETFPREGS == mach+3. */
8460 default:
8461 switch (e_type)
8462 {
b4db1224
JT
8463 case NT_NETBSDCORE_FIRSTMACH+1:
8464 return _("PT_GETREGS (reg structure)");
8465 case NT_NETBSDCORE_FIRSTMACH+3:
8466 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
8467 default:
8468 break;
8469 }
8470 }
8471
e9e44622
JJ
8472 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
8473 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
8474 return buff;
8475}
8476
6d118b09
NC
8477/* Note that by the ELF standard, the name field is already null byte
8478 terminated, and namesz includes the terminating null byte.
8479 I.E. the value of namesz for the name "FSF" is 4.
8480
e3c8793a 8481 If the value of namesz is zero, there is no name present. */
779fe533 8482static int
d3ba0551 8483process_note (Elf_Internal_Note *pnote)
779fe533 8484{
9437c45b
JT
8485 const char *nt;
8486
8487 if (pnote->namesz == 0)
1ec5cd37
NC
8488 /* If there is no note name, then use the default set of
8489 note type strings. */
8490 nt = get_note_type (pnote->type);
8491
18bd398b 8492 else if (strneq (pnote->namedata, "NetBSD-CORE", 11))
1ec5cd37
NC
8493 /* NetBSD-specific core file notes. */
8494 nt = get_netbsd_elfcore_note_type (pnote->type);
8495
9437c45b 8496 else
1ec5cd37
NC
8497 /* Don't recognize this note name; just use the default set of
8498 note type strings. */
9437c45b 8499 nt = get_note_type (pnote->type);
9437c45b 8500
103f02d3 8501 printf (" %s\t\t0x%08lx\t%s\n",
6d118b09 8502 pnote->namesz ? pnote->namedata : "(NONE)",
9437c45b 8503 pnote->descsz, nt);
779fe533
NC
8504 return 1;
8505}
8506
6d118b09 8507
779fe533 8508static int
d3ba0551 8509process_corefile_note_segment (FILE *file, bfd_vma offset, bfd_vma length)
779fe533 8510{
b34976b6
AM
8511 Elf_External_Note *pnotes;
8512 Elf_External_Note *external;
8513 int res = 1;
103f02d3 8514
779fe533
NC
8515 if (length <= 0)
8516 return 0;
103f02d3 8517
c256ffe7 8518 pnotes = get_data (NULL, file, offset, 1, length, _("notes"));
a6e9f9df
AM
8519 if (!pnotes)
8520 return 0;
779fe533 8521
103f02d3 8522 external = pnotes;
103f02d3 8523
305c7206 8524 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 8525 (unsigned long) offset, (unsigned long) length);
779fe533 8526 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 8527
6d118b09 8528 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 8529 {
b34976b6
AM
8530 Elf_External_Note *next;
8531 Elf_Internal_Note inote;
8532 char *temp = NULL;
6d118b09
NC
8533
8534 inote.type = BYTE_GET (external->type);
8535 inote.namesz = BYTE_GET (external->namesz);
8536 inote.namedata = external->name;
8537 inote.descsz = BYTE_GET (external->descsz);
8538 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
8539 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 8540
3e55a963
NC
8541 next = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
8542
8543 if (((char *) next) > (((char *) pnotes) + length))
8544 {
0fd3a477
JW
8545 warn (_("corrupt note found at offset %lx into core notes\n"),
8546 (long)((char *)external - (char *)pnotes));
8547 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
8548 inote.type, inote.namesz, inote.descsz);
8549 break;
8550 }
8551
8552 external = next;
6d118b09
NC
8553
8554 /* Verify that name is null terminated. It appears that at least
8555 one version of Linux (RedHat 6.0) generates corefiles that don't
8556 comply with the ELF spec by failing to include the null byte in
8557 namesz. */
8558 if (inote.namedata[inote.namesz] != '\0')
8559 {
8560 temp = malloc (inote.namesz + 1);
76da6bbe 8561
6d118b09
NC
8562 if (temp == NULL)
8563 {
8564 error (_("Out of memory\n"));
8565 res = 0;
8566 break;
8567 }
76da6bbe 8568
6d118b09
NC
8569 strncpy (temp, inote.namedata, inote.namesz);
8570 temp[inote.namesz] = 0;
76da6bbe 8571
6d118b09
NC
8572 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
8573 inote.namedata = temp;
8574 }
8575
8576 res &= process_note (& inote);
103f02d3 8577
6d118b09
NC
8578 if (temp != NULL)
8579 {
8580 free (temp);
8581 temp = NULL;
8582 }
779fe533
NC
8583 }
8584
8585 free (pnotes);
103f02d3 8586
779fe533
NC
8587 return res;
8588}
8589
8590static int
d3ba0551 8591process_corefile_note_segments (FILE *file)
779fe533 8592{
b34976b6
AM
8593 Elf_Internal_Phdr *segment;
8594 unsigned int i;
8595 int res = 1;
103f02d3 8596
d93f0186 8597 if (! get_program_headers (file))
779fe533 8598 return 0;
103f02d3 8599
779fe533
NC
8600 for (i = 0, segment = program_headers;
8601 i < elf_header.e_phnum;
b34976b6 8602 i++, segment++)
779fe533
NC
8603 {
8604 if (segment->p_type == PT_NOTE)
103f02d3 8605 res &= process_corefile_note_segment (file,
30800947
NC
8606 (bfd_vma) segment->p_offset,
8607 (bfd_vma) segment->p_filesz);
779fe533 8608 }
103f02d3 8609
779fe533
NC
8610 return res;
8611}
8612
8613static int
1ec5cd37
NC
8614process_note_sections (FILE *file)
8615{
8616 Elf_Internal_Shdr *section;
8617 unsigned long i;
8618 int res = 1;
8619
8620 for (i = 0, section = section_headers;
8621 i < elf_header.e_shnum;
8622 i++, section++)
8623 if (section->sh_type == SHT_NOTE)
8624 res &= process_corefile_note_segment (file,
8625 (bfd_vma) section->sh_offset,
8626 (bfd_vma) section->sh_size);
8627
8628 return res;
8629}
8630
8631static int
8632process_notes (FILE *file)
779fe533
NC
8633{
8634 /* If we have not been asked to display the notes then do nothing. */
8635 if (! do_notes)
8636 return 1;
103f02d3 8637
779fe533 8638 if (elf_header.e_type != ET_CORE)
1ec5cd37 8639 return process_note_sections (file);
103f02d3 8640
779fe533 8641 /* No program headers means no NOTE segment. */
1ec5cd37
NC
8642 if (elf_header.e_phnum > 0)
8643 return process_corefile_note_segments (file);
779fe533 8644
1ec5cd37
NC
8645 printf (_("No note segments present in the core file.\n"));
8646 return 1;
779fe533
NC
8647}
8648
252b5132 8649static int
d3ba0551 8650process_arch_specific (FILE *file)
252b5132 8651{
a952a375
NC
8652 if (! do_arch)
8653 return 1;
8654
252b5132
RH
8655 switch (elf_header.e_machine)
8656 {
11c1ff18
PB
8657 case EM_ARM:
8658 return process_arm_specific (file);
252b5132 8659 case EM_MIPS:
4fe85591 8660 case EM_MIPS_RS3_LE:
252b5132
RH
8661 return process_mips_specific (file);
8662 break;
8663 default:
8664 break;
8665 }
8666 return 1;
8667}
8668
8669static int
d3ba0551 8670get_file_header (FILE *file)
252b5132 8671{
9ea033b2
NC
8672 /* Read in the identity array. */
8673 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
8674 return 0;
8675
9ea033b2 8676 /* Determine how to read the rest of the header. */
b34976b6 8677 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
8678 {
8679 default: /* fall through */
8680 case ELFDATANONE: /* fall through */
adab8cdc
AO
8681 case ELFDATA2LSB:
8682 byte_get = byte_get_little_endian;
8683 byte_put = byte_put_little_endian;
8684 break;
8685 case ELFDATA2MSB:
8686 byte_get = byte_get_big_endian;
8687 byte_put = byte_put_big_endian;
8688 break;
9ea033b2
NC
8689 }
8690
8691 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 8692 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
8693
8694 /* Read in the rest of the header. */
8695 if (is_32bit_elf)
8696 {
8697 Elf32_External_Ehdr ehdr32;
252b5132 8698
9ea033b2
NC
8699 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
8700 return 0;
103f02d3 8701
9ea033b2
NC
8702 elf_header.e_type = BYTE_GET (ehdr32.e_type);
8703 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
8704 elf_header.e_version = BYTE_GET (ehdr32.e_version);
8705 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
8706 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
8707 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
8708 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
8709 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
8710 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
8711 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
8712 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
8713 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
8714 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
8715 }
252b5132 8716 else
9ea033b2
NC
8717 {
8718 Elf64_External_Ehdr ehdr64;
a952a375
NC
8719
8720 /* If we have been compiled with sizeof (bfd_vma) == 4, then
8721 we will not be able to cope with the 64bit data found in
8722 64 ELF files. Detect this now and abort before we start
50c2245b 8723 overwriting things. */
a952a375
NC
8724 if (sizeof (bfd_vma) < 8)
8725 {
e3c8793a
NC
8726 error (_("This instance of readelf has been built without support for a\n\
872764 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
8728 return 0;
8729 }
103f02d3 8730
9ea033b2
NC
8731 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
8732 return 0;
103f02d3 8733
9ea033b2
NC
8734 elf_header.e_type = BYTE_GET (ehdr64.e_type);
8735 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
8736 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
8737 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
8738 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
8739 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
8740 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
8741 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
8742 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
8743 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
8744 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
8745 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
8746 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
8747 }
252b5132 8748
7ece0d85
JJ
8749 if (elf_header.e_shoff)
8750 {
8751 /* There may be some extensions in the first section header. Don't
8752 bomb if we can't read it. */
8753 if (is_32bit_elf)
8754 get_32bit_section_headers (file, 1);
8755 else
8756 get_64bit_section_headers (file, 1);
8757 }
560f3c1c 8758
1007acb3
L
8759 is_relocatable = elf_header.e_type == ET_REL;
8760
252b5132
RH
8761 return 1;
8762}
8763
fb52b2f4
NC
8764/* Process one ELF object file according to the command line options.
8765 This file may actually be stored in an archive. The file is
8766 positioned at the start of the ELF object. */
8767
ff78d6d6 8768static int
fb52b2f4 8769process_object (char *file_name, FILE *file)
252b5132 8770{
252b5132
RH
8771 unsigned int i;
8772
252b5132
RH
8773 if (! get_file_header (file))
8774 {
8775 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 8776 return 1;
252b5132
RH
8777 }
8778
8779 /* Initialise per file variables. */
8780 for (i = NUM_ELEM (version_info); i--;)
8781 version_info[i] = 0;
8782
8783 for (i = NUM_ELEM (dynamic_info); i--;)
8784 dynamic_info[i] = 0;
8785
8786 /* Process the file. */
8787 if (show_name)
8788 printf (_("\nFile: %s\n"), file_name);
8789
18bd398b
NC
8790 /* Initialise the dump_sects array from the cmdline_dump_sects array.
8791 Note we do this even if cmdline_dump_sects is empty because we
8792 must make sure that the dump_sets array is zeroed out before each
8793 object file is processed. */
8794 if (num_dump_sects > num_cmdline_dump_sects)
8795 memset (dump_sects, 0, num_dump_sects);
8796
8797 if (num_cmdline_dump_sects > 0)
8798 {
8799 if (num_dump_sects == 0)
8800 /* A sneaky way of allocating the dump_sects array. */
8801 request_dump (num_cmdline_dump_sects, 0);
8802
8803 assert (num_dump_sects >= num_cmdline_dump_sects);
8804 memcpy (dump_sects, cmdline_dump_sects, num_cmdline_dump_sects);
8805 }
8806
252b5132 8807 if (! process_file_header ())
fb52b2f4 8808 return 1;
252b5132 8809
d1f5c6e3 8810 if (! process_section_headers (file))
2f62977e 8811 {
d1f5c6e3
L
8812 /* Without loaded section headers we cannot process lots of
8813 things. */
2f62977e 8814 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 8815
2f62977e
NC
8816 if (! do_using_dynamic)
8817 do_syms = do_reloc = 0;
8818 }
252b5132 8819
d1f5c6e3
L
8820 if (! process_section_groups (file))
8821 {
8822 /* Without loaded section groups we cannot process unwind. */
8823 do_unwind = 0;
8824 }
8825
2f62977e 8826 if (process_program_headers (file))
b2d38a17 8827 process_dynamic_section (file);
252b5132
RH
8828
8829 process_relocs (file);
8830
4d6ed7c8
NC
8831 process_unwind (file);
8832
252b5132
RH
8833 process_symbol_table (file);
8834
8835 process_syminfo (file);
8836
8837 process_version_sections (file);
8838
8839 process_section_contents (file);
f5842774 8840
1ec5cd37 8841 process_notes (file);
103f02d3 8842
047b2264
JJ
8843 process_gnu_liblist (file);
8844
252b5132
RH
8845 process_arch_specific (file);
8846
d93f0186
NC
8847 if (program_headers)
8848 {
8849 free (program_headers);
8850 program_headers = NULL;
8851 }
8852
252b5132
RH
8853 if (section_headers)
8854 {
8855 free (section_headers);
8856 section_headers = NULL;
8857 }
8858
8859 if (string_table)
8860 {
8861 free (string_table);
8862 string_table = NULL;
d40ac9bd 8863 string_table_length = 0;
252b5132
RH
8864 }
8865
8866 if (dynamic_strings)
8867 {
8868 free (dynamic_strings);
8869 dynamic_strings = NULL;
d79b3d50 8870 dynamic_strings_length = 0;
252b5132
RH
8871 }
8872
8873 if (dynamic_symbols)
8874 {
8875 free (dynamic_symbols);
8876 dynamic_symbols = NULL;
19936277 8877 num_dynamic_syms = 0;
252b5132
RH
8878 }
8879
8880 if (dynamic_syminfo)
8881 {
8882 free (dynamic_syminfo);
8883 dynamic_syminfo = NULL;
8884 }
ff78d6d6 8885
e4b17d5c
L
8886 if (section_headers_groups)
8887 {
8888 free (section_headers_groups);
8889 section_headers_groups = NULL;
8890 }
8891
8892 if (section_groups)
8893 {
8894 struct group_list *g, *next;
8895
8896 for (i = 0; i < group_count; i++)
8897 {
8898 for (g = section_groups [i].root; g != NULL; g = next)
8899 {
8900 next = g->next;
8901 free (g);
8902 }
8903 }
8904
8905 free (section_groups);
8906 section_groups = NULL;
8907 }
8908
19e6b90e 8909 free_debug_memory ();
18bd398b 8910
ff78d6d6 8911 return 0;
252b5132
RH
8912}
8913
fb52b2f4
NC
8914/* Process an ELF archive. The file is positioned just after the
8915 ARMAG string. */
8916
8917static int
8918process_archive (char *file_name, FILE *file)
8919{
8920 struct ar_hdr arhdr;
8921 size_t got;
8922 unsigned long size;
8923 char *longnames = NULL;
8924 unsigned long longnames_size = 0;
8925 size_t file_name_size;
d989285c 8926 int ret;
fb52b2f4
NC
8927
8928 show_name = 1;
8929
8930 got = fread (&arhdr, 1, sizeof arhdr, file);
8931 if (got != sizeof arhdr)
8932 {
8933 if (got == 0)
8934 return 0;
8935
8936 error (_("%s: failed to read archive header\n"), file_name);
8937 return 1;
8938 }
8939
8940 if (memcmp (arhdr.ar_name, "/ ", 16) == 0)
8941 {
8942 /* This is the archive symbol table. Skip it.
8943 FIXME: We should have an option to dump it. */
8944 size = strtoul (arhdr.ar_size, NULL, 10);
8945 if (fseek (file, size + (size & 1), SEEK_CUR) != 0)
8946 {
8947 error (_("%s: failed to skip archive symbol table\n"), file_name);
8948 return 1;
8949 }
8950
8951 got = fread (&arhdr, 1, sizeof arhdr, file);
8952 if (got != sizeof arhdr)
8953 {
8954 if (got == 0)
8955 return 0;
8956
8957 error (_("%s: failed to read archive header\n"), file_name);
8958 return 1;
8959 }
8960 }
8961
8962 if (memcmp (arhdr.ar_name, "// ", 16) == 0)
8963 {
8964 /* This is the archive string table holding long member
8965 names. */
8966
8967 longnames_size = strtoul (arhdr.ar_size, NULL, 10);
8968
8969 longnames = malloc (longnames_size);
8970 if (longnames == NULL)
8971 {
8972 error (_("Out of memory\n"));
8973 return 1;
8974 }
8975
8976 if (fread (longnames, longnames_size, 1, file) != 1)
8977 {
d989285c 8978 free (longnames);
18bd398b 8979 error (_("%s: failed to read string table\n"), file_name);
fb52b2f4
NC
8980 return 1;
8981 }
8982
8983 if ((longnames_size & 1) != 0)
8984 getc (file);
8985
8986 got = fread (&arhdr, 1, sizeof arhdr, file);
8987 if (got != sizeof arhdr)
8988 {
d989285c
ILT
8989 free (longnames);
8990
fb52b2f4
NC
8991 if (got == 0)
8992 return 0;
8993
8994 error (_("%s: failed to read archive header\n"), file_name);
8995 return 1;
8996 }
8997 }
8998
8999 file_name_size = strlen (file_name);
d989285c 9000 ret = 0;
fb52b2f4
NC
9001
9002 while (1)
9003 {
9004 char *name;
9005 char *nameend;
9006 char *namealc;
9007
9008 if (arhdr.ar_name[0] == '/')
9009 {
9010 unsigned long off;
9011
9012 off = strtoul (arhdr.ar_name + 1, NULL, 10);
9013 if (off >= longnames_size)
9014 {
0fd3a477 9015 error (_("%s: invalid archive string table offset %lu\n"), file_name, off);
d989285c
ILT
9016 ret = 1;
9017 break;
fb52b2f4
NC
9018 }
9019
9020 name = longnames + off;
9021 nameend = memchr (name, '/', longnames_size - off);
9022 }
9023 else
9024 {
9025 name = arhdr.ar_name;
9026 nameend = memchr (name, '/', 16);
9027 }
9028
9029 if (nameend == NULL)
9030 {
0fd3a477 9031 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
9032 ret = 1;
9033 break;
fb52b2f4
NC
9034 }
9035
9036 namealc = malloc (file_name_size + (nameend - name) + 3);
9037 if (namealc == NULL)
9038 {
9039 error (_("Out of memory\n"));
d989285c
ILT
9040 ret = 1;
9041 break;
fb52b2f4
NC
9042 }
9043
9044 memcpy (namealc, file_name, file_name_size);
9045 namealc[file_name_size] = '(';
9046 memcpy (namealc + file_name_size + 1, name, nameend - name);
9047 namealc[file_name_size + 1 + (nameend - name)] = ')';
9048 namealc[file_name_size + 2 + (nameend - name)] = '\0';
9049
9050 archive_file_offset = ftell (file);
9051 archive_file_size = strtoul (arhdr.ar_size, NULL, 10);
18bd398b 9052
d989285c 9053 ret |= process_object (namealc, file);
fb52b2f4
NC
9054
9055 free (namealc);
9056
9057 if (fseek (file,
9058 (archive_file_offset
9059 + archive_file_size
9060 + (archive_file_size & 1)),
9061 SEEK_SET) != 0)
9062 {
9063 error (_("%s: failed to seek to next archive header\n"), file_name);
d989285c
ILT
9064 ret = 1;
9065 break;
fb52b2f4
NC
9066 }
9067
9068 got = fread (&arhdr, 1, sizeof arhdr, file);
9069 if (got != sizeof arhdr)
9070 {
9071 if (got == 0)
d989285c 9072 break;
fb52b2f4
NC
9073
9074 error (_("%s: failed to read archive header\n"), file_name);
d989285c
ILT
9075 ret = 1;
9076 break;
fb52b2f4
NC
9077 }
9078 }
9079
9080 if (longnames != 0)
9081 free (longnames);
9082
d989285c 9083 return ret;
fb52b2f4
NC
9084}
9085
9086static int
9087process_file (char *file_name)
9088{
9089 FILE *file;
9090 struct stat statbuf;
9091 char armag[SARMAG];
9092 int ret;
9093
9094 if (stat (file_name, &statbuf) < 0)
9095 {
f24ddbdd
NC
9096 if (errno == ENOENT)
9097 error (_("'%s': No such file\n"), file_name);
9098 else
9099 error (_("Could not locate '%s'. System error message: %s\n"),
9100 file_name, strerror (errno));
9101 return 1;
9102 }
9103
9104 if (! S_ISREG (statbuf.st_mode))
9105 {
9106 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
9107 return 1;
9108 }
9109
9110 file = fopen (file_name, "rb");
9111 if (file == NULL)
9112 {
f24ddbdd 9113 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
9114 return 1;
9115 }
9116
9117 if (fread (armag, SARMAG, 1, file) != 1)
9118 {
9119 error (_("%s: Failed to read file header\n"), file_name);
9120 fclose (file);
9121 return 1;
9122 }
9123
9124 if (memcmp (armag, ARMAG, SARMAG) == 0)
9125 ret = process_archive (file_name, file);
9126 else
9127 {
9128 rewind (file);
9129 archive_file_size = archive_file_offset = 0;
9130 ret = process_object (file_name, file);
9131 }
9132
9133 fclose (file);
9134
9135 return ret;
9136}
9137
252b5132
RH
9138#ifdef SUPPORT_DISASSEMBLY
9139/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 9140 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 9141 symbols. */
252b5132
RH
9142
9143void
b34976b6 9144print_address (unsigned int addr, FILE *outfile)
252b5132
RH
9145{
9146 fprintf (outfile,"0x%8.8x", addr);
9147}
9148
e3c8793a 9149/* Needed by the i386 disassembler. */
252b5132
RH
9150void
9151db_task_printsym (unsigned int addr)
9152{
9153 print_address (addr, stderr);
9154}
9155#endif
9156
9157int
d3ba0551 9158main (int argc, char **argv)
252b5132 9159{
ff78d6d6
L
9160 int err;
9161
252b5132
RH
9162#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
9163 setlocale (LC_MESSAGES, "");
3882b010
L
9164#endif
9165#if defined (HAVE_SETLOCALE)
9166 setlocale (LC_CTYPE, "");
252b5132
RH
9167#endif
9168 bindtextdomain (PACKAGE, LOCALEDIR);
9169 textdomain (PACKAGE);
9170
869b9d07
MM
9171 expandargv (&argc, &argv);
9172
252b5132
RH
9173 parse_args (argc, argv);
9174
18bd398b 9175 if (num_dump_sects > 0)
59f14fc0 9176 {
18bd398b 9177 /* Make a copy of the dump_sects array. */
59f14fc0
AS
9178 cmdline_dump_sects = malloc (num_dump_sects);
9179 if (cmdline_dump_sects == NULL)
9180 error (_("Out of memory allocating dump request table."));
9181 else
9182 {
9183 memcpy (cmdline_dump_sects, dump_sects, num_dump_sects);
9184 num_cmdline_dump_sects = num_dump_sects;
9185 }
9186 }
9187
18bd398b
NC
9188 if (optind < (argc - 1))
9189 show_name = 1;
9190
ff78d6d6 9191 err = 0;
252b5132 9192 while (optind < argc)
18bd398b 9193 err |= process_file (argv[optind++]);
252b5132
RH
9194
9195 if (dump_sects != NULL)
9196 free (dump_sects);
59f14fc0
AS
9197 if (cmdline_dump_sects != NULL)
9198 free (cmdline_dump_sects);
252b5132 9199
ff78d6d6 9200 return err;
252b5132 9201}