Skip to content

Commit b59f697

Browse files
committed
Relocation improvements for .eh_frame
This is necessary to handle LSDA references in the future once unwinding is supported.
1 parent 349430c commit b59f697

File tree

1 file changed

+36
-3
lines changed

1 file changed

+36
-3
lines changed

src/debuginfo/emit.rs

+36-3
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,36 @@ 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+
// FIXME make JITModule::get_address public and use it here instead.
93+
// HACK rust_eh_personality is likely not defined in the same crate,
94+
// so get_finalized_function won't work. Use the rust_eh_personality
95+
// of cg_clif itself, which is likely ABI compatible.
96+
if jit_module.declarations().get_function_decl(func_id).name.as_deref()
97+
== Some("rust_eh_personality")
98+
{
99+
extern "C" {
100+
fn rust_eh_personality() -> !;
101+
}
102+
rust_eh_personality as *const u8
103+
} else {
104+
jit_module.get_finalized_function(func_id)
105+
}
106+
} else {
107+
jit_module
108+
.get_finalized_data(DataId::from_u32(
109+
u32::try_from(sym).unwrap() & !(1 << 31),
110+
))
111+
.0
112+
};
113+
91114
let val = (addr as u64 as i64 + reloc.addend) as u64;
92115
self.writer.write_udata_at(reloc.offset as usize, val, reloc.size).unwrap();
93116
}
@@ -196,6 +219,16 @@ impl Writer for WriterRelocate {
196219
});
197220
self.write_udata(0, size)
198221
}
222+
gimli::DW_EH_PE_absptr => {
223+
self.relocs.push(DebugReloc {
224+
offset: self.len() as u32,
225+
size: size.into(),
226+
name: DebugRelocName::Symbol(symbol),
227+
addend,
228+
kind: object::RelocationKind::Absolute,
229+
});
230+
self.write_udata(0, size.into())
231+
}
199232
_ => Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)),
200233
},
201234
}

0 commit comments

Comments
 (0)