Skip to content

Commit a2a1a25

Browse files
committed
Put unwinding support behind the unwinding cargo feature
1 parent 1897616 commit a2a1a25

File tree

5 files changed

+147
-125
lines changed

5 files changed

+147
-125
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", b
4646
unstable-features = ["jit", "inline_asm_sym"]
4747
jit = ["cranelift-jit", "libloading"]
4848
inline_asm_sym = []
49+
unwinding = [] # Not yet included in unstable-features for performance reasons
4950

5051
[package.metadata.rust-analyzer]
5152
rustc_private = true

src/abi/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -873,7 +873,7 @@ pub(crate) fn codegen_call_with_unwind_action(
873873
fx: &mut FunctionCx<'_, '_, '_>,
874874
span: Option<Span>,
875875
func_ref: CallTarget,
876-
unwind: UnwindAction,
876+
mut unwind: UnwindAction,
877877
call_args: &[Value],
878878
target_block: Option<Block>,
879879
) -> SmallVec<[Value; 2]> {
@@ -885,6 +885,11 @@ pub(crate) fn codegen_call_with_unwind_action(
885885
if target_block.is_some() {
886886
assert!(fx.bcx.func.dfg.signatures[sig_ref].returns.is_empty());
887887
}
888+
889+
if cfg!(not(feature = "unwinding")) {
890+
unwind = UnwindAction::Unreachable;
891+
}
892+
888893
match unwind {
889894
UnwindAction::Continue | UnwindAction::Unreachable => {
890895
let call_inst = match func_ref {

src/base.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,10 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
300300
}
301301

302302
if bb_data.is_cleanup {
303+
if cfg!(not(feature = "unwinding")) {
304+
continue;
305+
}
306+
303307
fx.bcx.set_cold_block(block);
304308
}
305309

@@ -534,13 +538,15 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
534538
codegen_unwind_terminate(fx, Some(source_info.span), *reason);
535539
}
536540
TerminatorKind::UnwindResume => {
537-
let exception_ptr = fx.bcx.use_var(fx.exception_slot);
538-
fx.lib_call(
539-
"_Unwind_Resume",
540-
vec![AbiParam::new(fx.pointer_type)],
541-
vec![],
542-
&[exception_ptr],
543-
);
541+
if cfg!(feature = "unwinding") {
542+
let exception_ptr = fx.bcx.use_var(fx.exception_slot);
543+
fx.lib_call(
544+
"_Unwind_Resume",
545+
vec![AbiParam::new(fx.pointer_type)],
546+
vec![],
547+
&[exception_ptr],
548+
);
549+
}
544550
fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap());
545551
}
546552
TerminatorKind::Unreachable => {

src/debuginfo/unwind.rs

Lines changed: 124 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -60,48 +60,51 @@ impl UnwindContext {
6060
gimli::DwEhPe(gimli::DW_EH_PE_indirect.0 | gimli::DW_EH_PE_absptr.0)
6161
};
6262

63+
cie.fde_address_encoding = ptr_encoding;
64+
6365
// FIXME only add personality function and lsda when necessary: https://github.com/rust-lang/rust/blob/1f76d219c906f0112bb1872f33aa977164c53fa6/compiler/rustc_codegen_ssa/src/mir/mod.rs#L200-L204
66+
if cfg!(feature = "unwinding") {
67+
cie.lsda_encoding = Some(ptr_encoding);
68+
69+
// FIXME use eh_personality lang item instead
70+
let personality = module
71+
.declare_function(
72+
"rust_eh_personality",
73+
Linkage::Import,
74+
&Signature {
75+
params: vec![
76+
AbiParam::new(types::I32),
77+
AbiParam::new(types::I32),
78+
AbiParam::new(types::I64),
79+
AbiParam::new(module.target_config().pointer_type()),
80+
AbiParam::new(module.target_config().pointer_type()),
81+
],
82+
returns: vec![AbiParam::new(types::I32)],
83+
call_conv: module.target_config().default_call_conv,
84+
},
85+
)
86+
.unwrap();
87+
88+
// Use indirection here to support PIC the case where rust_eh_personality is defined in
89+
// another DSO.
90+
let personality_ref = module
91+
.declare_data("DW.ref.rust_eh_personality", Linkage::Local, false, false)
92+
.unwrap();
93+
94+
let mut personality_ref_data = DataDescription::new();
95+
// Note: Must not use define_zeroinit. The unwinder can't handle this being in the .bss
96+
// section.
97+
let pointer_bytes = usize::from(module.target_config().pointer_bytes());
98+
personality_ref_data.define(vec![0; pointer_bytes].into_boxed_slice());
99+
let personality_func_ref =
100+
module.declare_func_in_data(personality, &mut personality_ref_data);
101+
personality_ref_data.write_function_addr(0, personality_func_ref);
102+
103+
module.define_data(personality_ref, &personality_ref_data).unwrap();
104+
105+
cie.personality = Some((code_ptr_encoding, address_for_data(personality_ref)));
106+
}
64107

65-
cie.fde_address_encoding = ptr_encoding;
66-
cie.lsda_encoding = Some(ptr_encoding);
67-
68-
// FIXME use eh_personality lang item instead
69-
let personality = module
70-
.declare_function(
71-
"rust_eh_personality",
72-
Linkage::Import,
73-
&Signature {
74-
params: vec![
75-
AbiParam::new(types::I32),
76-
AbiParam::new(types::I32),
77-
AbiParam::new(types::I64),
78-
AbiParam::new(module.target_config().pointer_type()),
79-
AbiParam::new(module.target_config().pointer_type()),
80-
],
81-
returns: vec![AbiParam::new(types::I32)],
82-
call_conv: module.target_config().default_call_conv,
83-
},
84-
)
85-
.unwrap();
86-
87-
// Use indirection here to support PIC the case where rust_eh_personality is defined in
88-
// another DSO.
89-
let personality_ref = module
90-
.declare_data("DW.ref.rust_eh_personality", Linkage::Local, false, false)
91-
.unwrap();
92-
93-
let mut personality_ref_data = DataDescription::new();
94-
// Note: Must not use define_zeroinit. The unwinder can't handle this being in the .bss
95-
// section.
96-
let pointer_bytes = usize::from(module.target_config().pointer_bytes());
97-
personality_ref_data.define(vec![0; pointer_bytes].into_boxed_slice());
98-
let personality_func_ref =
99-
module.declare_func_in_data(personality, &mut personality_ref_data);
100-
personality_ref_data.write_function_addr(0, personality_func_ref);
101-
102-
module.define_data(personality_ref, &personality_ref_data).unwrap();
103-
104-
cie.personality = Some((code_ptr_encoding, address_for_data(personality_ref)));
105108
Some(frame_table.add_cie(cie))
106109
} else {
107110
None
@@ -137,89 +140,94 @@ impl UnwindContext {
137140
match unwind_info {
138141
UnwindInfo::SystemV(unwind_info) => {
139142
let mut fde = unwind_info.to_fde(address_for_func(func_id));
140-
// FIXME use unique symbol name derived from function name
141-
let lsda = module.declare_anonymous_data(false, false).unwrap();
142-
143-
let encoding = Encoding {
144-
format: Format::Dwarf32,
145-
version: 1,
146-
address_size: module.isa().frontend_config().pointer_bytes(),
147-
};
148-
149-
let mut gcc_except_table_data = GccExceptTable {
150-
call_sites: CallSiteTable(vec![]),
151-
actions: ActionTable::new(),
152-
type_info: TypeInfoTable::new(gimli::DW_EH_PE_udata4),
153-
exception_specs: ExceptionSpecTable::new(),
154-
};
155-
156-
let catch_type = gcc_except_table_data.type_info.add(Address::Constant(0));
157-
let catch_action = gcc_except_table_data
158-
.actions
159-
.add(Action { kind: ActionKind::Catch(catch_type), next_action: None });
160-
161-
for call_site in context.compiled_code().unwrap().buffer.call_sites() {
162-
if call_site.exception_handlers.is_empty() {
163-
gcc_except_table_data.call_sites.0.push(CallSite {
164-
start: u64::from(call_site.ret_addr - 1),
165-
length: 1,
166-
landing_pad: 0,
167-
action_entry: None,
168-
});
169-
}
170-
for &(tag, landingpad) in call_site.exception_handlers {
171-
match tag.expand().unwrap().as_u32() {
172-
EXCEPTION_HANDLER_CLEANUP => {
173-
gcc_except_table_data.call_sites.0.push(CallSite {
174-
start: u64::from(call_site.ret_addr - 1),
175-
length: 1,
176-
landing_pad: u64::from(landingpad),
177-
action_entry: None,
178-
})
179-
}
180-
EXCEPTION_HANDLER_CATCH => {
181-
gcc_except_table_data.call_sites.0.push(CallSite {
182-
start: u64::from(call_site.ret_addr - 1),
183-
length: 1,
184-
landing_pad: u64::from(landingpad),
185-
action_entry: Some(catch_action),
186-
})
143+
144+
// FIXME only add personality function and lsda when necessary: https://github.com/rust-lang/rust/blob/1f76d219c906f0112bb1872f33aa977164c53fa6/compiler/rustc_codegen_ssa/src/mir/mod.rs#L200-L204
145+
if cfg!(feature = "unwinding") {
146+
// FIXME use unique symbol name derived from function name
147+
let lsda = module.declare_anonymous_data(false, false).unwrap();
148+
149+
let encoding = Encoding {
150+
format: Format::Dwarf32,
151+
version: 1,
152+
address_size: module.isa().frontend_config().pointer_bytes(),
153+
};
154+
155+
let mut gcc_except_table_data = GccExceptTable {
156+
call_sites: CallSiteTable(vec![]),
157+
actions: ActionTable::new(),
158+
type_info: TypeInfoTable::new(gimli::DW_EH_PE_udata4),
159+
exception_specs: ExceptionSpecTable::new(),
160+
};
161+
162+
let catch_type = gcc_except_table_data.type_info.add(Address::Constant(0));
163+
let catch_action = gcc_except_table_data
164+
.actions
165+
.add(Action { kind: ActionKind::Catch(catch_type), next_action: None });
166+
167+
for call_site in context.compiled_code().unwrap().buffer.call_sites() {
168+
if call_site.exception_handlers.is_empty() {
169+
gcc_except_table_data.call_sites.0.push(CallSite {
170+
start: u64::from(call_site.ret_addr - 1),
171+
length: 1,
172+
landing_pad: 0,
173+
action_entry: None,
174+
});
175+
}
176+
for &(tag, landingpad) in call_site.exception_handlers {
177+
match tag.expand().unwrap().as_u32() {
178+
EXCEPTION_HANDLER_CLEANUP => {
179+
gcc_except_table_data.call_sites.0.push(CallSite {
180+
start: u64::from(call_site.ret_addr - 1),
181+
length: 1,
182+
landing_pad: u64::from(landingpad),
183+
action_entry: None,
184+
})
185+
}
186+
EXCEPTION_HANDLER_CATCH => {
187+
gcc_except_table_data.call_sites.0.push(CallSite {
188+
start: u64::from(call_site.ret_addr - 1),
189+
length: 1,
190+
landing_pad: u64::from(landingpad),
191+
action_entry: Some(catch_action),
192+
})
193+
}
194+
_ => unreachable!(),
187195
}
188-
_ => unreachable!(),
189196
}
190197
}
191-
}
192198

193-
let mut gcc_except_table = super::emit::WriterRelocate::new(self.endian);
194-
195-
gcc_except_table_data.write(&mut gcc_except_table, encoding).unwrap();
196-
197-
let mut data = DataDescription::new();
198-
data.define(gcc_except_table.writer.into_vec().into_boxed_slice());
199-
data.set_segment_section("", ".gcc_except_table");
200-
201-
for reloc in &gcc_except_table.relocs {
202-
match reloc.name {
203-
DebugRelocName::Section(_id) => unreachable!(),
204-
DebugRelocName::Symbol(id) => {
205-
let id = id.try_into().unwrap();
206-
if id & 1 << 31 == 0 {
207-
let func_ref =
208-
module.declare_func_in_data(FuncId::from_u32(id), &mut data);
209-
data.write_function_addr(reloc.offset, func_ref);
210-
} else {
211-
let gv = module.declare_data_in_data(
212-
DataId::from_u32(id & !(1 << 31)),
213-
&mut data,
214-
);
215-
data.write_data_addr(reloc.offset, gv, 0);
199+
let mut gcc_except_table = super::emit::WriterRelocate::new(self.endian);
200+
201+
gcc_except_table_data.write(&mut gcc_except_table, encoding).unwrap();
202+
203+
let mut data = DataDescription::new();
204+
data.define(gcc_except_table.writer.into_vec().into_boxed_slice());
205+
data.set_segment_section("", ".gcc_except_table");
206+
207+
for reloc in &gcc_except_table.relocs {
208+
match reloc.name {
209+
DebugRelocName::Section(_id) => unreachable!(),
210+
DebugRelocName::Symbol(id) => {
211+
let id = id.try_into().unwrap();
212+
if id & 1 << 31 == 0 {
213+
let func_ref = module
214+
.declare_func_in_data(FuncId::from_u32(id), &mut data);
215+
data.write_function_addr(reloc.offset, func_ref);
216+
} else {
217+
let gv = module.declare_data_in_data(
218+
DataId::from_u32(id & !(1 << 31)),
219+
&mut data,
220+
);
221+
data.write_data_addr(reloc.offset, gv, 0);
222+
}
216223
}
217-
}
218-
};
224+
};
225+
}
226+
227+
module.define_data(lsda, &data).unwrap();
228+
fde.lsda = Some(address_for_data(lsda));
219229
}
220230

221-
module.define_data(lsda, &data).unwrap();
222-
fde.lsda = Some(address_for_data(lsda));
223231
self.frame_table.add_fde(self.cie_id.unwrap(), fde);
224232
}
225233
UnwindInfo::WindowsX64(_) | UnwindInfo::WindowsArm64(_) => {

src/intrinsics/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
11701170
returns: vec![],
11711171
});
11721172

1173-
if fx.tcx.sess.panic_strategy() == PanicStrategy::Abort {
1173+
if cfg!(not(feature = "unwinding"))
1174+
|| fx.tcx.sess.panic_strategy() == PanicStrategy::Abort
1175+
{
11741176
fx.bcx.ins().call_indirect(f_sig, f, &[data]);
11751177

11761178
let layout = fx.layout_of(fx.tcx.types.i32);

0 commit comments

Comments
 (0)