kernel/eka/euser/epoc/win32/uc_exec.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 1995-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 "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32\euser\epoc\win32\uc_exec.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #define __GEN_USER_EXEC_CODE__
       
    19 
       
    20 #include "uc_std.h"
       
    21 #include <e32svr.h>
       
    22 #include <emulator.h>
       
    23 
       
    24 typedef TInt (__fastcall *TDispatcher)(TInt, TInt*);
       
    25 TInt __fastcall LazyDispatch(TInt aFunction, TInt* aArgs);
       
    26 
       
    27 #pragma data_seg(".data2")
       
    28 #ifdef __VC32__
       
    29 #pragma bss_seg(".data2")
       
    30 #endif
       
    31 static TDispatcher TheDispatcher = &LazyDispatch;
       
    32 #pragma data_seg()
       
    33 #ifdef __VC32__
       
    34 #pragma bss_seg()
       
    35 #endif
       
    36 
       
    37 TInt __fastcall LazyDispatch(TInt aFunction, TInt* aArgs)
       
    38 	{
       
    39 	HINSTANCE kernel = GetModuleHandleA("ekern.exe");
       
    40 	if (kernel)
       
    41 		{
       
    42 		TDispatcher dispatcher = (TDispatcher)Emulator::GetProcAddress(kernel, (LPCSTR)1);
       
    43 		if (dispatcher)
       
    44 			{
       
    45 			TheDispatcher = dispatcher;
       
    46 			return dispatcher(aFunction, aArgs);
       
    47 			}
       
    48 		}
       
    49 	ExitProcess(101);
       
    50 	return 0;
       
    51 	}
       
    52 
       
    53 #include <u32exec.h>
       
    54 
       
    55 /******************************************************************************
       
    56  * Slow executive calls with preprocessing or extra arguments
       
    57  ******************************************************************************/
       
    58 
       
    59 __NAKED__ TInt Exec::SessionSend(TInt /*aHandle*/, TInt /*aFunction*/, TAny* /*aPtr*/, TRequestStatus* /*aStatus*/)
       
    60 //
       
    61 // Send a blind message to the server.
       
    62 //
       
    63 	{
       
    64 	__DISPATCH(EExecSessionSend|EXECUTIVE_SLOW)
       
    65 	}
       
    66 
       
    67 __NAKED__ TInt Exec::SessionSendSync(TInt /*aHandle*/, TInt /*aFunction*/, TAny* /*aPtr*/, TRequestStatus* /*aStatus*/)
       
    68 //
       
    69 // Send a blind message to the server using thread's dedicated message slot.
       
    70 //
       
    71 	{
       
    72 	__DISPATCH(EExecSessionSendSync|EXECUTIVE_SLOW)
       
    73 	}
       
    74 
       
    75 
       
    76 __NAKED__ TInt Exec::MessageIpcCopy(TInt /*aHandle*/, TInt /*aParam*/, SIpcCopyInfo& /*aInfo*/, TInt /*anOffset*/)
       
    77 //
       
    78 // Perform a descriptor-to-descriptor IPC copy
       
    79 //
       
    80 	{
       
    81 
       
    82 	__DISPATCH(EExecMessageIpcCopy|EXECUTIVE_SLOW)
       
    83 	}
       
    84 
       
    85 __NAKED__ TInt Exec::BTraceOut(TUint32 /*a0*/, TUint32 /*a1*/, const BTrace::SExecExtension& /*aExtension*/, TInt /*aDataSize*/)
       
    86 	{
       
    87 	__DISPATCH(EExecBTraceOut|EXECUTIVE_SLOW)
       
    88 	}
       
    89 
       
    90 __NAKED__ TInt Exec::BTraceOutBig(TUint32 /*a0*/, TUint32 /*a1*/, const BTrace::SExecExtension& /*aExtension*/, TInt /*aDataSize*/)
       
    91 	{
       
    92 	__DISPATCH(EExecBTraceOutBig|EXECUTIVE_SLOW)
       
    93 	}
       
    94 
       
    95 __NAKED__ TInt Exec::UTraceOut(TUint32 /*a0*/, TUint32 /*a1*/, const BTrace::SExecExtension& /*aExtension*/, TInt /*aDataSize*/)
       
    96 	{
       
    97 	__DISPATCH(EExecUTraceOut|EXECUTIVE_SLOW)
       
    98 	}
       
    99 
       
   100 EXPORT_C TBool BTrace::Out(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
       
   101 	{
       
   102 	BTrace::SExecExtension ext;
       
   103 	ext.iA2 = a2;
       
   104 	ext.iA3 = a3;
       
   105 	ext.iPc = (&a0)[-1]; // return address on X86
       
   106 	return Exec::BTraceOut(a0,a1,ext,0);
       
   107 	}
       
   108 
       
   109 EXPORT_C TBool BTrace::OutX(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
       
   110 	{
       
   111 	BTrace::SExecExtension ext;
       
   112 	ext.iA2 = a2;
       
   113 	ext.iA3 = a3;
       
   114 	ext.iPc = (&a0)[-1]; // return address on X86
       
   115 	return Exec::BTraceOut(a0,a1,ext,0);
       
   116 	}
       
   117 
       
   118 EXPORT_C TBool BTrace::OutN(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
       
   119 	{
       
   120 	BTrace::SExecExtension ext;
       
   121 	ext.iA2 = a2;
       
   122 	ext.iA3 = (TUint32)aData;
       
   123 	ext.iPc = (&a0)[-1]; // return address on X86
       
   124 	return Exec::BTraceOut(a0,a1,ext,aDataSize);
       
   125 	}
       
   126 
       
   127 EXPORT_C TBool BTrace::OutNX(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
       
   128 	{
       
   129 	BTrace::SExecExtension ext;
       
   130 	ext.iA2 = a2;
       
   131 	ext.iA3 = (TUint32)aData;
       
   132 	ext.iPc = (&a0)[-1]; // return address on X86
       
   133 	return Exec::BTraceOut(a0,a1,ext,aDataSize);
       
   134 	}
       
   135 
       
   136 EXPORT_C TBool BTrace::OutBig(TUint32 a0, TUint32 a1, const TAny* aData, TInt aDataSize)
       
   137 	{
       
   138 	BTrace::SExecExtension ext;
       
   139 	ext.iA2 = 0;
       
   140 	ext.iA3 = (TUint32)aData;
       
   141 	ext.iPc = (&a0)[-1]; // return address on X86
       
   142 
       
   143 	if((TUint)aDataSize>8u)
       
   144 		{
       
   145 		if((TUint)aDataSize>KMaxBTraceDataArray+4u)
       
   146 			return Exec::BTraceOutBig(a0,a1,ext,aDataSize);
       
   147 		a0 += 4;
       
   148 		aDataSize -= 4;
       
   149 		ext.iA2 = *((TUint32*&)aData)++;
       
   150 		ext.iA3 = (TUint32)aData;
       
   151 		return Exec::BTraceOut(a0,a1,ext,aDataSize);
       
   152 		}
       
   153 
       
   154 	if((TUint)aDataSize>4u)
       
   155 		ext.iA3 = ((TUint32*)aData)[1];
       
   156 	if(aDataSize)
       
   157 		ext.iA2 = ((TUint32*)aData)[0];
       
   158 	a0 += aDataSize;
       
   159 	aDataSize = 0;
       
   160 	return Exec::BTraceOut(a0,a1,ext,aDataSize);
       
   161 	}
       
   162 
       
   163 EXPORT_C TBool BTrace::OutFiltered(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
       
   164 	{
       
   165 	BTrace::SExecExtension ext;
       
   166 	a0 |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
       
   167 	ext.iA2 = a2;
       
   168 	ext.iA3 = a3;
       
   169 	ext.iPc = (&a0)[-1]; // return address on X86
       
   170 	return Exec::BTraceOut(a0,a1,ext,0);
       
   171 	}
       
   172 
       
   173 EXPORT_C TBool BTrace::OutFilteredX(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
       
   174 	{
       
   175 	BTrace::SExecExtension ext;
       
   176 	a0 |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
       
   177 	ext.iA2 = a2;
       
   178 	ext.iA3 = a3;
       
   179 	ext.iPc = (&a0)[-1]; // return address on X86
       
   180 	return Exec::BTraceOut(a0,a1,ext,0);
       
   181 	}
       
   182 
       
   183 EXPORT_C TBool BTrace::OutFilteredN(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
       
   184 	{
       
   185 	BTrace::SExecExtension ext;
       
   186 	a0 |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
       
   187 	ext.iA2 = a2;
       
   188 	ext.iA3 = (TUint32)aData;
       
   189 	ext.iPc = (&a0)[-1]; // return address on X86
       
   190 	return Exec::BTraceOut(a0,a1,ext,aDataSize);
       
   191 	}
       
   192 
       
   193 EXPORT_C TBool BTrace::OutFilteredNX(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
       
   194 	{
       
   195 	BTrace::SExecExtension ext;
       
   196 	a0 |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
       
   197 	ext.iA2 = a2;
       
   198 	ext.iA3 = (TUint32)aData;
       
   199 	ext.iPc = (&a0)[-1]; // return address on X86
       
   200 	return Exec::BTraceOut(a0,a1,ext,aDataSize);
       
   201 	}
       
   202 
       
   203 EXPORT_C TBool BTrace::OutFilteredBig(TUint32 a0, TUint32 a1, const TAny* aData, TInt aDataSize)
       
   204 	{
       
   205 	BTrace::SExecExtension ext;
       
   206 	a0 |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
       
   207 	ext.iA2 = 0;
       
   208 	ext.iA3 = (TUint32)aData;
       
   209 	ext.iPc = (&a0)[-1]; // return address on X86
       
   210 
       
   211 	if((TUint)aDataSize>8u)
       
   212 		{
       
   213 		if((TUint)aDataSize>KMaxBTraceDataArray+4u)
       
   214 			return Exec::BTraceOutBig(a0,a1,ext,aDataSize);
       
   215 		a0 += 4;
       
   216 		aDataSize -= 4;
       
   217 		ext.iA2 = *((TUint32*&)aData)++;
       
   218 		ext.iA3 = (TUint32)aData;
       
   219 		return Exec::BTraceOut(a0,a1,ext,aDataSize);
       
   220 		}
       
   221 
       
   222 	if((TUint)aDataSize>4u)
       
   223 		ext.iA3 = ((TUint32*)aData)[1];
       
   224 	if(aDataSize)
       
   225 		ext.iA2 = ((TUint32*)aData)[0];
       
   226 	a0 += aDataSize;
       
   227 	aDataSize = 0;
       
   228 	return Exec::BTraceOut(a0,a1,ext,aDataSize);
       
   229 	}
       
   230 
       
   231 EXPORT_C TBool BTrace::OutFilteredPcFormatBig(TUint32 aHeader, TUint32 aModuleUid, TUint32 aPc, TUint16 aFormatId, const TAny* aData, TInt aDataSize)
       
   232 	{
       
   233  	BTrace::SExecExtension ext;
       
   234 	aHeader |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
       
   235 	ext.iA2 = aFormatId;
       
   236 	ext.iA3 = (TUint32)aData;
       
   237 	ext.iPc = aPc;
       
   238 
       
   239 	if((TUint)aDataSize>KMaxBTraceDataArray)
       
   240 		return Exec::UTraceOut(aHeader,aModuleUid,ext,aDataSize);
       
   241 	aHeader += 4;
       
   242 	return Exec::BTraceOut(aHeader,aModuleUid,ext,aDataSize);
       
   243 	}
       
   244 
       
   245 __NAKED__ void ExecRequestComplete(TInt /*aHandle*/, TRequestStatus*& /*aStatus*/, TInt /*aReason*/)
       
   246 	{
       
   247 	_asm mov ecx, [esp+8]			// ecx = TRequestStatus**
       
   248 	_asm xor eax, eax				//
       
   249 	_asm lock xchg eax, [ecx]		// eax=TRequestStatus*, zero TRequestStatus*
       
   250 	_asm cmp eax, 0					//
       
   251 	_asm je ExecRequestComplete_ret
       
   252 	_asm mov ecx, [esp+12]			// ecx = aReason
       
   253 	_asm mov [eax], ecx				// store aReason in request status
       
   254 	__DISPATCH(EExecThreadRequestSignal|EXECUTIVE_SLOW)
       
   255 	_asm ExecRequestComplete_ret: ret
       
   256 	}
       
   257 
       
   258 
       
   259 
       
   260 
       
   261 EXPORT_C void RThread::RequestComplete(TRequestStatus*& aStatus, TInt aReason) const
       
   262 /**
       
   263 Signals this thread that an asynchronous request originating from this thread,
       
   264 is complete.
       
   265 
       
   266 The request is associated with the specified request status object supplied
       
   267 by this thread.
       
   268 
       
   269 Typically, the caller of this function is the service provider responsible
       
   270 for satisfying the request made by this thread.
       
   271 
       
   272 The request is completed with the completion code passed in aReason. This
       
   273 value is copied into this thread's request status, *aStatus, before signalling
       
   274 this thread's request semaphore.
       
   275 
       
   276 The meaning of the completion code is a matter of convention to be decided
       
   277 between the service provider and this thread.
       
   278 
       
   279 In a client-server situation, completion of a request takes place in the context
       
   280 of the server thread, but the pointer is interpreted in the address space
       
   281 of the client.
       
   282 
       
   283 It is often the case in client-server situations that the client and the server
       
   284 are in the same address space (i.e. the same process).
       
   285 
       
   286 Setting the pointer to the request status to NULL is a convenience, not all
       
   287 servers need it.
       
   288 
       
   289 @param aStatus A reference to a pointer to the request status originally
       
   290                supplied by this thread. This is a pointer into this thread's
       
   291                address space, which may be different to the thread currently
       
   292                executing (this code). On return, the pointer to the request
       
   293                status is set to NULL.
       
   294 
       
   295 @param aReason The completion code of this request.
       
   296 */
       
   297 	{
       
   298 	ExecRequestComplete(iHandle,aStatus,aReason);
       
   299 	}
       
   300 
       
   301 
       
   302 
       
   303 /**
       
   304 Signal this threads request semaphore.
       
   305 
       
   306 This is similar to RThread::RequestComplete() except that no TRequestStatus object
       
   307 is modified.
       
   308 
       
   309 May only be used to signal a thread in the same process as the callers.
       
   310 
       
   311 @panic KERN-EXEC 46 if the thread is not in the same process as the callers
       
   312 */
       
   313 EXPORT_C void RThread::RequestSignal() const
       
   314 	{
       
   315 	Exec::ThreadRequestSignal(iHandle);
       
   316 	}
       
   317 
       
   318 
       
   319 
       
   320 void ExitCurrentThread(TExitType aType, TInt aReason, const TDesC8* aCategory)
       
   321 	{
       
   322 	Exec::ThreadKill(KCurrentThreadHandle, aType, aReason, aCategory);
       
   323 	}
       
   324