Skip to content

Preparations for exception handling support #1575

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 3 additions & 11 deletions src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
);
}
TerminatorKind::UnwindTerminate(reason) => {
codegen_unwind_terminate(fx, source_info, *reason);
codegen_unwind_terminate(fx, Some(source_info.span), *reason);
}
TerminatorKind::UnwindResume => {
// FIXME implement unwinding
Expand Down Expand Up @@ -1117,18 +1117,10 @@ pub(crate) fn codegen_panic_nounwind<'tcx>(

pub(crate) fn codegen_unwind_terminate<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
source_info: mir::SourceInfo,
span: Option<Span>,
reason: UnwindTerminateReason,
) {
let args = [];

codegen_panic_inner(
fx,
reason.lang_item(),
&args,
UnwindAction::Terminate(UnwindTerminateReason::Abi),
Some(source_info.span),
);
codegen_panic_inner(fx, reason.lang_item(), &[], UnwindAction::Unreachable, span);
}

fn codegen_panic_inner<'tcx>(
Expand Down
1 change: 0 additions & 1 deletion src/compiler_builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,4 @@ builtin_functions! {
fn malloc(size: size_t) -> *mut c_void;
fn realloc(p: *mut c_void, size: size_t) -> *mut c_void;
fn free(p: *mut c_void) -> ();

}
39 changes: 36 additions & 3 deletions src/debuginfo/emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,36 @@ impl WriterRelocate {
/// Perform the collected relocations to be usable for JIT usage.
#[cfg(all(feature = "jit", not(windows)))]
pub(super) fn relocate_for_jit(mut self, jit_module: &cranelift_jit::JITModule) -> Vec<u8> {
use cranelift_module::Module;

for reloc in self.relocs.drain(..) {
match reloc.name {
super::DebugRelocName::Section(_) => unreachable!(),
super::DebugRelocName::Symbol(sym) => {
let addr = jit_module.get_finalized_function(
cranelift_module::FuncId::from_u32(sym.try_into().unwrap()),
);
let addr = if sym & 1 << 31 == 0 {
let func_id = FuncId::from_u32(sym.try_into().unwrap());
// FIXME make JITModule::get_address public and use it here instead.
// HACK rust_eh_personality is likely not defined in the same crate,
// so get_finalized_function won't work. Use the rust_eh_personality
// of cg_clif itself, which is likely ABI compatible.
if jit_module.declarations().get_function_decl(func_id).name.as_deref()
== Some("rust_eh_personality")
{
extern "C" {
fn rust_eh_personality() -> !;
}
rust_eh_personality as *const u8
} else {
jit_module.get_finalized_function(func_id)
}
} else {
jit_module
.get_finalized_data(DataId::from_u32(
u32::try_from(sym).unwrap() & !(1 << 31),
))
.0
};

let val = (addr as u64 as i64 + reloc.addend) as u64;
self.writer.write_udata_at(reloc.offset as usize, val, reloc.size).unwrap();
}
Expand Down Expand Up @@ -196,6 +219,16 @@ impl Writer for WriterRelocate {
});
self.write_udata(0, size)
}
gimli::DW_EH_PE_absptr => {
self.relocs.push(DebugReloc {
offset: self.len() as u32,
size: size.into(),
name: DebugRelocName::Symbol(symbol),
addend,
kind: object::RelocationKind::Absolute,
});
self.write_udata(0, size.into())
}
_ => Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)),
},
}
Expand Down
4 changes: 2 additions & 2 deletions src/driver/jit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec<String>) -> ! {

tcx.dcx().abort_if_errors();

jit_module.finalize_definitions();
let mut jit_module = jit_module.finalize_definitions();

println!(
"Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed"
Expand All @@ -104,7 +104,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec<String>) -> ! {
call_conv: jit_module.target_config().default_call_conv,
};
let start_func_id = jit_module.declare_function("main", Linkage::Import, &start_sig).unwrap();
let finalized_start: *const u8 = jit_module.module.get_finalized_function(start_func_id);
let finalized_start: *const u8 = jit_module.get_finalized_function(start_func_id);

let f: extern "C" fn(c_int, *const *const c_char) -> c_int =
unsafe { ::std::mem::transmute(finalized_start) };
Expand Down
9 changes: 3 additions & 6 deletions src/unwind_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,10 @@ impl UnwindModule<ObjectModule> {

#[cfg(feature = "jit")]
impl UnwindModule<cranelift_jit::JITModule> {
pub(crate) fn finalize_definitions(&mut self) {
pub(crate) fn finalize_definitions(mut self) -> cranelift_jit::JITModule {
self.module.finalize_definitions().unwrap();
let prev_unwind_context = std::mem::replace(
&mut self.unwind_context,
UnwindContext::new(&mut self.module, false),
);
unsafe { prev_unwind_context.register_jit(&self.module) };
unsafe { self.unwind_context.register_jit(&self.module) };
self.module
}
}

Expand Down