Unicorn2 Devblog: What's new and What will be new

Preface

It’s exciting to announce the release of Unicorn2 after more than 6 years. The release note is rather short and concise and this post would elaborate on what Unicorn2 would offer in a bit more details.

What’s new?

Obviously, this should be the first you may notice, a new log.

QEMU5

Unicorn1 was forked from QEMU 2.2.1 while Unicorn2 is based on QEMU 5.0.1. This bump provides tons of bugfix, better support for new ISA and about 10%-20% speedup.

New architectures

Compared to Unicorn1, Unicorn2 offers two new architectures: PPC && RISC-V.

New API

Unicorn2 has three new APIs while still keeps forward compatibility:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*
Map MMIO in for emulation.
This API adds a MMIO region that can be used by emulation.

@uc: handle returned by uc_open()
@address: starting address of the new MMIO region to be mapped in.
This address must be aligned to 4KB, or this will return with UC_ERR_ARG error.
@size: size of the new MMIO region to be mapped in.
This size must be multiple of 4KB, or this will return with UC_ERR_ARG error.
@read_cb: function for handling reads from this MMIO region.
@user_data_read: user-defined data. This will be passed to @read_cb function in its
last argument @user_data
@write_cb: function for handling writes to this MMIO region.
@user_data_write: user-defined data. This will be passed to @write_cb function in its
last argument @user_data
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_mmio_map(uc_engine *uc, uint64_t address, size_t size,
uc_cb_mmio_read_t read_cb, void *user_data_read,
uc_cb_mmio_write_t write_cb, void *user_data_write);
/*
Write value to a register of a context.

@ctx: handle returned by uc_context_alloc()
@regid: register ID that is to be modified.
@value: pointer to the value that will set to register @regid

@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_context_reg_write(uc_context *ctx, int regid, const void *value);

/*
Read register value from a context.

@ctx: handle returned by uc_context_alloc()
@regid: register ID that is to be retrieved.
@value: pointer to a variable storing the register value.

@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_context_reg_read(uc_context *ctx, int regid, void *value);

New supported platforms

Unicorn2 is supported to compile on Apple Silicon and Android. Make sure you follow the latest compilation guide.

New unit tests

The unit tests in Unicorn1 are not maintained for quite a long time and we bring it back in Unicorn2.

Rust bindings

We receive lots of request from rustaceans and Unicorn2 would have a better rust bindings.

New wiki and documents

See Github wiki.

New maintainer

Yes, it’s me. Let’s make Unicorn2 move further. ;)

What will be new?

A good reference is the current (and future) milestone. Roughly speaking, I have a list here:

  • Refine some bindings I’m familiar with, like golang etc
  • Integrate unicornafl to our code base.
  • Migrate old regress tests to unit tests.
  • Maybe some new API and functionality.
  • Better documents, both for users and developers.
  • Bugfix.

Since Unicorn is always an open source project, I look forward to all of your contributions!