blob: 48de998e6af49b292c6acc7ab6c525b34fc07c5b [file] [log] [blame]
//=== SoftBound/InitializeSoftBound.cpp - Helper Pass for SoftBound/CETS --*- C++ -*===//
// Copyright (c) 2011 Santosh Nagarakatte, Milo M. K. Martin. All rights reserved.
// Developed by: Santosh Nagarakatte, Milo M.K. Martin,
// Jianzhou Zhao, Steve Zdancewic
// Department of Computer and Information Sciences,
// University of Pennsylvania
// http://www.cis.upenn.edu/acg/softbound/
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal with the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimers.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the names of Santosh Nagarakatte, Milo M. K. Martin,
// Jianzhou Zhao, Steve Zdancewic, University of Pennsylvania, nor
// the names of its contributors may be used to endorse or promote
// products derived from this Software without specific prior
// written permission.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// WITH THE SOFTWARE.
//===---------------------------------------------------------------------===//
#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"
#include "SoftBound/InitializeSoftBound.h"
char InitializeSoftBound:: ID = 0;
static RegisterPass<InitializeSoftBound> P
("InitializeSoftBound","Prototype Creator Pass for SoftBound");
void InitializeSoftBound:: constructShadowStackHandlers(Module & module){
Type* VoidTy = Type::getVoidTy(module.getContext());
Type*
VoidPtrTy = PointerType::getUnqual(Type::getInt8Ty(module.getContext()));
Type* SizeTy = Type::getInt64Ty(module.getContext());
Type* Int32Ty = Type::getInt32Ty(module.getContext());
module.getOrInsertFunction("__softboundcets_allocate_shadow_stack_space",
VoidTy, Int32Ty, NULL);
module.getOrInsertFunction("__softboundcets_deallocate_shadow_stack_space",
VoidTy, NULL);
module.getOrInsertFunction("__softboundcets_load_base_shadow_stack",
VoidPtrTy, Int32Ty, NULL);
module.getOrInsertFunction("__softboundcets_load_bound_shadow_stack",
VoidPtrTy, Int32Ty, NULL);
module.getOrInsertFunction("__softboundcets_load_key_shadow_stack",
SizeTy, Int32Ty, NULL);
module.getOrInsertFunction("__softboundcets_load_lock_shadow_stack",
VoidPtrTy, Int32Ty, NULL);
module.getOrInsertFunction("__softboundcets_store_base_shadow_stack",
VoidTy, VoidPtrTy, Int32Ty, NULL);
module.getOrInsertFunction("__softboundcets_store_bound_shadow_stack",
VoidTy, VoidPtrTy, Int32Ty, NULL);
module.getOrInsertFunction("__softboundcets_store_key_shadow_stack",
VoidTy, SizeTy, Int32Ty, NULL);
module.getOrInsertFunction("__softboundcets_store_lock_shadow_stack",
VoidTy, VoidPtrTy, Int32Ty, NULL);
}
void InitializeSoftBound:: constructMetadataHandlers(Module & module){
Type* VoidTy = Type::getVoidTy(module.getContext());
Type*
VoidPtrTy = PointerType::getUnqual(Type::getInt8Ty(module.getContext()));
Type* SizeTy = Type::getInt64Ty(module.getContext());
Type* Int32Ty = Type::getInt32Ty(module.getContext());
module.getOrInsertFunction("__softboundcets_introspect_metadata",
VoidTy, VoidPtrTy, VoidPtrTy, Int32Ty, NULL);
module.getOrInsertFunction("__softboundcets_copy_metadata",
VoidTy, VoidPtrTy, VoidPtrTy, SizeTy, NULL);
Type* PtrVoidPtrTy = PointerType::getUnqual(VoidPtrTy);
Type* PtrSizeTy = PointerType::getUnqual(SizeTy);
module.getOrInsertFunction("__softboundcets_metadata_load",
VoidTy, VoidPtrTy, PtrVoidPtrTy, PtrVoidPtrTy,
PtrSizeTy, PtrVoidPtrTy, NULL);
module.getOrInsertFunction("__softboundcets_metadata_store",
VoidTy, VoidPtrTy, VoidPtrTy,
VoidPtrTy, SizeTy, VoidPtrTy, NULL);
module.getOrInsertFunction("__softboundcets_get_global_lock",
VoidPtrTy, NULL);
module.getOrInsertFunction("__softboundcets_stack_memory_allocation",
VoidTy, PtrVoidPtrTy,
PtrSizeTy, NULL);
module.getOrInsertFunction("__softboundcets_stack_memory_deallocation",
VoidTy, SizeTy, NULL);
module.getOrInsertFunction("__softboundcets_spatial_call_dereference_check",
VoidTy, VoidPtrTy, VoidPtrTy, VoidPtrTy, NULL);
}
void InitializeSoftBound:: constructCheckHandlers(Module & module){
Type* void_ty = Type::getVoidTy(module.getContext());
Type* void_ptr_ty = PointerType::getUnqual(Type::getInt8Ty(module.getContext()));
Type* size_ty = Type::getInt64Ty(module.getContext());
module.getOrInsertFunction("__softboundcets_spatial_load_dereference_check",
void_ty, void_ptr_ty, void_ptr_ty,
void_ptr_ty, size_ty, NULL);
module.getOrInsertFunction("__softboundcets_spatial_store_dereference_check",
void_ty, void_ptr_ty, void_ptr_ty,
void_ptr_ty, size_ty, NULL);
module.getOrInsertFunction("__softboundcets_temporal_load_dereference_check",
void_ty, void_ptr_ty, size_ty,
void_ptr_ty, void_ptr_ty, NULL);
module.getOrInsertFunction("__softboundcets_temporal_store_dereference_check",
void_ty, void_ptr_ty, size_ty,
void_ptr_ty, void_ptr_ty, NULL);
Function* global_init = (Function *) module.getOrInsertFunction("__softboundcets_global_init",
void_ty, NULL);
global_init->setDoesNotThrow();
global_init->setLinkage(GlobalValue::InternalLinkage);
BasicBlock* BB = BasicBlock::Create(module.getContext(),
"entry", global_init);
Function* softboundcets_init = (Function*) module.getOrInsertFunction("__softboundcets_init", void_ty, Type::getInt32Ty(module.getContext()), NULL);
SmallVector<Value*, 8> args;
Constant * const_one = ConstantInt::get(Type::getInt32Ty(module.getContext()), 1);
args.push_back(const_one);
Instruction* ret = ReturnInst::Create(module.getContext(), BB);
CallInst::Create(softboundcets_init, args, "", ret);
Type * Int32Type = IntegerType::getInt32Ty(module.getContext());
std::vector<Constant *> CtorInits;
CtorInits.push_back(ConstantInt::get(Int32Type, 0));
CtorInits.push_back(global_init);
StructType * ST = ConstantStruct::getTypeForElements(CtorInits, false);
Constant * RuntimeCtorInit = ConstantStruct::get(ST, CtorInits);
//
// Get the current set of static global constructors and add the new ctor
// to the list.
//
std::vector<Constant *> CurrentCtors;
GlobalVariable * GVCtor = module.getNamedGlobal ("llvm.global_ctors");
if (GVCtor) {
if (Constant * C = GVCtor->getInitializer()) {
for (unsigned index = 0; index < C->getNumOperands(); ++index) {
CurrentCtors.push_back (dyn_cast<Constant>(C->getOperand (index)));
}
}
}
CurrentCtors.push_back(RuntimeCtorInit);
//
// Create a new initializer.
//
ArrayType * AT = ArrayType::get (RuntimeCtorInit-> getType(),
CurrentCtors.size());
Constant * NewInit = ConstantArray::get (AT, CurrentCtors);
//
// Create the new llvm.global_ctors global variable and remove the old one
// if it existed.
//
Value * newGVCtor = new GlobalVariable (module,
NewInit->getType(),
false,
GlobalValue::AppendingLinkage,
NewInit,
"llvm.global_ctors");
if (GVCtor) {
newGVCtor->takeName (GVCtor);
GVCtor->eraseFromParent ();
}
}
bool InitializeSoftBound:: runOnModule (Module& module){
constructCheckHandlers(module);
constructShadowStackHandlers(module);
constructMetadataHandlers(module);
// constructAuxillaryFunctionHandlers(module);
return true;
}