Control LLVM's TrapUnreachable feature through rustc's TargetOptions.
This commit is contained in:
parent
365c159b80
commit
7b6b764917
4 changed files with 19 additions and 7 deletions
|
@ -435,6 +435,10 @@ pub struct TargetOptions {
|
||||||
|
|
||||||
/// Default number of codegen units to use in debug mode
|
/// Default number of codegen units to use in debug mode
|
||||||
pub default_codegen_units: Option<u64>,
|
pub default_codegen_units: Option<u64>,
|
||||||
|
|
||||||
|
/// Whether to generate trap instructions in places where optimization would
|
||||||
|
/// otherwise produce control flow that falls through into unrelated memory.
|
||||||
|
pub trap_unreachable: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TargetOptions {
|
impl Default for TargetOptions {
|
||||||
|
@ -498,6 +502,7 @@ impl Default for TargetOptions {
|
||||||
stack_probes: false,
|
stack_probes: false,
|
||||||
min_global_align: None,
|
min_global_align: None,
|
||||||
default_codegen_units: None,
|
default_codegen_units: None,
|
||||||
|
trap_unreachable: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -739,6 +744,7 @@ impl Target {
|
||||||
key!(stack_probes, bool);
|
key!(stack_probes, bool);
|
||||||
key!(min_global_align, Option<u64>);
|
key!(min_global_align, Option<u64>);
|
||||||
key!(default_codegen_units, Option<u64>);
|
key!(default_codegen_units, Option<u64>);
|
||||||
|
key!(trap_unreachable, bool);
|
||||||
|
|
||||||
if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
|
if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
|
||||||
for name in array.iter().filter_map(|abi| abi.as_string()) {
|
for name in array.iter().filter_map(|abi| abi.as_string()) {
|
||||||
|
@ -932,6 +938,7 @@ impl ToJson for Target {
|
||||||
target_option_val!(stack_probes);
|
target_option_val!(stack_probes);
|
||||||
target_option_val!(min_global_align);
|
target_option_val!(min_global_align);
|
||||||
target_option_val!(default_codegen_units);
|
target_option_val!(default_codegen_units);
|
||||||
|
target_option_val!(trap_unreachable);
|
||||||
|
|
||||||
if default.abi_blacklist != self.options.abi_blacklist {
|
if default.abi_blacklist != self.options.abi_blacklist {
|
||||||
d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()
|
d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()
|
||||||
|
|
|
@ -1605,7 +1605,8 @@ extern "C" {
|
||||||
UseSoftFP: bool,
|
UseSoftFP: bool,
|
||||||
PositionIndependentExecutable: bool,
|
PositionIndependentExecutable: bool,
|
||||||
FunctionSections: bool,
|
FunctionSections: bool,
|
||||||
DataSections: bool)
|
DataSections: bool,
|
||||||
|
TrapUnreachable: bool)
|
||||||
-> TargetMachineRef;
|
-> TargetMachineRef;
|
||||||
pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef);
|
pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef);
|
||||||
pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef, PM: PassManagerRef, M: ModuleRef);
|
pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef, PM: PassManagerRef, M: ModuleRef);
|
||||||
|
|
|
@ -196,6 +196,7 @@ pub fn target_machine_factory(sess: &Session)
|
||||||
let cpu = CString::new(cpu.as_bytes()).unwrap();
|
let cpu = CString::new(cpu.as_bytes()).unwrap();
|
||||||
let features = CString::new(target_feature(sess).as_bytes()).unwrap();
|
let features = CString::new(target_feature(sess).as_bytes()).unwrap();
|
||||||
let is_pie_binary = is_pie_binary(sess);
|
let is_pie_binary = is_pie_binary(sess);
|
||||||
|
let trap_unreachable = sess.target.target.options.trap_unreachable;
|
||||||
|
|
||||||
Arc::new(move || {
|
Arc::new(move || {
|
||||||
let tm = unsafe {
|
let tm = unsafe {
|
||||||
|
@ -208,6 +209,7 @@ pub fn target_machine_factory(sess: &Session)
|
||||||
is_pie_binary,
|
is_pie_binary,
|
||||||
ffunction_sections,
|
ffunction_sections,
|
||||||
fdata_sections,
|
fdata_sections,
|
||||||
|
trap_unreachable,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -366,7 +366,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
||||||
LLVMRustCodeModel RustCM, LLVMRustRelocMode RustReloc,
|
LLVMRustCodeModel RustCM, LLVMRustRelocMode RustReloc,
|
||||||
LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
|
LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
|
||||||
bool PositionIndependentExecutable, bool FunctionSections,
|
bool PositionIndependentExecutable, bool FunctionSections,
|
||||||
bool DataSections) {
|
bool DataSections, bool TrapUnreachable) {
|
||||||
|
|
||||||
auto CM = fromRust(RustCM);
|
auto CM = fromRust(RustCM);
|
||||||
auto OptLevel = fromRust(RustOptLevel);
|
auto OptLevel = fromRust(RustOptLevel);
|
||||||
|
@ -398,11 +398,13 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
||||||
Options.DataSections = DataSections;
|
Options.DataSections = DataSections;
|
||||||
Options.FunctionSections = FunctionSections;
|
Options.FunctionSections = FunctionSections;
|
||||||
|
|
||||||
|
if (TrapUnreachable) {
|
||||||
// Tell LLVM to translate `unreachable` into an explicit trap instruction.
|
// Tell LLVM to translate `unreachable` into an explicit trap instruction.
|
||||||
// This limits the extent of possible undefined behavior in some cases, as it
|
// This limits the extent of possible undefined behavior in some cases, as
|
||||||
// prevents control flow from "falling through" into whatever code happens to
|
// it prevents control flow from "falling through" into whatever code
|
||||||
// be laid out next in memory.
|
// happens to be laid out next in memory.
|
||||||
Options.TrapUnreachable = true;
|
Options.TrapUnreachable = true;
|
||||||
|
}
|
||||||
|
|
||||||
TargetMachine *TM = TheTarget->createTargetMachine(
|
TargetMachine *TM = TheTarget->createTargetMachine(
|
||||||
Trip.getTriple(), RealCPU, Feature, Options, RM, CM, OptLevel);
|
Trip.getTriple(), RealCPU, Feature, Options, RM, CM, OptLevel);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue