mlemay-intel created this revision.
mlemay-intel added reviewers: pcc, eugenis.
mlemay-intel added a subscriber: cfe-commits.

SafeStack uses thread-local storage by default in most OSes for the unsafe stack
pointer. For SafeStack to be applied to functions that may be invoked while
initializing the dynamic linker and libc, the functions can be compiled to
support a single-threaded unsafe stack pointer. This flag signals that such code
should be emitted.

http://reviews.llvm.org/D19853

Files:
  docs/CommandGuide/clang.rst
  include/clang/Basic/LangOptions.def
  include/clang/Driver/Options.td
  lib/CodeGen/CGDeclCXX.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/Driver/Tools.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/runtime-init-attr.c

Index: test/CodeGen/runtime-init-attr.c
===================================================================
--- /dev/null
+++ test/CodeGen/runtime-init-attr.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s -fruntime-init | FileCheck -check-prefix=DEF -check-prefix=CHECK %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s -fruntime-init -fsanitize=safe-stack | FileCheck -check-prefix=DEF -check-prefix=SAFESTACK %s
+
+// DEF: define {{.*}}void @test1() #[[A:.*]] {
+void test1() {
+}
+
+// CHECK: attributes #[[A]] = {{.*}} runtime_init
+// SAFESTACK: attributes #[[A]] = {{.*}} runtime_init safestack
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -1730,6 +1730,7 @@
   if (!Opts.NoBuiltin)
     getAllNoBuiltinFuncValues(Args, Opts.NoBuiltinFuncs);
   Opts.NoMathBuiltin = Args.hasArg(OPT_fno_math_builtin);
+  Opts.RuntimeInit = Args.hasArg(OPT_fruntime_init);
   Opts.SizedDeallocation = Args.hasArg(OPT_fsized_deallocation);
   Opts.ConceptsTS = Args.hasArg(OPT_fconcepts_ts);
   Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -4777,6 +4777,9 @@
       KernelOrKext)
     CmdArgs.push_back("-ffreestanding");
 
+  if (Args.hasArg(options::OPT_fruntime_init))
+    CmdArgs.push_back("-fruntime-init");
+
   // Forward -f (flag) options which we can pass directly.
   Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
   Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -698,6 +698,9 @@
   if (SanOpts.has(SanitizerKind::SafeStack))
     Fn->addFnAttr(llvm::Attribute::SafeStack);
 
+  if (getLangOpts().RuntimeInit)
+    Fn->addFnAttr(llvm::Attribute::RuntimeInit);
+
   // Pass inline keyword to optimizer if it appears explicitly on any
   // declaration. Also, in the case of -fno-inline attach NoInline
   // attribute to all function that are not marked AlwaysInline.
Index: lib/CodeGen/CGDeclCXX.cpp
===================================================================
--- lib/CodeGen/CGDeclCXX.cpp
+++ lib/CodeGen/CGDeclCXX.cpp
@@ -279,6 +279,9 @@
       Fn->addFnAttr(llvm::Attribute::SafeStack);
   }
 
+  if (getLangOpts().RuntimeInit)
+    Fn->addFnAttr(llvm::Attribute::RuntimeInit);
+
   return Fn;
 }
 
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -1031,6 +1031,7 @@
 def freg_struct_return : Flag<["-"], "freg-struct-return">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Override the default ABI to return small structs in registers">;
 def frtti : Flag<["-"], "frtti">, Group<f_Group>;
+def fruntime_init : Flag<["-"], "fruntime-init">, Group<f_Group>, Flags<[CC1Option]>;
 def : Flag<["-"], "fsched-interblock">, Group<clang_ignored_f_Group>;
 def fshort_enums : Flag<["-"], "fshort-enums">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Allocate to an enum type only as many bytes as it needs for the declared range of possible values">;
Index: include/clang/Basic/LangOptions.def
===================================================================
--- include/clang/Basic/LangOptions.def
+++ include/clang/Basic/LangOptions.def
@@ -132,6 +132,7 @@
 LANGOPT(Freestanding, 1, 0, "freestanding implementation")
 LANGOPT(NoBuiltin         , 1, 0, "disable builtin functions")
 LANGOPT(NoMathBuiltin     , 1, 0, "disable math builtin functions")
+LANGOPT(RuntimeInit       , 1, 0, "used during runtime initialization")
 LANGOPT(GNUAsm            , 1, 1, "GNU-style inline assembly")
 LANGOPT(Coroutines        , 1, 0, "C++ coroutines")
 
Index: docs/CommandGuide/clang.rst
===================================================================
--- docs/CommandGuide/clang.rst
+++ docs/CommandGuide/clang.rst
@@ -313,6 +313,13 @@
   model can be overridden with the tls_model attribute. The compiler will try
   to choose a more efficient model if possible.
 
+.. option:: -fruntime-init
+
+  Emit code for functions that permits them to be used both during and after
+  initialization of the runtime environment. This is only meaningful when
+  combined with the SafeStack pass. See the documentation associated with that
+  pass for more details.
+
 .. option:: -flto, -emit-llvm
 
   Generate output files in LLVM formats, suitable for link time optimization.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to