⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ieee.c

📁 java 反射机制详解示例,实现类属性及方法修改
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ieee.c -- Read and write IEEE-695 debugging information.
   Copyright 1996, 1998, 2000, 2001 Free Software Foundation, Inc.
   Written by Ian Lance Taylor <ian@cygnus.com>.

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.  */

/* This file reads and writes IEEE-695 debugging information.  */

#include <stdio.h>
#include <assert.h>

#include <bfd.h>
#include "ieee.h"
#include "bucomm.h"
#include <libiberty.h>
#include "debug.h"
#include "budbg.h"
#include "filenames.h"

/* This structure holds an entry on the block stack.  */

struct ieee_block
{
  /* The kind of block.  */
  int kind;
  /* The source file name, for a BB5 block.  */
  const char *filename;
  /* The index of the function type, for a BB4 or BB6 block.  */
  unsigned int fnindx;
  /* True if this function is being skipped.  */
  bfd_boolean skip;
};

/* This structure is the block stack.  */

#define BLOCKSTACK_SIZE (16)

struct ieee_blockstack
{
  /* The stack pointer.  */
  struct ieee_block *bsp;
  /* The stack.  */
  struct ieee_block stack[BLOCKSTACK_SIZE];
};

/* This structure holds information for a variable.  */

struct ieee_var
{
  /* Start of name.  */
  const char *name;
  /* Length of name.  */
  unsigned long namlen;
  /* Type.  */
  debug_type type;
  /* Slot if we make an indirect type.  */
  debug_type *pslot;
  /* Kind of variable or function.  */
  enum
    {
      IEEE_UNKNOWN,
      IEEE_EXTERNAL,
      IEEE_GLOBAL,
      IEEE_STATIC,
      IEEE_LOCAL,
      IEEE_FUNCTION
    } kind;
};

/* This structure holds all the variables.  */

struct ieee_vars
{
  /* Number of slots allocated.  */
  unsigned int alloc;
  /* Variables.  */
  struct ieee_var *vars;
};

/* This structure holds information for a type.  We need this because
   we don't want to represent bitfields as real types.  */

struct ieee_type
{
  /* Type.  */
  debug_type type;
  /* Slot if this is type is referenced before it is defined.  */
  debug_type *pslot;
  /* Slots for arguments if we make indirect types for them.  */
  debug_type *arg_slots;
  /* If this is a bitfield, this is the size in bits.  If this is not
     a bitfield, this is zero.  */
  unsigned long bitsize;
};

/* This structure holds all the type information.  */

struct ieee_types
{
  /* Number of slots allocated.  */
  unsigned int alloc;
  /* Types.  */
  struct ieee_type *types;
  /* Builtin types.  */
#define BUILTIN_TYPE_COUNT (60)
  debug_type builtins[BUILTIN_TYPE_COUNT];
};

/* This structure holds a linked last of structs with their tag names,
   so that we can convert them to C++ classes if necessary.  */

struct ieee_tag
{
  /* Next tag.  */
  struct ieee_tag *next;
  /* This tag name.  */
  const char *name;
  /* The type of the tag.  */
  debug_type type;
  /* The tagged type is an indirect type pointing at this slot.  */
  debug_type slot;
  /* This is an array of slots used when a field type is converted
     into a indirect type, in case it needs to be later converted into
     a reference type.  */
  debug_type *fslots;
};

/* This structure holds the information we pass around to the parsing
   functions.  */

struct ieee_info
{
  /* The debugging handle.  */
  PTR dhandle;
  /* The BFD.  */
  bfd *abfd;
  /* The start of the bytes to be parsed.  */
  const bfd_byte *bytes;
  /* The end of the bytes to be parsed.  */
  const bfd_byte *pend;
  /* The block stack.  */
  struct ieee_blockstack blockstack;
  /* Whether we have seen a BB1 or BB2.  */
  bfd_boolean saw_filename;
  /* The variables.  */
  struct ieee_vars vars;
  /* The global variables, after a global typedef block.  */
  struct ieee_vars *global_vars;
  /* The types.  */
  struct ieee_types types;
  /* The global types, after a global typedef block.  */
  struct ieee_types *global_types;
  /* The list of tagged structs.  */
  struct ieee_tag *tags;
};

/* Basic builtin types, not including the pointers.  */

enum builtin_types
{
  builtin_unknown = 0,
  builtin_void = 1,
  builtin_signed_char = 2,
  builtin_unsigned_char = 3,
  builtin_signed_short_int = 4,
  builtin_unsigned_short_int = 5,
  builtin_signed_long = 6,
  builtin_unsigned_long = 7,
  builtin_signed_long_long = 8,
  builtin_unsigned_long_long = 9,
  builtin_float = 10,
  builtin_double = 11,
  builtin_long_double = 12,
  builtin_long_long_double = 13,
  builtin_quoted_string = 14,
  builtin_instruction_address = 15,
  builtin_int = 16,
  builtin_unsigned = 17,
  builtin_unsigned_int = 18,
  builtin_char = 19,
  builtin_long = 20,
  builtin_short = 21,
  builtin_unsigned_short = 22,
  builtin_short_int = 23,
  builtin_signed_short = 24,
  builtin_bcd_float = 25
};

/* These are the values found in the derivation flags of a 'b'
   component record of a 'T' type extension record in a C++ pmisc
   record.  These are bitmasks.  */

/* Set for a private base class, clear for a public base class.
   Protected base classes are not supported.  */
#define BASEFLAGS_PRIVATE (0x1)
/* Set for a virtual base class.  */
#define BASEFLAGS_VIRTUAL (0x2)
/* Set for a friend class, clear for a base class.  */
#define BASEFLAGS_FRIEND (0x10)

/* These are the values found in the specs flags of a 'd', 'm', or 'v'
   component record of a 'T' type extension record in a C++ pmisc
   record.  The same flags are used for a 'M' record in a C++ pmisc
   record.  */

/* The lower two bits hold visibility information.  */
#define CXXFLAGS_VISIBILITY (0x3)
/* This value in the lower two bits indicates a public member.  */
#define CXXFLAGS_VISIBILITY_PUBLIC (0x0)
/* This value in the lower two bits indicates a private member.  */
#define CXXFLAGS_VISIBILITY_PRIVATE (0x1)
/* This value in the lower two bits indicates a protected member.  */
#define CXXFLAGS_VISIBILITY_PROTECTED (0x2)
/* Set for a static member.  */
#define CXXFLAGS_STATIC (0x4)
/* Set for a virtual override.  */
#define CXXFLAGS_OVERRIDE (0x8)
/* Set for a friend function.  */
#define CXXFLAGS_FRIEND (0x10)
/* Set for a const function.  */
#define CXXFLAGS_CONST (0x20)
/* Set for a volatile function.  */
#define CXXFLAGS_VOLATILE (0x40)
/* Set for an overloaded function.  */
#define CXXFLAGS_OVERLOADED (0x80)
/* Set for an operator function.  */
#define CXXFLAGS_OPERATOR (0x100)
/* Set for a constructor or destructor.  */
#define CXXFLAGS_CTORDTOR (0x400)
/* Set for a constructor.  */
#define CXXFLAGS_CTOR (0x200)
/* Set for an inline function.  */
#define CXXFLAGS_INLINE (0x800)

/* Local functions.  */

static void ieee_error
  PARAMS ((struct ieee_info *, const bfd_byte *, const char *));
static void ieee_eof PARAMS ((struct ieee_info *));
static char *savestring PARAMS ((const char *, unsigned long));
static bfd_boolean ieee_read_number
  PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
static bfd_boolean ieee_read_optional_number
  PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *, bfd_boolean *));
static bfd_boolean ieee_read_id
  PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
	   unsigned long *));
static bfd_boolean ieee_read_optional_id
  PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
	   unsigned long *, bfd_boolean *));
static bfd_boolean ieee_read_expression
  PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
static debug_type ieee_builtin_type
  PARAMS ((struct ieee_info *, const bfd_byte *, unsigned int));
static bfd_boolean ieee_alloc_type
  PARAMS ((struct ieee_info *, unsigned int, bfd_boolean));
static bfd_boolean ieee_read_type_index
  PARAMS ((struct ieee_info *, const bfd_byte **, debug_type *));
static int ieee_regno_to_genreg PARAMS ((bfd *, int));
static int ieee_genreg_to_regno PARAMS ((bfd *, int));
static bfd_boolean parse_ieee_bb PARAMS ((struct ieee_info *, const bfd_byte **));
static bfd_boolean parse_ieee_be PARAMS ((struct ieee_info *, const bfd_byte **));
static bfd_boolean parse_ieee_nn PARAMS ((struct ieee_info *, const bfd_byte **));
static bfd_boolean parse_ieee_ty PARAMS ((struct ieee_info *, const bfd_byte **));
static bfd_boolean parse_ieee_atn PARAMS ((struct ieee_info *, const bfd_byte **));
static bfd_boolean ieee_read_cxx_misc
  PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
static bfd_boolean ieee_read_cxx_class
  PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
static bfd_boolean ieee_read_cxx_defaults
  PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
static bfd_boolean ieee_read_reference
  PARAMS ((struct ieee_info *, const bfd_byte **));
static bfd_boolean ieee_require_asn
  PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
static bfd_boolean ieee_require_atn65
  PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
	   unsigned long *));

/* Report an error in the IEEE debugging information.  */

static void
ieee_error (info, p, s)
     struct ieee_info *info;
     const bfd_byte *p;
     const char *s;
{
  if (p != NULL)
    fprintf (stderr, "%s: 0x%lx: %s (0x%x)\n", bfd_get_filename (info->abfd),
	     (unsigned long) (p - info->bytes), s, *p);
  else
    fprintf (stderr, "%s: %s\n", bfd_get_filename (info->abfd), s);
}

/* Report an unexpected EOF in the IEEE debugging information.  */

static void
ieee_eof (info)
     struct ieee_info *info;
{
  ieee_error (info, (const bfd_byte *) NULL,
	      _("unexpected end of debugging information"));
}

/* Save a string in memory.  */

static char *
savestring (start, len)
     const char *start;
     unsigned long len;
{
  char *ret;

  ret = (char *) xmalloc (len + 1);
  memcpy (ret, start, len);
  ret[len] = '\0';
  return ret;
}

/* Read a number which must be present in an IEEE file.  */

static bfd_boolean
ieee_read_number (info, pp, pv)
     struct ieee_info *info;
     const bfd_byte **pp;
     bfd_vma *pv;
{
  return ieee_read_optional_number (info, pp, pv, (bfd_boolean *) NULL);
}

/* Read a number in an IEEE file.  If ppresent is not NULL, the number
   need not be there. */

static bfd_boolean
ieee_read_optional_number (info, pp, pv, ppresent)
     struct ieee_info *info;
     const bfd_byte **pp;
     bfd_vma *pv;
     bfd_boolean *ppresent;
{
  ieee_record_enum_type b;

  if (*pp >= info->pend)
    {
      if (ppresent != NULL)
	{
	  *ppresent = false;
	  return true;
	}
      ieee_eof (info);
      return false;
    }

  b = (ieee_record_enum_type) **pp;
  ++*pp;

  if (b <= ieee_number_end_enum)
    {
      *pv = (bfd_vma) b;
      if (ppresent != NULL)
	*ppresent = true;
      return true;
    }

  if (b >= ieee_number_repeat_start_enum && b <= ieee_number_repeat_end_enum)
    {
      unsigned int i;

      i = (int) b - (int) ieee_number_repeat_start_enum;
      if (*pp + i - 1 >= info->pend)
	{
	  ieee_eof (info);
	  return false;
	}

      *pv = 0;
      for (; i > 0; i--)
	{
	  *pv <<= 8;
	  *pv += **pp;
	  ++*pp;
	}

      if (ppresent != NULL)
	*ppresent = true;

      return true;
    }

  if (ppresent != NULL)
    {
      --*pp;
      *ppresent = false;
      return true;
    }

  ieee_error (info, *pp - 1, _("invalid number"));
  return false;
}

/* Read a required string from an IEEE file.  */

static bfd_boolean
ieee_read_id (info, pp, pname, pnamlen)
     struct ieee_info *info;
     const bfd_byte **pp;
     const char **pname;
     unsigned long *pnamlen;
{
  return ieee_read_optional_id (info, pp, pname, pnamlen, (bfd_boolean *) NULL);
}

/* Read a string from an IEEE file.  If ppresent is not NULL, the
   string is optional.  */

static bfd_boolean
ieee_read_optional_id (info, pp, pname, pnamlen, ppresent)
     struct ieee_info *info;
     const bfd_byte **pp;
     const char **pname;
     unsigned long *pnamlen;
     bfd_boolean *ppresent;
{
  bfd_byte b;
  unsigned long len;

  if (*pp >= info->pend)
    {
      ieee_eof (info);
      return false;
    }

  b = **pp;
  ++*pp;

  if (b <= 0x7f)
    len = b;
  else if ((ieee_record_enum_type) b == ieee_extension_length_1_enum)
    {
      len = **pp;
      ++*pp;
    }
  else if ((ieee_record_enum_type) b == ieee_extension_length_2_enum)
    {
      len = (**pp << 8) + (*pp)[1];
      *pp += 2;
    }
  else
    {
      if (ppresent != NULL)
	{
	  --*pp;
	  *ppresent = false;
	  return true;
	}
      ieee_error (info, *pp - 1, _("invalid string length"));
      return false;
    }

  if ((unsigned long) (info->pend - *pp) < len)
    {
      ieee_eof (info);
      return false;
    }

  *pname = (const char *) *pp;
  *pnamlen = len;
  *pp += len;

  if (ppresent != NULL)
    *ppresent = true;

  return true;
}

/* Read an expression from an IEEE file.  Since this code is only used
   to parse debugging information, I haven't bothered to write a full
   blown IEEE expression parser.  I've only thrown in the things I've
   seen in debugging information.  This can be easily extended if
   necessary.  */

static bfd_boolean
ieee_read_expression (info, pp, pv)
     struct ieee_info *info;
     const bfd_byte **pp;
     bfd_vma *pv;
{
  const bfd_byte *expr_start;
#define EXPR_STACK_SIZE (10)
  bfd_vma expr_stack[EXPR_STACK_SIZE];
  bfd_vma *esp;

  expr_start = *pp;

  esp = expr_stack;

  while (1)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -