1 #include "core/instance.hpp"
2 #include "core/messages.hpp"
3 #include "library/lua-base.hpp"
4 #include "library/lua-params.hpp"
5 #include "library/lua-class.hpp"
6 #include "library/memoryspace.hpp"
7 #include "library/serialization.hpp"
8 #include "library/string.hpp"
9 #include "lua/address.hpp"
10 #include "lua/internal.hpp"
14 template<typename T
> T
bswap(T val
)
17 serialization::swap_endian(val2
);
22 uint64_t lua_get_vmabase(const std::string
& vma
)
24 for(auto i
: CORE().memory
->get_regions())
27 throw std::runtime_error("No such VMA");
30 uint64_t lua_get_read_address(lua::parameters
& P
)
32 static std::map
<std::string
, char> deprecation_keys
;
33 char* deprecation
= &deprecation_keys
[P
.get_fname()];
35 if(P
.is
<lua_address
>()) {
36 return P
.arg
<lua_address
*>()->get();
37 } else if(P
.is_string())
38 vmabase
= lua_get_vmabase(P
.arg
<std::string
>());
41 if(P
.get_state().do_once(deprecation
))
42 messages
<< P
.get_fname() << ": Global memory form is deprecated." << std::endl
;
44 auto addr
= P
.arg
<uint64_t>();
45 return addr
+ vmabase
;
48 lua_address::lua_address(lua::state
& L
)
52 int lua_address::create(lua::state
& L
, lua::parameters
& P
)
54 lua_address
* a
= lua::_class
<lua_address
>::create(L
);
59 std::string
lua_address::print()
61 return (stringfmt() << vma
<< "+0x" << std::hex
<< addr
).str();
64 uint64_t lua_address::get()
66 for(auto i
: CORE().memory
->get_regions())
69 return i
->base
+ addr
;
70 (stringfmt() << "Address outside boound of memory area '" << vma
<< "' (" << std::hex
71 << addr
<< ">=" << std::hex
<< i
->size
<< ")").throwex();
73 throw std::runtime_error("No such memory area '" + vma
+ "'");
76 std::string
lua_address::get_vma()
81 uint64_t lua_address::get_offset()
83 for(auto i
: CORE().memory
->get_regions())
87 (stringfmt() << "Address outside boound of memory area '" << vma
<< "' (" << std::hex
88 << addr
<< ">=" << std::hex
<< i
->size
<< ")").throwex();
90 throw std::runtime_error("No such memory area '" + vma
+ "'");
93 int lua_address::l_get(lua::state
& L
, lua::parameters
& P
)
99 int lua_address::l_get_vma(lua::state
& L
, lua::parameters
& P
)
101 L
.pushlstring(get_vma());
105 int lua_address::l_get_offset(lua::state
& L
, lua::parameters
& P
)
107 L
.pushnumber(get_offset());
111 int lua_address::l_shift(lua::state
& L
, lua::parameters
& P
)
114 int64_t a
= 0, b
= 0, c
= 0;
126 lua_address
* adr
= lua::_class
<lua_address
>::create(L
);
137 adr
->addr
+= a
* b
+ c
;
143 int lua_address::l_replace(lua::state
& L
, lua::parameters
& P
)
148 P(P
.skipped(), newoffset
, P
.optional(bits
, -1));
150 lua_address
* adr
= lua::_class
<lua_address
>::create(L
);
153 adr
->addr
= newoffset
;
155 uint64_t mask
= ((1 << bits
) - 1);
156 adr
->addr
= (addr
& ~mask
) | (newoffset
& mask
);
161 template<class T
, bool _bswap
> int lua_address::rw(lua::state
& L
, lua::parameters
& P
)
170 T val
= core
.memory
->read
<T
>(get());
171 if(_bswap
) val
= bswap(val
);
174 } else if(P
.is_number()) {
177 if(_bswap
) val
= bswap(val
);
178 core
.memory
->write
<T
>(get(), val
);
181 P
.expected("number or nil");
182 return 0; //NOTREACHED
185 size_t lua_address::overcommit()
192 lua::_class
<lua_address
> LUA_class_address(lua_class_memory
, "ADDRESS", {
193 {"new", lua_address::create
},
195 {"addr", &lua_address::l_get
},
196 {"vma", &lua_address::l_get_vma
},
197 {"offset", &lua_address::l_get_offset
},
198 {"add", &lua_address::l_shift
},
199 {"replace", &lua_address::l_replace
},
200 {"sbyte", &lua_address::rw
<int8_t, false>},
201 {"byte", &lua_address::rw
<uint8_t, false>},
202 {"sword", &lua_address::rw
<int16_t, false>},
203 {"word", &lua_address::rw
<uint16_t, false>},
204 {"shword", &lua_address::rw
<ss_int24_t
, false>},
205 {"hword", &lua_address::rw
<ss_uint24_t
, false>},
206 {"sdword", &lua_address::rw
<int32_t, false>},
207 {"dword", &lua_address::rw
<uint32_t, false>},
208 {"sqword", &lua_address::rw
<int64_t, false>},
209 {"qword", &lua_address::rw
<uint64_t, false>},
210 {"float", &lua_address::rw
<float, false>},
211 {"double", &lua_address::rw
<double, false>},
212 {"isbyte", &lua_address::rw
<int8_t, true>},
213 {"ibyte", &lua_address::rw
<uint8_t, true>},
214 {"isword", &lua_address::rw
<int16_t, true>},
215 {"iword", &lua_address::rw
<uint16_t, true>},
216 {"ishword", &lua_address::rw
<ss_int24_t
, true>},
217 {"ihword", &lua_address::rw
<ss_uint24_t
, true>},
218 {"isdword", &lua_address::rw
<int32_t, true>},
219 {"idword", &lua_address::rw
<uint32_t, true>},
220 {"isqword", &lua_address::rw
<int64_t, true>},
221 {"iqword", &lua_address::rw
<uint64_t, true>},
222 {"ifloat", &lua_address::rw
<float, true>},
223 {"idouble", &lua_address::rw
<double, true>},
224 }, &lua_address::print
);