summary refs log tree commit diff
path: root/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-09-08 19:07:17 +0000
committerbors <bors@rust-lang.org>2023-09-08 19:07:17 +0000
commitffc48e3eda36e288f76b4022d72d94321887ebf5 (patch)
tree31ce78e4b25e750672074b2ef12d4cc1042d3852 /compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
parent26f4b7272428b181e0a88ad075e5c8f09dcb0e5c (diff)
parent0db66022b1e0f057362be1ca8593c3ff1fee1c85 (diff)
downloadrust-ffc48e3eda36e288f76b4022d72d94321887ebf5.tar.gz
rust-ffc48e3eda36e288f76b4022d72d94321887ebf5.zip
Auto merge of #115641 - durin42:llvm-18-fatlto-take-2, r=nikic
lto: load bitcode sections by name

Upstream change
llvm/llvm-project@6b539f5eb8ef1d3a3c87873caa2dbd5147e1adbd changed `isSectionBitcode` works and it now only respects `.llvm.lto` sections instead of also `.llvmbc`, which it says was never intended to be used for LTO. We instead load sections by name, and sniff for raw bitcode by hand.

This is an alternative approach to #115136, where we tried the same thing using the `object` crate, but it got too fraught to continue.

r? `@nikic`
`@rustbot` label: +llvm-main
Diffstat (limited to 'compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp')
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 5ecf3aec65d..09627e1cfed 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>
@@ -1558,6 +1559,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