unicorn/bindings/java/tests/RegressionTests.java

68 lines
2.2 KiB
Java
Raw Normal View History

package tests;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import unicorn.Unicorn;
import unicorn.UnicornException;
import unicorn.CodeHook;
public class RegressionTests {
/** Test for GH #1539: Unable to read ARM64 v or q register using java binding */
@Test
public void testARM64VReg() {
Unicorn uc = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM);
uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0x1);
uc.reg_write(Unicorn.UC_ARM64_REG_V0, 0x2);
uc.reg_read(Unicorn.UC_ARM64_REG_X0);
uc.reg_read(Unicorn.UC_ARM64_REG_V0); // should not crash
uc.close();
}
/** Test for GH #1164: Java binding use CodeHook on Windows, will invoke callback before every instruction */
@Test
public void testCodeHookRunsOnce() {
byte[] ARM_CODE =
{ 55, 0, (byte) 0xa0, (byte) 0xe3, 3, 16, 66, (byte) 0xe0 }; // mov r0, #0x37; sub r1, r2, r3
int ADDRESS = 0x10000;
final int[] hook_count = { 0 };
Unicorn u = new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_ARM);
u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL);
u.mem_write(ADDRESS, ARM_CODE);
u.hook_add((CodeHook) (uc, address, size, user) -> hook_count[0] += 1,
ADDRESS, ADDRESS, null);
u.emu_start(ADDRESS, ADDRESS + ARM_CODE.length, 0, 0);
assertEquals("Hook should only be called once", 1, hook_count[0]);
u.close();
}
/** Test that close() can be called multiple times without crashing */
@Test
public void testCloseIdempotent() {
Unicorn u = new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_ARM);
u.close();
u.close();
}
/** Test that close() can be called multiple times without crashing */
@Test
public void testUnicornsWillGC() {
final boolean[] close_called = { false };
new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_ARM) {
@Override
public void close() throws UnicornException {
close_called[0] = true;
super.close();
}
};
System.gc();
System.runFinalization();
assertEquals("close() was called", true, close_called[0]);
}
}