ELF file than is provided by objdump. In particular it can display DWARF
debugging information which (at the moment) objdump cannot. */
\f
+#include "config.h"
#include "sysdep.h"
#include <assert.h>
#include <sys/stat.h>
#include <time.h>
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
/* for PATH_MAX */
#ifdef HAVE_LIMITS_H
}
}
-#if defined BFD64 && !BFD_HOST_64BIT_LONG && !BFD_HOST_64BIT_LONG_LONG
+/* Print a VMA value. */
static int
-print_dec_vma (bfd_vma vma, int is_signed)
+print_vma (bfd_vma vma, print_mode mode)
{
- char buf[40];
- char *bufp = buf;
int nc = 0;
- if (is_signed && (bfd_signed_vma) vma < 0)
- {
- vma = -vma;
- putchar ('-');
- nc = 1;
- }
-
- do
+ switch (mode)
{
- *bufp++ = '0' + vma % 10;
- vma /= 10;
- }
- while (vma != 0);
- nc += bufp - buf;
-
- while (bufp > buf)
- putchar (*--bufp);
- return nc;
-}
-
-static int
-print_hex_vma (bfd_vma vma)
-{
- char buf[32];
- char *bufp = buf;
- int nc;
+ case FULL_HEX:
+ nc = printf ("0x");
+ /* Drop through. */
- do
- {
- char digit = '0' + (vma & 0x0f);
- if (digit > '9')
- digit += 'a' - '0' - 10;
- *bufp++ = digit;
- vma >>= 4;
- }
- while (vma != 0);
- nc = bufp - buf;
-
- while (bufp > buf)
- putchar (*--bufp);
- return nc;
-}
-#endif
-
-/* Print a VMA value. */
-static int
-print_vma (bfd_vma vma, print_mode mode)
-{
+ case LONG_HEX:
#ifdef BFD64
- if (is_32bit_elf)
+ if (is_32bit_elf)
+ return nc + printf ("%08.8" BFD_VMA_FMT "x", vma);
#endif
- {
- switch (mode)
- {
- case FULL_HEX:
- return printf ("0x%8.8lx", (unsigned long) vma);
+ printf_vma (vma);
+ return nc + 16;
- case LONG_HEX:
- return printf ("%8.8lx", (unsigned long) vma);
+ case DEC_5:
+ if (vma <= 99999)
+ return printf ("%5" BFD_VMA_FMT "d", vma);
+ /* Drop through. */
- case DEC_5:
- if (vma <= 99999)
- return printf ("%5ld", (long) vma);
- /* Drop through. */
+ case PREFIX_HEX:
+ nc = printf ("0x");
+ /* Drop through. */
- case PREFIX_HEX:
- return printf ("0x%lx", (unsigned long) vma);
+ case HEX:
+ return nc + printf ("%" BFD_VMA_FMT "x", vma);
- case HEX:
- return printf ("%lx", (unsigned long) vma);
+ case DEC:
+ return printf ("%" BFD_VMA_FMT "d", vma);
- case DEC:
- return printf ("%ld", (unsigned long) vma);
-
- case UNSIGNED:
- return printf ("%lu", (unsigned long) vma);
- }
+ case UNSIGNED:
+ return printf ("%" BFD_VMA_FMT "u", vma);
}
-#ifdef BFD64
- else
- {
- int nc = 0;
-
- switch (mode)
- {
- case FULL_HEX:
- nc = printf ("0x");
- /* Drop through. */
-
- case LONG_HEX:
- printf_vma (vma);
- return nc + 16;
-
- case PREFIX_HEX:
- nc = printf ("0x");
- /* Drop through. */
-
- case HEX:
-#if BFD_HOST_64BIT_LONG
- return nc + printf ("%lx", vma);
-#elif BFD_HOST_64BIT_LONG_LONG
-#ifndef __MSVCRT__
- return nc + printf ("%llx", vma);
-#else
- return nc + printf ("%I64x", vma);
-#endif
-#else
- return nc + print_hex_vma (vma);
-#endif
-
- case DEC:
-#if BFD_HOST_64BIT_LONG
- return printf ("%ld", vma);
-#elif BFD_HOST_64BIT_LONG_LONG
-#ifndef __MSVCRT__
- return printf ("%lld", vma);
-#else
- return printf ("%I64d", vma);
-#endif
-#else
- return print_dec_vma (vma, 1);
-#endif
-
- case DEC_5:
-#if BFD_HOST_64BIT_LONG
- if (vma <= 99999)
- return printf ("%5ld", vma);
- else
- return printf ("%#lx", vma);
-#elif BFD_HOST_64BIT_LONG_LONG
-#ifndef __MSVCRT__
- if (vma <= 99999)
- return printf ("%5lld", vma);
- else
- return printf ("%#llx", vma);
-#else
- if (vma <= 99999)
- return printf ("%5I64d", vma);
- else
- return printf ("%#I64x", vma);
-#endif
-#else
- if (vma <= 99999)
- return printf ("%5ld", _bfd_int64_low (vma));
- else
- return print_hex_vma (vma);
-#endif
-
- case UNSIGNED:
-#if BFD_HOST_64BIT_LONG
- return printf ("%lu", vma);
-#elif BFD_HOST_64BIT_LONG_LONG
-#ifndef __MSVCRT__
- return printf ("%llu", vma);
-#else
- return printf ("%I64u", vma);
-#endif
-#else
- return print_dec_vma (vma, 0);
-#endif
- }
- }
-#endif
return 0;
}
case EM_AVR_OLD:
case EM_BLACKFIN:
case EM_CR16:
+ case EM_CR16_OLD:
case EM_CRIS:
case EM_CRX:
case EM_D30V:
case EM_IP2K:
case EM_IP2K_OLD:
case EM_IQ2000:
+ case EM_M32C_OLD:
case EM_M32C:
case EM_M32R:
case EM_MCORE:
rtype = elf_xtensa_reloc_type (type);
break;
+ case EM_M32C_OLD:
case EM_M32C:
rtype = elf_m32c_reloc_type (type);
break;
break;
case EM_CR16:
+ case EM_CR16_OLD:
rtype = elf_cr16_reloc_type (type);
break;
}
case EM_IQ2000: return "Vitesse IQ2000";
case EM_XTENSA_OLD:
case EM_XTENSA: return "Tensilica Xtensa Processor";
+ case EM_M32C_OLD:
case EM_M32C: return "Renesas M32c";
case EM_MT: return "Morpho Techologies MT processor";
case EM_BLACKFIN: return "Analog Devices Blackfin";
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: return "National Semiconductor's CR16";
+ case EM_CR16:
+ case EM_CR16_OLD: return "National Semiconductor's CR16";
default:
snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
return buff;
}
break;
+ case EM_M32C_OLD:
case EM_M32C:
switch (elf_header.e_flags & EF_M32C_CPU_MASK)
{
|| 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, ".debug_")
+ || const_strneq (name, ".zdebug_")))
{
- name += 7;
+ if (name[1] == 'z')
+ name += sizeof (".zdebug_") - 1;
+ else
+ name += sizeof (".debug_") - 1;
if (do_debugging
|| (do_debug_info && streq (name, "info"))
case EM_CRIS:
return reloc_type == 3; /* R_CRIS_32. */
case EM_CR16:
+ case EM_CR16_OLD:
return reloc_type == 3; /* R_CR16_NUM32. */
case EM_CRX:
return reloc_type == 15; /* R_CRX_NUM32. */
return reloc_type == 2; /* R_IP2K_32. */
case EM_IQ2000:
return reloc_type == 2; /* R_IQ2000_32. */
+ case EM_M32C_OLD:
case EM_M32C:
return reloc_type == 3; /* R_M32C_32. */
case EM_M32R:
case EM_IP2K_OLD:
case EM_IP2K:
return reloc_type == 1; /* R_IP2K_16. */
+ case EM_M32C_OLD:
case EM_M32C:
return reloc_type == 1; /* R_M32C_16 */
case EM_MSP430_OLD:
}
}
+/* Uncompresses a section that was compressed using zlib, in place.
+ * 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)
+{
+#ifndef HAVE_ZLIB_H
+ /* These are just to quiet gcc. */
+ buffer = 0;
+ size = 0;
+ return FALSE;
+#else
+ dwarf_size_type compressed_size = *size;
+ unsigned char* compressed_buffer = *buffer;
+ dwarf_size_type uncompressed_size;
+ 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"))
+ 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;
+ uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[11];
+
+ /* It is possible the section consists of several compressed
+ buffers concatenated together, so we uncompress in a loop. */
+ strm.zalloc = NULL;
+ strm.zfree = NULL;
+ strm.opaque = NULL;
+ strm.avail_in = compressed_size - header_size;
+ strm.next_in = (Bytef*) compressed_buffer + header_size;
+ strm.avail_out = uncompressed_size;
+ uncompressed_buffer = xmalloc (uncompressed_size);
+
+ rc = inflateInit (&strm);
+ while (strm.avail_in > 0)
+ {
+ if (rc != Z_OK)
+ goto fail;
+ 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 = inflateEnd (&strm);
+ if (rc != Z_OK
+ || strm.avail_out != 0)
+ goto fail;
+
+ free (compressed_buffer);
+ *buffer = uncompressed_buffer;
+ *size = uncompressed_size;
+ return 1;
+
+ fail:
+ free (uncompressed_buffer);
+ return 0;
+#endif /* HAVE_ZLIB_H */
+}
+
/* Apply relocations to a debug section. */
static void
struct dwarf_section *section = &debug_displays [debug].section;
Elf_Internal_Shdr *sec;
char buf [64];
+ int section_is_compressed;
/* If it is already loaded, do nothing. */
if (section->start != NULL)
return 1;
/* Locate the debug section. */
- sec = find_section (section->name);
+ sec = find_section (section->uncompressed_name);
+ if (sec != NULL)
+ section->name = section->uncompressed_name;
+ else
+ {
+ sec = find_section (section->compressed_name);
+ if (sec != NULL)
+ section->name = section->compressed_name;
+ }
if (sec == NULL)
return 0;
+ section_is_compressed = section->name == section->compressed_name;
snprintf (buf, sizeof (buf), _("%s section data"), section->name);
section->address = sec->sh_addr;
section->size = sec->sh_size;
section->start = get_data (NULL, file, sec->sh_offset, 1,
sec->sh_size, buf);
+ if (section->start == NULL)
+ return 0;
+
+ if (section_is_compressed)
+ if (! uncompress_section_contents (§ion->start, §ion->size))
+ return 0;
if (debug_displays [debug].relocate)
debug_apply_relocations (file, sec, section->start);
- return section->start != NULL;
+ return 1;
}
void
/* See if we know how to display the contents of this section. */
for (i = 0; i < max; i++)
- if (streq (debug_displays[i].section.name, name))
+ if (streq (debug_displays[i].section.uncompressed_name, name)
+ || streq (debug_displays[i].section.compressed_name, name))
{
struct dwarf_section *sec = &debug_displays [i].section;
case 2:
printf ("Soft float\n");
break;
+ case 3:
+ printf ("Single-precision hard float\n");
+ break;
default:
printf ("??? (%d)\n", val);
break;
return _("NT_PRXFPREG (user_xfpregs structure)");
case NT_PPC_VMX:
return _("NT_PPC_VMX (ppc Altivec registers)");
+ case NT_PPC_VSX:
+ return _("NT_PPC_VSX (ppc VSX registers)");
case NT_PSTATUS:
return _("NT_PSTATUS (pstatus structure)");
case NT_FPREGS: