#include <zlib.h>
#endif
-/* for PATH_MAX */
+/* For PATH_MAX. */
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifndef PATH_MAX
-/* for MAXPATHLEN */
+/* For MAXPATHLEN. */
# ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
# endif
}
/* Print a VMA value. */
+
static int
print_vma (bfd_vma vma, print_mode mode)
{
return 0;
}
-/* Display a symbol on stdout. Handles the display of
- non-printing characters.
- If DO_WIDE is not true then format the symbol to be
- at most WIDTH characters, truncating as necessary.
- If WIDTH is negative then format the string to be
- exactly - WIDTH characters, truncating or padding
- as necessary. */
+/* Display a symbol on stdout. Handles the display of non-printing characters.
-static void
+ If DO_WIDE is not true then format the symbol to be at most WIDTH characters,
+ truncating as necessary. If WIDTH is negative then format the string to be
+ exactly - WIDTH characters, truncating or padding as necessary.
+
+ Returns the number of emitted characters. */
+
+static unsigned int
print_symbol (int width, const char *symbol)
{
- const char * format_string;
const char * c;
+ bfd_boolean extra_padding = FALSE;
+ unsigned int num_printed = 0;
if (do_wide)
{
- format_string = "%.*s";
/* Set the width to a very large value. This simplifies the code below. */
width = INT_MAX;
}
else if (width < 0)
{
- format_string = "%-*.*2s";
/* Keep the width positive. This also helps. */
width = - width;
- }
- else
- {
- format_string = "%-.*s";
+ extra_padding = TRUE;
}
while (width)
{
if (len > width)
len = width;
-
- printf (format_string, len, symbol);
+
+ printf ("%.*s", len, symbol);
width -= len;
+ num_printed += len;
}
if (* c == 0 || width == 0)
printf ("^%c", *c + 0x40);
width -= 2;
+ num_printed += 2;
}
else
{
if (width < 6)
break;
-
+
printf ("<0x%.2x>", *c);
width -= 6;
+ num_printed += 6;
}
symbol = c + 1;
}
+
+ if (extra_padding && width > 0)
+ {
+ /* Fill in the remaining spaces. */
+ printf ("%-*s", width, " ");
+ num_printed += 2;
+ }
+
+ return num_printed;
}
static void
psym = symtab + symtab_index;
printf (" ");
- print_vma (psym->st_value, LONG_HEX);
- printf (is_32bit_elf ? " " : " ");
+
+ if (ELF_ST_TYPE (psym->st_info) == STT_IFUNC)
+ {
+ const char * name;
+ unsigned int len;
+ unsigned int width = is_32bit_elf ? 8 : 14;
+
+ /* Relocations against IFUNC symbols do not use the value of
+ the symbol as the address to relocate against. Instead
+ they invoke the function named by the symbol and use its
+ result as the address for relocation.
+
+ To indicate this to the user, do not display the value of
+ the symbol in the "Symbols's Value" field. Instead show
+ its name followed by () as a hint that the symbol is
+ invoked. */
+
+ if (strtab == NULL
+ || psym->st_name == 0
+ || psym->st_name >= strtablen)
+ name = "??";
+ else
+ name = strtab + psym->st_name;
+
+ len = print_symbol (width, name);
+ printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
+ }
+ else
+ {
+ print_vma (psym->st_value, LONG_HEX);
+
+ printf (is_32bit_elf ? " " : " ");
+ }
if (psym->st_name == 0)
{
&& psym->st_shndx == SHN_IA_64_ANSI_COMMON)
sec_name = "ANSI_COM";
else if (elf_header.e_machine == EM_IA_64
- && (elf_header.e_ident[EI_OSABI]
+ && (elf_header.e_ident[EI_OSABI]
== ELFOSABI_OPENVMS)
&& psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
sec_name = "VMS_SYMVEC";
print_symbol (22, strtab + psym->st_name);
if (is_rela)
- printf (" + %lx", (unsigned long) rels[i].r_addend);
+ {
+ long offset = (long) (bfd_signed_vma) rels[i].r_addend;
+
+ if (offset < 0)
+ printf (" - %lx", - offset);
+ else
+ printf (" + %lx", offset);
+ }
}
}
else if (is_rela)
case EM_ALTERA_NIOS2: return "Altera Nios II";
case EM_XC16X: return "Infineon Technologies xc16x";
case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
- case EM_CR16:
+ case EM_CR16:
case EM_CR16_OLD: return "National Semiconductor's CR16";
default:
snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
else if (section->sh_type == SHT_RELA)
CHECK_ENTSIZE (section, i, Rela);
else if ((do_debugging || do_debug_info || do_debug_abbrevs
- || do_debug_lines || do_debug_lines_decoded || do_debug_pubnames
- || do_debug_aranges || do_debug_frames || do_debug_macinfo
+ || do_debug_lines || do_debug_lines_decoded || do_debug_pubnames
+ || do_debug_aranges || do_debug_frames || do_debug_macinfo
|| do_debug_str || do_debug_loc || do_debug_ranges)
&& (const_strneq (name, ".debug_")
|| const_strneq (name, ".zdebug_")))
if (do_debugging
|| (do_debug_info && streq (name, "info"))
|| (do_debug_abbrevs && streq (name, "abbrev"))
- || ((do_debug_lines || do_debug_lines_decoded)
+ || ((do_debug_lines || do_debug_lines_decoded)
&& streq (name, "line"))
|| (do_debug_pubnames && streq (name, "pubnames"))
|| (do_debug_aranges && streq (name, "aranges"))
if (type == STT_HP_STUB)
return "HP_STUB";
}
+ else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
+ || elf_header.e_ident[EI_OSABI] == ELFOSABI_HURD
+ /* GNU/Linux is still using the default value 0. */
+ || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE)
+ {
+ if (type == STT_IFUNC)
+ return "IFUNC";
+ }
snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
}
return reloc_type == 1; /* R_ARC_32. */
case EM_ARM:
return reloc_type == 2; /* R_ARM_ABS32 */
- case EM_AVR_OLD:
+ case EM_AVR_OLD:
case EM_AVR:
return reloc_type == 1;
case EM_BLACKFIN:
{
switch (elf_header.e_machine)
{
- case EM_68K:
- return reloc_type == 0; /* R_68K_NONE. */
- case EM_386:
- return reloc_type == 0; /* R_386_NONE. */
+ case EM_68K: /* R_68K_NONE. */
+ case EM_386: /* R_386_NONE. */
case EM_SPARC32PLUS:
case EM_SPARCV9:
- case EM_SPARC:
- return reloc_type == 0; /* R_SPARC_NONE. */
- case EM_MIPS:
- return reloc_type == 0; /* R_MIPS_NONE. */
- case EM_PARISC:
- return reloc_type == 0; /* R_PARISC_NONE. */
- case EM_ALPHA:
- return reloc_type == 0; /* R_ALPHA_NONE. */
- case EM_PPC:
- return reloc_type == 0; /* R_PPC_NONE. */
- case EM_PPC64:
- return reloc_type == 0; /* R_PPC64_NONE. */
- case EM_ARM:
- return reloc_type == 0; /* R_ARM_NONE. */
- case EM_IA_64:
- return reloc_type == 0; /* R_IA64_NONE. */
- case EM_SH:
- return reloc_type == 0; /* R_SH_NONE. */
+ case EM_SPARC: /* R_SPARC_NONE. */
+ case EM_MIPS: /* R_MIPS_NONE. */
+ case EM_PARISC: /* R_PARISC_NONE. */
+ case EM_ALPHA: /* R_ALPHA_NONE. */
+ case EM_PPC: /* R_PPC_NONE. */
+ case EM_PPC64: /* R_PPC64_NONE. */
+ case EM_ARM: /* R_ARM_NONE. */
+ case EM_IA_64: /* R_IA64_NONE. */
+ case EM_SH: /* R_SH_NONE. */
case EM_S390_OLD:
- case EM_S390:
- return reloc_type == 0; /* R_390_NONE. */
- case EM_CRIS:
- return reloc_type == 0; /* R_CRIS_NONE. */
- case EM_X86_64:
- return reloc_type == 0; /* R_X86_64_NONE. */
- case EM_MN10300:
- return reloc_type == 0; /* R_MN10300_NONE. */
- case EM_M32R:
- return reloc_type == 0; /* R_M32R_NONE. */
+ case EM_S390: /* R_390_NONE. */
+ case EM_CRIS: /* R_CRIS_NONE. */
+ case EM_X86_64: /* R_X86_64_NONE. */
+ case EM_MN10300: /* R_MN10300_NONE. */
+ case EM_M32R: /* R_M32R_NONE. */
+ return reloc_type == 0;
}
return FALSE;
}
/* Uncompresses a section that was compressed using zlib, in place.
- * This is a copy of bfd_uncompress_section_contents, in bfd/compress.c */
+ This is a copy of bfd_uncompress_section_contents, in bfd/compress.c */
static int
uncompress_section_contents (unsigned char **buffer, dwarf_size_type *size)
return FALSE;
#else
dwarf_size_type compressed_size = *size;
- unsigned char* compressed_buffer = *buffer;
+ unsigned char * compressed_buffer = *buffer;
dwarf_size_type uncompressed_size;
- unsigned char* uncompressed_buffer;
+ unsigned char * uncompressed_buffer;
z_stream strm;
int rc;
dwarf_size_type header_size = 12;
/* Read the zlib header. In this case, it should be "ZLIB" followed
by the uncompressed section size, 8 bytes in big-endian order. */
if (compressed_size < header_size
- || ! streq ((char*) compressed_buffer, "ZLIB"))
+ || ! streq ((char *) compressed_buffer, "ZLIB"))
return 0;
+
uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
strm.zfree = NULL;
strm.opaque = NULL;
strm.avail_in = compressed_size - header_size;
- strm.next_in = (Bytef*) compressed_buffer + header_size;
+ strm.next_in = (Bytef *) compressed_buffer + header_size;
strm.avail_out = uncompressed_size;
uncompressed_buffer = xmalloc (uncompressed_size);
- rc = inflateInit (&strm);
+ rc = inflateInit (& strm);
while (strm.avail_in > 0)
{
if (rc != Z_OK)
goto fail;
- strm.next_out = ((Bytef*) uncompressed_buffer
+ strm.next_out = ((Bytef *) uncompressed_buffer
+ (uncompressed_size - strm.avail_out));
rc = inflate (&strm, Z_FINISH);
if (rc != Z_STREAM_END)
goto fail;
- rc = inflateReset (&strm);
+ rc = inflateReset (& strm);
}
- rc = inflateEnd (&strm);
+ rc = inflateEnd (& strm);
if (rc != Z_OK
|| strm.avail_out != 0)
goto fail;
}
addend = is_rela ? rp->r_addend : byte_get (loc, reloc_size);
-
+
if (is_32bit_pcrel_reloc (reloc_type)
|| is_64bit_pcrel_reloc (reloc_type))
{
static const char *arm_attr_tag_CPU_arch[] =
{"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
- "v6K", "v7"};
+ "v6K", "v7", "v6-M", "v6S-M"};
static const char *arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
static const char *arm_attr_tag_THUMB_ISA_use[] =
{"No", "Thumb-1", "Thumb-2"};
static const char *arm_attr_tag_VFP_arch[] =
{"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16"};
-static const char *arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1"};
-static const char *arm_attr_tag_NEON_arch[] = {"No", "NEONv1"};
-static const char *arm_attr_tag_ABI_PCS_config[] =
+static const char *arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
+static const char *arm_attr_tag_Advanced_SIMD_arch[] = {"No", "NEONv1"};
+static const char *arm_attr_tag_PCS_config[] =
{"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
"PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
static const char *arm_attr_tag_ABI_PCS_R9_use[] =
{"V6", "SB", "TLS", "Unused"};
static const char *arm_attr_tag_ABI_PCS_RW_data[] =
{"Absolute", "PC-relative", "SB-relative", "None"};
-static const char *arm_attr_tag_ABI_PCS_RO_DATA[] =
+static const char *arm_attr_tag_ABI_PCS_RO_data[] =
{"Absolute", "PC-relative", "None"};
static const char *arm_attr_tag_ABI_PCS_GOT_use[] =
{"None", "direct", "GOT-indirect"};
static const char *arm_attr_tag_ABI_PCS_wchar_t[] =
{"None", "??? 1", "2", "??? 3", "4"};
static const char *arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
-static const char *arm_attr_tag_ABI_FP_denormal[] = {"Unused", "Needed"};
+static const char *arm_attr_tag_ABI_FP_denormal[] =
+ {"Unused", "Needed", "Sign only"};
static const char *arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
static const char *arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
static const char *arm_attr_tag_ABI_FP_number_model[] =
static const char *arm_attr_tag_ABI_FP_optimization_goals[] =
{"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
"Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
+static const char *arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
+static const char *arm_attr_tag_VFP_HP_extension[] =
+ {"Not Allowed", "Allowed"};
+static const char *arm_attr_tag_ABI_FP_16bit_format[] =
+ {"None", "IEEE 754", "Alternative Format"};
+static const char *arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
+static const char *arm_attr_tag_Virtualization_use[] =
+ {"Not Allowed", "Allowed"};
+static const char *arm_attr_tag_MPextension_use[] = {"Not Allowed", "Allowed"};
#define LOOKUP(id, name) \
{id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
LOOKUP(9, THUMB_ISA_use),
LOOKUP(10, VFP_arch),
LOOKUP(11, WMMX_arch),
- LOOKUP(12, NEON_arch),
- LOOKUP(13, ABI_PCS_config),
+ LOOKUP(12, Advanced_SIMD_arch),
+ LOOKUP(13, PCS_config),
LOOKUP(14, ABI_PCS_R9_use),
LOOKUP(15, ABI_PCS_RW_data),
- LOOKUP(16, ABI_PCS_RO_DATA),
+ LOOKUP(16, ABI_PCS_RO_data),
LOOKUP(17, ABI_PCS_GOT_use),
LOOKUP(18, ABI_PCS_wchar_t),
LOOKUP(19, ABI_FP_rounding),
LOOKUP(29, ABI_WMMX_args),
LOOKUP(30, ABI_optimization_goals),
LOOKUP(31, ABI_FP_optimization_goals),
- {32, "compatibility", 0, NULL}
+ {32, "compatibility", 0, NULL},
+ LOOKUP(34, CPU_unaligned_access),
+ LOOKUP(36, VFP_HP_extension),
+ LOOKUP(38, ABI_FP_16bit_format),
+ {64, "nodefaults", 0, NULL},
+ {65, "also_compatible_with", 0, NULL},
+ LOOKUP(66, T2EE_use),
+ {67, "conformance", 1, NULL},
+ LOOKUP(68, Virtualization_use),
+ LOOKUP(70, MPextension_use)
};
#undef LOOKUP
p += strlen((char *)p) + 1;
break;
+ case 64: /* Tag_nodefaults. */
+ p++;
+ printf ("True\n");
+ break;
+
+ case 65: /* Tag_also_compatible_with. */
+ val = read_uleb128 (p, &len);
+ p += len;
+ if (val == 6 /* Tag_CPU_arch. */)
+ {
+ val = read_uleb128 (p, &len);
+ p += len;
+ if ((unsigned int)val >= ARRAY_SIZE(arm_attr_tag_CPU_arch))
+ printf ("??? (%d)\n", val);
+ else
+ printf ("%s\n", arm_attr_tag_CPU_arch[val]);
+ }
+ else
+ printf ("???\n");
+ while (*(p++) != '\0' /* NUL terminator. */);
+ break;
+
default:
abort();
}
return p;
}
+ if (tag == Tag_GNU_Power_ABI_Struct_Return)
+ {
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf (" Tag_GNU_Power_ABI_Struct_Return: ");
+ switch (val)
+ {
+ case 0:
+ printf ("Any\n");
+ break;
+ case 1:
+ printf ("r3/r4\n");
+ break;
+ case 2:
+ printf ("Memory\n");
+ break;
+ default:
+ printf ("??? (%d)\n", val);
+ break;
+ }
+ return p;
+ }
+
if (tag & 1)
type = 1; /* String. */
else
size -= index_num * SIZEOF_AR_INDEX_NUMBERS;
/* Convert the index numbers into the host's numeric format. */
- index_array = malloc (index_num * sizeof (* index_array));
+ index_array = malloc (index_num * sizeof (* index_array));
if (index_array == NULL)
{
free (index_buffer);
error (_("%s: failed to read archive index symbol table\n"), file_name);
ret = 1;
goto out;
- }
+ }
}
else
{
{
error (_("%s: end of the symbol table reached before the end of the index\n"),
file_name);
- break;
+ break;
}
printf ("\t%s\n", sym_table + l);
l += strlen (sym_table + l) + 1;