kernel/eka/euser/us_func.cpp
changeset 300 1d28c8722707
parent 293 0659d0e1a03c
equal deleted inserted replaced
293:0659d0e1a03c 300:1d28c8722707
   742 	}
   742 	}
   743 
   743 
   744 
   744 
   745 
   745 
   746 
   746 
       
   747 TBool TEntryPointList::AlreadyCalled(TLinAddr aEP)
       
   748 	{
       
   749 	TInt i;
       
   750 
       
   751 	// if we find it in the list before the current one
       
   752 	// then it was already called, return true
       
   753 	for (i=0; i<iCurrentEP; ++i)
       
   754 		if (iEPs[i] == aEP)
       
   755 			return ETrue;
       
   756 
       
   757 	// if it *is* the current one (i==iCurrentEP here)
       
   758 	// then we're in some kind of hideous cycle. There is no
       
   759 	// way to resolve this that isn't wrong, but some people
       
   760 	// may depend on it anyway. The safest thing to do is to
       
   761 	// just claim the EP is already called and hope that
       
   762 	// the constructors aren't actually dependent on each other.
       
   763 	if (iEPs[i] == aEP)
       
   764 		return ETrue;
       
   765 		
       
   766 	// if we find it *after* the current one then it's not
       
   767 	// already been called, but we need to call it now
       
   768 	// rather than when we get that far back up the stack,
       
   769 	// so set that copy to -1.
       
   770 	for (++i; i<iNumEPs; ++i)
       
   771 		if (iEPs[i] == aEP)
       
   772 			iEPs[i] = 0xFFFFFFFFU;
       
   773 
       
   774 	// if this is not the top of the stack recurse, otherwise
       
   775 	// return false so the current load will call it
       
   776 	if (iPrevList)
       
   777 		return iPrevList->AlreadyCalled(aEP);
       
   778 	else
       
   779 		return EFalse;
       
   780 	}
       
   781 
       
   782 
       
   783 TInt TEntryPointList::CallEPs()
       
   784 	{
       
   785 	// The TLS entry for KNestedEntryPointCallKey is the head
       
   786 	// of a linked list of TEntryPointList objects. Add this one
       
   787 	// to the front of the list. iPrevList will end up NULL if
       
   788 	// there is no nested load yet.
       
   789 	// Only one thread per process can be doing a load at a time
       
   790 	// because of the DLL lock, so using TLS for this is fine.
       
   791 	iPrevList=(TEntryPointList*)UserSvr::DllTls(KNestedEntryPointCallKey, KDllUid_Special);
       
   792 	TInt r=UserSvr::DllSetTls(KNestedEntryPointCallKey, KDllUid_Special, this);
       
   793 	if (r != KErrNone)
       
   794 		return r;
       
   795 
       
   796 	// call each entry point unless it's already been called higher
       
   797 	// in the nested loading process, or it's been set to -1 because
       
   798 	// it was called lower in the nested load.
       
   799 	for (iCurrentEP=0; iCurrentEP<iNumEPs; ++iCurrentEP)
       
   800 		{
       
   801 		TLinAddr ep=iEPs[iCurrentEP];
       
   802 		if (ep != 0xFFFFFFFFU && (!iPrevList || !iPrevList->AlreadyCalled(ep)))
       
   803 			{
       
   804 			TLibraryEntry f=(TLibraryEntry)ep;
       
   805 			r = (*f)(KModuleEntryReasonProcessAttach);
       
   806 			if (r != KErrNone)
       
   807 				break;
       
   808 			}
       
   809 		}
       
   810 
       
   811 	// Take this object off the list before returning
       
   812 	UserSvr::DllSetTls(KNestedEntryPointCallKey, KDllUid_Special, iPrevList);
       
   813 
       
   814 	return r;
       
   815 	}
       
   816 
       
   817 
       
   818 
       
   819 
   747 void CallStaticEntryPoints(TBool aInit)
   820 void CallStaticEntryPoints(TBool aInit)
   748 	{
   821 	{
   749 	TLinAddr ep[KMaxLibraryEntryPoints];
   822 	TEntryPointList eplist;
   750 	TInt numEps=KMaxLibraryEntryPoints;
   823 	eplist.iNumEPs=KMaxLibraryEntryPoints;
   751 	TInt r=E32Loader::StaticCallList(numEps, ep);
   824 	TInt r=E32Loader::StaticCallList(eplist.iNumEPs, eplist.iEPs);
   752 	if (r!=KErrNone)
   825 	if (r!=KErrNone)
   753 		return;
   826 		return;
       
   827 	eplist.iNumEPs -= 1; // last EP is always process entry point
   754 	if (aInit)
   828 	if (aInit)
   755 		{
   829 		{
   756 		for (TInt i=0; i<numEps-1; ++i)	// last EP is always process entry point
   830 		eplist.CallEPs();
   757 			{
       
   758 			TLibraryEntry f=(TLibraryEntry)ep[i];
       
   759 			(*f)(KModuleEntryReasonProcessAttach);
       
   760 			}
       
   761 		}
   831 		}
   762 	else
   832 	else
   763 		{
   833 		{
   764 		for (TInt i=numEps-2; i>=0; --i)	// last EP is always process entry point
   834 		for (TInt i=eplist.iNumEPs-1; i>=0; --i)
   765 			{
   835 			{
   766 			TLibraryEntry f=(TLibraryEntry)ep[i];
   836 			TLibraryEntry f=(TLibraryEntry)eplist.iEPs[i];
   767 			(*f)(KModuleEntryReasonProcessDetach);
   837 			(*f)(KModuleEntryReasonProcessDetach);
   768 			}
   838 			}
   769 		}
   839 		}
   770 	}
   840 	}
   771 
   841 
   776 /**
   846 /**
   777 @internalAll
   847 @internalAll
   778 */
   848 */
   779 	{
   849 	{
   780 	CallStaticEntryPoints(ETrue);
   850 	CallStaticEntryPoints(ETrue);
       
   851 	E32Loader::StaticCallsDone();
   781 	}
   852 	}
   782 
   853 
   783 
   854 
   784 
   855 
   785 
   856 
  2015 	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
  2086 	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
  2016 	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
  2087 	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
  2017 	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
  2088 	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
  2018 	};
  2089 	};
  2019 
  2090 
  2020 /* RVCT 3.1 and 4.0 read past the end of arrays when unrolling loops.
       
  2021  * This only happens when using -O3 -Otime, so force to -O2.
       
  2022  */
       
  2023 #if __ARMCC_VERSION >= 310000 
       
  2024 #pragma push
       
  2025 #pragma O2
       
  2026 #endif
       
  2027 
  2091 
  2028 /**
  2092 /**
  2029 Performs a CCITT CRC-32 checksum on the specified data.
  2093 Performs a CCITT CRC-32 checksum on the specified data.
  2030 
  2094 
  2031 On return from this function, the referenced 32 bit integer contains the CRC
  2095 On return from this function, the referenced 32 bit integer contains the CRC
  2042 	TUint32 crc = aCrc;
  2106 	TUint32 crc = aCrc;
  2043 	while (p < q)
  2107 	while (p < q)
  2044 		crc = (crc >> 8) ^ CrcTab32[(crc ^ *p++) & 0xff];
  2108 		crc = (crc >> 8) ^ CrcTab32[(crc ^ *p++) & 0xff];
  2045 	aCrc = crc;
  2109 	aCrc = crc;
  2046 	}
  2110 	}
  2047 #if __ARMCC_VERSION >= 310000 
       
  2048 #pragma pop
       
  2049 #endif