1
Fork 0

Use LLVM for getting symbols from COFF bigobj files

This commit is contained in:
bjorn3 2022-11-26 13:55:18 +00:00
parent be6708428f
commit 0673cde5a3
2 changed files with 33 additions and 11 deletions

View file

@ -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)] #[deny(unsafe_op_in_unsafe_fn)]
fn get_llvm_object_symbols( fn get_llvm_object_symbols(
buf: &[u8], buf: &[u8],
f: &mut dyn FnMut(&[u8]) -> io::Result<()>, f: &mut dyn FnMut(&[u8]) -> io::Result<()>,
) -> io::Result<bool> { ) -> 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 mut state = Box::new(f);
let err = unsafe { let err = unsafe {

View file

@ -49,19 +49,33 @@ extern "C" void *LLVMRustGetSymbols(
std::unique_ptr<object::SymbolicFile> Obj; std::unique_ptr<object::SymbolicFile> Obj;
const file_magic Type = identify_magic(Buf->getBuffer()); const file_magic Type = identify_magic(Buf->getBuffer());
if (Type != file_magic::bitcode) { if (!object::SymbolicFile::isSymbolicFile(Type, &Context)) {
return ErrorCallback("not bitcode"); return 0;
} }
auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
if (Type == file_magic::bitcode) {
auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
Buf->getMemBufferRef(), file_magic::bitcode, &Context); Buf->getMemBufferRef(), file_magic::bitcode, &Context);
if (!ObjOrErr) { if (!ObjOrErr) {
Error E = ObjOrErr.takeError(); Error E = ObjOrErr.takeError();
SmallString<0> ErrorBuf; SmallString<0> ErrorBuf;
raw_svector_ostream Error(ErrorBuf); raw_svector_ostream Error(ErrorBuf);
Error << E << '\0'; Error << E << '\0';
return ErrorCallback(Error.str().data()); 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()) { for (const object::BasicSymbolRef &S : Obj->symbols()) {
if (!isArchiveSymbol(S)) if (!isArchiveSymbol(S))