diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a6ed6622f..70b4ae5170 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,11 @@ endif() add_executable(mold) target_compile_features(mold PRIVATE cxx_std_20) -target_link_libraries(mold PRIVATE ${CMAKE_DL_LIBS}) +if(MINGW) + target_link_libraries(mold PRIVATE dl) +else() + target_link_libraries(mold PRIVATE ${CMAKE_DL_LIBS}) +endif() if(NOT "${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "MSVC") target_compile_options(mold PRIVATE @@ -328,7 +332,7 @@ list(APPEND MOLD_ELF_TEMPLATE_FILES elf/tls.cc ) -if(WIN32) +if(WIN32 AND NOT(MINGW)) list(APPEND MOLD_ELF_TEMPLATE_FILES elf/lto-win32.cc) else() list(APPEND MOLD_ELF_TEMPLATE_FILES elf/lto-unix.cc) diff --git a/common/common.h b/common/common.h index d73f0356cc..1c9cf157e8 100644 --- a/common/common.h +++ b/common/common.h @@ -1001,6 +1001,32 @@ class MappedFile { return name; } + void close_fd() { +#ifdef WIN32 + if (fd != INVALID_HANDLE_VALUE) { + CloseHandle(fd); + fd = INVALID_HANDLE_VALUE; + } +#else + if (fd != -1) { + close(fd); + fd = -1; + } +#endif + } + + void reopen_fd(const char *path) { +#ifdef WIN32 + if (fd != INVALID_HANDLE_VALUE) + fd = CreateFileA(path, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); +#else + if (fd == -1) + fd = open(path, O_RDONLY); +#endif + } + std::string name; u8 *data = nullptr; i64 size = 0; diff --git a/elf/lto-unix.cc b/elf/lto-unix.cc index 4d0caae4ee..0c6ae1bb17 100644 --- a/elf/lto-unix.cc +++ b/elf/lto-unix.cc @@ -200,10 +200,7 @@ static PluginStatus release_input_file(const void *handle) { LOG << "release_input_file\n"; ObjectFile &file = *(ObjectFile *)handle; - if (file.mf->fd != -1) { - close(file.mf->fd); - file.mf->fd = -1; - } + file.mf->close_fd(); return LDPS_OK; } @@ -570,7 +567,11 @@ static ElfSym to_elf_sym(PluginSymbol &psym) { // Returns false if it's GCC. template static bool is_llvm(Context &ctx) { +#ifdef __MINGW32__ + return ctx.arg.plugin.ends_with("LLVMgold.dll"); +#else return ctx.arg.plugin.ends_with("LLVMgold.so"); +#endif } // Returns true if a given linker plugin supports the get_symbols_v3 API. @@ -590,11 +591,11 @@ create_plugin_input_file(Context &ctx, MappedFile *mf) { file.offset = mf->get_offset(); file.filesize = mf->size; - if (mf2->fd == -1) - mf2->fd = open(file.name, O_RDONLY); + mf2->reopen_fd(file.name); + file.fd = mf2->fd; - if (file.fd == -1) + if (!file.fd) Fatal(ctx) << "cannot open " << file.name << ": " << errno_string(); return file; } @@ -645,8 +646,7 @@ ObjectFile *read_lto_object(Context &ctx, MappedFile *mf) { // open files" issue, we close fd only for GCC. This is ugly, though. if (!is_llvm(ctx)) { MappedFile *mf2 = mf->parent ? mf->parent : mf; - close(mf2->fd); - mf2->fd = -1; + mf2->close_fd(); } // Create a symbol strtab diff --git a/elf/lto.h b/elf/lto.h index 489a06faeb..5f2225d268 100644 --- a/elf/lto.h +++ b/elf/lto.h @@ -73,7 +73,11 @@ enum PluginOutputFileType { struct PluginInputFile { const char *name; - i32 fd; +#if __MINGW32__ + HANDLE fd; +#else + int fd; +#endif u64 offset; u64 filesize; void *handle;