Skip to content

Commit ae6259a

Browse files
committed
Fix panic=unwind for JIT
1 parent 7666929 commit ae6259a

File tree

6 files changed

+84
-41
lines changed

6 files changed

+84
-41
lines changed

example/mini_core.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,10 +521,27 @@ fn panic_cannot_unwind() -> ! {
521521
}
522522

523523
#[lang = "eh_personality"]
524-
fn eh_personality() -> ! {
524+
// FIXME personality signature depends on target
525+
fn eh_personality(
526+
_version: i32,
527+
_actions: i32,
528+
_exception_class: u64,
529+
_exception_object: *mut (),
530+
_context: *mut (),
531+
) -> i32 {
525532
loop {}
526533
}
527534

535+
#[lang = "panic_in_cleanup"]
536+
fn panic_in_cleanup() -> ! {
537+
loop {}
538+
}
539+
540+
#[link(name = "gcc_s")]
541+
extern "C" {
542+
fn _Unwind_Resume(exc: *mut ()) -> !;
543+
}
544+
528545
#[lang = "drop_in_place"]
529546
#[allow(unconditional_recursion)]
530547
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {

scripts/test_rustc_tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,5 +182,5 @@ index 073116933bd..c3e4578204d 100644
182182
EOF
183183

184184
echo "[TEST] rustc test suite"
185-
COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 --test-args=--no-capture tests/{codegen-units,run-make,ui,incremental}
185+
COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 tests/{codegen-units,ui,incremental}
186186
popd

src/compiler_builtins.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,4 @@ builtin_functions! {
6767
fn malloc(size: size_t) -> *mut c_void;
6868
fn realloc(p: *mut c_void, size: size_t) -> *mut c_void;
6969
fn free(p: *mut c_void) -> ();
70-
7170
}

src/debuginfo/emit.rs

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,32 @@ impl WriterRelocate {
8181
/// Perform the collected relocations to be usable for JIT usage.
8282
#[cfg(all(feature = "jit", not(windows)))]
8383
pub(super) fn relocate_for_jit(mut self, jit_module: &cranelift_jit::JITModule) -> Vec<u8> {
84+
use cranelift_module::Module;
85+
8486
for reloc in self.relocs.drain(..) {
8587
match reloc.name {
8688
super::DebugRelocName::Section(_) => unreachable!(),
8789
super::DebugRelocName::Symbol(sym) => {
88-
let addr = jit_module.get_finalized_function(
89-
cranelift_module::FuncId::from_u32(sym.try_into().unwrap()),
90-
);
90+
let addr = if sym & 1 << 31 == 0 {
91+
let func_id = FuncId::from_u32(sym.try_into().unwrap());
92+
if jit_module.declarations().get_function_decl(func_id).name.as_deref()
93+
== Some("rust_eh_personality")
94+
{
95+
extern "C" {
96+
fn rust_eh_personality() -> !;
97+
}
98+
rust_eh_personality as *const u8
99+
} else {
100+
jit_module.get_finalized_function(func_id)
101+
}
102+
} else {
103+
jit_module
104+
.get_finalized_data(DataId::from_u32(
105+
u32::try_from(sym).unwrap() & !(1 << 31),
106+
))
107+
.0
108+
};
109+
91110
let val = (addr as u64 as i64 + reloc.addend) as u64;
92111
self.writer.write_udata_at(reloc.offset as usize, val, reloc.size).unwrap();
93112
}
@@ -196,6 +215,16 @@ impl Writer for WriterRelocate {
196215
});
197216
self.write_udata(0, size)
198217
}
218+
gimli::DW_EH_PE_absptr => {
219+
self.relocs.push(DebugReloc {
220+
offset: self.len() as u32,
221+
size: size.into(),
222+
name: DebugRelocName::Symbol(symbol),
223+
addend,
224+
kind: object::RelocationKind::Absolute,
225+
});
226+
self.write_udata(0, size.into())
227+
}
199228
_ => Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)),
200229
},
201230
}

src/debuginfo/unwind.rs

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,36 @@ impl UnwindContext {
2929
let mut frame_table = FrameTable::default();
3030

3131
let cie_id = if let Some(mut cie) = module.isa().create_systemv_cie() {
32-
if pic_eh_frame {
33-
cie.fde_address_encoding =
34-
gimli::DwEhPe(gimli::DW_EH_PE_pcrel.0 | gimli::DW_EH_PE_sdata4.0);
35-
cie.lsda_encoding =
36-
Some(gimli::DwEhPe(gimli::DW_EH_PE_pcrel.0 | gimli::DW_EH_PE_sdata4.0));
32+
let ptr_encoding = if pic_eh_frame {
33+
gimli::DwEhPe(gimli::DW_EH_PE_pcrel.0 | gimli::DW_EH_PE_sdata4.0)
3734
} else {
38-
cie.fde_address_encoding = gimli::DW_EH_PE_absptr;
39-
cie.lsda_encoding = Some(gimli::DW_EH_PE_absptr);
40-
}
35+
gimli::DW_EH_PE_absptr
36+
};
37+
let code_ptr_encoding = if pic_eh_frame {
38+
if module.isa().triple().architecture == target_lexicon::Architecture::X86_64 {
39+
gimli::DwEhPe(
40+
gimli::DW_EH_PE_indirect.0
41+
| gimli::DW_EH_PE_pcrel.0
42+
| gimli::DW_EH_PE_sdata4.0,
43+
)
44+
} else if let target_lexicon::Architecture::Aarch64(_) =
45+
module.isa().triple().architecture
46+
{
47+
gimli::DwEhPe(
48+
gimli::DW_EH_PE_indirect.0
49+
| gimli::DW_EH_PE_pcrel.0
50+
| gimli::DW_EH_PE_sdata8.0,
51+
)
52+
} else {
53+
todo!()
54+
}
55+
} else {
56+
gimli::DwEhPe(gimli::DW_EH_PE_indirect.0 | gimli::DW_EH_PE_absptr.0)
57+
};
58+
59+
cie.fde_address_encoding = ptr_encoding;
60+
cie.lsda_encoding = Some(ptr_encoding);
61+
4162
// FIXME use eh_personality lang item instead
4263
let personality = module
4364
.declare_function(
@@ -72,26 +93,7 @@ impl UnwindContext {
7293

7394
module.define_data(personality_ref, &personality_ref_data).unwrap();
7495

75-
cie.personality = Some((
76-
if module.isa().triple().architecture == target_lexicon::Architecture::X86_64 {
77-
gimli::DwEhPe(
78-
gimli::DW_EH_PE_indirect.0
79-
| gimli::DW_EH_PE_pcrel.0
80-
| gimli::DW_EH_PE_sdata4.0,
81-
)
82-
} else if let target_lexicon::Architecture::Aarch64(_) =
83-
module.isa().triple().architecture
84-
{
85-
gimli::DwEhPe(
86-
gimli::DW_EH_PE_indirect.0
87-
| gimli::DW_EH_PE_pcrel.0
88-
| gimli::DW_EH_PE_sdata8.0,
89-
)
90-
} else {
91-
todo!()
92-
},
93-
address_for_data(personality_ref),
94-
));
96+
cie.personality = Some((code_ptr_encoding, address_for_data(personality_ref)));
9597
Some(frame_table.add_cie(cie))
9698
} else {
9799
None
@@ -235,10 +237,10 @@ impl UnwindContext {
235237
}
236238

237239
#[cfg(all(feature = "jit", windows))]
238-
pub(crate) unsafe fn register_jit(self, _jit_module: &cranelift_jit::JITModule) {}
240+
pub(crate) unsafe fn register_jit(&mut self, _jit_module: &cranelift_jit::JITModule) {}
239241

240242
#[cfg(all(feature = "jit", not(windows)))]
241-
pub(crate) unsafe fn register_jit(self, jit_module: &cranelift_jit::JITModule) {
243+
pub(crate) unsafe fn register_jit(&mut self, jit_module: &cranelift_jit::JITModule) {
242244
use std::mem::ManuallyDrop;
243245

244246
let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(self.endian));

src/unwind_module.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,7 @@ impl UnwindModule<ObjectModule> {
3535
impl UnwindModule<cranelift_jit::JITModule> {
3636
pub(crate) fn finalize_definitions(&mut self) {
3737
self.module.finalize_definitions().unwrap();
38-
let prev_unwind_context = std::mem::replace(
39-
&mut self.unwind_context,
40-
UnwindContext::new(&mut self.module, false),
41-
);
42-
unsafe { prev_unwind_context.register_jit(&self.module) };
38+
unsafe { self.unwind_context.register_jit(&self.module) };
4339
}
4440
}
4541

0 commit comments

Comments
 (0)