Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// @SYMTestCaseID KBASE-DP_FUNC_ATTRIBUTES-0303
// @SYMTestCaseDesc Symbian OS Toolchain's Paging Override and the
// Paging Policy settings
// @SYMREQ REQ6808
// @SYMPREQ PREQ1110
// @SYMTestPriority High
// @SYMTestActions
// 1. Load executables with the RProcess API and run them. Each executable has a
// different set of attributes:
// " Paging attribute: paged, unpaged or no paging attribute in MMP and/or
// OBY files
// " Compression mode: specified or not
// " Executable built in ROM as 'data' or 'file'
// " Solid binaries or aliases
// Retrieve and analyse the demand paging activity trace caused by the preceding
// action, in order to determine whether this binary is paged on demand or not.
// 2. Repeat the preceding action by loading DLLs with the RLibrary API and
// making calls to them.
// @SYMTestExpectedResults
// 1. Process complete without error. If, according to the trace data gathered,
// the main thread newly created process causes the executable to be paged in,
// then it is a proof that the executable is paged. Depending on the Paging
// Override setting and the Loader Paging Policy specified at the time the ROM was
// built, the Loader makes a decision as to whether page the binary or not,
// according to the rules listed in the Design Sketch. This is how we determine
// this, in this order:
// a. If ROM paging is disabled: not paged
// b. If executable was built in ROM as 'data': not paged
// c. If the a file compression scheme was specified at ROM build time: not paged
// d. If the Loader Paging policy is 'NOT PAGED': not paged
// e. If the Loader Paging policy is 'ALWAYS PAGE': paged
// f. If the Paging Override is 'NOT PAGED': not paged
// g. If the Paging Override is 'ALWAYS PAGE': paged
// h. If the OBY paging keyword for this executable is 'PAGED': paged
// i. If the OBY paging keyword for this executable is 'NOT PAGED': unpaged
// j. If the MMP paging keyword for this executable is 'PAGED': paged
// k. If the MMP paging keyword for this executable is 'NOT PAGED': not paged
// l. If the Paging Override is 'DEFAULT UNPAGED': not paged
// m. If the Paging Override is 'DEFAULT PAGED': paged
// n. If the Paging Policy is 'DEFAULT UNPAGED': not paged
// o. The executable must be paged
// 2. DLL is loaded. Functions are called and complete without errors. The rules
// to determine whether the binary should be paged or not are the same as in the
// preceding action.
//
//
#include <e32test.h>
#include <e32ldr.h>
#include <d32btrace.h>
#include "u32std.h"
#include <f32file.h>
#include <dptest.h>
#define TEST_EQ(a,b) { if (a != b) { test.Printf(_L("%d != %d\n"), a, b); test(EFalse); } }
#define TEST_CONDITION(a) { if (!a) { test.Printf(_L("TEST FAILED at line %d\n"), __LINE__); pass = EFalse; } }
#define LE4(a) ((TUint) (*((a) + 3) << 24) + (*((a) + 2) << 16) + (*((a) + 1) << 8) + *(a))
RTest test(_L("T_DPATTR"));
RBTrace btrace;
RFs fs;
// ROM paging settings
TBool gIsRomDemangPagingEnabled;
TInt gPagingOverride;
TInt gPagingPolicy;
// This process
TUint32 gNThreadId = 0;
// Test executables attributes flags
enum
{
ENone = 0,
EMMPPaged = 1 << 0, // "PAGED" keyword in MMP file
EMMPUnpaged = 1 << 1, // "UNPAGED" keyword in MMP file
EMMPCompressTarget = 1 << 2, // "COMPRESSTARGET" keyword in MMP file
EMMPNoCompressTarget = 1 << 3, // "UNCOMPRESSTARGET" keyword in MMP file
EIBYData = 1 << 4, // File included as "data" in IBY file
EIBYFile = 1 << 5, // File included as "file" in IBY file
EIBYFileCompress = 1 << 6, // File included as "file_x_" in IBY file (_x_=compression scheme)
EIBYPaged = 1 << 7, // File declared "paged" in IBY file
EIBYUnpaged = 1 << 8, // File declared "unpaged in IBY file
EIBYAlias = 1 << 9, // File name is an alias
EDLLWritableStaticData = 1 << 10 // DLL contains writable static data
};
// Test executables attributes
const TUint testExeAttr[] =
{
/* 000 - does not exist */ ENone,
/* 001 */ EIBYFile,
/* 002 */ EMMPPaged | EIBYFile,
/* 003 */ EMMPUnpaged | EIBYFile,
/* 004 */ EIBYFileCompress,
/* 005 */ EMMPPaged | EIBYFileCompress,
/* 006 */ EMMPUnpaged | EIBYFileCompress,
/* 007 */ EIBYFileCompress,
/* 008 */ EMMPPaged | EIBYFileCompress,
/* 009 */ EMMPUnpaged | EIBYFileCompress,
/* 010 */ EIBYFileCompress,
/* 011 */ EMMPPaged | EIBYFileCompress,
/* 012 */ EMMPUnpaged | EIBYFileCompress,
/* 013 */ EIBYFile | EMMPCompressTarget,
/* 014 */ EMMPPaged | EIBYFile | EMMPNoCompressTarget,
/* 015 */ EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged,
/* 016 */ EIBYData,
/* 017 */ EMMPPaged | EIBYData,
/* 018 */ EMMPUnpaged | EIBYData,
/* 019 */ EIBYFile | EIBYPaged,
/* 020 */ EMMPPaged | EIBYFile | EIBYPaged,
/* 021 */ EMMPUnpaged | EIBYFile | EIBYPaged,
/* 022 */ EIBYFile | EIBYUnpaged,
/* 023 */ EMMPPaged | EIBYFile | EIBYUnpaged,
/* 024 */ EMMPUnpaged | EIBYFile | EIBYUnpaged,
/* 025 */ EIBYData | EIBYPaged,
/* 026 */ EMMPPaged | EIBYData | EIBYPaged,
/* 027 */ EMMPUnpaged | EIBYData | EIBYPaged,
/* 028 */ EIBYData | EIBYUnpaged,
/* 029 */ EMMPPaged | EIBYData | EIBYUnpaged,
/* 030 */ EMMPUnpaged | EIBYData | EIBYUnpaged,
/* 031 */ EIBYAlias | EIBYFile,
/* 032 */ EIBYAlias | EMMPPaged | EIBYFile,
/* 033 */ EIBYAlias | EMMPUnpaged | EIBYFile,
/* 034 */ EIBYAlias | EIBYFileCompress,
/* 035 */ EIBYAlias | EMMPPaged | EIBYFileCompress,
/* 036 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress,
/* 037 */ EIBYAlias | EIBYFileCompress,
/* 038 */ EIBYAlias | EMMPPaged | EIBYFileCompress,
/* 039 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress,
/* 040 */ EIBYAlias | EIBYFileCompress,
/* 041 */ EIBYAlias | EMMPPaged | EIBYFileCompress,
/* 042 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress,
/* 043 */ EIBYAlias | EIBYFile | EMMPCompressTarget,
/* 044 */ EIBYAlias | EMMPPaged | EIBYFile | EMMPNoCompressTarget,
/* 045 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged,
/* 046 */ EIBYAlias | EIBYData,
/* 047 */ EIBYAlias | EMMPPaged | EIBYData,
/* 048 */ EIBYAlias | EMMPUnpaged | EIBYData,
/* 049 */ EIBYAlias | EIBYFile | EIBYPaged,
/* 050 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYPaged,
/* 051 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYPaged,
/* 052 */ EIBYAlias | EIBYFile | EIBYUnpaged,
/* 053 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYUnpaged,
/* 054 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYUnpaged,
/* 055 */ EIBYAlias | EIBYData | EIBYPaged,
/* 056 */ EIBYAlias | EMMPPaged | EIBYData | EIBYPaged,
/* 057 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYPaged,
/* 058 */ EIBYAlias | EIBYData | EIBYUnpaged,
/* 059 */ EIBYAlias | EMMPPaged | EIBYData | EIBYUnpaged,
/* 060 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYUnpaged
};
const TUint testDllAttr[] =
{
/* 000 - does not exist */ ENone,
/* 001 */ EIBYFile,
/* 002 */ EMMPPaged | EIBYFile,
/* 003 */ EMMPUnpaged | EIBYFile,
/* 004 */ EIBYFileCompress,
/* 005 */ EMMPPaged | EIBYFileCompress,
/* 006 */ EMMPUnpaged | EIBYFileCompress,
/* 007 */ EDLLWritableStaticData,
/* 008 */ EMMPPaged | EDLLWritableStaticData,
/* 009 */ EMMPUnpaged | EDLLWritableStaticData,
/* 010 */ EIBYFileCompress,
/* 011 */ EMMPPaged | EIBYFileCompress,
/* 012 */ EMMPUnpaged | EIBYFileCompress,
/* 013 */ EIBYFile | EMMPCompressTarget,
/* 014 */ EMMPPaged | EIBYFile | EMMPNoCompressTarget,
/* 015 */ EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged,
/* 016 */ EIBYData,
/* 017 */ EMMPPaged | EIBYData,
/* 018 */ EMMPUnpaged | EIBYData,
/* 019 */ EIBYFile | EIBYPaged,
/* 020 */ EMMPPaged | EIBYFile | EIBYPaged,
/* 021 */ EMMPUnpaged | EIBYFile | EIBYPaged,
/* 022 */ EIBYFile | EIBYUnpaged,
/* 023 */ EMMPPaged | EIBYFile | EIBYUnpaged,
/* 024 */ EMMPUnpaged | EIBYFile | EIBYUnpaged,
/* 025 */ EIBYData | EIBYPaged,
/* 026 */ EMMPPaged | EIBYData | EIBYPaged,
/* 027 */ EMMPUnpaged | EIBYData | EIBYPaged,
/* 028 */ EIBYData | EIBYUnpaged,
/* 029 */ EMMPPaged | EIBYData | EIBYUnpaged,
/* 030 */ EMMPUnpaged | EIBYData | EIBYUnpaged,
/* 031 */ EIBYAlias | EIBYFile,
/* 032 */ EIBYAlias | EMMPPaged | EIBYFile,
/* 033 */ EIBYAlias | EMMPUnpaged | EIBYFile,
/* 034 */ EIBYAlias | EIBYFileCompress,
/* 035 */ EIBYAlias | EMMPPaged | EIBYFileCompress,
/* 036 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress,
/* 037 */ EIBYAlias | EDLLWritableStaticData,
/* 038 */ EIBYAlias | EMMPPaged | EDLLWritableStaticData,
/* 039 */ EIBYAlias | EMMPUnpaged | EDLLWritableStaticData,
/* 040 */ EIBYAlias | EIBYFileCompress,
/* 041 */ EIBYAlias | EMMPPaged | EIBYFileCompress,
/* 042 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress,
/* 043 */ EIBYAlias | EIBYFile | EMMPCompressTarget,
/* 044 */ EIBYAlias | EMMPPaged | EIBYFile | EMMPNoCompressTarget,
/* 045 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged,
/* 046 */ EIBYAlias | EIBYData,
/* 047 */ EIBYAlias | EMMPPaged | EIBYData,
/* 048 */ EIBYAlias | EMMPUnpaged | EIBYData,
/* 049 */ EIBYAlias | EIBYFile | EIBYPaged,
/* 050 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYPaged,
/* 051 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYPaged,
/* 052 */ EIBYAlias | EIBYFile | EIBYUnpaged,
/* 053 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYUnpaged,
/* 054 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYUnpaged,
/* 055 */ EIBYAlias | EIBYData | EIBYPaged,
/* 056 */ EIBYAlias | EMMPPaged | EIBYData | EIBYPaged,
/* 057 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYPaged,
/* 058 */ EIBYAlias | EIBYData | EIBYUnpaged,
/* 059 */ EIBYAlias | EMMPPaged | EIBYData | EIBYUnpaged,
/* 060 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYUnpaged
};
void InitNThreadID()
{
_LIT(KThreadName, "ARandomThreadName");
btrace.SetFilter(BTrace::EThreadIdentification, ETrue);
btrace.Empty();
btrace.SetMode(RBTrace::EEnable);
// rename the current thread to force a ThreadID trace
User::RenameThread(KThreadName);
btrace.SetMode(0);
TInt size;
TUint8* pDataStart;
TUint8* pCurrentRecord;
// extract the nano-kernel thread ID from the trace
while ((size = btrace.GetData(pDataStart)) != 0)
{
pCurrentRecord = pDataStart;
while (pCurrentRecord - pDataStart < size)
{
TInt extensionCount = 4 * (
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EHeader2Present ? 1 : 0) +
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestampPresent ? 1 : 0) +
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestamp2Present ? 1 : 0) +
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EContextIdPresent ? 1 : 0) +
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EPcPresent ? 1 : 0) +
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EExtraPresent ? 1 : 0));
//
if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EThreadIdentification) && (pCurrentRecord[BTrace::ESubCategoryIndex] == BTrace::EThreadName))
{
TBuf<255> threadName;
threadName.Format(_L(""));
for (TUint8* j = pCurrentRecord + 12 + extensionCount; j < pCurrentRecord + *pCurrentRecord; j++)
{
threadName.AppendFormat(_L("%c"), *j);
}
if (threadName == KThreadName)
{
test.Printf(_L("This thread's NThread ID: %08x\n"), LE4(pCurrentRecord + 4 + extensionCount));
gNThreadId = LE4(pCurrentRecord + 4 + extensionCount);
}
}
pCurrentRecord = BTrace::NextRecord(pCurrentRecord);
}
btrace.DataUsed();
}
}
void LoadExesRom()
{
TInt r;
TBool pass = ETrue;
r = btrace.ResizeBuffer(32768); // 32k should be large enough
TEST_EQ(r, KErrNone);
btrace.SetFilter(BTrace::EPaging, ETrue);
btrace.SetFilter(BTrace::EThreadIdentification, ETrue);
btrace.SetMode(0);
for (TInt i = 1; i <= 60; i++)
{
TBuf<255> filename;
filename.Format(_L("Z:\\SYS\\BIN\\DPEXE%03d.EXE"), i);
test.Printf(_L("Loading %S... "), &filename);
TBool paged = EFalse;
TBool inRom = EFalse;
TUint32 nthreadAddr = 0;
TBuf<255> processName;
if (fs.IsFileInRom(filename) != NULL)
{
inRom = ETrue;
}
else
{
inRom = EFalse;
}
// Ensure that the paging live list is empty
r = DPTest::FlushCache();
if (gIsRomDemangPagingEnabled)
{
TEST_EQ(r, KErrNone);
}
else
{
TEST_EQ(r, KErrNotSupported);
}
btrace.Empty(); // empty the BTrace buffer
btrace.SetMode(RBTrace::EEnable);
RProcess proc;
r = proc.Create(filename, _L(""));
if ((testExeAttr[i] & EIBYAlias) && (testExeAttr[i] & EIBYData) && (gIsRomDemangPagingEnabled))
// There cannot be aliases mapping to "data" files since they are moved to ROFS if the ROM is paged
{
TEST_EQ(r, KErrNotFound);
continue;
}
else
{
TEST_EQ(r, KErrNone);
}
// Resume the process and wait until it completes
TRequestStatus ps;
proc.Logon(ps);
proc.Resume();
proc.Close();
User::WaitForRequest(ps);
// Disable trace
btrace.SetMode(0);
TInt size;
TUint8* pDataStart;
TUint8* pCurrentRecord;
// We have a while loop here, in the unlikely case that our trace is fragmented
while ((size = btrace.GetData(pDataStart)) != 0)
{
pCurrentRecord = pDataStart;
while (pCurrentRecord - pDataStart < size)
{
// Number of bytes used by the BTrace extensions
TInt extensionCount = 4 * (
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EHeader2Present ? 1 : 0) +
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestampPresent ? 1 : 0) +
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestamp2Present ? 1 : 0) +
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EContextIdPresent ? 1 : 0) +
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EPcPresent ? 1 : 0) +
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EExtraPresent ? 1 : 0));
if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EThreadIdentification) && (pCurrentRecord[BTrace::ESubCategoryIndex] == BTrace::EProcessName))
// Process renamed
{
processName.Format(_L(""));
for (TUint8* j = pCurrentRecord + 12 + extensionCount; j < pCurrentRecord + *pCurrentRecord; j++)
{
processName.AppendFormat(_L("%c"), *j);
}
TBuf<255> expected;
expected.Format(_L("dpexe%03d.exe[%08x]%04x"), i, 0, 1);
if (processName == expected)
{
nthreadAddr = LE4(pCurrentRecord + 4 + extensionCount);
}
}
if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EPaging) && (LE4(pCurrentRecord + 8) == nthreadAddr))
/* The main thread of the test process tries to page in the test executable */
{
paged = ETrue;
}
pCurrentRecord = BTrace::NextRecord(pCurrentRecord); // move on to the next record
}
btrace.DataUsed();
}
if (paged)
test.Printf(_L("paged!\n"));
else
test.Printf(_L("not paged!\n"));
if (!gIsRomDemangPagingEnabled)
// ROM paging disabled. All files are in ROM and unpaged
{
test.Printf(_L("ROM Paging disabled: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(!paged);
}
else if (testExeAttr[i] & EIBYData)
// data - if ROM paged, then these executables will be moved to ROFS
// these are always expected to be RAM loaded
{
test.Printf(_L("EXE is DATA in ROFS\n"));
TEST_CONDITION(!inRom);
}
else if (testExeAttr[i] & EIBYFileCompress)
// Compression format specified in the IBY file
// These are expected to be stay in ROM, but will be RAM-loaded
{
test.Printf(_L("EXE has own compression method: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(!paged);
}
// from this point onwards, all executables can potentially be paged - paging policy takes precedence
else if (gPagingPolicy == EKernelConfigCodePagingPolicyNoPaging)
{
test.Printf(_L("Paging policy is No Paging: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(!paged);
}
else if (gPagingPolicy == EKernelConfigCodePagingPolicyAlwaysPage)
{
test.Printf(_L("Paging policy is No Paging: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(paged);
}
// from this point onwards, paging policy is either Default Paged or Default Unpaged - paging override takes precedence
else if (gPagingOverride == EKernelConfigCodePagingPolicyNoPaging)
{
test.Printf(_L("Paging override is No Paging: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(!paged);
}
else if (gPagingOverride == EKernelConfigCodePagingPolicyAlwaysPage)
{
test.Printf(_L("Paging override is Always Page: should be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(paged);
}
// from this point onwards, paging policy and override are either Default Paged or Default Unpaged - IBY setting takes precedence
else if (testExeAttr[i] & EIBYPaged)
{
test.Printf(_L("Paged keyword in OBY: should be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(paged);
}
else if (testExeAttr[i] & EIBYUnpaged)
{
test.Printf(_L("Unpaged keyword in OBY: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(!paged);
}
// Next, MMP setting takes precedence
else if (testExeAttr[i] & EMMPPaged)
{
test.Printf(_L("Paged keyword in MMP: should be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(paged);
}
else if (testExeAttr[i] & EMMPUnpaged)
{
test.Printf(_L("Unpaged keyword in MMP: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(!paged);
}
// The test exe has no attribute. Paging overright default paging mode takes precedence
else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultUnpaged)
{
test.Printf(_L("Paging override is Default Unpaged: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(!paged);
}
else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultPaged)
{
test.Printf(_L("Paging override is Default Paged: should be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(paged);
}
// Paging policy default paging mode takes precedence
else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultUnpaged)
{
test.Printf(_L("Paging policy is Default Unpaged: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(!paged);
}
else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultPaged)
{
test.Printf(_L("Paging policy is Default paged: should be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(paged);
}
// ROM Paging enabled without a default paging policy - this should not happen (default policy is No Paging)
else
{
test.Printf(_L("No paging policy!\n"));
test(EFalse);
}
}
test(pass);
}
void LoadDllsRom()
{
TInt r;
TBool pass = ETrue;
r = btrace.ResizeBuffer(32768); // 32k should be large enough
TEST_EQ(r, KErrNone);
btrace.SetFilter(BTrace::EPaging, ETrue);
btrace.SetFilter(BTrace::EThreadIdentification, ETrue);
btrace.SetMode(0);
for (TInt i = 1; i <= 60; i++)
{
TBuf<255> filename;
filename.Format(_L("Z:\\SYS\\BIN\\DPDLL%03d.DLL"), i);
test.Printf(_L("Loading %S... "), &filename);
TBool paged = EFalse;
TBool inRom = EFalse;
TUint libLoadEnd;
TInt filesize;
TUint8* addr;
if ((addr = fs.IsFileInRom(filename)) != NULL)
{
inRom = ETrue;
}
else
{
inRom = EFalse;
}
RFile file;
r = file.Open(fs, filename, EFileRead);
if ((testDllAttr[i] & EIBYAlias) && (testDllAttr[i] & EIBYData) && (gIsRomDemangPagingEnabled))
// There cannot be aliases mapping to "data" files since they are moved to ROFS if the ROM is paged
{
TEST_EQ(r, KErrNotFound);
continue;
}
else
{
TEST_EQ(r, KErrNone);
}
r = file.Size(filesize);
TEST_EQ(r, KErrNone);
file.Close();
// Ensure that the paging live list is empty
r = DPTest::FlushCache();
if (gIsRomDemangPagingEnabled)
{
TEST_EQ(r, KErrNone);
}
else
{
TEST_EQ(r, KErrNotSupported);
}
btrace.Empty(); // empty the BTrace buffer
btrace.SetMode(RBTrace::EEnable);
RLibrary lib;
r = lib.Load(filename);
libLoadEnd = User::FastCounter();
TEST_EQ(r, KErrNone);
TLibraryFunction function1;
TLibraryFunction function2;
TLibraryFunction function3;
TLibraryFunction function4;
function1 = lib.Lookup(1);
function2 = lib.Lookup(2);
function3 = lib.Lookup(3);
function4 = lib.Lookup(4);
test(function1 != NULL);
test(function2 != NULL);
test(function3 != NULL);
test(function4 == NULL);
// Resume the process and wait until it completes
function1();
function2();
function3();
lib.Close();
//processResumeStart = User::FastCounter();
//processResumeEnd = User::FastCounter();
// Disable trace
btrace.SetMode(0);
TInt size;
TUint8* pDataStart;
TUint8* pCurrentRecord;
// We have a while loop here, in the unlikely case that our trace is fragmented
while ((size = btrace.GetData(pDataStart)) != 0)
{
pCurrentRecord = pDataStart;
while (pCurrentRecord - pDataStart < size)
{
// Number of bytes used by the BTrace extensions
TInt extensionCount = 4 * (
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EHeader2Present ? 1 : 0) +
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestampPresent ? 1 : 0) +
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestamp2Present ? 1 : 0) +
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EContextIdPresent ? 1 : 0) +
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EPcPresent ? 1 : 0) +
(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EExtraPresent ? 1 : 0));
if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EPaging)
&& (pCurrentRecord[BTrace::ESubCategoryIndex] == BTrace::EPagingPageInBegin)
&& (LE4(pCurrentRecord + 4) > libLoadEnd)
&& (LE4(pCurrentRecord + extensionCount) == gNThreadId)
&& (LE4(pCurrentRecord + 4 + extensionCount) >= (TUint32) addr)
&& (LE4(pCurrentRecord + 4 + extensionCount) < ((TUint32) addr) + filesize))
// If the DLL is paged in under this thread after it's been RLibrary::Load'ed, then we assume the DLL is paged
{
paged = ETrue;
}
pCurrentRecord = BTrace::NextRecord(pCurrentRecord); // move on to the next record
}
btrace.DataUsed();
}
if (paged)
test.Printf(_L("paged!\n"));
else
test.Printf(_L("not paged!\n"));
if (!gIsRomDemangPagingEnabled)
// ROM paging disabled. All files are in ROM and unpaged
{
test.Printf(_L("ROM Paging disabled: shouldn't be paged\n"));
test(inRom);
TEST_CONDITION(!paged);
}
else if (testDllAttr[i] & EIBYData)
// data - if ROM paged, then these executables will be moved to ROFS
// these are always expected to be RAM loaded
{
test.Printf(_L("DLL is DATA in ROFS: shouldn't be paged\n"));
TEST_CONDITION(!inRom);
TEST_CONDITION(!paged);
}
else if (testDllAttr[i] & EIBYFileCompress)
// Compression format specified in the IBY file
// These are expected to be stay in ROM, but will be RAM-loaded
{
test.Printf(_L("DLL has own compression method: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(!paged);
}
// from this point onwards, all executables can potentially be paged - paging policy takes precedence
else if (gPagingPolicy == EKernelConfigCodePagingPolicyNoPaging)
{
test.Printf(_L("Paging policy is No Paging: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(!paged);
}
else if (gPagingPolicy == EKernelConfigCodePagingPolicyAlwaysPage)
{
test.Printf(_L("Paging policy is Always Page: should be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(paged);
}
// from this point onwards, paging policy is either Default Paged or Default Unpaged - paging override takes precedence
else if (gPagingOverride == EKernelConfigCodePagingPolicyNoPaging)
{
test.Printf(_L("Paging override is No Paging: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(!paged);
}
else if (gPagingOverride == EKernelConfigCodePagingPolicyAlwaysPage)
{
test.Printf(_L("Paging override is Always Page: should be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(paged);
}
// from this point onwards, paging policy and override are either Default Paged or Default Unpaged - IBY setting takes precedence
else if (testDllAttr[i] & EIBYPaged)
{
test.Printf(_L("Paged keyword in OBY: should be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(paged);
}
else if (testDllAttr[i] & EIBYUnpaged)
{
test.Printf(_L("Unpaged keyword in OBY: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(!paged);
}
// Next, MMP setting takes precedence
else if (testDllAttr[i] & EMMPPaged)
{
test.Printf(_L("Paged keyword in MMP: should be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(paged);
}
else if (testDllAttr[i] & EMMPUnpaged)
{
test.Printf(_L("Unpaged keyword in MMP: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(!paged);
}
// The test exe has no attribute. Paging overright default paging mode takes precedence
else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultUnpaged)
{
test.Printf(_L("Paging override is Default Unpaged: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(!paged);
}
else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultPaged)
{
test.Printf(_L("Paging override is Default Paged: should be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(paged);
}
// Paging policy default paging mode takes precedence
else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultUnpaged)
{
test.Printf(_L("Paging policy is Default Unpaged: shouldn't be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(!paged);
}
else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultPaged)
{
test.Printf(_L("Paging policy is Default paged: should be paged\n"));
TEST_CONDITION(inRom);
TEST_CONDITION(paged);
}
// ROM Paging enabled without a default paging policy - this should not happen (default policy is No Paging)
else
{
test.Printf(_L("No paging policy!\n"));
test(EFalse);
}
}
test(pass);
}
GLDEF_C TInt E32Main()
{
TInt r;
test.Title();
test.Start(_L("Check environment"));
// Open the BTrace handler
r = btrace.Open();
TEST_EQ(r, KErrNone);
// capture the NThread ID of the main thread of the current process
InitNThreadID();
test(gNThreadId != 0);
gPagingPolicy = E32Loader::PagingPolicy();
gPagingOverride = -1;
r = fs.Connect();
TEST_EQ(r, KErrNone);
if (fs.IsFileInRom(_L("\\ovr_nopaging")) != NULL)
{
gPagingOverride = EKernelConfigCodePagingPolicyNoPaging;
}
if (fs.IsFileInRom(_L("\\ovr_alwayspage")) != NULL)
{
gPagingOverride = EKernelConfigCodePagingPolicyAlwaysPage;
}
if (fs.IsFileInRom(_L("\\ovr_defaultunpaged")) != NULL)
{
gPagingOverride = EKernelConfigCodePagingPolicyDefaultUnpaged;
}
if (fs.IsFileInRom(_L("\\ovr_defaultpaged")) != NULL)
{
gPagingOverride = EKernelConfigCodePagingPolicyDefaultPaged;
}
if (fs.IsFileInRom(_L("\\pcy_nopaging")) != NULL)
{
gPagingPolicy = EKernelConfigCodePagingPolicyNoPaging;
}
if (fs.IsFileInRom(_L("\\pcy_alwayspage")) != NULL)
{
gPagingPolicy = EKernelConfigCodePagingPolicyAlwaysPage;
}
if (fs.IsFileInRom(_L("\\pcy_defaultunpaged")) != NULL)
{
gPagingPolicy = EKernelConfigCodePagingPolicyDefaultUnpaged;
}
if (fs.IsFileInRom(_L("\\pcy_defaultpaged")) != NULL)
{
gPagingPolicy = EKernelConfigCodePagingPolicyDefaultPaged;
}
gIsRomDemangPagingEnabled = (fs.IsFileInRom(_L("Z:\\SYS\\BIN\\DPEXE046.EXE")) == NULL);
test.Printf(_L("Demand Paging Enabled? %d\n"), gIsRomDemangPagingEnabled);
test.Printf(_L("PagingOverride %d\n"), gPagingOverride);
test.Printf(_L("PagingPolicy %d\n"), gPagingPolicy);
test.Next(_L("Load ROM EXEs"));
LoadExesRom();
test.Next(_L("Load ROM DLLs"));
LoadDllsRom();
btrace.Close();
fs.Close();
test.End();
test.Close();
return KErrNone;
}