authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-10-13 17:55:36-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-10-13 17:55:36-04:00
logf7f3dedb1de405e0123c93a4a9e54503e02942ee
tree04f1cd498a30a4a3621c3b9d82f5ebeb44fd5f36
parentb164e0ae5599610e39804845331caab612010c13
parent60cf3f8a8c26ad4131c5842238cefe6b45a67d9f
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #3436 from LemonBoy/unpatch-lld

Assemble lib files using LLVM tools instead of lld

4 files changed, 95 insertions(+), 33 deletions(-)

deps/lld/COFF/DriverUtils.cpp+4-12
...@@ -638,18 +638,10 @@ void fixupExports() {...@@ -638,18 +638,10 @@ void fixupExports() {
638638
639 if (config->killAt && config->machine == I386) {639 if (config->killAt && config->machine == I386) {
640 for (Export &e : config->exports) {640 for (Export &e : config->exports) {
641 if (!e.name.empty() && e.name[0] == '?')641 e.name = killAt(e.name, true);
642 continue;642 e.exportName = killAt(e.exportName, false);
643 e.symbolName = e.name;643 e.extName = killAt(e.extName, true);
644 // Trim off the trailing decoration. Symbols will always have a644 e.symbolName = killAt(e.symbolName, true);
645 // starting prefix here (either _ for cdecl/stdcall, @ for fastcall
646 // or ? for C++ functions). Vectorcall functions won't have any
647 // fixed prefix, but the function base name will still be at least
648 // one char.
649 e.name = e.name.substr(0, e.name.find('@', 1));
650 // By making sure E.SymbolName != E.Name for decorated symbols,
651 // writeImportLibrary writes these symbols with the type
652 // IMPORT_NAME_UNDECORATE.
653 }645 }
654 }646 }
655647
src/link.cpp+6-21
...@@ -2054,27 +2054,12 @@ static const char *get_def_lib(CodeGen *parent, const char *name, Buf *def_in_fi...@@ -2054,27 +2054,12 @@ static const char *get_def_lib(CodeGen *parent, const char *name, Buf *def_in_fi
2054 lib_final_path = buf_alloc();2054 lib_final_path = buf_alloc();
2055 os_path_join(artifact_dir, final_lib_basename, lib_final_path);2055 os_path_join(artifact_dir, final_lib_basename, lib_final_path);
20562056
2057 args.resize(0);2057 if (ZigLLVMWriteImportLibrary(buf_ptr(def_final_path),
2058 args.append("link");2058 parent->zig_target->arch,
2059 coff_append_machine_arg(parent, &args);2059 buf_ptr(lib_final_path),
2060 args.append("-lldmingw");2060 /* kill_at */ true))
2061 args.append("-kill-at");2061 {
20622062 zig_panic("link: could not emit %s", buf_ptr(lib_final_path));
2063 args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_final_path))));
2064 args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(lib_final_path))));
2065
2066 if (parent->verbose_link) {
2067 for (size_t i = 0; i < args.length; i += 1) {
2068 fprintf(stderr, "%s ", args.at(i));
2069 }
2070 fprintf(stderr, "\n");
2071 }
2072
2073 Buf diag = BUF_INIT;
2074 ZigLLVM_ObjectFormatType target_ofmt = target_object_format(parent->zig_target);
2075 if (!zig_lld_link(target_ofmt, args.items, args.length, &diag)) {
2076 fprintf(stderr, "%s\n", buf_ptr(&diag));
2077 exit(1);
2078 }2063 }
2079 } else {2064 } else {
2080 // cache hit2065 // cache hit
src/zig_llvm.cpp+82
...@@ -34,6 +34,9 @@...@@ -34,6 +34,9 @@
34#include <llvm/MC/SubtargetFeature.h>34#include <llvm/MC/SubtargetFeature.h>
35#include <llvm/Object/Archive.h>35#include <llvm/Object/Archive.h>
36#include <llvm/Object/ArchiveWriter.h>36#include <llvm/Object/ArchiveWriter.h>
37#include <llvm/Object/COFF.h>
38#include <llvm/Object/COFFImportFile.h>
39#include <llvm/Object/COFFModuleDefinition.h>
37#include <llvm/PassRegistry.h>40#include <llvm/PassRegistry.h>
38#include <llvm/Support/FileSystem.h>41#include <llvm/Support/FileSystem.h>
39#include <llvm/Support/TargetParser.h>42#include <llvm/Support/TargetParser.h>
...@@ -938,6 +941,85 @@ class MyOStream: public raw_ostream {...@@ -938,6 +941,85 @@ class MyOStream: public raw_ostream {
938 size_t pos;941 size_t pos;
939};942};
940943
944bool ZigLLVMWriteImportLibrary(const char *def_path, const ZigLLVM_ArchType arch,
945 const char *output_lib_path, const bool kill_at)
946{
947 COFF::MachineTypes machine = COFF::IMAGE_FILE_MACHINE_UNKNOWN;
948
949 switch (arch) {
950 case ZigLLVM_x86:
951 machine = COFF::IMAGE_FILE_MACHINE_I386;
952 break;
953 case ZigLLVM_x86_64:
954 machine = COFF::IMAGE_FILE_MACHINE_AMD64;
955 break;
956 case ZigLLVM_arm:
957 case ZigLLVM_armeb:
958 case ZigLLVM_thumb:
959 case ZigLLVM_thumbeb:
960 machine = COFF::IMAGE_FILE_MACHINE_ARMNT;
961 break;
962 case ZigLLVM_aarch64:
963 case ZigLLVM_aarch64_be:
964 machine = COFF::IMAGE_FILE_MACHINE_ARM64;
965 break;
966 default:
967 break;
968 }
969
970 if (machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
971 return true;
972 }
973
974 auto bufOrErr = MemoryBuffer::getFile(def_path);
975 if (!bufOrErr) {
976 return false;
977 }
978
979 MemoryBuffer& buf = *bufOrErr.get();
980 Expected<object::COFFModuleDefinition> def =
981 object::parseCOFFModuleDefinition(buf, machine, /* MingwDef */ true);
982
983 if (!def) {
984 return true;
985 }
986
987 // The exports-juggling code below is ripped from LLVM's DllToolDriver.cpp
988
989 // If ExtName is set (if the "ExtName = Name" syntax was used), overwrite
990 // Name with ExtName and clear ExtName. When only creating an import
991 // library and not linking, the internal name is irrelevant. This avoids
992 // cases where writeImportLibrary tries to transplant decoration from
993 // symbol decoration onto ExtName.
994 for (object::COFFShortExport& E : def->Exports) {
995 if (!E.ExtName.empty()) {
996 E.Name = E.ExtName;
997 E.ExtName.clear();
998 }
999 }
1000
1001 if (machine == COFF::IMAGE_FILE_MACHINE_I386 && kill_at) {
1002 for (object::COFFShortExport& E : def->Exports) {
1003 if (!E.AliasTarget.empty() || (!E.Name.empty() && E.Name[0] == '?'))
1004 continue;
1005 E.SymbolName = E.Name;
1006 // Trim off the trailing decoration. Symbols will always have a
1007 // starting prefix here (either _ for cdecl/stdcall, @ for fastcall
1008 // or ? for C++ functions). Vectorcall functions won't have any
1009 // fixed prefix, but the function base name will still be at least
1010 // one char.
1011 E.Name = E.Name.substr(0, E.Name.find('@', 1));
1012 // By making sure E.SymbolName != E.Name for decorated symbols,
1013 // writeImportLibrary writes these symbols with the type
1014 // IMPORT_NAME_UNDECORATE.
1015 }
1016 }
1017
1018 return static_cast<bool>(
1019 object::writeImportLibrary(def->OutputFile, output_lib_path,
1020 def->Exports, machine, /* MinGW */ true));
1021}
1022
941bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count,1023bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count,
942 ZigLLVM_OSType os_type)1024 ZigLLVM_OSType os_type)
943{1025{
src/zig_llvm.h+3
...@@ -465,6 +465,9 @@ ZIG_EXTERN_C bool ZigLLDLink(enum ZigLLVM_ObjectFormatType oformat, const char *...@@ -465,6 +465,9 @@ ZIG_EXTERN_C bool ZigLLDLink(enum ZigLLVM_ObjectFormatType oformat, const char *
465ZIG_EXTERN_C bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count,465ZIG_EXTERN_C bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count,
466 enum ZigLLVM_OSType os_type);466 enum ZigLLVM_OSType os_type);
467467
468bool ZigLLVMWriteImportLibrary(const char *def_path, const ZigLLVM_ArchType arch,
469 const char *output_lib_path, const bool kill_at);
470
468ZIG_EXTERN_C void ZigLLVMGetNativeTarget(enum ZigLLVM_ArchType *arch_type, enum ZigLLVM_SubArchType *sub_arch_type,471ZIG_EXTERN_C void ZigLLVMGetNativeTarget(enum ZigLLVM_ArchType *arch_type, enum ZigLLVM_SubArchType *sub_arch_type,
469 enum ZigLLVM_VendorType *vendor_type, enum ZigLLVM_OSType *os_type, enum ZigLLVM_EnvironmentType *environ_type,472 enum ZigLLVM_VendorType *vendor_type, enum ZigLLVM_OSType *os_type, enum ZigLLVM_EnvironmentType *environ_type,
470 enum ZigLLVM_ObjectFormatType *oformat);473 enum ZigLLVM_ObjectFormatType *oformat);