| author | |
| committer | |
| log | f7f3dedb1de405e0123c93a4a9e54503e02942ee |
| tree | 04f1cd498a30a4a3621c3b9d82f5ebeb44fd5f36 |
| parent | b164e0ae5599610e39804845331caab612010c13 |
| parent | 60cf3f8a8c26ad4131c5842238cefe6b45a67d9f |
| signature |
Assemble lib files using LLVM tools instead of lld4 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() { |
| 638 | 638 | ||
| 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 a | 644 | 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 | } |
| 655 | 647 |
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); |
| 2056 | 2056 | ||
| 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 | { |
| 2062 | 2062 | 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 hit | 2065 | // 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 | }; |
| 940 | 943 | ||
| 944 | bool 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 | |||
| 941 | bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count, | 1023 | bool 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 * |
| 465 | ZIG_EXTERN_C bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count, | 465 | ZIG_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); |
| 467 | 467 | ||
| 468 | bool ZigLLVMWriteImportLibrary(const char *def_path, const ZigLLVM_ArchType arch, | ||
| 469 | const char *output_lib_path, const bool kill_at); | ||
| 470 | |||
| 468 | ZIG_EXTERN_C void ZigLLVMGetNativeTarget(enum ZigLLVM_ArchType *arch_type, enum ZigLLVM_SubArchType *sub_arch_type, | 471 | ZIG_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); |