diff -r 0659d0e1a03c -r 1d28c8722707 kernel/eka/euser/us_func.cpp --- a/kernel/eka/euser/us_func.cpp Wed Oct 20 13:58:28 2010 +0100 +++ b/kernel/eka/euser/us_func.cpp Tue Nov 02 15:29:23 2010 +0000 @@ -744,26 +744,96 @@ +TBool TEntryPointList::AlreadyCalled(TLinAddr aEP) + { + TInt i; + + // if we find it in the list before the current one + // then it was already called, return true + for (i=0; iAlreadyCalled(aEP); + else + return EFalse; + } + + +TInt TEntryPointList::CallEPs() + { + // The TLS entry for KNestedEntryPointCallKey is the head + // of a linked list of TEntryPointList objects. Add this one + // to the front of the list. iPrevList will end up NULL if + // there is no nested load yet. + // Only one thread per process can be doing a load at a time + // because of the DLL lock, so using TLS for this is fine. + iPrevList=(TEntryPointList*)UserSvr::DllTls(KNestedEntryPointCallKey, KDllUid_Special); + TInt r=UserSvr::DllSetTls(KNestedEntryPointCallKey, KDllUid_Special, this); + if (r != KErrNone) + return r; + + // call each entry point unless it's already been called higher + // in the nested loading process, or it's been set to -1 because + // it was called lower in the nested load. + for (iCurrentEP=0; iCurrentEPAlreadyCalled(ep))) + { + TLibraryEntry f=(TLibraryEntry)ep; + r = (*f)(KModuleEntryReasonProcessAttach); + if (r != KErrNone) + break; + } + } + + // Take this object off the list before returning + UserSvr::DllSetTls(KNestedEntryPointCallKey, KDllUid_Special, iPrevList); + + return r; + } + + + + void CallStaticEntryPoints(TBool aInit) { - TLinAddr ep[KMaxLibraryEntryPoints]; - TInt numEps=KMaxLibraryEntryPoints; - TInt r=E32Loader::StaticCallList(numEps, ep); + TEntryPointList eplist; + eplist.iNumEPs=KMaxLibraryEntryPoints; + TInt r=E32Loader::StaticCallList(eplist.iNumEPs, eplist.iEPs); if (r!=KErrNone) return; + eplist.iNumEPs -= 1; // last EP is always process entry point if (aInit) { - for (TInt i=0; i=0; --i) // last EP is always process entry point + for (TInt i=eplist.iNumEPs-1; i>=0; --i) { - TLibraryEntry f=(TLibraryEntry)ep[i]; + TLibraryEntry f=(TLibraryEntry)eplist.iEPs[i]; (*f)(KModuleEntryReasonProcessDetach); } } @@ -778,6 +848,7 @@ */ { CallStaticEntryPoints(ETrue); + E32Loader::StaticCallsDone(); } @@ -2017,13 +2088,6 @@ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; -/* RVCT 3.1 and 4.0 read past the end of arrays when unrolling loops. - * This only happens when using -O3 -Otime, so force to -O2. - */ -#if __ARMCC_VERSION >= 310000 -#pragma push -#pragma O2 -#endif /** Performs a CCITT CRC-32 checksum on the specified data. @@ -2044,6 +2108,3 @@ crc = (crc >> 8) ^ CrcTab32[(crc ^ *p++) & 0xff]; aCrc = crc; } -#if __ARMCC_VERSION >= 310000 -#pragma pop -#endif