1 #include "lua/internal.hpp"
2 #include "core/instance.hpp"
3 #include "core/memorymanip.hpp"
4 #include "library/memoryspace.hpp"
5 #include "library/minmax.hpp"
12 compare_obj(lua::state
& L
, uint64_t addr
, uint64_t size
, uint64_t rows
, uint64_t stride
);
13 static size_t overcommit(uint64_t addr
, uint64_t size
, uint64_t rows
, uint64_t stride
)
15 return lua::overcommit_std_align
+ (size_t)size
* rows
;
17 static int create(lua::state
& L
, lua::parameters
& P
);
18 int call(lua::state
& L
, lua::parameters
& P
);
22 x
<< "addr=0x" << std::hex
<< addr
<< " rows=" << rows
<< " size=0x" << std::hex
<< size
23 << " stride=0x" << std::hex
<< stride
;
37 compare_obj::compare_obj(lua::state
& L
, uint64_t _addr
, uint64_t _size
, uint64_t _rows
, uint64_t _stride
)
39 if(!_size
|| !_rows
) {
55 rpair(minaddr
, maxaddr
) = memoryspace_row_bounds(addr
, size
, rows
, stride
);
56 try_map
= (minaddr
<= maxaddr
&& (maxaddr
- minaddr
+ 1));
57 if((((size_t)size
* rows
) + lua::overcommit_std_align
) / rows
< size
)
58 throw std::runtime_error("Size to monitor too large");
59 prev
= lua::align_overcommit
<compare_obj
, uint8_t>(this);
60 memset(prev
, 0, (size_t)size
* rows
);
64 int compare_obj::create(lua::state
& L
, lua::parameters
& P
)
67 uint64_t stride
= 0, rows
= 1;
69 addr
= lua_get_read_address(P
);
70 P(size
, P
.optional(rows
, 1));
74 compare_obj
* o
= lua::_class
<compare_obj
>::create(L
, addr
, size
, rows
, stride
);
80 int compare_obj::call(lua::state
& L
, lua::parameters
& P
)
84 char* pbuffer
= try_map
? core
.memory
->get_physical_mapping(minaddr
, maxaddr
- minaddr
+ 1) :
88 uint64_t offset
= addr
- minaddr
;
89 for(uint64_t i
= 0; i
< rows
; i
++) {
90 bool eq
= !memcmp(&prev
[i
* size
], pbuffer
+ offset
, size
);
92 memcpy(&prev
[i
* size
], pbuffer
+ offset
, size
);
98 for(uint64_t i
= 0; i
< rows
; i
++) {
99 uint64_t addr1
= addr
+ i
* stride
;
100 uint64_t addr2
= i
* size
;
101 for(uint64_t j
= 0; j
< size
; j
++) {
102 uint8_t byte
= core
.memory
->read
<uint8_t>(addr1
+ j
);
103 bool eq
= prev
[addr2
+ j
] == (char)byte
;
105 prev
[addr2
+ j
] = byte
;
110 L
.pushboolean(!equals
);
114 lua::_class
<compare_obj
> LUA_class_vmalist(lua_class_memory
, "COMPARE_OBJ", {
115 {"new", compare_obj::create
},
117 {"__call", &compare_obj::call
},
118 }, &compare_obj::print
);