mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1478036: Ensure that inproc nop-space patches use atomic writes; r=handyman
--HG-- extra : rebase_source : 9542cd801a8d4589e47d161c17c92552db468e7a
This commit is contained in:
parent
b231c55815
commit
9669df786c
@ -122,6 +122,14 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(_M_IX86)
|
||||
bool WriteAtomic(void* aDestPtr, const uint16_t aValue) const
|
||||
{
|
||||
*static_cast<uint16_t*>(aDestPtr) = aValue;
|
||||
return true;
|
||||
}
|
||||
#endif // defined(_M_IX86)
|
||||
|
||||
bool Protect(void* aVAddress, size_t aSize, uint32_t aProtFlags,
|
||||
uint32_t* aPrevProtFlags) const
|
||||
{
|
||||
|
@ -51,8 +51,7 @@ public:
|
||||
}
|
||||
|
||||
// mov edi, edi
|
||||
fn.WriteShort(0xff8b);
|
||||
fn.Commit();
|
||||
fn.CommitAndWriteShort(0xff8b);
|
||||
}
|
||||
|
||||
mPatchedFns.clear();
|
||||
@ -206,8 +205,7 @@ public:
|
||||
sizeof(uint16_t));
|
||||
|
||||
// Short jump up into our long jump.
|
||||
writableFn.WriteShort(0xF9EB); // jmp $-5
|
||||
return writableFn.Commit();
|
||||
return writableFn.CommitAndWriteShort(0xF9EB); // jmp $-5
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -177,6 +177,9 @@ public:
|
||||
}
|
||||
|
||||
mMMPolicy.FlushInstructionCache();
|
||||
|
||||
mStartWriteOffset += mLocalBytes.length();
|
||||
|
||||
mLocalBytes.clear();
|
||||
return true;
|
||||
}
|
||||
@ -228,6 +231,53 @@ public:
|
||||
mOffset += sizeof(uint16_t);
|
||||
}
|
||||
|
||||
#if defined(_M_IX86)
|
||||
private:
|
||||
template <typename T>
|
||||
bool CommitAndWriteShortInternal(const T& aMMPolicy, void* aDest, uint16_t aValue);
|
||||
|
||||
template <>
|
||||
bool CommitAndWriteShortInternal<MMPolicyInProcess>(const MMPolicyInProcess& aMMPolicy,
|
||||
void* aDest, uint16_t aValue)
|
||||
{
|
||||
return aMMPolicy.WriteAtomic(aDest, aValue);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool CommitAndWriteShortInternal<MMPolicyOutOfProcess>(const MMPolicyOutOfProcess& aMMPolicy,
|
||||
void* aDest, uint16_t aValue)
|
||||
{
|
||||
return aMMPolicy.Write(aDest, &aValue, sizeof(uint16_t));
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Commits any dirty writes, and then writes a short, atomically if possible.
|
||||
* This call may succeed in both inproc and outproc cases, but atomicity
|
||||
* is only guaranteed in the inproc case.
|
||||
*/
|
||||
bool CommitAndWriteShort(const uint16_t aValue)
|
||||
{
|
||||
// First, commit everything that has been written until now
|
||||
if (!Commit()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now immediately write the short, atomically if inproc
|
||||
bool ok = CommitAndWriteShortInternal(mMMPolicy,
|
||||
reinterpret_cast<void*>(mFunc +
|
||||
mStartWriteOffset),
|
||||
aValue);
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mMMPolicy.FlushInstructionCache();
|
||||
mStartWriteOffset += sizeof(uint16_t);
|
||||
return true;
|
||||
}
|
||||
#endif // defined(_M_IX86)
|
||||
|
||||
void WriteDisp32(const uintptr_t aAbsTarget)
|
||||
{
|
||||
intptr_t diff = static_cast<intptr_t>(aAbsTarget) -
|
||||
|
Loading…
Reference in New Issue
Block a user