in rts/linker/PEi386.c [898:965]
bool checkAndLoadImportLibrary( pathchar* arch_name, char* member_name, FILE* f )
{
char* image;
static bool load_dll_warn = false;
if (load_dll_warn) { return 0; }
/* Based on Import Library specification. PE Spec section 7.1 */
COFF_import_header hdr;
size_t n;
n = fread(&hdr, 1, sizeof_COFF_import_Header, f);
if (n != sizeof_COFF_import_Header) {
errorBelch("loadImportLibrary: error whilst reading `%s' header "
"in `%" PATH_FMT "'\n",
member_name, arch_name);
fseek(f, -(long int)sizeof_COFF_import_Header, SEEK_CUR);
return false;
}
if ( hdr.Sig1 != IMAGE_FILE_MACHINE_UNKNOWN
|| hdr.Sig2 != IMPORT_OBJECT_HDR_SIG2
|| getObjectType ((char*)&hdr, arch_name) != COFF_IMPORT_LIB) {
fseek(f, -(long int)sizeof_COFF_import_Header, SEEK_CUR);
IF_DEBUG(linker, debugBelch("loadArchive: Object `%s` is not an import lib. Skipping...\n", member_name));
return false;
}
IF_DEBUG(linker, debugBelch("loadArchive: reading %lu bytes at %ld\n", hdr.SizeOfData, ftell(f)));
image = stgMallocBytes(hdr.SizeOfData, "checkAndLoadImportLibrary(image)");
n = fread(image, 1, hdr.SizeOfData, f);
if (n != hdr.SizeOfData) {
errorBelch("loadArchive: error whilst reading `%s' header in `%" PATH_FMT "'. Did not read enough bytes.\n",
member_name, arch_name);
fseek(f, -(n + sizeof_COFF_import_Header), SEEK_CUR);
return false;
}
char* symbol = strtok(image, "\0");
int symLen = strlen(symbol) + 1;
int nameLen = n - symLen;
char* dllName = stgMallocBytes(sizeof(char) * nameLen,
"checkAndLoadImportLibrary(dllname)");
dllName = strncpy(dllName, image + symLen, nameLen);
pathchar* dll = stgMallocBytes(sizeof(wchar_t) * nameLen,
"checkAndLoadImportLibrary(dll)");
mbstowcs(dll, dllName, nameLen);
stgFree(dllName);
IF_DEBUG(linker, debugBelch("loadArchive: read symbol %s from lib `%" PATH_FMT "'\n", symbol, dll));
const char* result = addDLL(dll);
stgFree(image);
if (result != NULL) {
errorBelch("Could not load `%" PATH_FMT "'. Reason: %s\n", dll, result);
load_dll_warn = true;
stgFree(dll);
fseek(f, -(n + sizeof_COFF_import_Header), SEEK_CUR);
return false;
}
stgFree(dll);
return true;
}