diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-10-13 17:55:36 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-10-13 17:55:36 -0400 |
| commit | f7f3dedb1de405e0123c93a4a9e54503e02942ee (patch) | |
| tree | 04f1cd498a30a4a3621c3b9d82f5ebeb44fd5f36 /src/zig_llvm.cpp | |
| parent | b164e0ae5599610e39804845331caab612010c13 (diff) | |
| parent | 60cf3f8a8c26ad4131c5842238cefe6b45a67d9f (diff) | |
| download | zig-f7f3dedb1de405e0123c93a4a9e54503e02942ee.tar.gz zig-f7f3dedb1de405e0123c93a4a9e54503e02942ee.zip | |
Merge pull request #3436 from LemonBoy/unpatch-lld
Assemble lib files using LLVM tools instead of lld
Diffstat (limited to 'src/zig_llvm.cpp')
| -rw-r--r-- | src/zig_llvm.cpp | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 8166173051..ac17e6edfe 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -34,6 +34,9 @@ #include <llvm/MC/SubtargetFeature.h> #include <llvm/Object/Archive.h> #include <llvm/Object/ArchiveWriter.h> +#include <llvm/Object/COFF.h> +#include <llvm/Object/COFFImportFile.h> +#include <llvm/Object/COFFModuleDefinition.h> #include <llvm/PassRegistry.h> #include <llvm/Support/FileSystem.h> #include <llvm/Support/TargetParser.h> @@ -938,6 +941,85 @@ class MyOStream: public raw_ostream { size_t pos; }; +bool ZigLLVMWriteImportLibrary(const char *def_path, const ZigLLVM_ArchType arch, + const char *output_lib_path, const bool kill_at) +{ + COFF::MachineTypes machine = COFF::IMAGE_FILE_MACHINE_UNKNOWN; + + switch (arch) { + case ZigLLVM_x86: + machine = COFF::IMAGE_FILE_MACHINE_I386; + break; + case ZigLLVM_x86_64: + machine = COFF::IMAGE_FILE_MACHINE_AMD64; + break; + case ZigLLVM_arm: + case ZigLLVM_armeb: + case ZigLLVM_thumb: + case ZigLLVM_thumbeb: + machine = COFF::IMAGE_FILE_MACHINE_ARMNT; + break; + case ZigLLVM_aarch64: + case ZigLLVM_aarch64_be: + machine = COFF::IMAGE_FILE_MACHINE_ARM64; + break; + default: + break; + } + + if (machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN) { + return true; + } + + auto bufOrErr = MemoryBuffer::getFile(def_path); + if (!bufOrErr) { + return false; + } + + MemoryBuffer& buf = *bufOrErr.get(); + Expected<object::COFFModuleDefinition> def = + object::parseCOFFModuleDefinition(buf, machine, /* MingwDef */ true); + + if (!def) { + return true; + } + + // The exports-juggling code below is ripped from LLVM's DllToolDriver.cpp + + // If ExtName is set (if the "ExtName = Name" syntax was used), overwrite + // Name with ExtName and clear ExtName. When only creating an import + // library and not linking, the internal name is irrelevant. This avoids + // cases where writeImportLibrary tries to transplant decoration from + // symbol decoration onto ExtName. + for (object::COFFShortExport& E : def->Exports) { + if (!E.ExtName.empty()) { + E.Name = E.ExtName; + E.ExtName.clear(); + } + } + + if (machine == COFF::IMAGE_FILE_MACHINE_I386 && kill_at) { + for (object::COFFShortExport& E : def->Exports) { + if (!E.AliasTarget.empty() || (!E.Name.empty() && E.Name[0] == '?')) + continue; + E.SymbolName = E.Name; + // Trim off the trailing decoration. Symbols will always have a + // starting prefix here (either _ for cdecl/stdcall, @ for fastcall + // or ? for C++ functions). Vectorcall functions won't have any + // fixed prefix, but the function base name will still be at least + // one char. + E.Name = E.Name.substr(0, E.Name.find('@', 1)); + // By making sure E.SymbolName != E.Name for decorated symbols, + // writeImportLibrary writes these symbols with the type + // IMPORT_NAME_UNDECORATE. + } + } + + return static_cast<bool>( + object::writeImportLibrary(def->OutputFile, output_lib_path, + def->Exports, machine, /* MinGW */ true)); +} + bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count, ZigLLVM_OSType os_type) { |
