unixdev.net


Switch to SpeakEasy.net DSL

The Modular Manual Browser

Home Page
Manual: (OSF1-V5.1-alpha)
Page:
Section:
Apropos / Subsearch:
optional field



pdsc(4)								      pdsc(4)



NAME

  pdsc.h - Defines structures describing procedures conforming to the Calling
  Standard for Alpha Systems .

SYNOPSIS

  #include <pdsc.h>

DESCRIPTION

  The pdsc.h header file defines two basic data	structures:  the code range
  descriptor (crd) and the run-time procedure descriptor (rpd).

  Code range descriptors associate a contiguous	sequence of addresses with a
  run-time procedure descriptor.  This mapping can be many-to-one.  Code
  range	descriptors support optimizations (for example,	reducing cache colli-
  sions) where all of the code for a procedure might not be contiguous.
  Run-time procedure descriptors provide unwind	and exception handler infor-
  mation about a procedure or part of a	procedure.  Several run-time pro-
  cedure descriptors might be needed if	a procedure has	multiple entry points
  (as in FORTRAN).

  Currently, one code range descriptor exists for each run-time	procedure
  descriptor.  The assembler creates both the crds and rpds.  Crds are stored
  alone	in address order in the	.pdata section of an object file.  Rpds	are
  stored along with language generated exception information in	the .xdata
  section of an	object file.

  The assembler	supports an .edata 0 directive to allow	the language or	user
  to enter information into the	.xdata section.

  The .end assembler directive,	which denotes the end of a procedure, tells
  the assembler	to generate the	crd and	rpd for	the ended procedure.

  The .xdata and .pdata	sections are coalesced in order	from multiple relo-
  catable objects and non-shared libraries by the linker into one large
  .xdata and one large .pdata section for each executable or shared object.
  The linker adds an extra element to the code range descriptors, whose
  address is one address beyond	the end	of the text segment.

  For a	diagram	of a code range	descriptor, see	the pdsc.h file.

  The begin_address field is shifted left 2 bits.  Its position	is relative
  to the beginning of the whole	code range descriptor table.  This shift
  enables a binary search of these addresses.  (If they	were self relative
  like rpd_offset, you have to calculate the actual address before being able
  to do	the compare.) This field definition restricts the code range to	be
  within 32 bits of the	code range descriptor table.  This field is the	first
  address of a code range. The begin_address of	the next crd is	one address
  beyond the bounds the	code range from	the top.  As stated above, the linker
  adds a last element.

  The rpd_offset is a self-relative field that points to the run-time pro-
  cedure descriptor entry for this code	range.	This field definition res-
  tricts the run-time procedure	descriptor to be within	32 bits	of the code
  range	descriptor table. The rpd_offset field might equal zero	if the pro-
  cedure is a null frame whose entry_ra	is $26 and contains no handler and
  PDSC_FLAGS_REGISTER_FRAME is set.  This condition implies no separate
  procedure descriptor.

  The prologue bit is set if the code range does not contain a prologue.
  This information is important	in determining which register to restore dur-
  ing an unwind	operation.

  All the structure definitions	have simple typedefs to	define the fields in
  case they need to have idfefs	processed to differentiate the code on the
  basis	of the hardware	architecture.  See the pdsc.h header file for their
  specific definitions.

  The pdsc.h header file provides a union that allows for accessing the	two
  main fields as 32 bit	items.	The header file	also provides macros to	help
  use those 32 bit items.  The union definition	for code range descriptors
  follows:

       /*
	* Runtime Code Range Descriptor
	*/
       typedef union pdsc_crd {
	   struct {
	       pdsc_offset   begin_address;
				  /* offst to 1st address in range */
	       pdsc_offset   rpd_offset;
				  /* offst to rpd including bits */
	   } words;
	   struct {
	       pdsc_mask   context_t:1;
				  /* flags to be used with no_prolog */
	       pdsc_mask   context_s:1;
				  /* to	determine actual meaning */
	       pdsc_offset shifted_begin_address:30; /*	shifted	left 2 */
	       pdsc_mask   no_prolog:1;		   /* flag */
	       pdsc_mask   memory_speculation:1;   /* flag */
	       pdsc_offset  shifted_rpd_offset:30; /* shifted left 2 */
	  } fields;
	} pdsc_crd;

  Run-time procedure descriptors come in a number of variations.  The Tru64
  UNIX operating system	supports a short form and a long form and each may or
  may not have handler information.  Tru64 UNIX	supports a short form (and
  the no procedure descriptor form mentioned in	the code range descriptors
  discussion) to minimize the space required for exception and unwind infor-
  mation.  Tru64 UNIX supports a long form for procedures whose	information
  overflows the	fields in the short form.

  Tru64	UNIX also supports register frames that	do not manifest	a stack	frame
  and may use temporary	registers to save the ra.  Manual collusion between a
  caller and callee is required	to support the use of temporary	registers for
  intrinsic and	library	functions to save the cost of stores and restores to
  and from memory.

  See the pdsc.h header	file for diagrams of the short and long	forms of the
  descriptors.

  The pdsc.h header file provides a union that embodies	the different options
  discussed above.  The	union definition for run-time procedure	descriptors
  is:


       typedef union pdsc_rpd {

	   struct pdsc_short_stack_rpd {
	       pdsc_uchar_mask flags:8;
				  /* information about frame */
	       pdsc_uchar_offset rsa_offset;
				  /* savregs offst in quadwords	*/
	       pdsc_uchar_mask	fmask:8;
				  /* floating point reg	mask */
	       pdsc_uchar_mask	imask:8;
				  /* integer register mask */
	       pdsc_count	frame_size:16;
				  /* frame size	in 64 bit words	*/
	       pdsc_offset  sp_set:8;
				  /* instofset to inst which sets sp */
	       pdsc_count entry_length:8;
				  /* # of insts	in prologue */
	   } short_stack_rpd;

	   struct pdsc_short_reg_rpd {
	       pdsc_uchar_mask	flags:8;
				  /* information about frame */
	       pdsc_space	reserved1:3;   /* must be zero */
	       pdsc_register	entry_ra:5;
				  /* what contains ra on entry */
	       pdsc_register	save_ra:5;
				  /* entry_ra here after the prologue */
	       pdsc_space	reserved2:11;  /* must be zero */
	       pdsc_count	frame_size:16;
				  /* frame size	in 64 bit words	*/
	       pdsc_offset	sp_set:8;
				  /* instofset to inst which sets sp */
	       pdsc_count	entry_length:8;
				  /* # of insts	in prologue */
	   } short_reg_rpd;

	   struct pdsc_long_stack_rpd {
	       pdsc_mask	flags:11;
				  /* information about frame */
	       pdsc_register	entry_ra:5;
				  /* where ret pc is on	entry */
	       pdsc_ushort_offset rsa_offset;
				  /* saveregs offst in quadwords */
	       pdsc_count	sp_set:16;
				  /* instofset to inst which sets sp */
	       pdsc_count	entry_length:16;
				  /* # of insts	in prologue */
	       pdsc_count	frame_size;
				  /* frame size	in quadwords */
	       pdsc_mask	reserved:2;	 /* must be zero */
	       pdsc_offset	return_address:30;
				  /* offset from base to return	for
				     inserted code */
	       pdsc_mask	imask;
				  /* integer register mask */
	       pdsc_mask	fmask;
				  /* floating point register mask */
	   } long_stack_rpd;

	   struct pdsc_long_reg_rpd {

	       pdsc_mask	flags:11;
				  /* information about frame */
	       pdsc_register	entry_ra:5;
				  /* where ret pc is on	entry */
	       pdsc_register	save_ra:5;
				  /* we	moved entry_ra in the prologue */
	       pdsc_space	reserved1:11;  /* must be zero */
	       pdsc_count	sp_set:16;
				  /* instofset to inst which sets sp */
	       pdsc_count	entry_length:16;
				  /* # of insts	in prologue */
	       pdsc_count	frame_size;
				  /* frame size	in quadwords */
	       pdsc_mask	reserved:2;	/* must	be zero	*/
	       pdsc_offset	return_address:30;
				  /* offset from base to return	for
				     inserted code */
	       pdsc_mask	imask;
				  /* integer register mask */
	       pdsc_mask	fmask;
				  /* floating point register mask */
	   } long_reg_rpd;

	   struct pdsc_short_with_handler {
	       union {
	       struct pdsc_short_stack_rpd  short_stack_rpd;
				  /* base stack	rpd */
	       struct pdsc_short_reg_rpd    short_reg_rpd;
				  /* base stack	rpd */
	       } stack_or_reg;
	       pdsc_address	handler;
				  /* optional handler address */
	       pdsc_address	handler_data;
				  /* optional handler data */
	   } short_with_handler;

	   struct pdsc_long_with_handler {
	       union {
	       struct pdsc_long_stack_rpd  long_stack_rpd;
				  /* base stack	rpd */
	       struct pdsc_long_reg_rpd	   long_reg_rpd;
				  /* base stack	rpd */
	       } stack_or_reg;
	       pdsc_address	handler;
				  /* optional handler address */
	       pdsc_address	handler_data;
				  /* optional handler data */
	   } long_with_handler;

       } pdsc_rpd;		  /* runtime procedure descriptor */


  As noted in the preceding code fragment, the flags field is a	different
  length depending on whether a	long or	short descriptor is used.  Conse-
  quently, the most used flags are grouped together so that they fit in	the
  short	frame.

  Use the PDSC_FLAGS_EXCEPTION_FRAME flag to trace back	over signal frames.

  The PDSC_FLAGS_EXTENDER flag is not yet implemented and is reserved

  The header file defines a set	of macros that easily enable users to access
  fields.  Some	macros provide support so users	do not have to know whether
  they are using a short or long descriptor or even a stack frame as opposed
  to a register	frame.	The header file	will also normalize the	fields
  between descriptor types (for	example, the register mask will	be expanded
  to 32	bits).

  A null value for the rpd argument can	cause some of the macros to provide
  the default values.  This provision of default values	supports the case
  where	the pdsc_crd does not point at any rpd and is denoted by No rpd.

  In the following table, each macro carries a PDSC_ prefix, which is omitted
  in the table to conserve space.  Where there is no default value (such as
  for a	handler), a zero (0) is	returned when the value	is not present.	 In
  the second column, Support, N	means no rpd, S	means support for stack, R
  means	support	for register, H	means support for short, and L means support
  for long.

  _____________________________________________________________________________
  PDSC_	Macro		       Support	 Arg	   Comments
  _____________________________________________________________________________
  SHORT_RPD_SIZE			 None	   Size	of a short without
						   handler information.

  LONG_RPD_SIZE				 None	   Size	of a long without
						   handler information.

  DEFAULT_ENTRY_RA			 None	   $26,	the default return
						   address register.

  RPD_SHORT		       SRHL	 &rpd	   1 if	it is a	short rpd;
						   otherwise 0.

  RPD_REGISTER		       SRHL	 &rpd	   1 if	it is a	register frame;
						   otherwise 0.

  RPD_HAS_HANDLER	       SRHL	 &rpd	   1 if	there is handler
						   information;	otherwise 0.

  RPD_FLAGS		       SRHL	 &rpd	   Flags field.

  RPD_RSA_OFFSET_FIELD	       NSRHL	 &rpd	   rsa_offset field value.

  RPD_RSA_OFFSET	       NSRHL	 &rpd	   rsa_offset in bytes.

  RPD_SAVE_RA		       NSRHL	 &rpd	   save	ra register.

  RPD_ENTRY_RA		       NSRHL	 &rpd	   entry ra register.

  RPD_SIZE_FIELD	       NSRHL	 &rpd	   frame_size field value.

  RPD_SIZE		       NSRHL	 &rpd	   Frame size in bytes.

  RPD_SP_SET_FIELD	       NSRHL	 &rpd	   sp_set field	value.

  RPD_SP_SET		       NSHRL	 &rpd	   sp_set offset in bytes.

  RPD_ENTRY_LENGTH_FIELD       NSHRL	 &rpd	   entry_length
						   field value.

  RPD_ENTRY_LENGTH	       NSHRL	 &rpd	   Prologue size in bytes.

  RPD_IMASK		       NSHRL	 &rpd	   32 bit saved	int
						   register mask.

  RPD_FMASK		       NSHRL	 &rpd	   32 bit saved	fp
						   register mask.

  RPD_HANDLER		       NSHRL	 &rpd	   Handler address.

  RPD_HANDLER_DATA	       NSHRL	 &rpd	   Handler data	address.

  RPD_RETURN_ADDRESS_FIELD     SRL	 &rpd	   Return address field	value.



  RPD_RETURN_ADDRESS	       SRL

					 &.pdata
					 &rpd


						   The return address for an
						   inserted code range.

  CRD_OFFSET_MASK			 none	   Masks off the lsb two bits.

  CRD_NO_PROLOG_MASK			 none	   Masks all but the lsb bit.

  CRD_PRPD				 &crd	   Pointer to the rpd for
						   this	crd.

  CRD_CONTAINS_PROLOG			 &crd	   1 if	it does;
						   0 if	not.

  CRD_BEGIN_ADRESS_FIELD		 &crd	   Begin address field value.

  CRD_BEGIN_ADDRESS			 &.pdata   ptr to the first address
						   in the code range.
					 &crd

  CRD_TYPE_STANDARD			 &crd

						   1 if	this is	a standard type
						   code	range descriptor; 0 if
						   not.

  CRD_TYPE_CONTEXT			 &crd

						   1 if	this is	a context type
						   code	range descriptor that
						   does	not contain the	pro-
						   cedure prolog; 0 if not.

  CRD_TYPE_DATA				 &crd

						   1 if	the code range descrip-
						   tor describes data that
						   resides within the text
						   area; 0 if not.

  CRD_TYPE_NON_CONTEXT			 &crd

						   1 if	the code range is not
						   in a	routine	context, and it
						   does	not contain a stack
						   allocation that needs to be
						   deallocated;	0 if not.

  CRD_TYPE_NON_CONTEXT_STACK		 &crd

						   1 if	the code range is a
						   non-context region for
						   exception handling, and it
						   contains a stack allocation;
						   0 if	not.

  INST_OFFSET_SHIFT				   Amounts to << insts to
						   a get # of bytes.

  FRAME_SIZE_SHIFT				   Amounts to << frame siz
						   to a	get # of bytes

  SHORT_RPD_IMASK_SHIFT				   Amounts to << short imsk
						   to the position bits.

  SHORT_RPD_FMASK_SHIFT				   Amounts to << short fmsk
						   to the position bits.
  _____________________________________________________________________________

RELATED	INFORMATION

  exception_intro(3)