Document some safety constraints and use more safe wrappers

This commit is contained in:
Oli Scherer 2025-01-14 12:25:16 +00:00
parent 4b83038d63
commit dcf1e4d72b
11 changed files with 50 additions and 59 deletions

View file

@ -81,13 +81,13 @@ pub(crate) unsafe fn codegen(
llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility()));
let val = tcx.sess.opts.unstable_opts.oom.should_panic();
let llval = llvm::LLVMConstInt(i8, val as u64, False);
llvm::LLVMSetInitializer(ll_g, llval);
llvm::set_initializer(ll_g, llval);
let name = NO_ALLOC_SHIM_IS_UNSTABLE;
let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_c_char_ptr(), name.len(), i8);
llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility()));
let llval = llvm::LLVMConstInt(i8, 0, False);
llvm::LLVMSetInitializer(ll_g, llval);
llvm::set_initializer(ll_g, llval);
}
if tcx.sess.opts.debuginfo != DebugInfo::None {

View file

@ -11,7 +11,7 @@ use rustc_codegen_ssa::back::archive::{
use rustc_session::Session;
use crate::llvm::archive_ro::{ArchiveRO, Child};
use crate::llvm::{self, ArchiveKind};
use crate::llvm::{self, ArchiveKind, last_error};
/// Helper for adding many files to an archive.
#[must_use = "must call build() to finish building the archive"]
@ -169,6 +169,8 @@ impl<'a> LlvmArchiveBuilder<'a> {
.unwrap_or_else(|kind| self.sess.dcx().emit_fatal(UnknownArchiveKind { kind }));
let mut additions = mem::take(&mut self.additions);
// Values in the `members` list below will contain pointers to the strings allocated here.
// So they need to get dropped after all elements of `members` get freed.
let mut strings = Vec::new();
let mut members = Vec::new();
@ -229,12 +231,7 @@ impl<'a> LlvmArchiveBuilder<'a> {
self.sess.target.arch == "arm64ec",
);
let ret = if r.into_result().is_err() {
let err = llvm::LLVMRustGetLastError();
let msg = if err.is_null() {
"failed to write archive".into()
} else {
String::from_utf8_lossy(CStr::from_ptr(err).to_bytes())
};
let msg = last_error().unwrap_or_else(|| "failed to write archive".into());
Err(io::Error::new(io::ErrorKind::Other, msg))
} else {
Ok(!members.is_empty())

View file

@ -1049,24 +1049,18 @@ unsafe fn embed_bitcode(
{
// We don't need custom section flags, create LLVM globals.
let llconst = common::bytes_in_context(llcx, bitcode);
let llglobal = llvm::LLVMAddGlobal(
llmod,
common::val_ty(llconst),
c"rustc.embedded.module".as_ptr(),
);
llvm::LLVMSetInitializer(llglobal, llconst);
let llglobal =
llvm::add_global(llmod, common::val_ty(llconst), c"rustc.embedded.module");
llvm::set_initializer(llglobal, llconst);
llvm::set_section(llglobal, bitcode_section_name(cgcx));
llvm::set_linkage(llglobal, llvm::Linkage::PrivateLinkage);
llvm::LLVMSetGlobalConstant(llglobal, llvm::True);
let llconst = common::bytes_in_context(llcx, cmdline.as_bytes());
let llglobal = llvm::LLVMAddGlobal(
llmod,
common::val_ty(llconst),
c"rustc.embedded.cmdline".as_ptr(),
);
llvm::LLVMSetInitializer(llglobal, llconst);
let llglobal =
llvm::add_global(llmod, common::val_ty(llconst), c"rustc.embedded.cmdline");
llvm::set_initializer(llglobal, llconst);
let section = if cgcx.target_is_like_osx {
c"__LLVM,__cmdline"
} else if cgcx.target_is_like_aix {
@ -1106,31 +1100,29 @@ fn create_msvc_imps(
// underscores added in front).
let prefix = if cgcx.target_arch == "x86" { "\x01__imp__" } else { "\x01__imp_" };
unsafe {
let ptr_ty = Type::ptr_llcx(llcx);
let globals = base::iter_globals(llmod)
.filter(|&val| {
llvm::get_linkage(val) == llvm::Linkage::ExternalLinkage
&& llvm::LLVMIsDeclaration(val) == 0
})
.filter_map(|val| {
// Exclude some symbols that we know are not Rust symbols.
let name = llvm::get_value_name(val);
if ignored(name) { None } else { Some((val, name)) }
})
.map(move |(val, name)| {
let mut imp_name = prefix.as_bytes().to_vec();
imp_name.extend(name);
let imp_name = CString::new(imp_name).unwrap();
(imp_name, val)
})
.collect::<Vec<_>>();
let ptr_ty = Type::ptr_llcx(llcx);
let globals = base::iter_globals(llmod)
.filter(|&val| {
llvm::get_linkage(val) == llvm::Linkage::ExternalLinkage && !llvm::is_declaration(val)
})
.filter_map(|val| {
// Exclude some symbols that we know are not Rust symbols.
let name = llvm::get_value_name(val);
if ignored(name) { None } else { Some((val, name)) }
})
.map(move |(val, name)| {
let mut imp_name = prefix.as_bytes().to_vec();
imp_name.extend(name);
let imp_name = CString::new(imp_name).unwrap();
(imp_name, val)
})
.collect::<Vec<_>>();
for (imp_name, val) in globals {
let imp = llvm::LLVMAddGlobal(llmod, ptr_ty, imp_name.as_ptr());
llvm::LLVMSetInitializer(imp, val);
llvm::set_linkage(imp, llvm::Linkage::ExternalLinkage);
}
for (imp_name, val) in globals {
let imp = llvm::add_global(llmod, ptr_ty, &imp_name);
llvm::set_initializer(imp, val);
llvm::set_linkage(imp, llvm::Linkage::ExternalLinkage);
}
// Use this function to exclude certain symbols from `__imp` generation.

View file

@ -219,8 +219,8 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
let g = self.define_global(&sym, self.val_ty(sc)).unwrap_or_else(|| {
bug!("symbol `{}` is already defined", sym);
});
llvm::set_initializer(g, sc);
unsafe {
llvm::LLVMSetInitializer(g, sc);
llvm::LLVMSetGlobalConstant(g, True);
llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global);
}

View file

@ -191,7 +191,7 @@ fn check_and_apply_linkage<'ll, 'tcx>(
})
});
llvm::set_linkage(g2, llvm::Linkage::InternalLinkage);
unsafe { llvm::LLVMSetInitializer(g2, g1) };
llvm::set_initializer(g2, g1);
g2
} else if cx.tcx.sess.target.arch == "x86"
&& common::is_mingw_gnu_toolchain(&cx.tcx.sess.target)
@ -235,7 +235,7 @@ impl<'ll> CodegenCx<'ll, '_> {
}
_ => self.define_private_global(self.val_ty(cv)),
};
unsafe { llvm::LLVMSetInitializer(gv, cv) };
llvm::set_initializer(gv, cv);
set_global_alignment(self, gv, align);
llvm::SetUnnamedAddress(gv, llvm::UnnamedAddr::Global);
gv
@ -458,7 +458,7 @@ impl<'ll> CodegenCx<'ll, '_> {
new_g
};
set_global_alignment(self, g, alloc.align);
llvm::LLVMSetInitializer(g, v);
llvm::set_initializer(g, v);
if self.should_assume_dso_local(g, true) {
llvm::LLVMRustSetDSOLocal(g, true);

View file

@ -616,12 +616,10 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
pub(crate) fn create_used_variable_impl(&self, name: &'static CStr, values: &[&'ll Value]) {
let array = self.const_array(self.type_ptr(), values);
unsafe {
let g = llvm::LLVMAddGlobal(self.llmod, self.val_ty(array), name.as_ptr());
llvm::LLVMSetInitializer(g, array);
llvm::set_linkage(g, llvm::Linkage::AppendingLinkage);
llvm::set_section(g, c"llvm.metadata");
}
let g = llvm::add_global(self.llmod, self.val_ty(array), name);
llvm::set_initializer(g, array);
llvm::set_linkage(g, llvm::Linkage::AppendingLinkage);
llvm::set_section(g, c"llvm.metadata");
}
}
impl<'ll> SimpleCx<'ll> {

View file

@ -73,7 +73,7 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
.define_global(section_var_name, llvm_type)
.unwrap_or_else(|| bug!("symbol `{}` is already defined", section_var_name));
llvm::set_section(section_var, c".debug_gdb_scripts");
llvm::LLVMSetInitializer(section_var, cx.const_bytes(section_contents));
llvm::set_initializer(section_var, cx.const_bytes(section_contents));
llvm::LLVMSetGlobalConstant(section_var, llvm::True);
llvm::LLVMSetUnnamedAddress(section_var, llvm::UnnamedAddr::Global);
llvm::set_linkage(section_var, llvm::Linkage::LinkOnceODRLinkage);

View file

@ -235,7 +235,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
/// name.
pub(crate) fn get_defined_value(&self, name: &str) -> Option<&'ll Value> {
self.get_declared_value(name).and_then(|val| {
let declaration = unsafe { llvm::LLVMIsDeclaration(val) != 0 };
let declaration = llvm::is_declaration(val);
if !declaration { Some(val) } else { None }
})
}

View file

@ -824,7 +824,7 @@ fn codegen_msvc_try<'ll>(
if bx.cx.tcx.sess.target.supports_comdat() {
llvm::SetUniqueComdat(bx.llmod, tydesc);
}
unsafe { llvm::LLVMSetInitializer(tydesc, type_info) };
llvm::set_initializer(tydesc, type_info);
// The flag value of 8 indicates that we are catching the exception by
// reference instead of by value. We can't use catch by value because

View file

@ -2359,7 +2359,7 @@ unsafe extern "C" {
);
pub fn LLVMRustWriteOutputFile<'a>(
T: &'a TargetMachine,
PM: &PassManager<'a>,
PM: *mut PassManager<'a>,
M: &'a Module,
Output: *const c_char,
DwoOutput: *const c_char,

View file

@ -241,6 +241,10 @@ pub fn set_linkage(llglobal: &Value, linkage: Linkage) {
}
}
pub fn is_declaration(llglobal: &Value) -> bool {
unsafe { LLVMIsDeclaration(llglobal) == ffi::True }
}
pub fn get_visibility(llglobal: &Value) -> Visibility {
unsafe { LLVMGetVisibility(llglobal) }.to_rust()
}