add setProtectMode
diff --git a/xbyak/xbyak.h b/xbyak/xbyak.h
index 251dc97..b7f9d51 100644
--- a/xbyak/xbyak.h
+++ b/xbyak/xbyak.h
@@ -105,7 +105,7 @@
enum {
DEFAULT_MAX_CODE_SIZE = 4096,
- VERSION = 0x5680 /* 0xABCD = A.BC(D) */
+ VERSION = 0x5700 /* 0xABCD = A.BC(D) */
};
#ifndef MIE_INTEGER_TYPE_DEFINED
@@ -786,6 +786,7 @@
// 2nd parameter for constructor of CodeArray(maxSize, userPtr, alloc)
void *const AutoGrow = (void*)1; //-V566
+void *const DontSetProtectRWE = (void*)2; //-V566
class CodeArray {
enum Type {
@@ -825,6 +826,7 @@
size_t size_;
bool isCalledCalcJmpAddress_;
+ bool useProtect() const { return alloc_->useProtect(); }
/*
allocate new memory and copy old data to the new area
*/
@@ -848,7 +850,6 @@
uint64 disp = i->getVal(top_);
rewrite(i->codeOffset, disp, i->jmpSize);
}
- if (alloc_->useProtect() && !protect(top_, size_, PROTECT_RWE)) throw Error(ERR_CANT_PROTECT);
isCalledCalcJmpAddress_ = true;
}
public:
@@ -858,7 +859,7 @@
PROTECT_RE = 2 // read/exec
};
explicit CodeArray(size_t maxSize, void *userPtr = 0, Allocator *allocator = 0)
- : type_(userPtr == AutoGrow ? AUTO_GROW : userPtr ? USER_BUF : ALLOC_BUF)
+ : type_(userPtr == AutoGrow ? AUTO_GROW : (userPtr == 0 || userPtr == DontSetProtectRWE) ? ALLOC_BUF : USER_BUF)
, alloc_(allocator ? allocator : (Allocator*)&defaultAllocator_)
, maxSize_(maxSize)
, top_(type_ == USER_BUF ? reinterpret_cast<uint8*>(userPtr) : alloc_->alloc((std::max<size_t>)(maxSize, 1)))
@@ -866,7 +867,7 @@
, isCalledCalcJmpAddress_(false)
{
if (maxSize_ > 0 && top_ == 0) throw Error(ERR_CANT_ALLOC);
- if ((type_ == ALLOC_BUF && alloc_->useProtect()) && !protect(top_, maxSize, PROTECT_RWE)) {
+ if ((type_ == ALLOC_BUF && userPtr != DontSetProtectRWE && useProtect()) && !setProtectMode(PROTECT_RWE, false)) {
alloc_->free(top_);
throw Error(ERR_CANT_PROTECT);
}
@@ -874,10 +875,19 @@
virtual ~CodeArray()
{
if (isAllocType()) {
- if (alloc_->useProtect()) protect(top_, maxSize_, PROTECT_RW);
+ if (useProtect()) setProtectModeRW(false);
alloc_->free(top_);
}
}
+ bool setProtectMode(ProtectMode mode, bool throwException = true)
+ {
+ bool isOK = protect(top_, maxSize_, mode);
+ if (isOK) return true;
+ if (throwException) throw Error(ERR_CANT_PROTECT);
+ return false;
+ }
+ bool setProtectModeRE(bool throwException = true) { return setProtectMode(PROTECT_RE, throwException); }
+ bool setProtectModeRW(bool throwException = true) { return setProtectMode(PROTECT_RW, throwException); }
void resetSize()
{
size_ = 0;
@@ -2440,11 +2450,16 @@
MUST call ready() to complete generating code if you use AutoGrow mode.
It is not necessary for the other mode if hasUndefinedLabel() is true.
*/
- void ready()
+ void ready(ProtectMode mode = PROTECT_RWE)
{
if (hasUndefinedLabel()) throw Error(ERR_LABEL_IS_NOT_FOUND);
- if (isAutoGrow()) calcJmpAddress();
+ if (isAutoGrow()) {
+ calcJmpAddress();
+ if (useProtect()) setProtectMode(mode);
+ }
}
+ // set read/exec
+ void readyRE() { return ready(PROTECT_RE); }
#ifdef XBYAK_TEST
void dump(bool doClear = true)
{