bool checkAndLoadImportLibrary()

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;
}