mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-07-18 03:47:47 +00:00
merge upstream/noglib and update some glib related types
This commit is contained in:
commit
f8f9e993a8
7
Makefile
7
Makefile
|
@ -58,6 +58,9 @@ UNICORN_CFLAGS += -fPIC
|
||||||
# Verbose output?
|
# Verbose output?
|
||||||
V ?= 0
|
V ?= 0
|
||||||
|
|
||||||
|
# on MacOS, compile in Universal format by default
|
||||||
|
MACOS_UNIVERSAL ?= yes
|
||||||
|
|
||||||
ifeq ($(UNICORN_DEBUG),yes)
|
ifeq ($(UNICORN_DEBUG),yes)
|
||||||
CFLAGS += -g
|
CFLAGS += -g
|
||||||
else
|
else
|
||||||
|
@ -177,9 +180,9 @@ LIBDATADIR ?= $(LIBDIR)
|
||||||
|
|
||||||
ifndef USE_GENERIC_LIBDATADIR
|
ifndef USE_GENERIC_LIBDATADIR
|
||||||
ifeq ($(UNAME_S), FreeBSD)
|
ifeq ($(UNAME_S), FreeBSD)
|
||||||
LIBDATADIR = $(DESTDIR)$(PREFIX)/libdata
|
LIBDATADIR = $(PREFIX)/libdata
|
||||||
else ifeq ($(UNAME_S), DragonFly)
|
else ifeq ($(UNAME_S), DragonFly)
|
||||||
LIBDATADIR = $(DESTDIR)$(PREFIX)/libdata
|
LIBDATADIR = $(PREFIX)/libdata
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -8,24 +8,10 @@ To compile for Microsoft Windows, see [COMPILE-WINDOWS.md](COMPILE-WINDOWS.md)
|
||||||
|
|
||||||
[0] Dependencies
|
[0] Dependencies
|
||||||
|
|
||||||
Unicorn requires few dependent packages as follows.
|
For MacOS, Unicorn requires "pkg-config" package.
|
||||||
|
Brew users can install this with:
|
||||||
- For Mac OS X, "pkg-config" and "glib" are needed.
|
|
||||||
Brew users can install "pkg-config" and "glib" with:
|
|
||||||
|
|
||||||
$ brew install pkg-config glib
|
|
||||||
|
|
||||||
NOTE: to build Unicorn universal binaries (which support both 32-bit &
|
|
||||||
64-bit), you need to have glib in universal format. To do that, build &
|
|
||||||
install glib with:
|
|
||||||
|
|
||||||
$ brew install glib --universal
|
|
||||||
|
|
||||||
- For Linux, "glib2-dev" is needed.
|
|
||||||
Ubuntu/Debian users can install this with:
|
|
||||||
|
|
||||||
$ sudo apt-get install libglib2.0-dev
|
|
||||||
|
|
||||||
|
$ brew install pkg-config
|
||||||
|
|
||||||
|
|
||||||
[1] Tailor Unicorn to your need.
|
[1] Tailor Unicorn to your need.
|
||||||
|
@ -75,12 +61,8 @@ To build Unicorn on *nix (such as MacOSX, Linux, *BSD, Solaris):
|
||||||
|
|
||||||
$ UNICORN_QEMU_FLAGS="--python=/path/to/python2" ./make.sh
|
$ UNICORN_QEMU_FLAGS="--python=/path/to/python2" ./make.sh
|
||||||
|
|
||||||
- To cross-compile Unicorn on 64-bit Linux to target 32-bit binary, install
|
- To cross-compile Unicorn on 64-bit Linux to target 32-bit binary,
|
||||||
libglib2.0-dev for i386. On Ubuntu, this can be done with:
|
cross-compile to 32-bit with:
|
||||||
|
|
||||||
$ sudo apt-get install libglib2.0-dev:i386
|
|
||||||
|
|
||||||
Then cross-compile to 32-bit with:
|
|
||||||
|
|
||||||
$ ./make.sh linux32
|
$ ./make.sh linux32
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,8 @@ To compile for Linux, Mac OS X and Unix-based OS, see [COMPILE-NIX.md](COMPILE-N
|
||||||
|
|
||||||
[0] Dependencies
|
[0] Dependencies
|
||||||
|
|
||||||
For Windows, cross-compile requires Mingw. Mingw-glib2 is needed.
|
For Windows, cross-compile requires Mingw. At the moment, it is confirmed that
|
||||||
At the moment, it is confirmed that Unicorn can be compiled either on Ubuntu
|
Unicorn can be compiled either on Ubuntu or Windows.
|
||||||
or Windows.
|
|
||||||
|
|
||||||
- On Ubuntu 14.04 64-bit, do:
|
- On Ubuntu 14.04 64-bit, do:
|
||||||
|
|
||||||
|
@ -17,14 +16,6 @@ or Windows.
|
||||||
|
|
||||||
https://launchpad.net/~greg-hellings/+archive/ubuntu/mingw-libs/+build/2924251
|
https://launchpad.net/~greg-hellings/+archive/ubuntu/mingw-libs/+build/2924251
|
||||||
|
|
||||||
- To cross-compile for Windows 32-bit, install Mingw with (ignore all the warnings):
|
|
||||||
|
|
||||||
$ sudo dpkg -i --force-depends mingw64-x86-glib2_2.31.0_all.deb
|
|
||||||
|
|
||||||
To cross-compile for Windows 64-bit, install Mingw with:
|
|
||||||
|
|
||||||
$ sudo dpkg -i --force-depends mingw64-x64-glib2_2.31.0_all.deb
|
|
||||||
|
|
||||||
|
|
||||||
- On Windows, install MinGW via package MSYS2 at https://msys2.github.io/
|
- On Windows, install MinGW via package MSYS2 at https://msys2.github.io/
|
||||||
|
|
||||||
|
@ -43,7 +34,6 @@ or Windows.
|
||||||
$ pacman -S python2
|
$ pacman -S python2
|
||||||
$ pacman -S make
|
$ pacman -S make
|
||||||
$ pacman -S pkg-config
|
$ pacman -S pkg-config
|
||||||
$ pacman -S mingw-w64-i686-glib2
|
|
||||||
$ pacman -S mingw-w64-i686-toolchain
|
$ pacman -S mingw-w64-i686-toolchain
|
||||||
|
|
||||||
- To compile for Windows 64-bit, run:
|
- To compile for Windows 64-bit, run:
|
||||||
|
@ -51,15 +41,14 @@ or Windows.
|
||||||
$ pacman -S python2
|
$ pacman -S python2
|
||||||
$ pacman -S make
|
$ pacman -S make
|
||||||
$ pacman -S pkg-config
|
$ pacman -S pkg-config
|
||||||
$ pacman -S mingw-w64-x86_64-glib2
|
|
||||||
$ pacman -S mingw-w64-x86_64-toolchain
|
$ pacman -S mingw-w64-x86_64-toolchain
|
||||||
|
|
||||||
- For Cygwin, "make", "gcc-core", "pkg-config", "libpcre-devel", "zlib-devel"
|
- For Cygwin, "make", "gcc-core", "pkg-config", "libpcre-devel", "zlib-devel"
|
||||||
and "libglib2.0-devel" are needed.
|
are needed.
|
||||||
|
|
||||||
If apt-cyg is available, you can install these with:
|
If apt-cyg is available, you can install these with:
|
||||||
|
|
||||||
$ apt-cyg install make gcc-core pkg-config libpcre-devel zlib-devel libglib2.0-devel
|
$ apt-cyg install make gcc-core pkg-config libpcre-devel zlib-devel
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,7 +100,6 @@ To run sample_x86.exe on Windows 32-bit, you need the following files:
|
||||||
|
|
||||||
unicorn.dll
|
unicorn.dll
|
||||||
%MSYS2%\mingw32\bin\libgcc_s_dw2-1.dll
|
%MSYS2%\mingw32\bin\libgcc_s_dw2-1.dll
|
||||||
%MSYS2%\mingw32\bin\libglib-2.0-0.dll
|
|
||||||
%MSYS2%\mingw32\bin\libiconv-2.dll
|
%MSYS2%\mingw32\bin\libiconv-2.dll
|
||||||
%MSYS2%\mingw32\bin\libintl-8.dll
|
%MSYS2%\mingw32\bin\libintl-8.dll
|
||||||
%MSYS2%\mingw32\bin\libpcre-1.dll
|
%MSYS2%\mingw32\bin\libpcre-1.dll
|
||||||
|
@ -121,7 +109,6 @@ To run sample_x86.exe on Windows 64-bit, you need the following files:
|
||||||
|
|
||||||
unicorn.dll
|
unicorn.dll
|
||||||
%MSYS2%\mingw64\bin\libgcc_s_seh-1.dll
|
%MSYS2%\mingw64\bin\libgcc_s_seh-1.dll
|
||||||
%MSYS2%\mingw64\bin\libglib-2.0-0.dll
|
|
||||||
%MSYS2%\mingw64\bin\libiconv-2.dll
|
%MSYS2%\mingw64\bin\libiconv-2.dll
|
||||||
%MSYS2%\mingw64\bin\libintl-8.dll
|
%MSYS2%\mingw64\bin\libintl-8.dll
|
||||||
%MSYS2%\mingw64\bin\libpcre-1.dll
|
%MSYS2%\mingw64\bin\libpcre-1.dll
|
||||||
|
@ -171,14 +158,12 @@ be used on Windows machine.
|
||||||
To run sample_x86.exe on Windows 32-bit, you need the following files:
|
To run sample_x86.exe on Windows 32-bit, you need the following files:
|
||||||
|
|
||||||
unicorn.dll
|
unicorn.dll
|
||||||
/usr/i686-w64-mingw32/sys-root/mingw/bin/libglib-2.0-0.dll
|
|
||||||
/usr/lib/gcc/i686-w64-mingw32/4.8/libgcc_s_sjlj-1.dll
|
/usr/lib/gcc/i686-w64-mingw32/4.8/libgcc_s_sjlj-1.dll
|
||||||
/usr/i686-w64-mingw32/lib/libwinpthread-1.dll
|
/usr/i686-w64-mingw32/lib/libwinpthread-1.dll
|
||||||
|
|
||||||
To run sample_x86.exe on Windows 64-bit, you need the following files:
|
To run sample_x86.exe on Windows 64-bit, you need the following files:
|
||||||
|
|
||||||
unicorn.dll
|
unicorn.dll
|
||||||
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libglib-2.0-0.dll
|
|
||||||
/usr/lib/gcc/x86_64-w64-mingw32/4.8/libgcc_s_sjlj-1.dll
|
/usr/lib/gcc/x86_64-w64-mingw32/4.8/libgcc_s_sjlj-1.dll
|
||||||
/usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll
|
/usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll
|
||||||
|
|
||||||
|
|
1
make.sh
1
make.sh
|
@ -102,6 +102,7 @@ case "$1" in
|
||||||
"install" ) install;;
|
"install" ) install;;
|
||||||
"uninstall" ) uninstall;;
|
"uninstall" ) uninstall;;
|
||||||
"macos-universal" ) MACOS_UNIVERSAL=yes ${MAKE};;
|
"macos-universal" ) MACOS_UNIVERSAL=yes ${MAKE};;
|
||||||
|
"macos-universal-no" ) MACOS_UNIVERSAL=no ${MAKE};;
|
||||||
"cross-win32" ) build_cross i686-w64-mingw32;;
|
"cross-win32" ) build_cross i686-w64-mingw32;;
|
||||||
"cross-win64" ) build_cross x86_64-w64-mingw32;;
|
"cross-win64" ) build_cross x86_64-w64-mingw32;;
|
||||||
"cross-android" ) CROSS=arm-linux-androideabi ${MAKE};;
|
"cross-android" ) CROSS=arm-linux-androideabi ${MAKE};;
|
||||||
|
|
|
@ -65,7 +65,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
This may be marginally better than what glib does in their direct_hash
|
This may be marginally better than what glib does in their direct_hash
|
||||||
but someone with some chops in this space should fix if it needs improving
|
but someone with some chops in this space should fix if it needs improving
|
||||||
*/
|
*/
|
||||||
guint g_direct_hash(const void *v) {
|
guint g_direct_hash(const void *v)
|
||||||
|
{
|
||||||
#ifdef __HAVE_64_BIT_PTRS
|
#ifdef __HAVE_64_BIT_PTRS
|
||||||
uint64_t hash = (uint64_t)v;
|
uint64_t hash = (uint64_t)v;
|
||||||
hash = (hash >> 4) | (hash << 60);
|
hash = (hash >> 4) | (hash << 60);
|
||||||
|
@ -78,7 +79,8 @@ guint g_direct_hash(const void *v) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int g_direct_equal(const void *v1, const void *v2) {
|
int g_direct_equal(const void *v1, const void *v2)
|
||||||
|
{
|
||||||
return v1 == v2;
|
return v1 == v2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +88,8 @@ int g_direct_equal(const void *v1, const void *v2) {
|
||||||
djb2+ string hashing
|
djb2+ string hashing
|
||||||
see: http://www.cse.yorku.ca/~oz/hash.html
|
see: http://www.cse.yorku.ca/~oz/hash.html
|
||||||
*/
|
*/
|
||||||
guint g_str_hash(const void *v) {
|
guint g_str_hash(const void *v)
|
||||||
|
{
|
||||||
const char *s = (const char*)v;
|
const char *s = (const char*)v;
|
||||||
guint hash = 5381;
|
guint hash = 5381;
|
||||||
while (*s) {
|
while (*s) {
|
||||||
|
@ -96,7 +99,8 @@ guint g_str_hash(const void *v) {
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
int g_str_equal(const void *v1, const void *v2) {
|
int g_str_equal(const void *v1, const void *v2)
|
||||||
|
{
|
||||||
return strcmp((const char*)v1, (const char*)v2) == 0;
|
return strcmp((const char*)v1, (const char*)v2) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +108,8 @@ int g_str_equal(const void *v1, const void *v2) {
|
||||||
Bob Jenkins integer hash algorithm
|
Bob Jenkins integer hash algorithm
|
||||||
see: http://burtleburtle.net/bob/hash/integer.html
|
see: http://burtleburtle.net/bob/hash/integer.html
|
||||||
*/
|
*/
|
||||||
guint g_int_hash(const void *v) {
|
guint g_int_hash(const void *v)
|
||||||
|
{
|
||||||
guint hash = *(const guint*)v;
|
guint hash = *(const guint*)v;
|
||||||
hash = (hash + 0x7ed55d16) + (hash << 12);
|
hash = (hash + 0x7ed55d16) + (hash << 12);
|
||||||
hash = (hash ^ 0xc761c23c) ^ (hash >> 19);
|
hash = (hash ^ 0xc761c23c) ^ (hash >> 19);
|
||||||
|
@ -115,26 +120,30 @@ guint g_int_hash(const void *v) {
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
int g_int_equal(const void *v1, const void *v2) {
|
int g_int_equal(const void *v1, const void *v2)
|
||||||
|
{
|
||||||
return *(const int*)v1 == *(const int*)v2;
|
return *(const int*)v1 == *(const int*)v2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Doubly-linked list */
|
/* Doubly-linked list */
|
||||||
|
|
||||||
GList *g_list_first(GList *list) {
|
GList *g_list_first(GList *list)
|
||||||
|
{
|
||||||
if (list == NULL) return NULL;
|
if (list == NULL) return NULL;
|
||||||
while (list->prev) list = list->prev;
|
while (list->prev) list = list->prev;
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void g_list_foreach(GList *list, list_func func, void* user_data) {
|
void g_list_foreach(GList *list, GFunc func, void* user_data)
|
||||||
|
{
|
||||||
GList *lp;
|
GList *lp;
|
||||||
for (lp = list; lp; lp = lp->next) {
|
for (lp = list; lp; lp = lp->next) {
|
||||||
(*func)(lp->data, user_data);
|
(*func)(lp->data, user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void g_list_free(GList *list) {
|
void g_list_free(GList *list)
|
||||||
|
{
|
||||||
GList *lp, *next, *prev = NULL;
|
GList *lp, *next, *prev = NULL;
|
||||||
if (list) prev = list->prev;
|
if (list) prev = list->prev;
|
||||||
for (lp = list; lp; lp = next) {
|
for (lp = list; lp; lp = next) {
|
||||||
|
@ -147,7 +156,8 @@ void g_list_free(GList *list) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GList *g_list_insert_sorted(GList *list, void* data, compare_func compare) {
|
GList *g_list_insert_sorted(GList *list, void* data, GCompareFunc compare)
|
||||||
|
{
|
||||||
GList *i;
|
GList *i;
|
||||||
GList *n = (GList*)g_malloc(sizeof(GList));
|
GList *n = (GList*)g_malloc(sizeof(GList));
|
||||||
n->data = data;
|
n->data = data;
|
||||||
|
@ -170,7 +180,8 @@ GList *g_list_insert_sorted(GList *list, void* data, compare_func compare) {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
GList *g_list_prepend(GList *list, void* data) {
|
GList *g_list_prepend(GList *list, void* data)
|
||||||
|
{
|
||||||
GList *n = (GList*)g_malloc(sizeof(GList));
|
GList *n = (GList*)g_malloc(sizeof(GList));
|
||||||
n->next = list;
|
n->next = list;
|
||||||
n->prev = NULL;
|
n->prev = NULL;
|
||||||
|
@ -178,14 +189,16 @@ GList *g_list_prepend(GList *list, void* data) {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
GList *g_list_remove_link(GList *list, GList *llink) {
|
GList *g_list_remove_link(GList *list, GList *llink)
|
||||||
|
{
|
||||||
if (llink == list) list = list->next;
|
if (llink == list) list = list->next;
|
||||||
if (llink->prev) llink->prev->next = llink->next;
|
if (llink->prev) llink->prev->next = llink->next;
|
||||||
if (llink->next) llink->next->prev = llink->prev;
|
if (llink->next) llink->next->prev = llink->prev;
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
GList *g_list_sort(GList *list, compare_func compare) {
|
GList *g_list_sort(GList *list, GCompareFunc compare)
|
||||||
|
{
|
||||||
GList *i, *it, *j;
|
GList *i, *it, *j;
|
||||||
/* base case for singletons or empty lists */
|
/* base case for singletons or empty lists */
|
||||||
if (list == NULL || list->next == NULL) return list;
|
if (list == NULL || list->next == NULL) return list;
|
||||||
|
@ -235,7 +248,8 @@ GList *g_list_sort(GList *list, compare_func compare) {
|
||||||
|
|
||||||
/* Singly-linked list */
|
/* Singly-linked list */
|
||||||
|
|
||||||
GSList *g_slist_append(GSList *list, void* data) {
|
GSList *g_slist_append(GSList *list, void* data)
|
||||||
|
{
|
||||||
GSList *head = list;
|
GSList *head = list;
|
||||||
if (list) {
|
if (list) {
|
||||||
while (list->next) list = list->next;
|
while (list->next) list = list->next;
|
||||||
|
@ -250,14 +264,16 @@ GSList *g_slist_append(GSList *list, void* data) {
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
void g_slist_foreach(GSList *list, list_func func, void* user_data) {
|
void g_slist_foreach(GSList *list, GFunc func, void* user_data)
|
||||||
|
{
|
||||||
GSList *lp;
|
GSList *lp;
|
||||||
for (lp = list; lp; lp = lp->next) {
|
for (lp = list; lp; lp = lp->next) {
|
||||||
(*func)(lp->data, user_data);
|
(*func)(lp->data, user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void g_slist_free(GSList *list) {
|
void g_slist_free(GSList *list)
|
||||||
|
{
|
||||||
GSList *lp, *next;
|
GSList *lp, *next;
|
||||||
for (lp = list; lp; lp = next) {
|
for (lp = list; lp; lp = next) {
|
||||||
next = lp->next;
|
next = lp->next;
|
||||||
|
@ -265,7 +281,8 @@ void g_slist_free(GSList *list) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void g_slist_free_full(GSList *list, GDestroyNotify free_func) {
|
void g_slist_free_full(GSList *list, GDestroyNotify free_func)
|
||||||
|
{
|
||||||
GSList *lp, *next;
|
GSList *lp, *next;
|
||||||
for (lp = list; lp; lp = next) {
|
for (lp = list; lp; lp = next) {
|
||||||
next = lp->next;
|
next = lp->next;
|
||||||
|
@ -274,14 +291,16 @@ void g_slist_free_full(GSList *list, GDestroyNotify free_func) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList *g_slist_prepend(GSList *list, void* data) {
|
GSList *g_slist_prepend(GSList *list, void* data)
|
||||||
|
{
|
||||||
GSList *head = (GSList*)g_malloc(sizeof(GSList));
|
GSList *head = (GSList*)g_malloc(sizeof(GSList));
|
||||||
head->next = list;
|
head->next = list;
|
||||||
head->data = data;
|
head->data = data;
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList *g_slist_sort(GSList *list, compare_func compare) {
|
GSList *g_slist_sort(GSList *list, GCompareFunc compare)
|
||||||
|
{
|
||||||
GSList *i, *it, *j;
|
GSList *i, *it, *j;
|
||||||
/* base case for singletons or empty lists */
|
/* base case for singletons or empty lists */
|
||||||
if (list == NULL || list->next == NULL) return list;
|
if (list == NULL || list->next == NULL) return list;
|
||||||
|
@ -326,7 +345,8 @@ GSList *g_slist_sort(GSList *list, compare_func compare) {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList *g_slist_find_custom(GSList *list, const void *data, compare_func func) {
|
GSList *g_slist_find_custom(GSList *list, const void *data, GCompareFunc func)
|
||||||
|
{
|
||||||
GSList *lp;
|
GSList *lp;
|
||||||
for (lp = list; lp; lp = lp->next) {
|
for (lp = list; lp; lp = lp->next) {
|
||||||
if ((*func)(lp->data, data) == 0) return lp;
|
if ((*func)(lp->data, data) == 0) return lp;
|
||||||
|
@ -334,7 +354,8 @@ GSList *g_slist_find_custom(GSList *list, const void *data, compare_func func) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList *g_slist_remove(GSList *list, const void *data) {
|
GSList *g_slist_remove(GSList *list, const void *data)
|
||||||
|
{
|
||||||
GSList *lp, *prev = NULL;
|
GSList *lp, *prev = NULL;
|
||||||
for (lp = list; lp; lp = lp->next) {
|
for (lp = list; lp; lp = lp->next) {
|
||||||
if (lp->data == data) {
|
if (lp->data == data) {
|
||||||
|
@ -362,7 +383,7 @@ typedef struct _KeyValue {
|
||||||
void *value;
|
void *value;
|
||||||
} KeyValue;
|
} KeyValue;
|
||||||
|
|
||||||
typedef struct _GHashTable {
|
struct _GHashTable {
|
||||||
GHashFunc hash_func;
|
GHashFunc hash_func;
|
||||||
GEqualFunc key_equal_func;
|
GEqualFunc key_equal_func;
|
||||||
GDestroyNotify key_destroy_func;
|
GDestroyNotify key_destroy_func;
|
||||||
|
@ -371,15 +392,17 @@ typedef struct _GHashTable {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t num_entries;
|
uint32_t num_entries;
|
||||||
GSList **buckets;
|
GSList **buckets;
|
||||||
} GHashTable;
|
};
|
||||||
|
|
||||||
void g_hash_table_destroy(GHashTable *hash_table) {
|
void g_hash_table_destroy(GHashTable *hash_table)
|
||||||
|
{
|
||||||
if (hash_table == NULL) return;
|
if (hash_table == NULL) return;
|
||||||
g_hash_table_remove_all(hash_table);
|
g_hash_table_remove_all(hash_table);
|
||||||
g_hash_table_unref(hash_table);
|
g_hash_table_unref(hash_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* g_hash_table_find(GHashTable *hash_table, GHRFunc predicate, void* user_data) {
|
void* g_hash_table_find(GHashTable *hash_table, GHRFunc predicate, void* user_data)
|
||||||
|
{
|
||||||
if (hash_table == NULL) return NULL;
|
if (hash_table == NULL) return NULL;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < hash_table->size; i++) {
|
for (i = 0; i < hash_table->size; i++) {
|
||||||
|
@ -392,7 +415,8 @@ void* g_hash_table_find(GHashTable *hash_table, GHRFunc predicate, void* user_da
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void g_hash_table_foreach(GHashTable *hash_table, GHFunc func, void* user_data) {
|
void g_hash_table_foreach(GHashTable *hash_table, GHFunc func, void* user_data)
|
||||||
|
{
|
||||||
if (hash_table == NULL) return;
|
if (hash_table == NULL) return;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < hash_table->size; i++) {
|
for (i = 0; i < hash_table->size; i++) {
|
||||||
|
@ -404,7 +428,8 @@ void g_hash_table_foreach(GHashTable *hash_table, GHFunc func, void* user_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int g_hash_table_insert(GHashTable *hash_table, void* key, void* value) {
|
int g_hash_table_insert(GHashTable *hash_table, void* key, void* value)
|
||||||
|
{
|
||||||
if (hash_table == NULL) return 1;
|
if (hash_table == NULL) return 1;
|
||||||
GSList *lp;
|
GSList *lp;
|
||||||
guint hash = (*hash_table->hash_func)(key);
|
guint hash = (*hash_table->hash_func)(key);
|
||||||
|
@ -428,7 +453,8 @@ int g_hash_table_insert(GHashTable *hash_table, void* key, void* value) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* g_hash_table_lookup(GHashTable *hash_table, const void* key) {
|
void* g_hash_table_lookup(GHashTable *hash_table, const void* key)
|
||||||
|
{
|
||||||
if (hash_table == NULL) return NULL;
|
if (hash_table == NULL) return NULL;
|
||||||
GSList *lp;
|
GSList *lp;
|
||||||
guint hash = (*hash_table->hash_func)(key);
|
guint hash = (*hash_table->hash_func)(key);
|
||||||
|
@ -443,12 +469,14 @@ void* g_hash_table_lookup(GHashTable *hash_table, const void* key) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
GHashTable *g_hash_table_new(GHashFunc hash_func, GEqualFunc key_equal_func) {
|
GHashTable *g_hash_table_new(GHashFunc hash_func, GEqualFunc key_equal_func)
|
||||||
|
{
|
||||||
return g_hash_table_new_full(hash_func, key_equal_func, NULL, NULL);
|
return g_hash_table_new_full(hash_func, key_equal_func, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
GHashTable *g_hash_table_new_full(GHashFunc hash_func, GEqualFunc key_equal_func,
|
GHashTable *g_hash_table_new_full(GHashFunc hash_func, GEqualFunc key_equal_func,
|
||||||
GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func) {
|
GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
|
||||||
|
{
|
||||||
GHashTable *ht = (GHashTable*)g_malloc(sizeof(GHashTable));
|
GHashTable *ht = (GHashTable*)g_malloc(sizeof(GHashTable));
|
||||||
ht->hash_func = hash_func ? hash_func : g_direct_hash;
|
ht->hash_func = hash_func ? hash_func : g_direct_hash;
|
||||||
ht->key_equal_func = key_equal_func;
|
ht->key_equal_func = key_equal_func;
|
||||||
|
@ -461,7 +489,8 @@ GHashTable *g_hash_table_new_full(GHashFunc hash_func, GEqualFunc key_equal_func
|
||||||
return ht;
|
return ht;
|
||||||
}
|
}
|
||||||
|
|
||||||
void g_hash_table_remove_all(GHashTable *hash_table) {
|
void g_hash_table_remove_all(GHashTable *hash_table)
|
||||||
|
{
|
||||||
if (hash_table == NULL) return;
|
if (hash_table == NULL) return;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < hash_table->size; i++) {
|
for (i = 0; i < hash_table->size; i++) {
|
||||||
|
@ -478,7 +507,8 @@ void g_hash_table_remove_all(GHashTable *hash_table) {
|
||||||
hash_table->num_entries = 0;
|
hash_table->num_entries = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int g_hash_table_remove(GHashTable *hash_table, const void* key) {
|
int g_hash_table_remove(GHashTable *hash_table, const void* key)
|
||||||
|
{
|
||||||
GSList *lp, *prev = NULL;
|
GSList *lp, *prev = NULL;
|
||||||
if (hash_table == NULL) return 0;
|
if (hash_table == NULL) return 0;
|
||||||
guint hash = (*hash_table->hash_func)(key);
|
guint hash = (*hash_table->hash_func)(key);
|
||||||
|
@ -504,7 +534,8 @@ int g_hash_table_remove(GHashTable *hash_table, const void* key) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void g_hash_table_unref(GHashTable *hash_table) {
|
void g_hash_table_unref(GHashTable *hash_table)
|
||||||
|
{
|
||||||
if (hash_table == NULL) return;
|
if (hash_table == NULL) return;
|
||||||
hash_table->refcount--;
|
hash_table->refcount--;
|
||||||
if (hash_table->refcount == 0) {
|
if (hash_table->refcount == 0) {
|
||||||
|
@ -513,13 +544,15 @@ void g_hash_table_unref(GHashTable *hash_table) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GHashTable *g_hash_table_ref(GHashTable *hash_table) {
|
GHashTable *g_hash_table_ref(GHashTable *hash_table)
|
||||||
|
{
|
||||||
if (hash_table == NULL) return NULL;
|
if (hash_table == NULL) return NULL;
|
||||||
hash_table->refcount++;
|
hash_table->refcount++;
|
||||||
return hash_table;
|
return hash_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
guint g_hash_table_size(GHashTable *hash_table) {
|
guint g_hash_table_size(GHashTable *hash_table)
|
||||||
|
{
|
||||||
return hash_table ? hash_table->num_entries : 0;
|
return hash_table ? hash_table->num_entries : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,27 +561,31 @@ guint g_hash_table_size(GHashTable *hash_table) {
|
||||||
|
|
||||||
/* general g_XXX substitutes */
|
/* general g_XXX substitutes */
|
||||||
|
|
||||||
void *g_malloc(size_t size) {
|
void *g_malloc(size_t size)
|
||||||
|
{
|
||||||
if (size == 0) return NULL;
|
if (size == 0) return NULL;
|
||||||
void *res = malloc(size);
|
void *res = malloc(size);
|
||||||
if (res == NULL) exit(1);
|
if (res == NULL) exit(1);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *g_malloc0(size_t size) {
|
void *g_malloc0(size_t size)
|
||||||
|
{
|
||||||
if (size == 0) return NULL;
|
if (size == 0) return NULL;
|
||||||
void *res = calloc(size, 1);
|
void *res = calloc(size, 1);
|
||||||
if (res == NULL) exit(1);
|
if (res == NULL) exit(1);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *g_try_malloc0(size_t size) {
|
void *g_try_malloc0(size_t size)
|
||||||
|
{
|
||||||
if (size == 0) return NULL;
|
if (size == 0) return NULL;
|
||||||
void *res = calloc(size, 1);
|
void *res = calloc(size, 1);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *g_realloc(void *ptr, size_t size) {
|
void *g_realloc(void *ptr, size_t size)
|
||||||
|
{
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
free(ptr);
|
free(ptr);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -558,11 +595,13 @@ void *g_realloc(void *ptr, size_t size) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *g_strdup(const char *str) {
|
char *g_strdup(const char *str)
|
||||||
|
{
|
||||||
return str ? strdup(str) : NULL;
|
return str ? strdup(str) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *g_strdup_printf(const char *format, ...) {
|
char *g_strdup_printf(const char *format, ...)
|
||||||
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char *res;
|
char *res;
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
|
@ -571,20 +610,23 @@ char *g_strdup_printf(const char *format, ...) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *g_strdup_vprintf(const char *format, va_list ap) {
|
char *g_strdup_vprintf(const char *format, va_list ap)
|
||||||
|
{
|
||||||
char *str_res = NULL;
|
char *str_res = NULL;
|
||||||
vasprintf(&str_res, format, ap);
|
vasprintf(&str_res, format, ap);
|
||||||
return str_res;
|
return str_res;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *g_strndup(const char *str, size_t n) {
|
char *g_strndup(const char *str, size_t n)
|
||||||
|
{
|
||||||
/* try to mimic glib's g_strndup */
|
/* try to mimic glib's g_strndup */
|
||||||
char *res = calloc(n + 1, 1);
|
char *res = calloc(n + 1, 1);
|
||||||
strncpy(res, str, n);
|
strncpy(res, str, n);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void g_strfreev(char **str_array) {
|
void g_strfreev(char **str_array)
|
||||||
|
{
|
||||||
char **p = str_array;
|
char **p = str_array;
|
||||||
if (p) {
|
if (p) {
|
||||||
while (*p) {
|
while (*p) {
|
||||||
|
@ -594,7 +636,8 @@ void g_strfreev(char **str_array) {
|
||||||
free(str_array);
|
free(str_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *g_memdup(const void *mem, size_t byte_size) {
|
void *g_memdup(const void *mem, size_t byte_size)
|
||||||
|
{
|
||||||
if (mem) {
|
if (mem) {
|
||||||
void *res = g_malloc(byte_size);
|
void *res = g_malloc(byte_size);
|
||||||
memcpy(res, mem, byte_size);
|
memcpy(res, mem, byte_size);
|
||||||
|
@ -603,25 +646,29 @@ void *g_memdup(const void *mem, size_t byte_size) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *g_new_(size_t sz, size_t n_structs) {
|
void *g_new_(size_t sz, size_t n_structs)
|
||||||
|
{
|
||||||
size_t need = sz * n_structs;
|
size_t need = sz * n_structs;
|
||||||
if ((need / sz) != n_structs) return NULL;
|
if ((need / sz) != n_structs) return NULL;
|
||||||
return g_malloc(need);
|
return g_malloc(need);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *g_new0_(size_t sz, size_t n_structs) {
|
void *g_new0_(size_t sz, size_t n_structs)
|
||||||
|
{
|
||||||
size_t need = sz * n_structs;
|
size_t need = sz * n_structs;
|
||||||
if ((need / sz) != n_structs) return NULL;
|
if ((need / sz) != n_structs) return NULL;
|
||||||
return g_malloc0(need);
|
return g_malloc0(need);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *g_renew_(size_t sz, void *mem, size_t n_structs) {
|
void *g_renew_(size_t sz, void *mem, size_t n_structs)
|
||||||
|
{
|
||||||
size_t need = sz * n_structs;
|
size_t need = sz * n_structs;
|
||||||
if ((need / sz) != n_structs) return NULL;
|
if ((need / sz) != n_structs) return NULL;
|
||||||
return g_realloc(mem, need);
|
return g_realloc(mem, need);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *g_strconcat (const char *string1, ...) {
|
char *g_strconcat (const char *string1, ...)
|
||||||
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char *res;
|
char *res;
|
||||||
size_t sz = strlen(string1);
|
size_t sz = strlen(string1);
|
||||||
|
@ -644,7 +691,8 @@ char *g_strconcat (const char *string1, ...) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
char **g_strsplit(const char *string, const char *delimiter, int max_tokens) {
|
char **g_strsplit(const char *string, const char *delimiter, int max_tokens)
|
||||||
|
{
|
||||||
char **res;
|
char **res;
|
||||||
if (string == NULL || *string == 0) {
|
if (string == NULL || *string == 0) {
|
||||||
res = (char**)g_malloc(sizeof(char*));
|
res = (char**)g_malloc(sizeof(char*));
|
||||||
|
@ -686,7 +734,8 @@ char **g_strsplit(const char *string, const char *delimiter, int max_tokens) {
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
char *g_win32_error_message(int error) {
|
char *g_win32_error_message(int error)
|
||||||
|
{
|
||||||
char *msg;
|
char *msg;
|
||||||
char *winMsg = NULL;
|
char *winMsg = NULL;
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
|
|
|
@ -39,18 +39,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
/* typedefs for glib related types that may still be referenced */
|
/* typedefs for glib related types that may still be referenced */
|
||||||
typedef void* gpointer;
|
typedef void* gpointer;
|
||||||
typedef const void *gconstpointer;
|
typedef const void *gconstpointer;
|
||||||
typedef uint32_t guint;
|
typedef int gint;
|
||||||
|
typedef unsigned int guint;
|
||||||
typedef char gchar;
|
typedef char gchar;
|
||||||
typedef int gboolean;
|
typedef int gboolean;
|
||||||
|
|
||||||
typedef int (*GCompareFunc)(const void *v1, const void *v2);
|
typedef void (*GFunc)(void* data, void* user_data);
|
||||||
|
typedef gint (*GCompareFunc)(const void *v1, const void *v2);
|
||||||
typedef void (*GDestroyNotify)(void *data);
|
typedef void (*GDestroyNotify)(void *data);
|
||||||
|
|
||||||
uint32_t g_direct_hash(const void *v);
|
guint g_direct_hash(const void *v);
|
||||||
int g_direct_equal(const void *v1, const void *v2);
|
int g_direct_equal(const void *v1, const void *v2);
|
||||||
uint32_t g_str_hash(const void *v);
|
guint g_str_hash(const void *v);
|
||||||
int g_str_equal(const void *v1, const void *v2);
|
int g_str_equal(const void *v1, const void *v2);
|
||||||
uint32_t g_int_hash(const void *v);
|
guint g_int_hash(const void *v);
|
||||||
int g_int_equal(const void *v1, const void *v2);
|
int g_int_equal(const void *v1, const void *v2);
|
||||||
|
|
||||||
typedef struct _GList {
|
typedef struct _GList {
|
||||||
|
@ -59,17 +61,14 @@ typedef struct _GList {
|
||||||
struct _GList *prev;
|
struct _GList *prev;
|
||||||
} GList;
|
} GList;
|
||||||
|
|
||||||
typedef void (*list_func)(void* data, void* user_data);
|
|
||||||
typedef int (*compare_func)(const void *d1, const void *d2);
|
|
||||||
|
|
||||||
GList *g_list_first(GList *list);
|
GList *g_list_first(GList *list);
|
||||||
void g_list_foreach(GList *list, list_func func, void* user_data);
|
void g_list_foreach(GList *list, GFunc func, void* user_data);
|
||||||
void g_list_free(GList *list);
|
void g_list_free(GList *list);
|
||||||
GList *g_list_insert_sorted(GList *list, void* data, compare_func compare);
|
GList *g_list_insert_sorted(GList *list, void* data, GCompareFunc compare);
|
||||||
#define g_list_next(list) (list->next)
|
#define g_list_next(list) (list->next)
|
||||||
GList *g_list_prepend(GList *list, void* data);
|
GList *g_list_prepend(GList *list, void* data);
|
||||||
GList *g_list_remove_link(GList *list, GList *llink);
|
GList *g_list_remove_link(GList *list, GList *llink);
|
||||||
GList *g_list_sort(GList *list, compare_func compare);
|
GList *g_list_sort(GList *list, GCompareFunc compare);
|
||||||
|
|
||||||
typedef struct _GSList {
|
typedef struct _GSList {
|
||||||
void *data;
|
void *data;
|
||||||
|
@ -77,15 +76,15 @@ typedef struct _GSList {
|
||||||
} GSList;
|
} GSList;
|
||||||
|
|
||||||
GSList *g_slist_append(GSList *list, void* data);
|
GSList *g_slist_append(GSList *list, void* data);
|
||||||
void g_slist_foreach(GSList *list, list_func func, void* user_data);
|
void g_slist_foreach(GSList *list, GFunc func, void* user_data);
|
||||||
void g_slist_free(GSList *list);
|
void g_slist_free(GSList *list);
|
||||||
void g_slist_free_full(GSList *list, GDestroyNotify free_func);
|
void g_slist_free_full(GSList *list, GDestroyNotify free_func);
|
||||||
GSList *g_slist_prepend(GSList *list, void* data);
|
GSList *g_slist_prepend(GSList *list, void* data);
|
||||||
GSList *g_slist_sort(GSList *list, compare_func compare);
|
GSList *g_slist_sort(GSList *list, GCompareFunc compare);
|
||||||
GSList *g_slist_find_custom(GSList *list, const void *data, compare_func func);
|
GSList *g_slist_find_custom(GSList *list, const void *data, GCompareFunc func);
|
||||||
GSList *g_slist_remove(GSList *list, const void *data);
|
GSList *g_slist_remove(GSList *list, const void *data);
|
||||||
|
|
||||||
typedef uint32_t (*GHashFunc)(const void *key);
|
typedef guint (*GHashFunc)(const void *key);
|
||||||
typedef int (*GEqualFunc)(const void *a, const void *b);
|
typedef int (*GEqualFunc)(const void *a, const void *b);
|
||||||
typedef void (*GHFunc)(void* key, void* value, void* user_data);
|
typedef void (*GHFunc)(void* key, void* value, void* user_data);
|
||||||
typedef int (*GHRFunc)(void* key, void* value, void* user_data);
|
typedef int (*GHRFunc)(void* key, void* value, void* user_data);
|
||||||
|
@ -104,7 +103,7 @@ void g_hash_table_remove_all(GHashTable *hash_table);
|
||||||
int g_hash_table_remove(GHashTable *hash_table, const void* key);
|
int g_hash_table_remove(GHashTable *hash_table, const void* key);
|
||||||
void g_hash_table_unref(GHashTable *hash_table);
|
void g_hash_table_unref(GHashTable *hash_table);
|
||||||
GHashTable *g_hash_table_ref(GHashTable *hash_table);
|
GHashTable *g_hash_table_ref(GHashTable *hash_table);
|
||||||
uint32_t g_hash_table_size(GHashTable *hash_table);
|
guint g_hash_table_size(GHashTable *hash_table);
|
||||||
|
|
||||||
/* replacement for g_malloc dependency */
|
/* replacement for g_malloc dependency */
|
||||||
void *g_malloc(size_t size);
|
void *g_malloc(size_t size);
|
||||||
|
|
|
@ -119,7 +119,7 @@ static inline GList *g_list_insert_sorted_merged(GList *list,
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int32_t range_compare(gconstpointer a, gconstpointer b)
|
static inline gint range_compare(gconstpointer a, gconstpointer b)
|
||||||
{
|
{
|
||||||
Range *ra = (Range *)a, *rb = (Range *)b;
|
Range *ra = (Range *)a, *rb = (Range *)b;
|
||||||
if (ra->begin == rb->begin && ra->end == rb->end) {
|
if (ra->begin == rb->begin && ra->end == rb->end) {
|
||||||
|
|
|
@ -1285,6 +1285,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
|
||||||
return !(env->daif & PSTATE_I);
|
return !(env->daif & PSTATE_I);
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,7 @@ static void count_cpreg(gpointer key, gpointer opaque)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t cpreg_key_compare(gconstpointer a, gconstpointer b)
|
static gint cpreg_key_compare(gconstpointer a, gconstpointer b)
|
||||||
{
|
{
|
||||||
uint64_t aidx = cpreg_to_kvm_id(*(uint32_t *)a);
|
uint64_t aidx = cpreg_to_kvm_id(*(uint32_t *)a);
|
||||||
uint64_t bidx = cpreg_to_kvm_id(*(uint32_t *)b);
|
uint64_t bidx = cpreg_to_kvm_id(*(uint32_t *)b);
|
||||||
|
|
|
@ -14,7 +14,7 @@ V ?= 0
|
||||||
|
|
||||||
CFLAGS += -Wall -Werror -I../include
|
CFLAGS += -Wall -Werror -I../include
|
||||||
LDFLAGS += -L$(LIBDIR) -lunicorn -lpthread -lm
|
LDFLAGS += -L$(LIBDIR) -lunicorn -lpthread -lm
|
||||||
LDLIBS += -lpthread -lunicorn -lm
|
LDLIBS += -lpthread -lunicorn -lm -lrt
|
||||||
|
|
||||||
ifneq ($(CROSS),)
|
ifneq ($(CROSS),)
|
||||||
CC = $(CROSS)gcc
|
CC = $(CROSS)gcc
|
||||||
|
|
93
tests/regress/arm_bx_unmapped.py
Normal file
93
tests/regress/arm_bx_unmapped.py
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
from __future__ import print_function
|
||||||
|
from unicorn import *
|
||||||
|
from unicorn.arm_const import *
|
||||||
|
import regress
|
||||||
|
|
||||||
|
# code to be emulated
|
||||||
|
'''
|
||||||
|
ins = {
|
||||||
|
0x00008cd4: """
|
||||||
|
push {r11}
|
||||||
|
add r11, sp, #0
|
||||||
|
mov r3, pc
|
||||||
|
mov r0, r3
|
||||||
|
sub sp, r11, #0
|
||||||
|
pop {r11}
|
||||||
|
bx lr
|
||||||
|
""",
|
||||||
|
0x00008cf0: """
|
||||||
|
push {r11}
|
||||||
|
add r11, sp, #0
|
||||||
|
push {r6}
|
||||||
|
add r6, pc, $1
|
||||||
|
bx r6
|
||||||
|
.code 16
|
||||||
|
mov r3, pc
|
||||||
|
add r3, $0x4
|
||||||
|
push {r3}
|
||||||
|
pop {pc}
|
||||||
|
.code 32
|
||||||
|
pop {r6}
|
||||||
|
mov r0, r3
|
||||||
|
sub sp, r11, #0
|
||||||
|
pop {r11}
|
||||||
|
bx lr
|
||||||
|
""",
|
||||||
|
0x00008d20: """
|
||||||
|
push {r11}
|
||||||
|
add r11, sp, #0
|
||||||
|
mov r3, lr
|
||||||
|
mov r0, r3
|
||||||
|
sub sp, r11, #0
|
||||||
|
pop {r11}
|
||||||
|
bx lr
|
||||||
|
""",
|
||||||
|
0x00008d68: "bl 0x8cd4\n"
|
||||||
|
"mov r4, r0\n"
|
||||||
|
"bl 0x8cf0\n"
|
||||||
|
"mov r3, r0\n"
|
||||||
|
"add r4, r4, r3\n"
|
||||||
|
"bl 0x8d20\n"
|
||||||
|
"mov r3, r0\n"
|
||||||
|
"add r2, r4, r3",
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
|
||||||
|
class BxTwiceTest(regress.RegressTest):
|
||||||
|
def runTest(self):
|
||||||
|
ADDRESS = 0x8000
|
||||||
|
MAIN_ADDRESS = 0x8d68
|
||||||
|
STACK_ADDR = ADDRESS + 0x1000
|
||||||
|
|
||||||
|
code = {
|
||||||
|
0x8cf0: '\x04\xb0-\xe5\x00\xb0\x8d\xe2\x04`-\xe5\x01`\x8f\xe2\x16\xff/\xe1{F\x03\xf1\x04\x03\x08\xb4\x00\xbd\x00\x00\x04`\x9d\xe4\x03\x00\xa0\xe1\x00\xd0K\xe2\x04\xb0\x9d\xe4\x1e\xff/\xe1',
|
||||||
|
0x8d20: '\x04\xb0-\xe5\x00\xb0\x8d\xe2\x0e0\xa0\xe1\x03\x00\xa0\xe1\x00\xd0K\xe2\x04\xb0\x9d\xe4\x1e\xff/\xe1',
|
||||||
|
0x8cd4: '\x04\xb0-\xe5\x00\xb0\x8d\xe2\x0f0\xa0\xe1\x03\x00\xa0\xe1\x00\xd0K\xe2\x04\xb0\x9d\xe4\x1e\xff/\xe1',
|
||||||
|
0x8d68: '\xd9\xff\xff\xeb\x00@\xa0\xe1\xde\xff\xff\xeb\x000\xa0\xe1\x03@\x84\xe0\xe7\xff\xff\xeb\x000\xa0\xe1\x03 \x84\xe0'
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
mu = Uc(UC_ARCH_ARM, UC_MODE_ARM)
|
||||||
|
# map 2MB memory for this emulation
|
||||||
|
mu.mem_map(ADDRESS, 2 * 1024 * 1024)
|
||||||
|
|
||||||
|
# write machine code to be emulated to memory
|
||||||
|
for addr, c in code.items():
|
||||||
|
print("Writing chunk to 0x{:x}".format(addr))
|
||||||
|
mu.mem_write(addr, c)
|
||||||
|
|
||||||
|
# initialize machine registers
|
||||||
|
mu.reg_write(UC_ARM_REG_SP, STACK_ADDR)
|
||||||
|
|
||||||
|
print("Starting emulation")
|
||||||
|
|
||||||
|
# emulate code in infinite time & unlimited instructions
|
||||||
|
mu.emu_start(MAIN_ADDRESS, MAIN_ADDRESS + len(code[MAIN_ADDRESS]))
|
||||||
|
|
||||||
|
print("Emulation done")
|
||||||
|
|
||||||
|
r2 = mu.reg_read(UC_ARM_REG_R2)
|
||||||
|
print(">>> r2: 0x{:08x}".format(r2))
|
||||||
|
|
||||||
|
except UcError as e:
|
||||||
|
self.fail("ERROR: %s" % e)
|
Loading…
Reference in a new issue