HMODULE CRemoteLoader::LoadLibraryByPathIntoMemoryA( PCHAR Path, BOOL PEHeader ) { HMODULE hReturnValue = NULL; DebugShout( "[LoadLibraryByPathIntoMemoryA] %s (0x%X)", Path, PEHeader ); ModuleFile File = InitModuleFile( Path ); if( File.IsValid() == FALSE ) { DebugShout( "[LoadLibraryByPathIntoMemoryA] Failed to open file handle!" ); return NULL; } hReturnValue = LoadLibraryFromMemory( File.Buffer, File.Size, PEHeader, Path ); if( FreeModuleFile( File ) == FALSE ) { DebugShout( "[LoadLibraryByPathIntoMemoryA] Failed to free file handle..." ); } return hReturnValue; }
ModuleManager::AddModuleResult ModuleManager::addModule(StringRef FileName, ModuleKind Type, SourceLocation ImportLoc, ModuleFile *ImportedBy, unsigned Generation, off_t ExpectedSize, time_t ExpectedModTime, ModuleFile *&Module, std::string &ErrorStr) { Module = 0; // Look for the file entry. This only fails if the expected size or // modification time differ. const FileEntry *Entry; if (lookupModuleFile(FileName, ExpectedSize, ExpectedModTime, Entry)) { ErrorStr = "module file out of date"; return OutOfDate; } if (!Entry && FileName != "-") { ErrorStr = "module file not found"; return Missing; } // Check whether we already loaded this module, before ModuleFile *&ModuleEntry = Modules[Entry]; bool NewModule = false; if (!ModuleEntry) { // Allocate a new module. ModuleFile *New = new ModuleFile(Type, Generation); New->Index = Chain.size(); New->FileName = FileName.str(); New->File = Entry; New->ImportLoc = ImportLoc; Chain.push_back(New); NewModule = true; ModuleEntry = New; New->InputFilesValidationTimestamp = 0; if (New->Kind == MK_Module) { std::string TimestampFilename = New->getTimestampFilename(); vfs::Status Status; // A cached stat value would be fine as well. if (!FileMgr.getNoncachedStatValue(TimestampFilename, Status)) New->InputFilesValidationTimestamp = Status.getLastModificationTime().toEpochTime(); } // Load the contents of the module if (llvm::MemoryBuffer *Buffer = lookupBuffer(FileName)) { // The buffer was already provided for us. assert(Buffer && "Passed null buffer"); New->Buffer.reset(Buffer); } else { // Open the AST file. llvm::error_code ec; if (FileName == "-") { ec = llvm::MemoryBuffer::getSTDIN(New->Buffer); if (ec) ErrorStr = ec.message(); } else New->Buffer.reset(FileMgr.getBufferForFile(FileName, &ErrorStr)); if (!New->Buffer) return Missing; } // Initialize the stream New->StreamFile.init((const unsigned char *)New->Buffer->getBufferStart(), (const unsigned char *)New->Buffer->getBufferEnd()); } if (ImportedBy) { ModuleEntry->ImportedBy.insert(ImportedBy); ImportedBy->Imports.insert(ModuleEntry); } else { if (!ModuleEntry->DirectlyImported) ModuleEntry->ImportLoc = ImportLoc; ModuleEntry->DirectlyImported = true; } Module = ModuleEntry; return NewModule? NewlyLoaded : AlreadyLoaded; }
ModuleManager::AddModuleResult ModuleManager::addModule(StringRef FileName, ModuleKind Type, SourceLocation ImportLoc, ModuleFile *ImportedBy, unsigned Generation, off_t ExpectedSize, time_t ExpectedModTime, ASTFileSignature ExpectedSignature, ASTFileSignatureReader ReadSignature, ModuleFile *&Module, std::string &ErrorStr) { Module = nullptr; // Look for the file entry. This only fails if the expected size or // modification time differ. const FileEntry *Entry; if (Type == MK_ExplicitModule) { // If we're not expecting to pull this file out of the module cache, it // might have a different mtime due to being moved across filesystems in // a distributed build. The size must still match, though. (As must the // contents, but we can't check that.) ExpectedModTime = 0; } if (lookupModuleFile(FileName, ExpectedSize, ExpectedModTime, Entry)) { ErrorStr = "module file out of date"; return OutOfDate; } if (!Entry && FileName != "-") { ErrorStr = "module file not found"; return Missing; } // Check whether we already loaded this module, before ModuleFile *&ModuleEntry = Modules[Entry]; bool NewModule = false; if (!ModuleEntry) { // Allocate a new module. ModuleFile *New = new ModuleFile(Type, Generation); New->Index = Chain.size(); New->FileName = FileName.str(); New->File = Entry; New->ImportLoc = ImportLoc; Chain.push_back(New); if (!ImportedBy) Roots.push_back(New); NewModule = true; ModuleEntry = New; New->InputFilesValidationTimestamp = 0; if (New->Kind == MK_ImplicitModule) { std::string TimestampFilename = New->getTimestampFilename(); vfs::Status Status; // A cached stat value would be fine as well. if (!FileMgr.getNoncachedStatValue(TimestampFilename, Status)) New->InputFilesValidationTimestamp = Status.getLastModificationTime().toEpochTime(); } // Load the contents of the module if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) { // The buffer was already provided for us. New->Buffer = std::move(Buffer); } else { // Open the AST file. llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf( (std::error_code())); if (FileName == "-") { Buf = llvm::MemoryBuffer::getSTDIN(); } else { // Leave the FileEntry open so if it gets read again by another // ModuleManager it must be the same underlying file. // FIXME: Because FileManager::getFile() doesn't guarantee that it will // give us an open file, this may not be 100% reliable. Buf = FileMgr.getBufferForFile(New->File, /*IsVolatile=*/false, /*ShouldClose=*/false); } if (!Buf) { ErrorStr = Buf.getError().message(); return Missing; } New->Buffer = std::move(*Buf); } // Initialize the stream. PCHContainerRdr.ExtractPCH(New->Buffer->getMemBufferRef(), New->StreamFile); } if (ExpectedSignature) { if (NewModule) ModuleEntry->Signature = ReadSignature(ModuleEntry->StreamFile); else assert(ModuleEntry->Signature == ReadSignature(ModuleEntry->StreamFile)); if (ModuleEntry->Signature != ExpectedSignature) { ErrorStr = ModuleEntry->Signature ? "signature mismatch" : "could not read module signature"; if (NewModule) { // Remove the module file immediately, since removeModules might try to // invalidate the file cache for Entry, and that is not safe if this // module is *itself* up to date, but has an out-of-date importer. Modules.erase(Entry); assert(Chain.back() == ModuleEntry); Chain.pop_back(); if (Roots.back() == ModuleEntry) Roots.pop_back(); else assert(ImportedBy); delete ModuleEntry; } return OutOfDate; } } if (ImportedBy) { ModuleEntry->ImportedBy.insert(ImportedBy); ImportedBy->Imports.insert(ModuleEntry); } else { if (!ModuleEntry->DirectlyImported) ModuleEntry->ImportLoc = ImportLoc; ModuleEntry->DirectlyImported = true; } Module = ModuleEntry; return NewModule? NewlyLoaded : AlreadyLoaded; }