summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_llvm
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_llvm')
-rw-r--r--compiler/rustc_llvm/build.rs5
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp5
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp129
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp16
4 files changed, 146 insertions, 9 deletions
diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs
index 4302b1618..f606fa483 100644
--- a/compiler/rustc_llvm/build.rs
+++ b/compiler/rustc_llvm/build.rs
@@ -252,7 +252,10 @@ fn main() {
} else if target.contains("windows-gnu") {
println!("cargo:rustc-link-lib=shell32");
println!("cargo:rustc-link-lib=uuid");
- } else if target.contains("haiku") || target.contains("darwin") {
+ } else if target.contains("haiku")
+ || target.contains("darwin")
+ || (is_crossed && (target.contains("dragonfly") || target.contains("solaris")))
+ {
println!("cargo:rustc-link-lib=z");
} else if target.contains("netbsd") {
println!("cargo:rustc-link-lib=z");
diff --git a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
index 35d6b9ed7..54fdc84c7 100644
--- a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
@@ -203,7 +203,12 @@ LLVMRustWriteArchive(char *Dst, size_t NumMembers,
}
}
+#if LLVM_VERSION_LT(18, 0)
auto Result = writeArchive(Dst, Members, WriteSymbtab, Kind, true, false);
+#else
+ auto SymtabMode = WriteSymbtab ? SymtabWritingMode::NormalSymtab : SymtabWritingMode::NoSymtab;
+ auto Result = writeArchive(Dst, Members, SymtabMode, Kind, true, false);
+#endif
if (!Result)
return LLVMRustResult::Success;
LLVMRustSetLastError(toString(std::move(Result)).c_str());
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index b566ea496..b729c4022 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -1,5 +1,6 @@
#include <stdio.h>
+#include <cstddef>
#include <iomanip>
#include <vector>
#include <set>
@@ -9,6 +10,7 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
@@ -50,6 +52,8 @@
using namespace llvm;
+static codegen::RegisterCodeGenFlags CGF;
+
typedef struct LLVMOpaquePass *LLVMPassRef;
typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
@@ -235,16 +239,22 @@ enum class LLVMRustCodeGenOptLevel {
Aggressive,
};
-static CodeGenOpt::Level fromRust(LLVMRustCodeGenOptLevel Level) {
+#if LLVM_VERSION_GE(18, 0)
+ using CodeGenOptLevelEnum = llvm::CodeGenOptLevel;
+#else
+ using CodeGenOptLevelEnum = llvm::CodeGenOpt::Level;
+#endif
+
+static CodeGenOptLevelEnum fromRust(LLVMRustCodeGenOptLevel Level) {
switch (Level) {
case LLVMRustCodeGenOptLevel::None:
- return CodeGenOpt::None;
+ return CodeGenOptLevelEnum::None;
case LLVMRustCodeGenOptLevel::Less:
- return CodeGenOpt::Less;
+ return CodeGenOptLevelEnum::Less;
case LLVMRustCodeGenOptLevel::Default:
- return CodeGenOpt::Default;
+ return CodeGenOptLevelEnum::Default;
case LLVMRustCodeGenOptLevel::Aggressive:
- return CodeGenOpt::Aggressive;
+ return CodeGenOptLevelEnum::Aggressive;
default:
report_fatal_error("Bad CodeGenOptLevel.");
}
@@ -321,13 +331,13 @@ extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM,
PrintBackendInfo Print,
void* Out) {
const TargetMachine *Target = unwrap(TM);
- const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
const Triple::ArchType HostArch = Triple(sys::getDefaultTargetTriple()).getArch();
const Triple::ArchType TargetArch = Target->getTargetTriple().getArch();
std::ostringstream Buf;
#if LLVM_VERSION_GE(17, 0)
+ const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getAllProcessorDescriptions();
#else
Buf << "Full target CPU help is not supported by this LLVM version.\n\n";
@@ -406,7 +416,10 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
bool RelaxELFRelocations,
bool UseInitArray,
const char *SplitDwarfFile,
- bool ForceEmulatedTls) {
+ const char *OutputObjFile,
+ const char *DebugInfoCompression,
+ bool ForceEmulatedTls,
+ const char *ArgsCstrBuff, size_t ArgsCstrBuffLen) {
auto OptLevel = fromRust(RustOptLevel);
auto RM = fromRust(RustReloc);
@@ -421,7 +434,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
return nullptr;
}
- TargetOptions Options;
+ TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Trip);
Options.FloatABIType = FloatABI::Default;
if (UseSoftFloat) {
@@ -436,6 +449,19 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
if (SplitDwarfFile) {
Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
}
+ if (OutputObjFile) {
+ Options.ObjectFilenameForDebug = OutputObjFile;
+ }
+#if LLVM_VERSION_GE(16, 0)
+ if (!strcmp("zlib", DebugInfoCompression) && llvm::compression::zlib::isAvailable()) {
+ Options.CompressDebugSections = DebugCompressionType::Zlib;
+ } else if (!strcmp("zstd", DebugInfoCompression) && llvm::compression::zstd::isAvailable()) {
+ Options.CompressDebugSections = DebugCompressionType::Zstd;
+ } else if (!strcmp("none", DebugInfoCompression)) {
+ Options.CompressDebugSections = DebugCompressionType::None;
+ }
+#endif
+
Options.RelaxELFRelocations = RelaxELFRelocations;
Options.UseInitArray = UseInitArray;
@@ -462,12 +488,48 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
Options.EmitStackSizeSection = EmitStackSizeSection;
+
+ if (ArgsCstrBuff != nullptr)
+ {
+ int buffer_offset = 0;
+ assert(ArgsCstrBuff[ArgsCstrBuffLen - 1] == '\0');
+
+ const size_t arg0_len = std::strlen(ArgsCstrBuff);
+ char* arg0 = new char[arg0_len + 1];
+ memcpy(arg0, ArgsCstrBuff, arg0_len);
+ arg0[arg0_len] = '\0';
+ buffer_offset += arg0_len + 1;
+
+ const int num_cmd_arg_strings =
+ std::count(&ArgsCstrBuff[buffer_offset], &ArgsCstrBuff[ArgsCstrBuffLen], '\0');
+
+ std::string* cmd_arg_strings = new std::string[num_cmd_arg_strings];
+ for (int i = 0; i < num_cmd_arg_strings; ++i)
+ {
+ assert(buffer_offset < ArgsCstrBuffLen);
+ const int len = std::strlen(ArgsCstrBuff + buffer_offset);
+ cmd_arg_strings[i] = std::string(&ArgsCstrBuff[buffer_offset], len);
+ buffer_offset += len + 1;
+ }
+
+ assert(buffer_offset == ArgsCstrBuffLen);
+
+ Options.MCOptions.Argv0 = arg0;
+ Options.MCOptions.CommandLineArgs =
+ llvm::ArrayRef<std::string>(cmd_arg_strings, num_cmd_arg_strings);
+ }
+
TargetMachine *TM = TheTarget->createTargetMachine(
Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel);
return wrap(TM);
}
extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
+
+ MCTargetOptions& MCOptions = unwrap(TM)->Options.MCOptions;
+ delete[] MCOptions.Argv0;
+ delete[] MCOptions.CommandLineArgs.data();
+
delete unwrap(TM);
}
@@ -502,9 +564,17 @@ enum class LLVMRustFileType {
static CodeGenFileType fromRust(LLVMRustFileType Type) {
switch (Type) {
case LLVMRustFileType::AssemblyFile:
+#if LLVM_VERSION_GE(18, 0)
+ return CodeGenFileType::AssemblyFile;
+#else
return CGFT_AssemblyFile;
+#endif
case LLVMRustFileType::ObjectFile:
+#if LLVM_VERSION_GE(18, 0)
+ return CodeGenFileType::ObjectFile;
+#else
return CGFT_ObjectFile;
+#endif
default:
report_fatal_error("Bad FileType.");
}
@@ -1058,6 +1128,13 @@ extern "C" void LLVMRustPrintPasses() {
extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
size_t Len) {
auto PreserveFunctions = [=](const GlobalValue &GV) {
+ // Preserve LLVM-injected, ASAN-related symbols.
+ // See also https://github.com/rust-lang/rust/issues/113404.
+ if (GV.getName() == "___asan_globals_registered") {
+ return true;
+ }
+
+ // Preserve symbols exported from Rust modules.
for (size_t I = 0; I < Len; I++) {
if (GV.getName() == Symbols[I]) {
return true;
@@ -1202,7 +1279,11 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
Ret->ModuleMap[module->identifier] = mem_buffer;
+#if LLVM_VERSION_GE(18, 0)
+ if (Error Err = readModuleSummaryIndex(mem_buffer, Ret->Index)) {
+#else
if (Error Err = readModuleSummaryIndex(mem_buffer, Ret->Index, i)) {
+#endif
LLVMRustSetLastError(toString(std::move(Err)).c_str());
return nullptr;
}
@@ -1507,6 +1588,38 @@ LLVMRustGetBitcodeSliceFromObjectData(const char *data,
return BitcodeOrError->getBufferStart();
}
+// Find a section of an object file by name. Fail if the section is missing or
+// empty.
+extern "C" const char *LLVMRustGetSliceFromObjectDataByName(const char *data,
+ size_t len,
+ const char *name,
+ size_t *out_len) {
+ *out_len = 0;
+ StringRef Data(data, len);
+ MemoryBufferRef Buffer(Data, ""); // The id is unused.
+ file_magic Type = identify_magic(Buffer.getBuffer());
+ Expected<std::unique_ptr<object::ObjectFile>> ObjFileOrError =
+ object::ObjectFile::createObjectFile(Buffer, Type);
+ if (!ObjFileOrError) {
+ LLVMRustSetLastError(toString(ObjFileOrError.takeError()).c_str());
+ return nullptr;
+ }
+ for (const object::SectionRef &Sec : (*ObjFileOrError)->sections()) {
+ Expected<StringRef> Name = Sec.getName();
+ if (Name && *Name == name) {
+ Expected<StringRef> SectionOrError = Sec.getContents();
+ if (!SectionOrError) {
+ LLVMRustSetLastError(toString(SectionOrError.takeError()).c_str());
+ return nullptr;
+ }
+ *out_len = SectionOrError->size();
+ return SectionOrError->data();
+ }
+ }
+ LLVMRustSetLastError("could not find requested section");
+ return nullptr;
+}
+
// Computes the LTO cache key for the provided 'ModId' in the given 'Data',
// storing the result in 'KeyOut'.
// Currently, this cache key is a SHA-1 hash of anything that could affect
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 70cdf3d6d..4390486b0 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -2044,3 +2044,19 @@ extern "C" bool LLVMRustIsNonGVFunctionPointerTy(LLVMValueRef V) {
}
return false;
}
+
+extern "C" bool LLVMRustLLVMHasZlibCompressionForDebugSymbols() {
+#if LLVM_VERSION_GE(16, 0)
+ return llvm::compression::zlib::isAvailable();
+#else
+ return false;
+#endif
+}
+
+extern "C" bool LLVMRustLLVMHasZstdCompressionForDebugSymbols() {
+#if LLVM_VERSION_GE(16, 0)
+ return llvm::compression::zstd::isAvailable();
+#else
+ return false;
+#endif
+}