- Timestamp:
- Feb 8, 2007, 6:06:10 AM (19 years ago)
- Location:
- trunk/kLdr
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/kLdr.h
r2955 r2956 1186 1186 /** The module wasn't an EXE. */ 1187 1187 #define KLDR_ERR_NOT_EXE (KLDR_ERR_BASE + 60) 1188 /** Not implemented yet. */ 1189 #define KLDR_ERR_TODO (KLDR_ERR_BASE + 61) 1188 1190 1189 1191 1190 1192 /** @name kLdrModPE status codes 1191 1193 * @{ */ 1192 #define KLDR_ERR_PE_BASE (KLDR_ERR_BASE + 6 1)1194 #define KLDR_ERR_PE_BASE (KLDR_ERR_BASE + 62) 1193 1195 /** The machine isn't supported by the interpreter. */ 1194 1196 #define KLDR_ERR_PE_UNSUPPORTED_MACHINE (KLDR_ERR_PE_BASE + 0) -
trunk/kLdr/kLdrModMachO.c
r2955 r2956 101 101 /** The size of the mapped image. */ 102 102 KLDRADDR cbImage; 103 /** When set the load commands will be used when mapping / loading the bits. 104 * This is the case when segments are made up of sections that doesn't have 105 * proper ordering and/or aligning in the file alignment. */ 106 int fMapUsingLoadCommands; 103 /** When set the sections in the load command segments must be used when 104 * mapping or loading the image. */ 105 int fMapUsingLoadCommandSections; 107 106 108 107 /** Pointer to the load commands. (endian converted) */ … … 132 131 #if 0 133 132 static int32_t kldrModMachONumberOfImports(PKLDRMOD pMod, const void *pvBits); 134 static int kldrModMachORelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,135 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);136 133 #endif 134 static int kldrModMachORelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress, 135 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); 137 136 138 137 static int kldrModMachODoCreate(PKLDRRDR pRdr, PKLDRMODMACHO *ppMod); … … 140 139 uint32_t *pcSegments, uint32_t *pcbStringPool); 141 140 static int kldrModMachOParseLoadCommands(PKLDRMODMACHO pModMachO, char *pbStringPool, uint32_t cbStringPool); 142 143 #if 0 144 /*static void kldrModMachODoLoadConfigConversion(PIMAGE_LOAD_CONFIG_DIRECTORY64 pLoadCfg); */ 145 static int kLdrModPEDoOptionalHeaderValidation(PKLDRMODMACHO pModMachO); 146 static int kLdrModPEDoSectionHeadersValidation(PKLDRMODMACHO pModMachO); 147 static int kldrModMachODoForwarderQuery(PKLDRMODMACHO pModMachO, const void *pvBits, const char *pszForwarder, 148 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser, PKLDRADDR puValue, uint32_t *pfKind); 141 static int kldrModMachOLoadObjSymTab(PKLDRMODMACHO pModMachO); 149 142 static int kldrModMachODoFixups(PKLDRMODMACHO pModMachO, void *pvMapping, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress); 150 static int kldrModMachODoImports32Bit(PKLDRMODMACHO pModMachO, void *pvMapping, const IMAGE_IMPORT_DESCRIPTOR *pImpDesc,151 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);152 static int kldrModMachODoImports64Bit(PKLDRMODMACHO pModMachO, void *pvMapping, const IMAGE_IMPORT_DESCRIPTOR *pImpDesc,153 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);154 143 static int kldrModMachODoImports(PKLDRMODMACHO pModMachO, void *pvMapping, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); 155 static int kldrModMachODoCallDLL(PKLDRMODMACHO pModMachO, unsigned uOp, uintptr_t uHandle);156 static int kldrModMachODoCallTLS(PKLDRMODMACHO pModMachO, unsigned uOp, uintptr_t uHandle);157 static int32_t kldrModMachODoCall(uintptr_t uEntrypoint, uintptr_t uHandle, uint32_t uOp, void *pvReserved);158 #endif159 144 160 145 … … 360 345 pModMachO->LinkAddress = 0; 361 346 pModMachO->cbImage = 0; 362 pModMachO->fMapUsingLoadCommand s = 0;347 pModMachO->fMapUsingLoadCommandSections = 0; 363 348 pModMachO->offSymbols = 0; 364 349 pModMachO->cSymbols = 0; … … 416 401 uint32_t cbLeft = pHdr->sizeofcmds; 417 402 uint8_t *pb = pbLoadCommands; 418 int cSegmentCommands = 0; 419 int fConvertEndian = pHdr->magic == IMAGE_MACHO32_SIGNATURE_OE 420 || pHdr->magic == IMAGE_MACHO64_SIGNATURE_OE; 403 int cSegmentCommands = 0; 404 int cSymbolTabs = 0; 405 int fConvertEndian = pHdr->magic == IMAGE_MACHO32_SIGNATURE_OE 406 || pHdr->magic == IMAGE_MACHO64_SIGNATURE_OE; 421 407 422 408 *pcSegments = 0; … … 632 618 || (uint64_t)u.pSymTab->stroff + u.pSymTab->strsize > cbFile) 633 619 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 620 621 /* only one string in objects, please. */ 622 cSymbolTabs++; 623 if ( pHdr->filetype == MH_OBJECT 624 && cSymbolTabs != 1) 625 return KLDR_ERR_MACHO_BAD_OBJECT_FILE; 634 626 break; 635 627 … … 818 810 return KLDR_ERR_MACHO_BAD_SECTION; /** @todo move up! */ 819 811 812 /* If there are file bits, ensure they are in the current flow. 813 (yes, we are very very careful here, I know.) */ 820 814 if ( pSect->offset 821 815 && pSeg[-1].cbFile == pSeg[-1].cb) 822 816 { 823 if ( pSeg[-1].offFile + pSeg[-1].cbFile == pSect->offset 824 && pSeg[-1].cbFile == pSect->addr - pSeg[-1].LinkAddress) 817 int fOk = pSeg[-1].offFile + (pSect->addr - pSeg[-1].LinkAddress) == pSect->offset 818 && pSect[-1].offset 819 && pSeg[-1].offFile + pSeg[-1].cbFile == pSect[-1].offset + pSect[-1].size; 820 /* more checks? */ 821 if (fOk) 825 822 pSeg[-1].cbFile = (off_t)(pSect->addr - pSeg[-1].LinkAddress) + pSect->size; 826 else 823 else 827 824 { 825 828 826 pSeg[-1].cbFile = pSeg[-1].offFile = -1; 829 pModMachO->fMapUsingLoadCommand s = 1;827 pModMachO->fMapUsingLoadCommandSections = 1; 830 828 } 831 829 } … … 847 845 } 848 846 847 case LC_SYMTAB: 848 switch (pModMachO->Hdr.filetype) 849 { 850 case MH_OBJECT: 851 pModMachO->offSymbols = u.pSymTab->symoff; 852 pModMachO->cSymbols = u.pSymTab->nsyms; 853 pModMachO->offStrings = u.pSymTab->stroff; 854 pModMachO->cbStrings = u.pSymTab->strsize; 855 break; 856 } 857 break; 858 849 859 default: 850 860 break; 851 } 852 } 861 } /* command switch */ 862 } /* while more commands */ 853 863 854 864 /* … … 1061 1071 /** @copydoc kLdrModQuerySymbol */ 1062 1072 static int kldrModMachOQuerySymbol(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t iSymbol, 1063 const char *pchSymbol, size_t cchSymbol, const char *pszVersion,1064 PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, uint32_t *pfKind)1073 const char *pchSymbol, size_t cchSymbol, const char *pszVersion, 1074 PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, uint32_t *pfKind) 1065 1075 1066 1076 { … … 1256 1266 static int kldrModMachOGetImport(PKLDRMOD pMod, const void *pvBits, uint32_t iImport, char *pszName, size_t cchName) 1257 1267 { 1258 #if 0 1259 PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData; 1260 const IMAGE_IMPORT_DESCRIPTOR *pImpDesc; 1261 const char *pszImportName; 1262 size_t cchImportName; 1263 int rc; 1264 1265 /* 1266 * Make sure we've got mapped bits and resolve any base address aliases. 1267 */ 1268 rc = kldrModMachOBitsAndBaseAddress(pModMachO, &pvBits, NULL); 1269 if (rc) 1270 return rc; 1271 1272 /* 1273 * Simple bounds check. 1274 */ 1275 if (iImport >= (uint32_t)kldrModMachONumberOfImports(pMod, pvBits)) 1268 PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData; 1269 if (pModMachO->Hdr.filetype == MH_OBJECT) 1276 1270 return KLDR_ERR_IMPORT_ORDINAL_OUT_OF_BOUNDS; 1277 1271 1278 /* 1279 * Get the name. 1280 */ 1281 pImpDesc = KLDRMODMACHO_RVA2TYPE(pvBits, 1282 pModMachO->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress 1283 + sizeof(IMAGE_IMPORT_DESCRIPTOR) * iImport, 1284 const IMAGE_IMPORT_DESCRIPTOR *); 1285 pszImportName = KLDRMODMACHO_RVA2TYPE(pvBits, pImpDesc->Name, const char *); 1286 cchImportName = kLdrHlpStrLen(pszImportName); 1287 if (cchImportName < cchName) 1288 { 1289 kLdrHlpMemCopy(pszName, pszImportName, cchImportName + 1); 1290 rc = 0; 1291 } 1292 else 1293 { 1294 kLdrHlpMemCopy(pszName, pszImportName, cchName); 1295 if (cchName) 1296 pszName[cchName - 1] = '\0'; 1297 rc = KLDR_ERR_BUFFER_OVERFLOW; 1298 } 1299 1300 return rc; 1301 #else 1302 return -1; 1303 #endif 1272 /* later */ 1273 return KLDR_ERR_IMPORT_ORDINAL_OUT_OF_BOUNDS; 1304 1274 } 1305 1275 … … 1308 1278 static int32_t kldrModMachONumberOfImports(PKLDRMOD pMod, const void *pvBits) 1309 1279 { 1310 #if 01311 1280 PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData; 1312 if (pModMachO->cImportModules == ~(uint32_t)0) 1313 { 1314 /* 1315 * We'll have to walk the import descriptors to figure out their number. 1316 * First, make sure we've got mapped bits. 1317 */ 1318 if (kldrModMachOBitsAndBaseAddress(pModMachO, &pvBits, NULL)) 1319 return -1; 1320 pModMachO->cImportModules = 0; 1321 if ( pModMachO->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size 1322 && pModMachO->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress) 1323 { 1324 const IMAGE_IMPORT_DESCRIPTOR *pImpDesc; 1325 1326 pImpDesc = KLDRMODMACHO_RVA2TYPE(pvBits, 1327 pModMachO->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress, 1328 const IMAGE_IMPORT_DESCRIPTOR *); 1329 while (pImpDesc->Name && pImpDesc->FirstThunk) 1330 { 1331 pModMachO->cImportModules++; 1332 pImpDesc++; 1333 } 1334 } 1335 } 1336 return pModMachO->cImportModules; 1337 #else 1338 return 0; 1339 #endif 1281 if (pModMachO->Hdr.filetype == MH_OBJECT) 1282 return 0; 1283 1284 /* later */ 1285 return 0; 1340 1286 } 1341 1287 … … 1348 1294 pStackInfo->Address = NIL_KLDRADDR; 1349 1295 pStackInfo->LinkAddress = NIL_KLDRADDR; 1350 pStackInfo->cbStack = pStackInfo->cbStackThread = 0;//pModMachO->Hdrs.OptionalHeader.SizeOfStackReserve; 1296 pStackInfo->cbStack = pStackInfo->cbStackThread = 0; 1297 /* later */ 1351 1298 1352 1299 return 0; … … 1780 1727 static int kldrModMachODoImports(PKLDRMODMACHO pModMachO, void *pvMapping, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser) 1781 1728 { 1782 #if 0 1783 const IMAGE_IMPORT_DESCRIPTOR *pImpDesc; 1784 1785 /* 1786 * If no imports, there is nothing to do. 1787 */ 1788 kldrModMachONumberOfImports(pModMachO->pMod, pvMapping); 1789 if (!pModMachO->cImportModules) 1790 return 0; 1791 1792 pImpDesc = KLDRMODMACHO_RVA2TYPE(pvMapping, 1793 pModMachO->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress, 1794 const IMAGE_IMPORT_DESCRIPTOR *); 1795 if (pModMachO->Hdrs.FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32)) 1796 return kldrModMachODoImports32Bit(pModMachO, pvMapping, pImpDesc, pfnGetImport, pvUser); 1797 return kldrModMachODoImports64Bit(pModMachO, pvMapping, pImpDesc, pfnGetImport, pvUser); 1798 #else 1799 return 0; 1800 #endif 1801 } 1802 1803 1804 #if 0 1805 /** 1806 * Resolves imports, 32-bit image. 1807 * 1808 * @returns 0 on success, non-zero kLdr status code on failure. 1809 * @param pModMachO The PE module interpreter instance. 1810 * @param pvMapping The mapping which imports should be resolved. 1811 * @param pImpDesc Pointer to the first import descriptor. 1812 * @param pfnGetImport The callback for resolving an imported symbol. 1813 * @param pvUser User argument to the callback. 1814 */ 1815 static int kldrModMachODoImports32Bit(PKLDRMODMACHO pModMachO, void *pvMapping, const IMAGE_IMPORT_DESCRIPTOR *pImpDesc, 1816 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser) 1817 { 1818 PKLDRMOD pMod = pModMachO->pMod; 1819 uint32_t iImp; 1820 1821 /* 1822 * Iterate the import descriptors. 1823 */ 1824 for (iImp = 0; iImp < pModMachO->cImportModules; iImp++, pImpDesc++) 1825 { 1826 PIMAGE_THUNK_DATA32 pFirstThunk = KLDRMODMACHO_RVA2TYPE(pvMapping, pImpDesc->FirstThunk, PIMAGE_THUNK_DATA32); 1827 const IMAGE_THUNK_DATA32 *pThunk = pImpDesc->u.OriginalFirstThunk 1828 ? KLDRMODMACHO_RVA2TYPE(pvMapping, pImpDesc->u.OriginalFirstThunk, const IMAGE_THUNK_DATA32 *) 1829 : KLDRMODMACHO_RVA2TYPE(pvMapping, pImpDesc->FirstThunk, const IMAGE_THUNK_DATA32 *); 1830 1831 /* Iterate the thunks. */ 1832 while (pThunk->u1.Ordinal != 0) 1833 { 1834 KLDRADDR Value; 1835 uint32_t fKind; 1836 int rc; 1837 1838 /* Ordinal or name import? */ 1839 if (IMAGE_SNAP_BY_ORDINAL32(pThunk->u1.Ordinal)) 1840 rc = pfnGetImport(pMod, iImp, IMAGE_ORDINAL32(pThunk->u1.Ordinal), NULL, 0, NULL, &Value, &fKind, pvUser); 1841 else if (KLDRMODMACHO_VALID_RVA(pModMachO, pThunk->u1.Ordinal)) 1842 { 1843 const IMAGE_IMPORT_BY_NAME *pName = KLDRMODMACHO_RVA2TYPE(pvMapping, pThunk->u1.Ordinal, const IMAGE_IMPORT_BY_NAME *); 1844 rc = pfnGetImport(pMod, iImp, NIL_KLDRMOD_SYM_ORDINAL, (const char *)pName->Name, 1845 kLdrHlpStrLen((const char *)pName->Name), NULL, &Value, &fKind, pvUser); 1846 } 1847 else 1848 { 1849 KLDRMODMACHO_ASSERT(!"bad 32-bit import"); 1850 return KLDR_ERR_PE_BAD_IMPORT; 1851 } 1852 1853 /* Apply it. */ 1854 pFirstThunk->u1.Function = (uint32_t)Value; 1855 if (pFirstThunk->u1.Function != Value) 1856 { 1857 KLDRMODMACHO_ASSERT(!"overflow"); 1858 return KLDR_ERR_ADDRESS_OVERFLOW; 1859 } 1860 1861 /* next */ 1862 pThunk++; 1863 pFirstThunk++; 1864 } 1865 } 1866 return 0; 1867 } 1868 1869 1870 /** 1871 * Resolves imports, 64-bit image. 1872 * 1873 * @returns 0 on success, non-zero kLdr status code on failure. 1874 * @param pModMachO The PE module interpreter instance. 1875 * @param pvMapping The mapping which imports should be resolved. 1876 * @param pImpDesc Pointer to the first import descriptor. 1877 * @param pfnGetImport The callback for resolving an imported symbol. 1878 * @param pvUser User argument to the callback. 1879 */ 1880 static int kldrModMachODoImports64Bit(PKLDRMODMACHO pModMachO, void *pvMapping, const IMAGE_IMPORT_DESCRIPTOR *pImpDesc, 1881 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser) 1882 { 1883 PKLDRMOD pMod = pModMachO->pMod; 1884 uint32_t iImp; 1885 1886 /* 1887 * Iterate the import descriptors. 1888 */ 1889 for (iImp = 0; iImp < pModMachO->cImportModules; iImp++, pImpDesc++) 1890 { 1891 PIMAGE_THUNK_DATA64 pFirstThunk = KLDRMODMACHO_RVA2TYPE(pvMapping, pImpDesc->FirstThunk, PIMAGE_THUNK_DATA64); 1892 const IMAGE_THUNK_DATA64 *pThunk = pImpDesc->u.OriginalFirstThunk 1893 ? KLDRMODMACHO_RVA2TYPE(pvMapping, pImpDesc->u.OriginalFirstThunk, const IMAGE_THUNK_DATA64 *) 1894 : KLDRMODMACHO_RVA2TYPE(pvMapping, pImpDesc->FirstThunk, const IMAGE_THUNK_DATA64 *); 1895 1896 /* Iterate the thunks. */ 1897 while (pThunk->u1.Ordinal != 0) 1898 { 1899 KLDRADDR Value; 1900 uint32_t fKind; 1901 int rc; 1902 1903 /* Ordinal or name import? */ 1904 if (IMAGE_SNAP_BY_ORDINAL64(pThunk->u1.Ordinal)) 1905 rc = pfnGetImport(pMod, iImp, (uint32_t)IMAGE_ORDINAL64(pThunk->u1.Ordinal), NULL, 0, NULL, &Value, &fKind, pvUser); 1906 else if (KLDRMODMACHO_VALID_RVA(pModMachO, pThunk->u1.Ordinal)) 1907 { 1908 const IMAGE_IMPORT_BY_NAME *pName = KLDRMODMACHO_RVA2TYPE(pvMapping, pThunk->u1.Ordinal, const IMAGE_IMPORT_BY_NAME *); 1909 rc = pfnGetImport(pMod, iImp, NIL_KLDRMOD_SYM_ORDINAL, (const char *)pName->Name, 1910 kLdrHlpStrLen((const char *)pName->Name), NULL, &Value, &fKind, pvUser); 1911 } 1912 else 1913 { 1914 KLDRMODMACHO_ASSERT(!"bad 64-bit import"); 1915 return KLDR_ERR_PE_BAD_IMPORT; 1916 } 1917 1918 /* Apply it. */ 1919 pFirstThunk->u1.Function = Value; 1920 1921 /* next */ 1922 pThunk++; 1923 pFirstThunk++; 1924 } 1925 } 1926 return 0; 1927 } 1928 1929 #endif 1729 /* for when loading non-objects. */ 1730 return 0; 1731 } 1930 1732 1931 1733 … … 1933 1735 static int kldrModMachOCallInit(PKLDRMOD pMod, uintptr_t uHandle) 1934 1736 { 1935 #if 0 1936 PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData; 1937 int rc; 1938 1939 /* 1940 * Mapped? 1941 */ 1942 if (!pModMachO->pvMapping) 1943 return KLDR_ERR_NOT_MAPPED; 1944 1945 /* 1946 * Do TLS callbacks first and then call the init/term function if it's a DLL. 1947 */ 1948 rc = kldrModMachODoCallTLS(pModMachO, DLL_PROCESS_ATTACH, uHandle); 1949 if ( !rc 1950 && (pModMachO->Hdrs.FileHeader.Characteristics & IMAGE_FILE_DLL)) 1951 { 1952 rc = kldrModMachODoCallDLL(pModMachO, DLL_PROCESS_ATTACH, uHandle); 1953 if (rc) 1954 kldrModMachODoCallTLS(pModMachO, DLL_PROCESS_DETACH, uHandle); 1955 } 1956 1957 return rc; 1958 #else 1959 return 0; 1960 #endif 1961 } 1962 1963 1964 /** 1965 * Call the DLL entrypoint. 1966 * 1967 * @returns 0 on success. 1968 * @returns KLDR_ERR_MODULE_INIT_FAILED or KLDR_ERR_THREAD_ATTACH_FAILED on failure. 1969 * @param pModMachO The PE module interpreter instance. 1970 * @param uOp The operation (DLL_*). 1971 * @param uHandle The module handle to present. 1972 */ 1973 static int kldrModMachODoCallDLL(PKLDRMODMACHO pModMachO, unsigned uOp, uintptr_t uHandle) 1974 { 1975 #if 0 1976 int rc; 1977 1978 /* 1979 * If no entrypoint there isn't anything to be done. 1980 */ 1981 if (!pModMachO->Hdrs.OptionalHeader.AddressOfEntryPoint) 1982 return 0; 1983 1984 /* 1985 * Invoke the entrypoint and convert the boolean result to a kLdr status code. 1986 */ 1987 rc = kldrModMachODoCall((uintptr_t)pModMachO->pvMapping + pModMachO->Hdrs.OptionalHeader.AddressOfEntryPoint, 1988 uHandle, uOp, NULL); 1989 if (rc) 1990 rc = 0; 1991 else if (uOp == DLL_PROCESS_ATTACH) 1992 rc = KLDR_ERR_MODULE_INIT_FAILED; 1993 else if (uOp == DLL_THREAD_ATTACH) 1994 rc = KLDR_ERR_THREAD_ATTACH_FAILED; 1995 else /* detach: ignore failures */ 1996 rc = 0; 1997 return rc; 1998 #else 1999 return 0; 2000 #endif 2001 } 2002 2003 2004 /** 2005 * Call the TLS entrypoints. 2006 * 2007 * @returns 0 on success. 2008 * @returns KLDR_ERR_THREAD_ATTACH_FAILED on failure. 2009 * @param pModMachO The PE module interpreter instance. 2010 * @param uOp The operation (DLL_*). 2011 * @param uHandle The module handle to present. 2012 */ 2013 static int kldrModMachODoCallTLS(PKLDRMODMACHO pModMachO, unsigned uOp, uintptr_t uHandle) 2014 { 2015 /** @todo implement TLS support. */ 2016 return 0; 2017 } 2018 2019 2020 /** 2021 * Do a 3 parameter callback. 2022 * 2023 * @returns 32-bit callback return. 2024 * @param uEntrypoint The address of the function to be called. 2025 * @param uHandle The first argument, the module handle. 2026 * @param uOp The second argumnet, the reason we're calling. 2027 * @param pvReserved The third argument, reserved argument. (figure this one out) 2028 */ 2029 static int32_t kldrModMachODoCall(uintptr_t uEntrypoint, uintptr_t uHandle, uint32_t uOp, void *pvReserved) 2030 { 2031 #if 0 2032 int32_t rc; 2033 2034 /** @todo try/except */ 2035 #if defined(__X86__) || defined(__i386__) || defined(_M_IX86) 2036 /* 2037 * Be very careful. 2038 * Not everyone will have got the calling convention right. 2039 */ 2040 # ifdef __GNUC__ 2041 __asm__ __volatile__( 2042 "pushl %2\n\t" 2043 "pushl %1\n\t" 2044 "pushl %0\n\t" 2045 "lea 12(%%esp), %2\n\t" 2046 "call *%3\n\t" 2047 "movl %2, %%esp\n\t" 2048 : "=a" (rc) 2049 : "d" (uOp), 2050 "S" (0), 2051 "c" (uEntrypoint), 2052 "0" (uHandle)); 2053 # elif defined(_MSC_VER) 2054 __asm { 2055 mov eax, [uHandle] 2056 mov edx, [uOp] 2057 mov ecx, 0 2058 mov ebx, [uEntrypoint] 2059 push edi 2060 mov edi, esp 2061 push ecx 2062 push edx 2063 push eax 2064 call ebx 2065 mov esp, edi 2066 pop edi 2067 mov [rc], eax 2068 } 2069 # else 2070 # error "port me!" 2071 # endif 2072 2073 #elif defined(__AMD64__) || defined(__x86_64__) || defined(_M_IX86) 2074 /* 2075 * For now, let's just get the work done... 2076 */ 2077 /** @todo Deal with GCC / MSC differences in some sensible way. */ 2078 int (*pfn)(uintptr_t uHandle, uint32_t uOp, void *pvReserved); 2079 pfn = (int (*)(uintptr_t uHandle, uint32_t uOp, void *pvReserved))uEntrypoint; 2080 rc = pfn(uHandle, uOp, NULL); 2081 2082 #else 2083 # error "port me" 2084 #endif 2085 2086 return rc; 2087 #else 2088 return 0; 2089 #endif 1737 /* later */ 1738 return 0; 2090 1739 } 2091 1740 … … 2094 1743 static int kldrModMachOCallTerm(PKLDRMOD pMod, uintptr_t uHandle) 2095 1744 { 2096 #if 0 2097 PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData; 2098 2099 /* 2100 * Mapped? 2101 */ 2102 if (!pModMachO->pvMapping) 2103 return KLDR_ERR_NOT_MAPPED; 2104 2105 /* 2106 * Do TLS callbacks first. 2107 */ 2108 kldrModMachODoCallTLS(pModMachO, DLL_PROCESS_DETACH, uHandle); 2109 if (pModMachO->Hdrs.FileHeader.Characteristics & IMAGE_FILE_DLL) 2110 kldrModMachODoCallDLL(pModMachO, DLL_PROCESS_DETACH, uHandle); 2111 #endif 2112 1745 /* later */ 2113 1746 return 0; 2114 1747 } … … 2118 1751 static int kldrModMachOCallThread(PKLDRMOD pMod, uintptr_t uHandle, unsigned fAttachingOrDetaching) 2119 1752 { 2120 #if 0 2121 PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData; 2122 unsigned uOp = fAttachingOrDetaching ? DLL_THREAD_ATTACH : DLL_THREAD_DETACH; 2123 int rc; 2124 2125 /* 2126 * Do TLS callbacks first and then call the init/term function if it's a DLL. 2127 */ 2128 rc = kldrModMachODoCallTLS(pModMachO, uOp, uHandle); 2129 if (!fAttachingOrDetaching) 2130 rc = 0; 2131 if ( !rc 2132 && (pModMachO->Hdrs.FileHeader.Characteristics & IMAGE_FILE_DLL)) 2133 { 2134 rc = kldrModMachODoCallDLL(pModMachO, uOp, uHandle); 2135 if (!fAttachingOrDetaching) 2136 rc = 0; 2137 if (rc) 2138 kldrModMachODoCallTLS(pModMachO, uOp, uHandle); 2139 } 2140 return rc; 2141 #else 2142 return 0; 2143 #endif 1753 /* Relevant for Mach-O? */ 1754 return 0; 2144 1755 } 2145 1756 … … 2156 1767 static int kldrModMachOGetBits(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser) 2157 1768 { 2158 #if 02159 1769 PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData; 2160 1770 uint32_t i; … … 2164 1774 * Zero the entire buffer first to simplify things. 2165 1775 */ 2166 kLdrHlpMemSet(pvBits, 0, pModMachO->Hdrs.OptionalHeader.SizeOfImage); 2167 2168 /* 2169 * Iterate the segments and read the data within them. 2170 */ 2171 for (i = 0; i < pMod->cSegments; i++) 2172 { 2173 /* skip it? */ 2174 if ( pMod->aSegments[i].cbFile == -1 2175 || pMod->aSegments[i].offFile == -1 2176 || pMod->aSegments[i].LinkAddress == NIL_KLDRADDR 2177 || !pMod->aSegments[i].Alignment) 2178 continue; 2179 rc = kLdrRdrRead(pMod->pRdr, 2180 (uint8_t *)pvBits + (pMod->aSegments[i].LinkAddress - pModMachO->Hdrs.OptionalHeader.ImageBase), 2181 pMod->aSegments[i].cbFile, 2182 pMod->aSegments[i].offFile); 2183 if (rc) 2184 return rc; 1776 kLdrHlpMemSet(pvBits, 0, (size_t)pModMachO->cbImage); 1777 1778 /* 1779 * When possible use the segment table to load the data. 1780 * If not iterate the load commands and execute the segment / section loads. 1781 */ 1782 if (!pModMachO->fMapUsingLoadCommandSections) 1783 { 1784 for (i = 0; i < pMod->cSegments; i++) 1785 { 1786 /* skip it? */ 1787 if ( pMod->aSegments[i].cbFile == -1 1788 || pMod->aSegments[i].offFile == -1 1789 || pMod->aSegments[i].LinkAddress == NIL_KLDRADDR 1790 || !pMod->aSegments[i].Alignment) 1791 continue; 1792 rc = kLdrRdrRead(pMod->pRdr, 1793 (uint8_t *)pvBits + (pMod->aSegments[i].LinkAddress - pModMachO->LinkAddress), 1794 pMod->aSegments[i].cbFile, 1795 pMod->aSegments[i].offFile); 1796 if (rc) 1797 return rc; 1798 } 1799 } 1800 else 1801 { 1802 /** @todo implement this */ 1803 return KLDR_ERR_TODO; 2185 1804 } 2186 1805 … … 2188 1807 * Perform relocations. 2189 1808 */ 2190 return kldrModMachORelocateBits(pMod, pvBits, BaseAddress, pModMachO->Hdrs.OptionalHeader.ImageBase, pfnGetImport, pvUser); 2191 #else 2192 return 0; 2193 #endif 1809 return kldrModMachORelocateBits(pMod, pvBits, BaseAddress, pModMachO->LinkAddress, pfnGetImport, pvUser); 2194 1810 } 2195 1811 … … 2206 1822 */ 2207 1823 rc = kldrModMachODoFixups(pModMachO, pvBits, NewBaseAddress, OldBaseAddress); 2208 if ( !rc)1824 if (pModMachO->Hdr.filetype != MH_OBJECT) 2209 1825 rc = kldrModMachODoImports(pModMachO, pvBits, pfnGetImport, pvUser); 2210 1826
Note:
See TracChangeset
for help on using the changeset viewer.