/* libunwind - a platform-independent unwind library
   Copyright (C) 2002-2004 Hewlett-Packard Co
	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>

This file is part of libunwind.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */

/* This file defines the runtime-support routines for dynamically
generated code.  Even though it is implemented as part of libunwind,
it is logically separate from the interface to perform the actual
unwinding.  In particular, this interface is always used in the
context of the unwind target, whereas the rest of the unwind API is
used in context of the process that is doing the unwind (which may be
a debugger running on another machine, for example).

Note that the data-structures declared here server a dual purpose:
when a program registers a dynamically generated procedure, it uses
these structures directly.  On the other hand, with remote-unwinding,
the data-structures are read from the remote process's memory and
translated into internalized versions.  To facilitate remote-access,
the following rules should be followed in declaring these structures:

 (1) Declare a member as a pointer only if the the information the
     member points to needs to be internalized as well (e.g., a
     string representing a procedure name should be declared as
     "const char *", but the instruction pointer should be declared
     as unw_word_t).

 (2) Provide sufficient padding to ensure that no implicit padding
     will be needed on any of the supported target architectures.  For
     the time being, padding data structures with the assumption that
     sizeof (unw_word_t) == 8 should be sufficient.  (Note: it's not
     impossible to internalize structures with internal padding, but
     it does make the process a bit harder).

 (3) Don't declare members that contain bitfields or floating-point
     values.

 (4) Don't declare members with enumeration types.  Declare them as
     int32_t instead.  */

typedef enum
  {
    UNW_DYN_STOP = 0,		/* end-of-unwind-info marker */
    UNW_DYN_SAVE_REG,		/* save register to another register */
    UNW_DYN_SPILL_FP_REL,	/* frame-pointer-relative register spill */
    UNW_DYN_SPILL_SP_REL,	/* stack-pointer-relative register spill */
    UNW_DYN_ADD,		/* add constant value to a register */
    UNW_DYN_POP_FRAMES,		/* drop one or more stack frames */
    UNW_DYN_LABEL_STATE,	/* name the current state */
    UNW_DYN_COPY_STATE,		/* set the region's entry-state */
    UNW_DYN_ALIAS		/* get unwind info from an alias */
  }
unw_dyn_operation_t;

typedef enum
  {
    UNW_INFO_FORMAT_DYNAMIC,		/* unw_dyn_proc_info_t */
    UNW_INFO_FORMAT_TABLE,		/* unw_dyn_table_t */
    UNW_INFO_FORMAT_REMOTE_TABLE,	/* unw_dyn_remote_table_t */
    UNW_INFO_FORMAT_ARM_EXIDX		/* ARM specific unwind info */
  }
unw_dyn_info_format_t;

typedef struct unw_dyn_op
  {
    int8_t tag;				/* what operation? */
    int8_t qp;				/* qualifying predicate register */
    int16_t reg;			/* what register */
    int32_t when;			/* when does it take effect? */
    unw_word_t val;			/* auxiliary value */
  }
unw_dyn_op_t;

typedef struct unw_dyn_region_info
  {
    struct unw_dyn_region_info *next;	/* linked list of regions */
    int32_t insn_count;			/* region length (# of instructions) */
    uint32_t op_count;			/* length of op-array */
    unw_dyn_op_t op[1];			/* variable-length op-array */
  }
unw_dyn_region_info_t;

typedef struct unw_dyn_proc_info
  {
    unw_word_t name_ptr;	/* address of human-readable procedure name */
    unw_word_t handler;		/* address of personality routine */
    uint32_t flags;
    int32_t pad0;
    unw_dyn_region_info_t *regions;
  }
unw_dyn_proc_info_t;

typedef struct unw_dyn_table_info
  {
    unw_word_t name_ptr;	/* addr. of table name (e.g., library name) */
    unw_word_t segbase;		/* segment base */
    unw_word_t table_len;	/* must be a multiple of sizeof(unw_word_t)! */
    unw_word_t *table_data;
  }
unw_dyn_table_info_t;

typedef struct unw_dyn_remote_table_info
  {
    unw_word_t name_ptr;	/* addr. of table name (e.g., library name) */
    unw_word_t segbase;		/* segment base */
    unw_word_t table_len;	/* must be a multiple of sizeof(unw_word_t)! */
    unw_word_t table_data;
  }
unw_dyn_remote_table_info_t;

typedef struct unw_dyn_info
  {
    /* doubly-linked list of dyn-info structures: */
    struct unw_dyn_info *next;
    struct unw_dyn_info *prev;
    unw_word_t start_ip;	/* first IP covered by this entry */
    unw_word_t end_ip;		/* first IP NOT covered by this entry */
    unw_word_t gp;		/* global-pointer in effect for this entry */
    int32_t format;		/* real type: unw_dyn_info_format_t */
    int32_t pad;
    union
      {
	unw_dyn_proc_info_t pi;
	unw_dyn_table_info_t ti;
	unw_dyn_remote_table_info_t rti;
      }
    u;
  }
unw_dyn_info_t;

typedef struct unw_dyn_info_list
  {
    uint32_t version;
    uint32_t generation;
    unw_dyn_info_t *first;
  }
unw_dyn_info_list_t;

/* Return the size (in bytes) of an unw_dyn_region_info_t structure that can
   hold OP_COUNT ops.  */
#define _U_dyn_region_info_size(op_count)				\
	((char *) (((unw_dyn_region_info_t *) NULL)->op + (op_count))	\
	 - (char *) NULL)

/* Register the unwind info for a single procedure.
   This routine is NOT signal-safe.  */
extern void _U_dyn_register (unw_dyn_info_t *);

/* Cancel the unwind info for a single procedure.
   This routine is NOT signal-safe.  */
extern void _U_dyn_cancel (unw_dyn_info_t *);


/* Convenience routines.  */

#define _U_dyn_op(_tag, _qp, _when, _reg, _val)				\
	((unw_dyn_op_t) { (_tag), (_qp), (_reg), (_when), (_val) })

#define _U_dyn_op_save_reg(op, qp, when, reg, dst)			\
	(*(op) = _U_dyn_op (UNW_DYN_SAVE_REG, (qp), (when), (reg), (dst)))

#define _U_dyn_op_spill_fp_rel(op, qp, when, reg, offset)		\
	(*(op) = _U_dyn_op (UNW_DYN_SPILL_FP_REL, (qp), (when), (reg),	\
			    (offset)))

#define _U_dyn_op_spill_sp_rel(op, qp, when, reg, offset)		\
	(*(op) = _U_dyn_op (UNW_DYN_SPILL_SP_REL, (qp), (when), (reg),	\
			    (offset)))

#define _U_dyn_op_add(op, qp, when, reg, value)				\
	(*(op) = _U_dyn_op (UNW_DYN_ADD, (qp), (when), (reg), (value)))

#define _U_dyn_op_pop_frames(op, qp, when, num_frames)			\
	(*(op) = _U_dyn_op (UNW_DYN_POP_FRAMES, (qp), (when), 0, (num_frames)))

#define _U_dyn_op_label_state(op, label)				\
	(*(op) = _U_dyn_op (UNW_DYN_LABEL_STATE, _U_QP_TRUE, -1, 0, (label)))

#define _U_dyn_op_copy_state(op, label)					\
	(*(op) = _U_dyn_op (UNW_DYN_COPY_STATE, _U_QP_TRUE, -1, 0, (label)))

#define _U_dyn_op_alias(op, qp, when, addr)				\
	(*(op) = _U_dyn_op (UNW_DYN_ALIAS, (qp), (when), 0, (addr)))

#define _U_dyn_op_stop(op)						\
	(*(op) = _U_dyn_op (UNW_DYN_STOP, _U_QP_TRUE, -1, 0, 0))

/* The target-dependent qualifying predicate which is always TRUE.  On
   IA-64, that's p0 (0), on non-predicated architectures, the value is
   ignored.  */
#define _U_QP_TRUE	_U_TDEP_QP_TRUE
