os/kernelhwsrv/kernel/eka/memmodel/epoc/pcodeseg.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\pcodeseg.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include "plat_priv.h"
sl@0
    19
#include <e32uid.h>
sl@0
    20
sl@0
    21
TLinAddr DCodeSeg::ExceptionDescriptor()
sl@0
    22
	{
sl@0
    23
	DEpocCodeSeg* s = (DEpocCodeSeg*)this;
sl@0
    24
	if (s->iXIP)
sl@0
    25
		return s->RomInfo().iExceptionDescriptor;
sl@0
    26
	return s->RamInfo().iExceptionDescriptor;
sl@0
    27
	}
sl@0
    28
sl@0
    29
DEpocCodeSeg::~DEpocCodeSeg()
sl@0
    30
	{
sl@0
    31
	if (!iXIP && iMemory)
sl@0
    32
		{
sl@0
    33
		iMemory->iCodeSeg = 0;
sl@0
    34
		iMemory->Close();
sl@0
    35
		iMemory = NULL;
sl@0
    36
		}
sl@0
    37
	}
sl@0
    38
sl@0
    39
void DEpocCodeSeg::Destruct()
sl@0
    40
	{
sl@0
    41
	DCodeSeg::Wait();
sl@0
    42
	
sl@0
    43
	if (iLoaderCookie!=NULL)
sl@0
    44
		{
sl@0
    45
		if ((TInt) iLoaderCookie&1) // Not set fully loaded
sl@0
    46
			{
sl@0
    47
			iLoaderCookie = (TCodeSegLoaderCookieList*) ( ((TInt) iLoaderCookie) & ~1);
sl@0
    48
			delete iLoaderCookie;
sl@0
    49
			iLoaderCookie=NULL;
sl@0
    50
			}
sl@0
    51
		else
sl@0
    52
			{
sl@0
    53
			// Notify reaper of destruction
sl@0
    54
			NKern::LockSystem();
sl@0
    55
			if (DestructNotifyRequest->IsReady())
sl@0
    56
				{
sl@0
    57
				DThread* t = DestructNotifyThread;
sl@0
    58
				DestructNotifyThread = NULL;				
sl@0
    59
				Kern::QueueRequestComplete(t, DestructNotifyRequest,KErrNone);
sl@0
    60
				}
sl@0
    61
			NKern::UnlockSystem();
sl@0
    62
	
sl@0
    63
			iLoaderCookie->iNext=DestructNotifyList;
sl@0
    64
			DestructNotifyList=iLoaderCookie;
sl@0
    65
			iLoaderCookie=NULL;
sl@0
    66
			}
sl@0
    67
		}
sl@0
    68
sl@0
    69
	DCodeSeg::Signal();
sl@0
    70
	DCodeSeg::Destruct();
sl@0
    71
	}
sl@0
    72
sl@0
    73
void DEpocCodeSeg::Info(TCodeSegCreateInfo& aInfo)
sl@0
    74
	{
sl@0
    75
	CHECK_PAGING_SAFE;
sl@0
    76
	if (iXIP)
sl@0
    77
		{
sl@0
    78
		const TRomImageHeader& rih=RomInfo();
sl@0
    79
		aInfo.iCodeSize=rih.iCodeSize;
sl@0
    80
		aInfo.iTextSize=rih.iTextSize;
sl@0
    81
		aInfo.iDataSize=rih.iDataSize;
sl@0
    82
		aInfo.iBssSize=rih.iBssSize;
sl@0
    83
		aInfo.iTotalDataSize=rih.iTotalDataSize;
sl@0
    84
		aInfo.iExportDir=rih.iExportDir;
sl@0
    85
		aInfo.iExportDirCount=rih.iExportDirCount;
sl@0
    86
		aInfo.iCodeLoadAddress=rih.iCodeAddress;
sl@0
    87
		aInfo.iCodeRunAddress=rih.iCodeAddress;
sl@0
    88
		aInfo.iDataLoadAddress=rih.iDataAddress;
sl@0
    89
		aInfo.iDataRunAddress=rih.iDataBssLinearBase;
sl@0
    90
		aInfo.iExceptionDescriptor = rih.iExceptionDescriptor;
sl@0
    91
		}
sl@0
    92
	else
sl@0
    93
		{
sl@0
    94
		const SRamCodeInfo& ri=RamInfo();
sl@0
    95
		aInfo.iCodeSize=ri.iCodeSize;
sl@0
    96
		aInfo.iTextSize=ri.iTextSize;
sl@0
    97
		aInfo.iDataSize=ri.iDataSize;
sl@0
    98
		aInfo.iBssSize=ri.iBssSize;
sl@0
    99
		aInfo.iTotalDataSize=ri.iDataSize+ri.iBssSize;
sl@0
   100
		aInfo.iExportDir=ri.iExportDir;
sl@0
   101
		aInfo.iExportDirCount=ri.iExportDirCount;
sl@0
   102
		aInfo.iCodeLoadAddress=ri.iCodeLoadAddr;
sl@0
   103
		aInfo.iCodeRunAddress=ri.iCodeRunAddr;
sl@0
   104
		aInfo.iDataLoadAddress=ri.iDataLoadAddr;
sl@0
   105
		aInfo.iDataRunAddress=ri.iDataRunAddr;
sl@0
   106
		aInfo.iExceptionDescriptor = ri.iExceptionDescriptor;
sl@0
   107
		}
sl@0
   108
	DCodeSeg::Info(aInfo);
sl@0
   109
	}
sl@0
   110
sl@0
   111
void DEpocCodeSeg::GetDataSizeAndBase(TInt& aTotalDataSizeOut, TLinAddr& aDataBaseOut)
sl@0
   112
	{
sl@0
   113
	if (iXIP)
sl@0
   114
		{
sl@0
   115
		aTotalDataSizeOut=RomInfo().iTotalDataSize;
sl@0
   116
		aDataBaseOut=RomInfo().iDataBssLinearBase;
sl@0
   117
		}
sl@0
   118
	else
sl@0
   119
		{
sl@0
   120
		aTotalDataSizeOut=RamInfo().iDataSize+RamInfo().iBssSize;
sl@0
   121
		aDataBaseOut=RamInfo().iDataRunAddr;
sl@0
   122
		}	
sl@0
   123
	}
sl@0
   124
sl@0
   125
TLibraryFunction DEpocCodeSeg::Lookup(TInt aOrdinal)
sl@0
   126
	{
sl@0
   127
	CHECK_PAGING_SAFE;
sl@0
   128
	// return NULL for -ve ordinal or 0th ordinal when not stddll/stdexe
sl@0
   129
	if (aOrdinal<0 || (aOrdinal==0 && !(iAttr&ECodeSegAttNmdExpData)))
sl@0
   130
		return NULL;
sl@0
   131
	TInt xdc;
sl@0
   132
	TLinAddr* xd;	// points to the 0th ordinal of export table
sl@0
   133
	if (iXIP)
sl@0
   134
		{
sl@0
   135
		const TRomImageHeader& rih=RomInfo();
sl@0
   136
		xdc=rih.iExportDirCount;
sl@0
   137
		xd=(TLinAddr*)rih.iExportDir - 1;
sl@0
   138
		}
sl@0
   139
	else
sl@0
   140
		{
sl@0
   141
		SRamCodeInfo& ri=RamInfo();
sl@0
   142
		xdc=ri.iExportDirCount;
sl@0
   143
		xd=(TLinAddr*)ri.iExportDir - 1;
sl@0
   144
		}
sl@0
   145
	if (aOrdinal <= xdc)
sl@0
   146
		{
sl@0
   147
		UNLOCK_USER_MEMORY();
sl@0
   148
		TLibraryFunction f=(TLibraryFunction)xd[aOrdinal];
sl@0
   149
		LOCK_USER_MEMORY();
sl@0
   150
		if ((TLinAddr)f == iFileEntryPoint)
sl@0
   151
			f = NULL;
sl@0
   152
		__KTRACE_OPT(KDLL,Kern::Printf("Lookup(%d)->%08x",aOrdinal,f));
sl@0
   153
		return f;
sl@0
   154
		}
sl@0
   155
	__KTRACE_OPT(KDLL,Kern::Printf("Lookup(%d)->NULL",aOrdinal));
sl@0
   156
	return NULL;
sl@0
   157
	}
sl@0
   158
sl@0
   159
TInt DEpocCodeSeg::GetMemoryInfo(TModuleMemoryInfo& aInfo, DProcess*)
sl@0
   160
	{
sl@0
   161
	CHECK_PAGING_SAFE;
sl@0
   162
	if (iXIP)
sl@0
   163
		{
sl@0
   164
		const TRomImageHeader& rih		= RomInfo();
sl@0
   165
		aInfo.iCodeBase					= rih.iCodeAddress;
sl@0
   166
		aInfo.iCodeSize					= rih.iTextSize;
sl@0
   167
		aInfo.iConstDataSize			= rih.iCodeSize - aInfo.iCodeSize;
sl@0
   168
		aInfo.iConstDataBase			= (aInfo.iConstDataSize > 0) ? (aInfo.iCodeBase + aInfo.iCodeSize) : 0;
sl@0
   169
		aInfo.iInitialisedDataBase		= rih.iDataBssLinearBase;
sl@0
   170
		aInfo.iInitialisedDataSize		= rih.iDataSize;
sl@0
   171
		aInfo.iUninitialisedDataSize	= rih.iBssSize;
sl@0
   172
		aInfo.iUninitialisedDataBase	= aInfo.iInitialisedDataBase+aInfo.iInitialisedDataSize;
sl@0
   173
		}
sl@0
   174
	else
sl@0
   175
		{
sl@0
   176
		const SRamCodeInfo& ri			= RamInfo();
sl@0
   177
		aInfo.iCodeBase					= ri.iCodeRunAddr;
sl@0
   178
		aInfo.iCodeSize					= ri.iTextSize;
sl@0
   179
		aInfo.iConstDataSize			= ri.iCodeSize - aInfo.iCodeSize;
sl@0
   180
		aInfo.iConstDataBase			= (aInfo.iConstDataSize > 0) ? (aInfo.iCodeBase + aInfo.iCodeSize) : 0;
sl@0
   181
		aInfo.iInitialisedDataBase		= ri.iDataRunAddr;
sl@0
   182
		aInfo.iInitialisedDataSize		= ri.iDataSize;
sl@0
   183
		aInfo.iUninitialisedDataSize	= ri.iBssSize;
sl@0
   184
		aInfo.iUninitialisedDataBase	= aInfo.iInitialisedDataBase + aInfo.iInitialisedDataSize;
sl@0
   185
		}
sl@0
   186
	return KErrNone;
sl@0
   187
	}
sl@0
   188
sl@0
   189
//const TUint32 KRomImageFlagsAlwaysLoaded=KRomImageFlagPrimary|KRomImageFlagVariant|KRomImageFlagExtension;
sl@0
   190
const TUint32 KRomImageDataFlags=(KRomImageFlagData|KRomImageFlagDataInit|KRomImageFlagDataPresent);
sl@0
   191
TInt DEpocCodeSeg::DoCreate(TCodeSegCreateInfo& aInfo, DProcess* aProcess)
sl@0
   192
	{
sl@0
   193
	__KTRACE_OPT(KDLL,Kern::Printf(">DEpocCodeSeg::DoCreate code_addr=%08x",aInfo.iCodeLoadAddress));
sl@0
   194
	CHECK_PAGING_SAFE;
sl@0
   195
	TInt r=KErrNone;
sl@0
   196
	TBool exeSeg=(iExeCodeSeg==this);
sl@0
   197
	TBool kp=exeSeg && (aProcess->iAttributes&DProcess::ESupervisor);
sl@0
   198
	TBool user_proc=exeSeg && !kp;
sl@0
   199
	if (aInfo.iCodeLoadAddress)
sl@0
   200
		{
sl@0
   201
		iXIP=ETrue;
sl@0
   202
		iInfo=(const TAny*)aInfo.iCodeLoadAddress;
sl@0
   203
		}
sl@0
   204
	if (user_proc)
sl@0
   205
		{
sl@0
   206
		r=aProcess->CreateDataBssStackArea((TProcessCreateInfo&)aInfo);
sl@0
   207
		if (r!=KErrNone)
sl@0
   208
			return r;
sl@0
   209
		}
sl@0
   210
	if (iXIP)
sl@0
   211
		{
sl@0
   212
		const TRomImageHeader& rih=RomInfo();
sl@0
   213
		iXIP=ETrue;
sl@0
   214
		if ( (rih.iFlags & (KRomImageFlagExeInTree|KRomImageFlagDll)) == (KRomImageFlagExeInTree|KRomImageFlagDll))
sl@0
   215
			{
sl@0
   216
			const TRomImageHeader* exeRIH=rih.iDllRefTable->iEntry[0];	// EXE is always first entry
sl@0
   217
			if (aProcess)
sl@0
   218
				{
sl@0
   219
				DEpocCodeSeg* pS=(DEpocCodeSeg*)aProcess->CodeSeg();
sl@0
   220
				if (!pS->iXIP || &pS->RomInfo()!=exeRIH)
sl@0
   221
					return KErrNotSupported;
sl@0
   222
				iExeCodeSeg=pS;
sl@0
   223
				}
sl@0
   224
			}
sl@0
   225
sl@0
   226
		iMark |= (rih.iFlags & KRomImageDataFlags);
sl@0
   227
		iMark |= EMarkRecursiveFlagsValid;
sl@0
   228
		__KTRACE_OPT(KDLL,Kern::Printf("ROM Code Seg: mark %08x attr=%02x",iMark,iAttr));
sl@0
   229
		aInfo.iFileEntryPoint=rih.iEntryPoint;
sl@0
   230
		aInfo.iExportDir=rih.iExportDir;
sl@0
   231
		aInfo.iCodeLoadAddress=rih.iCodeAddress;
sl@0
   232
		aInfo.iCodeRunAddress=rih.iCodeAddress;
sl@0
   233
		iRunAddress = rih.iCodeAddress;
sl@0
   234
		iSize = rih.iCodeSize;
sl@0
   235
		aInfo.iDataLoadAddress=rih.iDataAddress;
sl@0
   236
		if (aInfo.iTotalDataSize && user_proc && aProcess->iDataBssRunAddress!=rih.iDataBssLinearBase)
sl@0
   237
			K::Fault(K::EProcessDataAddressInvalid);
sl@0
   238
		aInfo.iDataRunAddress=rih.iDataBssLinearBase;
sl@0
   239
		aInfo.iExceptionDescriptor = rih.iExceptionDescriptor;
sl@0
   240
		r=DoCreateXIP(aProcess);
sl@0
   241
		return r;
sl@0
   242
		}
sl@0
   243
	iMemory = DEpocCodeSegMemory::New(this);
sl@0
   244
	if (!iMemory)
sl@0
   245
		return KErrNoMemory;
sl@0
   246
	iInfo = &iMemory->iRamInfo;
sl@0
   247
sl@0
   248
	if (aInfo.iUseCodePaging)
sl@0
   249
		{
sl@0
   250
		if ((aInfo.iCodeBlockMapEntries==NULL) || (aInfo.iCodeBlockMapCommon.iLocalDriveNumber<0) ||
sl@0
   251
		(((TInt64) (aInfo.iFileClamp.iCookie[0] | aInfo.iFileClamp.iCookie[1]))==0))
sl@0
   252
				return KErrArgument;
sl@0
   253
			
sl@0
   254
		iLoaderCookie = new TCodeSegLoaderCookieList();
sl@0
   255
		if (!iLoaderCookie)
sl@0
   256
			return KErrNoMemory;
sl@0
   257
				
sl@0
   258
		SBlockMapInfoBase* cbm = &aInfo.iCodeBlockMapCommon;
sl@0
   259
sl@0
   260
		TUint startBlock;
sl@0
   261
		kumemget32(&startBlock, &aInfo.iCodeBlockMapEntries->iStartBlock, sizeof(TUint));
sl@0
   262
sl@0
   263
		iLoaderCookie->iCookie.iDriveNumber = cbm->iLocalDriveNumber;
sl@0
   264
		iLoaderCookie->iCookie.iStartAddress =	cbm->iStartBlockAddress +
sl@0
   265
												startBlock *
sl@0
   266
												cbm->iBlockGranularity +
sl@0
   267
												cbm->iBlockStartOffset;
sl@0
   268
		iLoaderCookie->iCookie.iFileClamp = aInfo.iFileClamp;
sl@0
   269
		// Mark cookie not to be closed yet
sl@0
   270
		iLoaderCookie = (TCodeSegLoaderCookieList*) ( ((TInt) iLoaderCookie) | 1);
sl@0
   271
		}
sl@0
   272
		
sl@0
   273
	SRamCodeInfo& ri=RamInfo();
sl@0
   274
	ri.iCodeSize=aInfo.iCodeSize;
sl@0
   275
	ri.iTextSize=aInfo.iTextSize;
sl@0
   276
	ri.iDataSize=aInfo.iDataSize;
sl@0
   277
	ri.iBssSize=aInfo.iBssSize;
sl@0
   278
	TInt total_data_size=ri.iDataSize+ri.iBssSize;
sl@0
   279
	ri.iExportDirCount=aInfo.iExportDirCount;
sl@0
   280
	if (total_data_size!=0)
sl@0
   281
		{
sl@0
   282
		iMark|=(EMarkData|EMarkDataPresent);
sl@0
   283
		if (!exeSeg)
sl@0
   284
			iMark|=EMarkDataInit;
sl@0
   285
		}
sl@0
   286
	// if this DLL/EXE doesn't have data, don't set valid bit since we don't yet know about its dependencies
sl@0
   287
sl@0
   288
	if (exeSeg)
sl@0
   289
		ri.iDataRunAddr=aProcess->iDataBssRunAddress;
sl@0
   290
	r=DoCreateRam(aInfo, aProcess);
sl@0
   291
	if (r==KErrNone)
sl@0
   292
		{
sl@0
   293
		aInfo.iFileEntryPoint+=ri.iCodeRunAddr;
sl@0
   294
		aInfo.iExportDir+=ri.iCodeRunAddr;
sl@0
   295
		ri.iExportDir=aInfo.iExportDir;
sl@0
   296
		aInfo.iCodeLoadAddress=ri.iCodeLoadAddr;
sl@0
   297
		aInfo.iCodeRunAddress=ri.iCodeRunAddr;
sl@0
   298
		aInfo.iDataLoadAddress=ri.iDataLoadAddr;
sl@0
   299
		aInfo.iDataRunAddress=ri.iDataRunAddr;
sl@0
   300
		TUint32 xd = aInfo.iExceptionDescriptor;
sl@0
   301
		ri.iExceptionDescriptor = xd ? (xd + ri.iCodeRunAddr) : 0;
sl@0
   302
		aInfo.iExceptionDescriptor = ri.iExceptionDescriptor;
sl@0
   303
		iRunAddress = ri.iCodeRunAddr;
sl@0
   304
		}
sl@0
   305
	__KTRACE_OPT(KDLL,Kern::Printf("RAM Code Seg: mark %08x attr=%02x xd=%08x",iMark,iAttr,ri.iExceptionDescriptor));
sl@0
   306
	__KTRACE_OPT(KDLL,Kern::Printf("<DEpocCodeSeg::DoCreate %d",r));
sl@0
   307
	return r;
sl@0
   308
	}
sl@0
   309
sl@0
   310
void DEpocCodeSeg::InitData()
sl@0
   311
	{
sl@0
   312
	__KTRACE_OPT(KDLL,Kern::Printf("DEpocCodeSeg::InitData %C", this));
sl@0
   313
	CHECK_PAGING_SAFE;
sl@0
   314
	TInt bss_size=0;
sl@0
   315
	TInt data_size=0;
sl@0
   316
	TUint8* data_run_ptr=0;
sl@0
   317
	const TUint8* data_load_ptr=0;
sl@0
   318
	if (iXIP)
sl@0
   319
		{
sl@0
   320
		const TRomImageHeader& rih=RomInfo();
sl@0
   321
		bss_size=rih.iBssSize;
sl@0
   322
		data_size=rih.iDataSize;
sl@0
   323
		data_run_ptr=(TUint8*)rih.iDataBssLinearBase;
sl@0
   324
		data_load_ptr=(const TUint8*)rih.iDataAddress;
sl@0
   325
		}
sl@0
   326
	else
sl@0
   327
		{
sl@0
   328
		SRamCodeInfo& ri=RamInfo();
sl@0
   329
		bss_size=ri.iBssSize;
sl@0
   330
		data_size=ri.iDataSize;
sl@0
   331
		data_run_ptr=(TUint8*)ri.iDataRunAddr;
sl@0
   332
		data_load_ptr=(const TUint8*)ri.iDataLoadAddr;
sl@0
   333
		}
sl@0
   334
	UNLOCK_USER_MEMORY();
sl@0
   335
	if (data_size)
sl@0
   336
		memcpy(data_run_ptr, data_load_ptr, data_size);
sl@0
   337
	if (bss_size)
sl@0
   338
		memclr(data_run_ptr+data_size, bss_size);
sl@0
   339
	LOCK_USER_MEMORY();
sl@0
   340
	}
sl@0
   341
sl@0
   342
DCodeSeg* DCodeSeg::FindRomCode(const TAny* aRomImgHdr)
sl@0
   343
	{
sl@0
   344
	CHECK_PAGING_SAFE;
sl@0
   345
	const TRomImageHeader& rih = *(const TRomImageHeader*)aRomImgHdr;
sl@0
   346
	TLinAddr ca = rih.iCodeAddress;
sl@0
   347
	return CodeSegsByAddress.Find(ca);
sl@0
   348
	}
sl@0
   349
sl@0
   350
void P::NormalizeExecutableFileName(TDes& /*aFileName*/)
sl@0
   351
	{
sl@0
   352
	}
sl@0
   353
	
sl@0
   354
TInt DEpocCodeSeg::Loaded(TCodeSegCreateInfo& aInfo)
sl@0
   355
	{
sl@0
   356
	iLoaderCookie = (TCodeSegLoaderCookieList*) ( ((TInt) iLoaderCookie) & ~1);
sl@0
   357
	return DCodeSeg::Loaded(aInfo);
sl@0
   358
	}
sl@0
   359
sl@0
   360
sl@0
   361
//
sl@0
   362
// DEpocCodeSegMemory
sl@0
   363
//
sl@0
   364
sl@0
   365
DEpocCodeSegMemory::DEpocCodeSegMemory(DEpocCodeSeg* aCodeSeg)
sl@0
   366
	: iAccessCount(1), iCodeSeg(aCodeSeg)
sl@0
   367
	{
sl@0
   368
	}
sl@0
   369
sl@0
   370
sl@0
   371
TInt DEpocCodeSegMemory::Open()
sl@0
   372
	{
sl@0
   373
	return __e32_atomic_tas_ord32(&iAccessCount, 1, 1, 0) ? KErrNone : KErrGeneral;
sl@0
   374
	}
sl@0
   375
sl@0
   376
sl@0
   377
TInt DEpocCodeSegMemory::Close()
sl@0
   378
	{
sl@0
   379
	if (__e32_atomic_tas_ord32(&iAccessCount, 1, -1, 0) == 1)
sl@0
   380
		{
sl@0
   381
		AsyncDelete();
sl@0
   382
		return DObject::EObjectDeleted;
sl@0
   383
		}
sl@0
   384
	return 0;
sl@0
   385
	}
sl@0
   386
sl@0
   387