Skip to content

Commit a3d6da4

Browse files
committed
Improve dynamic call array by checking at load-time
1 parent 2e613b8 commit a3d6da4

File tree

3 files changed

+18
-16
lines changed

3 files changed

+18
-16
lines changed

engine/src/script/script.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -395,19 +395,6 @@ void Script::dynamic_call_hash(uint32_t hash, gaddr_t straddr)
395395
}
396396
}
397397

398-
void Script::dynamic_call_array(uint32_t idx)
399-
{
400-
while (true) {
401-
try {
402-
this->m_dyncall_array.at(idx)(*this);
403-
return;
404-
} catch (const std::exception& e) {
405-
// This will re-throw unless a new dynamic call is discovered
406-
this->dynamic_call_error(idx, e);
407-
}
408-
}
409-
}
410-
411398
void Script::dynamic_call_error(uint32_t idx, const std::exception& e)
412399
{
413400
const uint32_t entries = machine().memory.read<uint32_t> (m_g_dyncall_table);

engine/src/script/script.hpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ struct Script
120120
static void
121121
set_dynamic_calls(std::vector<std::tuple<std::string, std::string, ghandler_t>>);
122122
void dynamic_call_hash(uint32_t hash, gaddr_t strname);
123-
void dynamic_call_array(uint32_t idx);
123+
void dynamic_call_array_unchecked(uint32_t idx);
124124

125125
/// @brief Retrieve arguments passed to a dynamic call, specifying each type.
126126
/// @tparam ...Args The types of arguments to retrieve.
@@ -556,3 +556,16 @@ template <typename T> inline GuestObjects<T> Script::guest_alloc(size_t n)
556556
}
557557
throw std::runtime_error("Unable to allocate guest objects");
558558
}
559+
560+
inline void Script::dynamic_call_array_unchecked(uint32_t idx)
561+
{
562+
while (true) {
563+
try {
564+
this->m_dyncall_array[idx](*this);
565+
return;
566+
} catch (const std::exception& e) {
567+
// This will re-throw unless a new dynamic call is discovered
568+
this->dynamic_call_error(idx, e);
569+
}
570+
}
571+
}

engine/src/script/script_syscalls.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ void Script::setup_syscall_interface()
191191
[](CPU<MARCH>& cpu, rv32i_instruction instr)
192192
{
193193
auto& scr = script(cpu.machine());
194-
scr.dynamic_call_array(instr.Itype.imm);
194+
scr.dynamic_call_array_unchecked(instr.Itype.imm);
195195
},
196196
[](char* buffer, size_t len, auto&, rv32i_instruction instr)
197197
{
@@ -250,7 +250,9 @@ void Script::setup_syscall_interface()
250250
{
251251
if (instr.opcode() == 0b1011011)
252252
{
253-
return dyncall_instruction_handler;
253+
if (instr.Itype.imm < ECALL_LAST - GAME_API_BASE)
254+
return dyncall_instruction_handler;
255+
throw std::runtime_error("Invalid dynamic call found in program");
254256
}
255257
if (instr.opcode() == 0b0001011)
256258
{

0 commit comments

Comments
 (0)