os/kernelhwsrv/kernel/eka/compsupp/symaehabi/symbian_support.h
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kernel/eka/compsupp/symaehabi/symbian_support.h	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,205 @@
     1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "ARM EABI LICENCE.txt"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// in kernel/eka/compsupp.
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// e32/compsupp/symaehabi/symbian_support.h
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +
    1.22 +#ifndef SYMBIAN_SUPPORT_H
    1.23 +#define SYMBIAN_SUPPORT_H
    1.24 +
    1.25 +#include <e32def_private.h>
    1.26 +
    1.27 +#ifdef __cplusplus
    1.28 +typedef _Unwind_Control_Block UCB;
    1.29 +
    1.30 +using std::terminate_handler;
    1.31 +using std::unexpected_handler;
    1.32 +using std::terminate;
    1.33 +using std::unexpected;
    1.34 +using std::type_info;
    1.35 +
    1.36 +/* --------- Exception control object: --------- */
    1.37 +
    1.38 +// Type __cxa_exception is the combined C++ housekeeping (LEO) and UCB.
    1.39 +// It will be followed by the user exception object, hence must ensure
    1.40 +// the latter is aligned on an 8 byte boundary.
    1.41 +
    1.42 +struct __cxa_exception {
    1.43 +  const type_info *exceptionType;       // RTTI object describing the type of the exception
    1.44 +  void *(*exceptionDestructor)(void *); // Destructor for the exception object (may be NULL)
    1.45 +  unexpected_handler unexpectedHandler; // Handler in force after evaluating throw expr
    1.46 +  terminate_handler terminateHandler;   // Handler in force after evaluating throw expr
    1.47 +  __cxa_exception *nextCaughtException; // Chain of "currently caught" c++ exception objects
    1.48 +  uint32_t handlerCount;                // Count of how many handlers this EO is "caught" in
    1.49 +  __cxa_exception *nextPropagatingException; // Chain of objects saved over cleanup
    1.50 +  uint32_t propagationCount;            // Count of live propagations (throws) of this EO
    1.51 +  UCB ucb;                              // Forces alignment of next item to 8-byte boundary
    1.52 +};
    1.53 +
    1.54 +
    1.55 +// Exceptions global support
    1.56 +typedef void (*handler)(void);
    1.57 +
    1.58 +struct __cxa_eh_globals {
    1.59 +  uint32_t uncaughtExceptions;               // counter
    1.60 +  unexpected_handler unexpectedHandler;      // per-thread handler
    1.61 +  terminate_handler terminateHandler;        // per-thread handler
    1.62 +  bool implementation_ever_called_terminate; // true if it ever did
    1.63 +  handler call_hook;     // transient field to tell terminate/unexpected which hook to call
    1.64 +  __cxa_exception *caughtExceptions;         // chain of "caught" exceptions
    1.65 +  __cxa_exception *propagatingExceptions;    // chain of "propagating" (in cleanup) exceptions
    1.66 +  void *emergency_buffer;                    // emergency buffer for when rest of heap full
    1.67 +};
    1.68 +
    1.69 +// emergency storage reserve primarily for throwing OOM exceptions
    1.70 +struct emergency_eco {
    1.71 +  __cxa_exception ep;
    1.72 +    XLeaveException aUserLeaveException;
    1.73 +};
    1.74 +
    1.75 +struct emergency_buffer {
    1.76 +  bool inuse;
    1.77 +  struct emergency_eco eco;
    1.78 +};
    1.79 +
    1.80 +
    1.81 +class TCppRTExceptionsGlobals
    1.82 +	{
    1.83 +public:
    1.84 +	IMPORT_C TCppRTExceptionsGlobals();
    1.85 +private:
    1.86 +	__cxa_eh_globals thread_globals;
    1.87 +	emergency_buffer buffer;
    1.88 +	};
    1.89 +
    1.90 +#endif
    1.91 +
    1.92 +// Support for finding ROM resident ExIdx tables
    1.93 +#define GET_ROM_EST(u) ((TRomExceptionSearchTable *)((u)->unwinder_cache.reserved4))
    1.94 +#define SET_ROM_EST(u,e) ((TRomExceptionSearchTable *)((u)->unwinder_cache.reserved4=(uint32_t)e))
    1.95 +#define GET_EXCEPTION_DESCRIPTOR(u) ((TExceptionDescriptor *)((u)->unwinder_cache.reserved5))
    1.96 +#define SET_EXCEPTION_DESCRIPTOR(u,e) ((TExceptionDescriptor *)((u)->unwinder_cache.reserved5=(uint32_t)e))
    1.97 +
    1.98 +// Support for checking which version of EHABI is in play
    1.99 +#define EHABI_MASK 0xfffffffc
   1.100 +// Checks if image implements V2 of EHABI
   1.101 +#define EHABI_V2(u) ((GET_EXCEPTION_DESCRIPTOR(u)->iROSegmentBase) & 1)
   1.102 +#define GET_RO_BASE(u) (((u)->iROSegmentBase) & EHABI_MASK)
   1.103 +#define ADDRESS_IN_EXCEPTION_DESCRIPTOR_RANGE(addr, aEDp) (((addr) >= GET_RO_BASE(aEDp)) && ((addr) < (aEDp)->iROSegmentLimit))
   1.104 +#define GET_EST_FENCEPOST(aESTp) ((aESTp)->iEntries[(aESTp)->iNumEntries])
   1.105 +#define ADDRESS_IN_ROM_EST(addr, aESTp) (((addr) >= (aESTp)->iEntries[0]) && ((addr) < GET_EST_FENCEPOST((aESTp))))
   1.106 +
   1.107 +
   1.108 +// Non __EPOC32__ versions defined in unwinder.c
   1.109 +#define EIT_base(u) \
   1.110 +    ((const __EIT_entry *)((GET_EXCEPTION_DESCRIPTOR(u))->iExIdxBase))
   1.111 +#define EIT_limit(u) \
   1.112 +    ((const __EIT_entry *)((GET_EXCEPTION_DESCRIPTOR(u))->iExIdxLimit))
   1.113 +
   1.114 +
   1.115 +#ifdef __cplusplus
   1.116 +extern "C" {
   1.117 +#endif
   1.118 +
   1.119 +typedef unsigned int size_t;
   1.120 +IMPORT_C void abort(void);
   1.121 +int typenameeq(const char * n1, const char * n2);
   1.122 +
   1.123 +#define malloc User::Alloc
   1.124 +#define free User::Free
   1.125 +
   1.126 +
   1.127 +#ifdef _DEBUG
   1.128 +// uncomment this for diagnostic output in UDEB build
   1.129 +//#define _DEBUG_SYMBIAN_EH_SUPPORT
   1.130 +#endif
   1.131 +
   1.132 +#ifdef _DEBUG_SYMBIAN_EH_SUPPORT
   1.133 +#define VRS_DIAGNOSTICS
   1.134 +#define UNWIND_ACTIVITY_DIAGNOSTICS
   1.135 +#define PR_DIAGNOSTICS
   1.136 +#define PRINTED_DIAGNOSTICS
   1.137 +#define CPP_DIAGNOSTICS
   1.138 +#endif
   1.139 +#define printf DebugPrintf
   1.140 +extern void DebugPrintf(const char *, ...);
   1.141 +
   1.142 +#ifdef _DEBUG_SYMBIAN_EH_SUPPORT
   1.143 +#define SYMBIAN_EH_SUPPORT_PRINTF DebugPrintf
   1.144 +#else
   1.145 +#define SYMBIAN_EH_SUPPORT_PRINTF (void)
   1.146 +#pragma diag_suppress 174
   1.147 +#endif
   1.148 +
   1.149 +void InitialiseSymbianSpecificUnwinderCache(uint32_t addr, _Unwind_Control_Block * ucbp);
   1.150 +TExceptionDescriptor * ReLoadExceptionDescriptor(uint32_t addr,_Unwind_Control_Block * ucbp);
   1.151 +
   1.152 +/* Functions used to convert between segment-relative offsets
   1.153 + * and absolute addresses. These are only used in unwinder.c and must be
   1.154 + * compilable by a C compiler.
   1.155 + */
   1.156 +
   1.157 +static __inline void ValidateExceptionDescriptor(uint32_t addr, _Unwind_Control_Block * ucbp)
   1.158 +{
   1.159 +  // On entry assume ROM exception search table and exception descriptor for current frame cached in ucbp
   1.160 +  
   1.161 +  // see if addr is in current exception descriptor range
   1.162 +  TExceptionDescriptor * aEDp = GET_EXCEPTION_DESCRIPTOR(ucbp);
   1.163 +  if (!ADDRESS_IN_EXCEPTION_DESCRIPTOR_RANGE(addr, aEDp)) {
   1.164 +    aEDp = ReLoadExceptionDescriptor(addr, ucbp);
   1.165 +    // If there's no valid exception descriptor abort.
   1.166 +    if (!aEDp) {
   1.167 +#ifdef _DEBUG
   1.168 +      DebugPrintf("EH ERROR: no exception descriptor for address 0x%08x\n", addr);
   1.169 +      DEBUGGER_BOTTLENECK(ucbp, _UASUBSYS_UNWINDER, _UAACT_ENDING, _UAARG_ENDING_UNWINDER_LOOKUPFAILED);
   1.170 +#endif
   1.171 +      abort();
   1.172 +    }
   1.173 +  }
   1.174 +}
   1.175 +
   1.176 +static __inline uint32_t addr_to_ER_RO_offset(uint32_t addr, _Unwind_Control_Block * ucbp)
   1.177 +{
   1.178 +  TExceptionDescriptor * aEDp = GET_EXCEPTION_DESCRIPTOR(ucbp);
   1.179 +  // assume ucbp has the correct exception descriptor for this offset
   1.180 +  return addr - GET_RO_BASE(aEDp);
   1.181 +}
   1.182 +
   1.183 +static __inline uint32_t ER_RO_offset_to_addr(uint32_t offset, _Unwind_Control_Block * ucbp)
   1.184 +{
   1.185 +  TExceptionDescriptor * aEDp = GET_EXCEPTION_DESCRIPTOR(ucbp);
   1.186 +  // assume ucbp has the correct exception descriptor for this offset
   1.187 +  return offset + GET_RO_BASE(aEDp);
   1.188 +}
   1.189 +
   1.190 +// This must be the same as the version in unwinder.c. However its structure is 
   1.191 +// governed by the EHABI and so it shouldn't change anytime soon.
   1.192 +typedef struct __EIT_entry {
   1.193 +  uint32_t fnoffset; /* Place-relative */
   1.194 +  uint32_t content;
   1.195 +} __EIT_entry;
   1.196 +
   1.197 +// The Symbian unwinder uses these specific search functions rather than the generic bsearch
   1.198 +// to find entries in the exception index table
   1.199 +const __EIT_entry *SearchEITV1(uint32_t return_address_offset, const __EIT_entry *base, unsigned int nelems);
   1.200 +__EIT_entry *SearchEITV2(uint32_t return_address, const __EIT_entry *base, unsigned int nelems);
   1.201 +
   1.202 +
   1.203 +#ifdef __cplusplus
   1.204 +}
   1.205 +#endif
   1.206 +
   1.207 +#endif // SYMBIAN_SUPPORT_H
   1.208 +