Control LLVM's TrapUnreachable feature through rustc's TargetOptions.
This commit is contained in:
parent
365c159b80
commit
7b6b764917
@ -435,6 +435,10 @@ pub struct TargetOptions {
|
||||
|
||||
/// Default number of codegen units to use in debug mode
|
||||
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 {
|
||||
@ -498,6 +502,7 @@ impl Default for TargetOptions {
|
||||
stack_probes: false,
|
||||
min_global_align: None,
|
||||
default_codegen_units: None,
|
||||
trap_unreachable: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -739,6 +744,7 @@ impl Target {
|
||||
key!(stack_probes, bool);
|
||||
key!(min_global_align, 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) {
|
||||
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!(min_global_align);
|
||||
target_option_val!(default_codegen_units);
|
||||
target_option_val!(trap_unreachable);
|
||||
|
||||
if default.abi_blacklist != self.options.abi_blacklist {
|
||||
d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()
|
||||
|
@ -1605,7 +1605,8 @@ extern "C" {
|
||||
UseSoftFP: bool,
|
||||
PositionIndependentExecutable: bool,
|
||||
FunctionSections: bool,
|
||||
DataSections: bool)
|
||||
DataSections: bool,
|
||||
TrapUnreachable: bool)
|
||||
-> TargetMachineRef;
|
||||
pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef);
|
||||
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 features = CString::new(target_feature(sess).as_bytes()).unwrap();
|
||||
let is_pie_binary = is_pie_binary(sess);
|
||||
let trap_unreachable = sess.target.target.options.trap_unreachable;
|
||||
|
||||
Arc::new(move || {
|
||||
let tm = unsafe {
|
||||
@ -208,6 +209,7 @@ pub fn target_machine_factory(sess: &Session)
|
||||
is_pie_binary,
|
||||
ffunction_sections,
|
||||
fdata_sections,
|
||||
trap_unreachable,
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -366,7 +366,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
||||
LLVMRustCodeModel RustCM, LLVMRustRelocMode RustReloc,
|
||||
LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
|
||||
bool PositionIndependentExecutable, bool FunctionSections,
|
||||
bool DataSections) {
|
||||
bool DataSections, bool TrapUnreachable) {
|
||||
|
||||
auto CM = fromRust(RustCM);
|
||||
auto OptLevel = fromRust(RustOptLevel);
|
||||
@ -398,11 +398,13 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
||||
Options.DataSections = DataSections;
|
||||
Options.FunctionSections = FunctionSections;
|
||||
|
||||
// Tell LLVM to translate `unreachable` into an explicit trap instruction.
|
||||
// This limits the extent of possible undefined behavior in some cases, as it
|
||||
// prevents control flow from "falling through" into whatever code happens to
|
||||
// be laid out next in memory.
|
||||
Options.TrapUnreachable = true;
|
||||
if (TrapUnreachable) {
|
||||
// Tell LLVM to translate `unreachable` into an explicit trap instruction.
|
||||
// This limits the extent of possible undefined behavior in some cases, as
|
||||
// it prevents control flow from "falling through" into whatever code
|
||||
// happens to be laid out next in memory.
|
||||
Options.TrapUnreachable = true;
|
||||
}
|
||||
|
||||
TargetMachine *TM = TheTarget->createTargetMachine(
|
||||
Trip.getTriple(), RealCPU, Feature, Options, RM, CM, OptLevel);
|
||||
|
Loading…
x
Reference in New Issue
Block a user