- Timestamp:
- Sep 18, 2010, 4:41:20 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/emx/src/emxomf/weakld.c
r3667 r3668 158 158 /** Filehandle if open */ 159 159 FILE *phFile; 160 /** Where in the file the library starts. */ 161 off_t off; 160 162 /** Set if it's a OMF library, clear if it's a unix archive. */ 161 163 unsigned fOmfLib; … … 193 195 /** Library relation - not used for libraries added thru wld_add_object(). */ 194 196 PWLDLIB pLib; 195 /* Linked list next pointer*/197 /** Pointer to the next module. */ 196 198 struct wldmod *pNext; 197 199 } WLDMOD, *PWLDMOD; … … 452 454 static int libLoadUndefSymbolsFromOmfLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded); 453 455 /** 454 * Callback parameter structure used between libLoadUndefSymbolsFromArchLib 456 * Callback parameter structure used between libLoadUndefSymbolsFromArchLib 455 457 * and libLoadUndefSymbolsFromArchLibCallback 456 458 */ … … 466 468 unsigned *pcLoaded; 467 469 } WLDLIBLOADUSFALPARAM, *PWLDLIBLOADUSFALPARAM; 468 static int libLoadUndefSymbolsFromArchLibCallback(FILE *pFile, const char *pszName, off_t cbFile, void *pvUser);470 static int libLoadUndefSymbolsFromArchLibCallback(FILE *pFile, const char *pszName, off_t offFile, off_t cbFile, void *pvUser); 469 471 static int libLoadUndefSymbolsFromArchLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded); 470 472 static int libLoadUndefSymbols(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded); … … 474 476 * @param pFile Stream positioned at the start of the file. Don't close. 475 477 * @param pszName The file name. 478 * @param offFile The offset of the file in the stream @a pFile. 476 479 * @param cbFile The file size. 477 480 * @param pvUser The user parameter. 478 481 */ 479 typedef int (* PFNLIBENUMFILE)(FILE *pFile, const char *pszName, off_t cbFile, void *pvUser);482 typedef int (* PFNLIBENUMFILE)(FILE *pFile, const char *pszName, off_t offFile, off_t cbFile, void *pvUser); 480 483 static int libEnumFilesArch(PWLDLIB pLib, int fAll, PFNLIBENUMFILE pfnCallback, void *pvUser); 481 484 static int libErr(PWLDLIB pLib, const char *pszFormat, ...); 482 #if 0483 485 static void libWarn(PWLDLIB pLib, const char *pszFormat, ...); 484 #endif485 486 /** @} */ 486 487 … … 499 500 static int symEnum(PWLD pWld, PWLDSYMTAB pSymTab, unsigned fFlags, unsigned fMask, PFNSYMENUM pfnEnum, void *pvUser); 500 501 static int symPrintUnDefEnum(PWLD pWld, PWLDSYM pSym, void *pvUser); 501 static int symMatchUnDef(PWLD pWld, const unsigned char *pachPascalString, PWLDSYM pSym); 502 static int symMatchUnDef(PWLD pWld, const char *pszName, size_t cchName, PWLDSYM pSym); 503 static int symMatchUnDefOmf(PWLD pWld, const unsigned char *pachPascalString, PWLDSYM pSym); 502 504 /** Pointed to by the pvUser parameter of symSearchLibEnum(). */ 503 505 typedef struct symSearchLibEnum_param … … 738 740 { 739 741 } 740 742 741 743 /* ensure it's open. */ 742 744 phFile = libOpen(pLib); 743 745 if (!phFile) 744 746 return -1; 745 747 746 748 if (pLib->fOmfLib) 747 749 { … … 749 751 if (fseek(phFile, pLib->LibHdr.offDict, SEEK_SET)) 750 752 return libErr(pLib, "Failed to seek to extended dictionary (offset %d).", (int)pLib->LibHdr.offDict); 751 753 752 754 /* read it */ 753 755 pLib->pDict = xmalloc(pLib->LibHdr.cDictBlocks * 512); 754 756 if (fread(pLib->pDict, 512, pLib->LibHdr.cDictBlocks, phFile) == pLib->LibHdr.cDictBlocks) 755 757 return 0; 756 758 757 759 libErr(pLib, "Failed to read extended dictionary."); 758 760 } 759 761 760 762 free(pLib->pDict); 761 763 pLib->pDict = NULL; … … 803 805 804 806 /** 805 * Implementation of libLoadUndefSymbols for unix archives. 807 * Common routine implementing libLoadUndefSymbol for OMF libraries as well as 808 * do the searching of OMF members on behalf of libLoadUndefSymbolsFromArch. 806 809 * 807 810 * @returns see libLoadUndefSymbols 808 811 * @param pWld Linker instance. 809 * @param pLib Library to search. 812 * @param pLib Library being searched. This does not have to be a 813 * OMF library. 814 * @param pLibHdr The library header read by the caller. 815 * @param offLib The offset of the library to search in the library stream. 810 816 * @param pSym See libLoadUndefSymbols. 811 817 * @param pcLoaded Number of modules which was loaded from this library. 812 818 */ 813 static int libLoadUndefSymbolsFromOmfLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded) 819 static int libLoadUndefSymbolsFromOmfLib2(PWLD pWld, PWLDLIB pLib, off_t offLib, POMFLIBHDR pLibHdr, 820 PWLDSYM pSym, unsigned *pcLoaded) 814 821 { 815 822 FILE * phFile = pLib->phFile; 816 823 unsigned char uchEnd1, uchEnd2; 824 OMFLIBHDR LibHdr; 817 825 OMFREC OmfRec; 818 826 off_t offCurMod = 0; … … 824 832 unsigned char uch, uch2; 825 833 826 827 /* Position the library at the first module record. */ 828 if (fseek(phFile, pLib->u.Omf.LibHdr.chType == LIBHDR ? pLib->u.Omf.LibHdr.cb + 3 : 0, SEEK_SET)) 834 /* Position the stream at the first module record. */ 835 if (fseek(phFile, offLib + (pLibHdr->chType == LIBHDR ? pLibHdr->cb + 3 : 0), SEEK_SET)) 829 836 return libErr(pLib, "Error when seeking to first module."); 830 837 831 if (pLib ->u.Omf.LibHdr.chType != LIBHDR)838 if (pLibHdr->chType != LIBHDR) 832 839 { 833 840 uchEnd1 = MODEND; … … 932 939 if (uch & 1) 933 940 ul = OMF_WORD(); 934 if (symMatchUnDef (pWld, u1.pch, pSym))941 if (symMatchUnDefOmf(pWld, u1.pch, pSym)) 935 942 fLoad = 1; 936 943 break; … … 952 959 ul = OMF_IS32BIT() ? OMF_DWORD() : OMF_WORD(); 953 960 us = OMF_GETINDEX(); /* typeindex */ 954 if (symMatchUnDef (pWld, u1.pch, pSym))961 if (symMatchUnDefOmf(pWld, u1.pch, pSym)) 955 962 fLoad = 1; 956 963 } … … 964 971 u1 = u; u.pch += 1 + *u.puch; /* alias name */ 965 972 u2 = u; u.pch += 1 + *u.puch; /* substitutt name. */ 966 if (symMatchUnDef (pWld, u1.pch, pSym))973 if (symMatchUnDefOmf(pWld, u1.pch, pSym)) 967 974 fLoad = 1; 968 975 } … … 991 998 return -1; 992 999 } 993 if (symMatchUnDef (pWld, u1.pch, pSym))1000 if (symMatchUnDefOmf(pWld, u1.pch, pSym)) 994 1001 fLoad = 1; 995 1002 } … … 1083 1090 1084 1091 /** 1085 * Callback used by libLoadUndefSymbolsFromArchLib 1086 * 1087 * @returns 0 or -1 see libLoadUndefSymbols. 1088 * @param phFile The library stream, positioned at the start of the file. 1089 * @param pszName The (short) file name. 1090 * @param cbFile The file size. 1091 * @param pvUser Parameters. 1092 */ 1093 static int libLoadUndefSymbolsFromArchLibCallback(FILE *pFile, const char *pszName, off_t cbFile, void *pvUser) 1094 { 1095 PWLDLIBLOADUSFALPARAM pParam = (PWLDLIBLOADUSFALPARAM)pvUser; 1096 /** @todo */ 1097 return 0; 1098 } 1099 1100 1101 /** 1102 * Implementation of libLoadUndefSymbols for unix archives. 1092 * Implementation of libLoadUndefSymbols for OMF libraries. 1103 1093 * 1104 1094 * @returns see libLoadUndefSymbols … … 1108 1098 * @param pcLoaded Number of modules which was loaded from this library. 1109 1099 */ 1100 static int libLoadUndefSymbolsFromOmfLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded) 1101 { 1102 return libLoadUndefSymbolsFromOmfLib2(pWld, pLib, 0, &pLib->u.Omf.LibHdr, pSym, pcLoaded); 1103 } 1104 1105 /** 1106 * Callback used by libLoadUndefSymbolsFromArchLib 1107 * 1108 * @returns 0 or -1 see libLoadUndefSymbols. 1109 * @param phFile The library stream, positioned at the start of the file. 1110 * @param pszName The (short) file name. 1111 * @param offFile The offset of the file in the stream @a pFile. 1112 * @param cbFile The file size. 1113 * @param pvUser Parameters. 1114 */ 1115 static int libLoadUndefSymbolsFromArchLibCallback(FILE *pFile, const char *pszName, 1116 off_t offFile, off_t cbFile, void *pvUser) 1117 { 1118 PWLDLIBLOADUSFALPARAM pParam = (PWLDLIBLOADUSFALPARAM)pvUser; 1119 size_t cbRead; 1120 int rc; 1121 union 1122 { 1123 OMFLIBHDR OmfLib; 1124 Elf32_Ehdr Ehdr; 1125 } uBuf; 1126 1127 cbRead = sizeof(uBuf); 1128 if (cbRead > cbFile) 1129 memset(&uBuf, 0, sizeof(uBuf)); 1130 1131 if (fread(&uBuf, cbRead, 1, pFile) != 1) 1132 return libErr(pParam->pLib, "failed to read archive member"); 1133 if (IS_ELF(uBuf.Ehdr)) 1134 { 1135 WLDINFO(pParam->pWld, ("Considering AR/ELF %s(%s)\n", pParam->pLib->pszLibName, pszName)); 1136 /** @todo */ 1137 rc = 0; 1138 } 1139 else if ( uBuf.OmfLib.chType == THEADR 1140 || uBuf.OmfLib.chType == LIBHDR) 1141 { 1142 WLDINFO(pParam->pWld, ("Considering AR/OMF %s(%s)\n", pParam->pLib->pszLibName, pszName)); 1143 rc = libLoadUndefSymbolsFromOmfLib2(pParam->pWld, pParam->pLib, offFile, &uBuf.OmfLib, 1144 pParam->pSym, pParam->pcLoaded); 1145 } 1146 else 1147 { 1148 libWarn(pParam->pLib, "Skipping unknown member '%s'"); 1149 rc = 0; 1150 } 1151 if (rc == 42) 1152 rc = 0; 1153 return rc; 1154 } 1155 1156 1157 /** 1158 * Implementation of libLoadUndefSymbols for unix archives. 1159 * 1160 * @returns see libLoadUndefSymbols 1161 * @param pWld Linker instance. 1162 * @param pLib Library to search. 1163 * @param pSym See libLoadUndefSymbols. 1164 * @param pcLoaded Number of modules which was loaded from this library. 1165 */ 1110 1166 static int libLoadUndefSymbolsFromArchLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded) 1111 1167 { 1112 1168 WLDLIBLOADUSFALPARAM Param; 1169 WLDINFO(pWld, ("libLoadUndefSymbolsFromArchLib - %s\n", pLib->pszLibName)); 1113 1170 1114 1171 Param.pWld = pWld; … … 1137 1194 { 1138 1195 if (!pLib->fOmfLib) 1139 return libLoadUndefSymbolsFromArchLib(pWld, pLib, pSym, pcLoaded); 1196 return libLoadUndefSymbolsFromArchLib(pWld, pLib, pSym, pcLoaded); 1140 1197 return libLoadUndefSymbolsFromOmfLib(pWld, pLib, pSym, pcLoaded); 1141 1198 } 1142 1199 1143 1200 1144 /** 1201 /** 1145 1202 * Validates a numeric ar_hdr field. 1146 1203 * 1147 * These are supposed to be padded with spaces, however, emximp seems to be 1148 * using null terminators as well (ar_mode for instance). 1204 * These are supposed to be padded with spaces, however, emximp seems to be 1205 * using null terminators as well (ar_mode for instance). 1149 1206 * 1150 1207 * @returns 0 if valid, -1 if invalid (error shown). … … 1177 1234 pachField++; 1178 1235 } 1179 1236 1180 1237 return 0; 1181 1238 } … … 1232 1289 /** 1233 1290 * Enumerates the files in the unix archive. 1234 * 1291 * 1235 1292 * @returns 0 if pfnCallback returned 0 for all the files. 1236 1293 * @returns first non-zero value pfnCallback returns (stops enumeration). … … 1268 1325 { 1269 1326 struct ar_hdr ArHdr; 1327 off_t offFile; 1270 1328 off_t cbFile; 1271 1329 size_t cbRead; … … 1288 1346 || libArchValidateNumField(pLib, ArHdr.ar_size, sizeof(ArHdr.ar_size), 10, "ar_size") ) 1289 1347 return 0; /* bitched already */ 1290 1348 1291 1349 cbFile = libArchHdrGetSize(&ArHdr); 1350 offFile = offNext; 1292 1351 offNext += cbFile; 1293 1352 offNext += offNext & 1; /* make even */ … … 1297 1356 if (cchExtraName) 1298 1357 { 1299 cbFile -= cchExtraName; 1358 offFile += cchExtraName; 1359 cbFile -= cchExtraName; 1300 1360 if (fseek(pFile, cchExtraName, SEEK_CUR)) 1301 1361 return libErr(pLib, "fseek past the extended name failed"); … … 1309 1369 1310 1370 fSpecial = !strcmp(ArHdr.ar_name, "__.SYMDEF") 1311 || !strcmp(ArHdr.ar_name, "/") 1312 || !strcmp(ArHdr.ar_name, "//") 1371 || !strcmp(ArHdr.ar_name, "/") 1372 || !strcmp(ArHdr.ar_name, "//") 1313 1373 || !strcmp(ArHdr.ar_name, "ARFILENAMES"); 1314 1374 1315 1375 /* trailing slashes used to be fashionable. */ 1316 if (!fSpecial && i > 0 && ArHdr.ar_name[i] == '/') 1376 if (!fSpecial && i > 0 && ArHdr.ar_name[i] == '/') 1317 1377 ArHdr.ar_name[i] = '\0'; 1318 1378 … … 1320 1380 if ( fAll 1321 1381 || !fSpecial) 1322 { 1323 rc = pfnCallback(pFile, ArHdr.ar_name, cbFile, pvUser);1382 { 1383 rc = pfnCallback(pFile, ArHdr.ar_name, offFile, cbFile, pvUser); 1324 1384 if (rc) 1325 1385 return rc; 1326 1386 } 1327 1387 1328 1388 /* advance to the next file */ 1329 1389 if (fseek(pFile, offNext, SEEK_SET)) 1330 1390 return libErr(pLib, "seek next failed."); 1331 1391 } 1332 1333 return 0; 1392 1393 return 0; 1334 1394 } 1335 1395 … … 1355 1415 } 1356 1416 1357 #if 01358 1417 /** 1359 1418 * Put out a warning for this library. … … 1373 1432 fputc('\n', stderr); 1374 1433 } 1375 #endif1376 1434 1377 1435 … … 1724 1782 1725 1783 /** 1784 * Checks the name with the specified undefined symbol, or all undefined 1785 * symbols. 1786 * 1787 * @returns 1 if symbol matches. 1788 * @returns 0 if symbol mis-matches. 1789 * @param pWld Linker instance. 1790 * @param pachName The symbol name. 1791 * @param cchName The length of the symbol name 1792 * @param pSym If NULL match all, if !NULL match this. 1793 */ 1794 static int symMatchUnDef(PWLD pWld, const char *pszName, size_t cchName, PWLDSYM pSym) 1795 { 1796 const char *psz; 1797 unsigned fFlags = 0; 1798 unsigned uHash = 0; 1799 int (*pfn)(const char *, const char *, size_t) = pWld->fFlags & WLDC_CASE_INSENSITIVE ? strnicmp : strncmp; 1800 1801 /* look for weak suffix and trucation */ 1802 for (psz = pszName + cchName - 1; psz > pszName; psz--) 1803 if ( psz[0] == '$' 1804 && psz[1] == 'w' 1805 && psz[2] == '$') 1806 { 1807 cchName = psz - pszName; 1808 if (cchName > 200) 1809 break; 1810 } 1811 1812 /** @todo: this isn't 100% correct when we're talking case insensitivity. */ 1813 if (!fFlags) 1814 uHash = symHash(pszName, cchName, pWld->fFlags & WLDC_CASE_INSENSITIVE); 1815 1816 /* compare */ 1817 if (pSym) 1818 return SYM_EQUAL2(pWld, pSym, pszName, fFlags, uHash, cchName, pfn); 1819 1820 for (pSym = pWld->Global.ap[uHash % WLDSYM_HASH_SIZE]; pSym; pSym = pSym->pHashNext) 1821 { 1822 if ((pSym->fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == WLDSF_UNDEF) 1823 { 1824 if (SYM_EQUAL2(pWld, pSym, pszName, fFlags, uHash, cchName, pfn)) 1825 return 1; 1826 } 1827 } 1828 return 0; 1829 } 1830 1831 1832 /** 1726 1833 * Checks the OMF encoded name with the specified undefined 1727 1834 * symbol, or all undefined symbols. … … 1733 1840 * @param pSym If NULL match all, if !NULL match this. 1734 1841 */ 1735 static int symMatchUnDef(PWLD pWld, const unsigned char *pachPascalString, PWLDSYM pSym) 1736 { 1737 int cchName = *pachPascalString; 1738 const char *pszName = pachPascalString + 1; 1739 const char *psz; 1740 unsigned fFlags = 0; 1741 unsigned uHash = 0; 1742 int (*pfn)(const char *, const char *, size_t) = pWld->fFlags & WLDC_CASE_INSENSITIVE ? strnicmp : strncmp; 1743 1744 /* look for weak suffix and trucation */ 1745 for (psz = pszName + cchName - 1; psz > pszName; psz--) 1746 if ( psz[0] == '$' 1747 && psz[1] == 'w' 1748 && psz[2] == '$') 1749 { 1750 cchName = psz - pszName; 1751 if (cchName > 200) 1752 break; 1753 } 1754 1755 /* @todo: this isn't 100% correct when we're talking case in sensitivity. */ 1756 if (!fFlags) 1757 uHash = symHash(pszName, cchName, pWld->fFlags & WLDC_CASE_INSENSITIVE); 1758 1759 /* compare */ 1760 if (pSym) 1761 return SYM_EQUAL2(pWld, pSym, pszName, fFlags, uHash, cchName, pfn); 1762 else 1763 { 1764 for (pSym = pWld->Global.ap[uHash % WLDSYM_HASH_SIZE]; pSym; pSym = pSym->pHashNext) 1765 { 1766 if ((pSym->fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == WLDSF_UNDEF) 1767 { 1768 if (SYM_EQUAL2(pWld, pSym, pszName, fFlags, uHash, cchName, pfn)) 1769 return 1; 1770 } 1771 } 1772 } 1773 return 0; 1842 static int symMatchUnDefOmf(PWLD pWld, const unsigned char *pachPascalString, PWLDSYM pSym) 1843 { 1844 return symMatchUnDef(pWld, pachPascalString + 1, *pachPascalString, pSym); 1774 1845 } 1775 1846 … … 3363 3434 && fread(&pLib->u.Omf.LibHdr, sizeof(OMFREC), 1, phFile) == 1) 3364 3435 { 3365 int rc; 3436 int rc; 3366 3437 if (pLib->u.Omf.LibHdr.chType == LIBHDR) 3367 3438 { … … 3409 3480 libErr(pLib, "Invalid library format or read error."); 3410 3481 } 3411 3482 3412 3483 fclose(phFile); 3413 3484 free(pLib);
Note:
See TracChangeset
for help on using the changeset viewer.