Changeset 2935 in kBuild for trunk/src/kWorker
- Timestamp:
- Sep 18, 2016 8:00:07 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kWorker/kWorker.c
r2934 r2935 100 100 # define KW_LOG(a) do { } while (0) 101 101 #endif 102 103 /** @def KWLDR_LOG 104 * Loader related logging. 105 * @param a Argument list for kwDbgPrintf */ 106 #ifdef KW_LOG_ENABLED 107 # define KWLDR_LOG(a) kwDbgPrintf a 108 #else 109 # define KWLDR_LOG(a) do { } while (0) 110 #endif 111 102 112 103 113 /** @def KWFS_LOG … … 214 224 { 215 225 /** Where we load the image. */ 216 void *pvLoad;226 KU8 *pbLoad; 217 227 /** Virgin copy of the image. */ 218 void *pvCopy;228 KU8 *pbCopy; 219 229 /** Ldr pvBits argument. This is NULL till we've successfully resolved 220 230 * the imports. */ … … 232 242 /** Set if we share memory with other executables. */ 233 243 KBOOL fUseLdBuf; 244 /** Set after the first whole image copy is done. */ 245 KBOOL fCanDoQuick; 246 /** Number of quick copy chunks. */ 247 KU8 cQuickCopyChunks; 248 /** Number of quick zero chunks. */ 249 KU8 cQuickZeroChunks; 250 /** Quicker image copy instructions that skips non-writable parts when 251 * possible. Need to check fCanDoQuick, fUseLdBuf and previous executable 252 * image. */ 253 struct 254 { 255 /** The copy destination. */ 256 KU8 *pbDst; 257 /** The copy source. */ 258 KU8 const *pbSrc; 259 /** How much to copy. */ 260 KSIZE cbToCopy; 261 } aQuickCopyChunks[3]; 262 /** For handling BSS and zero alignment padding when using aQuickCopyChunks. */ 263 struct 264 { 265 /** Where to start zeroing. */ 266 KU8 *pbDst; 267 /** How much to zero. */ 268 KSIZE cbToZero; 269 } aQuickZeroChunks[3]; 234 270 /** Number of imported modules. */ 235 271 KSIZE cImpMods; … … 755 791 /** The module currently occupying g_abDefLdBuf. */ 756 792 static PKWMODULE g_pModInLdBuf = NULL; 793 794 /** The module that previuosly occupied g_abDefLdBuf. */ 795 static PKWMODULE g_pModPrevInLdBuf = NULL; 757 796 758 797 /** Module hash table. */ … … 1424 1463 if (!pMod->fNative) 1425 1464 { 1426 kHlpPageFree(pMod->u.Manual.p vCopy, pMod->cbImage);1427 kHlpPageFree(pMod->u.Manual.p vLoad, pMod->cbImage);1465 kHlpPageFree(pMod->u.Manual.pbCopy, pMod->cbImage); 1466 kHlpPageFree(pMod->u.Manual.pbLoad, pMod->cbImage); 1428 1467 } 1429 1468 … … 1681 1720 1682 1721 /** 1722 * Sets up the quick zero & copy tables for the non-native module. 1723 * 1724 * This is a worker for kwLdrModuleCreateNonNative. 1725 * 1726 * @param pMod The module. 1727 */ 1728 static void kwLdrModuleCreateNonNativeSetupQuickZeroAndCopy(PKWMODULE pMod) 1729 { 1730 PCKLDRSEG paSegs = pMod->pLdrMod->aSegments; 1731 KU32 cSegs = pMod->pLdrMod->cSegments; 1732 KU32 iSeg; 1733 1734 KWLDR_LOG(("Setting up quick zero & copy for %s:\n", pMod->pszPath)); 1735 pMod->u.Manual.cQuickCopyChunks = 0; 1736 pMod->u.Manual.cQuickZeroChunks = 0; 1737 1738 for (iSeg = 0; iSeg < cSegs; iSeg++) 1739 switch (paSegs[iSeg].enmProt) 1740 { 1741 case KPROT_READWRITE: 1742 case KPROT_WRITECOPY: 1743 case KPROT_EXECUTE_READWRITE: 1744 case KPROT_EXECUTE_WRITECOPY: 1745 if (paSegs[iSeg].cbMapped) 1746 { 1747 KU32 iChunk = pMod->u.Manual.cQuickCopyChunks; 1748 if (iChunk < K_ELEMENTS(pMod->u.Manual.aQuickCopyChunks)) 1749 { 1750 /* 1751 * Check for trailing zero words. 1752 */ 1753 KSIZE cbTrailingZeros; 1754 if ( paSegs[iSeg].cbMapped >= 64 * 2 * sizeof(KSIZE) 1755 && (paSegs[iSeg].cbMapped & 7) == 0 1756 && pMod->u.Manual.cQuickZeroChunks < K_ELEMENTS(pMod->u.Manual.aQuickZeroChunks) ) 1757 { 1758 KSIZE const *pauNatural = (KSIZE const *)&pMod->u.Manual.pbCopy[(KSIZE)paSegs[iSeg].RVA]; 1759 KSIZE cNatural = paSegs[iSeg].cbMapped / sizeof(KSIZE); 1760 KSIZE idxFirstZero = cNatural; 1761 while (idxFirstZero > 0) 1762 if (pauNatural[--idxFirstZero] == 0) 1763 { /* likely */ } 1764 else 1765 { 1766 idxFirstZero++; 1767 break; 1768 } 1769 cbTrailingZeros = (cNatural - idxFirstZero) * sizeof(KSIZE); 1770 if (cbTrailingZeros < 128) 1771 cbTrailingZeros = 0; 1772 } 1773 else 1774 cbTrailingZeros = 0; 1775 1776 /* 1777 * Add quick copy entry. 1778 */ 1779 if (cbTrailingZeros < paSegs[iSeg].cbMapped) 1780 { 1781 pMod->u.Manual.aQuickCopyChunks[iChunk].pbDst = &pMod->u.Manual.pbLoad[(KSIZE)paSegs[iSeg].RVA]; 1782 pMod->u.Manual.aQuickCopyChunks[iChunk].pbSrc = &pMod->u.Manual.pbCopy[(KSIZE)paSegs[iSeg].RVA]; 1783 pMod->u.Manual.aQuickCopyChunks[iChunk].cbToCopy = paSegs[iSeg].cbMapped - cbTrailingZeros; 1784 pMod->u.Manual.cQuickCopyChunks = iChunk + 1; 1785 KWLDR_LOG(("aQuickCopyChunks[%u]: %#p LB %#" KSIZE_PRI " <- %p (%*.*s)\n", iChunk, 1786 pMod->u.Manual.aQuickCopyChunks[iChunk].pbDst, 1787 pMod->u.Manual.aQuickCopyChunks[iChunk].cbToCopy, 1788 pMod->u.Manual.aQuickCopyChunks[iChunk].pbSrc, 1789 paSegs[iSeg].cchName, paSegs[iSeg].cchName, paSegs[iSeg].pchName)); 1790 } 1791 1792 /* 1793 * Add quick zero entry. 1794 */ 1795 if (cbTrailingZeros) 1796 { 1797 KU32 iZero = pMod->u.Manual.cQuickZeroChunks; 1798 pMod->u.Manual.aQuickZeroChunks[iZero].pbDst = pMod->u.Manual.aQuickCopyChunks[iChunk].pbDst 1799 + pMod->u.Manual.aQuickCopyChunks[iChunk].cbToCopy; 1800 pMod->u.Manual.aQuickZeroChunks[iZero].cbToZero = cbTrailingZeros; 1801 pMod->u.Manual.cQuickZeroChunks = iZero + 1; 1802 KWLDR_LOG(("aQuickZeroChunks[%u]: %#p LB %#" KSIZE_PRI " <- zero (%*.*s)\n", iZero, 1803 pMod->u.Manual.aQuickZeroChunks[iZero].pbDst, 1804 pMod->u.Manual.aQuickZeroChunks[iZero].cbToZero, 1805 paSegs[iSeg].cchName, paSegs[iSeg].cchName, paSegs[iSeg].pchName)); 1806 } 1807 } 1808 else 1809 { 1810 /* 1811 * We're out of quick copy table entries, so just copy the whole darn thing. 1812 * We cannot 104% guarantee that the segments are in mapping order, so this is simpler. 1813 */ 1814 kHlpAssertFailed(); 1815 pMod->u.Manual.aQuickCopyChunks[0].pbDst = pMod->u.Manual.pbLoad; 1816 pMod->u.Manual.aQuickCopyChunks[0].pbSrc = pMod->u.Manual.pbCopy; 1817 pMod->u.Manual.aQuickCopyChunks[0].cbToCopy = pMod->cbImage; 1818 pMod->u.Manual.cQuickCopyChunks = 1; 1819 KWLDR_LOG(("Quick copy not possible!\n")); 1820 return; 1821 } 1822 } 1823 break; 1824 1825 default: 1826 break; 1827 } 1828 } 1829 1830 1831 /** 1683 1832 * Creates a module using the our own loader. 1684 1833 * … … 1745 1894 pMod->pLdrMod = pLdrMod; 1746 1895 pMod->u.Manual.cImpMods = (KU32)cImports; 1747 pMod->u.Manual.fUseLdBuf = K_FALSE;1748 1896 #if defined(KBUILD_OS_WINDOWS) && defined(KBUILD_ARCH_AMD64) 1749 1897 pMod->u.Manual.fRegisteredFunctionTable = K_FALSE; 1750 1898 #endif 1899 pMod->u.Manual.fUseLdBuf = K_FALSE; 1900 pMod->u.Manual.fCanDoQuick = K_FALSE; 1901 pMod->u.Manual.cQuickZeroChunks = 0; 1902 pMod->u.Manual.cQuickCopyChunks = 0; 1751 1903 pMod->pszPath = (char *)kHlpMemCopy(&pMod->u.Manual.apImpMods[cImports + 1], pszPath, cbPath); 1752 1904 pMod->pwszPath = (wchar_t *)(pMod->pszPath + cbPath + (cbPath & 1)); … … 1758 1910 fFixed = pLdrMod->enmType == KLDRTYPE_EXECUTABLE_FIXED 1759 1911 || pLdrMod->enmType == KLDRTYPE_SHARED_LIBRARY_FIXED; 1760 pMod->u.Manual.p vLoad = fFixed ? (void*)(KUPTR)pLdrMod->aSegments[0].LinkAddress : NULL;1912 pMod->u.Manual.pbLoad = fFixed ? (KU8 *)(KUPTR)pLdrMod->aSegments[0].LinkAddress : NULL; 1761 1913 pMod->cbImage = (KSIZE)kLdrModSize(pLdrMod); 1762 1914 if ( !fFixed 1763 1915 || pLdrMod->enmType != KLDRTYPE_EXECUTABLE_FIXED /* only allow fixed executables */ 1764 || (KUPTR)pMod->u.Manual.p vLoad - (KUPTR)g_abDefLdBuf >= sizeof(g_abDefLdBuf)1765 || sizeof(g_abDefLdBuf) - (KUPTR)pMod->u.Manual.p vLoad - (KUPTR)g_abDefLdBuf < pMod->cbImage)1766 rc = kHlpPageAlloc( &pMod->u.Manual.pvLoad, pMod->cbImage, KPROT_EXECUTE_READWRITE, fFixed);1916 || (KUPTR)pMod->u.Manual.pbLoad - (KUPTR)g_abDefLdBuf >= sizeof(g_abDefLdBuf) 1917 || sizeof(g_abDefLdBuf) - (KUPTR)pMod->u.Manual.pbLoad - (KUPTR)g_abDefLdBuf < pMod->cbImage) 1918 rc = kHlpPageAlloc((void **)&pMod->u.Manual.pbLoad, pMod->cbImage, KPROT_EXECUTE_READWRITE, fFixed); 1767 1919 else 1768 1920 pMod->u.Manual.fUseLdBuf = K_TRUE; 1769 1921 if (rc == 0) 1770 1922 { 1771 rc = kHlpPageAlloc(&pMod->u.Manual.p vCopy, pMod->cbImage, KPROT_READWRITE, K_FALSE);1923 rc = kHlpPageAlloc(&pMod->u.Manual.pbCopy, pMod->cbImage, KPROT_READWRITE, K_FALSE); 1772 1924 if (rc == 0) 1773 1925 { 1774 1775 1926 KI32 iImp; 1776 1927 … … 1778 1929 * Link the module (unless it's an executable image) and process the imports. 1779 1930 */ 1780 pMod->hOurMod = (HMODULE)pMod->u.Manual.p vLoad;1931 pMod->hOurMod = (HMODULE)pMod->u.Manual.pbLoad; 1781 1932 if (!fExe) 1782 1933 kwLdrModuleLink(pMod); 1783 1934 KW_LOG(("New module: %p LB %#010x %s (kLdr)\n", 1784 pMod->u.Manual.p vLoad, pMod->cbImage, pMod->pszPath));1785 kwDebuggerPrintf("TODO: .reload /f %s=%p\n", pMod->pszPath, pMod->u.Manual.p vLoad);1935 pMod->u.Manual.pbLoad, pMod->cbImage, pMod->pszPath)); 1936 kwDebuggerPrintf("TODO: .reload /f %s=%p\n", pMod->pszPath, pMod->u.Manual.pbLoad); 1786 1937 1787 1938 for (iImp = 0; iImp < cImports; iImp++) … … 1800 1951 if (rc == 0) 1801 1952 { 1802 rc = kLdrModGetBits(pLdrMod, pMod->u.Manual.p vCopy, (KUPTR)pMod->u.Manual.pvLoad,1953 rc = kLdrModGetBits(pLdrMod, pMod->u.Manual.pbCopy, (KUPTR)pMod->u.Manual.pbLoad, 1803 1954 kwLdrModuleGetImportCallback, pMod); 1804 1955 if (rc == 0) … … 1809 1960 * loader did that already, right... 1810 1961 */ 1811 KU8 *pbImg = (KU8 *)pMod->u.Manual.p vCopy;1962 KU8 *pbImg = (KU8 *)pMod->u.Manual.pbCopy; 1812 1963 IMAGE_NT_HEADERS const *pNtHdrs; 1813 1964 IMAGE_DATA_DIRECTORY const *pXcptDir; … … 1832 1983 #endif 1833 1984 1985 kwLdrModuleCreateNonNativeSetupQuickZeroAndCopy(pMod); 1986 1834 1987 /* 1835 1988 * Final finish. 1836 1989 */ 1837 pMod->u.Manual.pvBits = pMod->u.Manual.p vCopy;1990 pMod->u.Manual.pvBits = pMod->u.Manual.pbCopy; 1838 1991 pMod->u.Manual.enmState = KWMODSTATE_NEEDS_BITS; 1839 1992 return pMod; … … 1845 1998 } 1846 1999 1847 kHlpPageFree(pMod->u.Manual.p vLoad, pMod->cbImage);2000 kHlpPageFree(pMod->u.Manual.pbLoad, pMod->cbImage); 1848 2001 kwErrPrintf("Failed to allocate %#x bytes\n", pMod->cbImage); 1849 2002 } … … 1879 2032 puValue, pfKind); 1880 2033 else 1881 rc = kLdrModQuerySymbol(pImpMod->pLdrMod, pImpMod->u.Manual.pvBits, (KUPTR)pImpMod->u.Manual.p vLoad,2034 rc = kLdrModQuerySymbol(pImpMod->pLdrMod, pImpMod->u.Manual.pvBits, (KUPTR)pImpMod->u.Manual.pbLoad, 1882 2035 iSymbol, pchSymbol, cchSymbol, pszVersion, 1883 2036 NULL /*pfnGetForwarder*/, NULL /*pvUSer*/, … … 1920 2073 { 1921 2074 KLDRADDR uLdrAddrMain; 1922 int rc = kLdrModQueryMainEntrypoint(pMod->pLdrMod, pMod->u.Manual.pvBits, (KUPTR)pMod->u.Manual.pvLoad, &uLdrAddrMain);2075 int rc = kLdrModQueryMainEntrypoint(pMod->pLdrMod, pMod->u.Manual.pvBits, (KUPTR)pMod->u.Manual.pbLoad, &uLdrAddrMain); 1923 2076 if (rc == 0) 1924 2077 { … … 2152 2305 if (!pMod->fNative) 2153 2306 { 2154 /* Need to copy bits? */ 2307 /* 2308 * Need to copy bits? 2309 */ 2155 2310 if (pMod->u.Manual.enmState == KWMODSTATE_NEEDS_BITS) 2156 2311 { … … 2164 2319 } 2165 2320 #endif 2321 g_pModPrevInLdBuf = g_pModInLdBuf; 2166 2322 g_pModInLdBuf = pMod; 2167 2323 } 2168 2324 2169 kHlpMemCopy(pMod->u.Manual.pvLoad, pMod->u.Manual.pvCopy, pMod->cbImage); 2325 /* Do quick zeroing and copying when we can. */ 2326 pMod->u.Manual.fCanDoQuick = K_FALSE; 2327 if ( pMod->u.Manual.fCanDoQuick 2328 && ( !pMod->u.Manual.fUseLdBuf 2329 || g_pModPrevInLdBuf == pMod)) 2330 { 2331 /* Zero first. */ 2332 kHlpAssert(pMod->u.Manual.cQuickZeroChunks <= 3); 2333 switch (pMod->u.Manual.cQuickZeroChunks) 2334 { 2335 case 3: kHlpMemSet(pMod->u.Manual.aQuickZeroChunks[2].pbDst, 0, pMod->u.Manual.aQuickZeroChunks[2].cbToZero); 2336 case 2: kHlpMemSet(pMod->u.Manual.aQuickZeroChunks[1].pbDst, 0, pMod->u.Manual.aQuickZeroChunks[1].cbToZero); 2337 case 1: kHlpMemSet(pMod->u.Manual.aQuickZeroChunks[0].pbDst, 0, pMod->u.Manual.aQuickZeroChunks[0].cbToZero); 2338 case 0: break; 2339 } 2340 2341 /* Then copy. */ 2342 kHlpAssert(pMod->u.Manual.cQuickCopyChunks > 0); 2343 kHlpAssert(pMod->u.Manual.cQuickCopyChunks <= 3); 2344 switch (pMod->u.Manual.cQuickCopyChunks) 2345 { 2346 case 3: kHlpMemCopy(pMod->u.Manual.aQuickCopyChunks[2].pbDst, pMod->u.Manual.aQuickCopyChunks[2].pbSrc, 2347 pMod->u.Manual.aQuickCopyChunks[2].cbToCopy); 2348 case 2: kHlpMemCopy(pMod->u.Manual.aQuickCopyChunks[1].pbDst, pMod->u.Manual.aQuickCopyChunks[1].pbSrc, 2349 pMod->u.Manual.aQuickCopyChunks[1].cbToCopy); 2350 case 1: kHlpMemCopy(pMod->u.Manual.aQuickCopyChunks[0].pbDst, pMod->u.Manual.aQuickCopyChunks[0].pbSrc, 2351 pMod->u.Manual.aQuickCopyChunks[0].cbToCopy); 2352 case 0: break; 2353 } 2354 } 2355 /* Must copy the whole image. */ 2356 else 2357 { 2358 kHlpMemCopy(pMod->u.Manual.pbLoad, pMod->u.Manual.pbCopy, pMod->cbImage); 2359 pMod->u.Manual.fCanDoQuick = K_TRUE; 2360 } 2170 2361 pMod->u.Manual.enmState = KWMODSTATE_NEEDS_INIT; 2171 2362 } 2172 2363 2173 2364 #if defined(KBUILD_OS_WINDOWS) && defined(KBUILD_ARCH_AMD64) 2174 /* Need to register function table? */ 2365 /* 2366 * Need to register function table? 2367 */ 2175 2368 if ( !pMod->u.Manual.fRegisteredFunctionTable 2176 2369 && pMod->u.Manual.cFunctions > 0) … … 2178 2371 pMod->u.Manual.fRegisteredFunctionTable = RtlAddFunctionTable(pMod->u.Manual.paFunctions, 2179 2372 pMod->u.Manual.cFunctions, 2180 (KUPTR)pMod->u.Manual.p vLoad) != FALSE;2373 (KUPTR)pMod->u.Manual.pbLoad) != FALSE; 2181 2374 kHlpAssert(pMod->u.Manual.fRegisteredFunctionTable); 2182 2375 } … … 2185 2378 if (pMod->u.Manual.enmState == KWMODSTATE_NEEDS_INIT) 2186 2379 { 2187 /* Must do imports first, but mark our module as being initialized to avoid 2188 endless recursion should there be a dependency loop. */ 2380 /* 2381 * Must do imports first, but mark our module as being initialized to avoid 2382 * endless recursion should there be a dependency loop. 2383 */ 2189 2384 KSIZE iImp; 2190 2385 pMod->u.Manual.enmState = KWMODSTATE_BEING_INITED; … … 2197 2392 } 2198 2393 2199 rc = kLdrModCallInit(pMod->pLdrMod, pMod->u.Manual.p vLoad, (KUPTR)pMod->u.Manual.pvLoad);2394 rc = kLdrModCallInit(pMod->pLdrMod, pMod->u.Manual.pbLoad, (KUPTR)pMod->hOurMod); 2200 2395 if (rc == 0) 2201 2396 pMod->u.Manual.enmState = KWMODSTATE_READY; … … 4081 4276 int rc = kLdrModQuerySymbol(pMod->pLdrMod, 4082 4277 pMod->fNative ? NULL : pMod->u.Manual.pvBits, 4083 pMod->fNative ? KLDRMOD_BASEADDRESS_MAP : (KUPTR)pMod->u.Manual.p vLoad,4278 pMod->fNative ? KLDRMOD_BASEADDRESS_MAP : (KUPTR)pMod->u.Manual.pbLoad, 4084 4279 KU32_MAX /*iSymbol*/, 4085 4280 pszProc, … … 8271 8466 __except (EXCEPTION_EXECUTE_HANDLER) 8272 8467 { 8468 kwErrPrintf("Caught exception %#x!\n", GetExceptionCode()); 8273 8469 rcExit = 512; 8274 8470 }
Note:
See TracChangeset
for help on using the changeset viewer.