diff options
Diffstat (limited to 'compiler/rustc_llvm/llvm-wrapper')
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 6 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 15 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp | 96 |
3 files changed, 113 insertions, 4 deletions
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 18d37d95a83..7f4d63eed8b 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -627,7 +627,11 @@ LLVMRustOptimize( bool DebugPassManager = false; PassInstrumentationCallbacks PIC; +#if LLVM_VERSION_LT(16, 0) StandardInstrumentations SI(DebugPassManager); +#else + StandardInstrumentations SI(TheModule->getContext(), DebugPassManager); +#endif SI.registerCallbacks(PIC); if (LlvmSelfProfiler){ @@ -800,7 +804,7 @@ LLVMRustOptimize( auto Plugin = PassPlugin::Load(PluginPath.str()); if (!Plugin) { LLVMRustSetLastError(("Failed to load pass plugin" + PluginPath.str()).c_str()); - continue; + return LLVMRustResult::Failure; } Plugin->registerPassBuilderCallbacks(PB); } diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 0d9b5a57b69..792d921c6a4 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -9,7 +9,7 @@ #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/Mangler.h" #if LLVM_VERSION_GE(16, 0) -#include "llvm/IR/ModRef.h" +#include "llvm/Support/ModRef.h" #endif #include "llvm/Object/Archive.h" #include "llvm/Object/COFFImportFile.h" @@ -1036,8 +1036,9 @@ extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd( extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator( LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen, - int64_t Value, bool IsUnsigned) { - return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned)); + const uint64_t Value[2], unsigned SizeInBits, bool IsUnsigned) { + return wrap(Builder->createEnumerator(StringRef(Name, NameLen), + APSInt(APInt(SizeInBits, makeArrayRef(Value, 2)), IsUnsigned))); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType( @@ -1111,6 +1112,10 @@ extern "C" uint64_t LLVMRustDIBuilderCreateOpPlusUconst() { return dwarf::DW_OP_plus_uconst; } +extern "C" int64_t LLVMRustDIBuilderCreateOpLLVMFragment() { + return dwarf::DW_OP_LLVM_fragment; +} + extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) { RawRustStringOstream OS(Str); unwrap<llvm::Type>(Ty)->print(OS); @@ -1962,3 +1967,7 @@ extern "C" int32_t LLVMRustGetElementTypeArgIndex(LLVMValueRef CallSite) { #endif return -1; } + +extern "C" bool LLVMRustIsBitcode(char *ptr, size_t len) { + return identify_magic(StringRef(ptr, len)) == file_magic::bitcode; +} diff --git a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp new file mode 100644 index 00000000000..974207e918c --- /dev/null +++ b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp @@ -0,0 +1,96 @@ +// Derived from code in LLVM, which is: +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// Derived from: +// * https://github.com/llvm/llvm-project/blob/8ef3e895ad8ab1724e2b87cabad1dacdc7a397a3/llvm/include/llvm/Object/ArchiveWriter.h +// * https://github.com/llvm/llvm-project/blob/8ef3e895ad8ab1724e2b87cabad1dacdc7a397a3/llvm/lib/Object/ArchiveWriter.cpp + +#include "llvm/IR/LLVMContext.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/ADT/Optional.h" + +using namespace llvm; +using namespace llvm::sys; +using namespace llvm::object; + +static bool isArchiveSymbol(const object::BasicSymbolRef &S) { + Expected<uint32_t> SymFlagsOrErr = S.getFlags(); + if (!SymFlagsOrErr) + // FIXME: Actually report errors helpfully. + report_fatal_error(SymFlagsOrErr.takeError()); + if (*SymFlagsOrErr & object::SymbolRef::SF_FormatSpecific) + return false; + if (!(*SymFlagsOrErr & object::SymbolRef::SF_Global)) + return false; + if (*SymFlagsOrErr & object::SymbolRef::SF_Undefined) + return false; + return true; +} + +typedef void *(*LLVMRustGetSymbolsCallback)(void *, const char *); +typedef void *(*LLVMRustGetSymbolsErrorCallback)(const char *); + +// Note: This is implemented in C++ instead of using the C api from Rust as IRObjectFile doesn't +// implement getSymbolName, only printSymbolName, which is inaccessible from the C api. +extern "C" void *LLVMRustGetSymbols( + char *BufPtr, size_t BufLen, void *State, LLVMRustGetSymbolsCallback Callback, + LLVMRustGetSymbolsErrorCallback ErrorCallback) { + std::unique_ptr<MemoryBuffer> Buf = + MemoryBuffer::getMemBuffer(StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"), + false); + SmallString<0> SymNameBuf; + raw_svector_ostream SymName(SymNameBuf); + + // In the scenario when LLVMContext is populated SymbolicFile will contain a + // reference to it, thus SymbolicFile should be destroyed first. + LLVMContext Context; + std::unique_ptr<object::SymbolicFile> Obj; + + const file_magic Type = identify_magic(Buf->getBuffer()); + if (!object::SymbolicFile::isSymbolicFile(Type, &Context)) { + return 0; + } + + if (Type == file_magic::bitcode) { + auto ObjOrErr = object::SymbolicFile::createSymbolicFile( + Buf->getMemBufferRef(), file_magic::bitcode, &Context); + if (!ObjOrErr) { + Error E = ObjOrErr.takeError(); + SmallString<0> ErrorBuf; + raw_svector_ostream Error(ErrorBuf); + Error << E << '\0'; + return ErrorCallback(Error.str().data()); + } + Obj = std::move(*ObjOrErr); + } else { + auto ObjOrErr = object::SymbolicFile::createSymbolicFile(Buf->getMemBufferRef()); + if (!ObjOrErr) { + Error E = ObjOrErr.takeError(); + SmallString<0> ErrorBuf; + raw_svector_ostream Error(ErrorBuf); + Error << E << '\0'; + return ErrorCallback(Error.str().data()); + } + Obj = std::move(*ObjOrErr); + } + + + for (const object::BasicSymbolRef &S : Obj->symbols()) { + if (!isArchiveSymbol(S)) + continue; + if (Error E = S.printName(SymName)) { + SmallString<0> ErrorBuf; + raw_svector_ostream Error(ErrorBuf); + Error << E << '\0'; + return ErrorCallback(Error.str().data()); + } + SymName << '\0'; + if (void *E = Callback(State, SymNameBuf.str().data())) { + return E; + } + SymNameBuf.clear(); + } + return 0; +} |
