os/kernelhwsrv/kernel/eka/memmodel/epoc/moving/mcodeseg.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// e32\memmodel\epoc\moving\mcodeseg.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include "memmodel.h"
sl@0
    19
#include "cache_maintenance.h"
sl@0
    20
#include <demand_paging.h>
sl@0
    21
sl@0
    22
_LIT(KLitUserCode,"USER$CODE");
sl@0
    23
_LIT(KLitKernCode,"KERN$CODE");
sl@0
    24
sl@0
    25
TInt MM::CreateCodeChunk(TBool aKernel)
sl@0
    26
	{
sl@0
    27
	__KTRACE_OPT(KDLL,Kern::Printf("MM::CreateCodeChunk %d",aKernel));
sl@0
    28
	Mmu& m = Mmu::Get();
sl@0
    29
	SChunkCreateInfo c;
sl@0
    30
	c.iGlobal = ETrue;
sl@0
    31
	c.iAtt = TChunkCreate::EDisconnected;
sl@0
    32
	c.iForceFixed = EFalse;
sl@0
    33
	c.iOperations = 0;
sl@0
    34
	c.iPreallocated = 0;
sl@0
    35
	c.iOwner = NULL;
sl@0
    36
sl@0
    37
	if (aKernel)
sl@0
    38
		{
sl@0
    39
		c.iRunAddress = m.iKernelCodeBase;
sl@0
    40
		c.iType = EKernelCode;
sl@0
    41
		c.iMaxSize = m.iMaxKernelCodeSize;
sl@0
    42
		c.iName.Set(KLitKernCode);
sl@0
    43
		}
sl@0
    44
	else
sl@0
    45
		{
sl@0
    46
		c.iRunAddress = m.iUserCodeBase;
sl@0
    47
		c.iType = EDll;
sl@0
    48
		c.iMaxSize = m.iMaxUserCodeSize;
sl@0
    49
		c.iName.Set(KLitUserCode);
sl@0
    50
		}
sl@0
    51
sl@0
    52
	TLinAddr runAddr;
sl@0
    53
	DMemModelChunk* pC = NULL;
sl@0
    54
	TInt r=K::TheKernelProcess->NewChunk((DChunk*&)pC, c, runAddr);
sl@0
    55
	if (r==KErrNone)
sl@0
    56
		{
sl@0
    57
		pC->SetFixedAddress(c.iRunAddress, 0);
sl@0
    58
		if (aKernel)
sl@0
    59
			MM::KernelCodeChunk = pC;
sl@0
    60
		else
sl@0
    61
			MM::UserCodeChunk = pC;
sl@0
    62
		}
sl@0
    63
	return r;
sl@0
    64
	}
sl@0
    65
sl@0
    66
DCodeSeg* M::NewCodeSeg(TCodeSegCreateInfo&)
sl@0
    67
//
sl@0
    68
// Create a new instance of this class.
sl@0
    69
//
sl@0
    70
	{
sl@0
    71
sl@0
    72
	__KTRACE_OPT(KDLL,Kern::Printf("M::NewCodeSeg"));
sl@0
    73
	return new DMemModelCodeSeg;
sl@0
    74
	}
sl@0
    75
sl@0
    76
sl@0
    77
DEpocCodeSegMemory* DEpocCodeSegMemory::New(DEpocCodeSeg* aCodeSeg)
sl@0
    78
	{
sl@0
    79
	return new DMemModelCodeSegMemory(aCodeSeg);
sl@0
    80
	}
sl@0
    81
sl@0
    82
	
sl@0
    83
DMemModelCodeSegMemory::DMemModelCodeSegMemory(DEpocCodeSeg* aCodeSeg)
sl@0
    84
	: DMmuCodeSegMemory(aCodeSeg)
sl@0
    85
	{
sl@0
    86
	}
sl@0
    87
sl@0
    88
sl@0
    89
TInt DMemModelCodeSegMemory::Create(TCodeSegCreateInfo& aInfo)
sl@0
    90
	{
sl@0
    91
	TInt r = DMmuCodeSegMemory::Create(aInfo);
sl@0
    92
	if(r!=KErrNone)
sl@0
    93
		return r;
sl@0
    94
sl@0
    95
	Mmu& m=Mmu::Get();
sl@0
    96
sl@0
    97
	TInt codeSize = iPageCount<<m.iPageShift;
sl@0
    98
	TInt dataSize = iDataPageCount<<m.iPageShift;
sl@0
    99
	TInt totalSize = codeSize+dataSize;
sl@0
   100
sl@0
   101
	DCodeSeg::Wait();
sl@0
   102
	
sl@0
   103
	DChunk::TCommitType commitType = iIsDemandPaged ? DChunk::ECommitVirtual : DChunk::ECommitDiscontiguous;
sl@0
   104
	r=MM::UserCodeChunk->FindFree(totalSize, 0, 0);
sl@0
   105
	if (r<0)
sl@0
   106
		{
sl@0
   107
		r = KErrNoMemory;
sl@0
   108
		goto exit;
sl@0
   109
		}
sl@0
   110
	iCodeAllocBase = r;
sl@0
   111
	r = KErrNone;
sl@0
   112
	
sl@0
   113
	r=MM::UserCodeChunk->Commit(iCodeAllocBase, codeSize, commitType);
sl@0
   114
	if (r<0)
sl@0
   115
		{
sl@0
   116
		r = KErrNoMemory;
sl@0
   117
		goto exit;
sl@0
   118
		}
sl@0
   119
	
sl@0
   120
	iRamInfo.iCodeRunAddr = ((TLinAddr)MM::UserCodeChunk->Base())+iCodeAllocBase;
sl@0
   121
	iRamInfo.iCodeLoadAddr = iRamInfo.iCodeRunAddr;
sl@0
   122
sl@0
   123
	if (iRamInfo.iDataSize)
sl@0
   124
		{
sl@0
   125
		if(iDataPageCount)
sl@0
   126
			iRamInfo.iDataLoadAddr = iRamInfo.iCodeLoadAddr+codeSize;
sl@0
   127
		else
sl@0
   128
			iRamInfo.iDataLoadAddr = iRamInfo.iCodeLoadAddr+iRamInfo.iCodeSize;
sl@0
   129
		}
sl@0
   130
	
sl@0
   131
	if (!iIsDemandPaged)
sl@0
   132
		{
sl@0
   133
		TInt loadedSize = iRamInfo.iCodeSize+iRamInfo.iDataSize;
sl@0
   134
		memset((TAny*)(iRamInfo.iCodeLoadAddr+loadedSize), 0x03, totalSize-loadedSize);
sl@0
   135
		}
sl@0
   136
	else
sl@0
   137
		{
sl@0
   138
		if(dataSize)
sl@0
   139
			{
sl@0
   140
			r=MM::UserCodeChunk->Commit(iCodeAllocBase+codeSize, dataSize, DChunk::ECommitDiscontiguous);
sl@0
   141
			if (r<0)
sl@0
   142
				goto exit;
sl@0
   143
			memset((TAny*)(iRamInfo.iCodeLoadAddr+codeSize+iRamInfo.iDataSize), 0x03, dataSize-iRamInfo.iDataSize);
sl@0
   144
			}
sl@0
   145
		}
sl@0
   146
sl@0
   147
exit:
sl@0
   148
	DCodeSeg::Signal();
sl@0
   149
	return r;
sl@0
   150
	}
sl@0
   151
sl@0
   152
	
sl@0
   153
TInt DMemModelCodeSegMemory::Loaded(TCodeSegCreateInfo& aInfo)
sl@0
   154
	{
sl@0
   155
	TInt r = DMmuCodeSegMemory::Loaded(aInfo);
sl@0
   156
	if(r!=KErrNone)
sl@0
   157
		return r;
sl@0
   158
sl@0
   159
	Mmu& m=Mmu::Get();
sl@0
   160
	TInt pageShift = m.iPageShift;
sl@0
   161
sl@0
   162
	if(iIsDemandPaged)
sl@0
   163
		{
sl@0
   164
		// apply code fixups to pages which have already been loaded...
sl@0
   165
		TLinAddr loadAddr = iRamInfo.iCodeLoadAddr;
sl@0
   166
		TLinAddr loadAddrEnd = loadAddr+iRamInfo.iCodeSize;
sl@0
   167
		TLinAddr runAddr = iRamInfo.iCodeLoadAddr;
sl@0
   168
		TInt pageSize = 1<<pageShift;
sl@0
   169
		for(; loadAddr<loadAddrEnd; loadAddr+=pageSize,runAddr+=pageSize)
sl@0
   170
			{
sl@0
   171
			if(m.LinearToPhysical(loadAddr)!=KPhysAddrInvalid)
sl@0
   172
				{
sl@0
   173
				r = ApplyCodeFixupsOnLoad((TUint32*)loadAddr,runAddr);
sl@0
   174
				if(r!=KErrNone)
sl@0
   175
					return r;
sl@0
   176
				}
sl@0
   177
			}
sl@0
   178
		}
sl@0
   179
	CacheMaintenance::CodeChanged(iRamInfo.iCodeLoadAddr, iRamInfo.iCodeSize);
sl@0
   180
sl@0
   181
	// discard any temporary pages used to store loaded data section...
sl@0
   182
	if(iDataPageCount)
sl@0
   183
		{
sl@0
   184
		TInt codeSize = iPageCount<<pageShift;
sl@0
   185
		MM::UserCodeChunk->Decommit(iCodeAllocBase+codeSize, iDataPageCount<<pageShift);
sl@0
   186
		iDataPageCount = 0;
sl@0
   187
		//Reduce the size of the DCodeSeg now the data section has been moved
sl@0
   188
		iCodeSeg->iSize = codeSize;
sl@0
   189
		}
sl@0
   190
sl@0
   191
	return KErrNone;
sl@0
   192
	}
sl@0
   193
sl@0
   194
	
sl@0
   195
void DMemModelCodeSegMemory::Destroy()
sl@0
   196
	{
sl@0
   197
	if(iCodeAllocBase!=KMinTInt && iDataPageCount)
sl@0
   198
		{
sl@0
   199
		Mmu& m=Mmu::Get();
sl@0
   200
		TInt dataSize = iDataPageCount<<m.iPageShift;
sl@0
   201
		TInt codeSize = iPageCount<<m.iPageShift;
sl@0
   202
		if(dataSize)
sl@0
   203
			MM::UserCodeChunk->Decommit(iCodeAllocBase+codeSize, dataSize);
sl@0
   204
		}
sl@0
   205
	}
sl@0
   206
sl@0
   207
sl@0
   208
DMemModelCodeSegMemory::~DMemModelCodeSegMemory()
sl@0
   209
	{
sl@0
   210
	if(iCodeAllocBase!=KMinTInt)
sl@0
   211
		{
sl@0
   212
		Mmu& m=Mmu::Get();
sl@0
   213
		TInt codeSize = iPageCount<<m.iPageShift;
sl@0
   214
		DMemModelChunk::TDecommitType decommitType = iIsDemandPaged ? DChunk::EDecommitVirtual : DChunk::EDecommitNormal;
sl@0
   215
		MM::UserCodeChunk->Decommit(iCodeAllocBase, codeSize, decommitType);
sl@0
   216
		}
sl@0
   217
	}
sl@0
   218
sl@0
   219
sl@0
   220
DMemModelCodeSeg::DMemModelCodeSeg()
sl@0
   221
//
sl@0
   222
// Constructor
sl@0
   223
//
sl@0
   224
	:	iCodeAllocBase(KMinTInt),
sl@0
   225
		iDataAllocBase(KMinTInt)
sl@0
   226
	{
sl@0
   227
	}
sl@0
   228
sl@0
   229
DMemModelCodeSeg::~DMemModelCodeSeg()
sl@0
   230
//
sl@0
   231
// Destructor
sl@0
   232
//
sl@0
   233
	{
sl@0
   234
	__KTRACE_OPT(KDLL,Kern::Printf("DMemModelCodeSeg::Destruct %C", this));
sl@0
   235
	Mmu& m=Mmu::Get();
sl@0
   236
	if (!iXIP && iMemory)
sl@0
   237
		{
sl@0
   238
		SRamCodeInfo& ri=RamInfo();
sl@0
   239
		DCodeSeg::Wait();
sl@0
   240
		if (iCodeAllocBase!=KMinTInt)
sl@0
   241
			{
sl@0
   242
			TBool kernel=( (iAttr&(ECodeSegAttKernel|ECodeSegAttGlobal)) == ECodeSegAttKernel );
sl@0
   243
			if (kernel)
sl@0
   244
				MM::KernelCodeChunk->Decommit(iCodeAllocBase, iSize);
sl@0
   245
			}
sl@0
   246
		Memory()->Destroy();
sl@0
   247
		TInt data_alloc=(ri.iDataSize+ri.iBssSize+m.iPageMask)>>m.iPageShift;
sl@0
   248
		if (iDataAllocBase>=0)
sl@0
   249
			{
sl@0
   250
			MM::DllDataAllocator->Free(iDataAllocBase, data_alloc);
sl@0
   251
			}
sl@0
   252
		else if (iDataAllocBase==-1)
sl@0
   253
			{
sl@0
   254
			DMemModelProcess* p=(DMemModelProcess*)iAttachProcess;
sl@0
   255
			if (p->iExitType==EExitPending)
sl@0
   256
				{
sl@0
   257
				DMemModelChunk& c=*p->iDllDataChunk;
sl@0
   258
				TInt offset=ri.iDataRunAddr-TLinAddr(c.Base());
sl@0
   259
				c.Decommit(offset, data_alloc<<m.iPageShift);
sl@0
   260
				if (c.iSize==0)
sl@0
   261
					p->FreeDllDataChunk();
sl@0
   262
				}
sl@0
   263
			}
sl@0
   264
		DCodeSeg::Signal();
sl@0
   265
		}
sl@0
   266
	Kern::Free(iKernelData);
sl@0
   267
	DEpocCodeSeg::Destruct();
sl@0
   268
	}
sl@0
   269
sl@0
   270
sl@0
   271
TInt DMemModelCodeSeg::DoCreateRam(TCodeSegCreateInfo& aInfo, DProcess* aProcess)
sl@0
   272
	{
sl@0
   273
	__KTRACE_OPT(KDLL,Kern::Printf("DMemModelCodeSeg::DoCreateRam %C proc %O", this, aProcess));
sl@0
   274
	TBool kernel=( (iAttr&(ECodeSegAttKernel|ECodeSegAttGlobal)) == ECodeSegAttKernel );
sl@0
   275
	DMemModelProcess* p=(DMemModelProcess*)aProcess;
sl@0
   276
	Mmu& m=Mmu::Get();
sl@0
   277
	SRamCodeInfo& ri=RamInfo();
sl@0
   278
	iSize = Mmu::RoundToPageSize(ri.iCodeSize+ri.iDataSize);
sl@0
   279
	if (iSize==0)
sl@0
   280
		return KErrCorrupt;
sl@0
   281
	TInt total_data_size=ri.iDataSize+ri.iBssSize;
sl@0
   282
	TInt r=KErrNone;
sl@0
   283
	if (kernel)
sl@0
   284
		{
sl@0
   285
		r=MM::KernelCodeChunk->Allocate(iSize, 0, 0);
sl@0
   286
		if (r<0)
sl@0
   287
			return r;
sl@0
   288
		iCodeAllocBase=r;
sl@0
   289
		ri.iCodeRunAddr=(TUint32)MM::KernelCodeChunk->Base();
sl@0
   290
		ri.iCodeRunAddr+=r;
sl@0
   291
		ri.iCodeLoadAddr=ri.iCodeRunAddr;
sl@0
   292
		if (ri.iDataSize)
sl@0
   293
			ri.iDataLoadAddr=ri.iCodeLoadAddr+ri.iCodeSize;
sl@0
   294
		if (total_data_size)
sl@0
   295
			{
sl@0
   296
			iKernelData=Kern::Alloc(total_data_size);
sl@0
   297
			if (!iKernelData)
sl@0
   298
				return KErrNoMemory;
sl@0
   299
			ri.iDataRunAddr=(TLinAddr)iKernelData;
sl@0
   300
			}
sl@0
   301
		return KErrNone;
sl@0
   302
		}
sl@0
   303
sl@0
   304
	r = Memory()->Create(aInfo);
sl@0
   305
	if(r!=KErrNone)
sl@0
   306
		return r;
sl@0
   307
sl@0
   308
	r=KErrNone;
sl@0
   309
	if (total_data_size && p && p->iAttributes&DMemModelProcess::EFixedAddress)
sl@0
   310
		{
sl@0
   311
		SetAttachProcess(p);
sl@0
   312
		}
sl@0
   313
	if (total_data_size && !IsExe())
sl@0
   314
		{
sl@0
   315
		TInt data_alloc_size=Mmu::RoundToPageSize(total_data_size);
sl@0
   316
		TInt data_alloc=data_alloc_size>>m.iPageShift;
sl@0
   317
		DCodeSeg::Wait();
sl@0
   318
		if (p)
sl@0
   319
			{
sl@0
   320
			if (p->iExitType!=EExitPending)
sl@0
   321
				return KErrDied;
sl@0
   322
			}
sl@0
   323
		if (iAttachProcess)
sl@0
   324
			{
sl@0
   325
			r=KErrNone;
sl@0
   326
			if (!p->iDllDataChunk)
sl@0
   327
				r=p->CreateDllDataChunk();
sl@0
   328
			if (r==KErrNone)
sl@0
   329
				{
sl@0
   330
				DMemModelChunk& c=*p->iDllDataChunk;
sl@0
   331
				r=c.Allocate(data_alloc_size, 0, 0);
sl@0
   332
				if (r>=0)
sl@0
   333
					{
sl@0
   334
					ri.iDataRunAddr=TLinAddr(c.Base())+r;
sl@0
   335
					iDataAllocBase=-1;
sl@0
   336
					r=KErrNone;
sl@0
   337
					}
sl@0
   338
				else
sl@0
   339
					{
sl@0
   340
					if (c.iSize==0)
sl@0
   341
						p->FreeDllDataChunk();
sl@0
   342
					r=KErrNoMemory;
sl@0
   343
					}
sl@0
   344
				}
sl@0
   345
			}
sl@0
   346
		else
sl@0
   347
			{
sl@0
   348
			r=MM::DllDataAllocator->AllocConsecutive(data_alloc, ETrue);
sl@0
   349
			if (r>=0)
sl@0
   350
				MM::DllDataAllocator->Alloc(r, data_alloc);
sl@0
   351
			if (r>=0)
sl@0
   352
				{
sl@0
   353
				iDataAllocBase=r;
sl@0
   354
				ri.iDataRunAddr=m.iDataSectionEnd-((r+data_alloc)<<m.iPageShift);
sl@0
   355
				r=KErrNone;
sl@0
   356
				}
sl@0
   357
			else
sl@0
   358
				r=KErrNoMemory;
sl@0
   359
			}
sl@0
   360
		DCodeSeg::Signal();
sl@0
   361
		}
sl@0
   362
	if(r!=KErrNone)
sl@0
   363
		return r;
sl@0
   364
	
sl@0
   365
	return r;
sl@0
   366
	}
sl@0
   367
sl@0
   368
sl@0
   369
TInt DMemModelCodeSeg::DoCreateXIP(DProcess* aProcess)
sl@0
   370
	{
sl@0
   371
	__KTRACE_OPT(KDLL,Kern::Printf("DMemModelCodeSeg::DoCreateXIP %C proc %O", this, aProcess));
sl@0
   372
	DMemModelProcess* p=(DMemModelProcess*)aProcess;
sl@0
   373
	TInt r=KErrNone;
sl@0
   374
	TBool kernel=( (iAttr&(ECodeSegAttKernel|ECodeSegAttGlobal)) == ECodeSegAttKernel );
sl@0
   375
	const TRomImageHeader& rih=RomInfo();
sl@0
   376
	TBool fixed=p && (p->iAttributes&DMemModelProcess::EFixedAddress);
sl@0
   377
	if (!kernel && fixed)
sl@0
   378
		{
sl@0
   379
		// XIP images with static data loaded into fixed processes are specific to a single process
sl@0
   380
		if (rih.iFlags&KRomImageFlagDataPresent)
sl@0
   381
			{
sl@0
   382
			if (rih.iTotalDataSize)
sl@0
   383
				{
sl@0
   384
				TLinAddr process_data_base=p->iDataBssRunAddress;
sl@0
   385
				TUint32 process_data_maxsize=p->iDataBssStackChunk->iMaxSize;
sl@0
   386
				if (rih.iDataBssLinearBase<process_data_base || 
sl@0
   387
					(rih.iDataBssLinearBase+rih.iTotalDataSize)>(process_data_base+process_data_maxsize))
sl@0
   388
					return KErrNotSupported;
sl@0
   389
				}
sl@0
   390
			SetAttachProcess(p);
sl@0
   391
			iDataAllocBase=-1;
sl@0
   392
			}
sl@0
   393
		}
sl@0
   394
	return r;
sl@0
   395
	}
sl@0
   396
sl@0
   397
sl@0
   398
TInt DMemModelCodeSeg::Loaded(TCodeSegCreateInfo& aInfo)
sl@0
   399
	{
sl@0
   400
	if (!iXIP)
sl@0
   401
		{
sl@0
   402
		TBool kernel=( (iAttr&(ECodeSegAttKernel|ECodeSegAttGlobal)) == ECodeSegAttKernel );
sl@0
   403
		if(kernel)
sl@0
   404
			{
sl@0
   405
			// Clean DCache for specified area, Invalidate ICache/BTB for specified area
sl@0
   406
			SRamCodeInfo& ri=RamInfo();
sl@0
   407
			CacheMaintenance::CodeChanged(ri.iCodeRunAddr, ri.iCodeSize);
sl@0
   408
			}
sl@0
   409
		else
sl@0
   410
			{
sl@0
   411
			TInt r = Memory()->Loaded(aInfo);
sl@0
   412
			if(r!=KErrNone)
sl@0
   413
				return r;
sl@0
   414
			}
sl@0
   415
		}
sl@0
   416
	return DEpocCodeSeg::Loaded(aInfo);
sl@0
   417
	}
sl@0
   418
sl@0
   419
sl@0
   420
void DMemModelCodeSeg::ReadExportDir(TUint32* aDest)
sl@0
   421
	{
sl@0
   422
	__KTRACE_OPT(KDLL,Kern::Printf("DMemModelCodeSeg::ReadExportDir %08x",aDest));
sl@0
   423
	if (!iXIP)
sl@0
   424
		{
sl@0
   425
		SRamCodeInfo& ri=RamInfo();
sl@0
   426
		TInt size=(ri.iExportDirCount+1)*sizeof(TLinAddr);
sl@0
   427
		kumemput32(aDest, (const TUint32*)(ri.iExportDir-sizeof(TUint32)), size);
sl@0
   428
		}
sl@0
   429
	}
sl@0
   430
sl@0
   431
TBool DMemModelCodeSeg::OpenCheck(DProcess* aProcess)
sl@0
   432
	{
sl@0
   433
	return FindCheck(aProcess);
sl@0
   434
	}
sl@0
   435
sl@0
   436
TBool DMemModelCodeSeg::FindCheck(DProcess* aProcess)
sl@0
   437
	{
sl@0
   438
	__KTRACE_OPT(KDLL,Kern::Printf("CSEG:%08x Compat? proc=%O",this,aProcess));
sl@0
   439
	if (!aProcess)
sl@0
   440
		return !iAttachProcess;	// can't reuse same code segment for a new instance of the process
sl@0
   441
	DMemModelProcess& p=*(DMemModelProcess*)aProcess;
sl@0
   442
	DCodeSeg* pPSeg=p.CodeSeg();
sl@0
   443
	if (iAttachProcess && iAttachProcess!=aProcess)
sl@0
   444
		return EFalse;
sl@0
   445
	if (iExeCodeSeg && iExeCodeSeg!=pPSeg)
sl@0
   446
		return EFalse;
sl@0
   447
	if (!iAttachProcess && (iMark & EMarkDataPresent))
sl@0
   448
		{
sl@0
   449
		// code seg used for moving processes, data present
sl@0
   450
		if (p.iAttributes & DMemModelProcess::EFixedAddress)
sl@0
   451
			return EFalse;
sl@0
   452
		}
sl@0
   453
	return ETrue;
sl@0
   454
	}