質問
と思っていたがうものであjit compilataionでの学習)のようにしているのでクロスプラットフォームからしかったのは、ホーム(windows、os x、linuxで共通)。その上で、知りたい場合はその利用の仮想メモリwindowsの機能配分のメモリの実行アクセス権を表します。思うmallocや新しいポイントプロセッサーのようなブロックです。
他のヒント?
解決
可能性のひとつで必要とWindowsの設置実行プログラムは設定されてDEP AlwaysOff(bad)このメソッドをオーバーライドまたは発OptOut(よ)このメソッドをオーバーライド.
この設定可能(下WinXp SP2+とWin2k3SP1+少なくとも)を変更するボタンをクリックします。iniファイルの設定
/noexecute=OptOut
その後の設定で、個別のプログラムをオプトアウトを選択(XP):
Start button
Control Panel
System
Advanced tab
Performance Settings button
Data Execution Prevention tab
このこで実行することができコード内のプログラムの作成に飛ぶ malloc()
ブロックとなります。
ることに注意してくださいするプログラムが影響を受けやすくする攻撃発のための予防にいいのです。
このようになることも可能でWindows2008年のコマンド:
bcdedit.exe /set {current} nx OptOut
でも、正直、また最小限に抑えるためにはプラットフォーム依存のコードは、簡単にいっぱいで仕分けもバッチリでを分離することでコードを単一の機能のようなもの:
void *MallocWithoutDep(size_t sz) {
#if defined _IS_WINDOWS
return VirtualMalloc(sz, OPT_DEP_OFF); // or whatever
#elif defined IS_LINUX
// Do linuxy thing
#elif defined IS_MACOS
// Do something almost certainly inexplicable
#endif
}
を入れればすべてのプラットフォーム依存の機能自分のファイル探しも、予約も、支払も、全部エコードは自動的にプラットフォームagnostic.
他のヒント
DEPは、単にメモリのすべての非コード・ページから実行権限をオフにしています。アプリケーションのコードが実行許可を持っているメモリにロードされます。そしてDEPが有効になっている場合でも、Windowsの/ Linuxの/ MacOSXの中で働くのJITがたくさんあります。動的に必要なパーミッションを設定してメモリを割り当てる方法があるからである。
権限ごとのページであるため、通常、無地のmallocは、使用すべきではありません。ページへのmallocで割り当てられたメモリの整列は、いくつかのオーバーヘッドの価格でも可能です。あなたは(実行コードのみのために)、いくつかのカスタムメモリ管理をmalloc関数を使用しない場合。カスタム管理は、JITを行うための一般的な方法です。
JavaScriptのV8 VMのJITを使用し、クロスプラットフォームであるクロムプロジェクトからの解決策があります。クロスプラットフォームであるために、必要な機能は、複数のファイルで実装されており、それらはコンパイル時に選択されます。
のLinux:(クロムSRC / V8 / SRC / platform-linux.cc)フラグはMMAPのPROT_EXEC()である
。void* OS::Allocate(const size_t requested,
size_t* allocated,
bool is_executable) {
const size_t msize = RoundUp(requested, AllocateAlignment());
int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
void* addr = OS::GetRandomMmapAddr();
void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (mbase == MAP_FAILED) {
/** handle error */
return NULL;
}
*allocated = msize;
UpdateAllocatedSpaceLimits(mbase, msize);
return mbase;
}
のWin32(SRC / V8 / SRC / platform-win32.cc):フラグがVirtualAllocののPAGE_EXECUTE_READWRITE
でありますvoid* OS::Allocate(const size_t requested,
size_t* allocated,
bool is_executable) {
// The address range used to randomize RWX allocations in OS::Allocate
// Try not to map pages into the default range that windows loads DLLs
// Use a multiple of 64k to prevent committing unused memory.
// Note: This does not guarantee RWX regions will be within the
// range kAllocationRandomAddressMin to kAllocationRandomAddressMax
#ifdef V8_HOST_ARCH_64_BIT
static const intptr_t kAllocationRandomAddressMin = 0x0000000080000000;
static const intptr_t kAllocationRandomAddressMax = 0x000003FFFFFF0000;
#else
static const intptr_t kAllocationRandomAddressMin = 0x04000000;
static const intptr_t kAllocationRandomAddressMax = 0x3FFF0000;
#endif
// VirtualAlloc rounds allocated size to page size automatically.
size_t msize = RoundUp(requested, static_cast<int>(GetPageSize()));
intptr_t address = 0;
// Windows XP SP2 allows Data Excution Prevention (DEP).
int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
// For exectutable pages try and randomize the allocation address
if (prot == PAGE_EXECUTE_READWRITE &&
msize >= static_cast<size_t>(Page::kPageSize)) {
address = (V8::RandomPrivate(Isolate::Current()) << kPageSizeBits)
| kAllocationRandomAddressMin;
address &= kAllocationRandomAddressMax;
}
LPVOID mbase = VirtualAlloc(reinterpret_cast<void *>(address),
msize,
MEM_COMMIT | MEM_RESERVE,
prot);
if (mbase == NULL && address != 0)
mbase = VirtualAlloc(NULL, msize, MEM_COMMIT | MEM_RESERVE, prot);
if (mbase == NULL) {
LOG(ISOLATE, StringEvent("OS::Allocate", "VirtualAlloc failed"));
return NULL;
}
ASSERT(IsAligned(reinterpret_cast<size_t>(mbase), OS::AllocateAlignment()));
*allocated = msize;
UpdateAllocatedSpaceLimits(mbase, static_cast<int>(msize));
return mbase;
}
のMacOS(SRC / V8 / SRC / platform-macos.cc):フラグはちょうどLinuxや他のPOSIXと同様に、MMAPのPROT_EXECです。
。void* OS::Allocate(const size_t requested,
size_t* allocated,
bool is_executable) {
const size_t msize = RoundUp(requested, getpagesize());
int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
void* mbase = mmap(OS::GetRandomMmapAddr(),
msize,
prot,
MAP_PRIVATE | MAP_ANON,
kMmapFd,
kMmapFdOffset);
if (mbase == MAP_FAILED) {
LOG(Isolate::Current(), StringEvent("OS::Allocate", "mmap failed"));
return NULL;
}
*allocated = msize;
UpdateAllocatedSpaceLimits(mbase, msize);
return mbase;
}
私もそのbcdedit.exe
のような方法は、専用メモリに新しい実行可能コードを作成しますが、このページのExecのプロパティを設定していない非常に古いプログラムのために使用されるべきで、注意したいです。新しいプログラムでは、Firefoxやクロム/クロム、または任意の近代的なJITのように、DEPが有効であるべきであり、JITがきめ細かくでメモリアクセス権を管理します。