about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-11-26 13:55:18 +0000
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-11-26 19:35:32 +0000
commit0673cde5a36db203f18941c125a1665184e056ed (patch)
tree5cf3b1c28273fcdbafd37e4620bfc5d7a1754207 /compiler
parentbe6708428fdf6693188e2c2f10f05d1b1aaa5750 (diff)
downloadrust-0673cde5a36db203f18941c125a1665184e056ed.tar.gz
rust-0673cde5a36db203f18941c125a1665184e056ed.zip
Use LLVM for getting symbols from COFF bigobj files
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs10
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp34
2 files changed, 33 insertions, 11 deletions
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index dba35273485..0aee1a1439b 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -261,12 +261,20 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
     }
 }
 
+// The object crate doesn't know how to get symbols for LLVM bitcode and COFF bigobj files.
+// As such we need to use LLVM for them.
 #[deny(unsafe_op_in_unsafe_fn)]
 fn get_llvm_object_symbols(
     buf: &[u8],
     f: &mut dyn FnMut(&[u8]) -> io::Result<()>,
 ) -> io::Result<bool> {
-    if unsafe { llvm::LLVMRustIsBitcode(buf.as_ptr(), buf.len()) } {
+    let is_bitcode = unsafe { llvm::LLVMRustIsBitcode(buf.as_ptr(), buf.len()) };
+
+    // COFF bigobj file, msvc LTO file or import library. See
+    // https://github.com/llvm/llvm-project/blob/453f27bc9/llvm/lib/BinaryFormat/Magic.cpp#L38-L51
+    let is_unsupported_windows_obj_file = buf.get(0..4) == Some(b"\0\0\xFF\xFF");
+
+    if is_bitcode || is_unsupported_windows_obj_file {
         let mut state = Box::new(f);
 
         let err = unsafe {
diff --git a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
index 054f5f62a30..974207e918c 100644
--- a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
@@ -49,19 +49,33 @@ extern "C" void *LLVMRustGetSymbols(
   std::unique_ptr<object::SymbolicFile> Obj;
 
   const file_magic Type = identify_magic(Buf->getBuffer());
-  if (Type != file_magic::bitcode) {
-    return ErrorCallback("not bitcode");
+  if (!object::SymbolicFile::isSymbolicFile(Type, &Context)) {
+    return 0;
   }
-  auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
+
+  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());
+    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);
   }
-  Obj = std::move(*ObjOrErr);
+
 
   for (const object::BasicSymbolRef &S : Obj->symbols()) {
     if (!isArchiveSymbol(S))