Update contrib.
1 // Copyright (c) 1994-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\memmodel\emul\win32\mprocess.cpp
23 #define iMState iWaitLink.iSpare1
25 extern const char* JustInTime;
26 extern TBool DisableWSDWarning;
27 const TInt KMaxWsdDllsPerProcess = 256;
29 /********************************************
31 ********************************************/
32 DWin32Process::DWin32Process()
33 : iDllData(KMaxWsdDllsPerProcess, _FOFF(SProcessDllDataBlock,iCodeSeg))
35 // Set process JustInTime flag from the emulator property. This is not set
36 // for the process containing supervisor thread.
37 if (JustInTime && !_stricmp(JustInTime, "none"))
39 iFlags &= !KProcessFlagJustInTime;
43 DWin32Process::~DWin32Process()
45 __KTRACE_OPT(KMMU,Kern::Printf("DWin32Process destruct"));
51 TInt DWin32Process::NewChunk(DChunk*& aChunk, SChunkCreateInfo& aInfo, TLinAddr& aRunAddr)
54 DWin32Chunk* pC=new DWin32Chunk;
57 pC->iChunkType=aInfo.iType;
58 if (!aInfo.iGlobal && (iAttributes & DWin32Process::EPrivate)!=0)
59 pC->iAttributes |= DWin32Chunk::EPrivate;
60 pC->iOwningProcess=(aInfo.iGlobal)?NULL:this;
61 TInt r=pC->Create(aInfo);
62 if (r==KErrNone && (aInfo.iOperations & SChunkCreateInfo::EAdjust))
64 __ASSERT_ALWAYS(aInfo.iRunAddress==0,MM::Panic(MM::EInvalidChunkCreate));
65 if (aInfo.iPreallocated==0)
67 if (pC->iAttributes & DChunk::EDisconnected)
69 r=pC->Commit(aInfo.iInitialBottom,aInfo.iInitialTop-aInfo.iInitialBottom);
71 else if (pC->iAttributes & DChunk::EDoubleEnded)
73 r=pC->AdjustDoubleEnded(aInfo.iInitialBottom,aInfo.iInitialTop);
77 r=pC->Adjust(aInfo.iInitialTop);
82 aRunAddr=(TLinAddr)pC->Base();
87 pC->iDestroyedDfc = aInfo.iDestroyedDfc;
91 pC->Close(NULL); // NULL since chunk can't have been added to process
95 TInt DWin32Process::DoCreate(TBool aKernelProcess, TProcessCreateInfo& /*aInfo*/)
97 __KTRACE_OPT(KPROC,Kern::Printf("DWin32Process::DoCreate %O",this))
98 iAttributes=aKernelProcess ? ESupervisor|EPrivate : 0;
99 // force iDllData to reserve KMaxWsdDllsPerProcess. The Append will
100 // create the space, the Remove will not free it.
101 SProcessDllDataBlock data = {0,0,0};
102 TInt err = iDllData.Append(data);
105 __ASSERT_ALWAYS(iDllData.Count()==1,MM::Panic(MM::EWsdBadReserve));
111 TInt DWin32Process::CreateDataBssStackArea(TProcessCreateInfo& /*aInfo*/)
113 // This is managed for us by win32
116 __KTRACE_OPT(KPROC,Kern::Printf("DWin32Process::CreateDataBssStackArea %O",this));
120 TInt DWin32Process::AddChunk(DChunk* /*aChunk*/,TBool /*isReadOnly*/)
126 TInt DWin32Process::NewShPool(DShPool*& aPool, TShPoolCreateInfo& aInfo)
129 DWin32ShPool* pC = NULL;
131 if (aInfo.iInfo.iFlags & TShPoolCreateInfo::EPageAlignedBuffer)
133 pC = new DWin32AlignedShPool();
137 pC = new DWin32NonAlignedShPool();
145 TInt r = pC->Create(this, aInfo);
157 } // DWin32Process::NewShPool
160 void DWin32Process::Release()
162 CallRuntimeHook(EWin32RuntimeProcessDetach);
166 void DWin32Process::FinalRelease()
170 TInt DWin32Process::MapCodeSeg(DCodeSeg* aSeg)
173 __KTRACE_OPT(KDLL,Kern::Printf("Process %O MapCodeSeg(%C)", this, aSeg));
174 if (!aSeg || !aSeg->IsDll())
177 DWin32CodeSeg* seg = (DWin32CodeSeg*)aSeg;
178 if (seg->iRealDataSize == 0 && seg->iRealBssSize == 0)
181 if (!DisableWSDWarning && this!=K::TheKernelProcess)
182 Kern::Printf("WARNING!!: WSD Lib Loaded- Process %O, has loaded Lib %C"
183 " which has %d bytes of WSD",this,aSeg,
184 seg->iRealDataSize + seg->iRealBssSize);
186 // remove any existing copy of this code seg (should never happen)
189 SProcessDllDataBlock data;
194 data.iDataCopy = Kern::Alloc(seg->iRealDataSize);
195 data.iBssCopy = Kern::Alloc(seg->iRealBssSize);
196 if (!data.iDataCopy || !data.iBssCopy)
202 memcpy(data.iDataCopy, seg->iDataCopy, seg->iRealDataSize); // start with init data
203 memclr(data.iBssCopy, seg->iRealBssSize); // initialized to zeros
206 count = iDllData.Count();
207 if (count == KMaxWsdDllsPerProcess)
210 err = iDllData.InsertInUnsignedKeyOrder(data);
218 Kern::Free(data.iDataCopy);
219 Kern::Free(data.iBssCopy);
224 void DWin32Process::UnmapCodeSeg(DCodeSeg* aSeg)
226 if (!aSeg || !aSeg->IsDll())
229 DWin32CodeSeg* seg = (DWin32CodeSeg*)aSeg;
230 if (seg->iRealDataSize == 0 && seg->iRealBssSize == 0)
233 SProcessDllDataBlock data;
236 if (seg->iLiveProcess == this)
237 seg->iLiveProcess = NULL;
238 TInt ix = iDllData.FindInUnsignedKeyOrder(data);
249 Kern::Free(data.iDataCopy);
250 Kern::Free(data.iBssCopy);
251 __KTRACE_OPT(KDLL,Kern::Printf("Process %O UnmapCodeSeg(%C)", this, aSeg));
254 void DWin32Process::RemoveDllData()
256 // unmap all DLL data with kernel locked
257 TInt count = iDllData.Count();
258 for (TInt ii=count-1; ii>=0; ii--)
260 SProcessDllDataBlock data = iDllData[ii];
262 if (data.iCodeSeg->iLiveProcess == this)
263 data.iCodeSeg->iLiveProcess = NULL;
266 Kern::Free(data.iDataCopy);
267 Kern::Free(data.iBssCopy);
271 TInt DWin32Process::AttachExistingCodeSeg(TProcessCreateInfo& /*aInfo*/)
273 return KErrNotSupported; // never allowed
276 void DWin32Process::CallRuntimeHook(TWin32RuntimeReason aReason)
278 if (iWin32RuntimeHook)
281 TBool ok = iWin32RuntimeHook(aReason);
283 if (!ok && aReason != EWin32RuntimeProcessDetach)
284 Kern::PanicCurrentThread(_L("MemModel"), MM::EWin32RuntimeError);
289 void DThread::IpcExcHandler(TExcTrap* aTrap, DThread* aThread, TAny* aContext)
291 aThread->iIpcClient = 0;
292 TIpcExcTrap& xt=*(TIpcExcTrap*)aTrap;
293 TWin32ExcInfo& info=*(TWin32ExcInfo*)aContext;
294 TLinAddr va=(TLinAddr)info.iExcDataAddress;
295 if (va>=xt.iRemoteBase && (va-xt.iRemoteBase)<xt.iSize)
296 xt.Exception(KErrBadDescriptor); // problem accessing remote address - 'leave' so an error code will be returned
297 if (xt.iLocalBase && va>=xt.iLocalBase && (va-xt.iLocalBase)<xt.iSize)
298 NKern::UnlockSystem(); // problem accessing local address - return and panic current thread as usual
299 // otherwise return and fault kernel
302 TInt DThread::RawRead(const TAny* aSrc, TAny* aDest, TInt aLength, TInt /*aFlags*/, TIpcExcTrap* /*aExcTrap*/)
304 // Read from the thread's process.
305 // aSrc is run address of memory to read
306 // aDest is current address of destination
307 // Enter and leave with system locked
312 const TUint8* pS=(const TUint8*)aSrc;
313 TUint8* pD=(TUint8*)aDest;
314 TBool kernelLocked = EFalse;
315 const TUint8* pC=(const TUint8*)MM::CurrentAddress(this,pS,aLength,EFalse,kernelLocked);
318 // kernel locked because of DLL WSD IPC, do it all in one big block
320 __KTRACE_OPT(KTHREAD2,Kern::Printf("DThread::RawRead %08x",pC));
322 r = KErrBadDescriptor;
324 memcpy(pD,pC,aLength);
335 __KTRACE_OPT(KTHREAD2,Kern::Printf("DThread::Read %08x",pS));
337 TInt l=Min(aLength,K::MaxMemCopyInOneGo);
343 check=NKern::FlashSystem();
348 TInt DThread::RawWrite(const TAny* aDest, const TAny* aSrc, TInt aLength, TInt /*aFlags*/, DThread* /*anOriginatingThread*/, TIpcExcTrap* /*aExcTrap*/)
350 // Write to the thread's process.
351 // aDest is run address of memory to write
352 // aSrc is current address of destination
353 // anOriginatingThread is the thread on behalf of which this operation is performed (eg client of device driver).
354 // Enter and leave with system locked
359 TUint8* pD=(TUint8*)aDest;
360 const TUint8* pS=(const TUint8*)aSrc;
361 TBool kernelLocked = EFalse;
362 TUint8* pC=(TUint8*)MM::CurrentAddress(this,pD,aLength,ETrue,kernelLocked);
365 // kernel locked because of DLL WSD IPC, do it all in one big block
367 __KTRACE_OPT(KTHREAD2,Kern::Printf("DThread::RawWrite %08x",pC));
369 r = KErrBadDescriptor;
371 memcpy(pC,pS,aLength);
382 __KTRACE_OPT(KTHREAD2,Kern::Printf("DThread::Write %08x",pD));
384 TInt l=Min(aLength,K::MaxMemCopyInOneGo);
390 check=NKern::FlashSystem();
395 TInt DThread::ReadAndParseDesHeader(const TAny* aSrc, TDesHeader& aDest)
397 // Read and parse the header of a remote descriptor.
398 // Enter and leave with system locked.
401 __ASSERT_SYSTEM_LOCK;
402 static const TUint8 LengthLookup[16]={4,8,12,8,12,0,0,0,0,0,0,0,0,0,0,0};
403 if (iMState == EDead)
405 TBool kernelLocked = EFalse;
406 const TUint32* pS=(const TUint32*)MM::CurrentAddress(this,aSrc,sizeof(TDesC8),EFalse,kernelLocked);
407 if (!pS || (TInt(pS)&3)!=0)
411 return KErrBadDescriptor;
414 XTRAPD(r, XT_DEFAULT, \
415 type=*pS>>KShiftDesType8; \
416 TInt l=LengthLookup[type]; \
418 r=KErrBadDescriptor; \
420 wordmove(&aDest,pS,l); \
426 return K::ParseDesHeader(aSrc, (TRawDesHeader&)aDest, aDest);
429 DChunk* DThread::OpenSharedChunk(const TAny* aAddress, TBool /*aWrite*/, TInt& aOffset)
431 DWin32Chunk* chunk=0;
432 DObjectCon& chunks=*K::Containers[EChunk];
434 TInt count=chunks.Count();
439 DWin32Chunk* pC=(DWin32Chunk*)chunks[i];
440 offset = (TUint)aAddress-(TUint)pC->Base();
441 if(offset<TUint(pC->iMaxSize))
452 if((chunk->iChunkType!=ESharedKernelSingle && chunk->iChunkType!=ESharedKernelMultiple))
454 if(chunk->Open()!=KErrNone)
460 TInt DThread::PrepareMemoryForDMA(const TAny* /*aLinAddr*/, TInt /*aSize*/, TPhysAddr* /*aPhysicalPageList*/)
462 return KErrNotSupported;
465 TInt DThread::ReleaseMemoryFromDMA(const TAny* /*aLinAddr*/, TInt /*aSize*/, TPhysAddr* /*aPhysicalPageList*/)
467 return KErrNotSupported;