os/kernelhwsrv/kernel/eka/compsupp/symaehabi/symbian_support.h
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "ARM EABI LICENCE.txt"
     5 // which accompanies this distribution, and is available
     6 // in kernel/eka/compsupp.
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32/compsupp/symaehabi/symbian_support.h
    15 // 
    16 //
    17 
    18 
    19 #ifndef SYMBIAN_SUPPORT_H
    20 #define SYMBIAN_SUPPORT_H
    21 
    22 #include <e32def_private.h>
    23 
    24 #ifdef __cplusplus
    25 typedef _Unwind_Control_Block UCB;
    26 
    27 using std::terminate_handler;
    28 using std::unexpected_handler;
    29 using std::terminate;
    30 using std::unexpected;
    31 using std::type_info;
    32 
    33 /* --------- Exception control object: --------- */
    34 
    35 // Type __cxa_exception is the combined C++ housekeeping (LEO) and UCB.
    36 // It will be followed by the user exception object, hence must ensure
    37 // the latter is aligned on an 8 byte boundary.
    38 
    39 struct __cxa_exception {
    40   const type_info *exceptionType;       // RTTI object describing the type of the exception
    41   void *(*exceptionDestructor)(void *); // Destructor for the exception object (may be NULL)
    42   unexpected_handler unexpectedHandler; // Handler in force after evaluating throw expr
    43   terminate_handler terminateHandler;   // Handler in force after evaluating throw expr
    44   __cxa_exception *nextCaughtException; // Chain of "currently caught" c++ exception objects
    45   uint32_t handlerCount;                // Count of how many handlers this EO is "caught" in
    46   __cxa_exception *nextPropagatingException; // Chain of objects saved over cleanup
    47   uint32_t propagationCount;            // Count of live propagations (throws) of this EO
    48   UCB ucb;                              // Forces alignment of next item to 8-byte boundary
    49 };
    50 
    51 
    52 // Exceptions global support
    53 typedef void (*handler)(void);
    54 
    55 struct __cxa_eh_globals {
    56   uint32_t uncaughtExceptions;               // counter
    57   unexpected_handler unexpectedHandler;      // per-thread handler
    58   terminate_handler terminateHandler;        // per-thread handler
    59   bool implementation_ever_called_terminate; // true if it ever did
    60   handler call_hook;     // transient field to tell terminate/unexpected which hook to call
    61   __cxa_exception *caughtExceptions;         // chain of "caught" exceptions
    62   __cxa_exception *propagatingExceptions;    // chain of "propagating" (in cleanup) exceptions
    63   void *emergency_buffer;                    // emergency buffer for when rest of heap full
    64 };
    65 
    66 // emergency storage reserve primarily for throwing OOM exceptions
    67 struct emergency_eco {
    68   __cxa_exception ep;
    69     XLeaveException aUserLeaveException;
    70 };
    71 
    72 struct emergency_buffer {
    73   bool inuse;
    74   struct emergency_eco eco;
    75 };
    76 
    77 
    78 class TCppRTExceptionsGlobals
    79 	{
    80 public:
    81 	IMPORT_C TCppRTExceptionsGlobals();
    82 private:
    83 	__cxa_eh_globals thread_globals;
    84 	emergency_buffer buffer;
    85 	};
    86 
    87 #endif
    88 
    89 // Support for finding ROM resident ExIdx tables
    90 #define GET_ROM_EST(u) ((TRomExceptionSearchTable *)((u)->unwinder_cache.reserved4))
    91 #define SET_ROM_EST(u,e) ((TRomExceptionSearchTable *)((u)->unwinder_cache.reserved4=(uint32_t)e))
    92 #define GET_EXCEPTION_DESCRIPTOR(u) ((TExceptionDescriptor *)((u)->unwinder_cache.reserved5))
    93 #define SET_EXCEPTION_DESCRIPTOR(u,e) ((TExceptionDescriptor *)((u)->unwinder_cache.reserved5=(uint32_t)e))
    94 
    95 // Support for checking which version of EHABI is in play
    96 #define EHABI_MASK 0xfffffffc
    97 // Checks if image implements V2 of EHABI
    98 #define EHABI_V2(u) ((GET_EXCEPTION_DESCRIPTOR(u)->iROSegmentBase) & 1)
    99 #define GET_RO_BASE(u) (((u)->iROSegmentBase) & EHABI_MASK)
   100 #define ADDRESS_IN_EXCEPTION_DESCRIPTOR_RANGE(addr, aEDp) (((addr) >= GET_RO_BASE(aEDp)) && ((addr) < (aEDp)->iROSegmentLimit))
   101 #define GET_EST_FENCEPOST(aESTp) ((aESTp)->iEntries[(aESTp)->iNumEntries])
   102 #define ADDRESS_IN_ROM_EST(addr, aESTp) (((addr) >= (aESTp)->iEntries[0]) && ((addr) < GET_EST_FENCEPOST((aESTp))))
   103 
   104 
   105 // Non __EPOC32__ versions defined in unwinder.c
   106 #define EIT_base(u) \
   107     ((const __EIT_entry *)((GET_EXCEPTION_DESCRIPTOR(u))->iExIdxBase))
   108 #define EIT_limit(u) \
   109     ((const __EIT_entry *)((GET_EXCEPTION_DESCRIPTOR(u))->iExIdxLimit))
   110 
   111 
   112 #ifdef __cplusplus
   113 extern "C" {
   114 #endif
   115 
   116 typedef unsigned int size_t;
   117 IMPORT_C void abort(void);
   118 int typenameeq(const char * n1, const char * n2);
   119 
   120 #define malloc User::Alloc
   121 #define free User::Free
   122 
   123 
   124 #ifdef _DEBUG
   125 // uncomment this for diagnostic output in UDEB build
   126 //#define _DEBUG_SYMBIAN_EH_SUPPORT
   127 #endif
   128 
   129 #ifdef _DEBUG_SYMBIAN_EH_SUPPORT
   130 #define VRS_DIAGNOSTICS
   131 #define UNWIND_ACTIVITY_DIAGNOSTICS
   132 #define PR_DIAGNOSTICS
   133 #define PRINTED_DIAGNOSTICS
   134 #define CPP_DIAGNOSTICS
   135 #endif
   136 #define printf DebugPrintf
   137 extern void DebugPrintf(const char *, ...);
   138 
   139 #ifdef _DEBUG_SYMBIAN_EH_SUPPORT
   140 #define SYMBIAN_EH_SUPPORT_PRINTF DebugPrintf
   141 #else
   142 #define SYMBIAN_EH_SUPPORT_PRINTF (void)
   143 #pragma diag_suppress 174
   144 #endif
   145 
   146 void InitialiseSymbianSpecificUnwinderCache(uint32_t addr, _Unwind_Control_Block * ucbp);
   147 TExceptionDescriptor * ReLoadExceptionDescriptor(uint32_t addr,_Unwind_Control_Block * ucbp);
   148 
   149 /* Functions used to convert between segment-relative offsets
   150  * and absolute addresses. These are only used in unwinder.c and must be
   151  * compilable by a C compiler.
   152  */
   153 
   154 static __inline void ValidateExceptionDescriptor(uint32_t addr, _Unwind_Control_Block * ucbp)
   155 {
   156   // On entry assume ROM exception search table and exception descriptor for current frame cached in ucbp
   157   
   158   // see if addr is in current exception descriptor range
   159   TExceptionDescriptor * aEDp = GET_EXCEPTION_DESCRIPTOR(ucbp);
   160   if (!ADDRESS_IN_EXCEPTION_DESCRIPTOR_RANGE(addr, aEDp)) {
   161     aEDp = ReLoadExceptionDescriptor(addr, ucbp);
   162     // If there's no valid exception descriptor abort.
   163     if (!aEDp) {
   164 #ifdef _DEBUG
   165       DebugPrintf("EH ERROR: no exception descriptor for address 0x%08x\n", addr);
   166       DEBUGGER_BOTTLENECK(ucbp, _UASUBSYS_UNWINDER, _UAACT_ENDING, _UAARG_ENDING_UNWINDER_LOOKUPFAILED);
   167 #endif
   168       abort();
   169     }
   170   }
   171 }
   172 
   173 static __inline uint32_t addr_to_ER_RO_offset(uint32_t addr, _Unwind_Control_Block * ucbp)
   174 {
   175   TExceptionDescriptor * aEDp = GET_EXCEPTION_DESCRIPTOR(ucbp);
   176   // assume ucbp has the correct exception descriptor for this offset
   177   return addr - GET_RO_BASE(aEDp);
   178 }
   179 
   180 static __inline uint32_t ER_RO_offset_to_addr(uint32_t offset, _Unwind_Control_Block * ucbp)
   181 {
   182   TExceptionDescriptor * aEDp = GET_EXCEPTION_DESCRIPTOR(ucbp);
   183   // assume ucbp has the correct exception descriptor for this offset
   184   return offset + GET_RO_BASE(aEDp);
   185 }
   186 
   187 // This must be the same as the version in unwinder.c. However its structure is 
   188 // governed by the EHABI and so it shouldn't change anytime soon.
   189 typedef struct __EIT_entry {
   190   uint32_t fnoffset; /* Place-relative */
   191   uint32_t content;
   192 } __EIT_entry;
   193 
   194 // The Symbian unwinder uses these specific search functions rather than the generic bsearch
   195 // to find entries in the exception index table
   196 const __EIT_entry *SearchEITV1(uint32_t return_address_offset, const __EIT_entry *base, unsigned int nelems);
   197 __EIT_entry *SearchEITV2(uint32_t return_address, const __EIT_entry *base, unsigned int nelems);
   198 
   199 
   200 #ifdef __cplusplus
   201 }
   202 #endif
   203 
   204 #endif // SYMBIAN_SUPPORT_H
   205