Put unwinding support behind a cargo feature
This commit is contained in:
parent
0c7e953885
commit
e0ea4b016a
14 changed files with 231 additions and 150 deletions
|
|
@ -46,6 +46,7 @@ smallvec = "1.8.1"
|
|||
unstable-features = ["jit", "inline_asm_sym"]
|
||||
jit = ["cranelift-jit", "libloading"]
|
||||
inline_asm_sym = []
|
||||
unwinding = [] # Not yet included in unstable-features for performance reasons
|
||||
|
||||
[package.metadata.rust-analyzer]
|
||||
rustc_private = true
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ pub(crate) fn run(
|
|||
cg_clif_dylib: &CodegenBackend,
|
||||
rustup_toolchain_name: Option<&str>,
|
||||
bootstrap_host_compiler: &Compiler,
|
||||
panic_unwind_support: bool,
|
||||
) {
|
||||
std::fs::create_dir_all(&dirs.download_dir).unwrap();
|
||||
ABI_CAFE_REPO.fetch(dirs);
|
||||
|
|
@ -32,6 +33,7 @@ pub(crate) fn run(
|
|||
bootstrap_host_compiler,
|
||||
rustup_toolchain_name,
|
||||
bootstrap_host_compiler.triple.clone(),
|
||||
panic_unwind_support,
|
||||
);
|
||||
|
||||
eprintln!("Running abi-cafe");
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ pub(crate) fn build_backend(
|
|||
dirs: &Dirs,
|
||||
bootstrap_host_compiler: &Compiler,
|
||||
use_unstable_features: bool,
|
||||
panic_unwind_support: bool,
|
||||
) -> PathBuf {
|
||||
let _group = LogGroup::guard("Build backend");
|
||||
|
||||
|
|
@ -31,6 +32,10 @@ pub(crate) fn build_backend(
|
|||
cmd.arg("--features").arg("unstable-features");
|
||||
}
|
||||
|
||||
if panic_unwind_support {
|
||||
cmd.arg("--features").arg("unwinding");
|
||||
}
|
||||
|
||||
cmd.arg("--release");
|
||||
|
||||
eprintln!("[BUILD] rustc_codegen_cranelift");
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ pub(crate) fn build_sysroot(
|
|||
bootstrap_host_compiler: &Compiler,
|
||||
rustup_toolchain_name: Option<&str>,
|
||||
target_triple: String,
|
||||
panic_unwind_support: bool,
|
||||
) -> Compiler {
|
||||
let _guard = LogGroup::guard("Build sysroot");
|
||||
|
||||
|
|
@ -52,6 +53,9 @@ pub(crate) fn build_sysroot(
|
|||
.arg("-o")
|
||||
.arg(&wrapper_path)
|
||||
.arg("-Cstrip=debuginfo");
|
||||
if panic_unwind_support {
|
||||
build_cargo_wrapper_cmd.arg("--cfg").arg("support_panic_unwind");
|
||||
}
|
||||
if let Some(rustup_toolchain_name) = &rustup_toolchain_name {
|
||||
build_cargo_wrapper_cmd
|
||||
.env("TOOLCHAIN_NAME", rustup_toolchain_name)
|
||||
|
|
@ -77,6 +81,7 @@ pub(crate) fn build_sysroot(
|
|||
bootstrap_host_compiler.clone(),
|
||||
&cg_clif_dylib_path,
|
||||
sysroot_kind,
|
||||
panic_unwind_support,
|
||||
);
|
||||
host.install_into_sysroot(dist_dir);
|
||||
|
||||
|
|
@ -91,6 +96,7 @@ pub(crate) fn build_sysroot(
|
|||
},
|
||||
&cg_clif_dylib_path,
|
||||
sysroot_kind,
|
||||
panic_unwind_support,
|
||||
)
|
||||
.install_into_sysroot(dist_dir);
|
||||
}
|
||||
|
|
@ -141,12 +147,15 @@ fn build_sysroot_for_triple(
|
|||
compiler: Compiler,
|
||||
cg_clif_dylib_path: &CodegenBackend,
|
||||
sysroot_kind: SysrootKind,
|
||||
panic_unwind_support: bool,
|
||||
) -> SysrootTarget {
|
||||
match sysroot_kind {
|
||||
SysrootKind::None => build_rtstartup(dirs, &compiler)
|
||||
.unwrap_or(SysrootTarget { triple: compiler.triple, libs: vec![] }),
|
||||
SysrootKind::Llvm => build_llvm_sysroot_for_triple(compiler),
|
||||
SysrootKind::Clif => build_clif_sysroot_for_triple(dirs, compiler, cg_clif_dylib_path),
|
||||
SysrootKind::Clif => {
|
||||
build_clif_sysroot_for_triple(dirs, compiler, cg_clif_dylib_path, panic_unwind_support)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -188,6 +197,7 @@ fn build_clif_sysroot_for_triple(
|
|||
dirs: &Dirs,
|
||||
mut compiler: Compiler,
|
||||
cg_clif_dylib_path: &CodegenBackend,
|
||||
panic_unwind_support: bool,
|
||||
) -> SysrootTarget {
|
||||
let mut target_libs = SysrootTarget { triple: compiler.triple.clone(), libs: vec![] };
|
||||
|
||||
|
|
@ -206,7 +216,10 @@ fn build_clif_sysroot_for_triple(
|
|||
}
|
||||
|
||||
// Build sysroot
|
||||
let mut rustflags = vec!["-Zforce-unstable-if-unmarked".to_owned(), "-Cpanic=abort".to_owned()];
|
||||
let mut rustflags = vec!["-Zforce-unstable-if-unmarked".to_owned()];
|
||||
if !panic_unwind_support {
|
||||
rustflags.push("-Cpanic=abort".to_owned());
|
||||
}
|
||||
match cg_clif_dylib_path {
|
||||
CodegenBackend::Local(path) => {
|
||||
rustflags.push(format!("-Zcodegen-backend={}", path.to_str().unwrap()));
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ fn main() {
|
|||
let mut download_dir = None;
|
||||
let mut sysroot_kind = SysrootKind::Clif;
|
||||
let mut use_unstable_features = true;
|
||||
let mut panic_unwind_support = false;
|
||||
let mut frozen = false;
|
||||
let mut skip_tests = vec![];
|
||||
let mut use_backend = None;
|
||||
|
|
@ -108,6 +109,7 @@ fn main() {
|
|||
}
|
||||
}
|
||||
"--no-unstable-features" => use_unstable_features = false,
|
||||
"--panic-unwind-support" => panic_unwind_support = true,
|
||||
"--frozen" => frozen = true,
|
||||
"--skip-test" => {
|
||||
// FIXME check that all passed in tests actually exist
|
||||
|
|
@ -201,6 +203,7 @@ fn main() {
|
|||
&dirs,
|
||||
&bootstrap_host_compiler,
|
||||
use_unstable_features,
|
||||
panic_unwind_support,
|
||||
))
|
||||
};
|
||||
match command {
|
||||
|
|
@ -212,6 +215,7 @@ fn main() {
|
|||
&dirs,
|
||||
sysroot_kind,
|
||||
use_unstable_features,
|
||||
panic_unwind_support,
|
||||
&skip_tests.iter().map(|test| &**test).collect::<Vec<_>>(),
|
||||
&cg_clif_dylib,
|
||||
&bootstrap_host_compiler,
|
||||
|
|
@ -230,6 +234,7 @@ fn main() {
|
|||
&cg_clif_dylib,
|
||||
rustup_toolchain_name.as_deref(),
|
||||
&bootstrap_host_compiler,
|
||||
panic_unwind_support,
|
||||
);
|
||||
}
|
||||
Command::Build => {
|
||||
|
|
@ -240,6 +245,7 @@ fn main() {
|
|||
&bootstrap_host_compiler,
|
||||
rustup_toolchain_name.as_deref(),
|
||||
target_triple,
|
||||
panic_unwind_support,
|
||||
);
|
||||
}
|
||||
Command::Bench => {
|
||||
|
|
@ -250,6 +256,7 @@ fn main() {
|
|||
&bootstrap_host_compiler,
|
||||
rustup_toolchain_name.as_deref(),
|
||||
target_triple,
|
||||
panic_unwind_support,
|
||||
);
|
||||
bench::benchmark(&dirs, &compiler);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -233,6 +233,7 @@ pub(crate) fn run_tests(
|
|||
dirs: &Dirs,
|
||||
sysroot_kind: SysrootKind,
|
||||
use_unstable_features: bool,
|
||||
panic_unwind_support: bool,
|
||||
skip_tests: &[&str],
|
||||
cg_clif_dylib: &CodegenBackend,
|
||||
bootstrap_host_compiler: &Compiler,
|
||||
|
|
@ -251,12 +252,14 @@ pub(crate) fn run_tests(
|
|||
bootstrap_host_compiler,
|
||||
rustup_toolchain_name,
|
||||
target_triple.clone(),
|
||||
panic_unwind_support,
|
||||
);
|
||||
|
||||
let runner = TestRunner::new(
|
||||
dirs.clone(),
|
||||
target_compiler,
|
||||
use_unstable_features,
|
||||
panic_unwind_support,
|
||||
skip_tests,
|
||||
bootstrap_host_compiler.triple == target_triple,
|
||||
stdlib_source.clone(),
|
||||
|
|
@ -283,12 +286,14 @@ pub(crate) fn run_tests(
|
|||
bootstrap_host_compiler,
|
||||
rustup_toolchain_name,
|
||||
target_triple.clone(),
|
||||
panic_unwind_support,
|
||||
);
|
||||
|
||||
let mut runner = TestRunner::new(
|
||||
dirs.clone(),
|
||||
target_compiler,
|
||||
use_unstable_features,
|
||||
panic_unwind_support,
|
||||
skip_tests,
|
||||
bootstrap_host_compiler.triple == target_triple,
|
||||
stdlib_source,
|
||||
|
|
@ -314,6 +319,7 @@ pub(crate) fn run_tests(
|
|||
struct TestRunner<'a> {
|
||||
is_native: bool,
|
||||
jit_supported: bool,
|
||||
panic_unwind_support: bool,
|
||||
skip_tests: &'a [&'a str],
|
||||
dirs: Dirs,
|
||||
target_compiler: Compiler,
|
||||
|
|
@ -325,6 +331,7 @@ impl<'a> TestRunner<'a> {
|
|||
dirs: Dirs,
|
||||
mut target_compiler: Compiler,
|
||||
use_unstable_features: bool,
|
||||
panic_unwind_support: bool,
|
||||
skip_tests: &'a [&'a str],
|
||||
is_native: bool,
|
||||
stdlib_source: PathBuf,
|
||||
|
|
@ -335,7 +342,15 @@ impl<'a> TestRunner<'a> {
|
|||
let jit_supported =
|
||||
use_unstable_features && is_native && !target_compiler.triple.contains("windows");
|
||||
|
||||
Self { is_native, jit_supported, skip_tests, dirs, target_compiler, stdlib_source }
|
||||
Self {
|
||||
is_native,
|
||||
jit_supported,
|
||||
panic_unwind_support,
|
||||
skip_tests,
|
||||
dirs,
|
||||
target_compiler,
|
||||
stdlib_source,
|
||||
}
|
||||
}
|
||||
|
||||
fn run_testsuite(&self, tests: &[TestCase]) {
|
||||
|
|
@ -404,7 +419,9 @@ impl<'a> TestRunner<'a> {
|
|||
cmd.arg("-Cdebuginfo=2");
|
||||
cmd.arg("--target");
|
||||
cmd.arg(&self.target_compiler.triple);
|
||||
cmd.arg("-Cpanic=abort");
|
||||
if !self.panic_unwind_support {
|
||||
cmd.arg("-Cpanic=abort");
|
||||
}
|
||||
cmd.arg("--check-cfg=cfg(jit)");
|
||||
cmd.args(args);
|
||||
cmd
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ OPTIONS:
|
|||
Some features are not yet ready for production usage. This option will disable these
|
||||
features. This includes the JIT mode and inline assembly support.
|
||||
|
||||
--panic-unwind-support
|
||||
Enable support for unwinding when -Cpanic=unwind is used. This currently regresses build
|
||||
performance.
|
||||
|
||||
--frozen
|
||||
Require Cargo.lock and cache are up to date
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,11 @@ fn main() {
|
|||
sysroot = sysroot.parent().unwrap();
|
||||
}
|
||||
|
||||
let mut rustflags = vec!["-Cpanic=abort".to_owned(), "-Zpanic-abort-tests".to_owned()];
|
||||
let mut rustflags = vec![];
|
||||
if !cfg!(support_panic_unwind) {
|
||||
rustflags.push("-Cpanic=abort".to_owned());
|
||||
rustflags.push("-Zpanic-abort-tests".to_owned());
|
||||
}
|
||||
if let Some(name) = option_env!("BUILTIN_BACKEND") {
|
||||
rustflags.push(format!("-Zcodegen-backend={name}"));
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@ fn main() {
|
|||
|
||||
let passed_args = std::env::args_os().skip(1).collect::<Vec<_>>();
|
||||
let mut args = vec![];
|
||||
args.push(OsString::from("-Cpanic=abort"));
|
||||
args.push(OsString::from("-Zpanic-abort-tests"));
|
||||
if !cfg!(support_panic_unwind) {
|
||||
args.push(OsString::from("-Cpanic=abort"));
|
||||
args.push(OsString::from("-Zpanic-abort-tests"));
|
||||
}
|
||||
if let Some(name) = option_env!("BUILTIN_BACKEND") {
|
||||
args.push(OsString::from(format!("-Zcodegen-backend={name}")))
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@ fn main() {
|
|||
|
||||
let passed_args = std::env::args_os().skip(1).collect::<Vec<_>>();
|
||||
let mut args = vec![];
|
||||
args.push(OsString::from("-Cpanic=abort"));
|
||||
args.push(OsString::from("-Zpanic-abort-tests"));
|
||||
if !cfg!(support_panic_unwind) {
|
||||
args.push(OsString::from("-Cpanic=abort"));
|
||||
args.push(OsString::from("-Zpanic-abort-tests"));
|
||||
}
|
||||
if let Some(name) = option_env!("BUILTIN_BACKEND") {
|
||||
args.push(OsString::from(format!("-Zcodegen-backend={name}")))
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -844,7 +844,7 @@ pub(crate) fn codegen_call_with_unwind_action(
|
|||
fx: &mut FunctionCx<'_, '_, '_>,
|
||||
span: Span,
|
||||
func_ref: CallTarget,
|
||||
unwind: UnwindAction,
|
||||
mut unwind: UnwindAction,
|
||||
call_args: &[Value],
|
||||
target_block: Option<Block>,
|
||||
) -> SmallVec<[Value; 2]> {
|
||||
|
|
@ -856,6 +856,11 @@ pub(crate) fn codegen_call_with_unwind_action(
|
|||
if target_block.is_some() {
|
||||
assert!(fx.bcx.func.dfg.signatures[sig_ref].returns.is_empty());
|
||||
}
|
||||
|
||||
if cfg!(not(feature = "unwinding")) {
|
||||
unwind = UnwindAction::Unreachable;
|
||||
}
|
||||
|
||||
match unwind {
|
||||
UnwindAction::Continue | UnwindAction::Unreachable => {
|
||||
let call_inst = match func_ref {
|
||||
|
|
|
|||
20
src/base.rs
20
src/base.rs
|
|
@ -308,6 +308,10 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
|
|||
}
|
||||
|
||||
if bb_data.is_cleanup {
|
||||
if cfg!(not(feature = "unwinding")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
fx.bcx.set_cold_block(block);
|
||||
}
|
||||
|
||||
|
|
@ -542,13 +546,15 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
|
|||
codegen_unwind_terminate(fx, source_info.span, *reason);
|
||||
}
|
||||
TerminatorKind::UnwindResume => {
|
||||
let exception_ptr = fx.bcx.use_var(fx.exception_slot);
|
||||
fx.lib_call(
|
||||
"_Unwind_Resume",
|
||||
vec![AbiParam::new(fx.pointer_type)],
|
||||
vec![],
|
||||
&[exception_ptr],
|
||||
);
|
||||
if cfg!(feature = "unwinding") {
|
||||
let exception_ptr = fx.bcx.use_var(fx.exception_slot);
|
||||
fx.lib_call(
|
||||
"_Unwind_Resume",
|
||||
vec![AbiParam::new(fx.pointer_type)],
|
||||
vec![],
|
||||
&[exception_ptr],
|
||||
);
|
||||
}
|
||||
fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap());
|
||||
}
|
||||
TerminatorKind::Unreachable => {
|
||||
|
|
|
|||
|
|
@ -37,68 +37,74 @@ impl UnwindContext {
|
|||
} else {
|
||||
gimli::DW_EH_PE_absptr
|
||||
};
|
||||
let code_ptr_encoding = if pic_eh_frame {
|
||||
if module.isa().triple().architecture == target_lexicon::Architecture::X86_64 {
|
||||
gimli::DwEhPe(
|
||||
gimli::DW_EH_PE_indirect.0
|
||||
| gimli::DW_EH_PE_pcrel.0
|
||||
| gimli::DW_EH_PE_sdata4.0,
|
||||
)
|
||||
} else if let target_lexicon::Architecture::Aarch64(_) =
|
||||
module.isa().triple().architecture
|
||||
{
|
||||
gimli::DwEhPe(
|
||||
gimli::DW_EH_PE_indirect.0
|
||||
| gimli::DW_EH_PE_pcrel.0
|
||||
| gimli::DW_EH_PE_sdata8.0,
|
||||
)
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
} else {
|
||||
gimli::DwEhPe(gimli::DW_EH_PE_indirect.0 | gimli::DW_EH_PE_absptr.0)
|
||||
};
|
||||
|
||||
cie.fde_address_encoding = ptr_encoding;
|
||||
cie.lsda_encoding = Some(ptr_encoding);
|
||||
|
||||
// FIXME use eh_personality lang item instead
|
||||
let personality = module
|
||||
.declare_function(
|
||||
"rust_eh_personality",
|
||||
Linkage::Import,
|
||||
&Signature {
|
||||
params: vec![
|
||||
AbiParam::new(types::I32),
|
||||
AbiParam::new(types::I32),
|
||||
AbiParam::new(types::I64),
|
||||
AbiParam::new(module.target_config().pointer_type()),
|
||||
AbiParam::new(module.target_config().pointer_type()),
|
||||
],
|
||||
returns: vec![AbiParam::new(types::I32)],
|
||||
call_conv: module.target_config().default_call_conv,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
// 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
|
||||
if cfg!(feature = "unwinding") {
|
||||
let code_ptr_encoding = if pic_eh_frame {
|
||||
if module.isa().triple().architecture == target_lexicon::Architecture::X86_64 {
|
||||
gimli::DwEhPe(
|
||||
gimli::DW_EH_PE_indirect.0
|
||||
| gimli::DW_EH_PE_pcrel.0
|
||||
| gimli::DW_EH_PE_sdata4.0,
|
||||
)
|
||||
} else if let target_lexicon::Architecture::Aarch64(_) =
|
||||
module.isa().triple().architecture
|
||||
{
|
||||
gimli::DwEhPe(
|
||||
gimli::DW_EH_PE_indirect.0
|
||||
| gimli::DW_EH_PE_pcrel.0
|
||||
| gimli::DW_EH_PE_sdata8.0,
|
||||
)
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
} else {
|
||||
gimli::DwEhPe(gimli::DW_EH_PE_indirect.0 | gimli::DW_EH_PE_absptr.0)
|
||||
};
|
||||
|
||||
// Use indirection here to support PIC the case where rust_eh_personality is defined in
|
||||
// another DSO.
|
||||
let personality_ref = module
|
||||
.declare_data("DW.ref.rust_eh_personality", Linkage::Local, false, false)
|
||||
.unwrap();
|
||||
cie.lsda_encoding = Some(ptr_encoding);
|
||||
|
||||
let mut personality_ref_data = DataDescription::new();
|
||||
// Note: Must not use define_zeroinit. The unwinder can't handle this being in the .bss
|
||||
// section.
|
||||
let pointer_bytes = usize::from(module.target_config().pointer_bytes());
|
||||
personality_ref_data.define(vec![0; pointer_bytes].into_boxed_slice());
|
||||
let personality_func_ref =
|
||||
module.declare_func_in_data(personality, &mut personality_ref_data);
|
||||
personality_ref_data.write_function_addr(0, personality_func_ref);
|
||||
// FIXME use eh_personality lang item instead
|
||||
let personality = module
|
||||
.declare_function(
|
||||
"rust_eh_personality",
|
||||
Linkage::Import,
|
||||
&Signature {
|
||||
params: vec![
|
||||
AbiParam::new(types::I32),
|
||||
AbiParam::new(types::I32),
|
||||
AbiParam::new(types::I64),
|
||||
AbiParam::new(module.target_config().pointer_type()),
|
||||
AbiParam::new(module.target_config().pointer_type()),
|
||||
],
|
||||
returns: vec![AbiParam::new(types::I32)],
|
||||
call_conv: module.target_config().default_call_conv,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
module.define_data(personality_ref, &personality_ref_data).unwrap();
|
||||
// Use indirection here to support PIC the case where rust_eh_personality is defined in
|
||||
// another DSO.
|
||||
let personality_ref = module
|
||||
.declare_data("DW.ref.rust_eh_personality", Linkage::Local, false, false)
|
||||
.unwrap();
|
||||
|
||||
let mut personality_ref_data = DataDescription::new();
|
||||
// Note: Must not use define_zeroinit. The unwinder can't handle this being in the .bss
|
||||
// section.
|
||||
let pointer_bytes = usize::from(module.target_config().pointer_bytes());
|
||||
personality_ref_data.define(vec![0; pointer_bytes].into_boxed_slice());
|
||||
let personality_func_ref =
|
||||
module.declare_func_in_data(personality, &mut personality_ref_data);
|
||||
personality_ref_data.write_function_addr(0, personality_func_ref);
|
||||
|
||||
module.define_data(personality_ref, &personality_ref_data).unwrap();
|
||||
|
||||
cie.personality = Some((code_ptr_encoding, address_for_data(personality_ref)));
|
||||
}
|
||||
|
||||
cie.personality = Some((code_ptr_encoding, address_for_data(personality_ref)));
|
||||
Some(frame_table.add_cie(cie))
|
||||
} else {
|
||||
None
|
||||
|
|
@ -134,88 +140,93 @@ impl UnwindContext {
|
|||
match unwind_info {
|
||||
UnwindInfo::SystemV(unwind_info) => {
|
||||
let mut fde = unwind_info.to_fde(address_for_func(func_id));
|
||||
// FIXME use unique symbol name derived from function name
|
||||
let lsda = module.declare_anonymous_data(false, false).unwrap();
|
||||
|
||||
let encoding = Encoding {
|
||||
format: Format::Dwarf32,
|
||||
version: 1,
|
||||
address_size: module.isa().frontend_config().pointer_bytes(),
|
||||
};
|
||||
// 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
|
||||
if cfg!(feature = "unwinding") {
|
||||
// FIXME use unique symbol name derived from function name
|
||||
let lsda = module.declare_anonymous_data(false, false).unwrap();
|
||||
|
||||
let mut gcc_except_table_data = GccExceptTable {
|
||||
call_sites: CallSiteTable(vec![]),
|
||||
actions: ActionTable::new(),
|
||||
type_info: TypeInfoTable::new(gimli::DW_EH_PE_udata4),
|
||||
};
|
||||
|
||||
let catch_type = gcc_except_table_data.type_info.add(Address::Constant(0));
|
||||
let catch_action = gcc_except_table_data
|
||||
.actions
|
||||
.add(Action { kind: ActionKind::Catch(catch_type), next_action: None });
|
||||
|
||||
for call_site in context.compiled_code().unwrap().buffer.call_sites() {
|
||||
if call_site.exception_handlers.is_empty() {
|
||||
gcc_except_table_data.call_sites.0.push(CallSite {
|
||||
start: u64::from(call_site.ret_addr - 1),
|
||||
length: 1,
|
||||
landing_pad: 0,
|
||||
action_entry: None,
|
||||
});
|
||||
}
|
||||
for &(tag, landingpad) in call_site.exception_handlers {
|
||||
match tag.expand().unwrap().as_u32() {
|
||||
EXCEPTION_HANDLER_CLEANUP => {
|
||||
gcc_except_table_data.call_sites.0.push(CallSite {
|
||||
start: u64::from(call_site.ret_addr - 1),
|
||||
length: 1,
|
||||
landing_pad: u64::from(landingpad),
|
||||
action_entry: None,
|
||||
})
|
||||
}
|
||||
EXCEPTION_HANDLER_CATCH => {
|
||||
gcc_except_table_data.call_sites.0.push(CallSite {
|
||||
start: u64::from(call_site.ret_addr - 1),
|
||||
length: 1,
|
||||
landing_pad: u64::from(landingpad),
|
||||
action_entry: Some(catch_action),
|
||||
})
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut gcc_except_table = super::emit::WriterRelocate::new(self.endian);
|
||||
|
||||
gcc_except_table_data.write(&mut gcc_except_table, encoding).unwrap();
|
||||
|
||||
let mut data = DataDescription::new();
|
||||
data.define(gcc_except_table.writer.into_vec().into_boxed_slice());
|
||||
data.set_segment_section("", ".gcc_except_table");
|
||||
|
||||
for reloc in &gcc_except_table.relocs {
|
||||
match reloc.name {
|
||||
DebugRelocName::Section(_id) => unreachable!(),
|
||||
DebugRelocName::Symbol(id) => {
|
||||
let id = id.try_into().unwrap();
|
||||
if id & 1 << 31 == 0 {
|
||||
let func_ref =
|
||||
module.declare_func_in_data(FuncId::from_u32(id), &mut data);
|
||||
data.write_function_addr(reloc.offset, func_ref);
|
||||
} else {
|
||||
let gv = module.declare_data_in_data(
|
||||
DataId::from_u32(id & !(1 << 31)),
|
||||
&mut data,
|
||||
);
|
||||
data.write_data_addr(reloc.offset, gv, 0);
|
||||
}
|
||||
}
|
||||
let encoding = Encoding {
|
||||
format: Format::Dwarf32,
|
||||
version: 1,
|
||||
address_size: module.isa().frontend_config().pointer_bytes(),
|
||||
};
|
||||
|
||||
let mut gcc_except_table_data = GccExceptTable {
|
||||
call_sites: CallSiteTable(vec![]),
|
||||
actions: ActionTable::new(),
|
||||
type_info: TypeInfoTable::new(gimli::DW_EH_PE_udata4),
|
||||
};
|
||||
|
||||
let catch_type = gcc_except_table_data.type_info.add(Address::Constant(0));
|
||||
let catch_action = gcc_except_table_data
|
||||
.actions
|
||||
.add(Action { kind: ActionKind::Catch(catch_type), next_action: None });
|
||||
|
||||
for call_site in context.compiled_code().unwrap().buffer.call_sites() {
|
||||
if call_site.exception_handlers.is_empty() {
|
||||
gcc_except_table_data.call_sites.0.push(CallSite {
|
||||
start: u64::from(call_site.ret_addr - 1),
|
||||
length: 1,
|
||||
landing_pad: 0,
|
||||
action_entry: None,
|
||||
});
|
||||
}
|
||||
for &(tag, landingpad) in call_site.exception_handlers {
|
||||
match tag.expand().unwrap().as_u32() {
|
||||
EXCEPTION_HANDLER_CLEANUP => {
|
||||
gcc_except_table_data.call_sites.0.push(CallSite {
|
||||
start: u64::from(call_site.ret_addr - 1),
|
||||
length: 1,
|
||||
landing_pad: u64::from(landingpad),
|
||||
action_entry: None,
|
||||
})
|
||||
}
|
||||
EXCEPTION_HANDLER_CATCH => {
|
||||
gcc_except_table_data.call_sites.0.push(CallSite {
|
||||
start: u64::from(call_site.ret_addr - 1),
|
||||
length: 1,
|
||||
landing_pad: u64::from(landingpad),
|
||||
action_entry: Some(catch_action),
|
||||
})
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut gcc_except_table = super::emit::WriterRelocate::new(self.endian);
|
||||
|
||||
gcc_except_table_data.write(&mut gcc_except_table, encoding).unwrap();
|
||||
|
||||
let mut data = DataDescription::new();
|
||||
data.define(gcc_except_table.writer.into_vec().into_boxed_slice());
|
||||
data.set_segment_section("", ".gcc_except_table");
|
||||
|
||||
for reloc in &gcc_except_table.relocs {
|
||||
match reloc.name {
|
||||
DebugRelocName::Section(_id) => unreachable!(),
|
||||
DebugRelocName::Symbol(id) => {
|
||||
let id = id.try_into().unwrap();
|
||||
if id & 1 << 31 == 0 {
|
||||
let func_ref = module
|
||||
.declare_func_in_data(FuncId::from_u32(id), &mut data);
|
||||
data.write_function_addr(reloc.offset, func_ref);
|
||||
} else {
|
||||
let gv = module.declare_data_in_data(
|
||||
DataId::from_u32(id & !(1 << 31)),
|
||||
&mut data,
|
||||
);
|
||||
data.write_data_addr(reloc.offset, gv, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.define_data(lsda, &data).unwrap();
|
||||
fde.lsda = Some(address_for_data(lsda));
|
||||
}
|
||||
|
||||
module.define_data(lsda, &data).unwrap();
|
||||
fde.lsda = Some(address_for_data(lsda));
|
||||
self.frame_table.add_fde(self.cie_id.unwrap(), fde);
|
||||
}
|
||||
UnwindInfo::WindowsX64(_) | UnwindInfo::WindowsArm64(_) => {
|
||||
|
|
|
|||
|
|
@ -1367,7 +1367,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
|||
returns: vec![],
|
||||
});
|
||||
|
||||
if fx.tcx.sess.panic_strategy() == PanicStrategy::Abort {
|
||||
if cfg!(not(feature = "unwinding"))
|
||||
|| fx.tcx.sess.panic_strategy() == PanicStrategy::Abort
|
||||
{
|
||||
fx.bcx.ins().call_indirect(f_sig, f, &[data]);
|
||||
|
||||
let layout = fx.layout_of(fx.tcx.types.i32);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue