Changeset 3667 for trunk/emx/src/emxomf/weakld.c
- Timestamp:
- Sep 18, 2010, 3:06:59 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/emx/src/emxomf/weakld.c
r3462 r3667 35 35 * There is a couple of symbol types, but we can skip most of them for this 36 36 * pre-linking operation. We use one symbol type which is public or global 37 * symbols if you like. Perhaps it would be wise to d evide them into separat37 * symbols if you like. Perhaps it would be wise to divide them into separat 38 38 * type groups, but the choice was made to differenciate this using flags. 39 39 * So, symbol enumeration is done using flag masks. … … 101 101 #include <sys/omflib.h> 102 102 #include <sys/moddef.h> 103 #include <sys/elf.h> 104 #include <ar.h> 103 105 #include "defs.h" 104 106 #include "grow.h" … … 155 157 const char *pszLibName; 156 158 /** Filehandle if open */ 157 FILE * phFile; 158 /** Pointer to extended dictiorary. */ 159 void * pDict; 160 /** Library header. */ 161 OMFLIBHDR LibHdr; 159 FILE *phFile; 160 /** Set if it's a OMF library, clear if it's a unix archive. */ 161 unsigned fOmfLib; 162 /** Pointer to the extended dictionary (OMF) / symbol table (AR). */ 163 void *pDict; 164 union 165 { 166 struct 167 { 168 /** Library header. */ 169 OMFLIBHDR LibHdr; 170 } Omf; 171 struct 172 { 173 /** Later. */ 174 unsigned uDummy; 175 } Ar; 176 } u; 162 177 /** Linked list next pointer. */ 163 struct wldlib * 178 struct wldlib *pNext; 164 179 } WLDLIB, *PWLDLIB; 165 180 … … 414 429 static void wldIntErr(PWLD pWld, PWLDMOD pMod, const char *pszFile, unsigned iLine, const char *pszFunction); 415 430 static unsigned pass1ReadOMFMod(PWLD pWld, PWLDMOD pMod, int fLibSearch); 431 static unsigned pass1ReadELFMod(PWLD pWld, PWLDMOD pMod, int fLibSearch); 416 432 /** Parameter structure for wldDefCallback(). */ 417 433 typedef struct wldDefCallback_param … … 434 450 static void libCloseDict(PWLDLIB pLib); 435 451 static int libTryLoadSymbolThruDictionary(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded); 452 static int libLoadUndefSymbolsFromOmfLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded); 453 /** 454 * Callback parameter structure used between libLoadUndefSymbolsFromArchLib 455 * and libLoadUndefSymbolsFromArchLibCallback 456 */ 457 typedef struct libLoadUndefSymbolsFromArchLib_param 458 { 459 /** The linker instance. */ 460 PWLD pWld; 461 /** The library. */ 462 PWLDLIB pLib; 463 /** See libLoadUndefSymbols. */ 464 PWLDSYM pSym; 465 /** See libLoadUndefSymbols. */ 466 unsigned *pcLoaded; 467 } WLDLIBLOADUSFALPARAM, *PWLDLIBLOADUSFALPARAM; 468 static int libLoadUndefSymbolsFromArchLibCallback(FILE *pFile, const char *pszName, off_t cbFile, void *pvUser); 469 static int libLoadUndefSymbolsFromArchLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded); 436 470 static int libLoadUndefSymbols(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded); 471 /** 472 * Enumeration callback routine. 473 * @returns Any non-zero value stops the enumeration and is passed to the caller. 474 * @param pFile Stream positioned at the start of the file. Don't close. 475 * @param pszName The file name. 476 * @param cbFile The file size. 477 * @param pvUser The user parameter. 478 */ 479 typedef int (* PFNLIBENUMFILE)(FILE *pFile, const char *pszName, off_t cbFile, void *pvUser); 480 static int libEnumFilesArch(PWLDLIB pLib, int fAll, PFNLIBENUMFILE pfnCallback, void *pvUser); 437 481 static int libErr(PWLDLIB pLib, const char *pszFormat, ...); 438 482 #if 0 … … 678 722 #if 0 679 723 FILE *phFile; 724 680 725 /* been here, done that? */ 681 if (pLib-> pDict)726 if (pLib->upDict) 682 727 return 0; 683 728 684 /* check if it acutally is a library and have an ext dict */ 685 if ( pLib->LibHdr.chType != LIBHDR 686 || pLib->LibHdr.offDict != 0 687 || pLib->LibHdr.cDictBlocks != 0) 688 return 1; 689 729 if (pLib->fOmfLib) 730 { 731 /* check if it acutally is a library and have an ext dict */ 732 if ( pLib->u.Omf.LibHdr.chType != LIBHDR 733 || pLib->u.Omf.LibHdr.offDict != 0 734 || pLib->u.Omf.LibHdr.cDictBlocks != 0) 735 return 1; 736 } 737 else 738 { 739 } 740 690 741 /* ensure it's open. */ 691 742 phFile = libOpen(pLib); 692 743 if (!phFile) 693 744 return -1; 694 695 /* position us */ 696 if (fseek(phFile, pLib->LibHdr.offDict, SEEK_SET)) 697 return libErr(pLib, "Failed to seek to extended dictionary (offset %d).", (int)pLib->LibHdr.offDict); 698 699 /* read it */ 700 pLib->pDict = xmalloc(pLib->LibHdr.cDictBlocks * 512); 701 if (fread(pLib->pDict, 512, pLib->LibHdr.cDictBlocks, phFile) == pLib->LibHdr.cDictBlocks) 702 return 0; 703 libErr(pLib, "Failed to read extended dictionary."); 745 746 if (pLib->fOmfLib) 747 { 748 /* position us */ 749 if (fseek(phFile, pLib->LibHdr.offDict, SEEK_SET)) 750 return libErr(pLib, "Failed to seek to extended dictionary (offset %d).", (int)pLib->LibHdr.offDict); 751 752 /* read it */ 753 pLib->pDict = xmalloc(pLib->LibHdr.cDictBlocks * 512); 754 if (fread(pLib->pDict, 512, pLib->LibHdr.cDictBlocks, phFile) == pLib->LibHdr.cDictBlocks) 755 return 0; 756 757 libErr(pLib, "Failed to read extended dictionary."); 758 } 759 704 760 free(pLib->pDict); 705 761 pLib->pDict = NULL; 706 762 return -1; 763 707 764 #else 708 765 /* till we support processing the dictionary, we pretend there is none. */ 709 766 pLib->pDict = NULL; 710 return -1;767 return 1; 711 768 #endif 712 769 } … … 741 798 static int libTryLoadSymbolThruDictionary(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded) 742 799 { 743 return libLoadUndefSymbols(pWld, pLib, pSym, pcLoaded); /* @todo implement this function! */ 744 } 745 746 747 /** 748 * Read thru an module looking for definitions for undef symbols. 749 * If a definition is found we'll load the module containing it. 750 * 751 * @returns 0 on non failure. 752 * @returns 42 if none found. 753 * @returns -1 on link abort error. 754 * @param pWld Linker instance. 755 * @param pLib Library to search. 756 * @param pSym Undefined symbol to search for. 757 * If NULL we'll try and see if any defined global symbol we 758 * encounter is undefined. 800 return libLoadUndefSymbols(pWld, pLib, pSym, pcLoaded); /** @todo implement this function! */ 801 } 802 803 804 /** 805 * Implementation of libLoadUndefSymbols for unix archives. 806 * 807 * @returns see libLoadUndefSymbols 808 * @param pWld Linker instance. 809 * @param pLib Library to search. 810 * @param pSym See libLoadUndefSymbols. 759 811 * @param pcLoaded Number of modules which was loaded from this library. 760 812 */ 761 static int libLoadUndefSymbols (PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded)813 static int libLoadUndefSymbolsFromOmfLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded) 762 814 { 763 815 FILE * phFile = pLib->phFile; … … 774 826 775 827 /* Position the library at the first module record. */ 776 if (fseek(phFile, pLib-> LibHdr.chType == LIBHDR ? pLib->LibHdr.cb + 3 : 0, SEEK_SET))828 if (fseek(phFile, pLib->u.Omf.LibHdr.chType == LIBHDR ? pLib->u.Omf.LibHdr.cb + 3 : 0, SEEK_SET)) 777 829 return libErr(pLib, "Error when seeking to first module."); 778 830 779 if (pLib-> LibHdr.chType != LIBHDR)831 if (pLib->u.Omf.LibHdr.chType != LIBHDR) 780 832 { 781 833 uchEnd1 = MODEND; … … 1004 1056 if (OmfRec.chType == MODEND || OmfRec.chType == (MODEND | REC32)) 1005 1057 { 1006 unsigned cbPage = pLib-> LibHdr.cb + 3;1058 unsigned cbPage = pLib->u.Omf.LibHdr.cb + 3; 1007 1059 off_t off = ftell(phFile) + offSkip; 1008 1060 off -= cbPage * (off / cbPage); /* don't trust this to be 2**n. */ … … 1031 1083 1032 1084 /** 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. 1103 * 1104 * @returns see libLoadUndefSymbols 1105 * @param pWld Linker instance. 1106 * @param pLib Library to search. 1107 * @param pSym See libLoadUndefSymbols. 1108 * @param pcLoaded Number of modules which was loaded from this library. 1109 */ 1110 static int libLoadUndefSymbolsFromArchLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded) 1111 { 1112 WLDLIBLOADUSFALPARAM Param; 1113 1114 Param.pWld = pWld; 1115 Param.pLib = pLib; 1116 Param.pSym = pSym; 1117 Param.pcLoaded = pcLoaded; 1118 return libEnumFilesArch(pLib, 0 /*fAll*/, libLoadUndefSymbolsFromArchLibCallback, &Param); 1119 } 1120 1121 1122 /** 1123 * Read thru a library looking for definitions for undef symbols. 1124 * If a definition is found we'll load the module containing it. 1125 * 1126 * @returns 0 on non failure. 1127 * @returns 42 if none found. 1128 * @returns -1 on link abort error. 1129 * @param pWld Linker instance. 1130 * @param pLib Library to search. 1131 * @param pSym Undefined symbol to search for. 1132 * If NULL we'll try and see if any defined global symbol we 1133 * encounter is undefined. 1134 * @param pcLoaded Number of modules which was loaded from this library. 1135 */ 1136 static int libLoadUndefSymbols(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded) 1137 { 1138 if (!pLib->fOmfLib) 1139 return libLoadUndefSymbolsFromArchLib(pWld, pLib, pSym, pcLoaded); 1140 return libLoadUndefSymbolsFromOmfLib(pWld, pLib, pSym, pcLoaded); 1141 } 1142 1143 1144 /** 1145 * Validates a numeric ar_hdr field. 1146 * 1147 * These are supposed to be padded with spaces, however, emximp seems to be 1148 * using null terminators as well (ar_mode for instance). 1149 * 1150 * @returns 0 if valid, -1 if invalid (error shown). 1151 * @param pachField The field. 1152 * @param cchField The field length. 1153 * @param uBase 10 for decimal, 8 for octal. 1154 * @param pszName The field name. 1155 */ 1156 static int libArchValidateNumField(PWLDLIB pLib, char const *pachField, size_t cchField, unsigned uBase, const char *pszName) 1157 { 1158 while (cchField > 0) 1159 { 1160 unsigned ch = *pachField; 1161 if (ch - '0' >= uBase) 1162 { 1163 if (ch == ' ' || !ch) 1164 break; 1165 return libErr(pLib, "bad archive header field: %s", pszName); 1166 } 1167 cchField--; 1168 pachField++; 1169 } 1170 1171 while (cchField > 0) 1172 { 1173 char ch = *pachField; 1174 if (ch != ' ' && ch) 1175 return libErr(pLib, "bad archive header field: %s", pszName); 1176 cchField--; 1177 pachField++; 1178 } 1179 1180 return 0; 1181 } 1182 1183 /** 1184 * Checks the name field to see if there is a BSD style variable sized name 1185 * field following the header. 1186 * 1187 * @returns 0 if none, length if something. 1188 * @param pArHdr The archive header. 1189 */ 1190 static unsigned libArchHdrGetExtNameLen(struct ar_hdr *pArHdr) 1191 { 1192 unsigned cchExtName = 0; 1193 if (!memcmp(&pArHdr->ar_name[0], AR_EFMT1, sizeof(AR_EFMT1) - 1)) 1194 { 1195 int cch = sizeof(pArHdr->ar_name) - sizeof(AR_EFMT1) - 1; 1196 const char *pch = &pArHdr->ar_name[sizeof(AR_EFMT1) - 1]; 1197 while (cch-- > 0) 1198 { 1199 unsigned uDig = (unsigned char)*pch++ - '0'; 1200 if (uDig > 10) 1201 break; 1202 cchExtName *= 10; 1203 cchExtName += uDig; 1204 } 1205 } 1206 return cchExtName; 1207 } 1208 1209 1210 /** 1211 * Converts the size field of the header into something we can use. 1212 * @returns ar_size as off_t. 1213 * @param pArHdr The archive header. 1214 */ 1215 static off_t libArchHdrGetSize(struct ar_hdr *pArHdr) 1216 { 1217 off_t cb = 0; 1218 int cch = sizeof(pArHdr->ar_size); 1219 const char *pch = &pArHdr->ar_size[0]; 1220 while (cch-- > 0) 1221 { 1222 unsigned uDig = (unsigned char)*pch++ - '0'; 1223 if (uDig > 10) 1224 break; 1225 cb *= 10; 1226 cb += uDig; 1227 } 1228 return cb; 1229 } 1230 1231 1232 /** 1233 * Enumerates the files in the unix archive. 1234 * 1235 * @returns 0 if pfnCallback returned 0 for all the files. 1236 * @returns first non-zero value pfnCallback returns (stops enumeration). 1237 * @returns -1 if the library is invalid. 1238 * @param pLib The Library to enumerate 1239 * @param fAll Whether to include the special files or not. 1240 * @param pfnCallback The callback to invoke for each file. 1241 * @param pvUser The user argument to pass to the callback. 1242 */ 1243 static int libEnumFilesArch(PWLDLIB pLib, int fAll, PFNLIBENUMFILE pfnCallback, void *pvUser) 1244 { 1245 int rc = 0; 1246 FILE *pFile = pLib->phFile; 1247 off_t offNext; 1248 char szMagic[SARMAG + 1]; 1249 1250 if (pLib->fOmfLib) 1251 return libErr(pLib, "OMF library, expected ARCH!"); 1252 1253 /* 1254 * Read+reverify the magic. 1255 */ 1256 if ( fseek(pFile, 0, SEEK_SET) != 0 1257 || fread(&szMagic[0], SARMAG, 1, pFile) != 1) 1258 return libErr(pLib, "failed to read library magic"); 1259 szMagic[SARMAG] = '\0'; 1260 if (strcmp(szMagic, ARMAG) != 0) 1261 return libErr(pLib, "invalid library magic"); 1262 1263 /* 1264 * Process the archive, file by file. 1265 */ 1266 offNext = SARMAG; 1267 while (!feof(pFile)) 1268 { 1269 struct ar_hdr ArHdr; 1270 off_t cbFile; 1271 size_t cbRead; 1272 int cchExtraName; 1273 int fSpecial; 1274 int i; 1275 1276 /* read + verify the archive header */ 1277 cbRead = fread(&ArHdr, 1, sizeof(ArHdr), pFile); 1278 if (cbRead != sizeof(ArHdr)) 1279 return cbRead == 0 && feof(pFile) ? 0 : libErr(pLib, "fread error"); 1280 offNext += sizeof(ArHdr); 1281 1282 if (memcmp(ArHdr.ar_fmag, ARFMAG, sizeof(ArHdr.ar_fmag))) 1283 return libErr(pLib, "Bad ar_fmag value"); 1284 if ( libArchValidateNumField(pLib, ArHdr.ar_date, sizeof(ArHdr.ar_date), 10, "ar_date") 1285 || libArchValidateNumField(pLib, ArHdr.ar_uid, sizeof(ArHdr.ar_uid), 10, "ar_uid") 1286 || libArchValidateNumField(pLib, ArHdr.ar_gid, sizeof(ArHdr.ar_gid), 10, "ar_gid") 1287 || libArchValidateNumField(pLib, ArHdr.ar_mode, sizeof(ArHdr.ar_mode), 8, "ar_mode") 1288 || libArchValidateNumField(pLib, ArHdr.ar_size, sizeof(ArHdr.ar_size), 10, "ar_size") ) 1289 return 0; /* bitched already */ 1290 1291 cbFile = libArchHdrGetSize(&ArHdr); 1292 offNext += cbFile; 1293 offNext += offNext & 1; /* make even */ 1294 1295 /* skip the extended name field if present (BSD). */ 1296 cchExtraName = libArchHdrGetExtNameLen(&ArHdr); 1297 if (cchExtraName) 1298 { 1299 cbFile -= cchExtraName; 1300 if (fseek(pFile, cchExtraName, SEEK_CUR)) 1301 return libErr(pLib, "fseek past the extended name failed"); 1302 } 1303 1304 /* strip trailing spaces from the header name. */ 1305 i = sizeof(ArHdr.ar_name); 1306 ArHdr.ar_name[i] = '\0'; 1307 while (i-- > 0 && ArHdr.ar_name[i] == ' ') 1308 ArHdr.ar_name[i] = '\0'; 1309 1310 fSpecial = !strcmp(ArHdr.ar_name, "__.SYMDEF") 1311 || !strcmp(ArHdr.ar_name, "/") 1312 || !strcmp(ArHdr.ar_name, "//") 1313 || !strcmp(ArHdr.ar_name, "ARFILENAMES"); 1314 1315 /* trailing slashes used to be fashionable. */ 1316 if (!fSpecial && i > 0 && ArHdr.ar_name[i] == '/') 1317 ArHdr.ar_name[i] = '\0'; 1318 1319 /* ignore the archive symbol table. */ 1320 if ( fAll 1321 || !fSpecial) 1322 { 1323 rc = pfnCallback(pFile, ArHdr.ar_name, cbFile, pvUser); 1324 if (rc) 1325 return rc; 1326 } 1327 1328 /* advance to the next file */ 1329 if (fseek(pFile, offNext, SEEK_SET)) 1330 return libErr(pLib, "seek next failed."); 1331 } 1332 1333 return 0; 1334 } 1335 1336 1337 /** 1033 1338 * Put out an error for this library. 1339 * @returns -1. 1034 1340 * @param pLib Library which the warning occured in. 1035 1341 * @param pszFormat Message format. … … 2569 2875 2570 2876 2571 2877 /** 2878 * Reads an ELF module from a file. 2879 * 2880 * @returns 0 on success. 2881 * @returns non zero on failure. 2882 * @param pWld Pointer to linker instance. 2883 * @param pMod Pointer to module 2884 * @param fLibSearch Set if we're doing library search at this time. 2885 */ 2886 static unsigned pass1ReadELFMod(PWLD pWld, PWLDMOD pMod, int fLibSearch) 2887 { 2888 /** @todo implement me. */ 2889 return 0; 2890 } 2572 2891 2573 2892 … … 2687 3006 2688 3007 /** 3008 * Checks if the ELF header is valid. 3009 * 3010 * @returns 1 if it is, 0 if it isn't. 3011 * @param pEhdr The ELF header. 3012 * @param pszName The file name to use when reporting errors. 3013 */ 3014 static int wldIsValidElfHdr(Elf32_Ehdr const *pEhdr, const char *pszName) 3015 { 3016 if (!IS_ELF(*pEhdr)) 3017 fprintf(stderr, "weakld: '%s': not ELF file..\n", pszName); 3018 else if ( pEhdr->e_ident[EI_CLASS] != ELFCLASS32 3019 && pEhdr->e_ident[EI_CLASS] != ELFCLASSNONE) 3020 fprintf(stderr, "weakld: '%s': wrong ELF class.\n", pszName); 3021 else if ( pEhdr->e_ident[EI_DATA] != ELFDATA2LSB 3022 && pEhdr->e_ident[EI_DATA] != ELFDATANONE) 3023 fprintf(stderr, "weakld: '%s': wrong ELF endian.\n", pszName); 3024 else if (pEhdr->e_ident[EI_VERSION] != EV_CURRENT) 3025 fprintf(stderr, "weakld: '%s': wrong ELF version.\n", pszName); 3026 /* Ignore EI_OSABI, EI_ABIVERSION and EI_PAD. */ 3027 else if (pEhdr->e_type != ET_REL) 3028 fprintf(stderr, "weakld: '%s': not relocatable ELF file.\n", pszName); 3029 else if ( pEhdr->e_machine != EM_386 3030 && pEhdr->e_machine != EM_486) 3031 fprintf(stderr, "weakld: '%s': not 386 or 486 ELF file.\n", pszName); 3032 else if (pEhdr->e_version != EV_CURRENT) 3033 fprintf(stderr, "weakld: '%s': wrong ELF version (#2).\n", pszName); 3034 else if (pEhdr->e_ehsize != sizeof(*pEhdr)) 3035 fprintf(stderr, "weakld: '%s': wrong ELF header size.\n", pszName); 3036 else if (pEhdr->e_phoff && pEhdr->e_phoff < sizeof(*pEhdr)) 3037 fprintf(stderr, "weakld: '%s': bad ELF program header offset.\n", pszName); 3038 else if (pEhdr->e_shoff && pEhdr->e_shoff < sizeof(*pEhdr)) 3039 fprintf(stderr, "weakld: '%s': bad ELF section header offset.\n", pszName); 3040 else if (pEhdr->e_phentsize != sizeof(Elf32_Phdr) && (pEhdr->e_phnum || pEhdr->e_phentsize)) 3041 fprintf(stderr, "weakld: '%s': wrong ELF program header size: %d\n", pszName, pEhdr->e_phentsize); 3042 else if (pEhdr->e_shentsize != sizeof(Elf32_Shdr) && (pEhdr->e_shnum || pEhdr->e_shentsize)) 3043 fprintf(stderr, "weakld: '%s': wrong ELF section header size: %d\n", pszName, pEhdr->e_shentsize); 3044 else 3045 return 1; 3046 return 0; 3047 } 3048 3049 /** 2689 3050 * Adds a object module to the linking process. 2690 3051 * The object module will be analysed and the file handle closed. … … 2703 3064 int WLDAddObject(PWLD pWld, FILE *phFile, const char *pszName) 2704 3065 { 2705 OMFREC OmfRec = {0,0}; 3066 union 3067 { 3068 OMFREC OmfRec; 3069 Elf32_Ehdr Ehdr; 3070 } uBuf; 2706 3071 int rc = 0; 2707 3072 if (!phFile) … … 2713 3078 } 2714 3079 WLDINFO(pWld, ("adding object %s.", pszName)); 3080 if (fread(&uBuf.OmfRec, sizeof(uBuf.OmfRec), 1, phFile) != 1) 3081 { 3082 fprintf(stderr, "weakld: error reading object file '%s'.\n", pszName); 3083 fclose(phFile); 3084 return -1; 3085 } 2715 3086 2716 3087 /* 2717 * An object module is either a object or a library.3088 * An object module is either a object (OMF or ELF) or a library (OMF). 2718 3089 * In anycase all the modules it contains is to be added to the link. 2719 3090 */ 2720 fread(&OmfRec, sizeof(OmfRec), 1, phFile); 2721 if (OmfRec.chType == THEADR) 3091 if (uBuf.OmfRec.chType == THEADR) 2722 3092 { 2723 3093 /* Single Object */ … … 2731 3101 modClose(pMod); 2732 3102 } 2733 else if ( OmfRec.chType == LIBHDR)3103 else if (uBuf.OmfRec.chType == LIBHDR) 2734 3104 { 2735 3105 /* Library of object modules */ 2736 while ( OmfRec.chType != LIBEND &&OmfRec.chType != (LIBEND | REC32))2737 { 2738 if ( OmfRec.chType == THEADR ||OmfRec.chType == (THEADR | REC32))3106 while (uBuf.OmfRec.chType != LIBEND && uBuf.OmfRec.chType != (LIBEND | REC32)) 3107 { 3108 if (uBuf.OmfRec.chType == THEADR || uBuf.OmfRec.chType == (THEADR | REC32)) 2739 3109 { 2740 3110 PWLDMOD pMod = xmalloc(sizeof(*pMod)); … … 2742 3112 pMod->pszModName = strpool_add(pWld->pStrMisc, pszName); 2743 3113 pMod->phFile = phFile; 2744 pMod->off = ftell(phFile) - sizeof( OmfRec);3114 pMod->off = ftell(phFile) - sizeof(uBuf.OmfRec); 2745 3115 *pWld->ppObjsAdd = pMod; 2746 3116 pWld->ppObjsAdd = &pMod->pNext; … … 2761 3131 { 2762 3132 /* skip to the net record */ 2763 fseek(phFile, OmfRec.cb, SEEK_CUR);3133 fseek(phFile, uBuf.OmfRec.cb, SEEK_CUR); 2764 3134 } 2765 3135 2766 3136 /* read next record */ 2767 fread(& OmfRec, sizeof(OmfRec), 1, phFile);3137 fread(&uBuf.OmfRec, sizeof(uBuf.OmfRec), 1, phFile); 2768 3138 } 2769 3139 fclose(phFile); 3140 } 3141 else if ( uBuf.Ehdr.e_ident[EI_MAG0] == ELFMAG0 3142 && uBuf.Ehdr.e_ident[EI_MAG1] == ELFMAG1 3143 && uBuf.Ehdr.e_ident[EI_MAG2] == ELFMAG2 3144 && fread((char *)&uBuf.Ehdr + sizeof(uBuf.OmfRec), 3145 sizeof(uBuf.Ehdr) - sizeof(uBuf.OmfRec), 1, phFile) == 1 3146 && uBuf.Ehdr.e_ident[EI_MAG3] == ELFMAG3) 3147 { 3148 if (wldIsValidElfHdr(&uBuf.Ehdr, pszName)) 3149 { 3150 /* Single Object */ 3151 PWLDMOD pMod = xmalloc(sizeof(*pMod)); 3152 memset(pMod, 0, sizeof(*pMod)); 3153 pMod->pszModName = strpool_add(pWld->pStrMisc, pszName); 3154 pMod->phFile = phFile; 3155 *pWld->ppObjsAdd = pMod; 3156 pWld->ppObjsAdd = &pMod->pNext; 3157 rc = pass1ReadELFMod(pWld, pMod, 0); 3158 modClose(pMod); 3159 } 3160 else 3161 { 3162 fclose(phFile); 3163 rc = -1; 3164 } 2770 3165 } 2771 3166 else … … 2946 3341 int WLDAddLibrary(PWLD pWld, FILE *phFile, const char *pszName) 2947 3342 { 2948 PWLDLIB pLib; 2949 int rc = 0; 3343 PWLDLIB pLib; 2950 3344 2951 3345 if (!phFile) … … 2965 3359 pLib->pNext = NULL; 2966 3360 2967 /* read the library header . */3361 /* read the library header, detect the format. */ 2968 3362 if ( !fseek(phFile, 0, SEEK_SET) 2969 && fread(&pLib->LibHdr, sizeof(OMFREC), 1, phFile) == 1 2970 && ( pLib->LibHdr.chType != LIBHDR 2971 || fread(&pLib->LibHdr.offDict, sizeof(pLib->LibHdr) - sizeof(OMFREC), 1, phFile) == 1 2972 ) 2973 ) 2974 { 2975 /* link it in */ 2976 *pWld->ppLibsAdd = pLib; 2977 pWld->ppLibsAdd = &pLib->pNext; 2978 libClose(pLib); 3363 && fread(&pLib->u.Omf.LibHdr, sizeof(OMFREC), 1, phFile) == 1) 3364 { 3365 int rc; 3366 if (pLib->u.Omf.LibHdr.chType == LIBHDR) 3367 { 3368 pLib->fOmfLib = 1; 3369 if (fread(&pLib->u.Omf.LibHdr.offDict, sizeof(pLib->u.Omf.LibHdr) - sizeof(OMFREC), 1, phFile) == 1) 3370 rc = 0; 3371 else 3372 rc = libErr(pLib, "Failed reading OMF library header."); 3373 } 3374 else if (pLib->u.Omf.LibHdr.chType == THEADR) 3375 pLib->fOmfLib = 1; 3376 else if (!memcmp(&pLib->u.Omf.LibHdr, ARMAG, sizeof(OMFREC))) 3377 { 3378 char achMagic[SARMAG]; 3379 if (fread(achMagic, SARMAG - sizeof(OMFREC), 1, phFile) == 1) 3380 { 3381 if (!memcmp(achMagic, ARMAG + sizeof(OMFREC), SARMAG - sizeof(OMFREC))) 3382 { 3383 pLib->fOmfLib = 0; 3384 pLib->u.Ar.uDummy = 0; 3385 rc = 0; 3386 } 3387 else 3388 rc = libErr(pLib, "Invalid library format."); 3389 } 3390 else 3391 rc = libErr(pLib, "Failed reading AR library magic."); 3392 } 3393 else 3394 rc = libErr(pLib, "Invalid library format."); 3395 3396 if (rc == 0) 3397 { 3398 /* link it in */ 3399 *pWld->ppLibsAdd = pLib; 3400 pWld->ppLibsAdd = &pLib->pNext; 3401 libClose(pLib); 3402 3403 return 0; 3404 } 2979 3405 } 2980 3406 else … … 2982 3408 /* We failed. */ 2983 3409 libErr(pLib, "Invalid library format or read error."); 2984 fclose(phFile); 2985 free(pLib); 2986 rc = -1; 2987 } 2988 2989 return rc; 3410 } 3411 3412 fclose(phFile); 3413 free(pLib); 3414 return -1; 2990 3415 } 2991 3416 … … 3612 4037 pid_t pid = getpid(); 3613 4038 static char s_szTmp[_MAX_PATH + 1]; 3614 4039 3615 4040 /* We need to apply _realrealpath to the tmpdir, so resolve that once and for all. */ 3616 4041 if (!s_szTmp[0])
Note:
See TracChangeset
for help on using the changeset viewer.