OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [binutils/] [readelf.c] - Diff between revs 163 and 166

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 163 Rev 166
Line 1... Line 1...
/* readelf.c -- display contents of an ELF format file
/* readelf.c -- display contents of an ELF format file
   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
   2008, 2009, 2010, 2011
   2008, 2009, 2010, 2011, 2012
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
 
 
   Originally developed by Eric Youngdale <eric@andante.jic.com>
   Originally developed by Eric Youngdale <eric@andante.jic.com>
   Modifications by Nick Clifton <nickc@redhat.com>
   Modifications by Nick Clifton <nickc@redhat.com>
 
 
Line 40... Line 40...
 
 
  There is also the case that readelf can provide more information about an
  There is also the case that readelf can provide more information about an
  ELF file than is provided by objdump.  In particular it can display DWARF
  ELF file than is provided by objdump.  In particular it can display DWARF
  debugging information which (at the moment) objdump cannot.  */
  debugging information which (at the moment) objdump cannot.  */


#include "config.h"
 
#include "sysdep.h"
#include "sysdep.h"
#include <assert.h>
#include <assert.h>
#include <sys/stat.h>
 
#include <time.h>
#include <time.h>
#ifdef HAVE_ZLIB_H
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#include <zlib.h>
#endif
#endif
 
 
Line 3192... Line 3190...
  -n --notes             Display the core notes (if present)\n\
  -n --notes             Display the core notes (if present)\n\
  -r --relocs            Display the relocations (if present)\n\
  -r --relocs            Display the relocations (if present)\n\
  -u --unwind            Display the unwind info (if present)\n\
  -u --unwind            Display the unwind info (if present)\n\
  -d --dynamic           Display the dynamic section (if present)\n\
  -d --dynamic           Display the dynamic section (if present)\n\
  -V --version-info      Display the version sections (if present)\n\
  -V --version-info      Display the version sections (if present)\n\
  -A --arch-specific     Display architecture specific information (if any).\n\
  -A --arch-specific     Display architecture specific information (if any)\n\
  -c --archive-index     Display the symbol/file index in an archive\n\
  -c --archive-index     Display the symbol/file index in an archive\n\
  -D --use-dynamic       Use the dynamic section info when displaying symbols\n\
  -D --use-dynamic       Use the dynamic section info when displaying symbols\n\
  -x --hex-dump=<number|name>\n\
  -x --hex-dump=<number|name>\n\
                         Dump the contents of section <number|name> as bytes\n\
                         Dump the contents of section <number|name> as bytes\n\
  -p --string-dump=<number|name>\n\
  -p --string-dump=<number|name>\n\
Line 4966... Line 4964...
    }
    }
 
 
  if (section_headers == NULL)
  if (section_headers == NULL)
    {
    {
      error (_("Section headers are not available!\n"));
      error (_("Section headers are not available!\n"));
      abort ();
      /* PR 13622: This can happen with a corrupt ELF header.  */
 
      return 0;
    }
    }
 
 
  section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
  section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
                                                     sizeof (struct group *));
                                                     sizeof (struct group *));
 
 
Line 5600... Line 5599...
          dist = addr.offset - value;
          dist = addr.offset - value;
          if (!dist)
          if (!dist)
            break;
            break;
        }
        }
    }
    }
 
 
  if (best)
  if (best)
    {
    {
      *symname = (best->st_name >= strtab_size
      *symname = (best->st_name >= strtab_size
                  ? _("<corrupt>") : strtab + best->st_name);
                  ? _("<corrupt>") : strtab + best->st_name);
      *offset = dist;
      *offset = dist;
      return;
      return;
    }
    }
 
 
  *symname = NULL;
  *symname = NULL;
  *offset = addr.offset;
  *offset = addr.offset;
}
}
 
 
static void
static void
Line 5784... Line 5785...
 
 
  aux->table_len = size / (3 * eh_addr_size);
  aux->table_len = size / (3 * eh_addr_size);
  return 1;
  return 1;
}
}
 
 
static int
static void
ia64_process_unwind (FILE * file)
ia64_process_unwind (FILE * file)
{
{
  Elf_Internal_Shdr * sec;
  Elf_Internal_Shdr * sec;
  Elf_Internal_Shdr * unwsec = NULL;
  Elf_Internal_Shdr * unwsec = NULL;
  Elf_Internal_Shdr * strsec;
  Elf_Internal_Shdr * strsec;
Line 5921... Line 5922...
 
 
  if (aux.symtab)
  if (aux.symtab)
    free (aux.symtab);
    free (aux.symtab);
  if (aux.strtab)
  if (aux.strtab)
    free ((char *) aux.strtab);
    free ((char *) aux.strtab);
 
 
  return 1;
 
}
}
 
 
struct hppa_unw_table_entry
struct hppa_unw_table_entry
  {
  {
    struct absaddr start;
    struct absaddr start;
Line 6194... Line 6193...
  aux->table_len = nentries;
  aux->table_len = nentries;
 
 
  return 1;
  return 1;
}
}
 
 
static int
static void
hppa_process_unwind (FILE * file)
hppa_process_unwind (FILE * file)
{
{
  struct hppa_unw_aux_info aux;
  struct hppa_unw_aux_info aux;
  Elf_Internal_Shdr * unwsec = NULL;
  Elf_Internal_Shdr * unwsec = NULL;
  Elf_Internal_Shdr * strsec;
  Elf_Internal_Shdr * strsec;
  Elf_Internal_Shdr * sec;
  Elf_Internal_Shdr * sec;
  unsigned long i;
  unsigned long i;
 
 
  memset (& aux, 0, sizeof (aux));
 
 
 
  if (string_table == NULL)
  if (string_table == NULL)
    return 1;
    return;
 
 
 
  memset (& aux, 0, sizeof (aux));
 
 
  for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
  for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
    {
    {
      if (sec->sh_type == SHT_SYMTAB
      if (sec->sh_type == SHT_SYMTAB
          && sec->sh_link < elf_header.e_shnum)
          && sec->sh_link < elf_header.e_shnum)
Line 6254... Line 6253...
 
 
  if (aux.symtab)
  if (aux.symtab)
    free (aux.symtab);
    free (aux.symtab);
  if (aux.strtab)
  if (aux.strtab)
    free ((char *) aux.strtab);
    free ((char *) aux.strtab);
 
 
  return 1;
 
}
}
 
 
struct arm_section
struct arm_section
{
{
  unsigned char *data;
  unsigned char *      data;            /* The unwind data.  */
 
  Elf_Internal_Shdr *  sec;             /* The cached unwind section header.  */
  Elf_Internal_Shdr *sec;
  Elf_Internal_Rela *  rela;            /* The cached relocations for this section.  */
  Elf_Internal_Rela *rela;
  unsigned long        nrelas;          /* The number of relocations.  */
  unsigned long nrelas;
  unsigned int         rel_type;        /* REL or RELA ?  */
  unsigned int rel_type;
  Elf_Internal_Rela *  next_rela;       /* Cyclic pointer to the next reloc to process.  */
 
 
  Elf_Internal_Rela *next_rela;
 
};
};
 
 
struct arm_unw_aux_info
struct arm_unw_aux_info
{
{
  FILE *file;
  FILE *              file;             /* The file containing the unwind sections.  */
 
  Elf_Internal_Sym *  symtab;           /* The file's symbol table.  */
  Elf_Internal_Sym *symtab;     /* The symbol table.  */
 
  unsigned long nsyms;          /* Number of symbols.  */
  unsigned long nsyms;          /* Number of symbols.  */
  char *strtab;                 /* The string table.  */
  char *              strtab;           /* The file's string table.  */
  unsigned long strtab_size;    /* Size of string table.  */
  unsigned long strtab_size;    /* Size of string table.  */
};
};
 
 
static const char *
static const char *
arm_print_vma_and_name (struct arm_unw_aux_info *aux,
arm_print_vma_and_name (struct arm_unw_aux_info *aux,
Line 6319... Line 6313...
 
 
  if (arm_sec->rela != NULL)
  if (arm_sec->rela != NULL)
    free (arm_sec->rela);
    free (arm_sec->rela);
}
}
 
 
static int
/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
arm_section_get_word (struct arm_unw_aux_info *aux,
      cached section and install SEC instead.
 
   2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
 
      and return its valued in * WORDP, relocating if necessary.
 
   3) Update the NEXT_RELA field in ARM_SEC and store the section index and
 
      relocation's offset in ADDR.
 
   4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
 
      into the string table of the symbol associated with the reloc.  If no
 
      reloc was applied store -1 there.
 
   5) Return TRUE upon success, FALSE otherwise.  */
 
 
 
static bfd_boolean
 
get_unwind_section_word (struct arm_unw_aux_info *  aux,
                      struct arm_section *arm_sec,
                      struct arm_section *arm_sec,
                      Elf_Internal_Shdr *sec, bfd_vma word_offset,
                         Elf_Internal_Shdr *        sec,
                      unsigned int *wordp, struct absaddr *addr)
                         bfd_vma                    word_offset,
 
                         unsigned int *             wordp,
 
                         struct absaddr *           addr,
 
                         bfd_vma *                  sym_name)
{
{
  Elf_Internal_Rela *rp;
  Elf_Internal_Rela *rp;
  Elf_Internal_Sym *sym;
  Elf_Internal_Sym *sym;
  const char * relname;
  const char * relname;
  unsigned int word;
  unsigned int word;
  bfd_boolean wrapped;
  bfd_boolean wrapped;
 
 
  addr->section = SHN_UNDEF;
  addr->section = SHN_UNDEF;
  addr->offset = 0;
  addr->offset = 0;
 
 
 
  if (sym_name != NULL)
 
    *sym_name = (bfd_vma) -1;
 
 
 
  /* If necessary, update the section cache.  */
  if (sec != arm_sec->sec)
  if (sec != arm_sec->sec)
    {
    {
      Elf_Internal_Shdr *relsec;
      Elf_Internal_Shdr *relsec;
 
 
      arm_free_section (arm_sec);
      arm_free_section (arm_sec);
Line 6354... Line 6366...
        {
        {
          if (relsec->sh_info >= elf_header.e_shnum
          if (relsec->sh_info >= elf_header.e_shnum
              || section_headers + relsec->sh_info != sec)
              || section_headers + relsec->sh_info != sec)
            continue;
            continue;
 
 
 
          arm_sec->rel_type = relsec->sh_type;
          if (relsec->sh_type == SHT_REL)
          if (relsec->sh_type == SHT_REL)
            {
            {
              if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
              if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
                                     relsec->sh_size,
                                     relsec->sh_size,
                                     & arm_sec->rela, & arm_sec->nrelas))
                                     & arm_sec->rela, & arm_sec->nrelas))
                return 0;
                return FALSE;
              break;
              break;
            }
            }
          else if (relsec->sh_type == SHT_RELA)
          else if (relsec->sh_type == SHT_RELA)
            {
            {
              if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
              if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
                                      relsec->sh_size,
                                      relsec->sh_size,
                                      & arm_sec->rela, & arm_sec->nrelas))
                                      & arm_sec->rela, & arm_sec->nrelas))
                return 0;
                return FALSE;
              break;
              break;
            }
            }
 
          else
 
            warn (_("unexpected relocation type (%d) for section %d"),
 
                  relsec->sh_type, relsec->sh_info);
        }
        }
 
 
      arm_sec->next_rela = arm_sec->rela;
      arm_sec->next_rela = arm_sec->rela;
    }
    }
 
 
 
  /* If there is no unwind data we can do nothing.  */
  if (arm_sec->data == NULL)
  if (arm_sec->data == NULL)
    return 0;
    return FALSE;
 
 
 
  /* Get the word at the required offset.  */
  word = byte_get (arm_sec->data + word_offset, 4);
  word = byte_get (arm_sec->data + word_offset, 4);
 
 
 
  /* Look through the relocs to find the one that applies to the provided offset.  */
  wrapped = FALSE;
  wrapped = FALSE;
  for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
  for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
    {
    {
      bfd_vma prelval, offset;
      bfd_vma prelval, offset;
 
 
Line 6403... Line 6422...
        }
        }
 
 
      if (rp->r_offset < word_offset)
      if (rp->r_offset < word_offset)
        continue;
        continue;
 
 
      switch (elf_header.e_machine)
      sym = aux->symtab + ELF32_R_SYM (rp->r_info);
 
 
 
      if (arm_sec->rel_type == SHT_REL)
        {
        {
        case EM_ARM:
          offset = word & 0x7fffffff;
          relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
          if (offset & 0x40000000)
          break;
            offset |= ~ (bfd_vma) 0x7fffffff;
 
        }
 
      else if (arm_sec->rel_type == SHT_RELA)
 
        offset = rp->r_addend;
 
      else
 
        abort ();
 
 
        case EM_TI_C6000:
      offset += sym->st_value;
          relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
      prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
          break;
 
 
 
        default:
      /* Check that we are processing the expected reloc type.  */
            abort();
      if (elf_header.e_machine == EM_ARM)
        }
        {
 
          relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
 
 
      if (streq (relname, "R_ARM_NONE")
          if (streq (relname, "R_ARM_NONE"))
          || streq (relname, "R_C6000_NONE"))
 
        continue;
        continue;
 
 
      if (!(streq (relname, "R_ARM_PREL31")
          if (! streq (relname, "R_ARM_PREL31"))
            || streq (relname, "R_C6000_PREL31")))
 
        {
        {
          warn (_("Skipping unexpected relocation type %s\n"), relname);
          warn (_("Skipping unexpected relocation type %s\n"), relname);
          continue;
          continue;
        }
        }
 
        }
 
      else if (elf_header.e_machine == EM_TI_C6000)
 
        {
 
          relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
 
 
      sym = aux->symtab + ELF32_R_SYM (rp->r_info);
          if (streq (relname, "R_C6000_NONE"))
 
            continue;
 
 
      if (arm_sec->rel_type == SHT_REL)
          if (! streq (relname, "R_C6000_PREL31"))
        {
        {
          offset = word & 0x7fffffff;
              warn (_("Skipping unexpected relocation type %s\n"), relname);
          if (offset & 0x40000000)
              continue;
            offset |= ~ (bfd_vma) 0x7fffffff;
 
        }
        }
      else
 
        offset = rp->r_addend;
 
 
 
      offset += sym->st_value;
 
      prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
 
 
 
      if (streq (relname, "R_C6000_PREL31"))
 
        prelval >>= 1;
        prelval >>= 1;
 
        }
 
      else
 
        /* This function currently only supports ARM and TI unwinders.  */
 
        abort ();
 
 
      word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
      word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
      addr->section = sym->st_shndx;
      addr->section = sym->st_shndx;
      addr->offset = offset;
      addr->offset = offset;
 
      if (sym_name)
 
        * sym_name = sym->st_name;
      break;
      break;
    }
    }
 
 
  *wordp = word;
  *wordp = word;
  arm_sec->next_rela = rp;
  arm_sec->next_rela = rp;
 
 
  return 1;
  return TRUE;
}
}
 
 
static const char *tic6x_unwind_regnames[16] = {
static const char *tic6x_unwind_regnames[16] =
 
{
    "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
    "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
    "A14", "A13", "A12", "A11", "A10",
    "A14", "A13", "A12", "A11", "A10",
    "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"};
  "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
 
};
 
 
static void
static void
decode_tic6x_unwind_regmask (unsigned int mask)
decode_tic6x_unwind_regmask (unsigned int mask)
{
{
  int i;
  int i;
Line 6482... Line 6512...
 
 
#define ADVANCE                                                 \
#define ADVANCE                                                 \
  if (remaining == 0 && more_words)                              \
  if (remaining == 0 && more_words)                              \
    {                                                           \
    {                                                           \
      data_offset += 4;                                         \
      data_offset += 4;                                         \
      if (!arm_section_get_word (aux, data_arm_sec, data_sec,   \
      if (! get_unwind_section_word (aux, data_arm_sec, data_sec,       \
                                 data_offset, &word, &addr))    \
                                     data_offset, & word, & addr, NULL))        \
        return;                                                 \
        return;                                                 \
      remaining = 4;                                            \
      remaining = 4;                                            \
      more_words--;                                             \
      more_words--;                                             \
    }                                                           \
    }                                                           \
 
 
Line 6587... Line 6617...
                printf (", ");
                printf (", ");
              printf ("r%d", i);
              printf ("r%d", i);
            }
            }
          if (op & 0x08)
          if (op & 0x08)
            {
            {
              if (first)
              if (!first)
                printf (", ");
                printf (", ");
              printf ("r14");
              printf ("r14");
            }
            }
          printf ("}");
          printf ("}");
        }
        }
Line 6762... Line 6792...
        {
        {
          unsigned int reg;
          unsigned int reg;
          unsigned int nregs;
          unsigned int nregs;
          unsigned int i;
          unsigned int i;
          const char *name;
          const char *name;
          struct {
          struct
 
          {
              unsigned int offset;
              unsigned int offset;
              unsigned int reg;
              unsigned int reg;
          } regpos[16];
          } regpos[16];
 
 
          /* Scan entire instruction first so that GET_OP output is not
          /* Scan entire instruction first so that GET_OP output is not
Line 6819... Line 6850...
      else if (op == 0xd2)
      else if (op == 0xd2)
        {
        {
          unsigned char buf[9];
          unsigned char buf[9];
          unsigned int i, len;
          unsigned int i, len;
          unsigned long offset;
          unsigned long offset;
 
 
          for (i = 0; i < sizeof (buf); i++)
          for (i = 0; i < sizeof (buf); i++)
            {
            {
              GET_OP (buf[i]);
              GET_OP (buf[i]);
              if ((buf[i] & 0x80) == 0)
              if ((buf[i] & 0x80) == 0)
                break;
                break;
Line 6847... Line 6879...
      putchar ('\n');
      putchar ('\n');
    }
    }
}
}
 
 
static bfd_vma
static bfd_vma
expand_prel31 (bfd_vma word, bfd_vma where)
arm_expand_prel31 (bfd_vma word, bfd_vma where)
{
{
  bfd_vma offset;
  bfd_vma offset;
 
 
  offset = word & 0x7fffffff;
  offset = word & 0x7fffffff;
  if (offset & 0x40000000)
  if (offset & 0x40000000)
Line 6863... Line 6895...
  return offset + where;
  return offset + where;
}
}
 
 
static void
static void
decode_arm_unwind (struct arm_unw_aux_info *aux,
decode_arm_unwind (struct arm_unw_aux_info *aux,
                   unsigned int word, unsigned int remaining,
                   unsigned int               word,
                   bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
                   unsigned int               remaining,
 
                   bfd_vma                    data_offset,
 
                   Elf_Internal_Shdr *        data_sec,
                   struct arm_section *data_arm_sec)
                   struct arm_section *data_arm_sec)
{
{
  int per_index;
  int per_index;
  unsigned int more_words = 0;
  unsigned int more_words = 0;
  struct absaddr addr;
  struct absaddr addr;
 
  bfd_vma sym_name = (bfd_vma) -1;
 
 
  if (remaining == 0)
  if (remaining == 0)
    {
    {
      /* Fetch the first word.  */
      /* Fetch the first word.
      if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset,
         Note - when decoding an object file the address extracted
                                 &word, &addr))
         here will always be 0.  So we also pass in the sym_name
 
         parameter so that we can find the symbol associated with
 
         the personality routine.  */
 
      if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
 
                                     & word, & addr, & sym_name))
        return;
        return;
 
 
      remaining = 4;
      remaining = 4;
    }
    }
 
 
  if ((word & 0x80000000) == 0)
  if ((word & 0x80000000) == 0)
    {
    {
      /* Expand prel31 for personality routine.  */
      /* Expand prel31 for personality routine.  */
      bfd_vma fn;
      bfd_vma fn;
      const char *procname;
      const char *procname;
 
 
      fn = expand_prel31 (word, data_sec->sh_addr + data_offset);
      fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
      printf (_("  Personality routine: "));
      printf (_("  Personality routine: "));
 
      if (fn == 0
 
          && addr.section == SHN_UNDEF && addr.offset == 0
 
          && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
 
        {
 
          procname = aux->strtab + sym_name;
 
          print_vma (fn, PREFIX_HEX);
 
          if (procname)
 
            {
 
              fputs (" <", stdout);
 
              fputs (procname, stdout);
 
              fputc ('>', stdout);
 
            }
 
        }
 
      else
      procname = arm_print_vma_and_name (aux, fn, addr);
      procname = arm_print_vma_and_name (aux, fn, addr);
      fputc ('\n', stdout);
      fputc ('\n', stdout);
 
 
      /* The GCC personality routines use the standard compact
      /* The GCC personality routines use the standard compact
         encoding, starting with one byte giving the number of
         encoding, starting with one byte giving the number of
Line 6918... Line 6972...
      else
      else
        return;
        return;
    }
    }
  else
  else
    {
    {
 
      /* ARM EHABI Section 6.3:
 
 
 
         An exception-handling table entry for the compact model looks like:
 
 
 
           31 30-28 27-24 23-0
 
           -- ----- ----- ----
 
            1   0   index Data for personalityRoutine[index]    */
 
 
 
      if (elf_header.e_machine == EM_ARM
 
          && (word & 0x70000000))
 
        warn (_("Corrupt ARM compact model table entry: %x \n"), word);
 
 
      per_index = (word >> 24) & 0x7f;
      per_index = (word >> 24) & 0x7f;
      printf (_("  Compact model %d\n"), per_index);
      printf (_("  Compact model index: %d\n"), per_index);
      if (per_index == 0)
      if (per_index == 0)
        {
        {
          more_words = 0;
          more_words = 0;
          word <<= 8;
          word <<= 8;
          remaining--;
          remaining--;
Line 6944... Line 7009...
        {
        {
          decode_arm_unwind_bytecode (aux, word, remaining, more_words,
          decode_arm_unwind_bytecode (aux, word, remaining, more_words,
                                      data_offset, data_sec, data_arm_sec);
                                      data_offset, data_sec, data_arm_sec);
        }
        }
      else
      else
        printf ("  [reserved]\n");
        {
 
          warn (_("Unknown ARM compact model index encountered\n"));
 
          printf (_("  [reserved]\n"));
 
        }
      break;
      break;
 
 
    case EM_TI_C6000:
    case EM_TI_C6000:
      if (per_index < 3)
      if (per_index < 3)
        {
        {
Line 6968... Line 7036...
          putchar ('\n');
          putchar ('\n');
          printf (_("  Return register: %s\n"),
          printf (_("  Return register: %s\n"),
                  tic6x_unwind_regnames[word & 0xf]);
                  tic6x_unwind_regnames[word & 0xf]);
        }
        }
      else
      else
        printf ("  [reserved]\n");
        printf (_("  [reserved (%d)]\n"), per_index);
      break;
      break;
 
 
    default:
    default:
      abort ();
      error (_("Unsupported architecture type %d encountered when decoding unwind table"),
 
             elf_header.e_machine);
    }
    }
 
 
  /* Decode the descriptors.  Not implemented.  */
  /* Decode the descriptors.  Not implemented.  */
}
}
 
 
Line 6996... Line 7065...
      struct absaddr fn_addr, entry_addr;
      struct absaddr fn_addr, entry_addr;
      bfd_vma fn;
      bfd_vma fn;
 
 
      fputc ('\n', stdout);
      fputc ('\n', stdout);
 
 
      if (!arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
      if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
                                 8 * i, &exidx_fn, &fn_addr)
                                     8 * i, & exidx_fn, & fn_addr, NULL)
          || !arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
          || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
                                    8 * i + 4, &exidx_entry, &entry_addr))
                                        8 * i + 4, & exidx_entry, & entry_addr, NULL))
        {
        {
          arm_free_section (&exidx_arm_sec);
          arm_free_section (&exidx_arm_sec);
          arm_free_section (&extab_arm_sec);
          arm_free_section (&extab_arm_sec);
          return;
          return;
        }
        }
 
 
      fn = expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
      /* ARM EHABI, Section 5:
 
         An index table entry consists of 2 words.
 
         The first word contains a prel31 offset to the start of a function, with bit 31 clear.  */
 
      if (exidx_fn & 0x80000000)
 
        warn (_("corrupt index table entry: %x\n"), exidx_fn);
 
 
 
      fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
 
 
      arm_print_vma_and_name (aux, fn, entry_addr);
      arm_print_vma_and_name (aux, fn, fn_addr);
      fputs (": ", stdout);
      fputs (": ", stdout);
 
 
      if (exidx_entry == 1)
      if (exidx_entry == 1)
        {
        {
          print_vma (exidx_entry, PREFIX_HEX);
          print_vma (exidx_entry, PREFIX_HEX);
Line 7028... Line 7103...
        {
        {
          bfd_vma table, table_offset = 0;
          bfd_vma table, table_offset = 0;
          Elf_Internal_Shdr *table_sec;
          Elf_Internal_Shdr *table_sec;
 
 
          fputs ("@", stdout);
          fputs ("@", stdout);
          table = expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
          table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
          print_vma (table, PREFIX_HEX);
          print_vma (table, PREFIX_HEX);
          printf ("\n");
          printf ("\n");
 
 
          /* Locate the matching .ARM.extab.  */
          /* Locate the matching .ARM.extab.  */
          if (entry_addr.section != SHN_UNDEF
          if (entry_addr.section != SHN_UNDEF
Line 7063... Line 7138...
  arm_free_section (&exidx_arm_sec);
  arm_free_section (&exidx_arm_sec);
  arm_free_section (&extab_arm_sec);
  arm_free_section (&extab_arm_sec);
}
}
 
 
/* Used for both ARM and C6X unwinding tables.  */
/* Used for both ARM and C6X unwinding tables.  */
static int
 
 
static void
arm_process_unwind (FILE *file)
arm_process_unwind (FILE *file)
{
{
  struct arm_unw_aux_info aux;
  struct arm_unw_aux_info aux;
  Elf_Internal_Shdr *unwsec = NULL;
  Elf_Internal_Shdr *unwsec = NULL;
  Elf_Internal_Shdr *strsec;
  Elf_Internal_Shdr *strsec;
  Elf_Internal_Shdr *sec;
  Elf_Internal_Shdr *sec;
  unsigned long i;
  unsigned long i;
  unsigned int sec_type;
  unsigned int sec_type;
 
 
  memset (& aux, 0, sizeof (aux));
 
  aux.file = file;
 
 
 
  switch (elf_header.e_machine)
  switch (elf_header.e_machine)
    {
    {
    case EM_ARM:
    case EM_ARM:
      sec_type = SHT_ARM_EXIDX;
      sec_type = SHT_ARM_EXIDX;
      break;
      break;
Line 7087... Line 7160...
    case EM_TI_C6000:
    case EM_TI_C6000:
      sec_type = SHT_C6000_UNWIND;
      sec_type = SHT_C6000_UNWIND;
      break;
      break;
 
 
    default:
    default:
        abort();
      error (_("Unsupported architecture type %d encountered when processing unwind table"),
 
             elf_header.e_machine);
 
      return;
    }
    }
 
 
  if (string_table == NULL)
  if (string_table == NULL)
    return 1;
    return;
 
 
 
  memset (& aux, 0, sizeof (aux));
 
  aux.file = file;
 
 
  for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
  for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
    {
    {
      if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
      if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
        {
        {
Line 7109... Line 7187...
        }
        }
      else if (sec->sh_type == sec_type)
      else if (sec->sh_type == sec_type)
        unwsec = sec;
        unwsec = sec;
    }
    }
 
 
  if (!unwsec)
  if (unwsec == NULL)
    printf (_("\nThere are no unwind sections in this file.\n"));
    printf (_("\nThere are no unwind sections in this file.\n"));
 
  else
  for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
  for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
    {
    {
      if (sec->sh_type == sec_type)
      if (sec->sh_type == sec_type)
        {
        {
          printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
          printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
Line 7129... Line 7207...
 
 
  if (aux.symtab)
  if (aux.symtab)
    free (aux.symtab);
    free (aux.symtab);
  if (aux.strtab)
  if (aux.strtab)
    free ((char *) aux.strtab);
    free ((char *) aux.strtab);
 
 
  return 1;
 
}
}
 
 
static int
static void
process_unwind (FILE * file)
process_unwind (FILE * file)
{
{
  struct unwind_handler
  struct unwind_handler
  {
  {
    int machtype;
    int machtype;
    int (* handler)(FILE *);
    void (* handler)(FILE *);
  } handlers[] =
  } handlers[] =
  {
  {
    { EM_ARM, arm_process_unwind },
    { EM_ARM, arm_process_unwind },
    { EM_IA_64, ia64_process_unwind },
    { EM_IA_64, ia64_process_unwind },
    { EM_PARISC, hppa_process_unwind },
    { EM_PARISC, hppa_process_unwind },
Line 7151... Line 7227...
    { 0, 0 }
    { 0, 0 }
  };
  };
  int i;
  int i;
 
 
  if (!do_unwind)
  if (!do_unwind)
    return 1;
    return;
 
 
  for (i = 0; handlers[i].handler != NULL; i++)
  for (i = 0; handlers[i].handler != NULL; i++)
    if (elf_header.e_machine == handlers[i].machtype)
    if (elf_header.e_machine == handlers[i].machtype)
      return handlers[i].handler (file);
      return handlers[i].handler (file);
 
 
  printf (_("\nThere are no unwind sections in this file.\n"));
  printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
  return 1;
          get_machine_name (elf_header.e_machine));
}
}
 
 
static void
static void
dynamic_section_mips_val (Elf_Internal_Dyn * entry)
dynamic_section_mips_val (Elf_Internal_Dyn * entry)
{
{
  switch (entry->d_tag)
  switch (entry->d_tag)
    {
    {
    case DT_MIPS_FLAGS:
    case DT_MIPS_FLAGS:
      if (entry->d_un.d_val == 0)
      if (entry->d_un.d_val == 0)
        printf (_("NONE\n"));
        printf (_("NONE"));
      else
      else
        {
        {
          static const char * opts[] =
          static const char * opts[] =
          {
          {
            "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
            "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
Line 7188... Line 7264...
            if (entry->d_un.d_val & (1 << cnt))
            if (entry->d_un.d_val & (1 << cnt))
              {
              {
                printf ("%s%s", first ? "" : " ", opts[cnt]);
                printf ("%s%s", first ? "" : " ", opts[cnt]);
                first = 0;
                first = 0;
              }
              }
          puts ("");
 
        }
        }
      break;
      break;
 
 
    case DT_MIPS_IVERSION:
    case DT_MIPS_IVERSION:
      if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
      if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
        printf (_("Interface Version: %s\n"), GET_DYNAMIC_NAME (entry->d_un.d_val));
        printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
      else
      else
        printf (_("<corrupt: %ld>\n"), (long) entry->d_un.d_ptr);
        printf (_("<corrupt: %" BFD_VMA_FMT "d>"), entry->d_un.d_ptr);
      break;
      break;
 
 
    case DT_MIPS_TIME_STAMP:
    case DT_MIPS_TIME_STAMP:
      {
      {
        char timebuf[20];
        char timebuf[20];
Line 7209... Line 7284...
        time_t atime = entry->d_un.d_val;
        time_t atime = entry->d_un.d_val;
        tmp = gmtime (&atime);
        tmp = gmtime (&atime);
        snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
        snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
                  tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
                  tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
                  tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
                  tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
        printf (_("Time Stamp: %s\n"), timebuf);
        printf (_("Time Stamp: %s"), timebuf);
      }
      }
      break;
      break;
 
 
    case DT_MIPS_RLD_VERSION:
    case DT_MIPS_RLD_VERSION:
    case DT_MIPS_LOCAL_GOTNO:
    case DT_MIPS_LOCAL_GOTNO:
Line 7226... Line 7301...
    case DT_MIPS_DELTA_INSTANCE_NO:
    case DT_MIPS_DELTA_INSTANCE_NO:
    case DT_MIPS_DELTA_RELOC_NO:
    case DT_MIPS_DELTA_RELOC_NO:
    case DT_MIPS_DELTA_SYM_NO:
    case DT_MIPS_DELTA_SYM_NO:
    case DT_MIPS_DELTA_CLASSSYM_NO:
    case DT_MIPS_DELTA_CLASSSYM_NO:
    case DT_MIPS_COMPACT_SIZE:
    case DT_MIPS_COMPACT_SIZE:
      printf ("%ld\n", (long) entry->d_un.d_ptr);
      print_vma (entry->d_un.d_ptr, DEC);
      break;
      break;
 
 
    default:
    default:
      printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr);
      print_vma (entry->d_un.d_ptr, PREFIX_HEX);
    }
    }
 
    putchar ('\n');
}
}
 
 
static void
static void
dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
{
{
Line 8684... Line 8760...
                return "HP_STUB";
                return "HP_STUB";
            }
            }
 
 
          if (type == STT_GNU_IFUNC
          if (type == STT_GNU_IFUNC
              && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
              && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
 
                  || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
                  /* GNU is still using the default value 0.  */
                  /* GNU is still using the default value 0.  */
                  || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
                  || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
            return "IFUNC";
            return "IFUNC";
 
 
          snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
          snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
Line 12924... Line 13001...
        }
        }
 
 
      external = next;
      external = next;
 
 
      /* Prevent out-of-bounds indexing.  */
      /* Prevent out-of-bounds indexing.  */
      if (inote.namedata + inote.namesz >= (char *) pnotes + length
      if (inote.namedata + inote.namesz > (char *) pnotes + length
          || inote.namedata + inote.namesz < inote.namedata)
          || inote.namedata + inote.namesz < inote.namedata)
        {
        {
          warn (_("corrupt note found at offset %lx into core notes\n"),
          warn (_("corrupt note found at offset %lx into core notes\n"),
                (unsigned long) ((char *) external - (char *) pnotes));
                (unsigned long) ((char *) external - (char *) pnotes));
          warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
          warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
Line 12938... Line 13015...
 
 
      /* Verify that name is null terminated.  It appears that at least
      /* Verify that name is null terminated.  It appears that at least
         one version of Linux (RedHat 6.0) generates corefiles that don't
         one version of Linux (RedHat 6.0) generates corefiles that don't
         comply with the ELF spec by failing to include the null byte in
         comply with the ELF spec by failing to include the null byte in
         namesz.  */
         namesz.  */
      if (inote.namedata[inote.namesz] != '\0')
      if (inote.namedata[inote.namesz - 1] != '\0')
        {
        {
          temp = (char *) malloc (inote.namesz + 1);
          temp = (char *) malloc (inote.namesz + 1);
 
 
          if (temp == NULL)
          if (temp == NULL)
            {
            {
Line 13001... Line 13078...
  Elf_Internal_Shdr * section;
  Elf_Internal_Shdr * section;
  unsigned long i;
  unsigned long i;
  int res = 1;
  int res = 1;
 
 
  for (i = 0, section = section_headers;
  for (i = 0, section = section_headers;
       i < elf_header.e_shnum;
       i < elf_header.e_shnum && section != NULL;
       i++, section++)
       i++, section++)
    if (section->sh_type == SHT_NOTE)
    if (section->sh_type == SHT_NOTE)
      res &= process_corefile_note_segment (file,
      res &= process_corefile_note_segment (file,
                                            (bfd_vma) section->sh_offset,
                                            (bfd_vma) section->sh_offset,
                                            (bfd_vma) section->sh_size);
                                            (bfd_vma) section->sh_size);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.