Use the object crate rather than LLVM for extracting bitcode sections

This commit is contained in:
bjorn3 2025-07-25 09:42:18 +00:00
parent 27e2709f3e
commit fe2eeabe27
5 changed files with 10 additions and 66 deletions

View file

@ -12,7 +12,7 @@ codegen_llvm_from_llvm_optimization_diag = {$filename}:{$line}:{$column} {$pass_
codegen_llvm_load_bitcode = failed to load bitcode of module "{$name}"
codegen_llvm_load_bitcode_with_llvm_err = failed to load bitcode of module "{$name}": {$llvm_err}
codegen_llvm_lto_bitcode_from_rlib = failed to get bitcode from object file for LTO ({$llvm_err})
codegen_llvm_lto_bitcode_from_rlib = failed to get bitcode from object file for LTO ({$err})
codegen_llvm_mismatch_data_layout =
data-layout for target `{$rustc_target}`, `{$rustc_layout}`, differs from LLVM target's `{$llvm_target}` default layout, `{$llvm_layout}`

View file

@ -7,6 +7,7 @@ use std::sync::Arc;
use std::{io, iter, slice};
use object::read::archive::ArchiveFile;
use object::{Object, ObjectSection};
use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule, ThinShared};
use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput};
use rustc_codegen_ssa::traits::*;
@ -105,31 +106,15 @@ fn get_bitcode_slice_from_object_data<'a>(
// name" which in the public API for sections gets treated as part of the section name, but
// internally in MachOObjectFile.cpp gets treated separately.
let section_name = bitcode_section_name(cgcx).to_str().unwrap().trim_start_matches("__LLVM,");
let mut len = 0;
let data = unsafe {
llvm::LLVMRustGetSliceFromObjectDataByName(
obj.as_ptr(),
obj.len(),
section_name.as_ptr(),
section_name.len(),
&mut len,
)
};
if !data.is_null() {
assert!(len != 0);
let bc = unsafe { slice::from_raw_parts(data, len) };
// `bc` must be a sub-slice of `obj`.
assert!(obj.as_ptr() <= bc.as_ptr());
assert!(bc[bc.len()..bc.len()].as_ptr() <= obj[obj.len()..obj.len()].as_ptr());
let obj =
object::File::parse(obj).map_err(|err| LtoBitcodeFromRlib { err: err.to_string() })?;
Ok(bc)
} else {
assert!(len == 0);
Err(LtoBitcodeFromRlib {
llvm_err: llvm::last_error().unwrap_or_else(|| "unknown LLVM error".to_string()),
})
}
let section = obj
.section_by_name(section_name)
.ok_or_else(|| LtoBitcodeFromRlib { err: format!("Can't find section {section_name}") })?;
section.data().map_err(|err| LtoBitcodeFromRlib { err: err.to_string() })
}
/// Performs fat LTO by merging all modules into a single one and returning it

View file

@ -39,7 +39,7 @@ pub(crate) struct AutoDiffWithoutEnable;
#[derive(Diagnostic)]
#[diag(codegen_llvm_lto_bitcode_from_rlib)]
pub(crate) struct LtoBitcodeFromRlib {
pub llvm_err: String,
pub err: String,
}
#[derive(Diagnostic)]

View file

@ -2612,13 +2612,6 @@ unsafe extern "C" {
len: usize,
Identifier: *const c_char,
) -> Option<&Module>;
pub(crate) fn LLVMRustGetSliceFromObjectDataByName(
data: *const u8,
len: usize,
name: *const u8,
name_len: usize,
out_len: &mut usize,
) -> *const u8;
pub(crate) fn LLVMRustLinkerNew(M: &Module) -> &mut Linker<'_>;
pub(crate) fn LLVMRustLinkerAdd(

View file

@ -1650,40 +1650,6 @@ extern "C" LLVMModuleRef LLVMRustParseBitcodeForLTO(LLVMContextRef Context,
return wrap(std::move(*SrcOrError).release());
}
// 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 name_len,
size_t *out_len) {
*out_len = 0;
auto Name = StringRef(name, name_len);
auto Data = StringRef(data, len);
auto Buffer = MemoryBufferRef(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> SecName = Sec.getName();
if (SecName && *SecName == 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