mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-30 06:38:14 +00:00
Support OpenBSD's native frame protection conventions.
OpenBSD's stack smashing protection differs slightly from other platforms: 1. The smash handler function is "__stack_smash_handler(const char *funcname)" instead of "__stack_chk_fail(void)". 2. There's a hidden "long __guard_local" object that gets linked into each executable and DSO. Patch by Matthew Dempsky. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183533 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
47b0c0a9a0
commit
62ed8d3e35
@ -25,6 +25,8 @@
|
|||||||
#include "llvm/IR/DataLayout.h"
|
#include "llvm/IR/DataLayout.h"
|
||||||
#include "llvm/IR/DerivedTypes.h"
|
#include "llvm/IR/DerivedTypes.h"
|
||||||
#include "llvm/IR/Function.h"
|
#include "llvm/IR/Function.h"
|
||||||
|
#include "llvm/IR/GlobalValue.h"
|
||||||
|
#include "llvm/IR/GlobalVariable.h"
|
||||||
#include "llvm/IR/Instructions.h"
|
#include "llvm/IR/Instructions.h"
|
||||||
#include "llvm/IR/Intrinsics.h"
|
#include "llvm/IR/Intrinsics.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
@ -41,7 +43,8 @@ namespace {
|
|||||||
class StackProtector : public FunctionPass {
|
class StackProtector : public FunctionPass {
|
||||||
/// TLI - Keep a pointer of a TargetLowering to consult for determining
|
/// TLI - Keep a pointer of a TargetLowering to consult for determining
|
||||||
/// target type sizes.
|
/// target type sizes.
|
||||||
const TargetLoweringBase *TLI;
|
const TargetLoweringBase *const TLI;
|
||||||
|
const Triple Trip;
|
||||||
|
|
||||||
Function *F;
|
Function *F;
|
||||||
Module *M;
|
Module *M;
|
||||||
@ -84,7 +87,8 @@ namespace {
|
|||||||
initializeStackProtectorPass(*PassRegistry::getPassRegistry());
|
initializeStackProtectorPass(*PassRegistry::getPassRegistry());
|
||||||
}
|
}
|
||||||
StackProtector(const TargetLoweringBase *tli)
|
StackProtector(const TargetLoweringBase *tli)
|
||||||
: FunctionPass(ID), TLI(tli) {
|
: FunctionPass(ID), TLI(tli),
|
||||||
|
Trip(tli->getTargetMachine().getTargetTriple()) {
|
||||||
initializeStackProtectorPass(*PassRegistry::getPassRegistry());
|
initializeStackProtectorPass(*PassRegistry::getPassRegistry());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,8 +132,6 @@ bool StackProtector::ContainsProtectableArray(Type *Ty, bool Strong,
|
|||||||
return true;
|
return true;
|
||||||
const TargetMachine &TM = TLI->getTargetMachine();
|
const TargetMachine &TM = TLI->getTargetMachine();
|
||||||
if (!AT->getElementType()->isIntegerTy(8)) {
|
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
|
// 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.
|
// add stack protectors unless the array is a character array.
|
||||||
if (InStruct || !Trip.isOSDarwin())
|
if (InStruct || !Trip.isOSDarwin())
|
||||||
@ -283,6 +285,10 @@ bool StackProtector::InsertStackProtectors() {
|
|||||||
|
|
||||||
StackGuardVar = ConstantExpr::getIntToPtr(OffsetVal,
|
StackGuardVar = ConstantExpr::getIntToPtr(OffsetVal,
|
||||||
PointerType::get(PtrTy, AddressSpace));
|
PointerType::get(PtrTy, AddressSpace));
|
||||||
|
} else if (Trip.getOS() == llvm::Triple::OpenBSD) {
|
||||||
|
StackGuardVar = M->getOrInsertGlobal("__guard_local", PtrTy);
|
||||||
|
cast<GlobalValue>(StackGuardVar)
|
||||||
|
->setVisibility(GlobalValue::HiddenVisibility);
|
||||||
} else {
|
} else {
|
||||||
StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy);
|
StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy);
|
||||||
}
|
}
|
||||||
@ -359,12 +365,31 @@ bool StackProtector::InsertStackProtectors() {
|
|||||||
/// CreateFailBB - Create a basic block to jump to when the stack protector
|
/// CreateFailBB - Create a basic block to jump to when the stack protector
|
||||||
/// check fails.
|
/// check fails.
|
||||||
BasicBlock *StackProtector::CreateFailBB() {
|
BasicBlock *StackProtector::CreateFailBB() {
|
||||||
BasicBlock *FailBB = BasicBlock::Create(F->getContext(),
|
LLVMContext &Context = F->getContext();
|
||||||
"CallStackCheckFailBlk", F);
|
BasicBlock *FailBB = BasicBlock::Create(Context, "CallStackCheckFailBlk", F);
|
||||||
Constant *StackChkFail =
|
if (Trip.getOS() == llvm::Triple::OpenBSD) {
|
||||||
M->getOrInsertFunction("__stack_chk_fail",
|
Constant *StackChkFail = M->getOrInsertFunction(
|
||||||
Type::getVoidTy(F->getContext()), NULL);
|
"__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);
|
CallInst::Create(StackChkFail, "", FailBB);
|
||||||
new UnreachableInst(F->getContext(), FailBB);
|
}
|
||||||
|
new UnreachableInst(Context, FailBB);
|
||||||
return FailBB;
|
return FailBB;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck --check-prefix=LINUX-X64 %s
|
; 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 -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=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 = type { [16 x i8] }
|
||||||
%struct.foo.0 = type { [4 x i8] }
|
%struct.foo.0 = type { [4 x i8] }
|
||||||
@ -69,6 +70,10 @@ entry:
|
|||||||
; DARWIN-X64: test1b:
|
; DARWIN-X64: test1b:
|
||||||
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
|
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
|
||||||
; DARWIN-X64: callq ___stack_chk_fail
|
; 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
|
%a.addr = alloca i8*, align 8
|
||||||
%buf = alloca [16 x i8], align 16
|
%buf = alloca [16 x i8], align 16
|
||||||
store i8* %a, i8** %a.addr, align 8
|
store i8* %a, i8** %a.addr, align 8
|
||||||
|
Loading…
x
Reference in New Issue
Block a user