diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 06922d986b3..59b40e9e2dc 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1053,6 +1053,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, 2 = full debug info with variable and type information"), opt_level: Option = (None, parse_opt_string, [TRACKED], "optimize with possible levels 0-3, s, or z"), + force_frame_pointers: Option = (None, parse_opt_bool, [TRACKED], + "force use of the frame pointers"), debug_assertions: Option = (None, parse_opt_bool, [TRACKED], "explicitly enable the cfg(debug_assertions) directive"), inline_threshold: Option = (None, parse_opt_uint, [TRACKED], @@ -2965,6 +2967,10 @@ mod tests { opts.cg.debuginfo = Some(0xba5eba11); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); + opts = reference.clone(); + opts.cg.force_frame_pointers = Some(false); + assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); + opts = reference.clone(); opts.cg.debug_assertions = Some(true); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 37a6b2e79f7..2ab72ba20bf 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -20,7 +20,7 @@ use lint::builtin::BuiltinLintDiagnostics; use middle::allocator::AllocatorKind; use middle::dependency_format; use session::search_paths::PathKind; -use session::config::{DebugInfoLevel, OutputType}; +use session::config::{OutputType}; use ty::tls; use util::nodemap::{FxHashSet}; use util::common::{duration_to_secs_str, ErrorReported}; @@ -658,8 +658,11 @@ impl Session { } pub fn must_not_eliminate_frame_pointers(&self) -> bool { - self.opts.debuginfo != DebugInfoLevel::NoDebugInfo - || !self.target.target.options.eliminate_frame_pointer + if let Some(x) = self.opts.cg.force_frame_pointers { + x + } else { + !self.target.target.options.eliminate_frame_pointer + } } /// Returns the symbol name for the registrar function, diff --git a/src/librustc_target/spec/apple_ios_base.rs b/src/librustc_target/spec/apple_ios_base.rs index acbbab313fe..46bb01e7c42 100644 --- a/src/librustc_target/spec/apple_ios_base.rs +++ b/src/librustc_target/spec/apple_ios_base.rs @@ -98,6 +98,7 @@ pub fn opts(arch: Arch) -> Result { executables: true, pre_link_args, has_elf_tls: false, + eliminate_frame_pointer: false, // The following line is a workaround for jemalloc 4.5 being broken on // ios. jemalloc 5.0 is supposed to fix this. // see https://github.com/rust-lang/rust/issues/45262 diff --git a/src/librustc_target/spec/i686_apple_darwin.rs b/src/librustc_target/spec/i686_apple_darwin.rs index 06ea1e4649b..d17789dfcc0 100644 --- a/src/librustc_target/spec/i686_apple_darwin.rs +++ b/src/librustc_target/spec/i686_apple_darwin.rs @@ -16,6 +16,7 @@ pub fn target() -> TargetResult { base.max_atomic_width = Some(64); base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]); base.stack_probes = true; + base.eliminate_frame_pointer = false; Ok(Target { llvm_target: "i686-apple-darwin".to_string(), diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index f455c19cc0b..5baed57092d 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -69,8 +69,6 @@ pub fn naked(val: ValueRef, is_naked: bool) { } pub fn set_frame_pointer_elimination(cx: &CodegenCx, llfn: ValueRef) { - // FIXME: #11906: Omitting frame pointers breaks retrieving the value of a - // parameter. if cx.sess().must_not_eliminate_frame_pointers() { llvm::AddFunctionAttrStringValue( llfn, llvm::AttributePlace::Function, diff --git a/src/test/codegen/force-frame-pointers.rs b/src/test/codegen/force-frame-pointers.rs new file mode 100644 index 00000000000..f70e3667198 --- /dev/null +++ b/src/test/codegen/force-frame-pointers.rs @@ -0,0 +1,16 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +// +// compile-flags: -C no-prepopulate-passes -C force-frame-pointers=y + +#![crate_type="lib"] + +// CHECK: attributes #{{.*}} "no-frame-pointer-elim"="true" +pub fn foo() {} diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs index 2b82a894363..7bcb4e5ec2d 100644 --- a/src/test/run-pass/backtrace-debuginfo.rs +++ b/src/test/run-pass/backtrace-debuginfo.rs @@ -16,6 +16,7 @@ // "enable" to 0 instead. // compile-flags:-g -Cllvm-args=-enable-tail-merge=0 -Cllvm-args=-opt-bisect-limit=0 +// compile-flags:-Cforce-frame-pointers=yes // ignore-pretty issue #37195 // ignore-cloudabi spawning processes is not supported // ignore-emscripten spawning processes is not supported