Skip to content

Commit 4b03de5

Browse files
committed
Put unwinding support behind the unwinding cargo feature
1 parent 55c36d3 commit 4b03de5

File tree

5 files changed

+148
-124
lines changed

5 files changed

+148
-124
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
@@ -855,7 +855,7 @@ pub(crate) fn codegen_call_with_unwind_action(
855855
fx: &mut FunctionCx<'_, '_, '_>,
856856
span: Option<Span>,
857857
func_ref: CallTarget,
858-
unwind: UnwindAction,
858+
mut unwind: UnwindAction,
859859
call_args: &[Value],
860860
target_block: Option<Block>,
861861
) -> SmallVec<[Value; 2]> {
@@ -867,6 +867,11 @@ pub(crate) fn codegen_call_with_unwind_action(
867867
if target_block.is_some() {
868868
assert!(fx.bcx.func.dfg.signatures[sig_ref].returns.is_empty());
869869
}
870+
871+
if cfg!(not(feature = "unwinding")) {
872+
unwind = UnwindAction::Unreachable;
873+
}
874+
870875
match unwind {
871876
UnwindAction::Continue | UnwindAction::Unreachable => {
872877
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: 125 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -61,45 +61,50 @@ impl UnwindContext {
6161
};
6262

6363
cie.fde_address_encoding = ptr_encoding;
64-
cie.lsda_encoding = Some(ptr_encoding);
65-
66-
// FIXME use eh_personality lang item instead
67-
let personality = module
68-
.declare_function(
69-
"rust_eh_personality",
70-
Linkage::Import,
71-
&Signature {
72-
params: vec![
73-
AbiParam::new(types::I32),
74-
AbiParam::new(types::I32),
75-
AbiParam::new(types::I64),
76-
AbiParam::new(module.target_config().pointer_type()),
77-
AbiParam::new(module.target_config().pointer_type()),
78-
],
79-
returns: vec![AbiParam::new(types::I32)],
80-
call_conv: module.target_config().default_call_conv,
81-
},
82-
)
83-
.unwrap();
84-
85-
// Use indirection here to support PIC the case where rust_eh_personality is defined in
86-
// another DSO.
87-
let personality_ref = module
88-
.declare_data("DW.ref.rust_eh_personality", Linkage::Local, false, false)
89-
.unwrap();
90-
91-
let mut personality_ref_data = DataDescription::new();
92-
// Note: Must not use define_zeroinit. The unwinder can't handle this being in the .bss
93-
// section.
94-
let pointer_bytes = usize::from(module.target_config().pointer_bytes());
95-
personality_ref_data.define(vec![0; pointer_bytes].into_boxed_slice());
96-
let personality_func_ref =
97-
module.declare_func_in_data(personality, &mut personality_ref_data);
98-
personality_ref_data.write_function_addr(0, personality_func_ref);
99-
100-
module.define_data(personality_ref, &personality_ref_data).unwrap();
101-
102-
cie.personality = Some((code_ptr_encoding, address_for_data(personality_ref)));
64+
65+
// 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+
}
107+
103108
Some(frame_table.add_cie(cie))
104109
} else {
105110
None
@@ -135,89 +140,94 @@ impl UnwindContext {
135140
match unwind_info {
136141
UnwindInfo::SystemV(unwind_info) => {
137142
let mut fde = unwind_info.to_fde(address_for_func(func_id));
138-
// FIXME use unique symbol name derived from function name
139-
let lsda = module.declare_anonymous_data(false, false).unwrap();
140-
141-
let encoding = Encoding {
142-
format: Format::Dwarf32,
143-
version: 1,
144-
address_size: module.isa().frontend_config().pointer_bytes(),
145-
};
146-
147-
let mut gcc_except_table_data = GccExceptTable {
148-
call_sites: CallSiteTable(vec![]),
149-
actions: ActionTable::new(),
150-
type_info: TypeInfoTable::new(gimli::DW_EH_PE_udata4),
151-
exception_specs: ExceptionSpecTable::new(),
152-
};
153-
154-
let catch_type = gcc_except_table_data.type_info.add(Address::Constant(0));
155-
let catch_action = gcc_except_table_data
156-
.actions
157-
.add(Action { kind: ActionKind::Catch(catch_type), next_action: None });
158-
159-
for call_site in context.compiled_code().unwrap().buffer.call_sites() {
160-
if call_site.exception_handlers.is_empty() {
161-
gcc_except_table_data.call_sites.0.push(CallSite {
162-
start: u64::from(call_site.ret_addr - 1),
163-
length: 1,
164-
landing_pad: 0,
165-
action_entry: None,
166-
});
167-
}
168-
for &(tag, landingpad) in call_site.exception_handlers {
169-
match tag.expand().unwrap().as_u32() {
170-
EXCEPTION_HANDLER_CLEANUP => {
171-
gcc_except_table_data.call_sites.0.push(CallSite {
172-
start: u64::from(call_site.ret_addr - 1),
173-
length: 1,
174-
landing_pad: u64::from(landingpad),
175-
action_entry: None,
176-
})
177-
}
178-
EXCEPTION_HANDLER_CATCH => {
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: Some(catch_action),
184-
})
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!(),
185195
}
186-
_ => unreachable!(),
187196
}
188197
}
189-
}
190198

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

219-
module.define_data(lsda, &data).unwrap();
220-
fde.lsda = Some(address_for_data(lsda));
221231
self.frame_table.add_fde(self.cie_id.unwrap(), fde);
222232
}
223233
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)