Index: include/llvm/ADT/Triple.h =================================================================== --- include/llvm/ADT/Triple.h +++ include/llvm/ADT/Triple.h @@ -163,6 +163,7 @@ AMDHSA, // AMD HSA Runtime PS4, ELFIAMCU, + Contiki, TvOS, // Apple tvOS WatchOS, // Apple watchOS Mesa3D, @@ -469,6 +470,10 @@ return getOS() == Triple::ELFIAMCU; } + bool isOSContiki() const { + return getOS() == Triple::Contiki; + } + /// Checks if the environment could be MSVC. bool isWindowsMSVCEnvironment() const { return getOS() == Triple::Win32 && Index: lib/CodeGen/SafeStack.cpp =================================================================== --- lib/CodeGen/SafeStack.cpp +++ lib/CodeGen/SafeStack.cpp @@ -50,17 +50,6 @@ #define DEBUG_TYPE "safestack" -enum UnsafeStackPtrStorageVal { ThreadLocalUSP, SingleThreadUSP }; - -static cl::opt USPStorage("safe-stack-usp-storage", - cl::Hidden, cl::init(ThreadLocalUSP), - cl::desc("Type of storage for the unsafe stack pointer"), - cl::values(clEnumValN(ThreadLocalUSP, "thread-local", - "Thread-local storage"), - clEnumValN(SingleThreadUSP, "single-thread", - "Non-thread-local storage"), - clEnumValEnd)); - namespace llvm { STATISTIC(NumFunctions, "Total number of functions"); @@ -367,25 +356,19 @@ auto UnsafeStackPtr = dyn_cast_or_null(M.getNamedValue(UnsafeStackPtrVar)); - bool UseTLS = USPStorage == ThreadLocalUSP; - if (!UnsafeStackPtr) { - auto TLSModel = UseTLS ? - GlobalValue::InitialExecTLSModel : - GlobalValue::NotThreadLocal; // The global variable is not defined yet, define it ourselves. // We use the initial-exec TLS model because we do not support the // variable living anywhere other than in the main executable. UnsafeStackPtr = new GlobalVariable( M, StackPtrTy, false, GlobalValue::ExternalLinkage, nullptr, - UnsafeStackPtrVar, nullptr, TLSModel); + UnsafeStackPtrVar, nullptr, GlobalValue::InitialExecTLSModel); } else { // The variable exists, check its type and attributes. if (UnsafeStackPtr->getValueType() != StackPtrTy) report_fatal_error(Twine(UnsafeStackPtrVar) + " must have void* type"); - if (UseTLS != UnsafeStackPtr->isThreadLocal()) - report_fatal_error(Twine(UnsafeStackPtrVar) + " must " + - (UseTLS ? "" : "not ") + "be thread-local"); + if (!UnsafeStackPtr->isThreadLocal()) + report_fatal_error(Twine(UnsafeStackPtrVar) + " must be thread-local"); } return UnsafeStackPtr; } Index: lib/Support/Triple.cpp =================================================================== --- lib/Support/Triple.cpp +++ lib/Support/Triple.cpp @@ -186,6 +186,7 @@ case AMDHSA: return "amdhsa"; case PS4: return "ps4"; case ELFIAMCU: return "elfiamcu"; + case Contiki: return "contiki"; case TvOS: return "tvos"; case WatchOS: return "watchos"; case Mesa3D: return "mesa3d"; @@ -448,6 +449,7 @@ .StartsWith("amdhsa", Triple::AMDHSA) .StartsWith("ps4", Triple::PS4) .StartsWith("elfiamcu", Triple::ELFIAMCU) + .StartsWith("contiki", Triple::Contiki) .StartsWith("tvos", Triple::TvOS) .StartsWith("watchos", Triple::WatchOS) .StartsWith("mesa3d", Triple::Mesa3D) Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -1937,6 +1937,25 @@ } Value *X86TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const { + if (Subtarget.isTargetContiki()) { + const char *Name = "__safestack_unsafe_stack_ptr"; + auto StackPtrTy = Type::getInt8PtrTy(IRB.getContext()); + Module &M = *IRB.GetInsertBlock()->getParent()->getParent(); + GlobalVariable *V = dyn_cast_or_null(M.getNamedValue(Name)); + if (!V) { + // The global variable is not defined yet, define it ourselves. + V = new GlobalVariable( + M, StackPtrTy, false, GlobalValue::ExternalLinkage, nullptr, Name); + } else { + // The variable exists, check its type and attributes. + if (V->getValueType() != StackPtrTy) + report_fatal_error(Twine(Name) + " must have void* type"); + if (V->isThreadLocal()) + report_fatal_error(Twine(Name) + " must not be thread-local"); + } + return V; + } + if (!Subtarget.isTargetAndroid()) return TargetLowering::getSafeStackPointerLocation(IRB); Index: lib/Target/X86/X86Subtarget.h =================================================================== --- lib/Target/X86/X86Subtarget.h +++ lib/Target/X86/X86Subtarget.h @@ -472,6 +472,7 @@ bool isTargetNaCl32() const { return isTargetNaCl() && !is64Bit(); } bool isTargetNaCl64() const { return isTargetNaCl() && is64Bit(); } bool isTargetMCU() const { return TargetTriple.isOSIAMCU(); } + bool isTargetContiki() const { return TargetTriple.isOSContiki(); } bool isTargetWindowsMSVC() const { return TargetTriple.isWindowsMSVCEnvironment(); Index: test/Transforms/SafeStack/array.ll =================================================================== --- test/Transforms/SafeStack/array.ll +++ test/Transforms/SafeStack/array.ll @@ -1,7 +1,6 @@ ; RUN: opt -safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck %s -; RUN: opt -safe-stack -safe-stack-usp-storage=single-thread -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck -check-prefix=SINGLE-THREAD %s +; RUN: opt -safe-stack -S -mtriple=i386-pc-contiki-gnu < %s -o - | FileCheck -check-prefix=SINGLE-THREAD %s ; RUN: opt -safe-stack -S -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck %s -; RUN: opt -safe-stack -safe-stack-usp-storage=single-thread -S -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck -check-prefix=SINGLE-THREAD %s ; array [4 x i8] ; Requires protector.