mirror of
https://github.com/herumi/xbyak
synced 2024-11-20 16:06:14 -07:00
add PROTECT_RE mode for protect()
This commit is contained in:
parent
71b75f653f
commit
59573e6e7a
11 changed files with 49 additions and 20 deletions
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
Xbyak 5.65 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++
|
Xbyak 5.66 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++
|
||||||
=============
|
=============
|
||||||
|
|
||||||
Abstract
|
Abstract
|
||||||
|
@ -333,6 +333,7 @@ The header files under xbyak/ are independent of cybozulib.
|
||||||
|
|
||||||
History
|
History
|
||||||
-------------
|
-------------
|
||||||
|
* 2018/Jul/24 ver 5.66 add CodeArray::PROTECT_RE to mode of protect()
|
||||||
* 2018/Jun/26 ver 5.65 fix push(qword [mem])
|
* 2018/Jun/26 ver 5.65 fix push(qword [mem])
|
||||||
* 2018/Mar/07 ver 5.64 fix zero division in Cpu() on some cpu
|
* 2018/Mar/07 ver 5.64 fix zero division in Cpu() on some cpu
|
||||||
* 2018/Feb/14 ver 5.63 fix Cpu::setCacheHierarchy() and fix EvexModifierZero for clang<3.9(thanks to mgouicem)
|
* 2018/Feb/14 ver 5.63 fix Cpu::setCacheHierarchy() and fix EvexModifierZero for clang<3.9(thanks to mgouicem)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 5.65
|
C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 5.66
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
◎概要
|
◎概要
|
||||||
|
@ -343,6 +343,7 @@ cybozulibは単体テストでのみ利用されていて、xbyak/ディレク
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
◎履歴
|
◎履歴
|
||||||
|
|
||||||
|
2018/07/24 ver 5.66 protect()のmodeにCodeArray::PROTECT_REを追加
|
||||||
2018/06/26 ver 5.65 fix push(qword [mem])
|
2018/06/26 ver 5.65 fix push(qword [mem])
|
||||||
2018/03/07 ver 5.64 Cpu()の中でzero divisionが出ることがあるのを修正
|
2018/03/07 ver 5.64 Cpu()の中でzero divisionが出ることがあるのを修正
|
||||||
2018/02/14 ver 5.63 Cpu::setCacheHierarchy()の修正とclang<3.9のためのEvexModifierZero修正(thanks to mgouicem)
|
2018/02/14 ver 5.63 Cpu::setCacheHierarchy()の修正とclang<3.9のためのEvexModifierZero修正(thanks to mgouicem)
|
||||||
|
|
|
@ -13,7 +13,6 @@ struct Code : Xbyak::CodeGenerator {
|
||||||
{
|
{
|
||||||
puts("generate");
|
puts("generate");
|
||||||
printf("ptr=%p, %p\n", getCode(), buf);
|
printf("ptr=%p, %p\n", getCode(), buf);
|
||||||
Xbyak::CodeArray::protect(buf, sizeof(buf), true);
|
|
||||||
#ifdef XBYAK32
|
#ifdef XBYAK32
|
||||||
mov(eax, ptr [esp + 4]);
|
mov(eax, ptr [esp + 4]);
|
||||||
add(eax, ptr [esp + 8]);
|
add(eax, ptr [esp + 8]);
|
||||||
|
@ -23,6 +22,11 @@ struct Code : Xbyak::CodeGenerator {
|
||||||
lea(rax, ptr [rdi + rsi]);
|
lea(rax, ptr [rdi + rsi]);
|
||||||
#endif
|
#endif
|
||||||
ret();
|
ret();
|
||||||
|
Xbyak::CodeArray::protect(buf, sizeof(buf), Xbyak::CodeArray::PROTECT_RE);
|
||||||
|
}
|
||||||
|
~Code()
|
||||||
|
{
|
||||||
|
Xbyak::CodeArray::protect(buf, sizeof(buf), Xbyak::CodeArray::PROTECT_RW);
|
||||||
}
|
}
|
||||||
} s_code;
|
} s_code;
|
||||||
|
|
||||||
|
|
|
@ -165,15 +165,15 @@ int main()
|
||||||
const size_t codeSize = 1024;
|
const size_t codeSize = 1024;
|
||||||
uint8 buf[codeSize + 16];
|
uint8 buf[codeSize + 16];
|
||||||
uint8 *p = CodeArray::getAlignedAddress(buf);
|
uint8 *p = CodeArray::getAlignedAddress(buf);
|
||||||
CodeArray::protect(p, codeSize, true);
|
|
||||||
Sample s(p, codeSize);
|
Sample s(p, codeSize);
|
||||||
|
CodeArray::protect(p, codeSize, CodeArray::PROTECT_RE);
|
||||||
int (*func)(int) = s.getCode<int (*)(int)>();
|
int (*func)(int) = s.getCode<int (*)(int)>();
|
||||||
if (Xbyak::CastTo<uint8*>(func) != p) {
|
if (Xbyak::CastTo<uint8*>(func) != p) {
|
||||||
fprintf(stderr, "internal error %p %p\n", p, Xbyak::CastTo<uint8*>(func));
|
fprintf(stderr, "internal error %p %p\n", p, Xbyak::CastTo<uint8*>(func));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
printf("0 + ... + %d = %d\n", 100, func(100));
|
printf("0 + ... + %d = %d\n", 100, func(100));
|
||||||
CodeArray::protect(p, codeSize, false);
|
CodeArray::protect(p, codeSize, CodeArray::PROTECT_RW);
|
||||||
}
|
}
|
||||||
puts("OK");
|
puts("OK");
|
||||||
testReset();
|
testReset();
|
||||||
|
|
|
@ -1143,10 +1143,11 @@ CYBOZU_TEST_AUTO(rip_addr_with_fixed_buf)
|
||||||
ret();
|
ret();
|
||||||
}
|
}
|
||||||
} code;
|
} code;
|
||||||
Xbyak::CodeArray::protect(p, 4096, true);
|
Xbyak::CodeArray::protect(p, 4096, Xbyak::CodeArray::PROTECT_RE);
|
||||||
code.getCode<void (*)()>()();
|
code.getCode<void (*)()>()();
|
||||||
CYBOZU_TEST_EQUAL(*x0, 123);
|
CYBOZU_TEST_EQUAL(*x0, 123);
|
||||||
CYBOZU_TEST_EQUAL(*x1, 456);
|
CYBOZU_TEST_EQUAL(*x1, 456);
|
||||||
CYBOZU_TEST_EQUAL(buf[8], 99);
|
CYBOZU_TEST_EQUAL(buf[8], 99);
|
||||||
|
Xbyak::CodeArray::protect(p, 4096, Xbyak::CodeArray::PROTECT_RW);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,7 +31,7 @@ address %1% jit > nm.cpp
|
||||||
echo cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
echo cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
||||||
cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
||||||
nm_frame > x.lst
|
nm_frame > x.lst
|
||||||
diff x.lst ok.lst
|
diff -w x.lst ok.lst
|
||||||
wc x.lst
|
wc x.lst
|
||||||
|
|
||||||
:end
|
:end
|
||||||
|
|
|
@ -38,5 +38,5 @@ make_nm jit > nm.cpp
|
||||||
echo cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
echo cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
||||||
cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
||||||
nm_frame |%FILTER% > x.lst
|
nm_frame |%FILTER% > x.lst
|
||||||
diff x.lst ok.lst
|
diff -w x.lst ok.lst
|
||||||
wc x.lst
|
wc x.lst
|
||||||
|
|
|
@ -27,5 +27,5 @@ awk "{if (index($3, ""-"")) { conti=substr($3, 0, length($3) - 1) } else { conti
|
||||||
make_512 jit > nm.cpp
|
make_512 jit > nm.cpp
|
||||||
cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2% /DXBYAK_AVX512
|
cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2% /DXBYAK_AVX512
|
||||||
nm_frame |%FILTER% > x.lst
|
nm_frame |%FILTER% > x.lst
|
||||||
diff x.lst ok.lst
|
diff -w x.lst ok.lst
|
||||||
wc x.lst
|
wc x.lst
|
||||||
|
|
|
@ -39,5 +39,5 @@ if /i "%Y%"=="1" (
|
||||||
make_nm jit > nm.cpp
|
make_nm jit > nm.cpp
|
||||||
cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
||||||
nm_frame |%FILTER% > x.lst
|
nm_frame |%FILTER% > x.lst
|
||||||
diff x.lst ok.lst
|
diff -w x.lst ok.lst
|
||||||
wc x.lst
|
wc x.lst
|
||||||
|
|
|
@ -105,7 +105,7 @@ namespace Xbyak {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
DEFAULT_MAX_CODE_SIZE = 4096,
|
DEFAULT_MAX_CODE_SIZE = 4096,
|
||||||
VERSION = 0x5650 /* 0xABCD = A.BC(D) */
|
VERSION = 0x5660 /* 0xABCD = A.BC(D) */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef MIE_INTEGER_TYPE_DEFINED
|
#ifndef MIE_INTEGER_TYPE_DEFINED
|
||||||
|
@ -848,10 +848,15 @@ protected:
|
||||||
uint64 disp = i->getVal(top_);
|
uint64 disp = i->getVal(top_);
|
||||||
rewrite(i->codeOffset, disp, i->jmpSize);
|
rewrite(i->codeOffset, disp, i->jmpSize);
|
||||||
}
|
}
|
||||||
if (alloc_->useProtect() && !protect(top_, size_, true)) throw Error(ERR_CANT_PROTECT);
|
if (alloc_->useProtect() && !protect(top_, size_, PROTECT_RWE)) throw Error(ERR_CANT_PROTECT);
|
||||||
isCalledCalcJmpAddress_ = true;
|
isCalledCalcJmpAddress_ = true;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
enum ProtectMode {
|
||||||
|
PROTECT_RW = 0, // read/write
|
||||||
|
PROTECT_RWE = 1, // read/write/exec
|
||||||
|
PROTECT_RE = 2 // read/exec
|
||||||
|
};
|
||||||
explicit CodeArray(size_t maxSize, void *userPtr = 0, Allocator *allocator = 0)
|
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 ? USER_BUF : ALLOC_BUF)
|
||||||
, alloc_(allocator ? allocator : (Allocator*)&defaultAllocator_)
|
, alloc_(allocator ? allocator : (Allocator*)&defaultAllocator_)
|
||||||
|
@ -861,7 +866,7 @@ public:
|
||||||
, isCalledCalcJmpAddress_(false)
|
, isCalledCalcJmpAddress_(false)
|
||||||
{
|
{
|
||||||
if (maxSize_ > 0 && top_ == 0) throw Error(ERR_CANT_ALLOC);
|
if (maxSize_ > 0 && top_ == 0) throw Error(ERR_CANT_ALLOC);
|
||||||
if ((type_ == ALLOC_BUF && alloc_->useProtect()) && !protect(top_, maxSize, true)) {
|
if ((type_ == ALLOC_BUF && alloc_->useProtect()) && !protect(top_, maxSize, PROTECT_RWE)) {
|
||||||
alloc_->free(top_);
|
alloc_->free(top_);
|
||||||
throw Error(ERR_CANT_PROTECT);
|
throw Error(ERR_CANT_PROTECT);
|
||||||
}
|
}
|
||||||
|
@ -869,7 +874,7 @@ public:
|
||||||
virtual ~CodeArray()
|
virtual ~CodeArray()
|
||||||
{
|
{
|
||||||
if (isAllocType()) {
|
if (isAllocType()) {
|
||||||
if (alloc_->useProtect()) protect(top_, maxSize_, false);
|
if (alloc_->useProtect()) protect(top_, maxSize_, PROTECT_RW);
|
||||||
alloc_->free(top_);
|
alloc_->free(top_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -960,19 +965,36 @@ public:
|
||||||
change exec permission of memory
|
change exec permission of memory
|
||||||
@param addr [in] buffer address
|
@param addr [in] buffer address
|
||||||
@param size [in] buffer size
|
@param size [in] buffer size
|
||||||
@param canExec [in] true(enable to exec), false(disable to exec)
|
@param protectMode [in] mode(RW/RWE/RE)
|
||||||
@return true(success), false(failure)
|
@return true(success), false(failure)
|
||||||
*/
|
*/
|
||||||
static inline bool protect(const void *addr, size_t size, bool canExec)
|
static inline bool protect(const void *addr, size_t size, int protectMode)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_MSC_VER)
|
||||||
|
const DWORD c_rw = PAGE_READWRITE;
|
||||||
|
const DWORD c_rwe = PAGE_EXECUTE_READWRITE;
|
||||||
|
const DWORD c_re = PAGE_EXECUTE_READ;
|
||||||
|
DWORD mode;
|
||||||
|
#else
|
||||||
|
const int c_rw = PROT_READ | PROT_WRITE;
|
||||||
|
const int c_rwe = PROT_READ | PROT_WRITE | PROT_EXEC;
|
||||||
|
const int c_re = PROT_READ | PROT_EXEC;
|
||||||
|
int mode;
|
||||||
|
#endif
|
||||||
|
switch (protectMode) {
|
||||||
|
case PROTECT_RW: mode = c_rw; break;
|
||||||
|
case PROTECT_RWE: mode = c_rwe; break;
|
||||||
|
case PROTECT_RE: mode = c_re; break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#if defined(_MSC_VER)
|
||||||
DWORD oldProtect;
|
DWORD oldProtect;
|
||||||
return VirtualProtect(const_cast<void*>(addr), size, canExec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &oldProtect) != 0;
|
return VirtualProtect(const_cast<void*>(addr), size, mode, &oldProtect) != 0;
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
size_t pageSize = sysconf(_SC_PAGESIZE);
|
size_t pageSize = sysconf(_SC_PAGESIZE);
|
||||||
size_t iaddr = reinterpret_cast<size_t>(addr);
|
size_t iaddr = reinterpret_cast<size_t>(addr);
|
||||||
size_t roundAddr = iaddr & ~(pageSize - static_cast<size_t>(1));
|
size_t roundAddr = iaddr & ~(pageSize - static_cast<size_t>(1));
|
||||||
int mode = PROT_READ | PROT_WRITE | (canExec ? PROT_EXEC : 0);
|
|
||||||
return mprotect(reinterpret_cast<void*>(roundAddr), size + (iaddr - roundAddr), mode) == 0;
|
return mprotect(reinterpret_cast<void*>(roundAddr), size + (iaddr - roundAddr), mode) == 0;
|
||||||
#else
|
#else
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const char *getVersionString() const { return "5.65"; }
|
const char *getVersionString() const { return "5.66"; }
|
||||||
void adc(const Operand& op, uint32 imm) { opRM_I(op, imm, 0x10, 2); }
|
void adc(const Operand& op, uint32 imm) { opRM_I(op, imm, 0x10, 2); }
|
||||||
void adc(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x10); }
|
void adc(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x10); }
|
||||||
void adcx(const Reg32e& reg, const Operand& op) { opGen(reg, op, 0xF6, 0x66, isREG32_REG32orMEM, NONE, 0x38); }
|
void adcx(const Reg32e& reg, const Operand& op) { opGen(reg, op, 0xF6, 0x66, isREG32_REG32orMEM, NONE, 0x38); }
|
||||||
|
|
Loading…
Reference in a new issue