Skip to content

Instantly share code, notes, and snippets.

@oupo
Created June 5, 2010 12:37
Show Gist options
  • Select an option

  • Save oupo/426595 to your computer and use it in GitHub Desktop.

Select an option

Save oupo/426595 to your computer and use it in GitHub Desktop.
DeSmuME スタックトレース その2
diff -up src-orig/arm_instructions.cpp src/arm_instructions.cpp
--- src-orig/arm_instructions.cpp 2010-04-18 02:11:20.000000000 +0900
+++ src/arm_instructions.cpp 2010-06-04 18:45:54.625000000 +0900
@@ -6376,6 +6376,12 @@ TEMPLATE static u32 FASTCALL OP_STMDB_W
u32 c = 0, b;
u32 start = cpu->R[REG_POS(i,16)];
+#ifdef HAVE_LUA
+ if (REG_POS(i,16) == 13 && BIT_N(i, 14) && PROCNUM == 0) {
+ CallRegisteredLuaFunctions(LUACALL_ENTERFUNCTION);
+ }
+#endif
+
for(b=0; b<16; ++b)
{
if(BIT_N(i, 15-b))
diff -up src-orig/lua-engine.cpp src/lua-engine.cpp
--- src-orig/lua-engine.cpp 2010-02-04 15:22:54.000000000 +0900
+++ src/lua-engine.cpp 2010-06-04 18:20:34.328125000 +0900
@@ -154,6 +154,8 @@ static const char* luaCallIDStrings [] =
"CALL_HOTKEY_14",
"CALL_HOTKEY_15",
"CALL_HOTKEY_16",
+
+ "CALL_ENTERFUNCTION",
};
static const int _makeSureWeHaveTheRightNumberOfStrings [sizeof(luaCallIDStrings)/sizeof(*luaCallIDStrings) == LUACALL_COUNT ? 1 : 0];
@@ -393,6 +395,18 @@ DEFINE_LUA_FUNCTION(input_registerhotkey
}
}
+DEFINE_LUA_FUNCTION(emu_registerenterfunc, "func")
+{
+ if (!lua_isnil(L,1))
+ luaL_checktype(L, 1, LUA_TFUNCTION);
+ lua_settop(L,1);
+ lua_getfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_ENTERFUNCTION]);
+ lua_insert(L,1);
+ lua_setfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_ENTERFUNCTION]);
+ StopScriptIfFinished(luaStateToUIDMap[L->l_G->mainthread]);
+ return 1;
+}
+
static int doPopup(lua_State* L, const char* deftype, const char* deficon)
{
const char* str = toCString(L,1);
@@ -4126,6 +4140,7 @@ static const struct luaL_reg emulib [] =
{"reset", emu_reset},
// alternative names
// {"openrom", emu_loadrom},
+ {"registerenterfunc", emu_registerenterfunc},
{NULL, NULL}
};
static const struct luaL_reg guilib [] =
diff -up src-orig/lua-engine.h src/lua-engine.h
--- src-orig/lua-engine.h 2009-10-17 00:46:36.000000000 +0900
+++ src/lua-engine.h 2010-06-04 17:16:47.296875000 +0900
@@ -37,6 +37,8 @@ enum LuaCallID
LUACALL_SCRIPT_HOTKEY_15,
LUACALL_SCRIPT_HOTKEY_16,
+ LUACALL_ENTERFUNCTION,
+
LUACALL_COUNT
};
void CallRegisteredLuaFunctions(LuaCallID calltype);
diff -up src-orig/thumb_instructions.cpp src/thumb_instructions.cpp
--- src-orig/thumb_instructions.cpp 2010-04-18 20:51:46.000000000 +0900
+++ src/thumb_instructions.cpp 2010-06-04 18:45:39.250000000 +0900
@@ -869,6 +869,11 @@ TEMPLATE static u32 FASTCALL OP_PUSH_LR
u32 adr = cpu->R[13] - 4;
u32 c = 0, j;
+#ifdef HAVE_LUA
+ if (PROCNUM == 0) {
+ CallRegisteredLuaFunctions(LUACALL_ENTERFUNCTION);
+ }
+#endif
WRITE32(cpu->mem_if->data, adr, cpu->R[14]);
c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_WRITE>(adr);
adr -= 4;
local call_stack = {}
local call_count_map = {}
emu.registerenterfunc(function()
if get_cpsr().mode == 18 then -- IRQ mode
return
end
local addr = get_current_insn_addr()
local sp = memory.getregister("r13")
while #call_stack > 0 do
local last = call_stack[#call_stack]
if last.sp > sp then break end
table.remove(call_stack)
end
if not next(call_count_map) then
print("enterfunc callback")
end
call_stack[#call_stack+1] = {
caller = memory.getregister("r14"),
callee = addr,
is_thumb = is_thumb_state(),
callee_id = inc_call_count(addr),
sp = sp
}
end)
function inc_call_count(addr)
local id = (call_count_map[addr] or 0)
call_count_map[addr] = id + 1
return id
end
function inspect_stacktrace(stacktrace)
local lines = {}
for k,v in ipairs(stacktrace) do
lines[#lines+1] = string.format("%.8x,%.8x(%d)%s,%.8x",
v.caller, v.callee, v.callee_id,
v.is_thumb and " T" or "", v.sp)
end
return table.concat(lines, "\r\n")
end
function print_stacktrace()
print("caller callee sp")
print(inspect_stacktrace(call_stack))
print("-------------------------------")
end
function get_current_insn_addr()
local pc = memory.getregister("r15")
return pc - (is_thumb_state() and 4 or 8)
end
function is_thumb_state()
return get_cpsr().t
end
function get_cpsr()
local cpsr = memory.getregister("cpsr")
return {
mode = bit.band(cpsr, 31),
t = bit.band(bit.rshift(cpsr, 5), 1) ~= 0,
f = bit.band(bit.rshift(cpsr, 6), 1) ~= 0,
i = bit.band(bit.rshift(cpsr, 7), 1) ~= 0,
raz = bit.band(bit.rshift(cpsr, 8), 0x7ffff),
q = bit.band(bit.rshift(cpsr, 27), 1) ~= 0,
v = bit.band(bit.rshift(cpsr, 28), 1) ~= 0,
c = bit.band(bit.rshift(cpsr, 29), 1) ~= 0,
z = bit.band(bit.rshift(cpsr, 30), 1) ~= 0,
n = bit.band(bit.rshift(cpsr, 31), 1) ~= 0,
}
end
@oupo
Copy link
Author

oupo commented Jun 5, 2010

http://gist.github.com/418914 の改良版。

  • ARMステートに対応
  • POP {...,PC}命令のフックは必要なくPUSH {...,LR}命令だけでいいんじゃないのと気づいたので変更
  • スタックトレースの処理はLuaスクリプトへのコールバックで任せることにしていちいち変更するたびコンパイルしなくていいように(その代わり遅くなった

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment