Merge pull request #3436 from LemonBoy/unpatch-lld

Assemble lib files using LLVM tools instead of lld
master
Andrew Kelley 2019-10-13 17:55:36 -04:00 committed by GitHub
commit f7f3dedb1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 95 additions and 33 deletions

View File

@ -638,18 +638,10 @@ void fixupExports() {
if (config->killAt && config->machine == I386) {
for (Export &e : config->exports) {
if (!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.
e.name = killAt(e.name, true);
e.exportName = killAt(e.exportName, false);
e.extName = killAt(e.extName, true);
e.symbolName = killAt(e.symbolName, true);
}
}

View File

@ -2054,27 +2054,12 @@ static const char *get_def_lib(CodeGen *parent, const char *name, Buf *def_in_fi
lib_final_path = buf_alloc();
os_path_join(artifact_dir, final_lib_basename, lib_final_path);
args.resize(0);
args.append("link");
coff_append_machine_arg(parent, &args);
args.append("-lldmingw");
args.append("-kill-at");
args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_final_path))));
args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(lib_final_path))));
if (parent->verbose_link) {
for (size_t i = 0; i < args.length; i += 1) {
fprintf(stderr, "%s ", args.at(i));
}
fprintf(stderr, "\n");
}
Buf diag = BUF_INIT;
ZigLLVM_ObjectFormatType target_ofmt = target_object_format(parent->zig_target);
if (!zig_lld_link(target_ofmt, args.items, args.length, &diag)) {
fprintf(stderr, "%s\n", buf_ptr(&diag));
exit(1);
if (ZigLLVMWriteImportLibrary(buf_ptr(def_final_path),
parent->zig_target->arch,
buf_ptr(lib_final_path),
/* kill_at */ true))
{
zig_panic("link: could not emit %s", buf_ptr(lib_final_path));
}
} else {
// cache hit

View File

@ -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)
{

View File

@ -465,6 +465,9 @@ ZIG_EXTERN_C bool ZigLLDLink(enum ZigLLVM_ObjectFormatType oformat, const char *
ZIG_EXTERN_C bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count,
enum ZigLLVM_OSType os_type);
bool ZigLLVMWriteImportLibrary(const char *def_path, const ZigLLVM_ArchType arch,
const char *output_lib_path, const bool kill_at);
ZIG_EXTERN_C void ZigLLVMGetNativeTarget(enum ZigLLVM_ArchType *arch_type, enum ZigLLVM_SubArchType *sub_arch_type,
enum ZigLLVM_VendorType *vendor_type, enum ZigLLVM_OSType *os_type, enum ZigLLVM_EnvironmentType *environ_type,
enum ZigLLVM_ObjectFormatType *oformat);