Support OpenBSD's native frame protection conventions

Matthew Dempsky matthew at dempsky.org
Thu Jun 6 11:56:58 PDT 2013


Ping?  Anything else I need to do for this patch?

(I'm not an LLVM committer.)

On Mon, Jun 03, 2013 at 12:20:45PM -0700, Matthew Dempsky wrote:
> Thanks for the review!  Updated patch below.
> 
> Index: lib/CodeGen/StackProtector.cpp
> ===================================================================
> --- lib/CodeGen/StackProtector.cpp	(revision 183062)
> +++ lib/CodeGen/StackProtector.cpp	(working copy)
> @@ -25,6 +25,8 @@
>  #include "llvm/IR/DataLayout.h"
>  #include "llvm/IR/DerivedTypes.h"
>  #include "llvm/IR/Function.h"
> +#include "llvm/IR/GlobalValue.h"
> +#include "llvm/IR/GlobalVariable.h"
>  #include "llvm/IR/Instructions.h"
>  #include "llvm/IR/Intrinsics.h"
>  #include "llvm/IR/Module.h"
> @@ -41,7 +43,8 @@
>    class StackProtector : public FunctionPass {
>      /// TLI - Keep a pointer of a TargetLowering to consult for determining
>      /// target type sizes.
> -    const TargetLoweringBase *TLI;
> +    const TargetLoweringBase *const TLI;
> +    const Triple Trip;
>  
>      Function *F;
>      Module *M;
> @@ -84,7 +87,8 @@
>        initializeStackProtectorPass(*PassRegistry::getPassRegistry());
>      }
>      StackProtector(const TargetLoweringBase *tli)
> -      : FunctionPass(ID), TLI(tli) {
> +        : FunctionPass(ID), TLI(tli),
> +          Trip(tli->getTargetMachine().getTargetTriple()) {
>        initializeStackProtectorPass(*PassRegistry::getPassRegistry());
>      }
>  
> @@ -128,8 +132,6 @@
>        return true;
>      const TargetMachine &TM = TLI->getTargetMachine();
>      if (!AT->getElementType()->isIntegerTy(8)) {
> -      Triple Trip(TM.getTargetTriple());
> -
>        // If we're on a non-Darwin platform or we're inside of a structure, don't
>        // add stack protectors unless the array is a character array.
>        if (InStruct || !Trip.isOSDarwin())
> @@ -283,6 +285,10 @@
>  
>          StackGuardVar = ConstantExpr::getIntToPtr(OffsetVal,
>                                        PointerType::get(PtrTy, AddressSpace));
> +      } else if (Trip.getOS() == llvm::Triple::OpenBSD) {
> +        StackGuardVar = M->getOrInsertGlobal("__guard_local", PtrTy);
> +        cast<GlobalValue>(StackGuardVar)
> +            ->setVisibility(GlobalValue::HiddenVisibility);
>        } else {
>          StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy);
>        }
> @@ -359,12 +365,31 @@
>  /// CreateFailBB - Create a basic block to jump to when the stack protector
>  /// check fails.
>  BasicBlock *StackProtector::CreateFailBB() {
> -  BasicBlock *FailBB = BasicBlock::Create(F->getContext(),
> -                                          "CallStackCheckFailBlk", F);
> -  Constant *StackChkFail =
> -    M->getOrInsertFunction("__stack_chk_fail",
> -                           Type::getVoidTy(F->getContext()), NULL);
> -  CallInst::Create(StackChkFail, "", FailBB);
> -  new UnreachableInst(F->getContext(), FailBB);
> +  LLVMContext &Context = F->getContext();
> +  BasicBlock *FailBB = BasicBlock::Create(Context, "CallStackCheckFailBlk", F);
> +  if (Trip.getOS() == llvm::Triple::OpenBSD) {
> +    Constant *StackChkFail = M->getOrInsertFunction(
> +        "__stack_smash_handler", Type::getVoidTy(Context),
> +        Type::getInt8PtrTy(Context), NULL);
> +
> +    Constant *NameStr = ConstantDataArray::getString(Context, F->getName());
> +    Constant *FuncName =
> +        new GlobalVariable(*M, NameStr->getType(), true,
> +                           GlobalVariable::PrivateLinkage, NameStr, "SSH");
> +
> +    SmallVector<Constant *, 2> IdxList;
> +    IdxList.push_back(ConstantInt::get(Type::getInt8Ty(Context), 0));
> +    IdxList.push_back(ConstantInt::get(Type::getInt8Ty(Context), 0));
> +
> +    SmallVector<Value *, 1> Args;
> +    Args.push_back(ConstantExpr::getGetElementPtr(FuncName, IdxList));
> +
> +    CallInst::Create(StackChkFail, Args, "", FailBB);
> +  } else {
> +    Constant *StackChkFail = M->getOrInsertFunction(
> +        "__stack_chk_fail", Type::getVoidTy(Context), NULL);
> +    CallInst::Create(StackChkFail, "", FailBB);
> +  }
> +  new UnreachableInst(Context, FailBB);
>    return FailBB;
>  }
> Index: test/CodeGen/X86/stack-protector.ll
> ===================================================================
> --- test/CodeGen/X86/stack-protector.ll	(revision 183062)
> +++ test/CodeGen/X86/stack-protector.ll	(working copy)
> @@ -2,6 +2,7 @@
>  ; RUN: llc -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck --check-prefix=LINUX-X64 %s
>  ; RUN: llc -code-model=kernel -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck --check-prefix=LINUX-KERNEL-X64 %s
>  ; RUN: llc -mtriple=x86_64-apple-darwin < %s -o - | FileCheck --check-prefix=DARWIN-X64 %s
> +; RUN: llc -mtriple=amd64-pc-openbsd < %s -o - | FileCheck --check-prefix=OPENBSD-AMD64 %s
>  
>  %struct.foo = type { [16 x i8] }
>  %struct.foo.0 = type { [4 x i8] }
> @@ -69,6 +70,10 @@
>  ; DARWIN-X64: test1b:
>  ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
>  ; DARWIN-X64: callq ___stack_chk_fail
> +
> +; OPENBSD-AMD64: test1b:
> +; OPENBSD-AMD64: movq __guard_local(%rip)
> +; OPENBSD-AMD64: callq __stack_smash_handler
>    %a.addr = alloca i8*, align 8
>    %buf = alloca [16 x i8], align 16
>    store i8* %a, i8** %a.addr, align 8



More information about the llvm-commits mailing list