mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 02:17:35 +00:00
UserspaceEmulator: Warn on conditional op with uninitialized dependency
We now track whether the flags register is tainted by the use of one or more uninitialized values in a computation. For now, the state is binary; the flags are either tainted or not. We could be more precise about this and only taint the specific flags that get updated by each instruction, but I think this will already get us 99% of the results we want. :^)
This commit is contained in:
parent
30025dd576
commit
e634fe6072
2 changed files with 87 additions and 26 deletions
|
@ -421,6 +421,26 @@ public:
|
|||
template<bool check_zf, typename Callback>
|
||||
void do_once_or_repeat(const X86::Instruction& insn, Callback);
|
||||
|
||||
template<typename A>
|
||||
void taint_flags_from(const A& a)
|
||||
{
|
||||
m_flags_tainted = a.is_uninitialized();
|
||||
}
|
||||
|
||||
template<typename A, typename B>
|
||||
void taint_flags_from(const A& a, const B& b)
|
||||
{
|
||||
m_flags_tainted = a.is_uninitialized() || b.is_uninitialized();
|
||||
}
|
||||
|
||||
template<typename A, typename B, typename C>
|
||||
void taint_flags_from(const A& a, const B& b, const C& c)
|
||||
{
|
||||
m_flags_tainted = a.is_uninitialized() || b.is_uninitialized() || c.is_uninitialized();
|
||||
}
|
||||
|
||||
void warn_if_flags_tainted(const char* message) const;
|
||||
|
||||
// ^X86::InstructionStream
|
||||
virtual bool can_read() override { return false; }
|
||||
virtual u8 read8() override;
|
||||
|
@ -958,6 +978,8 @@ private:
|
|||
u16 m_segment[8] { 0 };
|
||||
u32 m_eflags { 0 };
|
||||
|
||||
bool m_flags_tainted { false };
|
||||
|
||||
u32 m_eip { 0 };
|
||||
|
||||
const u8* m_cached_code_ptr { nullptr };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue