mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-16 14:31:59 +00:00
- Add a "getOrInsertGlobal" method to the Module class. This acts similarly to
"getOrInsertFunction" in that it either adds a new declaration of the global and returns it, or returns the current one -- optionally casting it to the correct type. - Use the new getOrInsertGlobal in the stack protector code. - Use "splitBasicBlock" in the stack protector code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58727 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f1f75b1bd1
commit
b7c2c1246f
@ -229,6 +229,15 @@ public:
|
|||||||
return getGlobalVariable(Name, true);
|
return getGlobalVariable(Name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getOrInsertGlobal - Look up the specified global in the module symbol
|
||||||
|
/// table.
|
||||||
|
/// 1. If it does not exist, add a declaration of the global and return it.
|
||||||
|
/// 2. Else, the global exists but has the wrong type: return the function
|
||||||
|
/// with a constantexpr cast to the right type.
|
||||||
|
/// 3. Finally, if the existing global is the correct delclaration, return
|
||||||
|
/// the existing global.
|
||||||
|
Constant *getOrInsertGlobal(const std::string &Name, const Type *Ty);
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @name Global Alias Accessors
|
/// @name Global Alias Accessors
|
||||||
/// @{
|
/// @{
|
||||||
|
@ -52,7 +52,7 @@ namespace {
|
|||||||
AllocaInst *StackProtFrameSlot;
|
AllocaInst *StackProtFrameSlot;
|
||||||
|
|
||||||
/// StackGuardVar - The global variable for the stack guard.
|
/// StackGuardVar - The global variable for the stack guard.
|
||||||
GlobalVariable *StackGuardVar;
|
Constant *StackGuardVar;
|
||||||
|
|
||||||
Function *F;
|
Function *F;
|
||||||
Module *M;
|
Module *M;
|
||||||
@ -115,14 +115,8 @@ void StackProtector::InsertStackProtectorPrologue() {
|
|||||||
BasicBlock &Entry = F->getEntryBlock();
|
BasicBlock &Entry = F->getEntryBlock();
|
||||||
Instruction &InsertPt = Entry.front();
|
Instruction &InsertPt = Entry.front();
|
||||||
|
|
||||||
const char *StackGuardStr = "__stack_chk_guard";
|
StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard",
|
||||||
StackGuardVar = M->getNamedGlobal(StackGuardStr);
|
PointerType::getUnqual(Type::Int8Ty));
|
||||||
|
|
||||||
if (!StackGuardVar)
|
|
||||||
StackGuardVar = new GlobalVariable(PointerType::getUnqual(Type::Int8Ty),
|
|
||||||
false, GlobalValue::ExternalLinkage,
|
|
||||||
0, StackGuardStr, M);
|
|
||||||
|
|
||||||
StackProtFrameSlot = new AllocaInst(PointerType::getUnqual(Type::Int8Ty),
|
StackProtFrameSlot = new AllocaInst(PointerType::getUnqual(Type::Int8Ty),
|
||||||
"StackProt_Frame", &InsertPt);
|
"StackProt_Frame", &InsertPt);
|
||||||
LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, &InsertPt);
|
LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, &InsertPt);
|
||||||
@ -161,7 +155,7 @@ void StackProtector::InsertStackProtectorEpilogue() {
|
|||||||
// %3 = cmp i1 %1, %2
|
// %3 = cmp i1 %1, %2
|
||||||
// br i1 %3, label %SPRet, label %CallStackCheckFailBlk
|
// br i1 %3, label %SPRet, label %CallStackCheckFailBlk
|
||||||
//
|
//
|
||||||
// SPRet:
|
// SP_return:
|
||||||
// ret ...
|
// ret ...
|
||||||
//
|
//
|
||||||
// CallStackCheckFailBlk:
|
// CallStackCheckFailBlk:
|
||||||
@ -174,12 +168,15 @@ void StackProtector::InsertStackProtectorEpilogue() {
|
|||||||
ReturnInst *RI = cast<ReturnInst>(BB->getTerminator());
|
ReturnInst *RI = cast<ReturnInst>(BB->getTerminator());
|
||||||
Function::iterator InsPt = BB; ++InsPt; // Insertion point for new BB.
|
Function::iterator InsPt = BB; ++InsPt; // Insertion point for new BB.
|
||||||
|
|
||||||
BasicBlock *NewBB = BasicBlock::Create("SPRet", F, InsPt);
|
// Split the basic block before the return instruction.
|
||||||
|
BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return");
|
||||||
|
|
||||||
// Move the return instruction into the new basic block.
|
// Move the newly created basic block to the point right after the old basic
|
||||||
RI->removeFromParent();
|
// block.
|
||||||
NewBB->getInstList().insert(NewBB->begin(), RI);
|
NewBB->removeFromParent();
|
||||||
|
F->getBasicBlockList().insert(InsPt, NewBB);
|
||||||
|
|
||||||
|
// Generate the stack protector instructions in the old basic block.
|
||||||
LoadInst *LI2 = new LoadInst(StackGuardVar, "", false, BB);
|
LoadInst *LI2 = new LoadInst(StackGuardVar, "", false, BB);
|
||||||
LoadInst *LI1 = new LoadInst(StackProtFrameSlot, "", true, BB);
|
LoadInst *LI1 = new LoadInst(StackProtFrameSlot, "", true, BB);
|
||||||
ICmpInst *Cmp = new ICmpInst(CmpInst::ICMP_EQ, LI1, LI2, "", BB);
|
ICmpInst *Cmp = new ICmpInst(CmpInst::ICMP_EQ, LI1, LI2, "", BB);
|
||||||
|
@ -224,6 +224,28 @@ GlobalVariable *Module::getGlobalVariable(const std::string &Name,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Constant *Module::getOrInsertGlobal(const std::string &Name, const Type *Ty) {
|
||||||
|
ValueSymbolTable &SymTab = getValueSymbolTable();
|
||||||
|
|
||||||
|
// See if we have a definition for the specified global already.
|
||||||
|
GlobalVariable *GV = dyn_cast_or_null<GlobalVariable>(SymTab.lookup(Name));
|
||||||
|
if (GV == 0) {
|
||||||
|
// Nope, add it
|
||||||
|
GlobalVariable *New =
|
||||||
|
new GlobalVariable(Ty, false, GlobalVariable::ExternalLinkage, 0, Name);
|
||||||
|
GlobalList.push_back(New);
|
||||||
|
return New; // Return the new declaration.
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the variable exists but has the wrong type, return a bitcast to the
|
||||||
|
// right type.
|
||||||
|
if (GV->getType() != PointerType::getUnqual(Ty))
|
||||||
|
return ConstantExpr::getBitCast(GV, PointerType::getUnqual(Ty));
|
||||||
|
|
||||||
|
// Otherwise, we just found the existing function or a prototype.
|
||||||
|
return GV;
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Methods for easy access to the global variables in the module.
|
// Methods for easy access to the global variables in the module.
|
||||||
//
|
//
|
||||||
|
Loading…
x
Reference in New Issue
Block a user