mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 06:33:24 +00:00
Implement stack protectors as function attributes: "ssp" and "sspreq".
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59202 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7fc610f073
commit
e9e6bdf27f
@ -47,6 +47,8 @@ const Attributes ReadOnly = 1<<10; ///< Function only reads from memory
|
|||||||
const Attributes NoInline = 1<<11; // inline=never
|
const Attributes NoInline = 1<<11; // inline=never
|
||||||
const Attributes AlwaysInline = 1<<12; // inline=always
|
const Attributes AlwaysInline = 1<<12; // inline=always
|
||||||
const Attributes OptimizeForSize = 1<<13; // opt_size
|
const Attributes OptimizeForSize = 1<<13; // opt_size
|
||||||
|
const Attributes StackProtect = 1<<14; // Stack protection.
|
||||||
|
const Attributes StackProtectReq = 1<<15; // Stack protection required.
|
||||||
const Attributes Alignment = 0xffff<<16; ///< Alignment of parameter (16 bits)
|
const Attributes Alignment = 0xffff<<16; ///< Alignment of parameter (16 bits)
|
||||||
// 0 = unknown, else in clear (not log)
|
// 0 = unknown, else in clear (not log)
|
||||||
|
|
||||||
@ -55,7 +57,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet;
|
|||||||
|
|
||||||
/// @brief Attributes that only apply to function.
|
/// @brief Attributes that only apply to function.
|
||||||
const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
|
const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
|
||||||
NoInline | AlwaysInline | OptimizeForSize;
|
NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq;
|
||||||
|
|
||||||
/// @brief Parameter attributes that do not apply to vararg call arguments.
|
/// @brief Parameter attributes that do not apply to vararg call arguments.
|
||||||
const Attributes VarArgsIncompatible = StructRet;
|
const Attributes VarArgsIncompatible = StructRet;
|
||||||
|
@ -26,16 +26,6 @@ namespace llvm {
|
|||||||
class TargetLowering;
|
class TargetLowering;
|
||||||
class RegisterCoalescer;
|
class RegisterCoalescer;
|
||||||
|
|
||||||
/// StackProtectorLevel - An enumeration for when to determin when to turn
|
|
||||||
/// stack smashing protection (SSP) on.
|
|
||||||
namespace SSP {
|
|
||||||
enum StackProtectorLevel {
|
|
||||||
OFF, // Stack protectors are off.
|
|
||||||
SOME, // Stack protectors on only for functions that require them.
|
|
||||||
ALL // Stack protectors on for all functions.
|
|
||||||
};
|
|
||||||
} // end SSP namespace
|
|
||||||
|
|
||||||
/// createUnreachableBlockEliminationPass - The LLVM code generator does not
|
/// createUnreachableBlockEliminationPass - The LLVM code generator does not
|
||||||
/// work well with unreachable basic blocks (what live ranges make sense for a
|
/// work well with unreachable basic blocks (what live ranges make sense for a
|
||||||
/// block that cannot be reached?). As such, a code generator should either
|
/// block that cannot be reached?). As such, a code generator should either
|
||||||
@ -204,8 +194,7 @@ namespace llvm {
|
|||||||
FunctionPass *createStackSlotColoringPass();
|
FunctionPass *createStackSlotColoringPass();
|
||||||
|
|
||||||
/// createStackProtectorPass - This pass adds stack protectors to functions.
|
/// createStackProtectorPass - This pass adds stack protectors to functions.
|
||||||
FunctionPass *createStackProtectorPass(SSP::StackProtectorLevel lvl,
|
FunctionPass *createStackProtectorPass(const TargetLowering *tli);
|
||||||
const TargetLowering *tli);
|
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
|
@ -499,6 +499,8 @@ int LLLexer::LexIdentifier() {
|
|||||||
KEYWORD("noinline", NOINLINE);
|
KEYWORD("noinline", NOINLINE);
|
||||||
KEYWORD("alwaysinline", ALWAYSINLINE);
|
KEYWORD("alwaysinline", ALWAYSINLINE);
|
||||||
KEYWORD("optsize", OPTSIZE);
|
KEYWORD("optsize", OPTSIZE);
|
||||||
|
KEYWORD("ssp", SSP);
|
||||||
|
KEYWORD("sspreq", SSPREQ);
|
||||||
|
|
||||||
KEYWORD("type", TYPE);
|
KEYWORD("type", TYPE);
|
||||||
KEYWORD("opaque", OPAQUE);
|
KEYWORD("opaque", OPAQUE);
|
||||||
|
@ -1137,7 +1137,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
|||||||
|
|
||||||
// Function Attributes
|
// Function Attributes
|
||||||
%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
|
%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
|
||||||
%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE
|
%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE SSP SSPREQ
|
||||||
|
|
||||||
// Visibility Styles
|
// Visibility Styles
|
||||||
%token DEFAULT HIDDEN PROTECTED
|
%token DEFAULT HIDDEN PROTECTED
|
||||||
@ -1305,7 +1305,9 @@ FuncAttr : NORETURN { $$ = Attribute::NoReturn; }
|
|||||||
| READONLY { $$ = Attribute::ReadOnly; }
|
| READONLY { $$ = Attribute::ReadOnly; }
|
||||||
| NOINLINE { $$ = Attribute::NoInline; }
|
| NOINLINE { $$ = Attribute::NoInline; }
|
||||||
| ALWAYSINLINE { $$ = Attribute::AlwaysInline; }
|
| ALWAYSINLINE { $$ = Attribute::AlwaysInline; }
|
||||||
| OPTSIZE { $$ = Attribute::OptimizeForSize; }
|
| OPTSIZE { $$ = Attribute::OptimizeForSize; }
|
||||||
|
| SSP { $$ = Attribute::StackProtect; }
|
||||||
|
| SSPREQ { $$ = Attribute::StackProtectReq; }
|
||||||
;
|
;
|
||||||
|
|
||||||
OptFuncAttrs : /* empty */ { $$ = Attribute::None; }
|
OptFuncAttrs : /* empty */ { $$ = Attribute::None; }
|
||||||
|
@ -60,19 +60,6 @@ static cl::opt<cl::boolOrDefault>
|
|||||||
EnableFastISelOption("fast-isel", cl::Hidden,
|
EnableFastISelOption("fast-isel", cl::Hidden,
|
||||||
cl::desc("Enable the experimental \"fast\" instruction selector"));
|
cl::desc("Enable the experimental \"fast\" instruction selector"));
|
||||||
|
|
||||||
// Enable stack protectors.
|
|
||||||
static cl::opt<SSP::StackProtectorLevel>
|
|
||||||
EnableStackProtector("enable-stack-protector",
|
|
||||||
cl::desc("Stack canary protection level: (default: off)"),
|
|
||||||
cl::init(SSP::OFF),
|
|
||||||
cl::values(clEnumValN(SSP::ALL, "all",
|
|
||||||
"All functions get stack protectors."),
|
|
||||||
clEnumValN(SSP::SOME, "some",
|
|
||||||
"Only functions requiring stack protectors get them."),
|
|
||||||
clEnumValN(SSP::OFF, "off",
|
|
||||||
"No functions get stack protectors."),
|
|
||||||
clEnumValEnd));
|
|
||||||
|
|
||||||
FileModel::Model
|
FileModel::Model
|
||||||
LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
|
LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
|
||||||
raw_ostream &Out,
|
raw_ostream &Out,
|
||||||
@ -178,8 +165,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, bool Fast) {
|
|||||||
if (!Fast)
|
if (!Fast)
|
||||||
PM.add(createCodeGenPreparePass(getTargetLowering()));
|
PM.add(createCodeGenPreparePass(getTargetLowering()));
|
||||||
|
|
||||||
if (EnableStackProtector != SSP::OFF)
|
PM.add(createStackProtectorPass(getTargetLowering()));
|
||||||
PM.add(createStackProtectorPass(EnableStackProtector, getTargetLowering()));
|
|
||||||
|
|
||||||
if (PrintISelInput)
|
if (PrintISelInput)
|
||||||
PM.add(createPrintFunctionPass("\n\n"
|
PM.add(createPrintFunctionPass("\n\n"
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#define DEBUG_TYPE "stack-protector"
|
#define DEBUG_TYPE "stack-protector"
|
||||||
#include "llvm/CodeGen/Passes.h"
|
#include "llvm/CodeGen/Passes.h"
|
||||||
|
#include "llvm/Attributes.h"
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
#include "llvm/Function.h"
|
#include "llvm/Function.h"
|
||||||
@ -37,9 +38,6 @@ SSPBufferSize("stack-protector-buffer-size", cl::init(8),
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class VISIBILITY_HIDDEN StackProtector : public FunctionPass {
|
class VISIBILITY_HIDDEN StackProtector : public FunctionPass {
|
||||||
/// Level - The level of stack protection.
|
|
||||||
SSP::StackProtectorLevel Level;
|
|
||||||
|
|
||||||
/// 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 TargetLowering *TLI;
|
const TargetLowering *TLI;
|
||||||
@ -64,9 +62,9 @@ namespace {
|
|||||||
bool RequiresStackProtector() const;
|
bool RequiresStackProtector() const;
|
||||||
public:
|
public:
|
||||||
static char ID; // Pass identification, replacement for typeid.
|
static char ID; // Pass identification, replacement for typeid.
|
||||||
StackProtector() : FunctionPass(&ID), Level(SSP::OFF), TLI(0) {}
|
StackProtector() : FunctionPass(&ID), TLI(0) {}
|
||||||
StackProtector(SSP::StackProtectorLevel lvl, const TargetLowering *tli)
|
StackProtector(const TargetLowering *tli)
|
||||||
: FunctionPass(&ID), Level(lvl), TLI(tli) {}
|
: FunctionPass(&ID), TLI(tli) {}
|
||||||
|
|
||||||
virtual bool runOnFunction(Function &Fn);
|
virtual bool runOnFunction(Function &Fn);
|
||||||
};
|
};
|
||||||
@ -76,9 +74,8 @@ char StackProtector::ID = 0;
|
|||||||
static RegisterPass<StackProtector>
|
static RegisterPass<StackProtector>
|
||||||
X("stack-protector", "Insert stack protectors");
|
X("stack-protector", "Insert stack protectors");
|
||||||
|
|
||||||
FunctionPass *llvm::createStackProtectorPass(SSP::StackProtectorLevel lvl,
|
FunctionPass *llvm::createStackProtectorPass(const TargetLowering *tli) {
|
||||||
const TargetLowering *tli) {
|
return new StackProtector(tli);
|
||||||
return new StackProtector(lvl, tli);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StackProtector::runOnFunction(Function &Fn) {
|
bool StackProtector::runOnFunction(Function &Fn) {
|
||||||
@ -193,10 +190,10 @@ BasicBlock *StackProtector::CreateFailBB() {
|
|||||||
/// add a guard variable to functions that call alloca, and functions with
|
/// add a guard variable to functions that call alloca, and functions with
|
||||||
/// buffers larger than 8 bytes.
|
/// buffers larger than 8 bytes.
|
||||||
bool StackProtector::RequiresStackProtector() const {
|
bool StackProtector::RequiresStackProtector() const {
|
||||||
switch (Level) {
|
if (F->hasFnAttr(Attribute::StackProtectReq))
|
||||||
default: return false;
|
return true;
|
||||||
case SSP::ALL: return true;
|
|
||||||
case SSP::SOME: {
|
if (F->hasFnAttr(Attribute::StackProtect)) {
|
||||||
const TargetData *TD = TLI->getTargetData();
|
const TargetData *TD = TLI->getTargetData();
|
||||||
|
|
||||||
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
|
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
|
||||||
@ -220,5 +217,6 @@ bool StackProtector::RequiresStackProtector() const {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,10 @@ std::string Attribute::getAsString(Attributes Attrs) {
|
|||||||
Result += "noinline ";
|
Result += "noinline ";
|
||||||
if (Attrs & Attribute::AlwaysInline)
|
if (Attrs & Attribute::AlwaysInline)
|
||||||
Result += "alwaysinline ";
|
Result += "alwaysinline ";
|
||||||
|
if (Attrs & Attribute::StackProtect)
|
||||||
|
Result += "ssp ";
|
||||||
|
if (Attrs & Attribute::StackProtectReq)
|
||||||
|
Result += "sspreq ";
|
||||||
if (Attrs & Attribute::Alignment) {
|
if (Attrs & Attribute::Alignment) {
|
||||||
Result += "align ";
|
Result += "align ";
|
||||||
Result += utostr((Attrs & Attribute::Alignment) >> 16);
|
Result += utostr((Attrs & Attribute::Alignment) >> 16);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user